.githooks.js.hbs 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. var exec = require('sync-exec');
  2. var exit = 0;
  3. var glob = require("glob");
  4. var globOptions = {
  5. ignore: [
  6. 'bower_components/**/*',
  7. 'node_modules/**/*'
  8. ]
  9. };
  10. var pkg = require('../../package');
  11. // Change to \{{ hook }} once that variable is available.
  12. // @see https://github.com/wecodemore/grunt-githooks/pull/40
  13. var hooks = pkg.githooks && pkg.githooks['{{ task }}'];
  14. if (hooks) {
  15. var ret, hook, files, commands, staged, matchAll;
  16. var filesMatched = [];
  17. // Iterate over all hook definitions.
  18. for (var h in hooks) {
  19. hook = hooks[h];
  20. commands = hook.commands || [];
  21. staged = hook.staged === void 0 ? false : !!hook.staged;
  22. matchAll = hook.matchAll === void 0 ? true : !!hook.matchAll;
  23. // Iterate over all files in a hook definition.
  24. if (hook.files) {
  25. // Expand all file paths using glob (for pattern matching).
  26. if (typeof hook.files === 'string') {
  27. files = glob.sync(hook.files, globOptions) || [];
  28. }
  29. if (Array.isArray(hook.files)) {
  30. files = [];
  31. for (var f = 0; f < hook.files.length; f++) {
  32. files = [].concat(files, glob.sync(hook.files[f], globOptions) || []);
  33. }
  34. }
  35. // All files must either be staged or modified for the entire
  36. // hook definition command(s) to be executed.
  37. for (f in files) {
  38. var file = files[f];
  39. if (file) {
  40. // Only continue if file has been staged or modified.
  41. ret = exec((staged ? 'git diff --name-only --cached ' + file : 'git diff HEAD@{1} --stat -- ' + file));
  42. exit = ret.status;
  43. if (exit === 0 && ret.stdout !== '') {
  44. filesMatched.push(file);
  45. }
  46. else if (matchAll && (exit > 0 || ret.stdout === '')) {
  47. console.log(ret.stdout);
  48. filesMatched = [];
  49. break;
  50. }
  51. }
  52. }
  53. }
  54. // Iterate over all commands that should be executed for matched files.
  55. if (filesMatched.length) {
  56. if (typeof commands === 'string') {
  57. commands = [commands];
  58. }
  59. for (var c in commands) {
  60. var command = commands[c];
  61. console.log("\033[4;35mgit: {{ task }}\033[0;35m\n>> " + command + "\033[0m\n");
  62. ret = exec(command);
  63. console.log(ret.stdout);
  64. exit = ret.status;
  65. if (exit > 0) {
  66. break;
  67. }
  68. }
  69. }
  70. // Display any errors.
  71. if (exit > 0 && ret && ret.stderr) {
  72. console.log(ret.stderr);
  73. }
  74. }
  75. }
  76. process.exit(exit);