Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
node_modules
npm-debug.log
coverage
.nyc_output
.tern-port
11 changes: 10 additions & 1 deletion hook
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,15 @@ elif [[ -x "$LOCAL" ]]; then
BINARY="$LOCAL"
fi

#
# Run from the repository root so `require.resolve('pre-commit')` works for Yarn PnP,
# and GUI git clients that invoke hooks with an unexpected cwd still resolve deps.
#
REPO_ROOT="$(git rev-parse --show-toplevel 2>/dev/null)" || REPO_ROOT=""
if [[ -n "$REPO_ROOT" ]]; then
cd "$REPO_ROOT" || exit 1
fi

#
# Add --dry-run cli flag support so we can execute this hook without side effects
# and see if it works in the current environment
Expand All @@ -46,5 +55,5 @@ if [[ $* == *--dry-run* ]]; then
exit 1
fi
else
"$BINARY" "$("$BINARY" -e "console.log(require.resolve('pre-commit'))")"
exec "$BINARY" "$("$BINARY" -e "console.log(require.resolve('pre-commit'))")"
fi
22 changes: 18 additions & 4 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,16 @@
'use strict';

//
// cross-spawn.spawnSync returns the same shape as child_process.spawnSync
// (`status`, not `code`).
//
function failedSpawn(result) {
if (!result) return true;
if (result.error) return true;
if (result.signal) return true;
return result.status !== 0;
}

var spawn = require('cross-spawn')
, which = require('which')
, path = require('path')
Expand Down Expand Up @@ -173,8 +184,8 @@ Hook.prototype.initialize = function initialize() {
this.root = this.exec(this.git, ['rev-parse', '--show-toplevel']);
this.status = this.exec(this.git, ['status', '--porcelain']);

if (this.status.code) return this.log(Hook.log.status, 0);
if (this.root.code) return this.log(Hook.log.root, 0);
if (failedSpawn(this.status)) return this.log(Hook.log.status, 0);
if (failedSpawn(this.root)) return this.log(Hook.log.root, 0);

this.status = this.status.stdout.toString().trim();
this.root = this.root.stdout.toString().trim();
Expand Down Expand Up @@ -229,8 +240,11 @@ Hook.prototype.run = function runner() {
env: process.env,
cwd: hooked.root,
stdio: [0, 1, 2]
}).once('close', function closed(code) {
if (code) return hooked.log(hooked.format(Hook.log.failure, script, code));
}).once('close', function closed(code, signal) {
var exitCode = typeof code === 'number' ? code : (signal ? 1 : 0);
if (exitCode !== 0) {
return hooked.log(hooked.format(Hook.log.failure, script, exitCode));
}

again(scripts);
});
Expand Down
35 changes: 20 additions & 15 deletions install.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,17 @@ var fs = require('fs')
, path = require('path')
, os = require('os')
, hook = path.join(__dirname, 'hook')
, hookAbs = path.resolve(hook)
, root = path.resolve(__dirname, '..', '..')
, exists = fs.existsSync || path.existsSync;

//
// POSIX single-quoted string for embedding paths in generated shell scripts.
//
function shellSingleQuote(str) {
return '\'' + str.replace(/'/g, '\'\\\'\'') + '\'';
}

//
// Gather the location of the possible hidden .git directory, the hooks
// directory which contains all git hooks and the absolute location of the
Expand Down Expand Up @@ -45,10 +53,10 @@ function getGitFolderPath(currentPath) {
//
// Resolve git directory for submodules
//
if (exists(git) && fs.lstatSync(git).isFile()) {
if (git && exists(git) && fs.lstatSync(git).isFile()) {
var gitinfo = fs.readFileSync(git).toString()
, gitdirmatch = /gitdir: (.+)/.exec(gitinfo)
, gitdir = gitdirmatch.length == 2 ? gitdirmatch[1] : null;
, gitdir = gitdirmatch && gitdirmatch.length === 2 ? gitdirmatch[1].trim() : null;

Comment thread
3rd-Eden marked this conversation as resolved.
Outdated
if (gitdir !== null) {
git = path.resolve(root, gitdir);
Expand Down Expand Up @@ -92,20 +100,17 @@ if (exists(precommit) && !fs.lstatSync(precommit).isSymbolicLink()) {
try { fs.unlinkSync(precommit); }
catch (e) {}

// Create generic precommit hook that launches this modules hook (as well
// as stashing - unstashing the unstaged changes)
// TODO: we could keep launching the old pre-commit scripts
var hookRelativeUnixPath = hook.replace(root, '.');

if(os.platform() === 'win32') {
hookRelativeUnixPath = hookRelativeUnixPath.replace(/[\\\/]+/g, '/');
// Delegate to this package's `hook` script using an absolute path so Yarn Plug'n'Play
// and other layouts without `node_modules/pre-commit` still work. The hook script
// changes to the git root before resolving `pre-commit` via Node.
//
var hookLauncher = hookAbs;
if (os.platform() === 'win32') {
hookLauncher = hookLauncher.replace(/\\/g, '/');
}

var precommitContent = '#!/usr/bin/env bash' + os.EOL
+ hookRelativeUnixPath + os.EOL
+ 'RESULT=$?' + os.EOL
+ '[ $RESULT -ne 0 ] && exit 1' + os.EOL
+ 'exit 0' + os.EOL;
+ 'exec bash ' + shellSingleQuote(hookLauncher) + ' "$@"' + os.EOL;

//
// It could be that we do not have rights to this folder which could cause the
Expand All @@ -121,10 +126,10 @@ catch (e) {
console.error('pre-commit:');
}

try { fs.chmodSync(precommit, '777'); }
try { fs.chmodSync(precommit, 0o755); }
catch (e) {
console.error('pre-commit:');
console.error('pre-commit: chmod 0777 the pre-commit file in your .git/hooks folder because:');
console.error('pre-commit: chmod 0755 the pre-commit file in your .git/hooks folder because:');
console.error('pre-commit: '+ e.message);
console.error('pre-commit:');
}
Loading