From a841dc92e4e5f17338b9b779a0720c2c68172f3c Mon Sep 17 00:00:00 2001 From: Adam Bergman Date: Wed, 3 Jan 2018 09:35:58 +0100 Subject: [PATCH] feat(debug): Add debug statements Add debug log statements inside scripts to be able to debug all scripts --- src/index.js | 49 +++++++++++++++++++++++------- src/scripts/build.js | 10 +++++++ src/scripts/bundle.js | 53 +++++++++++++++++---------------- src/scripts/contributors.js | 3 ++ src/scripts/format.js | 12 +++++++- src/scripts/lint.js | 6 ++++ src/scripts/precommit.js | 4 +++ src/scripts/release.js | 4 +++ src/scripts/test.js | 6 ++++ src/utils/hijack-cosmiconfig.js | 13 +++++++- src/utils/run-script.js | 14 ++++++++- 11 files changed, 136 insertions(+), 38 deletions(-) diff --git a/src/index.js b/src/index.js index 61acb66..b24f90b 100644 --- a/src/index.js +++ b/src/index.js @@ -1,18 +1,41 @@ +if (process.argv.includes('--debug')) { + process.env.DEBUG = process.env.DEBUG || 'frans:*'; +} + const sade = require('sade'); const { toPairs, forEach, map, prop } = require('ramda'); +const dbg = require('debug'); const { setScriptEnv } = require('./utils'); const defaults = require('./defaults'); -const wrapAction = action => async args => { - try { - await Promise.resolve().then(() => action(args)); - } catch (err) { - console.error(err.message); - process.exitCode = typeof err.code === 'number' ? err.code : 1; +const debug = dbg('frans:init'); +const error = dbg('frans:error'); + +const handleError = err => { + if (process.env.DEBUG) { + error('%O', err); + } else { + console.error('An error occured. Run again with flag "--debug" to debug'); + console.error(`Error message: ${err.message}`); } + + process.exitCode = typeof err.code === 'number' ? err.code : 1; }; +const wrapAction = action => args => + Promise.resolve() + .then(() => action(args)) + .then(res => { + debug('Command executed succesfully'); + debug('Result: %O', res); + }) + .catch(handleError); + const attachCommand = cli => ([command, { config, description }]) => { + debug(`Setup action handler for script ${command}`); + debug(`With config: ${config}`); + debug(`With description: ${description}`); + const script = require(`./scripts/${command}`); const actionHandler = script(config, cli); @@ -41,12 +64,18 @@ function fransScripts( actions = defaults.actions, { name, version, description } = defaults.cliOptions, ) { - const cli = sade(name); + try { + debug(`Initialize cli with name "${name}"`); + const cli = sade(name); - cli.version(version).describe(description); - attachCommands(cli, actions); + cli.version(version).describe(description); + attachCommands(cli, actions); - cli.parse(process.argv); + cli.parse(process.argv); + debug('Cli initialized'); + } catch (err) { + handleError(err); + } } module.exports = fransScripts; diff --git a/src/scripts/build.js b/src/scripts/build.js index a816d47..cb51e22 100644 --- a/src/scripts/build.js +++ b/src/scripts/build.js @@ -1,3 +1,4 @@ +const debug = require('debug')('frans:build'); const { isNil, is, has, prop, propIs } = require('ramda'); const { promisify } = require('util'); const rimraf = promisify(require('rimraf')); @@ -18,17 +19,26 @@ function build(configPath) { } return async args => { + debug('Setup script build'); const hasArg = p => has(p, args); const getArg = p => prop(p, args); const argIsString = p => propIs(String, p, args); const useBuiltinConfig = !hasArg('presets') && !hasFile('.babelrc') && !hasPkgProp('babel'); + debug(`Use builtin config: ${useBuiltinConfig}`); const useBuiltinIgnore = !hasArg('ignore'); + debug(`Use builtin ignore: ${useBuiltinIgnore}`); + const useBuiltinOutDir = !hasArg('out-dir') || !argIsString('out-dir'); + debug(`Use builtin out dir: ${useBuiltinOutDir}`); + const useBuiltinCopy = !hasArg('copy-files') || getArg('copy-files'); + debug(`Use builtin copy: ${useBuiltinCopy}`); + const useBuiltinClean = !hasArg('clean') || getArg('clean'); + debug(`Use builtin clean: ${useBuiltinClean}`); const config = useBuiltinConfig ? ['--presets', configPath] diff --git a/src/scripts/bundle.js b/src/scripts/bundle.js index 5f29cc4..6830bde 100644 --- a/src/scripts/bundle.js +++ b/src/scripts/bundle.js @@ -1,7 +1,8 @@ +const debug = require('debug')('frans:bundle'); const { promisify } = require('util'); const rimraf = promisify(require('rimraf')); const { isNil, is, has, prop, propIs } = require('ramda'); -const pEachSeries = require('p-each-series'); +const pSeries = require('p-series'); const runScript = require('../utils/run-script'); const { resolveBin, hasFile, fromRoot, reformatFlags } = require('../utils'); @@ -13,14 +14,17 @@ function bundle(configPath) { } return async args => { + debug('Setup script build'); const hasArg = p => has(p, args); const getArg = p => prop(p, args); const argIsString = p => propIs(String, p, args); const useBuiltinConfig = !hasArg('config') && !hasArg('c') && !hasFile('rollup.config.js'); + debug(`Use builtin config: ${useBuiltinConfig}`); const useBuiltinClean = !hasArg('clean') || getArg('clean'); + debug(`Use builtin clean: ${useBuiltinClean}`); const config = useBuiltinConfig ? ['--config', configPath] @@ -32,6 +36,7 @@ function bundle(configPath) { const flags = reformatFlags(args, ['config', 'clean', 'watch']); const outputDir = process.env.BUNDLE_OUTPUT_DIR || 'dist'; + debug(`Output dir: ${outputDir}`); const formats = ['esm', 'cjs', 'umd', 'umd.min']; const tasks = formats.map(format => { @@ -40,33 +45,31 @@ function bundle(configPath) { const mode = minify ? 'production' : 'development'; const sourcemap = name === 'umd'; - const envVars = [ - `NODE_ENV=${mode}`, - `BABEL_ENV=${mode}`, - `BUNDLE_FORMAT=${name}`, - `BUNDLE_MINIFY=${Boolean(minify)}`, - `BUNDLE_SOURCEMAP=${sourcemap}`, - ]; - - const crossEnv = resolveBin('cross-env'); const rollup = resolveBin('rollup'); - - return runScript(crossEnv, [...envVars, rollup, ...config, ...flags]); + return () => + runScript(rollup, [...config, ...flags], { + env: { + NODE_ENV: mode, + BABEL_ENV: mode, + BUNDLE_FORMAT: name, + BUNDLE_MINIFY: Boolean(minify), + BUNDLE_SOURCEMAP: sourcemap, + }, + }); }); - return pEachSeries( - [ - () => { - if (useBuiltinClean) { - return rimraf(fromRoot(outputDir)); - } - - return Promise.resolve(); - }, - ...tasks, - ], - () => Promise.resolve(), - ); + return pSeries([ + async () => { + if (useBuiltinClean) { + debug(`Clean output dir`); + await rimraf(fromRoot(outputDir)); + debug(`Output dir cleaned successfully`); + } else { + debug('Skip cleaning output dir'); + } + }, + ...tasks, + ]); }; } diff --git a/src/scripts/contributors.js b/src/scripts/contributors.js index 7151d58..9648ea0 100644 --- a/src/scripts/contributors.js +++ b/src/scripts/contributors.js @@ -1,8 +1,11 @@ +const debug = require('debug')('frans:contributors'); const runScript = require('../utils/run-script'); const { resolveBin } = require('../utils'); function contributors() { return async ({ _: args }) => { + debug('Setup script contributors'); + const bin = resolveBin('all-contributors-cli', { executable: 'all-contributors', }); diff --git a/src/scripts/format.js b/src/scripts/format.js index f403fba..51f2bc1 100644 --- a/src/scripts/format.js +++ b/src/scripts/format.js @@ -1,3 +1,4 @@ +const debug = require('debug')('frans:format'); const { has, propIs, prop, isNil, is } = require('ramda'); const runScript = require('../utils/run-script'); const { @@ -16,6 +17,8 @@ function format(configPath) { } return async args => { + debug('Setup script format'); + const hasArg = p => has(p, args); const getArg = p => prop(p, args); const argIsString = p => propIs(String, p, args); @@ -26,11 +29,17 @@ function format(configPath) { !hasFile('prettier.config.js') && !hasPkgProp('prettier'); + debug(`Use builtin config: ${useBuiltinConfig}`); + const useGitignore = hasFile('.gitignore') && !hasFile('.prettierignore') && !hasArg('ignore-path'); + + debug(`Use .gitignore: ${useGitignore}`); + const useBuiltinWrite = !hasArg('write') || getArg('write'); + debug(`Use --write: ${useBuiltinWrite}`); const config = useBuiltinConfig ? ['--config', configPath] @@ -62,7 +71,8 @@ function format(configPath) { const bin = resolveBin('prettier'); const commandArgs = [...flags, ...config, ...ignore, ...write, ...files]; - return runScript(bin, commandArgs); + const result = await runScript(bin, commandArgs); + return result; }; } diff --git a/src/scripts/lint.js b/src/scripts/lint.js index ced03e6..6af2bd4 100644 --- a/src/scripts/lint.js +++ b/src/scripts/lint.js @@ -1,3 +1,4 @@ +const debug = require('debug')('frans:lint'); const { isNil, is, has, prop, propIs } = require('ramda'); const runScript = require('../utils/run-script'); const { @@ -16,6 +17,8 @@ function lint(configPath) { } return async args => { + debug('Setup script lint'); + const hasArg = p => has(p, args); const getArg = p => prop(p, args); const argIsString = p => propIs(String, p, args); @@ -26,14 +29,17 @@ function lint(configPath) { !hasFile('.eslintrc.json') && !hasFile('.eslintrc.js') && !hasPkgProp('eslintConfig'); + debug(`Use builtin config: ${useBuiltinConfig}`); const useGitignore = hasFile('.gitignore') && !hasArg('ignore-path') && !hasFile('.eslintignore') && !hasPkgProp('eslintIgnore'); + debug(`Use gitignore: ${useGitignore}`); const useBuiltinCache = !hasArg('cache') || getArg('cache'); + debug(`Use builtin cache: ${useBuiltinCache}`); const config = useBuiltinConfig ? ['--config', configPath] diff --git a/src/scripts/precommit.js b/src/scripts/precommit.js index f7bf919..5bd287b 100644 --- a/src/scripts/precommit.js +++ b/src/scripts/precommit.js @@ -1,3 +1,4 @@ +const debug = require('debug')('frans:precommit'); const { has, propIs, prop, isNil, is } = require('ramda'); const runScript = require('../utils/run-script'); const { hasFile, hasPkgProp, resolveBin, reformatFlags } = require('../utils'); @@ -10,6 +11,8 @@ function precommit(configPath) { } return async args => { + debug('Setup script precommit'); + const hasArg = p => has(p, args); const getArg = p => prop(p, args); const argIsString = p => propIs(String, p, args); @@ -19,6 +22,7 @@ function precommit(configPath) { !hasFile('.lintstagedrc') && !hasFile('lintstaged.config.js') && !hasPkgProp('lint-staged'); + debug(`Use builtin config: ${useBuiltinConfig}`); const config = useBuiltinConfig ? ['--config', configPath] diff --git a/src/scripts/release.js b/src/scripts/release.js index bc233ab..580816f 100644 --- a/src/scripts/release.js +++ b/src/scripts/release.js @@ -1,3 +1,4 @@ +const debug = require('debug')('frans:release'); const { isNil, prop } = require('ramda'); const { toCamelCase } = require('strman'); const hijackCosmiconfig = require('../utils/hijack-cosmiconfig'); @@ -26,7 +27,10 @@ function release(configPath) { } return async args => { + debug('Setup script release'); + const useBuiltinConfig = configPath != null && !hasPkgProp('release'); + debug(`Use builtin config: ${useBuiltinConfig}`); if (useBuiltinConfig) { await hijackCosmiconfig('semantic-release', configPath, 'release'); diff --git a/src/scripts/test.js b/src/scripts/test.js index ee403af..002cf6d 100644 --- a/src/scripts/test.js +++ b/src/scripts/test.js @@ -1,3 +1,4 @@ +const debug = require('debug')('frans:test'); const isCi = require('is-ci'); const { isNil, is, has, prop, propIs } = require('ramda'); const runScript = require('../utils/run-script'); @@ -17,6 +18,9 @@ function test(configPath) { } return async args => { + debug('Setup script test'); + + debug('Set NODE_ENV and BABEL_ENV = "test"'); process.env.NODE_ENV = 'test'; process.env.BABEL_ENV = 'test'; @@ -26,6 +30,7 @@ function test(configPath) { const useBuiltinConfig = !hasArg('config') && !hasFile('jest.config.js') && !hasPkgProp('jest'); + debug(`Use builtin config: ${useBuiltinConfig}`); const hasNoWatchArg = hasArg('watch') && !getArg('watch'); const useBuiltinWatch = @@ -34,6 +39,7 @@ function test(configPath) { !parseEnv('SCRIPTS_PRECOMMIT', false) && !hasArg('coverage') && !hasArg('updateSnapshot'); + debug(`Use builtin watch: ${useBuiltinWatch}`); const config = useBuiltinConfig ? ['--config', configPath] diff --git a/src/utils/hijack-cosmiconfig.js b/src/utils/hijack-cosmiconfig.js index 5e7230f..2e1a3dd 100644 --- a/src/utils/hijack-cosmiconfig.js +++ b/src/utils/hijack-cosmiconfig.js @@ -1,8 +1,11 @@ const path = require('path'); const { promisify } = require('util'); const resolve = promisify(require('resolve')); +const debug = require('debug')('frans:hijac-cosmiconfig'); async function hijackCosmiconfig(forPackage, configPath, prop = forPackage) { + debug(`Setup cosmiconfgi hijac for package ${forPackage} and prop ${prop}`); + const pkgPath = require.resolve(forPackage); const cosmiconfigPath = await resolve('cosmiconfig', { basedir: path.dirname(pkgPath), @@ -12,13 +15,21 @@ async function hijackCosmiconfig(forPackage, configPath, prop = forPackage) { function fakeCosmiconfig(...args) { if (args[0] === prop) { - return { load: () => Promise.resolve({ config: require(configPath) }) }; + return { + load: () => { + debug(`Cosmiconfig loaded for ${forPackage}`); + debug(`With config path ${configPath}`); + return Promise.resolve({ config: require(configPath) }); + }, + }; } + debug('Ignore loading fake cosmiconfig'); return realCosmiconfig(...args); } require.cache[cosmiconfigPath] = { exports: fakeCosmiconfig }; + debug(`Cosmiconfig hijacked for package ${forPackage}`); } module.exports = hijackCosmiconfig; diff --git a/src/utils/run-script.js b/src/utils/run-script.js index dd3d7c3..ff942be 100644 --- a/src/utils/run-script.js +++ b/src/utils/run-script.js @@ -1,14 +1,26 @@ const execa = require('execa'); const isCi = require('is-ci'); +const debug = require('debug')('frans:run-script'); const runScript = (bin, args, opts = {}) => { + debug(`Execute command ${bin}`); + debug('With args: %o', args); + const proc = execa(bin, args, { stdio: 'inherit', ...opts, env: { ...process.env, FORCE_COLOR: !isCi, ...opts.env }, }); - return proc; + return proc + .then(res => { + debug(`Command ${bin} executed succesfully`); + return res; + }) + .catch(err => { + debug(`Command ${bin} got rejected`); + throw err; + }); }; module.exports = runScript;