UNPKG

4.76 kBJavaScriptView Raw
1'use strict';
2
3var pkg = require('../package');
4console.log('%s %s in %s', pkg.name, pkg.version, process.cwd());
5
6var path = require('path');
7var join = path.join;
8var fs = require('fs');
9var read = fs.readFileSync;
10var write = fs.writeFileSync;
11
12//
13// Compatiblity with older node.js.
14//
15var existsSync = fs.existsSync || path.existsSync;
16
17var isForced = process.argv.some(function (argument) {
18 return argument === '-f' || argument === '--force';
19});
20
21function readJsonFile(filename) {
22 return JSON.parse(read(filename));
23}
24
25function writeJsonToFile(filename, object) {
26 console.log('saving updated files %s', filename);
27 write(filename, JSON.stringify(object, null, 2));
28}
29
30(function avoidSelfInstall() {
31 if (isForced) {
32 return;
33 }
34 // only install hook if this is executed from folder
35 // that is dependency of the current root path
36 // package A
37 // node_modules/pre-git
38 // installs pre-git hook for package A
39 var pkgPath = 'node_modules' + path.sep + pkg.name;
40 // we are constructing RegExp using paths, that can
41 // use \ (Windows) as path separator. Need to escape \
42 // before constructing the RegExp.
43 pkgPath = pkgPath.replace('\\', '\\\\');
44 var nameRegex = new RegExp(pkgPath + '$');
45 if (!nameRegex.test(process.cwd())) {
46 console.log('running install inside self, no need');
47 console.log('cwd', process.cwd());
48 console.log('pkgPath', pkgPath);
49 process.exit(0);
50 }
51}());
52
53//
54// The root of repository.
55//
56var root = path.resolve(__dirname, '../..');
57function getRootPackagePath() {
58 return join(root, 'package.json');
59}
60
61var exec = require('shelljs').exec;
62var result = exec('git rev-parse --show-toplevel');
63if (result.code === 0) {
64 root = path.resolve(result.output.trim());
65}
66
67//
68// The location .git and it's hooks
69//
70var git = path.resolve(root, '.git');
71var hooks = path.resolve(git, 'hooks');
72
73//
74// Check if we are in a git repository so we can bail out early when this is not
75// the case.
76//
77if (!existsSync(git) || !fs.lstatSync(git).isDirectory()) {
78 console.error('Could not find git repo in ' + git);
79 process.exit(0);
80}
81
82(function () {
83 if (!existsSync(hooks)) {
84 fs.mkdirSync(hooks);
85 }
86}());
87console.log('git hooks folder %s', hooks);
88
89var hookScripts = ['commit-msg',
90 'pre-commit', 'pre-push', 'post-commit', 'post-checkout', 'post-merge'];
91
92var sourceHooksFolders = join(__dirname, '../hooks');
93
94if (existsSync(sourceHooksFolders)) {
95 hookScripts.forEach(installHook);
96} else {
97 console.log('cannot find hooks folder %s', sourceHooksFolders);
98}
99
100function missingCommitScript(pkg) {
101 return !pkg.scripts ||
102 !pkg.scripts.commit ||
103 /node_modules\/commitizen/.test(pkg.scripts.commit);
104}
105
106function setupMessageValidation(pkg) {
107 if (!pkg.scripts) {
108 pkg.scripts = {};
109 }
110 pkg.scripts.commit = 'commit-wizard';
111}
112
113(function addToPackage(hookNames) {
114 var pkgPath = getRootPackagePath(),
115 targetPackage;
116 if (existsSync(pkgPath)) {
117 targetPackage = readJsonFile(pkgPath);
118 console.log('read target package from %s', pkgPath);
119 } else {
120 console.log('could not find package under path %s', pkgPath);
121 return;
122 }
123
124 if (!targetPackage.config) {
125 targetPackage.config = {};
126 }
127
128 if (!targetPackage.config['pre-git']) {
129 targetPackage.config['pre-git'] = {};
130 var config = targetPackage.config['pre-git'];
131
132 hookNames.forEach(function addProperty(hookName) {
133 if (hookName === 'commit-msg') {
134 config[hookName] = 'simple';
135 console.log('set simple %s format', hookName);
136 } else {
137 config[hookName] = [];
138 console.log('added empty command list for hook %s', hookName);
139 }
140 });
141
142 if (missingCommitScript(targetPackage)) {
143 setupMessageValidation(targetPackage);
144 }
145
146 writeJsonToFile(pkgPath, targetPackage);
147 }
148
149}(hookScripts));
150
151function installHook(name) {
152 console.log('installing hook %s', name);
153
154 var targetHookFilename = path.resolve(hooks, name);
155 //
156 // Our own hook runner.
157 //
158 var fullname = join(sourceHooksFolders, name);
159 if (!existsSync(fullname)) {
160 throw new Error('Cannot find hook file to copy ' + fullname);
161 }
162 var hook = read(fullname);
163
164 //
165 // If there's an existing `pre-commit` hook we want to back it up instead of
166 // overriding it and losing it completely
167 //
168 if (existsSync(targetHookFilename)) {
169 console.log('');
170 console.log(name + ': Detected an existing git hook');
171 write(targetHookFilename + '.old', read(targetHookFilename));
172 console.log(name + ': Old hook backuped to .old');
173 console.log('');
174 }
175
176 //
177 // Everything is ready for the installation of the pre-commit hook. Write it and
178 // make it executable.
179 //
180 write(targetHookFilename, hook);
181 fs.chmodSync(targetHookFilename, '755');
182}