Skip to content

Commit 349e7f9

Browse files
committed
feat(postinstall): warn when no hooks were installed
various scenarios like no scripts field, no githook scripts, no valid githook scripts
1 parent 7a475af commit 349e7f9

File tree

5 files changed

+90
-17
lines changed

5 files changed

+90
-17
lines changed

.eslintrc

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
},
88
rules: {
99
// think in function scope
10-
'vars-on-top': 0
10+
'vars-on-top': 0,
11+
// command line tool
12+
'no-console': 0
1113
}
1214
}

postinstall.js

Lines changed: 36 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -70,23 +70,45 @@ if (!fs.statSync(gitHooksDirectoryPath).isDirectory()) {
7070
return;
7171
}
7272

73-
Object.keys(parentModulePackage.scripts)
74-
.forEach(function (scriptName) {
73+
var githookNames = Object
74+
.keys(parentModulePackage.scripts)
75+
.map(function (scriptName) {
7576
var scriptParts = /^githook:(.+)$/.exec(scriptName);
7677
if (!scriptParts) {
7778
debug(scriptName + ' ignored');
78-
return;
79+
return false;
7980
}
80-
8181
var hookName = scriptParts[1];
82-
if (VALID_HOOK_NAMES.indexOf(hookName) === -1) {
83-
console.warn('githook-scripts: "' + hookName + '" is not a valid git hook, ignoring');
84-
return;
85-
}
86-
87-
var hookPath = path.join(gitHooksDirectoryPath, hookName);
88-
fs.writeFileSync(hookPath, '#!/bin/bash\n npm run ' + scriptName + ' "$@"');
89-
fs.chmodSync(hookPath, '755');
90-
debug('wrote ', hookPath);
91-
console.log('githook-scripts: added hook ' + hookName);
82+
return hookName;
83+
})
84+
.filter(function (hookName) {
85+
return !!hookName;
9286
});
87+
88+
if (githookNames.length <= 0) {
89+
console.warn('githook-scripts: no githook scripts found, add one (ex: "githook:pre-commit") to package.json and run "npm rebuild githook-scripts" to activate');
90+
return;
91+
}
92+
93+
var validGithookNames = githookNames.filter(function (hookName) {
94+
if (VALID_HOOK_NAMES.indexOf(hookName) >= 0) {
95+
return true;
96+
}
97+
console.warn('githook-scripts: "' + hookName + '" is not a valid git hook, ignoring');
98+
return false;
99+
});
100+
101+
if (validGithookNames.length <= 0) {
102+
console.warn('githook-scripts: no valid githook scripts found, add one (ex: "githook:pre-commit") to package.json and run "npm rebuild githook-scripts" to activate');
103+
console.warn('githook-scripts: valid githooks are ' + VALID_HOOK_NAMES.join(', '));
104+
return;
105+
}
106+
107+
validGithookNames.forEach(function (hookName) {
108+
var hookPath = path.join(gitHooksDirectoryPath, hookName);
109+
var scriptName = 'githook:' + hookName;
110+
fs.writeFileSync(hookPath, '#!/bin/bash\n npm run ' + scriptName + ' "$@"');
111+
fs.chmodSync(hookPath, '755');
112+
debug('wrote ', hookPath);
113+
console.log('githook-scripts: added hook ' + hookName);
114+
});

test/_utils.js

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
var fs = require('fs');
22
var path = require('path');
33
var execSync = require('child_process').execSync;
4+
var spawnSync = require('child_process').spawnSync;
45

56
var debug = require('debug')('githook-scripts:test-utils');
67
var rimraf = require('rimraf');
@@ -54,8 +55,17 @@ function setup(scripts, opts) {
5455
{ PATH: BROKEN_GIT_LOCATION + (process.platform === 'win32' ? ';' : ':') + process.env.PATH }
5556
);
5657
}
57-
debug('npm install: ' + execSync('npm --loglevel=silent install', npmExecOpts).toString());
58+
var npmInstallResults = spawnSync('npm', ['--loglevel=silent', 'install'], npmExecOpts);
59+
var rawLogs = '' + npmInstallResults.stdout + '\n' + npmInstallResults.stderr;
60+
debug('npm install: ' + rawLogs);
5861

5962
debug('setup finished');
63+
64+
return rawLogs
65+
.split('\n')
66+
.filter(function (line) {
67+
debug(line.startsWith('githook-scripts:') + ' ' + line);
68+
return line.startsWith('githook-scripts:');
69+
});
6070
}
6171
module.exports.setup = setup;

test/no-scripts.spec.js

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,21 @@ var expect = chai.expect;
77
chai.use(chaiFiles);
88

99
describe('no scripts', function () {
10-
after(utils.teardown);
10+
afterEach(utils.teardown);
1111

1212
it('should not fail if a package.json does not have a scripts field', function () {
1313
expect(function () { utils.setup(undefined); }).not.to.throw();
1414
});
15+
16+
it('should warn if a package.json does not have a scripts field', function () {
17+
var logLines = utils.setup(undefined);
18+
expect(logLines).to.have.length(1);
19+
expect(logLines[0]).to.equal('githook-scripts: no "scripts" field in package.json, skipping');
20+
});
21+
22+
it('should warn if a package.json does not have any scripts defined', function () {
23+
var logLines = utils.setup({ });
24+
expect(logLines).to.have.length(1);
25+
expect(logLines[0]).to.equal('githook-scripts: no githook scripts found, add one (ex: "githook:pre-commit") to package.json and run "npm rebuild githook-scripts" to activate');
26+
});
1527
});

test/no-valid-hook-scripts.spec.js

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
var utils = require('./_utils.js');
2+
3+
var chai = require('chai');
4+
var expect = chai.expect;
5+
6+
describe('no valid hook scripts', function () {
7+
afterEach(utils.teardown);
8+
9+
it('should warn that no hooks were valid', function () {
10+
var logLines = utils.setup({ 'githook:not-a-valid-hook': 'exit 1' });
11+
expect(logLines).to.have.length(3);
12+
expect(logLines[0]).to.equal('githook-scripts: "not-a-valid-hook" is not a valid git hook, ignoring');
13+
});
14+
15+
it('should say what valid hooks are and how to activate them when added', function () {
16+
var logLines = utils.setup({ 'githook:not-a-valid-hook': 'exit 1' });
17+
expect(logLines).to.have.length(3);
18+
expect(logLines[1]).to.equal('githook-scripts: no valid githook scripts found, add one (ex: "githook:pre-commit") to package.json and run "npm rebuild githook-scripts" to activate');
19+
expect(logLines[2]).to.equal('githook-scripts: valid githooks are applypatch-msg, pre-applypatch, post-applypatch, pre-commit, prepare-commit-msg, commit-msg, post-commit, pre-rebase, post-checkout, post-merge, pre-receive, update, post-receive, post-update, pre-auto-gc, post-rewrite, pre-push');
20+
});
21+
22+
it('should warn if a package.json does not have any githook scripts defined', function () {
23+
var logLines = utils.setup({ test: 'jest' });
24+
expect(logLines).to.have.length(1);
25+
expect(logLines[0]).to.equal('githook-scripts: no githook scripts found, add one (ex: "githook:pre-commit") to package.json and run "npm rebuild githook-scripts" to activate');
26+
});
27+
});

0 commit comments

Comments
 (0)