What's the recommended way to copy multiple dotfiles with yeoman?

Raine Revere picture Raine Revere · Jul 19, 2014 · Viewed 8.3k times · Source

I am building a yeoman generator for a fairly typical node app:

/
|--package.json
|--.gitignore
|--.travis.yml
|--README.md
|--app/
    |--index.js
    |--models
    |--views
    |--controllers

In the templates folder of my yeoman generator, I have to rename the dotfiles (and the package.json) to prevent them from being processed as part of the generator:

templates/
 |--_package.json
 |--_gitignore
 |--_travis.yml
 |--README.md
 |--app/
     |--index.js
     |--models
     |--views
     |--controllers

I see a lot of generators that copy dotfiles individually manually:

this.copy('_package.json', 'package.json')
this.copy('_gitignore', '.gitignore')
this.copy('_gitattributes', '.gitattributes')

I think it's a pain to manually change my generator code when I add new template files. I would like to automatically copy all files in the /templates folder, and rename the ones that are prefixed with _.

What's the best way to do this?

If I were to describe my intention in imaginary regex, this is what it would look like:

this.copy(/^_(.*)/, '.$1')
ths.copy(/^[^_]/)

EDIT This is the best I can manage:

this.expandFiles('**', { cwd: this.sourceRoot() }).map(function() {
    this.copy file, file.replace(/^_/, '.')
}, this);

Answer

callumacrae picture callumacrae · Dec 9, 2014

I found this question through Google as I was looking for the solution, and then I figured it out myself.

Using the new fs API, you can use globs!

// Copy all non-dotfiles
this.fs.copy(
  this.templatePath('static/**/*'),
  this.destinationRoot()
);

// Copy all dotfiles
this.fs.copy(
  this.templatePath('static/.*'),
  this.destinationRoot()
);