Copie todos los archivos de un directorio a otro con la copia de Grunt.js

91

Estoy intentando copiar todos los archivos de un directorio a otro directorio como parte de mi proceso de compilación. Funciona bien para archivos individuales que especifico explícitamente, pero cuando trato de copiar todo el directorio, hace cosas raras como copiar la estructura completa del directorio (o nada en absoluto). Aquí está la parte relevante de mi 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/" }
    ]
  }
},

Específicamente, es la última línea que no puedo hacer para trabajar:

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

Respuestas:

149

La flatten: trueopción como en esta respuesta podría funcionar para algunos casos, pero me parece que el requisito más común (como en mi caso) es copiar una carpeta y su estructura de subcarpetas, tal como está, en dest. Parece que, en la mayoría de los casos, si tiene subcarpetas, probablemente se haga referencia a ellas de esa manera en el código. La clave para hacer esto es la cwdopción, que preservará la estructura de la carpeta en relación con el directorio de trabajo especificado:

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
  }
}
Brian Moeskau
fuente
Gracias, tienes razón, esta respuesta es más lo que estaba buscando cuando hice la pregunta. Había aprendido a lidiar con el aplanamiento causado por la respuesta anterior, pero era molesto.
Evan Hobbs
13
He perdido más de una hora por esto ... Si usa cwdopciones, asegúrese de girar expand:true. Si no lo configura expand:true, cwd no funcionará correctamente.
ducin
2
Tuve que asegurarme de que las rutas del directorio terminen con '/' y agregarlas flatten: falsepara que esto funcione.
Samuel Rossille
**/* Eso es lo que estaba buscando, estaba usando ** gracias hombre.
Sam
43

Esta tarea mantendrá la estructura de la carpeta si especifica un archivo global. Lo que quieres es la flattenopción que eliminará la estructura.

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

Encuentre el resto de las opciones disponibles en el repositorio de Github . Espero que esto ayude.

Ben
fuente
24

Me gustaría agregar que cambiar el formato del glob en src modificará cómo funciona la copia.

Como lo señaló bmoeskau anteriormente, lo siguiente copiará todo lo que hay adentro dist/y lo moverá path/to/dir(sobrescribiendo el destino si ya existe).

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

Sin embargo, tenga en cuenta que:

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

Solo copiará archivos dentro dist/y directorios, pero no copiará el contenido de esos directorios al destino.

Además, la siguiente con src: '*/*'voluntad única copia directorios con contenido dentro dist/. Es decir, dist/no se copiarán los archivos que están justo adentro .

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

Finalmente, lo mismo que el anterior, pero solosrc: '**/**' copiará los archivos dentro y los archivos dentro de los subdirectorios a . Entonces no habrá carpetas dentro del destino.dist/dist/path/to/dir

copy: {
  files: {
    expand: true,
    dest: 'path/to/dir',
    cwd: 'dist/',
    src: '*/*',
    flatten: true,
    filter: 'isFile'
  }
}
Jorge Bucaran
fuente
4
gran explicacion! +1
myrocode
3
mejor que la documentación en github, me gustan los ejemplos
wukong
+1 ¿Existe una convención sobre lo que debería significar el número de estrellas, por ejemplo, **siempre significa archivos y directorios, y *solo archivos?
CodyBugstein
1
@Imray Del manual de bash : dos *s adyacentes usados ​​como un solo patrón coincidirán con todos los archivos y cero o más directorios y subdirectorios . Si sigue a /, dos *s adyacentes coincidirán solo con directorios y subdirectorios .
Jorge Bucaran
1
**coincide con todo , mientras que **/ solo con directorios y subdirectorios (no archivos).
Jorge Bucaran
1

Tuve que usar egdy en lugar de llaves para el segmento de archivos (en Coffeescript) ...

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

Si está desarrollando con angular yeoman, entonces esta es la mejor manera de copiar con gruñido. expand: true es obligatorio cuando se utiliza cwd. <% = yeoman.app%> es solo la ruta de la aplicación ('.').

 {
    expand: true,
     cwd: '<%= yeoman.app %>/data',
     dest: '<%= yeoman.dist %>/data',
     src: ['**']
    }
LearnToday
fuente
Si bien este fragmento de código puede resolver la pregunta, incluir una explicación realmente ayuda a mejorar la calidad de su publicación. Recuerde que está respondiendo la pregunta para los lectores en el futuro, y es posible que esas personas no conozcan los motivos de su sugerencia de código. Por favor, también trate de no llenar su código con comentarios explicativos, ya que esto reduce la legibilidad tanto del código como de las explicaciones.
Adiós StackExchange