diff --git a/cli.js b/cli.js index 4ee2ca021..be297adc8 100755 --- a/cli.js +++ b/cli.js @@ -17,7 +17,7 @@ updateNotifier({ }).notify() const cli = require('yargs') -const { config } = require('./src/config/user') +const { userConfig } = require('./src/config/user') cli .scriptName('aegir') .env('AEGIR') @@ -28,7 +28,7 @@ cli .example('npm test -- -- --browsers Firefox', 'If `npm test` translates to `aegir test -t browser` and you want to forward options you need to use `-- --` instead.') .epilog('Use `$0 --help` to learn more about each command.') .middleware((yargs) => { - yargs.config = config() + yargs.config = userConfig }) .commandDir('cmds') .help() @@ -37,19 +37,19 @@ cli .option('debug', { desc: 'Show debug output.', type: 'boolean', - default: false, - alias: 'd' + alias: 'd', + default: userConfig.debug }) // TODO remove after webpack 5 upgrade .options('node', { type: 'boolean', describe: 'Flag to control if bundler should inject node globals or built-ins.', - default: false + default: userConfig.node }) .options('ts', { type: 'boolean', describe: 'Enable support for Typescript', - default: false + default: userConfig.ts // needs to be changed to another name to not conflict with the ts cmd options }) .group(['help', 'version', 'debug', 'node', 'ts'], 'Global Options:') .demandCommand(1, 'You need at least one command.') diff --git a/cmds/build.js b/cmds/build.js index 569e9aed5..788affac2 100644 --- a/cmds/build.js +++ b/cmds/build.js @@ -1,5 +1,5 @@ 'use strict' - +const { userConfig } = require('../src/config/user') /** * @typedef {import("yargs").Argv} Argv * @typedef {import("yargs").Arguments} Arguments @@ -21,18 +21,18 @@ module.exports = { bundle: { type: 'boolean', describe: 'Build the JS standalone bundle.', - default: true + default: userConfig.build.bundle }, bundlesize: { alias: 'b', type: 'boolean', describe: 'Analyse bundle size. Default threshold is 100kB, you can override that in `.aegir.js` with the property `bundlesize.maxSize`.', - default: false + default: userConfig.build.bundlesize }, types: { type: 'boolean', describe: 'Build the Typescripts type declarations.', - default: true + default: userConfig.build.types } }) }, diff --git a/cmds/docs.js b/cmds/docs.js index 7ec2bafcd..a091837a3 100644 --- a/cmds/docs.js +++ b/cmds/docs.js @@ -1,4 +1,5 @@ 'use strict' +const { userConfig } = require('../src/config/user') const EPILOG = ` Typescript config file is required to generated docs. Try \`aegir ts --preset config > tsconfig.json\` @@ -18,7 +19,12 @@ module.exports = { alias: 'p', type: 'boolean', describe: 'Publish to GitHub Pages', - default: false + default: userConfig.docs.publish + }, + entryPoint: { + type: 'string', + describe: 'Specifies the entry points to be documented by TypeDoc. TypeDoc will examine the exports of these files and create documentation according to the exports. Either files or directories may be specified. If a directory is specified, all source files within the directory will be included as an entry point.', + default: userConfig.docs.entryPoint } } ) diff --git a/cmds/lint.js b/cmds/lint.js index 15644488f..7a1331264 100644 --- a/cmds/lint.js +++ b/cmds/lint.js @@ -1,5 +1,5 @@ 'use strict' - +const { userConfig } = require('../src/config/user') module.exports = { command: 'lint', desc: 'Lint all project files', @@ -7,8 +7,18 @@ module.exports = { fix: { alias: 'f', type: 'boolean', - describe: 'Automatically fix errors if possible', - default: false + describe: 'Automatically fix errors if possible.', + default: userConfig.lint.fix + }, + files: { + type: 'array', + describe: 'Files to lint.', + default: userConfig.lint.files + }, + silent: { + type: 'boolean', + describe: 'Disable eslint output.', + default: userConfig.lint.silent } }, handler (argv) { diff --git a/cmds/ts.js b/cmds/ts.js index 03c48ee02..69b538fef 100644 --- a/cmds/ts.js +++ b/cmds/ts.js @@ -4,7 +4,6 @@ const EPILOG = ` Presets: \`check\` Runs the type checker with your local config (without writing any files). . \`types\` Emits type declarations to \`dist\` folder. -\`docs\` Generates documentation based on type declarations to the \`docs\` folder. \`config\` Prints base config to stdout. Note: @@ -22,7 +21,7 @@ module.exports = { .options({ preset: { type: 'string', - choices: ['config', 'check', 'types', 'docs'], + choices: ['config', 'check', 'types'], describe: 'Preset to run', alias: 'p' }, diff --git a/package.json b/package.json index ad5ca1902..224a074c3 100644 --- a/package.json +++ b/package.json @@ -73,7 +73,7 @@ "@types/dirty-chai": "^2.0.2", "@types/mocha": "^8.2.0", "@types/node": "^14.14.22", - "aegir-typedoc-theme": "^0.1.0", + "@types/sinon": "^9.0.10", "babel-loader": "^8.2.2", "buffer": "^6.0.3", "bytes": "^3.1.0", @@ -85,14 +85,12 @@ "conventional-changelog": "^3.1.24", "conventional-github-releaser": "^3.1.5", "cors": "^2.8.5", - "cosmiconfig": "^7.0.0", "dirty-chai": "^2.0.1", "electron-mocha": "^10.0.0", "eslint": "^7.18.0", "eslint-config-ipfs": "^1.0.0", "execa": "^5.0.0", "extract-zip": "^2.0.1", - "findup-sync": "^4.0.0", "fs-extra": "^9.1.0", "gh-pages": "^3.1.0", "git-authors-cli": "^1.0.33", @@ -110,6 +108,7 @@ "karma-mocha-webworker": "^1.3.0", "karma-sourcemap-loader": "~0.3.8", "karma-webpack": "4.0.2", + "lilconfig": "^2.0.2", "listr": "~0.14.2", "merge-options": "^3.0.4", "mocha": "^8.2.1", @@ -127,7 +126,7 @@ "strip-bom": "^4.0.0", "strip-json-comments": "^3.1.1", "terser-webpack-plugin": "^3.0.5", - "typedoc": "^0.20.16", + "typedoc": "^0.20.17", "typescript": "4.1.x", "update-notifier": "^5.0.0", "webpack": "^4.43.0", @@ -138,12 +137,14 @@ "yargs-parser": "^20.2.3" }, "devDependencies": { + "@types/bytes": "^3.1.0", "@types/fs-extra": "^9.0.6", + "@types/listr": "^0.14.2", "@types/polka": "^0.5.2", + "@types/semver": "^7.3.4", "@types/yargs": "^15.0.12", "electron": "^11.2.0", "iso-url": "^1.0.0", - "mock-require": "^3.0.2", "sinon": "^9.2.3" }, "engines": { diff --git a/src/build/index.js b/src/build/index.js index 095594579..b71f77677 100644 --- a/src/build/index.js +++ b/src/build/index.js @@ -2,16 +2,19 @@ 'use strict' const path = require('path') -const fs = require('fs') +const { readJsonSync } = require('fs-extra') const bytes = require('bytes') const execa = require('execa') const { premove: del } = require('premove') const { fromAegir, gzipSize, pkg, hasTsconfig } = require('./../utils') -const userConfig = require('../config/user') const tsCmd = require('../ts') +const { userConfig } = require('../config/user') -const config = userConfig() - +/** + * Build command + * + * @param {any} argv + */ module.exports = async (argv) => { const input = argv._.slice(1) const forwardOptions = argv['--'] ? argv['--'] : [] @@ -44,9 +47,9 @@ module.exports = async (argv) => { }) if (argv.bundlesize) { - const stats = JSON.parse(fs.readFileSync(path.join(process.cwd(), 'dist/stats.json'))) + const stats = readJsonSync(path.join(process.cwd(), 'dist/stats.json')) const gzip = await gzipSize(path.join(stats.outputPath, stats.assets[0].name)) - const maxsize = bytes(config.bundlesize.maxSize) + const maxsize = bytes(/** @type {string} */(userConfig.bundlesize.maxSize)) const diff = gzip - maxsize console.log('Use http://webpack.github.io/analyse/ to load "./dist/stats.json".') @@ -61,6 +64,6 @@ module.exports = async (argv) => { } if (argv.types && hasTsconfig) { - await tsCmd({ preset: 'types' }) + await tsCmd({ ...argv, preset: 'types' }) } } diff --git a/src/config/karma.conf.js b/src/config/karma.conf.js index 5f05ffdd1..ec73ad545 100644 --- a/src/config/karma.conf.js +++ b/src/config/karma.conf.js @@ -5,7 +5,7 @@ const webpack = require('webpack') const path = require('path') const webpackConfig = require('./webpack.config') const { fromRoot, hasFile } = require('../utils') -const userConfig = require('./user')() +const { userConfig } = require('./user') const isTSEnable = process.env.AEGIR_TS === 'true' const isWebworker = process.env.AEGIR_RUNNER === 'webworker' diff --git a/src/config/user.js b/src/config/user.js index 92164382b..8180d4c57 100644 --- a/src/config/user.js +++ b/src/config/user.js @@ -1,6 +1,7 @@ +/* eslint-disable no-console */ 'use strict' -const { cosmiconfigSync } = require('cosmiconfig') +const { lilconfigSync } = require('lilconfig') const merge = require('merge-options') const utils = require('../utils') @@ -28,11 +29,33 @@ function normalizeHooks (hooks = {}) { return merge(result, hooks) } -function userConfig () { - const userConfig = utils.getUserConfig() +const config = (searchFrom) => { + let userConfig + try { + const configExplorer = lilconfigSync('aegir', { - const user = merge( + searchPlaces: [ + 'package.json', + '.aegir.js' + ] + }) + const lilconfig = configExplorer.search(searchFrom) + if (lilconfig) { + userConfig = lilconfig.config + } else { + userConfig = {} + } + } catch (err) { + console.error(err) + throw new Error('Error finding your config file.') + } + const conf = merge( { + // global options + debug: false, + node: false, + ts: false, + // old options webpack: {}, karma: {}, hooks: {}, @@ -40,41 +63,46 @@ function userConfig () { bundlesize: { path: './dist/index.min.js', maxSize: '100kB' + }, + // build cmd options + build: { + bundle: true, + bundlesize: false, + types: true + }, + // linter cmd options + lint: { + silent: false, + fix: false, + files: [ + '*.{js,ts}', + 'bin/**', + 'config/**/*.{js,ts}', + 'test/**/*.{js,ts}', + 'src/**/*.{js,ts}', + 'tasks/**/*.{js,ts}', + 'benchmarks/**/*.{js,ts}', + 'utils/**/*.{js,ts}', + '!**/node_modules/**', + '!**/*.d.ts' + ] + }, + // docs cmd options + docs: { + publish: false, + entryPoint: 'src/index.js' } }, - userConfig - ) - - user.hooks = normalizeHooks(user.hooks) - - return user -} - -const config = () => { - let cosmiconfig - try { - const configExplorer = cosmiconfigSync('aegir', { - searchPlaces: ['package.json', '.aegir.js'] - }) - const { config } = configExplorer.search() - cosmiconfig = config || {} - } catch (err) { - cosmiconfig = {} - } - const conf = merge({ - webpack: {}, - karma: {}, - hooks: {}, - entry: utils.fromRoot('src', 'index.js'), - bundlesize: { - path: './dist/index.min.js', - maxSize: '100kB' + userConfig, + { + hooks: normalizeHooks(userConfig.hooks) } - }, - cosmiconfig) + ) return conf } -module.exports = userConfig -userConfig.config = config +module.exports = { + userConfig: config(), + config +} diff --git a/src/config/webpack.config.js b/src/config/webpack.config.js index 64c161839..3c7676bed 100644 --- a/src/config/webpack.config.js +++ b/src/config/webpack.config.js @@ -6,7 +6,7 @@ const merge = require('webpack-merge') const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer') const TerserPlugin = require('terser-webpack-plugin') const { fromRoot, pkg, paths, getLibraryName } = require('../utils') -const userConfig = require('./user')() +const { userConfig } = require('./user') const isProduction = process.env.NODE_ENV === 'production' const isTSEnable = process.env.AEGIR_TS === 'true' diff --git a/src/docs/index.js b/src/docs/index.js index c7fd73b41..edc8b5b29 100644 --- a/src/docs/index.js +++ b/src/docs/index.js @@ -2,27 +2,72 @@ const Listr = require('listr') const chalk = require('chalk') +const execa = require('execa') +const fs = require('fs-extra') +const path = require('path') const { premove: del } = require('premove') -const { getListrConfig, publishDocs, hasTsconfig } = require('../utils') -const tsCmd = require('../ts') +const { + getListrConfig, + publishDocs, + hasTsconfig, + fromAegir, + fromRoot +} = require('../utils') + +/** + * @typedef {Object} Options + * @property {string} entryPoint - Entry point for typedoc (defaults: 'src/index.js') + * @property {string[]} forwardOptions - Extra options to forward to the backend + */ + +/** + * Docs command + * + * @param {any} ctx + */ +const docs = async (ctx) => { + /** @type {Options} */ + const opts = { + forwardOptions: ctx['--'] ? ctx['--'] : [], + entryPoint: ctx.entryPoint + } + if (!hasTsconfig) { + // eslint-disable-next-line no-console + console.error(chalk.yellow('Documentation requires typescript config.\nTry running `aegir ts --preset config > tsconfig.json`')) + return + } + // run typedoc + await execa( + 'typedoc', + [ + fromRoot(opts.entryPoint), + '--out', 'docs', + '--hideGenerator', + '--includeVersion', + '--gitRevision', 'master', + '--plugin', fromAegir('src/ts/typedoc-plugin.js'), + ...opts.forwardOptions + ], + { + localDir: path.join(__dirname, '..'), + preferLocal: true, + stdio: 'inherit' + } + ) + + // write .nojekyll file + fs.writeFileSync('docs/.nojekyll', '') +} const TASKS = new Listr( [ { title: 'Clean ./docs', - task: () => del('docs') + task: async () => del('docs') }, { title: 'Generating documentation', - task: () => { - if (!hasTsconfig) { - // eslint-disable-next-line no-console - console.error(chalk.yellow('Documentation requires typescript config.\nTry running `aegir ts --preset config > tsconfig.json`')) - return - } - - return tsCmd({ preset: 'docs' }) - } + task: docs }, { title: 'Publish to GitHub Pages', diff --git a/src/lint.js b/src/lint.js index cdbd0846e..2bed997a5 100644 --- a/src/lint.js +++ b/src/lint.js @@ -3,22 +3,8 @@ const path = require('path') const globby = require('globby') const { CLIEngine } = require('eslint') -const userConfig = require('./config/user') const formatter = CLIEngine.getFormatter() -const FILES = [ - '*.{js,ts}', - 'bin/**', - 'config/**/*.{js,ts}', - 'test/**/*.{js,ts}', - 'src/**/*.{js,ts}', - 'tasks/**/*.{js,ts}', - 'benchmarks/**/*.{js,ts}', - 'utils/**/*.{js,ts}', - '!**/node_modules/**', - '!**/*.d.ts' -] - function checkDependencyVersions () { const checkVersions = (type, pkg, key) => { const badVersions = [] @@ -87,9 +73,7 @@ function runLinter (opts = {}) { fix: opts.fix }) - const config = userConfig() - const patterns = (config.lint && config.lint.files) || FILES - return globby(patterns) + return globby(opts.files) .then(files => { const report = cli.executeOnFiles(files) if (opts.fix) { diff --git a/src/test/index.js b/src/test/index.js index 7b29e7ce6..0667b6383 100644 --- a/src/test/index.js +++ b/src/test/index.js @@ -31,7 +31,7 @@ const TASKS = [ module.exports = { run (opts, execaOptions) { - const userConfig = require('../config/user')() + const { userConfig } = require('../config/user') const pmap = require('p-map') // TODO remove hooks and just use opts.userConfig diff --git a/src/ts/index.js b/src/ts/index.js index f0c71b8fe..0bfbeb9a8 100644 --- a/src/ts/index.js +++ b/src/ts/index.js @@ -10,6 +10,10 @@ const hasConfig = hasFile('tsconfig.json') /** * @typedef {import("yargs").Argv} Argv * @typedef {import("yargs").Arguments} Arguments + * @typedef {Object} Options + * @property {"config" | "check" | "types" | "docs"} preset + * @property {string[]} forwardOptions - Extra options to forward to the backend + * @property {string[]} extraInclude - Extra include files for the TS Config */ /** @@ -18,8 +22,12 @@ const hasConfig = hasFile('tsconfig.json') * @param {any} argv */ module.exports = async (argv) => { - const forwardOptions = argv['--'] ? argv['--'] : [] - const extraInclude = (argv.include && argv.include.length > 0) ? await globby(argv.include) : [] + /** @type {Options} */ + const opts = { + forwardOptions: argv['--'] ? argv['--'] : [], + extraInclude: (argv.include && argv.include.length > 0) ? await globby(argv.include) : [], + preset: argv.preset + } if (argv.preset === 'config') { const extendsConfig = `{ @@ -48,16 +56,16 @@ module.exports = async (argv) => { 'TS config not found. Try running `aegir ts --preset config > tsconfig.json`' ) } - const userConfig = readJson(fromRoot('tsconfig.json')) + const userTSConfig = readJson(fromRoot('tsconfig.json')) switch (argv.preset) { case 'check': - return check(userConfig, forwardOptions, extraInclude) + return check(userTSConfig, opts) case 'types': - return types(userConfig, forwardOptions, extraInclude) + return types(userTSConfig, opts) case 'docs': - return docs(userConfig, forwardOptions, extraInclude) + return docs(userTSConfig, opts) default: - return execa('tsc', ['--build', ...forwardOptions], { + return execa('tsc', ['--build', ...opts.forwardOptions], { localDir: path.join(__dirname, '../..'), preferLocal: true, stdio: 'inherit' @@ -68,17 +76,16 @@ module.exports = async (argv) => { /** * Check preset * - * @param {any} userConfig - * @param {any} forwardOptions - * @param {string[]} extraInclude + * @param {any} userTSConfig + * @param {Options} opts */ -const check = async (userConfig, forwardOptions, extraInclude) => { +const check = async (userTSConfig, { extraInclude, forwardOptions }) => { const configPath = fromRoot('tsconfig-check.aegir.json') try { fs.writeJsonSync( configPath, merge.apply({ concatArrays: true }, [ - userConfig, + userTSConfig, { compilerOptions: { noEmit: true, @@ -101,17 +108,16 @@ const check = async (userConfig, forwardOptions, extraInclude) => { /** * Types preset * - * @param {any} userConfig - * @param {any} forwardOptions - * @param {string[]} extraInclude + * @param {any} userTSConfig + * @param {Options} opts */ -const types = async (userConfig, forwardOptions, extraInclude) => { +const types = async (userTSConfig, { extraInclude, forwardOptions }) => { const configPath = fromRoot('tsconfig-types.aegir.json') try { fs.writeJsonSync( configPath, merge.apply({ concatArrays: true }, [ - userConfig, + userTSConfig, { compilerOptions: { noEmit: false, @@ -141,40 +147,20 @@ const types = async (userConfig, forwardOptions, extraInclude) => { /** * Docs preset * - * @param {any} userConfig - * @param {any} forwardOptions - * @param {string[]} extraInclude + * @param {any} userTSConfig + * @param {Options} opts */ -const docs = async (userConfig, forwardOptions, extraInclude) => { - await types(userConfig, forwardOptions, extraInclude) - +const docs = async (userTSConfig, opts) => { // run typedoc await execa( 'typedoc', [ - '--inputfiles', - fromRoot('dist'), - '--mode', - 'modules', - '--out', - 'docs', - '--excludeExternals', - // '--excludeNotDocumented', - // '--excludeNotExported', - // '--excludePrivate', - // '--excludeProtected', - '--includeDeclarations', + fromRoot('src/index.js'), + '--out', 'docs', '--hideGenerator', '--includeVersion', - '--gitRevision', - 'master', - '--disableSources', - '--plugin', - fromAegir('src/ts/typedoc-plugin.js'), - '--theme', - fromAegir( - './../../node_modules/aegir-typedoc-theme/bin/default' - ) + '--gitRevision', 'master', + '--plugin', fromAegir('src/ts/typedoc-plugin.js') ], { localDir: path.join(__dirname, '..'), diff --git a/src/ts/typedoc-plugin.js b/src/ts/typedoc-plugin.js index 438c5579c..3c875d8ff 100644 --- a/src/ts/typedoc-plugin.js +++ b/src/ts/typedoc-plugin.js @@ -7,29 +7,25 @@ module.exports = function (PluginHost) { const app = PluginHost.owner const pkg = path.join(process.cwd(), 'package.json') let pkgJson - let main + try { pkgJson = JSON.parse(fs.readFileSync(pkg).toString()) - main = path.join(process.cwd(), pkgJson.main) } catch (err) { throw new Error('cant find package.json') } - - app.converter.on(Converter.EVENT_CREATE_DECLARATION, (context, reflection, node) => { - if (reflection.kind === 1 && node) { - // entry point - if (pkgJson && reflection.name === main) { - reflection.name = '\u0000' + pkgJson.name.charAt(0).toUpperCase() + pkgJson.name.slice(1) - // reflection.kind = 2 - } - - if (pkgJson && reflection.name.includes('dist/src/index.d.ts')) { - reflection.name = '\u0000' + pkgJson.name.charAt(0) + pkgJson.name.slice(1) - } - - if (pkgJson && reflection.name.includes('.d.ts')) { - reflection.name = reflection.name.replace('.d.ts', '.js') + /** + * @param {import("typedoc/dist/lib/converter/context")} context + * @param {import("typedoc/dist/lib/models/reflections/abstract").Reflection} reflection + * @param {import("typescript").Node} node + */ + const cb = (context, reflection, node) => { + if (pkgJson && reflection.name === 'export=') { + let name + if (node) { + name = node.symbol.escapedName } + reflection.name = `${name || 'default'}` } - }) + } + app.converter.on(Converter.EVENT_CREATE_DECLARATION, cb) } diff --git a/src/utils.js b/src/utils.js index b455a2481..246856818 100644 --- a/src/utils.js +++ b/src/utils.js @@ -12,7 +12,6 @@ const stripComments = require('strip-json-comments') const stripBom = require('strip-bom') const { download } = require('@electron/get') const path = require('path') -const findUp = require('findup-sync') const readPkgUp = require('read-pkg-up') const fs = require('fs-extra') const execa = require('execa') @@ -96,24 +95,6 @@ exports.getPathToDist = () => { return path.join(exports.getBasePath(), DIST_FOLDER) } -exports.getUserConfigPath = () => { - return findUp('.aegir.js') -} - -exports.getUserConfig = () => { - let conf = {} - try { - const path = exports.getUserConfigPath() - if (!path) { - return {} - } - conf = require(path) - } catch (err) { - console.error(err) // eslint-disable-line no-console - } - return conf -} - /** * Converts the given name from something like `peer-id` to `PeerId`. * diff --git a/test/config/fixtures/custom-config-package-json/package.json b/test/config/fixtures/custom-config-package-json/package.json new file mode 100644 index 000000000..70ca3c2cf --- /dev/null +++ b/test/config/fixtures/custom-config-package-json/package.json @@ -0,0 +1,6 @@ +{ + "name": "custom-config", + "aegir": { + "custom": true + } +} \ No newline at end of file diff --git a/test/config/fixtures/custom-config/.aegir.js b/test/config/fixtures/custom-config/.aegir.js new file mode 100644 index 000000000..ee8844250 --- /dev/null +++ b/test/config/fixtures/custom-config/.aegir.js @@ -0,0 +1,14 @@ +module.exports = { + webpack: { + devtool: 'eval' + }, + entry: 'src/main.js', + hooks: { + pre() { + return Promise.resolve('pre'); + }, + post() { + return Promise.resolve('post'); + } + } +}; diff --git a/test/config/fixtures/custom-config/package.json b/test/config/fixtures/custom-config/package.json new file mode 100644 index 000000000..1503ae7af --- /dev/null +++ b/test/config/fixtures/custom-config/package.json @@ -0,0 +1,3 @@ +{ + "name": "custom-config" +} \ No newline at end of file diff --git a/test/config/fixtures/custom-user-async-hooks/.aegir.js b/test/config/fixtures/custom-user-async-hooks/.aegir.js new file mode 100644 index 000000000..138dd46d0 --- /dev/null +++ b/test/config/fixtures/custom-user-async-hooks/.aegir.js @@ -0,0 +1,18 @@ +module.exports = { + webpack: { + devtool: 'eval' + }, + entry: 'src/main.js', + hooks: { + async pre () { + await Promise.resolve() + + return 'pre done async' + }, + async post () { + await Promise.resolve() + + return 'post done async' + } + } +}; diff --git a/test/config/fixtures/custom-user-async-hooks/package.json b/test/config/fixtures/custom-user-async-hooks/package.json new file mode 100644 index 000000000..1503ae7af --- /dev/null +++ b/test/config/fixtures/custom-user-async-hooks/package.json @@ -0,0 +1,3 @@ +{ + "name": "custom-config" +} \ No newline at end of file diff --git a/test/config/user.js b/test/config/user.js index 0e43e8383..62fb4fbd0 100644 --- a/test/config/user.js +++ b/test/config/user.js @@ -1,126 +1,34 @@ /* eslint-env mocha */ 'use strict' -const expect = require('chai').expect -const mock = require('mock-require') +const { expect } = require('chai') +const { config } = require('../../src/config/user') +const path = require('path') describe('config - user', () => { - let config - - before(() => { - mock('../../src/utils', { - getPkg () { - return Promise.resolve({ - name: 'example' - }) - }, - getUserConfig () { - return { - webpack: { - devtool: 'eval' - }, - entry: 'src/main.js', - hooks: { - pre () { - return Promise.resolve('pre') - }, - post () { - return Promise.resolve('post') - } - } - } - }, - getLibraryName () { - return 'Example' - }, - getPathToDist () { - return 'dist' - }, - getPathToNodeModules () { - return 'aegir/node_modules' - }, - fromRoot () { - return './src/index.js' - } - }) - - config = mock.reRequire('../../src/config/user')() - }) - - after(() => { - mock.stop('../../src/utils.js') - }) - it('custom config', () => { - expect(config).to.have.property('webpack').eql({ + const conf = config(path.join(__dirname, 'fixtures/custom-config')) + expect(conf).to.have.property('webpack').eql({ devtool: 'eval' }) - expect(config).to.have.property('entry', 'src/main.js') + expect(conf).to.have.property('entry', 'src/main.js') - expect(config.hooks).to.have.nested.property('browser.pre') - expect(config.hooks).to.have.nested.property('browser.post') - expect(config.hooks).to.have.nested.property('node.pre') - expect(config.hooks).to.have.nested.property('node.post') + expect(conf.hooks).to.have.nested.property('browser.pre') + expect(conf.hooks).to.have.nested.property('browser.post') + expect(conf.hooks).to.have.nested.property('node.pre') + expect(conf.hooks).to.have.nested.property('node.post') - return config.hooks.browser.pre().then((res) => { + return conf.hooks.browser.pre().then((res) => { expect(res).to.eql('pre') }) }) -}) - -describe('config - user with async hooks', () => { - let config - - before(() => { - mock('../../src/utils', { - getPkg () { - return Promise.resolve({ - name: 'example' - }) - }, - getUserConfig () { - return { - webpack: { - devtool: 'eval' - }, - entry: 'src/main.js', - hooks: { - async pre () { - await Promise.resolve() - - return 'pre done async' - }, - async post () { - await Promise.resolve() - - return 'post done async' - } - } - } - }, - getLibraryName () { - return 'Example' - }, - getPathToDist () { - return 'dist' - }, - getPathToNodeModules () { - return 'aegir/node_modules' - }, - fromRoot () { - return './src/index.js' - } - }) - - config = mock.reRequire('../../src/config/user')() - }) - - after(() => { - mock.stop('../../src/utils.js') + it('supports async hooks', async () => { + const conf = config(path.join(__dirname, 'fixtures/custom-user-async-hooks')) + expect(await conf.hooks.browser.pre()).to.eql('pre done async') + expect(await conf.hooks.browser.post()).to.eql('post done async') }) - it('supports async hooks', async () => { - expect(await config.hooks.browser.pre()).to.eql('pre done async') - expect(await config.hooks.browser.post()).to.eql('post done async') + const conf = config(path.join(__dirname, 'fixtures/custom-config-package-json')) + expect(await conf.custom).to.ok() }) }) diff --git a/test/lint.js b/test/lint.js index eef772dc5..22add698b 100644 --- a/test/lint.js +++ b/test/lint.js @@ -6,6 +6,7 @@ const { expect } = require('../utils/chai') const path = require('path') const fs = require('fs') const { premove: del } = require('premove/sync') +const { userConfig } = require('../src/config/user') const TEMP_FOLDER = path.join(__dirname, '../node_modules/.temp-test') @@ -27,12 +28,12 @@ const setupProjectWithDeps = deps => setupProject({ const dependenciesShouldPassLinting = (deps) => { return setupProjectWithDeps(deps) - .then(() => lint()) + .then(() => lint(userConfig.lint)) } const dependenciesShouldFailLinting = (deps) => { return setupProjectWithDeps(deps) - .then(() => lint()) + .then(() => lint(userConfig.lint)) .then(() => { throw new Error('Should have failed!') }) @@ -43,14 +44,14 @@ const dependenciesShouldFailLinting = (deps) => { const projectShouldPassLint = async (project) => { await setupProject(project) - await lint() + await lint(userConfig.lint) } const projectShouldFailLint = async (project) => { await setupProject(project) let failed = false try { - await lint({ silent: true }) + await lint(userConfig.lint) } catch (error) { failed = true expect(error.message).to.contain('Lint errors') @@ -72,7 +73,7 @@ describe('lint', () => { it('lint itself (aegir)', function () { this.timeout(20 * 1000) // slow ci is slow - return lint({ fix: false, silent: true }) + return lint({ fix: false, silent: true, files: userConfig.lint.files }) }) it('succeeds when package.json contains dependencies with good versions', function () { @@ -158,39 +159,35 @@ describe('lint', () => { }) it('should pass in user defined path globs', () => { + const dir = `test-${Date.now()}` return setupProjectWithDeps([]) .then(() => { // Directory not included in the default globs - const dir = `test-${Date.now()}` fs.mkdirSync(dir) fs.writeFileSync(`${dir}/test-pass.js`, '\'use strict\'\n\nmodule.exports = {}\n') - fs.writeFileSync( - '.aegir.js', - `module.exports = { lint: { files: ['${dir}/*.js'] } }` - ) }) - .then(() => lint({ silent: true })) + .then(() => lint({ silent: true, files: [`${dir}/*.js`] })) }) it('should fail in user defined path globs', async () => { + const dir = `test-${Date.now()}` await setupProjectWithDeps([]) // Directory not included in the default globs - const dir = `test-${Date.now()}` fs.mkdirSync(dir) fs.writeFileSync(`${dir}/test-fail.js`, '() .> {') - fs.writeFileSync( - '.aegir.js', - `module.exports = { lint: { files: ['${dir}/*.js'] } }` - ) - await expect(lint({ silent: true })).to.eventually.be.rejectedWith('Lint errors') + await expect(lint({ + silent: true, + files: [`${dir}/*.js`] + })) + .to.eventually.be.rejectedWith('Lint errors') }) it('should lint ts and js with different parsers rules', async () => { process.chdir(path.join(__dirname, './fixtures/js+ts/')) - await lint() + await lint(userConfig.lint) }) it('should pass if no .eslintrc found and does not follows ipfs eslint rules', async () => { diff --git a/test/utils.js b/test/utils.js index 9f695bd29..e398fd33a 100644 --- a/test/utils.js +++ b/test/utils.js @@ -23,16 +23,6 @@ describe('utils', () => { expect(utils.getPathToDist()).to.match(/dist$/) }) - it('getUserConfigPath', () => { - expect(utils.getUserConfigPath()).to.match(/.aegir.js$/) - }) - - it('getUserConfig', () => { - sinon.stub(utils, 'getUserConfigPath').returns(path.join(__dirname, 'fixtures/.aegir.js')) - expect(utils.getUserConfig()).to.eql({ config: 'mine' }) - sinon.restore() - }) - it('getLibraryName', () => { const cases = [ ['hello world', 'HelloWorld'],