John Doe
John Doe

Reputation: 338

Grunt-Contrib-Copy, how to copy contents of a directory keeping the same folder structure without overwriting existing files/folders in dest folder?

Source Structure ``` folder

|----Sub-Folder-1
|    |-a.js
|    |-b.js
|----Sub-Folder-2
|    |-c.js
|-d.js
|-e.js
```

Destination structure before running copy task ``` folder

|----Sub-Folder-1
|    |-a.js
|-e.js
```

I need the destination folder to be exactly the same as src folder but I don't want to overwrite the existing files, like a.js and e.js in the above example already exist so they should not be touched, other files/folders should be created, so I want to recursively check inside 'folder' if a file exists or not and copy it if it doesn't exist. I have been using following filter for not overwriting single files filter: function (filepath) { return !(grunt.file.exists('dest')); } but 'folder consists several subdirectories and files so it is not feasible to write for every file. Please help in writing custom grunt task which can do this .

Upvotes: 1

Views: 1014

Answers (1)

RobC
RobC

Reputation: 24992

This can be achieved by adding custom logic inside the filter function of the grunt-contrib-copy target to carry out the following:

  1. Utilize the nodejs path module to help ascertain what the resultant path will be.
  2. Determine whether a file already exists at its destination path by utilizing grunt.file.exists.

The following gists demonstrates how to achieve your requirement cross-platform:

Gruntfile.js

module.exports = function (grunt) {

  'use strict';

  var path = require('path'); // Load additional built-in node module. 

  grunt.loadNpmTasks('grunt-contrib-copy');

  grunt.initConfig({
    copy: {
      non_existing: {
        expand: true,
        cwd: 'src/', //       <-- Define as necessary.
        src: [ '**/*.js' ],
        dest: 'dist/', //     <-- Define as necessary.

        // Copy file only when it does not exist.
        filter: function (filePath) {

          // For cross-platform. When run on Windows any forward slash(s)
          // defined in the `cwd` config path are replaced with backslash(s).
          var srcDir = path.normalize(grunt.config('copy.non_existing.cwd'));

          // Combine the `dest` config path value with the
          // `filepath` value excluding the cwd` config path part.
          var destPath = path.join(
            grunt.config('copy.non_existing.dest'),
            filePath.replace(srcDir, '')
          );

          // Returns false when the file exists.
          return !(grunt.file.exists(destPath));
        }
      }
    }
  });

  grunt.registerTask('default', [ 'copy:non_existing' ]);
};

Upvotes: 2

Related Questions