grunt copy part of a sorted directory

88 Views Asked by At

I have a directory structure like the following:

dist/
static/
static/keep1
static/keep2
static/versions/1
static/versions/2
static/versions/3

I want to copy everything from static into dist, with the exception of the versions directory. I want to sort the directory and take the most recent version (e.g. version 3).

If I simply do {expand: true, cwd:'static', src: '**', dest: 'dist/', dot: 'true'}, I'll get old, unnecessary versions that bloat my dist/ directory

Is there a way to programmatically select the most recent version so I don't have to manually update my gruntfile config every time I update static/versions/?

I'm thinking I could potentially node-glob or minimatch will work for me, or maybe I could use grunt-execute or grunt-run (both of which might get ugly). I was hoping there would just be a way to do it with the copy.

1

There are 1 best solutions below

0
RobC On

This can be achieved without additional grunt plug-ins. However, it is necessary to programmatically find the most recent version stored in the ./versions/ directory, and this must be computed in advance of running the copy Task. grunt-contrib-copy has no built-in functionality to determine that.

Once the most recent version directory has been determined simply utilize a couple of Targets in your copy Task.

The following gist demonstrates how this can be achieved:

Note: This solution assumes the most recent version is the highest numbered directory, and is not determined via created or modified dates in any way.

Gruntfile,js

module.exports = function(grunt) {

  'use strict';

  // Additional built-in node module.
  var stats = require('fs').lstatSync;

  /**
   * Find the most recent version. Loops over all paths one level deep in the
   * `static/versions/` directory to obtain the highest numbered directory.
   * The highest numbered directory is assumed to be the most recent version.
   */
  var latestVersion = grunt.file.expand('static/versions/*')

    // 1. Include only directories from the 'static/versions/' 
    //    directory that are named with numbers only.
    .filter(function (_path) {
      return stats(_path).isDirectory() && /^\d+$/.test(_path.split('/')[2]);
    })

    // 2. Return all the numbered directory names.
    .map(function (dirPath) { return dirPath.split('/')[2] })

    // 3. Sort numbers in ascending order.
    .sort(function (a, b) { return a - b; })

    // 4. Reverse array order and return highest number.
    .reverse()[0];


  grunt.initConfig({
    copy: {

      // First target copies everything from `static`
      // to `dist` excluding the `versions` directory.
      allExludingVersions:{
        files:[{
          expand: true,
          dot: true,
          cwd: 'static/',
          src: ['**/*', '!versions/**'],
          dest: 'dist/'
        }]
      },

      // Second target copies only the sub directory with the
      // highest number name from `static/versions` to `dist`.
      latestVersion: {
        files: [{
          expand: true,
          dot: true,
          cwd: 'static/versions/',
          src: latestVersion + '/**/*',
          dest: 'dist/'
       }]
      }
    }
  });

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

Results

Running $ grunt using the Gruntfile.js above, (with your example directory structure), will result in a dist directory structured as follows:

dist
├── keep1
│   └── ...
├── keep2
│   └── ...
└── 3
    └── ...