From 77dc227288941c33edc8dbe7ecaa196c4f7c3770 Mon Sep 17 00:00:00 2001 From: Even Stensberg Date: Wed, 5 Apr 2017 19:33:45 +0200 Subject: [PATCH 1/5] feat: refactor Lays the groundwork for a first release. Integrated Validation to migrate, refactored creator for the init feature to not be circular and made a cleaner structure to the project inside lib/creator. --- lib/creator/index.js | 62 +++++++++---------- lib/creator/init-transform.js | 37 ----------- lib/creator/transformations/index.js | 25 ++++++++ lib/creator/{ => utils}/validate-options.js | 0 .../{ => utils}/validate-options.spec.js | 2 +- .../adapter.js => yeoman/webpack-adapter.js} | 0 .../index.js => yeoman/webpack-generator.js} | 0 lib/initialize.js | 4 +- lib/migrate.js | 17 ++++- .../utils/WebpackOptionsValidationError.js | 0 lib/utils/resolve-packages.js | 2 +- lib/{creator => }/utils/validateSchema.js | 0 .../utils/webpackOptionsSchema.json | 0 13 files changed, 71 insertions(+), 78 deletions(-) delete mode 100644 lib/creator/init-transform.js create mode 100644 lib/creator/transformations/index.js rename lib/creator/{ => utils}/validate-options.js (100%) rename lib/creator/{ => utils}/validate-options.spec.js (79%) rename lib/creator/{generators/adapter.js => yeoman/webpack-adapter.js} (100%) rename lib/creator/{generators/index.js => yeoman/webpack-generator.js} (100%) rename lib/{creator => }/utils/WebpackOptionsValidationError.js (100%) rename lib/{creator => }/utils/validateSchema.js (100%) rename lib/{creator => }/utils/webpackOptionsSchema.json (100%) diff --git a/lib/creator/index.js b/lib/creator/index.js index 7f8daf8cb71..7953d141e3f 100644 --- a/lib/creator/index.js +++ b/lib/creator/index.js @@ -1,42 +1,36 @@ -const validateSchema = require('./utils/validateSchema.js'); -const webpackOptionsSchema = require('./utils/webpackOptionsSchema.json'); -const WebpackOptionsValidationError = require('./utils/WebpackOptionsValidationError'); -const initTransform = require('./init-transform'); -const chalk = require('chalk'); +const yeoman = require('yeoman-environment'); +const Generator = require('yeoman-generator'); +const defaultGenerator = require('./yeoman/webpack-generator'); +const WebpackAdapter = require('./yeoman/webpack-adapter'); +const runTransform = require('./transformations/index'); + /* * @function creator * -* Main function to build up a webpack configuration. -* Either throws an error if it doesn't match the webpack schema, -* or validates the filepaths of the options given. -* If a package is supplied, it finds the path of the package and runs inquirer +* Runs yeoman and runs the transformations based on the object +* built up from an author/user * -* @param { Array } pkgPaths - An Array of packages to run -* @param { } opts - An object containing webpackOptions or nothing -* @returns { } initTransform - Initializes the scaffold in yeoman +* @param { String } options - An path to the given generator +* @returns { Function } runTransform - Run transformations based on yeoman prompt */ -module.exports = function creator(pkgPaths, opts) { - // null, config -> without package - // addon, null -> with package - // we're dealing with init, we need to change this later, as it may have been emptied by yeoman - if(!pkgPaths && !opts) { - initTransform(); - } - else if(pkgPaths) { - // this example app actually needs a refactor in order for it to work - initTransform(pkgPaths); - } - else if(!pkgPaths && opts) { - console.log(opts); - // scaffold is done - /* - const webpackOptionsValidationErrors = validateSchema(webpackOptionsSchema, initialWebpackConfig); - if (webpackOptionsValidationErrors.length) { - throw new WebpackOptionsValidationError(webpackOptionsValidationErrors); - } else { - process.stdout.write('\n' + chalk.green('Congratulations! Your new webpack config file is created!') + '\n'); - } - */ +module.exports = function creator(options) { + const env = yeoman.createEnv(null, null, new WebpackAdapter()); + + if(options) { + env.register(require.resolve(options), 'npm:app'); + + env.run('npm:app') + .on('end', () => { + return runTransform(env.getArgument('configuration')); + }); + + } else { + env.registerStub(defaultGenerator, 'npm:app'); + + env.run('npm:app') + .on('end', () => { + return runTransform(env.getArgument('configuration')); + }); } }; diff --git a/lib/creator/init-transform.js b/lib/creator/init-transform.js deleted file mode 100644 index d557cc2997e..00000000000 --- a/lib/creator/init-transform.js +++ /dev/null @@ -1,37 +0,0 @@ -const fs = require('fs'); -const path = require('path'); -const yeoman = require('yeoman-environment'); -const Generator = require('yeoman-generator'); -const initGenerator = require('./generators/index'); -const WebpackAdapter = require('./generators/adapter'); - -/* -* @function initTransform -* -* Runs yeoman and in the future lets us grab the answers from the generators -* -* @param { Array } options - An Array of paths to match generators for -* @returns { } -*/ - -module.exports = function initTransform(options) { - const creator = require('./index'); - const env = yeoman.createEnv(null, null, new WebpackAdapter()); - - if(options) { - env.register(require.resolve(options), 'npm:app'); - - env.run('npm:app') - .on('end', () => { - return creator(null, env.getArgument('configuration')); - }); - - } else { - env.registerStub(initGenerator, 'npm:app'); - - env.run('npm:app') - .on('end', () => { - return creator(null, env.getArgument('configuration')); - }); - } -}; diff --git a/lib/creator/transformations/index.js b/lib/creator/transformations/index.js new file mode 100644 index 00000000000..75ce0cac0ab --- /dev/null +++ b/lib/creator/transformations/index.js @@ -0,0 +1,25 @@ +const chalk = require('chalk'); +const validateSchema = require('../../utils/validateSchema.js'); +const webpackOptionsSchema = require('../../utils/webpackOptionsSchema.json'); +const WebpackOptionsValidationError = require('../../utils/WebpackOptionsValidationError'); +/* +* @function runTransform +* +* Runs the transformations from an object we get from yeoman +* +* @param { Object } transformObject - Options to transform +* @returns { } TODO +*/ + +module.exports = function runTransform(transformObject) { + + // scaffold is done + /* + const webpackOptionsValidationErrors = validateSchema(webpackOptionsSchema, initialWebpackConfig); + if (webpackOptionsValidationErrors.length) { + throw new WebpackOptionsValidationError(webpackOptionsValidationErrors); + } else { + process.stdout.write('\n' + chalk.green('Congratulations! Your new webpack config file is created!') + '\n'); + } + */ +}; diff --git a/lib/creator/validate-options.js b/lib/creator/utils/validate-options.js similarity index 100% rename from lib/creator/validate-options.js rename to lib/creator/utils/validate-options.js diff --git a/lib/creator/validate-options.spec.js b/lib/creator/utils/validate-options.spec.js similarity index 79% rename from lib/creator/validate-options.spec.js rename to lib/creator/utils/validate-options.spec.js index 5ffa642da2a..fc2c0ef0f4f 100644 --- a/lib/creator/validate-options.spec.js +++ b/lib/creator/utils/validate-options.spec.js @@ -1,6 +1,6 @@ 'use strict'; -const validateOptions = require('../../__mocks__/creator/validate-options.mock').validateOptions; +const validateOptions = require('../../../__mocks__/creator/validate-options.mock').validateOptions; describe('validate-options', () => { diff --git a/lib/creator/generators/adapter.js b/lib/creator/yeoman/webpack-adapter.js similarity index 100% rename from lib/creator/generators/adapter.js rename to lib/creator/yeoman/webpack-adapter.js diff --git a/lib/creator/generators/index.js b/lib/creator/yeoman/webpack-generator.js similarity index 100% rename from lib/creator/generators/index.js rename to lib/creator/yeoman/webpack-generator.js diff --git a/lib/initialize.js b/lib/initialize.js index 81a107ff32b..91a2bba3027 100644 --- a/lib/initialize.js +++ b/lib/initialize.js @@ -8,8 +8,8 @@ const creator = require('./creator/index'); * if we are running the init command with no arguments or if we got dependencies * * @param { Object } pkg - packages included when running the init command -* @returns { } prompt|npmPackagesExists - returns either an inquirer prompt with -* the initial questions we provide, or validates the packages given +* @returns { } creator|npmPackagesExists - returns an installation of the package, +* followed up with a yeoman instance of that if there's packages. If not, it creates a defaultGenerator */ module.exports = function initializeInquirer(pkg) { diff --git a/lib/migrate.js b/lib/migrate.js index 797afe1258c..6a3db45a3cb 100644 --- a/lib/migrate.js +++ b/lib/migrate.js @@ -4,6 +4,9 @@ const diff = require('diff'); const inquirer = require('inquirer'); const PLazy = require('p-lazy'); const Listr = require('listr'); +const validateSchema = require('./utils/validateSchema.js'); +const webpackOptionsSchema = require('./utils/webpackOptionsSchema.json'); +const WebpackOptionsValidationError = require('./utils/WebpackOptionsValidationError'); module.exports = function transformFile(currentConfigPath, outputConfigPath, options) { const recastOptions = Object.assign({ @@ -65,9 +68,17 @@ module.exports = function transformFile(currentConfigPath, outputConfigPath, opt ]) .then(answers => { if (answers['confirmMigration']) { - // TODO validate the config - fs.writeFileSync(outputConfigPath, result, 'utf8'); - console.log(chalk.green(`✔︎ New webpack v2 config file is at ${outputConfigPath}`)); + fs.writeFile(outputConfigPath, result, 'utf8', (err) => { + const webpackOptionsValidationErrors = validateSchema(webpackOptionsSchema, require(outputConfigPath)); + if (err) { + throw err; + } + else if (webpackOptionsValidationErrors.length) { + throw new WebpackOptionsValidationError(webpackOptionsValidationErrors); + } else { + console.log(chalk.green(`\n ✔︎ New webpack v2 config file is at ${outputConfigPath}`)); + } + }); } else { console.log(chalk.red('✖ Migration aborted')); } diff --git a/lib/creator/utils/WebpackOptionsValidationError.js b/lib/utils/WebpackOptionsValidationError.js similarity index 100% rename from lib/creator/utils/WebpackOptionsValidationError.js rename to lib/utils/WebpackOptionsValidationError.js diff --git a/lib/utils/resolve-packages.js b/lib/utils/resolve-packages.js index 8f8f5587272..b30bc05ec93 100644 --- a/lib/utils/resolve-packages.js +++ b/lib/utils/resolve-packages.js @@ -49,7 +49,7 @@ module.exports = function resolvePackages(pkg) { return processPromise(spawnChild(pkg)).then( () => { try { let loc = path.join('..', '..', 'node_modules', pkg); - creator(loc, null); + return creator(loc); } catch(err) { console.log('Package wasn\'t validated correctly..'); console.log('Submit an issue for', pkg, 'if this persists'); diff --git a/lib/creator/utils/validateSchema.js b/lib/utils/validateSchema.js similarity index 100% rename from lib/creator/utils/validateSchema.js rename to lib/utils/validateSchema.js diff --git a/lib/creator/utils/webpackOptionsSchema.json b/lib/utils/webpackOptionsSchema.json similarity index 100% rename from lib/creator/utils/webpackOptionsSchema.json rename to lib/utils/webpackOptionsSchema.json From 9a84b36076719f9837c41bc2bdb764f216a3287c Mon Sep 17 00:00:00 2001 From: Even Stensberg Date: Fri, 7 Apr 2017 09:42:46 +0200 Subject: [PATCH 2/5] feat: Use custom generatorNames --- lib/creator/index.js | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/lib/creator/index.js b/lib/creator/index.js index 7953d141e3f..ca2d355c797 100644 --- a/lib/creator/index.js +++ b/lib/creator/index.js @@ -1,5 +1,5 @@ const yeoman = require('yeoman-environment'); -const Generator = require('yeoman-generator'); +const path = require('path'); const defaultGenerator = require('./yeoman/webpack-generator'); const WebpackAdapter = require('./yeoman/webpack-adapter'); const runTransform = require('./transformations/index'); @@ -16,21 +16,36 @@ const runTransform = require('./transformations/index'); module.exports = function creator(options) { const env = yeoman.createEnv(null, null, new WebpackAdapter()); - if(options) { - env.register(require.resolve(options), 'npm:app'); + const generatorName = replaceGeneratorName(path.basename(options)); + env.register(require.resolve(options), generatorName); - env.run('npm:app') + env.run(generatorName) .on('end', () => { return runTransform(env.getArgument('configuration')); }); } else { - env.registerStub(defaultGenerator, 'npm:app'); + env.registerStub(defaultGenerator, 'webpack-default-generator'); - env.run('npm:app') + env.run('webpack-default-generator') .on('end', () => { return runTransform(env.getArgument('configuration')); }); } }; + +/* +* @function replaceGeneratorName +* +* Replaces the webpack-addons pattern with the end of the addons name merged +* with 'generator' +* +* @param { String } name - name of the generator +* @returns { String } name - replaced pattern of the name +*/ + +function replaceGeneratorName(name) { + return name.replace( + /(webpack-addons)?([^:]+)(:.*)?/g, 'generator$2'); +} From 8870ec0a589081b14081e884eda8dfb1e6d3e4e9 Mon Sep 17 00:00:00 2001 From: Even Stensberg Date: Fri, 7 Apr 2017 10:33:31 +0200 Subject: [PATCH 3/5] feat: Simply logic for yeoman Also commented out unused modules for now. --- lib/creator/index.js | 17 ++++++----------- lib/creator/transformations/index.js | 8 ++++---- 2 files changed, 10 insertions(+), 15 deletions(-) diff --git a/lib/creator/index.js b/lib/creator/index.js index ca2d355c797..ec0c1e98d31 100644 --- a/lib/creator/index.js +++ b/lib/creator/index.js @@ -16,23 +16,18 @@ const runTransform = require('./transformations/index'); module.exports = function creator(options) { const env = yeoman.createEnv(null, null, new WebpackAdapter()); + const generatorName = options ? replaceGeneratorName(path.basename(options)) : 'webpack-default-generator'; if(options) { const generatorName = replaceGeneratorName(path.basename(options)); env.register(require.resolve(options), generatorName); - - env.run(generatorName) - .on('end', () => { - return runTransform(env.getArgument('configuration')); - }); - } else { env.registerStub(defaultGenerator, 'webpack-default-generator'); - - env.run('webpack-default-generator') - .on('end', () => { - return runTransform(env.getArgument('configuration')); - }); } + + env.run(generatorName) + .on('end', () => { + return runTransform(env.getArgument('configuration')); + }); }; /* diff --git a/lib/creator/transformations/index.js b/lib/creator/transformations/index.js index 75ce0cac0ab..308d2644156 100644 --- a/lib/creator/transformations/index.js +++ b/lib/creator/transformations/index.js @@ -1,7 +1,7 @@ -const chalk = require('chalk'); -const validateSchema = require('../../utils/validateSchema.js'); -const webpackOptionsSchema = require('../../utils/webpackOptionsSchema.json'); -const WebpackOptionsValidationError = require('../../utils/WebpackOptionsValidationError'); +//const chalk = require('chalk'); +//const validateSchema = require('../../utils/validateSchema.js'); +//const webpackOptionsSchema = require('../../utils/webpackOptionsSchema.json'); +//const WebpackOptionsValidationError = require('../../utils/WebpackOptionsValidationError'); /* * @function runTransform * From 3dee6deea27305951438a099bb4469002b5d84f6 Mon Sep 17 00:00:00 2001 From: Even Stensberg Date: Fri, 7 Apr 2017 13:28:59 +0200 Subject: [PATCH 4/5] fix: add tests --- lib/creator/index.test.js | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 lib/creator/index.test.js diff --git a/lib/creator/index.test.js b/lib/creator/index.test.js new file mode 100644 index 00000000000..22717ef5052 --- /dev/null +++ b/lib/creator/index.test.js @@ -0,0 +1,15 @@ +'use strict'; + +function replaceGeneratorName(name) { + return name.replace( + /(webpack-addons)?([^:]+)(:.*)?/g, 'generator$2'); +} + +describe('replaceGeneratorName', () => { + + it('should replace a pattern of an addon', () => { + const generatorName = replaceGeneratorName('webpack-addons-thefox'); + expect(generatorName).toEqual('generator-thefox'); + }); + +}); From 717b61ec9d7fb2edb2f77652054af662be7da20c Mon Sep 17 00:00:00 2001 From: Even Stensberg Date: Fri, 7 Apr 2017 13:46:53 +0200 Subject: [PATCH 5/5] fix: use real implementation for test --- lib/creator/index.js | 9 +++++++-- lib/creator/index.test.js | 5 +---- lib/initialize.js | 2 +- lib/utils/resolve-packages.js | 2 +- 4 files changed, 10 insertions(+), 8 deletions(-) diff --git a/lib/creator/index.js b/lib/creator/index.js index ec0c1e98d31..9778b08fbe5 100644 --- a/lib/creator/index.js +++ b/lib/creator/index.js @@ -14,7 +14,7 @@ const runTransform = require('./transformations/index'); * @returns { Function } runTransform - Run transformations based on yeoman prompt */ -module.exports = function creator(options) { +function creator(options) { const env = yeoman.createEnv(null, null, new WebpackAdapter()); const generatorName = options ? replaceGeneratorName(path.basename(options)) : 'webpack-default-generator'; if(options) { @@ -28,7 +28,7 @@ module.exports = function creator(options) { .on('end', () => { return runTransform(env.getArgument('configuration')); }); -}; +} /* * @function replaceGeneratorName @@ -44,3 +44,8 @@ function replaceGeneratorName(name) { return name.replace( /(webpack-addons)?([^:]+)(:.*)?/g, 'generator$2'); } + +module.exports = { + creator, + replaceGeneratorName +}; diff --git a/lib/creator/index.test.js b/lib/creator/index.test.js index 22717ef5052..cbe6ad75cf4 100644 --- a/lib/creator/index.test.js +++ b/lib/creator/index.test.js @@ -1,9 +1,6 @@ 'use strict'; -function replaceGeneratorName(name) { - return name.replace( - /(webpack-addons)?([^:]+)(:.*)?/g, 'generator$2'); -} +const replaceGeneratorName = require('./index').replaceGeneratorName; describe('replaceGeneratorName', () => { diff --git a/lib/initialize.js b/lib/initialize.js index 91a2bba3027..0988943e89d 100644 --- a/lib/initialize.js +++ b/lib/initialize.js @@ -1,5 +1,5 @@ const npmPackagesExists = require('./utils/npm-packages-exists'); -const creator = require('./creator/index'); +const creator = require('./creator/index').creator; /* * @function initializeInquirer diff --git a/lib/utils/resolve-packages.js b/lib/utils/resolve-packages.js index b30bc05ec93..a892cc494d0 100644 --- a/lib/utils/resolve-packages.js +++ b/lib/utils/resolve-packages.js @@ -1,5 +1,5 @@ const spawn = require('cross-spawn'); -const creator = require('../creator/index'); +const creator = require('../creator/index').creator; const path = require('path'); const chalk = require('chalk');