lib/base-generator.js (44 lines of code) (raw):
'use strict';
const Generator = require('yeoman-generator');
const globby = require('globby');
const path = require('path');
const { withEnhancedConflicter } = require('./decorators.js');
const utils = require('./utils.js');
/*
Base generator has capability for processing ejs template tokens directly inside file paths.
However, win-based paths itself does not support ejs syntaxis. This base class contains number of decorators, which
bring the capability for path preprocessing so that default yo generator can fully leverage ejs.
Example:
We are going to create solution named: 'SampleProject'. Sample flow below shows how generator calculates the final dest path:
Default dest path: <TargetFolder>\Project\src\Foundation\FoundationProject\code\SolutionX.Foundation.FoundationProject.csproj
Preprocessed dest path: <TargetFolder>\Project\src\Foundation\FoundationProject\code\<%= SolutionX %>.Foundation.FoundationProject.csproj
Final dest path: <TargetFolder>\Project\src\Foundation\FoundationProject\code\SampleProject.Foundation.FoundationProject.csproj
*/
class BaseGenerator extends Generator {
// Decorates default copyTpl function. Allows preprocessing through the customOptions.preProcessPath function
_copyTpl(sourcePath, destinationPath, ctx, globOptions, customOptions) {
this._mapFiles(sourcePath, destinationPath, globOptions, customOptions)
.forEach(({ sourceFilePath, destPath }) => this.fs.copyTpl(sourceFilePath, destPath, ctx, globOptions));
}
// Decorates default copy function. Allows preprocessing through the customOptions.preProcessPath function
_copy(sourcePath, destinationPath, ctx, globOptions, customOptions) {
this._mapFiles(sourcePath, destinationPath, globOptions, customOptions)
.forEach(({ sourceFilePath, destPath }) => this.fs.copy(sourceFilePath, destPath, globOptions, ctx));
}
_mapFiles(sourcePath, destinationPath, globOptions, customOptions) {
const diskFiles = globby.sync(sourcePath, globOptions);
return diskFiles.map(sourceFilePath => {
const commonPath = utils.getCommonPath(sourcePath);
const toFile = path.relative(commonPath, sourceFilePath);
let destPath = path.join(destinationPath, toFile);
destPath = !customOptions.preProcessPath ? destPath : customOptions.preProcessPath(destPath);
return { sourceFilePath, destPath };
});
}
_updateFileContent(filePath, transformations, options) {
let contents = this.fs.read(filePath);
contents = transformations.reduce((contents, f) => f(contents, options), contents);
this.fs.write(filePath, contents);
}
_runPipeline(versionKey, destinationPath, pipeline) {
const patches = require(this.sourceRoot() + '/patch.json');
const rootPaths = ['default', ...(patches[versionKey] || [])];
pipeline.forEach(f => rootPaths.forEach(rootPath => f.bind(this)(rootPath, destinationPath)));
}
_baseGlobOptions() {
return {
dot: true,
sync: true,
debug: false,
};
}
}
module.exports = withEnhancedConflicter(BaseGenerator);