git pre-commit hook that lints js code
authorAleksander Łukasz <aleksander.lukasz@nowoczesnapolska.org.pl>
Tue, 15 Jul 2014 10:18:53 +0000 (12:18 +0200)
committerAleksander Łukasz <aleksander.lukasz@nowoczesnapolska.org.pl>
Tue, 15 Jul 2014 13:27:27 +0000 (15:27 +0200)
Installation:

$ npm install
$ grunt githooks

Gruntfile.js
package.json
pre-commit.template.js [new file with mode: 0644]

index 05c4483..8417c15 100644 (file)
@@ -2,9 +2,9 @@
 
 module.exports = function(grunt) {
     'use strict';
 
 module.exports = function(grunt) {
     'use strict';
-
     var build_output_dir = grunt.option('output-dir') || 'build',
     var build_output_dir = grunt.option('output-dir') || 'build',
-        less_files = {};
+        less_files = {},
+        jshint_targets = grunt.option('jshint-targets');
 
     less_files[build_output_dir + '/rng.css'] = 'src/editor/styles/main.less';
 
 
     less_files[build_output_dir + '/rng.css'] = 'src/editor/styles/main.less';
 
@@ -39,7 +39,7 @@ module.exports = function(grunt) {
             },
         },
         jshint: {
             },
         },
         jshint: {
-            all: ['Gruntfile.js', 'src/**/*.js'],
+            all: jshint_targets ? jshint_targets.split(',') : ['Gruntfile.js', 'src/**/*.js'],
             options: {
                 jshintrc: '.jshintrc'
             }
             options: {
                 jshintrc: '.jshintrc'
             }
@@ -50,6 +50,18 @@ module.exports = function(grunt) {
               {src: ['libs/bootstrap/img/**'], dest: build_output_dir+'/'},
             ]
           }
               {src: ['libs/bootstrap/img/**'], dest: build_output_dir+'/'},
             ]
           }
+        },
+        githooks: {
+            all: {
+                options: {
+                    dest: grunt.option('git-hooks-dir') || '.git/hooks',
+                },
+                'pre-commit': {
+                    taskNames: ['lint'],
+                    args: '--no-color',
+                    template: 'pre-commit.template.js'
+                }
+            }
         }
     });
 
         }
     });
 
@@ -57,6 +69,7 @@ module.exports = function(grunt) {
     grunt.loadNpmTasks('grunt-contrib-less');
     grunt.loadNpmTasks('grunt-contrib-jshint');
     grunt.loadNpmTasks('grunt-contrib-copy');
     grunt.loadNpmTasks('grunt-contrib-less');
     grunt.loadNpmTasks('grunt-contrib-jshint');
     grunt.loadNpmTasks('grunt-contrib-copy');
+    grunt.loadNpmTasks('grunt-githooks');
 
     grunt.registerTask('build', ['requirejs', 'less:production', 'copy:resources']);
     grunt.registerTask('lint', ['jshint']);
 
     grunt.registerTask('build', ['requirejs', 'less:production', 'copy:resources']);
     grunt.registerTask('lint', ['jshint']);
index a72c0f6..1517354 100644 (file)
@@ -6,6 +6,7 @@
     "grunt-contrib-requirejs": "~0.4.1",
     "grunt-contrib-less": "~0.8.3",
     "grunt-contrib-jshint": "~0.7.2",
     "grunt-contrib-requirejs": "~0.4.1",
     "grunt-contrib-less": "~0.8.3",
     "grunt-contrib-jshint": "~0.7.2",
-    "grunt-contrib-copy": "~0.4.1"
+    "grunt-contrib-copy": "~0.4.1",
+    "grunt-githooks": "~0.3.1"
   }
 }
   }
 }
diff --git a/pre-commit.template.js b/pre-commit.template.js
new file mode 100644 (file)
index 0000000..2f0363b
--- /dev/null
@@ -0,0 +1,22 @@
+/* jshint node: true */
+'use strict';
+
+var exec = require('child_process').exec;
+var fs = require('fs');
+
+exec('git diff --cached --name-status', function (err, stdout) {
+    void(err);
+    var toLint = [];
+    stdout.split('\n').forEach(function(line) {
+        var filePath = line.split('\t')[1];
+        if(filePath && filePath.substr(-3) === '.js' && fs.existsSync(filePath)) {
+            toLint.push(filePath);
+        }
+    });
+    if(toLint.length) {
+        exec('grunt {{task}} {{args}} --jshint-targets=' + toLint.join(','), function (err, stdout) {
+            console.log(stdout);
+            process.exit(err ? -1 : 0);
+        });
+    }
+});