Skip to content

Commit

Permalink
Better jshint hook
Browse files Browse the repository at this point in the history
  • Loading branch information
cristirusu committed Jul 24, 2017
1 parent 7d7c91d commit a5f8a44
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 218 deletions.
229 changes: 33 additions & 196 deletions contrib/pre-commit-js
Original file line number Diff line number Diff line change
@@ -1,199 +1,36 @@
#!/usr/bin/env node
#!/bin/sh

'use strict';

var child = require('child_process');

//
// Get the root of the repository.
//
child.exec('git status --porcelain', function changes(err, status) {
if (err) {
console.error('pre-commit: Failed to find git root. Cannot run the tests.');
return process.exit(1);
}

child.exec('git rev-parse --show-toplevel', run.bind(null, status));
});

/**
* You've failed on some of the scripts, output how much you've sucked today.
*
* @param {Error} err The actual error.
* @api private
*/
function failure(err) {
console.error('');
console.error('pre-commit: You\'ve failed to pass all the hooks.');
console.error('pre-commit:');

if (err.ran) {
console.error('pre-commit: The "npm run '+ err.ran +'" script failed.');
} else {
var stack = err.stack.split('\n')
console.error('pre-commit: An Error was thrown: '+ stack.shift());
console.error('pre-commit:');
stack.forEach(function trace(line) {
console.error('pre-commit: '+ line.trim());
});
}
console.error('pre-commit:');
console.error('pre-commit: You can skip the git pre-commit hook by running:');
console.error('pre-commit:');
console.error('pre-commit: git commit -n (--no-verify)');
console.error('pre-commit:');
console.error('pre-commit: But this is not adviced as your tests are obviously failing.');
console.error('');
process.exit(1);
command -v jshint >/dev/null 2>&1 || { # http://tldp.org/LDP/abs/html/io-redirection.html
echo >&2 "\033[1mJSHint is not installed. Please install it using \033[41mnpm install -g jshint\033[0m.";
exit 1;
}

/**
* Run the set pre-commit hooks.
*
* @param {Error} err The error that happend while executing the command.
* @param {Error} output The output of rev-parse.
* @api private
*/
function run(status, err, output) {
if (err) {
console.error('');
console.error('pre-commit: Failed to find git root. Cannot run the tests.');
console.error('');
return process.exit(1);
}

//
// Check if there are scripts specified that we need to run.
//
var root = output.trim()
, run = []
, hasPreCommit = false
, silent
, pkg
, commit_template
, commit_template_cmd;

//
// Bail-out when we failed to parse the package.json, there is probably a some
// funcky chars in there.
//
try { pkg = require(root +'/package.json'); }
catch (e) { return failure(e); }

silent = pkg['pre-commit.silent'] || false;

if (!status.trim().length) {
if (!silent) {
console.log('');
console.log('pre-commit: No changes detected, bailing out.');
console.log('');
}
return;
}

if (!pkg.scripts) {
if (!silent) {
console.log('');
console.log('pre-commit: No scripts detected in the package.json, bailing out.');
console.log('');
}
return;
}

//
// If there's a `pre-commit` property in the package.json we should use that
// array.
//
if (pkg['pre-commit'] && Array.isArray(pkg['pre-commit'])) {
hasPreCommit = true;
run = pkg['pre-commit'];
}
//
// configure commit.template in git if we are asked to do so
//
commit_template = pkg['pre-commit.commit-template'];

if (commit_template) {
commit_template_cmd = 'git config commit.template "' + commit_template + '"';
child.exec(commit_template_cmd, [], function exec(error, stdout, stderr) {
if (error) { //it is better to write this even if we are 'silent'
stderr.write('pre-commit: ' + commit_template_cmd + ' failed\n');
}
});
}

//
// If we don't have any run processes to run try to see if there's a `test`
// property which we should run instead. But we should check if it's not the
// default value that `npm` adds when your run the `npm init` command.
//
if (
!hasPreCommit
&& !run.length
&& pkg.scripts.test
&& pkg.scripts.test !== 'echo "Error: no test specified" && exit 1'
) {
run.push('test');
}

//
// Bailout if we don't have anything to run.
//
if (!run.length) {
if (!silent) {
console.log('');
console.log('pre-commit: Nothing to run. Bailing out.');
console.log('');
}
return;
}

//
// Behold, a lazy man's async flow control library;
//
(function runner(done) {
(function next(err, task) {
//
// Bailout when we received an error. This will make sure that we don't
// run the rest of the tasks.
//
if (err) {
err = new Error(err.message);
err.ran = task;
return done(err);
}

// Check if we have tasks to be executed or if we are complete.
task = run.shift();
if (!task) return done();

var args = ['run', task];

if (silent) {
args.push('--silent');
}

var npm = child.spawn('npm', args, {
cwd: root, // Make sure that we spawn it in the root of repo.
env: process.env, // Give them the same ENV variables.
stdio: [0, 1, 2] // Pipe all the things.
});

//
// Check the close code to see if we passed or failed.
//
npm.on('close', function close(code) {
if (code !== 0) return next(new Error(task +' closed with code '+ code), task);

next(undefined, task);
});
})();
})(function ready(err) {
if (err) return failure(err);

//
// Congratulation young padawan, all hooks passed.
//
process.exit(0);
});
}
files=$(git diff --name-only --cached | grep "\.js$") # use --cached because we run this after 'git add'; js files only.

if [ "$files" = "" ]; then
echo "No files found. Exiting.";
exit 0;
fi

pass=true;

echo "\n\033[1mRunning JSHint on the following scripts:\n"
for file in ${files}; do
result=$(jshint ${file})
if [ "$result" != "" ]; then
echo "\t\033[31m \xE2\x9C\x97 Fail \t\033[0m $file";
echo "$result"; # quotes to preserve newlines
pass=false;
else
echo "\t\033[32m \xE2\x9C\x93 OK \t\t\033[0m $file";
fi
done

echo "\n\033[1mJSHint check complete.\n";

if ! $pass; then
echo "\033[41mCOMMIT FAILED:\033[0m \t\033[31mJSHint found errors or potential problems in your JavaScript code. Please review these files before committing.\033[0m\n";
exit 1;
else
echo "\033[42mCOMMIT SUCCESFULL\033[0m\n";
fi
22 changes: 0 additions & 22 deletions package.json

This file was deleted.

0 comments on commit a5f8a44

Please sign in to comment.