Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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); 
like image 923
Raine Revere Avatar asked Jul 19 '14 21:07

Raine Revere


People also ask

How does Yeoman handle overwriting files?

Yeoman is very careful when it comes to overwriting users files. Basically, every write happening on a pre-existing file will go through a conflict resolution process. This process requires that the user validate every file write that overwrites content to its file. This behaviour prevents bad surprises and limits the risk of errors.

How do I copy and process a template in Yeoman?

Yeoman calls this internally after the conflicts stage of the run loop. Here’s an example where we’d want to copy and process a template file. We’ll then use the copyTpl method to copy the file while processing the content as a template. copyTpl is using ejs template syntax.

How to update a pre-existing file using Yeoman transform stream?

You can basically use any gulp plugins with the Yeoman transform stream to process generated files during the writing phase. Updating a pre-existing file is not always a simple task. The most reliable way to do so is to parse the file AST ( abstract syntax tree) and edit it.

What is synchronous file system in Yeoman?

As asynchronous APIs are harder to use, Yeoman provide a synchronous file-system API where every file gets written to an in-memory file system and are only written to disk once when Yeoman is done running. This memory file system is shared between all composed generators.


2 Answers

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() ); 
like image 183
callumacrae Avatar answered Oct 15 '22 05:10

callumacrae


Adding to @callumacrae 's answer: you can also define dot: true in the globOptions of copy(). That way a /** glob will include dotfiles. Example:

this.fs.copy(   this.templatePath('files/**'),   this.destinationPath('client'),   { globOptions: { dot: true } } ); 

A list of available Glob options can be found in the README of node-glob.

like image 23
sthzg Avatar answered Oct 15 '22 05:10

sthzg