dg-npm-templates
Version:
Npx generator for react app dependency creation by digite
228 lines (206 loc) • 7.45 kB
JavaScript
console.log("Generator Started!");
const inquirer = require('inquirer');
const fs = require('fs');
const CURR_DIR = process.cwd();
const TEMPLATES = fs.readdirSync(`${__dirname}/templates`);
const QUESTIONS = [
{
name: 'project-choice',
type: 'list',
message: 'What project template would you like to generate?',
choices: TEMPLATES
},
{
name: 'project-name',
type: 'input',
message: 'Project name:',
validate: function (input) {
if (/^([A-Za-z\-\_\d])+$/.test(input)) {
return true
} else {
return 'Project name may only include letters, numbers, underscores and hashes.';
}
}
},
{
name: 'author-name',
type: 'input',
message: 'Author name:',
validate: function (input) {
if (input && input.trim()) {
return true
} else {
return 'Author name must be specified.';
}
}
},
{
name: 'author-email',
type: 'input',
message: 'Author email:',
validate: function (input) {
if ( input && input.trim() ) {
if ( input.trim().toLowerCase().match(/^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/) ) {
return true;
} else {
return 'Author email is not correct.';
}
} else {
return 'Author email must be specified.';
}
}
},
{
name: 'gitlab-repo-name',
type: 'input',
message: 'Git repo name:',
validate: function (input) {
if ( input && input.trim() ) {
if ( input.indexOf(' ') !== -1 ) {
return 'Git repo name must not have spaces in it.';
} else {
return true;
}
} else {
return 'Git repo must be specified.';
}
}
},
{
name: 'gitlab-runner-tag',
type: 'input',
message: 'Gitlab runner tag(pass anything if you do not know runner tag yet and later change in .gitlab-ci.yml if exist in your template):',
validate: function (input) {
if ( input && input.trim() ) {
if ( input.indexOf(' ') !== -1 ) {
return 'Gitlab runner tag must not have spaces in it.';
} else {
return true;
}
} else {
return 'Gitlab runner tag must be specified.';
}
}
}
];
const MICRO_FRONTEND_QUESTIONS = [
{
name: 'mfe-main-container-id',
type: 'input',
message: 'Microfrontend main container id:',
validate: function (input) {
if ( input && input.trim() ) {
if ( input.indexOf(' ') !== -1 ) {
return 'Microfrontend main container id must not have spaces in it.';
} else {
return true;
}
} else {
return 'Microfrontend main container id must be specified.';
}
}
}
];
const NODE_BACKEND_QUESTIONS = [
{
name: 'app-context-path',
type: 'input',
message: 'App context path(Do not type any breaking character for URL):',
validate: function (input) {
if ( input && input.trim() ) {
if ( input.indexOf(' ') !== -1 || input.indexOf('/') !== -1 || input.indexOf('#') !== -1 ||
input.indexOf('.') !== -1 || input.indexOf('_') !== -1 ) {
return 'App context path must not have spaces, /, #, ., _ in it';
} else {
return true;
}
} else {
return 'App context path must be specified.';
}
}
},
{
name: 'app-name',
type: 'input',
message: 'App name(Do not add any invalid character):',
validate: function (input) {
if ( input && input.trim() ) {
if ( input.indexOf(' ') !== -1 ) {
return 'App name have spaces in it';
} else {
return true;
}
} else {
return 'App name must be specified.';
}
}
}
];
inquirer
.prompt(QUESTIONS)
.then(answers => {
const project = answers['project-choice'];
if ( 'dg-react-micro-frontend' === project || 'dg-react-micro-frontend-latest' === project
|| 'dg-react-micro-frontend-latest' === project ) {
inquirer.prompt(MICRO_FRONTEND_QUESTIONS).then( microFrontendANswers => {
processAnswers(answers, microFrontendANswers)
} )
} else if ( 'dg-nodejs-backend-app' === project ) {
inquirer.prompt(NODE_BACKEND_QUESTIONS).then( nodeBackendAnswers => {
processAnswers(answers, nodeBackendAnswers)
} )
} else {
processAnswers(answers)
}
});
function processAnswers(answers, secondaryAnswers) {
const projectChoice = answers['project-choice'];
const projectName = answers['project-name'];
const templatePath = `${__dirname}/templates/${projectChoice}`;
fs.mkdirSync(`${CURR_DIR}/${projectName}`);
createDirectoryContents(templatePath, projectName, answers, secondaryAnswers);
}
function createDirectoryContents (templatePath, newProjectPath, userInputs, secondaryAnswers) {
const filesToCreate = fs.readdirSync(templatePath);
filesToCreate.forEach(file => {
const originalFilePath = `${templatePath}/${file}`;
// get stats about the current file
const stats = fs.statSync(originalFilePath);
if ( stats.isFile() ) {
const contents = processFileContent(file, fs.readFileSync(originalFilePath, 'utf8'), userInputs, secondaryAnswers);
const writePath = `${CURR_DIR}/${newProjectPath}/${file}`;
fs.writeFileSync(writePath, contents, 'utf8');
} else if ( stats.isDirectory() ) {
fs.mkdirSync(`${CURR_DIR}/${newProjectPath}/${file}`);
// recursive call
createDirectoryContents(`${templatePath}/${file}`, `${newProjectPath}/${file}`, userInputs, secondaryAnswers);
}
});
}
function processFileContent(fileName, content, userInputs, secondaryAnswers) {
let processedContent = content;
if ( fileName === 'package.json' ) {
processedContent = processedContent
.replace('#package-name#', userInputs['project-name'].trim())
.replace('#author-name#', userInputs['author-name'].trim())
.replace('#author-email#', userInputs['author-email'].trim())
} else if ( fileName === '.gitlab-ci.yml' ) {
processedContent = processedContent
.replace(new RegExp('#GIT-REPO-NAME#', 'g'), userInputs['gitlab-repo-name'].trim())
.replace(new RegExp('#gitlab-runner-tag#', 'g'), userInputs['gitlab-runner-tag'].trim())
} else if ( fileName === 'devops_jestparser_result.py' || fileName === 'index.html'
|| fileName === 'readme.md' || fileName === 'OnCommit' || fileName === 'weeekly' ) {
processedContent = processedContent
.replace(new RegExp('#GIT-REPO-NAME#', 'g'), userInputs['gitlab-repo-name'].trim())
} else if ( secondaryAnswers && ( fileName === 'styles.scss' || fileName === 'App.js' ) ) {
processedContent = processedContent
.replace(new RegExp('mf-cnt', 'g'), secondaryAnswers['mfe-main-container-id'].trim())
.replace(new RegExp('#GIT-REPO-NAME#', 'g'), userInputs['gitlab-repo-name'].trim())
} else if ( fileName === '.env' && secondaryAnswers ) {
processedContent = processedContent
.replace('#APP_NAME#', secondaryAnswers['app-name'] ? secondaryAnswers['app-name'].trim() : '')
.replace('#CONTEXT_PATH#', secondaryAnswers['app-context-path'] ? secondaryAnswers['app-context-path'].trim() : '')
}
return processedContent;
}