Какой рекомендуемый способ копирования нескольких dotfiles с йоменом?

Я создаю генератор йома для довольно типичного приложения node:

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

В папке шаблонов моего генератора йомен я должен переименовать dotfiles (и package.json), чтобы они не обрабатывались как часть генератора:

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

Я вижу много генераторов, которые копируют dotfiles индивидуально вручную:

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

Мне кажется, что мне больно вручную изменить код генератора, когда я добавляю новые файлы шаблонов. Я хотел бы автоматически копировать все файлы в папке /templates и переименовать те, которые имеют префикс _.

Какой лучший способ сделать это?

Если бы я описал свое намерение в воображаемом регулярном выражении, это будет выглядеть так:

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

ИЗМЕНИТЬ Это лучшее, что я могу решить:

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

Ответы

Ответ 1

Я нашел этот вопрос через Google, поскольку искал решение, а потом сам понял.

Используя новый API fs, вы можете использовать globs!

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

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

Ответ 2

Добавление в ответ @callumacrae: вы также можете определить dot: true в globOptions copy(). Таким образом, /** glob будет включать dotfiles. Пример:

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

Список доступных параметров Glob можно найти в README node-glob.

Ответ 3

Просто у меня получилось: globOptions должен быть в пятом аргументе:

this.fs.copyTpl(
  this.templatePath('sometemplate/**/*'),
  this.destinationPath(this.destinationRoot()),
  null,
  null,
  { globOptions: { dot: true } }
);

Ответ 4

Если вы не хотите использовать шаблоны, начинающиеся с точки, вы можете использовать модуль dive для достижения чего-то идентичного:

var templatePath = this.templatePath('static-dotfiles');
var destinationRoot = this.destinationRoot();
dive(templatePath, {all: true}, function (err, file, stat) {
    if (err) throw err;
    this.fs.copy(
            file,
            (destinationRoot + path.sep + path.relative(templatePath, file))
                    .replace(path.sep + '_', path.sep + '.')
    );
}.bind(this));

где static-dotfiles - это имя вашей папки шаблонов для dotfiles, где _ заменяет . в именах файлов (например: _gitignore).

Не забудьте добавить требование к dive в верхней части вашего генератора с помощью

var dive = require('dive');

Конечно, это также работает для copyTpl.

Обратите внимание, что все подстроки путей, начинающиеся с _, будут заменены на . (ex: static-dotfiles/_config/_gitignore будет сгенерировано как .config/.gitignore)