Copiez tous les fichiers d'un répertoire à un autre avec copie Grunt.js


91

J'essaie de copier tous les fichiers d'un répertoire dans un autre répertoire dans le cadre de mon processus de construction. Cela fonctionne bien pour les fichiers individuels que je spécifie explicitement, mais lorsque j'essaie de copier le répertoire entier, cela fait des choses étranges comme copier la structure complète du répertoire (ou rien du tout). Voici la partie pertinente de mon 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/" }
    ]
  }
},

Plus précisément, c'est la dernière ligne que je ne peux pas obtenir au travail:

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

Réponses:


149

L' flatten: trueoption comme dans cette réponse peut fonctionner dans certains cas, mais il me semble que l'exigence la plus courante (comme dans mon cas) est de copier un dossier et sa structure de sous-dossiers, tels quels, dans dest. Il semble que dans la plupart des cas, si vous avez des sous-dossiers, ils sont probablement référencés de cette façon dans le code. La clé pour cela est l' cwdoption, qui préservera la structure des dossiers par rapport au répertoire de travail spécifié:

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
  }
}

Merci - vous avez raison, cette réponse est plus ce que je cherchais quand j'ai posé la question. J'avais appris à gérer l'aplatissement causé par la réponse précédente mais c'était ennuyeux.
Evan Hobbs

13
J'ai perdu plus d'une heure pour ça ... Si vous utilisez des cwdoptions, assurez-vous de tourner expand:true. Si vous ne définissez pas expand:true, cwd ne fonctionnera pas correctement.
ducin

2
Je devais m'assurer que les chemins de répertoire se terminaient par «/» et ajouter flatten: falsepour que cela fonctionne.
Samuel Rossille

**/* C'est ce que je cherchais, j'utilisais ** merci mec.
Sam

43

Cette tâche conservera la structure des dossiers si vous spécifiez un fichier glob. Ce que vous voulez, c'est l' flattenoption qui supprimera la structure.

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

Trouvez le reste des options disponibles dans le référentiel Github . J'espère que cela t'aides.


24

Je voudrais ajouter que changer le format du glob dans src modifiera le fonctionnement de la copie.

Comme indiqué par bmoeskau ci-dessus, ce qui suit copiera tout ce qui se trouve à l' intérieur dist/et le déplacera vers path/to/dir(écrasant la destination si elle existe déjà).

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

Notez cependant que:

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

Copiera uniquement les fichiers à l'intérieur dist/ainsi que les répertoires, mais ne copiera pas le contenu de ces répertoires vers la destination.

En outre, ce qui suit avec src: '*/*'seront uniquement des répertoires avec copie contenu à l' intérieur dist/. Autrement dit, les fichiers juste à l'intérieur dist/ne seront pas copiés.

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

Enfin, comme ci-dessus, mais src: '**/**'ne copiera que les fichiers à l'intérieur dist/ainsi que les fichiers à l'intérieur des dist/sous-répertoires vers path/to/dir. Il n'y aura donc aucun dossier à l'intérieur de la destination.

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

4
grande explication! +1
myrocode

3
mieux que la documentation sur github, j'aime les exemples
wukong

+1 Existe-t-il une convention sur ce que le nombre d'étoiles devrait signifier, par exemple signifie **toujours des fichiers et des répertoires, et *seulement des fichiers?
CodyBugstein

1
@Imray Du manuel de bash : deux *s adjacents utilisés comme un seul modèle correspondront à tous les fichiers et à zéro ou plusieurs répertoires et sous-répertoires . S'il est suivi d'un /, deux *s adjacents correspondront uniquement aux répertoires et sous-répertoires .
Jorge Bucaran

1
**correspond à tout , alors que **/ seuls les répertoires et sous-répertoires (pas les fichiers).
Jorge Bucaran

1

J'ai dû utiliser egdy à la place des accolades pour le segment des fichiers (dans Coffeescript) ...

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

0

Si vous développez avec un yeoman angulaire, c'est la meilleure façon de copier avec grognement. expand: true est requis lors de l'utilisation de cwd. <% = yeoman.app%> est simplement la route de l'application ('.').

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

Bien que cet extrait de code puisse résoudre la question, inclure une explication aide vraiment à améliorer la qualité de votre message. N'oubliez pas que vous répondez à la question aux lecteurs à l'avenir, et que ces personnes pourraient ne pas connaître les raisons de votre suggestion de code. Essayez également de ne pas surcharger votre code avec des commentaires explicatifs, car cela réduit la lisibilité du code et des explications!
Au revoir StackExchange
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.