Copie todos os arquivos do diretório para outro com cópia Grunt.js

91

Estou tentando copiar todos os arquivos de um diretório para outro como parte do meu processo de construção. Funciona bem para arquivos individuais que eu especifico explicitamente, mas quando tento copiar todo o diretório, ele faz coisas estranhas como copiar a estrutura completa do diretório (ou nada). Aqui está a parte relevante do meu 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/" }
    ]
  }
},

Especificamente, é a última linha que não consigo fazer:

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

Respostas:

149

A flatten: trueopção como nesta resposta pode funcionar para alguns casos, mas parece-me que o requisito mais comum (como no meu caso) é copiar uma pasta e sua estrutura de subpasta, como está, para dest. Parece que, na maioria dos casos, se você tiver subpastas, provavelmente elas serão referenciadas dessa forma no código. A chave para fazer isso é a cwdopção, que preservará a estrutura de pastas em relação ao diretório de trabalho 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
fonte
Obrigado - você está certo, esta resposta é mais o que eu estava procurando quando fiz a pergunta. Eu aprendi a lidar com o achatamento causado pela resposta anterior, mas era irritante.
Evan Hobbs
13
Perdi mais de uma hora com isso ... Se você usar cwdopções, certifique-se de virar expand:true. Se você não definir expand:true, o cwd não funcionará corretamente.
ducin
2
Eu tive que ter certeza de que os caminhos do diretório terminam com '/' e adicionar flatten: falsepara fazer isso funcionar.
Samuel Rossille
**/* Isso é o que eu estava procurando, eu estava usando ** obrigado cara.
Sam
43

Esta tarefa manterá a estrutura de pastas se você especificar um arquivo glob. O que você quer é a flattenopção que removerá a estrutura.

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

Encontre o resto das opções disponíveis no repositório Github . Espero que isto ajude.

Ben
fonte
24

Eu gostaria de acrescentar que mudando o formato do glob em src modificará o funcionamento da cópia.

Conforme apontado por bmoeskau acima, o seguinte irá copiar tudo dentro dist/e mover para path/to/dir(sobrescrevendo o destino se ele já existir).

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

Observe, entretanto, que:

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

Copia apenas arquivos dentro dist/e também de diretórios, mas não copiará o conteúdo desses diretórios para o destino.

Além disso, a seguinte com src: '*/*'vontade única copiar diretórios com conteúdo dentro dist/. Ou seja, os arquivos que estiverem lá dentro dist/não serão copiados.

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

Finalmente, o mesmo que acima, mas src: '**/**'irá copiar apenas os arquivos dentro dist/, bem como os arquivos dentro dos dist/subdiretórios para path/to/dir. Portanto, não haverá pastas dentro do destino.

copy: {
  files: {
    expand: true,
    dest: 'path/to/dir',
    cwd: 'dist/',
    src: '*/*',
    flatten: true,
    filter: 'isFile'
  }
}
Jorge Bucaran
fonte
4
ótima explicação! +1
mirocode
3
melhor do que a documentação no github, eu gosto de exemplos
wukong
+1 Existe uma convenção sobre o que o número de estrelas deve significar, por exemplo, **sempre significa arquivos e diretórios, e *apenas arquivos?
CodyBugstein
1
@Imray Do manual do bash : dois *s adjacentes usados ​​como um único padrão irão corresponder a todos os arquivos e zero ou mais diretórios e subdiretórios . Se seguido por a /, dois *s adjacentes corresponderão apenas a diretórios e subdiretórios .
Jorge Bucaran
1
**corresponde a tudo , enquanto **/ apenas diretórios e subdiretórios (não arquivos).
Jorge Bucaran
1

Tive que usar chaves egdy em vez de chaves para o segmento de arquivos (em Coffeescript) ...

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

Se você estiver desenvolvendo com o Angular Yeoman, esta é a melhor maneira de copiar com o Grunt. expand: true é necessário ao usar cwd. <% = yeoman.app%> é apenas a rota do aplicativo ('.').

 {
    expand: true,
     cwd: '<%= yeoman.app %>/data',
     dest: '<%= yeoman.dist %>/data',
     src: ['**']
    }
LearnToday
fonte
Embora este snippet de código possa resolver a questão, incluir uma explicação realmente ajuda a melhorar a qualidade de sua postagem. Lembre-se de que você está respondendo à pergunta para leitores no futuro e essas pessoas podem não saber os motivos de sua sugestão de código. Tente também não sobrecarregar seu código com comentários explicativos, pois isso reduz a legibilidade do código e das explicações!
Adeus StackExchange de