Git Product home page Git Product logo

grunt-newer's Introduction

grunt-newer

Configure Grunt tasks to run with newer files only.

Synopsis: The newer task will configure another task to run with src files that are a) newer than the dest files or b) newer than the last successful run (if there are no dest files). See below for examples and more detail.

Getting Started

This plugin requires Grunt ~0.4.1

If you haven't used Grunt before, be sure to check out the Getting Started guide, as it explains how to create a gruntfile.js as well as install and use Grunt plugins. Once you're familiar with that process, you may install this plugin with this command:

npm install grunt-newer --save-dev

Once the plugin has been installed, it may be enabled inside your gruntfile.js with this line:

grunt.loadNpmTasks('grunt-newer');

The newer task

The newer task doesn't require any special configuration. To use it, just add newer as the first argument when running other tasks.

For example, if you want to use Uglify to minify your source files only when one or more of them is newer than the previously minified destination file, configure the uglify task as you would otherwise, and then register a task with newer at the front.

  grunt.initConfig({
    uglify: {
      all: {
        files: {
          'dest/app.min.js': ['src/**/*.js']
        }
      }
    }
  });

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

  grunt.registerTask('minify', ['newer:uglify:all']);

With the above configuration the minify task will only run uglify if one or more of the src/**/*.js files is newer than the dest/app.min.js file.

The above example shows how the newer task works with other tasks that specify both src and dest files. In this case, the modification time of src files are compared to modification times of corresponding dest files to determine which src files to include.

The newer task can also be used with tasks that don't generate any dest files. In this case, newer will only use files that are newer than the last successful run of the same task.

For example, if you want to run JSHint on only those files that have been modified since the last successful run, configure the jshint task as you would otherwise, and then register a task with newer at the front.

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

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

  grunt.registerTask('lint', ['newer:jshint:all']);

With the above configuration, running grunt lint will configure your jshint:all task to use only files in the jshint.all.src config that have been modified since the last successful run of the same task. The first time the jshint:newer:all task runs, all source files will be used. After that, only the files you modify will be run through the linter.

Another example is to use the newer task in conjunction with watch. For example, you might want to set up a watch to run a linter on all your .js files whenever one changes. With the newer task, instead of re-running the linter on all files, you only need to run it on the files that changed.

  var srcFiles = 'src/**/*.js';

  grunt.initConfig({
    jshint: {
      all: {
        src: srcFiles
      }
    },
    watch: {
      all: {
        files: srcFiles,
        tasks: ['newer:jshint:all']
      }
    }
  });

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

With the above configuration, running grunt jshint watch will first lint all your files with jshint and then set up a watch. Whenever one of your source files changes, the jshint task will be run on just the modified file.

Note: If your task is configured with dest files, newer will run your task with only those files that are newer than the corresponding dest files.

Options for the newer task

In most cases, you shouldn't need to add any special configuration for the newer task. Just grunt.loadNpmTasks('grunt-newer') and you can use newer as a prefix to your other tasks. The options below are available for advanced usage.

  • type: string
  • default: node_modules/grunt-newer/.cache

To keep track of timestamps for successful runs, the newer task writes to a cache directory. The default is to use a .cache directory within the grunt-newer installation directory. If you need timestamp info to be written to a different location, configure the task with a cache option.

Example use of the cache option:

  grunt.initConfig({
    newer: {
      options: {
        cache: 'path/to/custom/cache/directory'
      }
    }
  });
  • type: function(Object, function(boolean))
  • default: null

The newer task determines which files to include for a specific task based on file modification time. There are occassions where you may want to include a file even if it has not been modified. For example, if a LESS file imports some other files, you will want to include it if any of the imports have been modified. To support this, you can provide an override function that takes two arguments:

  • details - Object
    • task - string The currently running task name.
    • target - string The currently running target name.
    • path - string The path to a src file that appears to be "older" (not modified since the time below).
    • time - Date The comparison time. For tasks with dest files, this is the modification time of the dest file. For tasks without dest files, this is the last successful run time of the same task.
  • include - function(boolean) A callback that determines whether this src file should be included. Call with true to include or false to exclude the file.

Example use of the override option:

  grunt.initConfig({
    newer: {
      options: {
        override: function(detail, include) {
          if (detail.task === 'less') {
            checkForModifiedImports(detail.path, detail.time, include);
          } else {
            include(false);
          }
        }
      }
    }
  });
  • type: number (milliseconds)
  • default: 0

The newer tasks compares the file modification times of the source and destination files with millisecond precision. On some file systems this causes destination files to always be considered older because of imprecision in the registration of modification times.

If your tasks are always run even though the source files are not modified use the tolerance option to compensate for this imprecision.

In most cases setting the option to 1000 milliseconds should be enough. If the file system is very imprecise use a higher value.

Example use of the tolerance option:

  grunt.initConfig({
    newer: {
      options: {
        tolerance: 1000
      }
    }
  });

That's it

Please submit an issue if you encounter any trouble. Contributions or suggestions for improvements welcome!

Current Status

Known limitations

The newer task relies on Grunt's convention for specifying src/dest mappings. So it should be expected to work with two types of tasks:

  1. Tasks that specify both src and dest files. In this case, the task prefixed by newer will be configured to run with src files that are newer than the corresponding dest file (based on the mtime of files).

  2. Tasks that specify only src files. In this case, the task prefixed by newer will be configured to run with src files that are newer than the previous successful run of the same task.

The newer task will not work as a prefix for the following tasks:

  • grunt-rsync - Though this task specifies src and dest files, the dest file is not generated based on src files (instead it is a directory).

grunt-newer's People

Contributors

danez avatar greenkeeperio-bot avatar jorrit avatar malys avatar ruslansagitov avatar steveoh avatar tschaub avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

grunt-newer's Issues

`timestamps` option not remembered

It seems like the timestamps setting reverts back to the default path after the first use of newer:

In the same task run:

Running "newer-timestamp:jsbeautifier:build:tmp/.cache" (newer-timestamp) task

then

Running "newer-timestamp:gluejs:test:/Users/<user>/<project>/node_modules/grunt-newer/.cache" (newer-timestamp) task

How do I use this with the `usemin` task?

Can someone please tell me how to use grunt-newer with the usemin task? This is what my Gruntfile has:

213     // Reads HTML for usemin blocks to enable smart builds that automatically
214     // concat, minify and revision files. Creates configurations in memory so
215     // additional tasks can operate on them
216     useminPrepare: {
217       html: '<%= yeoman.app %>/index.html',
218       options: {
219         dest: 'www',
220         flow: {
221           html: {
222             steps: {
223               js: ['concat', 'uglifyjs'],
224               css: ['cssmin']
225             },
226             post: {}
227           }
228         }
229       }
230     },
231 
232     // Performs rewrites based on the useminPrepare configuration
233     usemin: {
234       html: ['www/**/*.html'],
235       css: ['www/<%= yeoman.styles %>/**/*.css'],
236       options: {
237         assetsDirs: ['www']
238       }
239     },

Thanks

grunt-tslint runs again all the files with newer

My grunt-ts config:

        tslint: {
            options: {
                configuration: grunt.file.readJSON("tslint.json")
            },
            all: {
                src: ["app.ts", "**/*.ts", "!node_modules/**/*.ts"]
            }
        },

If I run newer:tslint:all in my watch task, it still runs again all the ts files.

Not working with grunt-contrib-imagemin

Given that it works with other contrib plugins, like copy and uglify, it would be great if it worked with imagemin.

Here's my imagemin config:

    imagemin: {
        main: {
        files: [{
          expand: true,
          cwd: 'Source/',
          src: ['**/*.{png,jpg,gif}'],
          dest: 'Runtime/'
        }]
      }
    },

and my registerTask:

grunt.registerTask('build', ['gitinfo','newer:copy','any-newer:uglify','any-newer:concat','any-newer:cssmin','usemin','newer:imagemin:main']);

Thanks.

How to configure the task to check just the saved file?

My task is running all files every time I save a ts file, I'd like to run just saved file

 watch: {
      ts: {
        files: ['app/**/*.ts'],
        tasks: ['newer:tslint:all','newer:ts:default'],
        options: {
          spawn: false
        }
      },
 ...
 }

 // Typescript settings for grunt-ts
    ts: {
      default: {
        src: ['app/scripts/app.ts', '!node_modules/**/*.ts'],
        option: {
          target: 'es5',
          fast: 'never',
          sourceMap: true,
          module: 'amd'
        }
      },
      build: {
        src: ['app/scripts/app.ts', '!node_modules/**/*.ts'],
        out: "app/roamdash2.js",
        options: {
          target: "es5",  
            sourceMap: false,
            module: "amd"
        }
      }
    },

    //definitelytyped tsd settings for grunt-tsd
    tsd: {
      refresh: {
        options: {
          //execute a command
          command: 'reinstall',
          //optional: always get from HEAD
          latest: true,
          //specify config file
          config: 'tsd.json'
        }
      }
    },

    // Make sure code styles are up to par and there are no obvious mistakes    
    tslint: {
        options: {
            configuration: grunt.file.readJSON("tslint.json")
        },
        all: {
            src: ["app/scripts/**/*.ts", "!node_modules/**/*.ts", "!obj/**/*.ts", "!typings/**/*.ts"] 
            // avoid linting typings files and node_modules files
        }
    },

the ts task, run correctly compiling just the js file, but tslint check all files.

Support full spectrum of ways to specify files in grunt config

I found grunt-newer worked if I did

        // JSHint checking of the JS app files
        jshint :
        {
            all : {
                files : ['Gruntfile.js', 'media/js/app/**/*.js'],
            },
            options : {
                jshintrc : '.jshintrc'
            }
        },

but not for

        // JSHint checking of the JS app files
        jshint :
        {
            all : ['Gruntfile.js', 'media/js/app/**/*.js'],
            options : {
                jshintrc : '.jshintrc'
            }
        },

It seems to only understand one syntax for files but grunt supports multiple ways of specifying.

Refs #39

Include all 'src's per src-dest file mapping if any of the src newer

I am not sure how to title this but in multiple src-dest file mappings, each mapping might have multiple src's, when any of the src is newer, I want all the src's to be included.

I already test this with Grunt Files Object Format and Files Array Format.

This inclusion is useful for task that may compile/concatenate multiple src files like concat, uglify and less.

Consider this:

less: {
    options: {
        paths: [
            'app/bower_components/bootstrap/less'
        ]
    },
    files: {
        'app/styles/bootstrap.css': [
            'app/styles/bootstrap/variables.less',
            'app/styles/bootstrap/bootstrap.less',
            'app/styles/bootstrap/theme.less'
        ],
        'app/styles/main.css': [
            'app/styles/main.less'
        ]
    }
}

If variables.less was modified, newer should include all the 3 files instead of just variables.less so less will compile properly to the dest bootstrap.css.

Currently this is the newer output to the less:

    files: {
        'app/styles/bootstrap.css': [
            'app/styles/bootstrap/variables.less'
        ]
    }

But I expect to have this:

    files: {
        'app/styles/bootstrap.css': [
            'app/styles/bootstrap/variables.less',
            'app/styles/bootstrap/bootstrap.less',
            'app/styles/bootstrap/theme.less'
        ]
    }

I try to use wildcard but it produce the same:

    files: {
        'app/styles/bootstrap.css': [
            'app/styles/bootstrap/*.less'
        ],
        'app/styles/main.css': [
            'app/styles/main.less'
        ]
    }

Personally I see this is must have option unless I use it only for jshint or copy task.

I think if we have this option, we can use this as workaround to other dependencies issue related to @import for less, scss or stylus by adding all the includes into the src's.

Plugin don't see the New files for - "Tasks that specify only "src" files"

imagemin: {
        all: {
            files: [{
                expand: true,
                cwd: 'images/',
                src: '**/*.{gif,png,jpg,jpeg}',
                dest: 'images/'
            }]
        }
    }

After first run(when the cache has been created), the grunt-newer don't see NEW added images in images/ folder:). It sees only changed images...
I have such feeling that the plugin is do not stores src's folder files list in plugin's cache...

Support to define custom caching decision to skip task

Hi,

in our project, there is atm a mixture of another build tool and grunt.
The other build tool is called with shell:ant task.

It would be very cool to give a custom decision to cache or not to cache,
at simplest to explicitly name the files to decide to cache or not.

e.g. something like:

newer : {
antCache: ['folderOne/*/']
}

registerTask("cacheAnt", "newer:antCache:shell:ant")

Does this make sense to you?

LESSLint : Always linting full file stack.

Each time a change happens to a less file, the entirety of the files are ran through the linter.

I have tried with/without the spawn/cwd options on the watch.

Ideas? Thanks.

Snipped - watch block.

watch: {
    lesslint: {
            files: [
                      '<%= codebase %>**/_less/*.less',
                      '!<%= codebase %><%= bootstrap %>_less/**/*.less'
                    ],
            tasks: [ 'newer:lesslint:module' ],
            options: {
                spawn: false,
                cwd: '<%= codebase %>'
        }
    },
}

Snipped - lesslint block.

lesslint: {
      module: {
        src: [
                '<%= codebase %>**/_less/*.less',
                '!<%= codebase %><%= bootstrap %>_less/**/*.less'
              ],
      },
      imports: {
        src: [ '<%= codebase %><%= bootstrap %>_less/imports.less' ]
      }
    },

Updates timestamp though task has failed when running from Netbeans/Webstorm

Many IDEs today have simple integration with grunt. When running task like 'newer:jshint:files' from Netbeans or Webstorm, grunt-newer writes timestamp in his cache directory though jshint task failed due to errors and task newer-post hasn't run.

When running from OS shell the same task it works properly, and timestamp doesn't get overwritten when it shouldn't.

I cannot force other people from project's team to use it from separate console because it's very inconvinient to have one more window, but I would like to speed up jshint. Unfortunately running it from IDE is now pretty useless, because it's easy to fire grunt-watch more than once and miss some errors from JSHint.

I would suggest to not rely on operating system modification date, but instead manually write timestamp to file in .cache directory only in newer-post task.

Updated:
I looked a bit more into this issue, and it seems, that newer-postrun task gets fired even though jshint fails, but it doesn't show up in the console.

I probably managed to fix it by adding the following line:

grunt.log.writeln('POSTRUN');
+this.requires(taskName + ':' + targetName);

in the newer-postrun task which according to grunt's documentation does what it should - even if it gets fired it will fail if jshint task failed. I checked, and with this line, the problem doesn't occur.

Not working with grunt-includes

grunt-newer doesn't work with grunt-includes.
Here is my grunt-includes config:

includes: {
    js: {
        options: {
            duplicates: false
        },
        files: [{
            cwd: '<%= pkg.jsAppDir %><%= pkg.theme %>',
            src: 'watchdir/**/*.js',
            dest: '<%= pkg.jsAppDir %><%= pkg.theme %>/.generated/',
        }],
    },
}

If I run grunt newer:includes:js I get an Warning: ENOENT, stat 'watchdir/file1.js' Use --force to continue.. So the file seems not to exist for him, but it does.
If I run in verbose mode I can see the file list.

Files: watchdir/file1.js, watchdir/file2.js, watchdir/file3.js -> app/frontend/js/themes/default/.generated/

grunt-ts support

I am trying to use grunt-ts along with grunt-newer but I am facing some problems. I am using the
ts {
test {
{
src : ["test.ts", "test_2.ts",
outDir: tmp/
}
}
}

The problem seems to be that the outDir configuration is not there when i am using newer:ts.

Running "newer:ts:client_ts" (newer) task
Options: cache="D:\Localhost\www\won\node_modules\grunt-newer.cache"
Files: test.ts test_2.ts

Running "ts:test" (ts) task
Verifying property ts.test exists in config...OK
Files: test.ts -> [no dest]
Options: allowBool, allowImportModule=false, compile, declaration=false, mapRoot="", module="amd", noImplicitAny=false, noResolve=false, comments=null, removeComments=null, sourceMap=false, sourceRoot="", target="es5", verbose=false
Warning: Cannot call method 'indexOf' of undefined Use --force to continue.

Aborted due to warnings.

Newer doesn't work with the coffeelint task

Hello,
I tried to set up your module with the coffeelint task in the same way as it's in your example for jshint.

It looks like this:

grunt.initConfig
    coffeelint:
      app:
        files:
          src: '*/**/*.coffee'
    watch:
      coffeelint:
        files: '*/**/*.coffee',
        tasks: 'newer:coffeelint:app'

However, when I change a coffescript file, it automatically execute the coffeelint task for all coffeescript files in the whole project.

What is wrong?

Thank you.

newer always says [no files] with rsync task

I'm trying to use newer to rsync any modified files up to my dev server. Here's my setup:

watch: {
    upload: {
        files: ['**/*'],
        tasks: ['newer:rsync:dev']
    },
},

rsync: {
    options: {
        args: ['--verbose'],
        exclude: ['.*','node_modules','sql','artifacts','session','logs','cache'],
        recursive: true,
        syncDestIgnoreExcl: true
    },
    dev: {
        options: {
            src: './',
            dest: '/path/to/project',
            host: 'dev3',
        }
    }
},

When I run the watch with --verbose and the modify a file, it tells me:

Running "newer:rsync:dev" (newer) task
Options: cache="/path/to/project/node_modules/grunt-newer/.cache"
File: [no files]
No newer files to process.

If it's trying to compare the source files against the rsync dest, that would be incorrect, because those live on a different server.... there don't appear to be any options to suppress this behaviour, however.

Deleting removed files

Would any one else like it if this plugin removed deleted files?

Perhaps it's out of scope for this plugin.

I'd be willing to code the functionality fi I know that it'll be useful to others, and accepted by the maintainer.

Add a quiet mode

The title is explicit, a simple config line to quite mode could be awesome.

Thx for this perfect plugin

Document v0.8?

The latest release, v0.8, doesn't show up in changelog.md nor does it have any documentation in the github release list. Would be nice to know the changes without having to dig into the code?

Error while checking same folder for two different tasks

In my config I'm checking the same folder and files for grunt-csscomb and grunt-compass. But if the newer task has checked the state for csscomb, it doesn't work for compass anymore.
I need a way to say grunt-newer to check newer files for every task.

Issue with Tasks that also do filtering (ex.grunt-contrib-copy)

I came across this issue that I wanted to report back you..
Before finding grunt-newer, I was using the following task for copy:

copy: {
    build: {
        src:    ['src/**/*'],
        dest:   userOpt.buildLocation + '/<%= pkg.name %>/',
        expand: true,
        filter: onlyNew(['copy', 'build'])
    }
}

Notice the filter option is defined, which is a function that in itself looks at timestamps and determine which files should be copied based on that (ps. I'll be commenting out that line, now that I have found your grunt plugin).

The problem is that when I run it with the above setup, I get the following:

Running "newer:copy:build" (newer) task
Files: src/MyBoard.Dev.aspx -> C:/BUILD/SPListBoard/src/MyBoard.Dev.aspx
Files: src/MyBoard.aspx -> C:/BUILD/SPListBoard/src/MyBoard.aspx

Running "copy:build" (copy) task
Verifying property copy.build exists in config...OK
Files: [no src] -> C:/BUILD/SPListBoard/src/MyBoard.Dev.aspx
Files: [no src] -> C:/BUILD/SPListBoard/src/MyBoard.aspx
Options: processContent=undefined, processContentExclude=["**/*.{png,gif,jpg,ico,psd}"]


Running "newer-postrun:copy:build:1:C:/BUILD/SPListBoard/build/" (newer-post
run) task
Writing C:\BUILD\SPListBoard\build\copy\build\timestamp...OK

Looks like the reference to the two files that were changed above were lost.

Again, just want to report it case others are encountering the same issue. In my case, I'll be removing that filter since grunt-newer will be taking its place.

Paul.

Running 'grunt newer:jshint' causes the full jshint task to run

I setup my jshint configuration as so:

jshint: {
   src: ['<%= jsPath %>/*.js', '<%= jsPath %>/app/**/*.js', '<%= jsPath %>/nls/**/*.js'],
    options: {
        'browser': true,
                'undef': true
    }
}

Then I tried to run grunt newer:jshint and got the following output:

Running "newer:jshint" (newer) task

Running "newer:jshint:src" (newer) task

Running "jshint:src" (jshint) task
>> 111 files lint free.

Running "newer-postrun:jshint:src:1:node_modules/grunt-newer/.cache" (newer-postrun) task

Done, without errors.

I have ran it a number of times and the same output occurs, I thought it would only lint files that changed after the first run?

Naming convention

Hello, I just discovered grunt-newer, and I find this very usefull. However, in order to disable caching problems, I use a versioning convention as follow : timestamp.my.file.js I would like to know if it is possible to uglify the files with a grep on files or something.

Best Regards,
Rémi

Using with Jade

I am using newer with contrib-jade and modified imports does not triggers parent template compile.

template.jade

p some content
block superblock
    p some block content

modules/sub.jade

append superblock
    p add this to my block

And when I change sub.jade I want to compile template.jade but watcher do not do it. Same problem with include. Maybe a problem is in my gruntfile config?

I tried to use override function but get Fatal error: checkForModifiedImports is not defined on this. Is checkForModifiedImports are example function name that I need to write on my own?

My gruntfile: https://gist.github.com/Grawl/0eef67b20a40ec97ace

Renaming a file causes newer to update all files next time around

I think this is easier to explain with some code

My file system:

 |– Gruntfile.js
 |_ devfiles
 |    |_ components
 |         |_ component1
 |         |     |_ style.css
 |         |     |_ index.html
 |         |_ component2   
 |               |_ style.css
 |               |_ index.html 
 |_buildfiles

and the relevant bit of my Gruntfile

    copy: {
        componentDev: {
            files: [
                {
                    cwd: "devfiles/components/",
                    expand: true,
                    src: ['*/**/*.css'],
                    filter: 'isFile',
                    rename: function(a,b){var q = b.split("/"); return "buildfiles/" + q[q.length-1]}
                }
           ]
       }
   },
    watch: {
        componentDev: {
            files: 'devfiles/components/**',
            tasks: ['newer:copy:componentDev'],
        }
   }

grunt.registerTask('devtest', ['watch:componentDev']);

So, the idea is to watch the dev files directory, pull out whichever "style.css" changed, and copy it to the buildfiles directory. (the watch "files" is a bit vague because there is other stuff going on as well)
First time that it "watches", all the styles.css files get copies, which is fine, they just overwrite each other and the one from the alphabetically-last component wins.
This is ok.

The developer then starts with their work, and next time they change a style.css in any component, this one should overwrite the styles.css in buildfiles. (as it is the only one with a modification date larger than the last run date)
This is what I understand by
"Run Grunt tasks with only those source files modified since the last successful run."

The modification time should be compared to the last run time. However, renaming the watched file when copying it (or the deleting of old copied and watched files) screws everything up and on the next run, all the matching files are copied again, and I once again end up with the last-alpha-component.

This must mean that there is some comparison between the modification date of the source file and the creation date of the copied file. This has to be a bug. Or the description of grunt-newer is wrong.

Optionally compare files based on md5sum

I'm inclined to create a new task for this: different. The benefit of the first is clearer semantics and the ability to use newer and different within a single gruntfile.

Unable to work with multiple file changes

When multiple files are changed at the same time (git reset etc.), it is only picking up one of the files. Is it an intended behavior?

Running "watch" task
Completed in 0.041s at Mon Nov 11 2013 10:50:08 GMT-0500 (EST) - Waiting...
OK
>> File "src/js/script.js" changed.
>> File "src/css/style.less" changed.


Running "newer:uglify" (newer) task

Running "uglify" (uglify) task
File "build/js/script.js" created.

Running "newer-timestamp:uglify:~/node_modules/grunt-newer/.cache" (newer-timestamp) task

Running "newer-reconfigure:uglify:3" (newer-reconfigure) task

Running "newer:less" (newer) task
No newer files to process.

Save timestamps for individual files & re-run the task on change

Sometimes when working with Git you need to checkout an earlier commit; running newer:task:target will then not regenerate the file since its timestamp is earlier than the one saved by grunt-newer.

It'd be useful if grunt-newer saved time stamps for every source file the task is run on and that it would re-run the task if the timestamp changed in any direction, not just if it got newer than the generated file.

New files added to src are not detected

If you have a grunt task that has a src:[] of files and you add or remove a file from this array newer does not detect this change and run the respective grunt task this occurs on version 0.8.0.

Take for example;

 uglify:
      lib:
        src:[
          'bower_components/jquery/dist/jquery.js'
          'bower_components/lodash/dist/lodash.js'
          'bower_components/localforage/dist/localforage.js'
          'bower_components/angular/angular.js'
          'bower_components/angular-animate/angular-animate.js'
          'bower_components/angular-localforage/dist/angular-localForage.js'
        ]
        dest:'app/tmp/lib.js'

if you remove one of this files so the task looks like (remove localForage):

 uglify:
      lib:
        src:[
          'bower_components/jquery/dist/jquery.js'
          'bower_components/lodash/dist/lodash.js'
          'bower_components/localforage/dist/localforage.js'
          'bower_components/angular/angular.js'
          'bower_components/angular-animate/angular-animate.js'
        ]
        dest:'app/tmp/lib.js'

and run grunt newer:uglify:lib it will say No newer files to process. I would expect it to rebuild the lib.js without the file that has been removed from the list.
If you run this with the ---verbose the Files: output shows that localForgage file is not longer part of the src list but still does not initiate the task.

The same happens in reverse if for instance you add another file

 uglify:
      lib:
        src:[
          'bower_components/jquery/dist/jquery.js'
          'bower_components/lodash/dist/lodash.js'
          'bower_components/localforage/dist/localforage.js'
          'bower_components/angular/angular.js'
          'bower_components/angular-animate/angular-animate.js'
          'bower_components/angular-localforage/dist/angular-localForage.js'
          'bower_components/ng-simplePagination/simplePagination.js'
        ]
        dest:'app/tmp/lib.js'

When run with ---verbose the 'Files:' output includes simplePagination but it does not trigger the uglify task.

Am I missing something?

Run newer on aliases

Currently the following code does not work:

grunt.registerTask( "validate", [ "jshint", "jscs" ] );
grunt.registerTask( "default", [ "newer:validate" ] );

It throws Object.keys called on non-object
The expected here would be to run newer:jshint and newer:jscs, even though they are not prefixed as newer:jshint and newer:jscs in the alias.

Run "compass" from "watch" through "newer" when '@import'-ed file has changed

in my Grunt file I have:

..

        compass: {
            dest: {
                outputStyle: 'compact',
                relativeAssets: true,
                files: {
                    '<%= destFolder %>/assets/css/main.css': "src/assets/scss/main.scss",
                }
            }
        },
        watch: {
            compass: {
                files: ['src/assets/scss/**/*.scss'],
                tasks: ['newer:compass:dest']
            }
        }
..

When I edit a partial *.scss, the "watch" task detects the changes but the "newer" task thinks nothing has changed so it doesn't run the compass on "main.scss".

I have seen an issue here #35 similar but with less.. is there any fix for sass?

Strange behavior with `expand` and `cwd`

hi, I'm using newer for jshint task and got strange behavior.
It works fine with following config:

    grunt.config('jshint', {
       all: {
            expand: true,
            //cwd: 'src',
            src: 'src/background/*.js'
        }
...
grunt.registerTask('lint', ['newer:jshint']);

but if I uncomment cwd and change src to relative path - it always think that files changed and runs jshint over them:

    grunt.config('jshint', {
       all: {
            expand: true,
            cwd: 'src',
            src: 'background/*.js'
        }
...
grunt.registerTask('lint', ['newer:jshint']);

always get >> 1 file lint free. for grunt lint

Did someone have the same issue and how to solve it?
I'm on macos.

newer not working with coffee watch

I have a watch for building coffeescript files, and the relevant parts of my Gruntfile look like this:

    var coffeeFiles = 'public/javascripts/**/*.coffee';
    grunt.initConfig({
        coffee: {
          all: {
            expand: true,
            src: coffeeFiles,
            ext: '.js'
          }
        },
        watch: {
          options: {
            nospawn: true
          },
          all: {
            files: coffeeFiles,
            tasks: ['newer:coffee:all'],
            options: {
              livereload: true
            }
        }
    });

The first time I change a coffeescript file, the watch compiles ALL coffeescript files. Subsequent changes will compile just the changed file.

Adding changed files to the override method in order to support partials change

I'm working with a large codebase of sass files, where some files @import other partial files.
When a partial file changes, I would like to be able to compile all of its dependencies (files that @import it), using a watch and a newer:sass tasks.

I thought the override function will allow me to to the following pseudo code:

foreach changed file
   if file is partial
      get all non-changed files that import the partial file
      include these files for the task

But the list of changed files is not available in the override function.

Instead, with current implementation, i need to go over all of the non-changed files, extract all of their @imprort-ed files, and check if the partial file has been changed lately, and only then i can decide if the file should be included or not. that is very inefficient.

I wonder if it possible to pass the list of changed files to the override function.

Broken reference to grunt.task.current.data

Hey, this seems like an issue that someone else would have reported by now if it were "real", but searching got me nothing.

I have a concat task, that adds a banner with a list of all concatted files. This works when used independantly via grunt concat:concatModule. When fired from a newer:concat via watch when saving one of the files in concat:concatModule's src list, it does not properly print the list of files. The files are concatted correctly and the banner and footer are added - it's only the file list being printed via grunt.task.current.data which doesn't work.

Digging into it, it seems like the src and dest are in grunt.task.current.data.files[0]. I thought, "okay, that makes sense, the newer task has its own data, so the originals are nested in here - I can if around that". But when attempting to write the file list from that location, it seems like the newer task either doesn't properly write to the output, or maybe the banner is processed a second time and the task no longer has references to either grunt.task.current.data or grunt.task.current.data[0].files.

I'm pretty sure the process option on the concat task and the module wrapper strings added to the task are NOT the reason for this error, but I've included them for completeness.

Expected banner output:

/*! 
  packagename - v0.0.0
  filepath/dest.js
  Included Files:
    file1.js,
    file2.js,
    file3.js,
    file4.js,
    file5.js
 */

Generated banner output:

/*! 
  packagename - v0.0.0

 */

Here is the simplified Gruntfile

var concatBanner = '/*! \n  <%= pkg.name %> - v<%= pkg.version %>\n' +
    '<% if (grunt.task.current.data && grunt.task.current.data.src){ %>' +
    '  <%= grunt.task.current.data.dest %>\n' +
    '  Included Files:\n    ' +
    '<%= grunt.task.current.data.src.join("\\n    ") %>' +
    '<% } %>\n */',

    moduleStart = "\n(function(){\n",

    moduleEnd = "\n}());\n";

grunt.initConfig({
    pkg: grunt.file.readJSON('package.json'),
    watch: {
        js: {
            files: [
                '/**/*.js'
            ],
            tasks: [
                'newer:concat'
            ]
        }
    },
    concat: {
        options: {
            separator: ';',
            success: true,
            banner: concatBanner,
            process: function(src, filepath) {
                // Add the filename above each concatenated section
                return '\n\n// FILE: ' + filepath + '\n\n' + src;
            }
        },
        concatModule: {
            nonull: true,
            src: [
                'file1.js',
                'file2.js',
                'file3.js',
                'file4.js',
                'file5.js'
            ],
            options: {
                banner: concatBanner + moduleStart,
                footer: moduleEnd
            }
        },
        otherConcatWithoutModuleWrapper1: {},
        otherConcatWithoutModuleWrapper2: {}
    }
});

grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-contrib-concat');
grunt.loadNpmTasks('grunt-newer');

Explore recursively when dest is a directory

Hello,
I am using grunt-newer with grunt-ts, a typescript compiler wrapper. For this plugin, the dest parameter is the directory in which the compiled files should be written.
For the moment, grunt-newer checks the mTime of this directory, which is not updated when grunt-ts is invoked and put files inside it. So grunt-ts is systematically called if the target directory happens to be older than one of the src files.
Something inside me tells me that the guilty is grunt-ts not respecting grunt's src/dest conventions, but maybe this is just a missing feature of grunt-newer.

My question is simple : would you merge a pool request that would check if dest is a directory, and if so walk it recursively to get all the mTime of the children ?

Watch task notices changed files, but newer seems to skip them, LESS related.

LESS task defined as below in grunt file:

less: {
  all: {
    options: {
      strictImports: true
    },
    files: [
      {src: ['<%= am.assets %>/src/shared/less/global.less'], dest: '<%= am.dest %>/css/global.css'},
      {src: ['<%= am.assets %>/src/app/common/less/app.less'], dest: '<%= am.dest %>/css/app.css'},
      {src: ['<%= am.assets %>/src/app/taxes/less/taxes.less'], dest: '<%= am.dest %>/css/taxes.css'},
      {src: ['<%= am.assets %>/src/app/storeAdmin/less/storeAdmin.less'], dest: '<%= am.dest %>/css/storeAdmin.css'},
      {src: ['<%= am.assets %>/src/corp/less/corp.less'], dest: '<%= am.dest %>/css/amilia-corporation.css'},
      {src: ['<%= am.assets %>/src/directory/less/directory.less'], dest: '<%= am.dest %>/css/amilia-directory.css'},
      {src: ['<%= am.assets %>/src/claim/less/claim.less'], dest: '<%= am.dest %>/css/amilia-claim.css'},
      {src: ['<%= am.assets %>/src/store/less/store.less'], dest: '<%= am.dest %>/css/amilia-store.css'},
      {src: ['<%= am.assets %>/src/store/less/store-mobile.less'], dest: '<%= am.dest %>/css/amilia-store-mobile.css'},
      {src: ['<%= am.third %>/backgrid/*.css'], dest: '<%= am.dest %>/css/amilia.app-libs.css'}
    ]
  },
}

And the Grunt watch task is as below:

watch: {
  lessfiles: {
    files: ['<%= am.assets %>/src/**/*.less'],
    tasks: ['newer:less:all', 'newer:autoprefixer:dist']
  },
}

Finally, as watch is waiting for changes, I tested by editing the file home.less, and got the output in my terminal as follows:

Running "watch" task
Waiting...OK
>> File "..\assets\src\corp\less\home.less" changed.

Running "newer:less:all" (newer) task
No newer files to process.

New files not being detected when src and dest are the same

A bit more info. I'm using grunt-contrib-imagemin to optimise some folders of images, and grunt-newer to stop imagemin from optimising files it has already optimised.

I'm not sure if I'm just misunderstanding how grunt-newer works, but it doesn't seem to detect when I add new files to my image directories. It just says "No newer files to process":

$ grunt
Running "concurrent:first" (concurrent) task

    Running "newer:imagemin" (newer) task

    Running "newer:imagemin:dist" (newer) task
    No newer files to process.

    Done, without errors.

Done, without errors.

It seems the reason for this is because in my config I've set my source and destination directories to be the same location (which was intentional) - see my config below:

module.exports = {

    options: {
        cache: false,
        optimizationLevel: 7, // (png) 0-7, 7 being the most optimised, but the slowest to execute
        progressive: true, // (jpeg)
        interlaced: true, // (gif)
    },

    dist: {
        files: [{
            expand: true,
            cwd: 'public_html/',
            src: [
                'assets/**/*.{png,jpg,gif}',
                'shop/media/**/*.{png,jpg,gif}'
            ],
            dest: 'public_html/'
        }]
    }
};

Is there a way round this?

Multiples files and folders > No newer files to process

I am trying to compile only changed 'less' but grunt-newer detect only some less changes, watch task detect them. /bootstrap and /views are ignored with this message : No newer files to process and /layout less files are compiled.

hereis my grunt's config

package.json

 "grunt": "~0.4.2",
 "grunt-contrib-watch": "~0.5.3",
 "grunt-contrib-compass": "~0.6.0",
 "assemble-less": "~0.7.0",
 "grunt-newer": "~0.6.1"

this is the structure :

grunt is in a grunt folder
/grunt

less to compile
/views/bloc/folder/.less
/views/bloc/folder/folder/.less
/views/layout/.less
/web/assets/css/bootstrap/3-0-3/.less

compiled css
/web/assets/css/.css

Grunfile.js

module.exports = function (grunt) {

    grunt.initConfig({

        pkg: grunt.file.readJSON('package.json'),

        css_path : '../web/assets/css',
        bootstrap_path : '<%= css_path %>/bootstrap/3-0-3',
        sass_path : '../views/common/components/sass',
        layout_path: '../views/layout',

        less: {

            development: {
                options: {
                    paths: ['<%= css_path %>']
                },
                files: {
                    '<%= css_path %>/bootstrap.css': '<%= bootstrap_path %>/bootstrap.less',
                    '<%= css_path %>/layoutb.css': '<%= layout_path %>/b.less',
                    '<%= css_path %>/layouta.css': '<%= layout_path %>/a.less',
                }
            },
            production: {
                options: {
                    paths: ['<%= css_path %>'],
                    cleancss: true,
                },
                files: {
                    '<%= css_path %>/bootstrap.css': '<%= bootstrap_path %>/bootstrap.less',
                    '<%= css_path %>/layoutb.css': '<%= layout_path %>/layoutb.less',
                    '<%= css_path %>/layouta.css': '<%= layout_path %>/layouta.less',
                }
            }
        },

        // https://github.com/gruntjs/grunt-contrib-compass
        compass: {
            dist: {
                options: {
                    raw: 'preferred_syntax = :scss\n',
                    noLineComments: true,
                    relativeAssets: true,
                    outputStyle: 'expanded',
                    cssDir: '<%= css_path %>/',
                    sassDir: '<%= sass_path %>/',
                    imagesDir: '../web/assets/img/sprites/',
                    //config: 'config.rb'
                }
            }
        },

        watch: {
            options: {
                spawn: false
            },
            gruntfile: {
                files: ['Gruntfile.js'],
                tasks: ['newer:less:development', 'compass']
            },
            stylesheets: {
                files: [
                    '<%= bootstrap_path %>/*.less',
                    '../views/bloc/**/*.less',
                    '<%= layout_path %>/**/*.less',
                ],
                tasks: ['newer:less:development']
            },
        }
    });

    grunt.loadNpmTasks('grunt-contrib-watch');
    grunt.loadNpmTasks('assemble-less');
    grunt.loadNpmTasks('grunt-contrib-compass');
    grunt.loadNpmTasks('grunt-newer');

    grunt.registerTask('default', [
        'compass',
        'less',
    ]);
    grunt.registerTask('dev', [
        'watch'
    ]);

};

Option to handle plugins such as grunt-spritesmith?

Great plugin. Seems to work out of the box with all the plugins that comply with the 'files', 'src' syntax, but I've issues with "grunt-spritesmith":

Running "newer:sprite:employees1x" (newer) task
[...]
Running "sprite:employees1x" (sprite) task
Verifying property sprite.employees1x exists in config...OK
Files: build/tmp/images/employees@1X/dan.lipsa.jpg -> [no dest]
Fatal error: grunt.sprite requires a src, destImg, and destCSS property

I was wondering if this has to do with how source and destination files are specified:

sprite: {
  employees1x: {
    src: 'build/tmp/images/employees@1X/*.jpg',
    destImg: 'build/images/employees/[email protected]',
    destCSS: 'build/css/[email protected]'
  }
}

Is grunt-newer expecting something like the below syntax? Not certain, just a hunch, I might not have identified the problem correctly.

sprite: {
  employees1x: {
    options: {
      destImg: 'build/images/employees/[email protected]',
      destCSS: 'build/css/[email protected]'
    },
    files: [{
      expand: true,
      cwd: 'build/tmp/images/employees@1X/',
      src: ['*.jpg']
    }]
  }
}

Would you have a recommendation on how to handle that case?
Thank you. (I also submitted this issue in the grunt-spritesmith tracker, for suggestions)

newer:imagemin:dynamic and newer:imagemin when only one in task

Installed newer today and started using it with imagemin. Though the only task specified is newer:imagemin:dynamic, I found that it ran followed by imagemin dynamic:

Running "newer:imagemin:dynamic" (newer) task
Running "imagemin:dynamic" (imagemin) task

Here's the config:

module.exports = function(grunt) {
var mozjpeg = require('imagemin-mozjpeg');
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
imagemin: {                          // Task
dynamic: {
 files: [{
    expand: true,                  // Enable dynamic expansion
    cwd: '.',                   // Src matches are relative to this path
    src: ['**/*.{png,jpg,gif}'],   // Actual patterns to match
    dest: '.'                  // Destination path prefix
  }]
    }
}
  });
grunt.loadNpmTasks('grunt-contrib-imagemin');
grunt.loadNpmTasks('grunt-newer');
grunt.registerTask('default', ['newer:imagemin:dynamic']);
};

Thanks for any advice.

Possible to combine with tasks lazy loading?

Hi,

I've been using grunt-newer pretty much everywhere but recently had the need to add an extra layer to my gruntfiles as they were becoming pretty slow at times.

Im now using jit-grunt to load the tasks only as needed but this had an undesired side effect, grunt-newer now seems to do nothing, on every change all files get processed as if they were all newer.

This is most likely due to any misstep on my configuration, so I was wondering if you can help me identify where the problem is.

I've also noticed that the cache files are all zero bytes, perhaps the reason the process happens for every file everytime.

I've simplified my Gruntfile a bit to show how I am trying to use grunt-newer:

'use strict';

module.exports = function ( grunt ) {

  require('time-grunt')(grunt);
  require('jit-grunt')(grunt, {
    "assemble": "assemble",
    "newer"   : "grunt-newer",
    "sass"    : "grunt-sass",
    "watch"   : "grunt-contrib-watch",
    "tinypng" : "grunt-tinypng"
  });

  // set up grunt
  grunt.initConfig({

    pkg: grunt.file.readJSON('package.json'),

    watch: {
      assemble: {
        files: ['{pages,templates}/{,*/}*.{md,hbs,yml}'],
        tasks: ['assemble'],
        options: {
          livereload: false
        }
      },
      images: {
        files: ['images/{,*/}*.png'],
        tasks: ['newer:tinypng'],
        options: {
          livereload: false
        }
      },
      livereload: {
        options: {
          livereload: true
        },
        files: [
          '<%= config.dist %>/{,*/}*.html',
          '<%= config.dist %>/css/{,*/}*.css',
          '<%= config.dist %>/js/*.min.js',
          '<%= config.dist %>/images/{,*/}*.{png,jpg,jpeg}'
        ]
      }
    },

    assemble: {

      options: {
        flatten: false,
        assets: '<%= config.dist %>',
        dist: '<%= config.dist %>',
        layout: 'templates/layouts/default.hbs',
        partials: 'templates/partials/*.hbs',
      },

      pages: {
        files: { '<%= config.dist %>': ['pages/{,*/}*.hbs'] }
      }

    },

    tinypng: {
      options: {
        apiKey: "####"
      },
      compress: {
        expand: true,
        src: 'images/*.png',
        dest: 'dist/'
      }
    }

  });


  grunt.registerTask('default', [
    'connect',
    'watch'
  ]);


};

With this setup, when I change an image for example, i get the following output:
screenshot 2013-12-27 10 33 50

There should be an option to force newer to work in "src only mode"

Even if a task specifies dest files, there should be a way to force newer to work in "src only mode".

What if you clean the dest directory within the building process. So newer will have no chance to ignore old files.

For example:

grunt.initConfig
  clean:
    build: 'project/build'

  imagemin:
    build:
      files: [{
        expand: true
        cwd: 'project/src/images'
        src: '**/*'
        dest: 'project/build/images'
      }]

grunt.registerTask('imagemin_', ['newer:imagemin'])

grunt.registerTask('build', ['clean', 'imagemin_'])

Not able to work with watch

I tried the newer task with grunt newer:uglify:development and it works. Whenever I change one of the js file, it updates that one file only. But when I try to use watch to call ['newer:uglify:development'] task, it doesn't work. There is no indication in -verbose mode on why it doesn't. Obviously watch did work, otherwise the task wouldn't even be called, so I don't know where the bug is. Sample of the tasks:

     watch: {
      uglify_watch: {
        files: ['src/js/*.js'],
        tasks: ['newer:uglify:development']
      }
    },
    uglify: {
    development: {
      options: {
        mangle: false,
        compress: false,
        preserveComments: 'all',
        beautify: true
      },
      expand: true,
      cwd: 'src/js',
      src: ['*.js'],
      dest: 'build/js'
    }
}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.