From 43848f3e672a06303182211cc7a569c3fadf2793 Mon Sep 17 00:00:00 2001 From: xcatliu Date: Thu, 9 Nov 2017 16:49:59 +0800 Subject: [PATCH 1/4] Add windows support --- lib/git-hooks.js | 37 ++++++++++++++++++++++++++++++------- package.json | 4 ++-- tests/run.test.js | 22 ++++++++++++++++++++++ 3 files changed, 54 insertions(+), 9 deletions(-) diff --git a/lib/git-hooks.js b/lib/git-hooks.js index 730b49e..3ada710 100644 --- a/lib/git-hooks.js +++ b/lib/git-hooks.js @@ -114,14 +114,11 @@ module.exports = { return path.resolve(hooksDirname, hookName); }) .filter(function (hookPath) { - var isFile = fs.lstatSync(hookPath).isFile(); - var isExecutable = fs.lstatSync(hookPath).isFile() && fsHelpers.isExecutable(hookPath); - - if (isFile && !isExecutable) { + if (!isExecutable(hookPath) && !isJS(hookPath)) { console.warn('[GIT-HOOKS WARNING] Non-executable file ' + hookPath + ' is skipped'); + return false; } - - return isFile && isExecutable; + return true; }); runHooks(hooks, args, callback); @@ -167,7 +164,13 @@ function runHooks(hooks, args, callback) { */ function spawnHook(hookName, args) { args = args || []; - return spawn(hookName, args, {stdio: 'inherit'}); + if (isExecutable(hookName)) { + return spawn(hookName, args, {stdio: 'inherit'}); + } else if (isJS(hookName)) { + return spawn('node', [hookName].concat(args), {stdio: 'inherit'}); + } else { + return spawn(hookName, args, {stdio: 'inherit'}); + } } /** @@ -195,3 +198,23 @@ function getClosestGitPath(currentPath) { return getClosestGitPath(nextPath); } + +/** + * Check if the file is executable + * + * @param {String} filePath + * @returns {Boolean} + */ +function isExecutable(filePath) { + return fs.lstatSync(filePath).isFile() && fsHelpers.isExecutable(filePath); +} + +/** + * Check if the file is a JavaScript file + * + * @param {String} filePath + * @returns {Boolean} + */ +function isJS(filePath) { + return fs.lstatSync(filePath).isFile() && path.extname(filePath) === '.js'; +} diff --git a/package.json b/package.json index 88676b0..f1acccb 100644 --- a/package.json +++ b/package.json @@ -36,8 +36,8 @@ }, "engine-strict": true, "scripts": { - "postinstall": "./bin/git-hooks --install", - "preuninstall": "./bin/git-hooks --uninstall", + "postinstall": "node ./bin/git-hooks --install", + "preuninstall": "node ./bin/git-hooks --uninstall", "test": "jscs . && jshint . && mocha --reporter spec --recursive tests", "coverage": "istanbul cover _mocha --recursive tests" }, diff --git a/tests/run.test.js b/tests/run.test.js index 972f54c..3e09372 100644 --- a/tests/run.test.js +++ b/tests/run.test.js @@ -149,5 +149,27 @@ describe('git-hook runner', function () { }); }); }); + + describe('and a hook is unexecutable but is a JavaScript file', function () { + var logFile = SANDBOX_PATH + 'hello.log'; + beforeEach(function () { + fs.writeFileSync(PROJECT_PRECOMMIT_HOOK + 'hello.js', 'echo "Hello, world! ${@:1}" > ' + logFile); + }); + + it('should pass all arguments to them', function (done) { + gitHooks.run(PRECOMMIT_HOOK_PATH, ['I', 'am', 'working', 'properly!'], function () { + fs.readFileSync(logFile).toString().should.equal('Hello, world! I am working properly!\n'); + done(); + }); + }); + + it('should run a hook with success status', function (done) { + gitHooks.run(PRECOMMIT_HOOK_PATH, [], function (code) { + code.should.equal(0); + fs.readFileSync(logFile).toString().should.equal('Hello, world! \n'); + done(); + }); + }); + }); }); }); From c6e71880e076970acdde590173f6a9aba7a1a073 Mon Sep 17 00:00:00 2001 From: xcatliu Date: Thu, 9 Nov 2017 17:31:45 +0800 Subject: [PATCH 2/4] Fix test error --- tests/run.test.js | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/tests/run.test.js b/tests/run.test.js index 3e09372..306cb03 100644 --- a/tests/run.test.js +++ b/tests/run.test.js @@ -153,20 +153,15 @@ describe('git-hook runner', function () { describe('and a hook is unexecutable but is a JavaScript file', function () { var logFile = SANDBOX_PATH + 'hello.log'; beforeEach(function () { - fs.writeFileSync(PROJECT_PRECOMMIT_HOOK + 'hello.js', 'echo "Hello, world! ${@:1}" > ' + logFile); - }); - - it('should pass all arguments to them', function (done) { - gitHooks.run(PRECOMMIT_HOOK_PATH, ['I', 'am', 'working', 'properly!'], function () { - fs.readFileSync(logFile).toString().should.equal('Hello, world! I am working properly!\n'); - done(); - }); + var content = 'var fs = require("fs"); ' + + 'fs.writeFileSync("' + logFile.replace(/\\/g, '\\\\') + '", "Hello, world!");'; + fs.writeFileSync(PROJECT_PRECOMMIT_HOOK + 'hello.js', content); }); it('should run a hook with success status', function (done) { gitHooks.run(PRECOMMIT_HOOK_PATH, [], function (code) { code.should.equal(0); - fs.readFileSync(logFile).toString().should.equal('Hello, world! \n'); + fs.readFileSync(logFile).toString().should.equal('Hello, world!'); done(); }); }); From 13000b90b383848219fc275867a98e5414b84510 Mon Sep 17 00:00:00 2001 From: xcatliu Date: Thu, 9 Nov 2017 18:13:48 +0800 Subject: [PATCH 3/4] Update spawnHook --- lib/git-hooks.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/lib/git-hooks.js b/lib/git-hooks.js index 3ada710..44cf6b5 100644 --- a/lib/git-hooks.js +++ b/lib/git-hooks.js @@ -166,10 +166,9 @@ function spawnHook(hookName, args) { args = args || []; if (isExecutable(hookName)) { return spawn(hookName, args, {stdio: 'inherit'}); - } else if (isJS(hookName)) { + } + if (isJS(hookName)) { return spawn('node', [hookName].concat(args), {stdio: 'inherit'}); - } else { - return spawn(hookName, args, {stdio: 'inherit'}); } } From 5d224c46d446799cd4c3797f633a9baa4c6ccb46 Mon Sep 17 00:00:00 2001 From: xcatliu Date: Fri, 10 Nov 2017 15:11:59 +0800 Subject: [PATCH 4/4] Add bash script support for windows --- lib/git-hooks.js | 15 ++++++++++++++- tests/run.test.js | 16 ++++++++++++++++ 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/lib/git-hooks.js b/lib/git-hooks.js index 44cf6b5..eb30f5f 100644 --- a/lib/git-hooks.js +++ b/lib/git-hooks.js @@ -114,7 +114,7 @@ module.exports = { return path.resolve(hooksDirname, hookName); }) .filter(function (hookPath) { - if (!isExecutable(hookPath) && !isJS(hookPath)) { + if (!isExecutable(hookPath) && !isJS(hookPath) && !isBash(hookPath)) { console.warn('[GIT-HOOKS WARNING] Non-executable file ' + hookPath + ' is skipped'); return false; } @@ -170,6 +170,9 @@ function spawnHook(hookName, args) { if (isJS(hookName)) { return spawn('node', [hookName].concat(args), {stdio: 'inherit'}); } + if (isBash(hookName)) { + return spawn('bash', [hookName].concat(args), {stdio: 'inherit'}); + } } /** @@ -217,3 +220,13 @@ function isExecutable(filePath) { function isJS(filePath) { return fs.lstatSync(filePath).isFile() && path.extname(filePath) === '.js'; } + +/** + * Check if the file is a bash script file + * + * @param {String} filePath + * @returns {Boolean} + */ +function isBash(filePath) { + return fs.lstatSync(filePath).isFile() && path.extname(filePath) === '.sh'; +} diff --git a/tests/run.test.js b/tests/run.test.js index 306cb03..0db9886 100644 --- a/tests/run.test.js +++ b/tests/run.test.js @@ -166,5 +166,21 @@ describe('git-hook runner', function () { }); }); }); + + describe('and a hook is unexecutable but is a bash script file', function () { + var logFile = SANDBOX_PATH + 'hello.log'; + beforeEach(function () { + var content = 'echo "Hello, world!" > ' + logFile.replace(/\\/g, '\\\\'); + fs.writeFileSync(PROJECT_PRECOMMIT_HOOK + 'hello.sh', content); + }); + + it('should run a hook with success status', function (done) { + gitHooks.run(PRECOMMIT_HOOK_PATH, [], function (code) { + code.should.equal(0); + fs.readFileSync(logFile).toString().should.equal('Hello, world!\n'); + done(); + }); + }); + }); }); });