UNPKG

@mvp-rockets/namma-generator

Version:

A generator to generate mvp-rockets projects

322 lines (288 loc) 11.7 kB
const Generator = require('yeoman-generator'); const simpleGit = require('simple-git'); const path = require('path'); const yosay = require('yosay'); const fs = require("fs"); module.exports = class extends Generator { get git() { if (!this._simpleGit) { this._simpleGit = simpleGit({ baseDir: this.destinationPath() }).env({ ...process.env, // eslint-disable-next-line @typescript-eslint/naming-convention LANG: 'en', }); } return this._simpleGit; } async initGit() { try { await this.git.init(); if (this.nammaInfo?.repoUrl) { await this.git.addRemote('origin', this.nammaInfo.repoUrl); } await this.git .add('.') .commit('Initializing Project - ' + this.nammaInfo.projectName) .addTag('v1.0.0'); } catch (e) { console.error("Init git failed", e); } } async initializing() { this.nammaInfo = { initProject: false, isRepo: await this.git.checkIsRepo('root') }; } /** * Overides parent. Checks against services.json else directory * @returns {string} appname */ determineAppname() { let appname = this.readDestinationJSON('services.json', {}).projectName; if (!appname) { appname = path.basename(this.destinationRoot()); } return appname.replace(/[^\w\s]+?/g, ' '); } /** * Show Yeoman's greeting * @param {string} message greeting message * @return {Generator} this */ greet(message) { if (!this.options.skipGreeting) { this.log(yosay(message)); } return this; } /** * Compose with a local subgenerator within the same package * @param {string} subgeneratorPath relative path of the subgenerator * @param {string} namespace namespace for the called generator to operate in * @param {Object} options options to pass to the generator * @return {Generator} this */ composeWithLocal(subgeneratorPath, namespace, options) { const generator = require(subgeneratorPath); this.composeWith({ Generator: generator, namespace: namespace, path: path.join(__dirname, subgeneratorPath), }, options ); return this; } //--------------------------------------------------- // file handling //--------------------------------------------------- /** * Read template file * @param {string} filePath path of the file within the template directory * @param {Object} options generator.fs.read's options. See {@link https://github.com/sboudrias/mem-fs-editor|mem-fs-editor} * @return {string} content of the file */ readTemplate(filePath, options) { return this.fs.read(this.templatePath(filePath), options); } /** * Read destination file * @param {string} filePath path of the file within destination directory * @param {Object} options generator.fs.read's options. See {@link https://github.com/sboudrias/mem-fs-editor|mem-fs-editor} * @return {string} content of the file */ readDestination(filePath, options) { return this.fs.read(this.destinationPath(filePath), options); } /** * Read JSON file from template * @param {string} filePath path of the file within template directory * @return {Object} object parsed from the JSON file */ readTemplateJSON(filePath) { return this.fs.readJSON(this.templatePath(filePath), {}); } /** * Read JSON file from destination * @param {string} filePath path of the file within destination directory * @return {Object} object parsed from the JSON file */ readDestinationJSON(filePath) { return this.fs.readJSON(this.destinationPath(filePath), {}); } /** * Write to destination * @param {string} filePath path of the file within destination directory * @param {string} contents content to write * @return {Generator} this */ write(filePath, contents) { this.fs.write(this.destinationPath(filePath), contents); return this; } /** * Write contents to destination as JSON file * @param {string} filePath path of the file within destination directory * @param {Object} contents content to write * @param {...any} args additional options. See {@link https://github.com/sboudrias/mem-fs-editor|mem-fs-editor} * @return {Generator} this */ writeJSON(filePath, contents, ...args) { this.fs.writeJSON(this.destinationPath(filePath), contents, ...args); return this; } /** * Load template * @param {string} filePath path of the file within template directory * @return {function} template function */ loadTemplate(filePath) { return template(this.fs.read(this.templatePath(filePath))); } /** * Add more contents to destination JSON file * @param {string} filePath path of the file within destination directory * @param {Object} contents content to write * @param {...any} args additional arguments. See {@link https://github.com/sboudrias/mem-fs-editor|mem-fs-editor} * @return {Generator} this */ extendJSON(filePath, contents, ...args) { this.fs.extendJSON(this.destinationPath(filePath), contents, ...args); return this; } /** * Add more contents from the template file to the destination JSON file * @param {string} filePath path of the template file within template directory * @param {string} destPath path of the destination file within destination directory * @param {Object} props properties to pass to the template * @param {...any} args additional arguments. See {@link https://github.com/sboudrias/mem-fs-editor|mem-fs-editor} * @return {Generator} this */ extendJSONWithTemplate(filePath, destPath = null, props, ...args) { const template = this.loadTemplate(filePath); const partial = JSON.parse(template(props)); return this.extendJSON(destPath || filePath, partial, ...args); } /** * Copy file from template directory to destination directory * @param {string} filePath path of the template file within template directory * @param {string} destPath path of the destination file within destination directory. If omitted, will use the same path as filePath. * @param {Object} options additional options. See {@link https://github.com/sboudrias/mem-fs-editor|mem-fs-editor} * @return {Generator} this */ copy(filePath, destPath = null, options) { this.fs.copy( this.templatePath(filePath), this.destinationPath(destPath || filePath), options ); return this; } /** * Create content based on a template in template directory and write to destination directory * @param {string} filePath path of the template file within template directory * @param {string} destPath path of the destination file within destination directory. If omitted, will use the same path as filePath. * @param {Object} props properties to pass to the template * @param {...any} args additional arguments. See {@link https://github.com/sboudrias/mem-fs-editor|mem-fs-editor} * @return {Generator} this */ copyTemplate(filePath, destPath = null, props, ...args) { this.fs.copyTpl( this.templatePath(filePath), this.destinationPath(destPath || filePath), props, ...args ); return this; } /** * Append file from template directory to destination directory * @param {string} filePath path of the template file within template directory * @param {string} destPath path of the destination file within destination directory. If omitted, will use the same path as filePath. * @param {Object} options additional options. See {@link https://github.com/sboudrias/mem-fs-editor|mem-fs-editor} * @return {Generator} this */ append(filePath, destPath, options) { let content = this.readTemplate(filePath); this.fs.append( this.destinationPath(destPath || filePath), content, options ); return this; } /** * Check if the template file exists * @param {string} filePath path of the file in template directory * @return {boolean} true if the file exists */ templateExists(filePath) { return this.fs.exists(this.templatePath(filePath)); } /** * Check if the destination file exists * @param {string} filePath path of the file in destination directory * @return {boolean} true if the file exists */ destinationExists(filePath) { return this.fs.exists(this.destinationPath(filePath)); } /** * Check if the destination file exists physically. * @param {string} filePath path of the file in destination directory * @return {boolean} true if the file exists */ targetExists(filePath) { return fs.existsSync(filePath); } /** * List files in the template directory * @param {string} pattern glob pattern for the files * @param {Array.<string>} ignore glob pattern(s) to ignore * @return {Array.<string>} array of file names relative to the template path */ listTemplateFiles(pattern, ignore) { const generator = this; return glob .sync(generator.templatePath(pattern), { nodir: true, ignore: ignore ? ignore.map(ig => generator.templatePath(ig)) : null }) .map(d => d.replace(generator.templatePath('') + '/', '')); } /** * Copy files from template directory to destination directory. * Files with static content are copied directly. * Files with dynamic content are created using the template and given props. * @param {string} pattern glob pattern for the files * @param {Object} options options * @param {Array.<string>} options.ignore glob pattern(s) to ignore * @param {Array.<string>} options.dynamicFiles array of files with dynamic content (need templating) * @param {Object} options.props properties for creating dynamic content * @return {Generator} this */ copyFiles(pattern, options = {}) { const { ignore = [], dynamicFiles = [], props } = options; const staticFiles = this.listTemplateFiles( pattern, dynamicFiles.concat(ignore) ); staticFiles.forEach(file => this.copy(file)); dynamicFiles.forEach(file => { this.copyTemplate(file, file, props); }); return this; } /** * Save service details into services.json in destination directory * @param {JSON} service see templates/init/services.json * @return {Generator} */ saveServicesJson(service) { let serviceJson = this.readDestinationJSON('services.json'); serviceJson.services.push(service); this.writeJSON('services.json', serviceJson); return this; } };