最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Running grunt-contrib-jshint only on recently modified files - Stack Overflow

programmeradmin3浏览0评论

We're going through refactoring the code on a very large site. I would like to enforce linting on any files that get changed, but ignore the rest (as many of them will end up being removed so it's a waste of time to tidy them up).

I would like to have a grunt task that checks that a file's modified date is more recent than its created (*fetched from repo) date and lints it if this is the case (would be good also to have grunt update a json list of files to be linted).

I haven't used node much apart from grunt and its plugins. I'm going to use as a starting point, but could someone sketch out for me how I might approach writing this task, in particular any considerations to do with asynchronisity.

We're going through refactoring the code on a very large site. I would like to enforce linting on any files that get changed, but ignore the rest (as many of them will end up being removed so it's a waste of time to tidy them up).

I would like to have a grunt task that checks that a file's modified date is more recent than its created (*fetched from repo) date and lints it if this is the case (would be good also to have grunt update a json list of files to be linted).

I haven't used node much apart from grunt and its plugins. I'm going to use http://gruntjs./creating-tasks as a starting point, but could someone sketch out for me how I might approach writing this task, in particular any considerations to do with asynchronisity.

Share Improve this question asked Jul 9, 2013 at 15:05 wheresrhyswheresrhys 23.6k21 gold badges96 silver badges165 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 10

A couple options:

1 - You can use a custom filter function to filter the list of files returned by your jshint file pattern. Something like this:

module.exports = function(grunt) {
  var fs = require('fs');

  var myLibsPattern = ['./mylibs/**/*.js'];

  // on linux, at least, ctime is not retained after subsequent modifications,
  // so find the date/time of the earliest-created file matching the filter pattern
  var creationTimes = grunt.file.expand( myLibsPattern ).map(function(f) { return new Date(fs.lstatSync(f).ctime).getTime() });
  var earliestCreationTime = Math.min.apply(Math, creationTimes);
  // hack: allow for 3 minutes to check out from repo
  var filterSince = (new Date(earliestCreationTime)).getTime() + (3 * 60 * 1000);

  grunt.initConfig({
    options: {
      eqeqeq: true,
      eqnull: true
    },
    jshint: {
      sincecheckout: {
        src: myLibsPattern,
        // filter based on whether it's newer than our repo creation time
        filter: function(filepath) {
          return (fs.lstatSync(filepath).mtime > filterSince);
        },
      },
    },
  });

  grunt.loadNpmTasks('grunt-contrib-jshint');
  grunt.registerTask('default', ['jshint']);
};

2 - use the grunt-contrib-watch plugin to detect when files are changing. Then you can read the list of files from the event, as described in this ment by Kyle Robinson Young ("shama"):

grunt.initConfig({
  watch: {
    all: {
      files: ['<%= jshint.all.src %>'],
      tasks: ['jshint'],
      options: { nospawn: true }
    }
  },
  jshint: { all: { src: ['Gruntfile.js', 'lib/**/*.js'] } }
});
// On watch events, inject only the changed files into the config
grunt.event.on('watch', function(action, filepath) {
  grunt.config(['jshint', 'all', 'src'], [filepath]);
});

This doesn't exactly meet your requirements since it depends on having the watch running as soon as you start modifying files, but it might fit better with the overall Grunt approach.

See also this question but beware some of it relates to older version of Grunt and to coffeescript.

UPDATE: there's now a grunt-newer plugin which handles all this in a more elegant way

Use grunt-newer for this. It is especially made to configure Grunt tasks to run with newer files only.

Example:

grunt.initConfig({
  jshint: {
    options: {
      jshintrc: '.jshintrc'
    },
    all: {
      src: 'src/**/*.js'
    }
  }
});

grunt.loadNpmTasks('grunt-contrib-jshint');
grunt.loadNpmTasks('grunt-newer');

grunt.registerTask('lint', ['newer:jshint:all']);
发布评论

评论列表(0)

  1. 暂无评论