Copy all files from directory to another with Grunt.js copy

JavascriptGruntjs

Javascript Problem Overview


I'm trying to copy all the files in a directory to another directory as part of my build process. It works fine for individual files that I specify explicitly but when I try to copy the whole directory it does weird things like copies the full directory structure (or nothing at all). Here is the relevant part from my GruntFile.js:

copy: {
  myvoice: {
    files: [
      { src:"src/html/index.html", dest:"dist/myvoice/index.html" },
      { src:"src/html/css/style.css", dest:"dist/myvoice/css/style.css" },
      { src:"src/html/js/require.js", dest:"dist/myvoice/js/require.js" },
      { src:"build/myvoice/main.js", dest:"dist/myvoice/js/main.js" },
      { src:"src/html/css/fonts/*", dest:"dist/myvoice/css/fonts/" }
    ]
  }
},

Specifically it's the last line that I can't get to work:

      { src:"src/html/css/fonts/*", dest:"dist/myvoice/css/fonts/" }

Javascript Solutions


Solution 1 - Javascript

The flatten: true option as in this answer might work for some cases, but it seems to me that the more common requirement (as in my case) is to copy a folder and its sub-folder structure, as-is, to dest. It seems that in most cases if you have sub-folders, they are probably being referenced that way in code. The key to doing this is the cwd option, which will preserve folder structure relative to the specified working directory:

copy: {
  files: {
    cwd: 'path/to/files',  // set working folder / root to copy
    src: '**/*',           // copy all files and subfolders
    dest: 'dist/files',    // destination folder
    expand: true           // required when using cwd
  }
}

Solution 2 - Javascript

This task will maintain folder structure if you specify a file glob. What you want is the flatten option which will remove the structure.

{
    expand: true,
    flatten: true,
    src: ['src/html/css/fonts/**'],
    dest: 'dist/myvoice/css/fonts/',
    filter: 'isFile'
}

Find the rest of the available options in the Github repo. Hope this helps.

Solution 3 - Javascript

I would like to add that changing the format of the glob in src will modify how the copy works.

As pointed out by bmoeskau above, the following will copy everything inside dist/ and move it to path/to/dir (overwriting the destination if it already exists).

copy: {
  files: {
    expand: true,
    dest: 'path/to/dir',
    cwd: 'dist/',
    src: '**'
  }
}

Note however, that:

copy: {
  files: {
    expand: true,
    dest: 'path/to/dir',
    cwd: 'dist/',
    src: '*'
  }
}

Will only copy files inside dist/ as well as directories, but will not copy the contents of those directories to the destination.

Also, the following with src: '*/*' will only copy directories with contents inside dist/. That is, files just inside dist/ will not be copied.

copy: {
  files: {
    expand: true,
    dest: 'path/to/dir',
    cwd: 'dist/',
    src: '*/*'
  }
}

Finally, same as above, but src: '**/**' will copy only files inside dist/ as well as files inside dist/ subdirectories to path/to/dir. So there will be no folders inside the destination.

copy: {
  files: {
    expand: true,
    dest: 'path/to/dir',
    cwd: 'dist/',
    src: '*/*',
    flatten: true,
    filter: 'isFile'
  }
}

Solution 4 - Javascript

Had to use egdy instead curly braces for the files segment (in Coffeescript)...

copy: {
  files: [
    cwd: 'path/to/files'
    src: '**/*'
    dest: 'dist/files'
    expand: true
  ]
}

Solution 5 - Javascript

If you are developing with angular yeoman , then this is the better way to copy with grunt. expand: true is required when using cwd. <%= yeoman.app %> is just the app route ('.').

 {
    expand: true,
     cwd: '<%= yeoman.app %>/data',
     dest: '<%= yeoman.dist %>/data',
     src: ['**']
    }

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionEvan HobbsView Question on Stackoverflow
Solution 1 - JavascriptBrian MoeskauView Answer on Stackoverflow
Solution 2 - JavascriptBenView Answer on Stackoverflow
Solution 3 - JavascriptJorge BucaranView Answer on Stackoverflow
Solution 4 - JavascriptSaschlongView Answer on Stackoverflow
Solution 5 - JavascriptLearnTodayView Answer on Stackoverflow