Skip to content

Instantly share code, notes, and snippets.

@ThomasBurleson
Forked from mklabs/pre-commit
Created November 16, 2011 21:58
Show Gist options
  • Save ThomasBurleson/1371589 to your computer and use it in GitHub Desktop.
Save ThomasBurleson/1371589 to your computer and use it in GitHub Desktop.
run jshint as git/hg hooks, NO COMMIT IF NO LINT FREE.

Run jshint on changed files in the working directory, and prevent commits if no lint free.

git

To enable this hook, make this file executable by chmod +x .git/hooks/pre-commit.

http://progit.org/book/ch7-3.html

git init
curl https://raw.github.com/gist/1367701/pre-commit >> .git/hooks/pre-commit
chmod +x .git/hooks/pre-commit
git commit

hg

http://hgbook.red-bean.com/read/handling-repository-events-with-hooks.html#sec:hook:simple

hg init
mkdir .hg/hooks
curl https://raw.github.com/gist/1367701/pre-commit >> .hg/hooks/pre-commit
chmod +x .hg/hooks/pre-commit

echo '[hooks]' >> .hg/hgrc
echo 'pre-commit = ./.hg/pre-commit' >> .hg/hgrc
cat .hg/hgrc

hg commit

note: the hg hook for precommit is actually pre-commit, not precommit.

NO COMMIT IF NO LINT FREE.

#!/usr/bin/env node
// todo: try to require jshint here, instead of spawning process, then fallback to spawning process.
var jshint = nrequire('jshint');
if (jshint) return process.exit(0);
// jshint not installed locally, spawn process instead.
// basically the same, but less pretty.
var exec = require('child_process').exec;
// Get the list of changed files in working dir. command depends on __dirname
// where a path with `.git/` triggers the git command. otherwise hg.
// git: git status -s
// hg: hg status
var cmd = /\.git\//.test(__dirname) ? 'git status -s' : 'hg status'
exec(cmd, function(err, stdout) {
if(err) return error(err);
var changed = (stdout.match(/^\s?M\s(.+)/gim) || []).map(function(file) {
return file.trim().replace(/^M\s?/, '');
});
if(!changed.length) return process.exit(0);
console.log('Running jshint on', changed.length, 'files');
exec('jshint ' + changed.join(' '), function(err, stdout) {
if(err) return error(stdout);
console.log(stdout);
process.exit(0);
});
});
function nrequire(m) {
var n;
try { n = require(m); }
catch(e) { console.log('please, install ' + m + ' locally to be able to use it programmatically. will spawn process instead. \n'); }
return n;
}
function error(err) {
if(!(err instanceof Error)) err = new Error(err);
console.error(err.message || err.stack);
process.exit(1);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment