diff --git a/scripts/test-install.sh b/scripts/test-install.sh index e0a05b7a8..1459624e9 100644 --- a/scripts/test-install.sh +++ b/scripts/test-install.sh @@ -131,5 +131,26 @@ if [ "$exitCode" -eq 0 ]; then exit 1 fi +# --- +test "hook should fail if command not found" +cat > .huskyrc << EOL +{ + "skipCI": false, + "hooks": { + "pre-commit": "cmdfoo" + } +} +EOL + +set +e +commit fifth +exitCode=$? +set -e + +if [ "$exitCode" -eq 0 ]; then + echo "Fail: pre-commit hook should have failed" + exit 1 +fi + echo echo "Success: all tests passed" diff --git a/src/runner/__tests__/index.ts b/src/runner/__tests__/index.ts index 453084101..a13abd40f 100644 --- a/src/runner/__tests__/index.ts +++ b/src/runner/__tests__/index.ts @@ -47,7 +47,7 @@ describe('run', (): void => { expect(status).toBe(0) }) - it('should return 0 status if the command is undefined', async (): Promise< + it('should return 0 status if no hooks are defined', async (): Promise< void > => { const dir = tempy.directory() @@ -64,6 +64,26 @@ describe('run', (): void => { expect(status).toBe(0) }) + it('should return 1 status if the command is not found in PATH', async (): Promise< + void + > => { + const dir = tempy.directory() + + fs.writeFileSync( + path.join(dir, 'package.json'), + JSON.stringify({ + husky: { + hooks: { + 'pre-commit': 'cmdfoo' + } + } + }) + ) + + const status = await index(['', '', 'pre-commit'], { cwd: dir }) + expect(status).toBe(1) + }) + it('should run failing command and return 1 status', async (): Promise< void > => { diff --git a/src/runner/index.ts b/src/runner/index.ts index d7faf9724..459219e34 100644 --- a/src/runner/index.ts +++ b/src/runner/index.ts @@ -58,6 +58,13 @@ function runCommand( console.log(`husky > ${hookName} hook failed ${noVerifyMessage}`) } + // If shell exits with 127 it means that some command was not found. + // However, if husky has been deleted from node_modules, it'll be a 127 too. + // To be able to distinguish between both cases, 127 is changed to 1. + if (status === 127) { + return 1 + } + return status || 0 }