Search code examples
javascriptgulp

How to select the most recent file?


I need to grab the most recent file with src in every subdirectory.

This is the task I have :

gulp.task('compile', function() {
  return gulp.src('src/jade/**/*.js')
    .pipe(jade({pretty: true}))
    .pipe(gulp.dest('dist'));
});

Is there a way to get the freshest JS with gulp src ?


Solution

  • Well, without really having used gulp so far, what you should do would be something like:

    • Find all the files you wish to compile
    • send them to the src method (which takes a string, or an array of files or a stream)

    One of my problems was how to handle the glob style path, so for that I installed the glob npm package in my local package.json

    What I then did was, get all the files using glob( path, callback ), filter those according to the last modified using fs.stat and the mtime or mtimeMs and only keeping the last one

    const { src, dest } = require('gulp');
    const glob = require('glob');
    const path = require('path');
    const fs = require('fs');
    
    async function getFileLastModifiedBy( file ) {
      return new Promise( (resolve, reject) => {
        fs.stat( file, (err, stats) => {
          if (err) {
            reject( err );
            return;
          }
          resolve( stats.mtimeMs );
        });
      } );
    }
    
    async function filterByNewest( input ) {
      const filesByModifiedBy = {};
      for (let file of input) {
        let directory = path.dirname( file );
        let lastModifiedBy = await getFileLastModifiedBy( file );
        if (!filesByModifiedBy[directory] || filesByModifiedBy[directory].lastModifiedBy < lastModifiedBy) {
          filesByModifiedBy[directory] = { file, lastModifiedBy };
        }
      }
      return Object.values( filesByModifiedBy ).map( v => v.file );
    }
    

    and then you could integrate it with your current workflow like in the following way

    gulp.task('compile', function() {
      return new Promise( (resolve, reject) => {
        glob('src/jade/**/*.js', async function( err, files ) {
          if ( files ) {
            const newest = await filterByNewest( files );
            resolve( 
              src( newest )
                .pipe(jade({pretty: true}))
                .pipe(dest('dist'))
            );
            return;
          }
          reject( err );
        })
      });
    });