UNPKG

generator-confit

Version:

Yeoman generator for creating the development process, tools and a sample project for current-generation web applications

238 lines (200 loc) 7.88 kB
'use strict'; const confitGen = require('../../core/ConfitGenerator.js'); const inquirer = require('inquirer'); const spdxLic = require('spdx-license-list'); // Do some one-time checks to see if Confit needs to be updated (function updateCheck() { const updateNotifier = require('update-notifier'); const pkg = require('../../../package.json'); let options = { name: pkg.name, version: pkg.version.indexOf('semantic') > -1 ? '0.0.0' : pkg.version, }; let notifier = updateNotifier({pkg: options}); notifier.notify(); })(); // Yeoman calls each object-function sequentially, from top-to-bottom. Good to know. // This generator is a shell to call other generators and setup global config. // It doesn't do much other work. let hasConfig; module.exports = confitGen.create({ initializing: function() { this.rebuildFromConfig = false; hasConfig = this.hasExistingConfig(); }, prompting: { // By splitting this run-context into 2 sub-contexts, they are guaranteed to run in sequence promptForMode: function() { this.displayTitle('Confit App Generator'); if (hasConfig) { let modePrompt = [ { type: 'confirm', name: 'rebuildFromConfig', message: 'Would you like to rebuild from the existing configuration in ' + this.configFile + '?', default: true, }, ]; return this.prompt(modePrompt).then(function(props) { // Build site, skip to configuring this.rebuildFromConfig = props.rebuildFromConfig; }.bind(this)); } }, promptForProjectType: function() { // Bail out if we just want to rebuild from the configuration file // AND we have a project type if (this.rebuildFromConfig && this.projectType) { this.getBuildProfiles(this.projectType); this.updateBuildTool(); return; } let resources = this.getResources().app; let prompts = [ { type: 'list', name: 'projectType', message: 'Choose the project type', choices: resources.projectTypeList, default: this.projectType || resources.defaults.projectType, }, ]; return this.prompt(prompts).then(function(answers) { this.projectType = answers.projectType; }.bind(this)); }, promptForEverything: function() { // Bail out if we just want to rebuild from the configuration file // But if we don't have a build tool, we need some answers! if (this.rebuildFromConfig && !this.buildTool.isNull) { return; } // Sort out the build profiles let projectType = this.projectType || this.getConfig('projectType'); let buildProfiles = this.getBuildProfiles(projectType); let profileDescriptions = buildProfiles.sort((a, b) => { return a.priority - b.priority; }).map((profile) => { return { value: profile.name, name: profile.name + ' - ' + profile.description, }; }); let resources = this.getResources().app; let genDefaults = this.merge(resources.defaults, this.getConfig()); let popularLicenses = resources.licenses.popular; let allLicenses = Object.keys(spdxLic); let defaultUser = this.user.git && this.user.git.name() ? this.user.git.name() : ''; // Ask everything... let prompts = [ { type: 'list', name: 'buildProfile', message: 'Choose a build-profile for your project', choices: profileDescriptions, default: genDefaults.buildProfile || profileDescriptions[0], }, { type: 'list', name: 'repositoryType', message: 'Where will this project be hosted?', default: genDefaults.repositoryType, choices: resources.repositoryTypes, }, { type: 'confirm', name: 'publicRepository', message: 'Is this repository public (viewable by everyone)?', default: genDefaults.publicRepository, }, { type: 'list', name: 'license', message: 'Choose a licence', default: genDefaults.license, choices: [].concat(new inquirer.Separator('---- Popular (below) ----'), popularLicenses, new inquirer.Separator('---- Popular (above) ----'), allLicenses), }, { type: 'input', name: 'copyrightOwner', message: 'Copyright owner', default: genDefaults.copyrightOwner || defaultUser, }, ]; return this.prompt(prompts).then(function(answers) { this.answers = this.generateObjFromAnswers(answers, prompts); // Make sure projectType is stored as an answer, even though we may have asked the question in a previous prompt this.answers.projectType = projectType; }.bind(this)); }, }, configuring: function() { // If we have new answers, then change the config if (this.answers) { this.setConfig(this.answers); // Update our buildTool, as it may have changed this.updateBuildTool(); } // IMPORTANT: Reload the resources to include the project-type resources. this.initResources(this.projectType, true); // Make sure that even older configurations receive a license property, even when rebuilding let existingConfig = this.getConfig(); if (!existingConfig.license) { existingConfig.license = this.getResources().app.defaults.license; this.setConfig(existingConfig); } // Common files (independent of the build-tool) to write this.copyIfNotExist( this.templatePath('_package.json'), this.destinationPath('package.json'), {name: this.appPackageName} ); let subGenOptions = { 'rebuildFromConfig': this.rebuildFromConfig, 'skip-install': this.options['skip-install'], 'skip-run': this.options['skip-run'], 'configFile': this.configFile, }; // Now call the other generators this.getResources().app.subGenerators.forEach((subGeneratorName) => { this.composeWith(subGeneratorName, {options: this.merge(subGenOptions)}); }); }, writing: function() { let resources = this.getResources().app; let config = this.getConfig(); this.writeGeneratorConfig(resources); // Write the license file if there is one if (config.license && resources.licenses.noLicenseFile.indexOf(config.license) === -1) { let licenseObj = require('spdx-license-list/full')[config.license]; let licenseText = licenseObj.licenseText; let templateData = { licenseText, copyrightOwner: config.copyrightOwner, projectName: String(this.readPackageJson().name), }; this.copyGeneratorTemplates(resources.licenses.templateFiles, templateData); if (licenseText.indexOf('<') > -1) { this.displayWarning('The license file MAY contain templates. Please review before committing.'); } } this.buildTool.write.call(this); // Run finalisation for all the used buildTools this.buildTool.finalizeAll.call(this); }, install: function() { // Before installing, remove any devDependencies that are also dependencies in package.json let pkg = this.readPackageJson(); let newDevDepNames = Object.keys(pkg.devDependencies || {}) || []; let existingDepNames = Object.keys(pkg.dependencies || {}) || []; newDevDepNames.filter((name) => existingDepNames.indexOf(name) === -1).forEach((name) => { delete pkg.devDependencies[name]; }); // InstallDependencies runs 'npm install' and 'bower install' this.installDependencies({ skipInstall: this.options['skip-install'], // --skip-install skipMessage: true, bower: false, }); }, });