From f654f1832d13d9e556e770547dba74b1bbff1d4d Mon Sep 17 00:00:00 2001 From: Samuel Attard Date: Sat, 31 Dec 2016 14:42:49 +1300 Subject: [PATCH 1/2] feat(generic): use an ora/promise helper instead of a global uncaught rejection handler ISSUES CLOSED: #38 --- package.json | 2 +- src/electron-forge-import.js | 85 +++++++------ src/electron-forge-lint.js | 50 ++++---- src/electron-forge-make.js | 66 +++++----- src/electron-forge-publish.js | 23 ++-- src/electron-forge-start.js | 36 +++--- src/electron-forge.js | 51 ++++---- src/init/init-custom.js | 59 ++++----- src/init/init-directory.js | 37 +++--- src/init/init-git.js | 33 ++--- src/init/init-npm.js | 51 ++++---- src/init/init-standard-fix.js | 12 +- src/init/init-starter-files.js | 30 ++--- src/publishers/github.js | 63 +++++----- src/util/compile-hook.js | 57 +++++---- src/util/ora-handler.js | 23 ++++ src/util/rebuild.js | 222 ++++++++++++++++----------------- 17 files changed, 452 insertions(+), 448 deletions(-) create mode 100644 src/util/ora-handler.js diff --git a/package.json b/package.json index b5215cc0f3..d1fc598ae1 100644 --- a/package.json +++ b/package.json @@ -72,7 +72,7 @@ "lodash.template": "^4.4.0", "log-symbols": "^1.0.2", "node-gyp": "^3.4.0", - "ora": "^0.3.0", + "ora": "^0.4.0", "pify": "^2.3.0", "resolve-package": "^1.0.1", "semver": "^5.3.0", diff --git a/src/electron-forge-import.js b/src/electron-forge-import.js index 866df5a447..1c31cf400b 100644 --- a/src/electron-forge-import.js +++ b/src/electron-forge-import.js @@ -1,7 +1,6 @@ import debug from 'debug'; import fs from 'fs-promise'; import inquirer from 'inquirer'; -import ora from 'ora'; import path from 'path'; import program from 'commander'; import { spawn as yarnOrNPMSpawn, hasYarn } from 'yarn-or-npm'; @@ -9,6 +8,7 @@ import { spawn as yarnOrNPMSpawn, hasYarn } from 'yarn-or-npm'; import initGit from './init/init-git'; import { deps, devDeps } from './init/init-npm'; +import asyncOra from './util/ora-handler'; import installDepList from './util/install-dependencies'; import readPackageJSON from './util/read-package-json'; @@ -114,9 +114,9 @@ const main = async () => { } const writeChanges = async () => { - const writeSpinner = ora.ora('Writing modified package.json file').start(); - await fs.writeFile(path.resolve(dir, 'package.json'), `${JSON.stringify(packageJSON, null, 2)}\n`); - writeSpinner.succeed(); + await asyncOra('Writing modified package.json file', async () => { + await fs.writeFile(path.resolve(dir, 'package.json'), `${JSON.stringify(packageJSON, null, 2)}\n`); + }); }; let electronVersion; @@ -129,30 +129,30 @@ const main = async () => { await writeChanges(); if (electronName) { - const pruneSpinner = ora.ora('Pruning deleted modules').start(); - await new Promise((resolve) => { - d('attempting to prune node_modules in:', dir); - const child = yarnOrNPMSpawn(hasYarn() ? [] : ['prune'], { - cwd: dir, - stdio: 'ignore', + await asyncOra('Pruning deleted modules', async () => { + await new Promise((resolve) => { + d('attempting to prune node_modules in:', dir); + const child = yarnOrNPMSpawn(hasYarn() ? [] : ['prune'], { + cwd: dir, + stdio: 'ignore', + }); + child.on('exit', () => resolve()); }); - child.on('exit', () => resolve()); }); - pruneSpinner.succeed(); - - const installSpinner = ora.ora('Installing dependencies').start(); - - await fs.remove(path.resolve(dir, 'node_modules/.bin/electron')); - await fs.remove(path.resolve(dir, 'node_modules/.bin/electron.cmd')); - await fs.remove(path.resolve(dir, 'node_modules', electronName)); - d('installing dependencies'); - await installDepList(dir, deps); - d('installing devDependencies'); - await installDepList(dir, devDeps, true); - d('installing electron-prebuilt-compile'); - await installDepList(dir, [`electron-prebuilt-compile@${electronVersion}`], false, true); - installSpinner.succeed(); + await asyncOra('Installing dependencies', async () => { + d('deleting old dependencies forcefully'); + await fs.remove(path.resolve(dir, 'node_modules/.bin/electron')); + await fs.remove(path.resolve(dir, 'node_modules/.bin/electron.cmd')); + await fs.remove(path.resolve(dir, 'node_modules', electronName)); + + d('installing dependencies'); + await installDepList(dir, deps); + d('installing devDependencies'); + await installDepList(dir, devDeps, true); + d('installing electron-prebuilt-compile'); + await installDepList(dir, [`electron-prebuilt-compile@${electronVersion}`], false, true); + }); } packageJSON = await readPackageJSON(dir); @@ -163,14 +163,14 @@ const main = async () => { await writeChanges(); - const gitignoreSpinner = ora.ora('Fixing .gitignore').start(); - if (await fs.exists(path.resolve(dir, '.gitignore'))) { - const gitignore = await fs.readFile(path.resolve(dir, '.gitignore')); - if (!gitignore.includes('out')) { - await fs.writeFile(path.resolve(dir, '.gitignore'), `${gitignore}\nout/`); + await asyncOra('Fixing .gitignore', async () => { + if (await fs.exists(path.resolve(dir, '.gitignore'))) { + const gitignore = await fs.readFile(path.resolve(dir, '.gitignore')); + if (!gitignore.includes('out')) { + await fs.writeFile(path.resolve(dir, '.gitignore'), `${gitignore}\nout/`); + } } - } - gitignoreSpinner.succeed(); + }); let babelConfig = packageJSON.babel; const babelPath = path.resolve(dir, '.babelrc'); @@ -179,19 +179,18 @@ const main = async () => { } if (babelConfig) { - const babelSpinner = ora.ora('Porting original babel config').start(); - - let compileConfig = {}; - const compilePath = path.resolve(dir, '.compilerc'); - if (await fs.exists(compilePath)) { - compileConfig = JSON.parse(await fs.readFile(compilePath, 'utf8')); - } + await asyncOra('Porting original babel config', async () => { + let compileConfig = {}; + const compilePath = path.resolve(dir, '.compilerc'); + if (await fs.exists(compilePath)) { + compileConfig = JSON.parse(await fs.readFile(compilePath, 'utf8')); + } - await fs.writeFile(compilePath, JSON.stringify(Object.assign(compileConfig, { - 'application/javascript': babelConfig, - }), null, 2)); + await fs.writeFile(compilePath, JSON.stringify(Object.assign(compileConfig, { + 'application/javascript': babelConfig, + }), null, 2)); + }); - babelSpinner.succeed(); console.info('NOTE: You might be able to remove your `.compilerc` file completely if you are only using the `es2015` and `react` presets'.yellow); } diff --git a/src/electron-forge-lint.js b/src/electron-forge-lint.js index e443aba336..47d664e2e7 100644 --- a/src/electron-forge-lint.js +++ b/src/electron-forge-lint.js @@ -3,16 +3,15 @@ import debug from 'debug'; import fs from 'fs-promise'; import path from 'path'; import program from 'commander'; -import ora from 'ora'; import { spawn as yarnOrNPMSpawn } from 'yarn-or-npm'; import './util/terminate'; +import asyncOra from './util/ora-handler'; import resolveDir from './util/resolve-dir'; const d = debug('electron-forge:lint'); const main = async () => { - const lintSpinner = ora.ora('Linting Application').start(); let dir = process.cwd(); program .version(require('../package.json').version) @@ -27,31 +26,32 @@ const main = async () => { }) .parse(process.argv); - dir = await resolveDir(dir); - if (!dir) { - lintSpinner.fail(); - console.error('Failed to locate lintable Electron application'.red); - if (global._resolveError) global._resolveError(); - process.exit(1); - } - - d('executing "run lint -- --color" in dir:', dir); - const child = yarnOrNPMSpawn(['run', 'lint', '--', '--color'], { - stdio: process.platform === 'win32' ? 'inherit' : 'pipe', - cwd: dir, - }); - const output = []; - if (process.platform !== 'win32') { - child.stdout.on('data', data => output.push(data.toString())); - child.stderr.on('data', data => output.push(data.toString().red)); - } - child.on('exit', (code) => { - if (code === 0) lintSpinner.succeed(); - if (code !== 0) { + await asyncOra('Linting Application', async (lintSpinner) => { + dir = await resolveDir(dir); + if (!dir) { lintSpinner.fail(); - output.forEach(data => process.stdout.write(data)); - process.exit(code); + console.error('Failed to locate lintable Electron application'.red); + if (global._resolveError) global._resolveError(); + process.exit(1); } + + d('executing "run lint -- --color" in dir:', dir); + const child = yarnOrNPMSpawn(['run', 'lint', '--', '--color'], { + stdio: process.platform === 'win32' ? 'inherit' : 'pipe', + cwd: dir, + }); + const output = []; + if (process.platform !== 'win32') { + child.stdout.on('data', data => output.push(data.toString())); + child.stderr.on('data', data => output.push(data.toString().red)); + } + child.on('exit', (code) => { + if (code !== 0) { + lintSpinner.fail(); + output.forEach(data => process.stdout.write(data)); + process.exit(code); + } + }); }); }; diff --git a/src/electron-forge-make.js b/src/electron-forge-make.js index 0810e718cb..13bfa59941 100644 --- a/src/electron-forge-make.js +++ b/src/electron-forge-make.js @@ -2,9 +2,9 @@ import 'colors'; import fs from 'fs-promise'; import path from 'path'; import program from 'commander'; -import ora from 'ora'; import './util/terminate'; +import asyncOra from './util/ora-handler'; import electronHostArch from './util/electron-host-arch'; import getForgeConfig from './util/forge-config'; import packager from './electron-forge-package'; @@ -13,7 +13,6 @@ import requireSearch from './util/require-search'; import resolveDir from './util/resolve-dir'; const main = async () => { - const resolveSpinner = ora.ora('Resolving Forge Config').start(); let dir = process.cwd(); program .version(require('../package.json').version) @@ -33,15 +32,18 @@ const main = async () => { }) .parse(process.argv); - dir = await resolveDir(dir); - if (!dir) { - resolveSpinner.fail(); - console.error('Failed to locate makeable Electron application'.red); - if (global._resolveError) global._resolveError(); - process.exit(1); - } + let forgeConfig; + await asyncOra('Resolving Forge Config', async (resolveSpinner) => { + dir = await resolveDir(dir); + if (!dir) { + resolveSpinner.fail(); + console.error('Failed to locate makeable Electron application'.red); + if (global._resolveError) global._resolveError(); + process.exit(1); + } - resolveSpinner.succeed(); + forgeConfig = await getForgeConfig(dir); + }); if (program.platform && program.platform !== process.platform && !(process.platform === 'darwin' && program.platform === 'mas')) { console.error('You can not "make" for a platform other than your systems platform'.red); @@ -58,7 +60,6 @@ const main = async () => { const declaredArch = program.arch || electronHostArch(); const declaredPlatform = program.platform || process.platform; - const forgeConfig = await getForgeConfig(dir); let targets = forgeConfig.make_targets[declaredPlatform]; if (program.targets) { targets = program.targets.split(','); @@ -93,24 +94,31 @@ const main = async () => { } for (const target of targets) { - const makeSpinner = ora.ora(`Making for target: ${target.cyan} - On platform: ${declaredPlatform.cyan} - For arch: ${targetArch.cyan}`).start(); - const maker = requireSearch(__dirname, [ - `./makers/${process.platform}/${target}.js`, - `./makers/generic/${target}.js`, - `electron-forge-maker-${target}`, - ]); - if (!maker) { - makeSpinner.fail(); - throw new Error(`Could not find a build target with the name: ${target} for the platform: ${declaredPlatform}`); - } - try { - outputs.push(await (maker.default || maker)(packageDir, appName, targetArch, forgeConfig, packageJSON)); - } catch (err) { - makeSpinner.fail(); - if (err) throw err; - throw new Error(`An error occurred while making for target: ${target}`); - } - makeSpinner.succeed(); + // eslint-disable-next-line no-loop-func + await asyncOra(`Making for target: ${target.cyan} - On platform: ${declaredPlatform.cyan} - For arch: ${targetArch.cyan}`, async () => { + const maker = requireSearch(__dirname, [ + `./makers/${process.platform}/${target}.js`, + `./makers/generic/${target}.js`, + `electron-forge-maker-${target}`, + ]); + if (!maker) { + // eslint-disable-next-line no-throw-literal + throw `Could not find a build target with the name: ${target} for the platform: ${declaredPlatform}`; + } + try { + outputs.push(await (maker.default || maker)(packageDir, appName, targetArch, forgeConfig, packageJSON)); + } catch (err) { + if (err) { + // eslint-disable-next-line no-throw-literal + throw { + message: `An error occured while making for target: ${target}`, + stack: `${err.message}\n${err.stack}`, + }; + } else { + throw new Error(`An unknown error occured while making for target: ${target}`); + } + } + }); } } diff --git a/src/electron-forge-publish.js b/src/electron-forge-publish.js index 3a84b3dbd5..04bf8b36fc 100644 --- a/src/electron-forge-publish.js +++ b/src/electron-forge-publish.js @@ -2,9 +2,9 @@ import 'colors'; import fs from 'fs-promise'; import path from 'path'; import program from 'commander'; -import ora from 'ora'; import './util/terminate'; +import asyncOra from './util/ora-handler'; import getForgeConfig from './util/forge-config'; import readPackageJSON from './util/read-package-json'; import requireSearch from './util/require-search'; @@ -51,17 +51,16 @@ const main = async () => { if (!program.target) program.target = 'github'; - const targetSpinner = ora.ora(`Resolving publish target: ${`${program.target}`.cyan}`).start(); - - const publisher = requireSearch(__dirname, [ - `./publishers/${program.target}.js`, - `electron-forge-publisher-${program.target}`, - ]); - if (!publisher) { - targetSpinner.fail(); - throw new Error(`Could not find a publish target with the name: ${program.target}`); - } - targetSpinner.succeed(); + let publisher; + await asyncOra(`Resolving publish target: ${`${program.target}`.cyan}`, async () => { + publisher = requireSearch(__dirname, [ + `./publishers/${program.target}.js`, + `electron-forge-publisher-${program.target}`, + ]); + if (!publisher) { + throw `Could not find a publish target with the name: ${program.target}`; // eslint-disable-line + } + }); await publisher(artifacts, packageJSON, forgeConfig, program.authToken, program.tag); }; diff --git a/src/electron-forge-start.js b/src/electron-forge-start.js index 6539e378cd..6f04b87622 100644 --- a/src/electron-forge-start.js +++ b/src/electron-forge-start.js @@ -3,15 +3,14 @@ import { spawn } from 'child_process'; import fs from 'fs-promise'; import path from 'path'; import program from 'commander'; -import ora from 'ora'; import './util/terminate'; +import asyncOra from './util/ora-handler'; import readPackageJSON from './util/read-package-json'; import rebuild from './util/rebuild'; import resolveDir from './util/resolve-dir'; const main = async () => { - const locateSpinner = ora.ora('Locating Application').start(); let dir = process.cwd(); program .version(require('../package.json').version) @@ -27,21 +26,20 @@ const main = async () => { }) .parse(process.argv.slice(0, 2)); - dir = await resolveDir(dir); - if (!dir) { - locateSpinner.fail(); - console.error('Failed to locate startable Electron application'.red); - if (global._resolveError) global._resolveError(); - process.exit(1); - } - locateSpinner.succeed(); + await asyncOra('Locating Application', async (locateSpinner) => { + dir = await resolveDir(dir); + if (!dir) { + locateSpinner.fail(); + console.error('Failed to locate startable Electron application'.red); + if (global._resolveError) global._resolveError(); + process.exit(1); + } + }); const packageJSON = await readPackageJSON(dir); await rebuild(dir, packageJSON.devDependencies['electron-prebuilt-compile'], process.platform, process.arch); - const startSpinner = ora.ora('Launching Application').start(); - const spawnOpts = { cwd: dir, stdio: 'inherit', @@ -50,13 +48,13 @@ const main = async () => { ELECTRON_ENABLE_STACK_DUMPING: true, } : {}), }; - if (process.platform === 'win32') { - spawn(path.resolve(dir, 'node_modules/.bin/electron.cmd'), ['.'].concat(process.argv.slice(2)), spawnOpts); - } else { - spawn(path.resolve(dir, 'node_modules/.bin/electron'), ['.'].concat(process.argv.slice(2)), spawnOpts); - } - - startSpinner.succeed(); + await asyncOra('Launching Application', async () => { + if (process.platform === 'win32') { + spawn(path.resolve(dir, 'node_modules/.bin/electron.cmd'), ['.'].concat(process.argv.slice(2)), spawnOpts); + } else { + spawn(path.resolve(dir, 'node_modules/.bin/electron'), ['.'].concat(process.argv.slice(2)), spawnOpts); + } + }); }; main(); diff --git a/src/electron-forge.js b/src/electron-forge.js index eebe53d7be..6e03ea262e 100644 --- a/src/electron-forge.js +++ b/src/electron-forge.js @@ -1,34 +1,37 @@ #!/usr/bin/env node import 'colors'; -import ora from 'ora'; import program from 'commander'; import './util/terminate'; +import asyncOra from './util/ora-handler'; import checkSystem from './util/check-system'; import config from './util/config'; -const checker = ora('Checking your System').start(); -checkSystem() - .then((goodSystem) => { - checker.succeed(); - if (!goodSystem) { - console.error(('It looks like you are missing some dependencies you need to get Electron running.\n' + - 'Make sure you have git installed and Node.js version 6.0.0+').red); - process.exit(1); - } - program - .version(require('../package.json').version) - .option('--verbose', 'Enables verbose mode') - .command('init', 'Initialize a new Electron application') - .command('import', 'Attempts to navigate you through the process of importing an existing project to "electron-forge"') - .command('lint', 'Lints the current Electron application') - .command('package', 'Package the current Electron application') - .command('make', 'Generate distributables for the current Electron application') - .command('start', 'Start the current Electron application') - .command('publish', 'Publish the current Electron application to GitHub') - .parse(process.argv); - - config.reset(); - config.set('verbose', !!program.verbose); +(async () => { + let goodSystem; + await asyncOra('Checking your system', async () => { + goodSystem = await checkSystem(); }); + + if (!goodSystem) { + console.error(('It looks like you are missing some dependencies you need to get Electron running.\n' + + 'Make sure you have git installed and Node.js version 6.0.0+').red); + process.exit(1); + } + + program + .version(require('../package.json').version) + .option('--verbose', 'Enables verbose mode') + .command('init', 'Initialize a new Electron application') + .command('import', 'Attempts to navigate you through the process of importing an existing project to "electron-forge"') + .command('lint', 'Lints the current Electron application') + .command('package', 'Package the current Electron application') + .command('make', 'Generate distributables for the current Electron application') + .command('start', 'Start the current Electron application') + .command('publish', 'Publish the current Electron application to GitHub') + .parse(process.argv); + + config.reset(); + config.set('verbose', !!program.verbose); +})(); diff --git a/src/init/init-custom.js b/src/init/init-custom.js index 9e929a0585..20b836cdcc 100644 --- a/src/init/init-custom.js +++ b/src/init/init-custom.js @@ -6,58 +6,51 @@ import ora from 'ora'; import path from 'path'; import { copy } from './init-starter-files'; +import asyncOra from '../util/ora-handler'; import installDepList from '../util/install-dependencies'; const d = debug('electron-forge:init:custom'); export default async (dir, template, lintStyle) => { - const resolveSpinner = ora.ora(`Locating custom template: "${template}"`).start(); let templateModulePath; - try { - templateModulePath = await resolvePackage(`electron-forge-template-${template}`); - } catch (err) { - resolveSpinner.fail(); - throw new Error(`Failed to locate custom template: "${template}"\n\nTry \`npm install -g electron-forge-template-${template}\``); - } - resolveSpinner.succeed(); + await asyncOra(`Locating custom template: "${template}"`, async () => { + try { + templateModulePath = await resolvePackage(`electron-forge-template-${template}`); + } catch (err) { + // eslint-disable-next-line no-throw-literal + throw `Failed to locate custom template: "${template}"\n\nTry \`npm install -g electron-forge-template-${template}\``; + } + }); let templateModule = require(templateModulePath); templateModule = templateModule.default || templateModule; - const installSpinner = ora.ora('Installing Template Dependencies').start(); - - try { + await asyncOra('Installing Template Dependencies', async () => { d('installing dependencies'); await installDepList(dir, templateModule.dependencies || []); d('installing devDependencies'); await installDepList(dir, templateModule.devDependencies || [], true); - } catch (err) { - installSpinner.fail(); - throw err; - } - - installSpinner.succeed(); - - const copySpinner = ora.ora('Copying Template Files').start(); - const templateDirectory = templateModule.templateDirectory; - if (templateDirectory) { - const tmplPath = templateDirectory; - if (!path.isAbsolute(templateDirectory)) { - copySpinner.fail(); - throw new Error(`Custom template path needs to be absolute, this is an issue with "electron-forge-template-${template}"`); - } + }); + + await asyncOra('Copying Template Files', async () => { + const templateDirectory = templateModule.templateDirectory; + if (templateDirectory) { + const tmplPath = templateDirectory; + if (!path.isAbsolute(templateDirectory)) { + // eslint-disable-next-line no-throw-literal + throw `Custom template path needs to be absolute, this is an issue with "electron-forge-template-${template}"`; + } - const files = glob.sync(path.resolve(tmplPath, '**/*')); + const files = glob.sync(path.resolve(tmplPath, '**/*')); - for (const file of files) { - if ((await fs.stat(file)).isFile()) { - await copy(file, path.resolve(dir, path.relative(tmplPath, file).replace(/^_/, '.'))); + for (const file of files) { + if ((await fs.stat(file)).isFile()) { + await copy(file, path.resolve(dir, path.relative(tmplPath, file).replace(/^_/, '.'))); + } } } - } - - copySpinner.succeed(); + }); if (typeof templateModule.postCopy === 'function') { await Promise.resolve(templateModule.postCopy(dir, ora.ora, lintStyle)); diff --git a/src/init/init-directory.js b/src/init/init-directory.js index 036b31a125..4a13441b60 100644 --- a/src/init/init-directory.js +++ b/src/init/init-directory.js @@ -2,29 +2,28 @@ import debug from 'debug'; import fs from 'fs-promise'; import inquirer from 'inquirer'; import logSymbols from 'log-symbols'; -import ora from 'ora'; + +import asyncOra from '../util/ora-handler'; const d = debug('electron-forge:init:directory'); export default async (dir) => { - const initSpinner = ora.ora('Initializing Project Directory').start(); - - d('creating directory:', dir); - await fs.mkdirs(dir); + await asyncOra('Initializing Project Directory', async (initSpinner) => { + d('creating directory:', dir); + await fs.mkdirs(dir); - const files = await fs.readdir(dir); - if (files.length !== 0) { - d('found', files.length, 'files in the directory. warning the user'); - initSpinner.stop(logSymbols.warning); - const { confirm } = await inquirer.createPromptModule()({ - type: 'confirm', - name: 'confirm', - message: `WARNING: The specified path: "${dir}" is not empty, do you wish to continue?`, - }); - if (!confirm) { - initSpinner.fail(); - process.exit(1); + const files = await fs.readdir(dir); + if (files.length !== 0) { + d('found', files.length, 'files in the directory. warning the user'); + initSpinner.stop(logSymbols.warning); + const { confirm } = await inquirer.createPromptModule()({ + type: 'confirm', + name: 'confirm', + message: `WARNING: The specified path: "${dir}" is not empty, do you wish to continue?`, + }); + if (!confirm) { + throw 'Cancelled by user'; // eslint-disable-line + } } - } - initSpinner.succeed(); + }); }; diff --git a/src/init/init-git.js b/src/init/init-git.js index 04186f3cb7..80190619b2 100644 --- a/src/init/init-git.js +++ b/src/init/init-git.js @@ -1,25 +1,26 @@ import { exec } from 'child_process'; import debug from 'debug'; import fs from 'fs-promise'; -import ora from 'ora'; import path from 'path'; +import asyncOra from '../util/ora-handler'; + const d = debug('electron-forge:init:git'); -export default async dir => - new Promise(async (resolve, reject) => { - const spinner = ora.ora('Initializing Git Repository').start(); - if (await fs.exists(path.resolve(dir, '.git'))) { - d('.git directory already exists, skipping git initialization'); - spinner.succeed(); - return resolve(); - } - d('executing "git init" in directory:', dir); - exec('git init', { - cwd: dir, - }, (err) => { - if (err) return spinner.fail() && reject(err); - spinner.succeed(); - resolve(); +export default async (dir) => { + await asyncOra('Initializing Git Repository', async () => { + await new Promise(async (resolve, reject) => { + if (await fs.exists(path.resolve(dir, '.git'))) { + d('.git directory already exists, skipping git initialization'); + return resolve(); + } + d('executing "git init" in directory:', dir); + exec('git init', { + cwd: dir, + }, (err) => { + if (err) return reject(err); + resolve(); + }); }); }); +}; diff --git a/src/init/init-npm.js b/src/init/init-npm.js index 2d1287c8b8..5b72251973 100644 --- a/src/init/init-npm.js +++ b/src/init/init-npm.js @@ -1,11 +1,11 @@ import debug from 'debug'; import fs from 'fs-promise'; -import ora from 'ora'; import path from 'path'; import username from 'username'; import installDepList from '../util/install-dependencies'; import readPackageJSON from '../util/read-package-json'; +import asyncOra from '../util/ora-handler'; const d = debug('electron-forge:init:npm'); @@ -17,29 +17,27 @@ export const airbnDeps = ['eslint', 'eslint-config-airbnb', 'eslint-plugin-impor 'eslint-plugin-jsx-a11y@^2.2.3', 'eslint-plugin-react']; export default async (dir, lintStyle) => { - const initSpinner = ora.ora('Initializing NPM Module').start(); - const packageJSON = await readPackageJSON(path.resolve(__dirname, '../../tmpl')); - packageJSON.productName = packageJSON.name = path.basename(dir).toLowerCase(); - packageJSON.config.forge.electronWinstallerConfig.name = packageJSON.name.replace(/-/g, '_'); - packageJSON.author = await username(); - switch (lintStyle) { - case 'standard': - packageJSON.scripts.lint = 'standard'; - break; - case 'airbnb': - packageJSON.scripts.lint = 'eslint src'; - break; - default: - packageJSON.scripts.lint = 'echo "No linting configured"'; - break; - } - d('writing package.json to:', dir); - await fs.writeFile(path.resolve(dir, 'package.json'), JSON.stringify(packageJSON, null, 4)); - initSpinner.succeed(); - - const installSpinner = ora.ora('Installing NPM Dependencies').start(); + await asyncOra('Initializing NPM Module', async () => { + const packageJSON = await readPackageJSON(path.resolve(__dirname, '../../tmpl')); + packageJSON.productName = packageJSON.name = path.basename(dir).toLowerCase(); + packageJSON.config.forge.electronWinstallerConfig.name = packageJSON.name.replace(/-/g, '_'); + packageJSON.author = await username(); + switch (lintStyle) { + case 'standard': + packageJSON.scripts.lint = 'standard'; + break; + case 'airbnb': + packageJSON.scripts.lint = 'eslint src'; + break; + default: + packageJSON.scripts.lint = 'echo "No linting configured"'; + break; + } + d('writing package.json to:', dir); + await fs.writeFile(path.resolve(dir, 'package.json'), JSON.stringify(packageJSON, null, 4)); + }); - try { + await asyncOra('Installing NPM Dependencies', async () => { d('installing dependencies'); await installDepList(dir, deps); d('installing devDependencies'); @@ -61,10 +59,5 @@ export default async (dir, lintStyle) => { d('not installing linting deps'); break; } - } catch (err) { - installSpinner.fail(); - throw err; - } - - installSpinner.succeed(); + }); }; diff --git a/src/init/init-standard-fix.js b/src/init/init-standard-fix.js index 334f049f0e..d5b9f92434 100644 --- a/src/init/init-standard-fix.js +++ b/src/init/init-standard-fix.js @@ -1,7 +1,8 @@ import debug from 'debug'; -import ora from 'ora'; import { spawn as yarnOrNPMSpawn } from 'yarn-or-npm'; +import asyncOra from '../util/ora-handler'; + const d = debug('electron-forge:init:standard-fix'); const run = dir => @@ -18,13 +19,8 @@ const run = dir => }); export default async (dir) => { - const initSpinner = ora.ora('Applying Standard Style to JS').start(); - try { + await asyncOra('Applying Standard Style to JS', async () => { d('executing "standard --fix" in:', dir); await run(dir); - } catch (err) { - initSpinner.fail(); - throw err; - } - initSpinner.succeed(); + }); }; diff --git a/src/init/init-starter-files.js b/src/init/init-starter-files.js index 0cef90a21e..0cc96b7961 100644 --- a/src/init/init-starter-files.js +++ b/src/init/init-starter-files.js @@ -1,8 +1,9 @@ import debug from 'debug'; import fs from 'fs-promise'; -import ora from 'ora'; import path from 'path'; +import asyncOra from '../util/ora-handler'; + const d = debug('electron-forge:init:starter-files'); export const copy = (source, target) => @@ -24,21 +25,20 @@ export const copy = (source, target) => }); export default async (dir, lintStyle) => { - const initSpinner = ora.ora('Copying Starter Files').start(); - const tmplPath = path.resolve(__dirname, '../../tmpl'); + await asyncOra('Copying Starter Files', async () => { + const tmplPath = path.resolve(__dirname, '../../tmpl'); - d('creating directory:', path.resolve(dir, 'src')); - await fs.mkdirs(path.resolve(dir, 'src')); - const rootFiles = ['_gitignore']; - if (lintStyle === 'airbnb') rootFiles.push('_eslintrc'); - const srcFiles = ['index.js', 'index.html']; + d('creating directory:', path.resolve(dir, 'src')); + await fs.mkdirs(path.resolve(dir, 'src')); + const rootFiles = ['_gitignore']; + if (lintStyle === 'airbnb') rootFiles.push('_eslintrc'); + const srcFiles = ['index.js', 'index.html']; - rootFiles.forEach(async (file) => { - await copy(path.resolve(tmplPath, file), path.resolve(dir, file.replace(/^_/, '.'))); - }); - srcFiles.forEach(async (file) => { - await copy(path.resolve(tmplPath, file), path.resolve(dir, 'src', file)); + rootFiles.forEach(async (file) => { + await copy(path.resolve(tmplPath, file), path.resolve(dir, file.replace(/^_/, '.'))); + }); + srcFiles.forEach(async (file) => { + await copy(path.resolve(tmplPath, file), path.resolve(dir, 'src', file)); + }); }); - - initSpinner.succeed(); }; diff --git a/src/publishers/github.js b/src/publishers/github.js index e843175834..3cf40d9eb8 100644 --- a/src/publishers/github.js +++ b/src/publishers/github.js @@ -1,5 +1,6 @@ -import ora from 'ora'; import path from 'path'; + +import asyncOra from '../util/ora-handler'; import GitHub from '../util/github'; export default async (artifacts, packageJSON, forgeConfig, authToken, tag) => { @@ -12,38 +13,39 @@ export default async (artifacts, packageJSON, forgeConfig, authToken, tag) => { const github = new GitHub(authToken); let release; - try { - release = (await github.getGitHub().repos.getReleases({ - owner: forgeConfig.github_repository.owner, - repo: forgeConfig.github_repository.name, - per_page: 100, - })).find(testRelease => testRelease.tag_name === (tag || `v${packageJSON.version}`)); - if (!release) { - throw { code: 404 }; // eslint-disable-line - } - } catch (err) { - if (err.code === 404) { - // Release does not exist, let's make it - release = await github.getGitHub().repos.createRelease({ + await asyncOra('Searching for target Release', async () => { + try { + release = (await github.getGitHub().repos.getReleases({ owner: forgeConfig.github_repository.owner, repo: forgeConfig.github_repository.name, - tag_name: tag || `v${packageJSON.version}`, - name: tag || `v${packageJSON.version}`, - draft: true, - }); - } else { - // Unknown error - throw err; + per_page: 100, + })).find(testRelease => testRelease.tag_name === (tag || `v${packageJSON.version}`)); + if (!release) { + throw { code: 404 }; // eslint-disable-line + } + } catch (err) { + if (err.code === 404) { + // Release does not exist, let's make it + release = await github.getGitHub().repos.createRelease({ + owner: forgeConfig.github_repository.owner, + repo: forgeConfig.github_repository.name, + tag_name: tag || `v${packageJSON.version}`, + name: tag || `v${packageJSON.version}`, + draft: true, + }); + } else { + // Unknown error + throw err; + } } - } + }); let uploaded = 0; - const uploadSpinner = ora.ora(`Uploading Artifacts ${uploaded}/${artifacts.length}`).start(); - const updateSpinner = () => { - uploadSpinner.text = `Uploading Artifacts ${uploaded}/${artifacts.length}`; - }; + await asyncOra(`Uploading Artifacts ${uploaded}/${artifacts.length}`, async (uploadSpinner) => { + const updateSpinner = () => { + uploadSpinner.text = `Uploading Artifacts ${uploaded}/${artifacts.length}`; // eslint-disable-line + }; - try { await Promise.all(artifacts.map(artifactPath => new Promise(async (resolve) => { const done = () => { @@ -64,10 +66,5 @@ export default async (artifacts, packageJSON, forgeConfig, authToken, tag) => { return done(); }) )); - } catch (err) { - updateSpinner.fail(); - throw err; - } - - uploadSpinner.succeed(); + }); }; diff --git a/src/util/compile-hook.js b/src/util/compile-hook.js index 48bbe5f69a..32c100ad62 100644 --- a/src/util/compile-hook.js +++ b/src/util/compile-hook.js @@ -1,43 +1,42 @@ import fs from 'fs-promise'; -import ora from 'ora'; import path from 'path'; + +import asyncOra from './ora-handler'; import readPackageJSON from './read-package-json'; export default async(originalDir, buildPath, electronVersion, pPlatform, pArch, done) => { - const compileSpinner = ora.ora('Compiling Application').start(); - - const compileCLI = require(path.resolve(originalDir, 'node_modules/electron-compile/lib/cli.js')); - - async function compileAndShim(appDir) { - for (const entry of await fs.readdir(appDir)) { - if (!entry.match(/^(node_modules|bower_components)$/)) { - const fullPath = path.join(appDir, entry); - - if ((await fs.stat(fullPath)).isDirectory()) { - const log = console.log; - console.log = () => {}; - await compileCLI.main(appDir, [fullPath]); - console.log = log; + await asyncOra('Compiling Application', async () => { + const compileCLI = require(path.resolve(originalDir, 'node_modules/electron-compile/lib/cli.js')); + + async function compileAndShim(appDir) { + for (const entry of await fs.readdir(appDir)) { + if (!entry.match(/^(node_modules|bower_components)$/)) { + const fullPath = path.join(appDir, entry); + + if ((await fs.stat(fullPath)).isDirectory()) { + const log = console.log; + console.log = () => {}; + await compileCLI.main(appDir, [fullPath]); + console.log = log; + } } } - } - - const packageJSON = await readPackageJSON(appDir); - const index = packageJSON.main || 'index.js'; - packageJSON.originalMain = index; - packageJSON.main = 'es6-shim.js'; + const packageJSON = await readPackageJSON(appDir); - await fs.writeFile(path.join(appDir, 'es6-shim.js'), - await fs.readFile(path.join(path.resolve(originalDir, 'node_modules/electron-compile/lib/es6-shim.js')), 'utf8')); + const index = packageJSON.main || 'index.js'; + packageJSON.originalMain = index; + packageJSON.main = 'es6-shim.js'; - await fs.writeFile( - path.join(appDir, 'package.json'), - JSON.stringify(packageJSON, null, 2)); - } + await fs.writeFile(path.join(appDir, 'es6-shim.js'), + await fs.readFile(path.join(path.resolve(originalDir, 'node_modules/electron-compile/lib/es6-shim.js')), 'utf8')); - await compileAndShim(buildPath); + await fs.writeFile( + path.join(appDir, 'package.json'), + JSON.stringify(packageJSON, null, 2)); + } - compileSpinner.succeed(); + await compileAndShim(buildPath); + }); done(); }; diff --git a/src/util/ora-handler.js b/src/util/ora-handler.js new file mode 100644 index 0000000000..85021ffca9 --- /dev/null +++ b/src/util/ora-handler.js @@ -0,0 +1,23 @@ +import colors from 'colors'; +import ora from 'ora'; + +export default (initalOraValue, asyncFn) => { + const fnOra = ora.ora(initalOraValue).start(); + return new Promise((resolve) => { + asyncFn(fnOra).then(() => { + fnOra.succeed(); + resolve(); + }).catch((err) => { + fnOra.fail(); + if (err && err.message && err.stack) { + console.error('\nAn unhandled error has occurred inside Forge:'); + console.error(colors.red(err.message)); + console.error(colors.red(err.stack)); + } else { + console.error('\nElectron forge was terminated:'.red); + console.error(colors.red(JSON.stringify(err))); + } + process.exit(1); + }); + }); +}; diff --git a/src/util/rebuild.js b/src/util/rebuild.js index 946e996f7c..a861d78679 100644 --- a/src/util/rebuild.js +++ b/src/util/rebuild.js @@ -1,11 +1,12 @@ import { spawn } from 'child_process'; import debug from 'debug'; import fs from 'fs-promise'; -import ora from 'ora'; import os from 'os'; import path from 'path'; import readPackageJSON from './read-package-json'; +import asyncOra from './ora-handler'; + const d = debug('electron-forge:rebuild'); export default async (buildPath, electronVersion, pPlatform, pArch) => { @@ -14,132 +15,127 @@ export default async (buildPath, electronVersion, pPlatform, pArch) => { let rebuildCompleteCount = 0; const prodDeps = {}; - const nativeSpinner = ora.ora(`Preparing native dependencies ${rebuildCompleteCount}/${rebuildCount}`).start(); - const updateNativeSpinner = () => { - nativeSpinner.text = `Preparing native dependencies ${rebuildCompleteCount}/${rebuildCount}`; - }; + await asyncOra(`Preparing native dependencies ${rebuildCompleteCount}/${rebuildCount}`, async (nativeSpinner) => { + const updateNativeSpinner = () => { + nativeSpinner.text = `Preparing native dependencies ${rebuildCompleteCount}/${rebuildCount}`; // eslint-disable-line + }; - const rebuildModuleAt = async (modulePath) => { - if (await fs.exists(path.resolve(modulePath, 'binding.gyp'))) { - const metaPath = path.resolve(modulePath, 'build', 'Release', '.forge-meta'); - rebuildCount += 1; - updateNativeSpinner(); - if (await fs.exists(metaPath)) { - const meta = await fs.readFile(metaPath, 'utf8'); - if (meta === pArch) { - d(`skipping: ${path.basename(modulePath)} as it is already built`); - rebuildCompleteCount += 1; - updateNativeSpinner(); - return; + const rebuildModuleAt = async (modulePath) => { + if (await fs.exists(path.resolve(modulePath, 'binding.gyp'))) { + const metaPath = path.resolve(modulePath, 'build', 'Release', '.forge-meta'); + rebuildCount += 1; + updateNativeSpinner(); + if (await fs.exists(metaPath)) { + const meta = await fs.readFile(metaPath, 'utf8'); + if (meta === pArch) { + d(`skipping: ${path.basename(modulePath)} as it is already built`); + rebuildCompleteCount += 1; + updateNativeSpinner(); + return; + } } - } - d('rebuilding:', path.basename(modulePath)); - const rebuildArgs = [ - 'rebuild', - `--target=${electronVersion}`, - `--arch=${pArch}`, - '--dist-url=https://atom.io/download/electron', - '--build-from-source', - ]; - - const modulePackageJSON = await readPackageJSON(modulePath); - Object.keys(modulePackageJSON.binary || {}).forEach((binaryKey) => { - let value = modulePackageJSON.binary[binaryKey]; - if (binaryKey === 'module_path') { - value = path.resolve(modulePath, value); - } - rebuildArgs.push(`--${binaryKey}=${value}`); - }); + d('rebuilding:', path.basename(modulePath)); + const rebuildArgs = [ + 'rebuild', + `--target=${electronVersion}`, + `--arch=${pArch}`, + '--dist-url=https://atom.io/download/electron', + '--build-from-source', + ]; - await new Promise((resolve, reject) => { - const child = spawn(path.resolve(__dirname, `../../node_modules/.bin/node-gyp${process.platform === 'win32' ? '.cmd' : ''}`), rebuildArgs, { - cwd: modulePath, - env: Object.assign({}, process.env, { - HOME: path.resolve(os.homedir(), '.electron-gyp'), - USERPROFILE: path.resolve(os.homedir(), '.electron-gyp'), - npm_config_disturl: 'https://atom.io/download/electron', - npm_config_runtime: 'electron', - npm_config_arch: pArch, - npm_config_target_arch: pArch, - npm_config_build_from_source: true, - }), + const modulePackageJSON = await readPackageJSON(modulePath); + Object.keys(modulePackageJSON.binary || {}).forEach((binaryKey) => { + let value = modulePackageJSON.binary[binaryKey]; + if (binaryKey === 'module_path') { + value = path.resolve(modulePath, value); + } + rebuildArgs.push(`--${binaryKey}=${value}`); }); - let output = ''; - child.stdout.on('data', (data) => { output += data; }); - child.stderr.on('data', (data) => { output += data; }); - child.on('exit', async (code) => { - d('built:', path.basename(modulePath)); - if (code !== 0) return reject(new Error(`Failed to rebuild: ${modulePath}\n\n${output}`)); - await fs.mkdirs(path.dirname(metaPath)); - await fs.writeFile(metaPath, pArch); - rebuildCompleteCount += 1; - updateNativeSpinner(); - resolve(); - }); - }); - } - }; - const rebuildAllModulesIn = (nodeModulesPath, prefix = '') => { - d('scanning:', nodeModulesPath); - for (const modulePath of fs.readdirSync(nodeModulesPath)) { - if (prodDeps[`${prefix}${modulePath}`]) { - rebuilds.push(rebuildModuleAt(path.resolve(nodeModulesPath, modulePath))); + await new Promise((resolve, reject) => { + const child = spawn(path.resolve(__dirname, `../../node_modules/.bin/node-gyp${process.platform === 'win32' ? '.cmd' : ''}`), rebuildArgs, { + cwd: modulePath, + env: Object.assign({}, process.env, { + HOME: path.resolve(os.homedir(), '.electron-gyp'), + USERPROFILE: path.resolve(os.homedir(), '.electron-gyp'), + npm_config_disturl: 'https://atom.io/download/electron', + npm_config_runtime: 'electron', + npm_config_arch: pArch, + npm_config_target_arch: pArch, + npm_config_build_from_source: true, + }), + }); + let output = ''; + child.stdout.on('data', (data) => { output += data; }); + child.stderr.on('data', (data) => { output += data; }); + child.on('exit', async (code) => { + d('built:', path.basename(modulePath)); + if (code !== 0) return reject(new Error(`Failed to rebuild: ${modulePath}\n\n${output}`)); + await fs.mkdirs(path.dirname(metaPath)); + await fs.writeFile(metaPath, pArch); + rebuildCompleteCount += 1; + updateNativeSpinner(); + resolve(); + }); + }); } - if (modulePath.startsWith('@')) { - rebuildAllModulesIn(path.resolve(nodeModulesPath, modulePath), `${modulePath}/`); + }; + + const rebuildAllModulesIn = (nodeModulesPath, prefix = '') => { + d('scanning:', nodeModulesPath); + for (const modulePath of fs.readdirSync(nodeModulesPath)) { + if (prodDeps[`${prefix}${modulePath}`]) { + rebuilds.push(rebuildModuleAt(path.resolve(nodeModulesPath, modulePath))); + } + if (modulePath.startsWith('@')) { + rebuildAllModulesIn(path.resolve(nodeModulesPath, modulePath), `${modulePath}/`); + } + if (fs.existsSync(path.resolve(nodeModulesPath, modulePath, 'node_modules'))) { + rebuildAllModulesIn(path.resolve(nodeModulesPath, modulePath, 'node_modules')); + } } - if (fs.existsSync(path.resolve(nodeModulesPath, modulePath, 'node_modules'))) { - rebuildAllModulesIn(path.resolve(nodeModulesPath, modulePath, 'node_modules')); + }; + + const findModule = async (moduleName, fromDir, foundFn) => { + let targetDir = fromDir; + const foundFns = []; + while (targetDir !== buildPath) { + const testPath = path.resolve(targetDir, 'node_modules', moduleName); + if (await fs.exists(testPath)) { + foundFns.push(foundFn(testPath)); + } + targetDir = path.dirname(targetDir); } - } - }; + await Promise.all(foundFns); + }; - const findModule = async (moduleName, fromDir, foundFn) => { - let targetDir = fromDir; - const foundFns = []; - while (targetDir !== buildPath) { - const testPath = path.resolve(targetDir, 'node_modules', moduleName); - if (await fs.exists(testPath)) { - foundFns.push(foundFn(testPath)); + const markChildrenAsProdDeps = async (modulePath) => { + d('exploring:', modulePath); + let childPackageJSON; + try { + childPackageJSON = await readPackageJSON(modulePath); + } catch (err) { + return; } - targetDir = path.dirname(targetDir); - } - await Promise.all(foundFns); - }; + const moduleWait = []; + Object.keys(childPackageJSON.dependencies || {}).forEach((key) => { + if (prodDeps[key]) return; + prodDeps[key] = true; + moduleWait.push(findModule(key, modulePath, markChildrenAsProdDeps)); + }); + await Promise.all(moduleWait); + }; - const markChildrenAsProdDeps = async (modulePath) => { - d('exploring:', modulePath); - let childPackageJSON; - try { - childPackageJSON = await readPackageJSON(modulePath); - } catch (err) { - return; - } - const moduleWait = []; - Object.keys(childPackageJSON.dependencies || {}).forEach((key) => { - if (prodDeps[key]) return; + const rootPackageJSON = await readPackageJSON(buildPath); + const markWaiters = []; + Object.keys(rootPackageJSON.dependencies || {}).concat(Object.keys(rootPackageJSON.optionalDependencies || {})).forEach((key) => { prodDeps[key] = true; - moduleWait.push(findModule(key, modulePath, markChildrenAsProdDeps)); + markWaiters.push(markChildrenAsProdDeps(path.resolve(buildPath, 'node_modules', key))); }); - await Promise.all(moduleWait); - }; - - const rootPackageJSON = await readPackageJSON(buildPath); - const markWaiters = []; - Object.keys(rootPackageJSON.dependencies || {}).concat(Object.keys(rootPackageJSON.optionalDependencies || {})).forEach((key) => { - prodDeps[key] = true; - markWaiters.push(markChildrenAsProdDeps(path.resolve(buildPath, 'node_modules', key))); - }); - await Promise.all(markWaiters); + await Promise.all(markWaiters); - rebuildAllModulesIn(path.resolve(buildPath, 'node_modules')); - try { + rebuildAllModulesIn(path.resolve(buildPath, 'node_modules')); await Promise.all(rebuilds); - } catch (err) { - nativeSpinner.fail(); - throw err; - } - nativeSpinner.succeed(); + }); }; From a2c609b31621a420fdbe28a49e9bcbc960e52231 Mon Sep 17 00:00:00 2001 From: Samuel Attard Date: Sat, 31 Dec 2016 15:52:16 +1300 Subject: [PATCH 2/2] refactor(generic): remove the global._resolveError logic --- src/electron-forge-lint.js | 6 ++---- src/electron-forge-make.js | 8 +++----- src/electron-forge-package.js | 6 ++---- src/electron-forge-publish.js | 5 ++--- src/electron-forge-start.js | 8 +++----- src/util/ora-handler.js | 4 ++-- src/util/resolve-dir.js | 8 ++++---- src/util/terminate.js | 20 ++++++++++++++++---- 8 files changed, 34 insertions(+), 31 deletions(-) diff --git a/src/electron-forge-lint.js b/src/electron-forge-lint.js index 47d664e2e7..33a287b34a 100644 --- a/src/electron-forge-lint.js +++ b/src/electron-forge-lint.js @@ -29,10 +29,8 @@ const main = async () => { await asyncOra('Linting Application', async (lintSpinner) => { dir = await resolveDir(dir); if (!dir) { - lintSpinner.fail(); - console.error('Failed to locate lintable Electron application'.red); - if (global._resolveError) global._resolveError(); - process.exit(1); + // eslint-disable-next-line no-throw-literal + throw 'Failed to locate lintable Electron application'; } d('executing "run lint -- --color" in dir:', dir); diff --git a/src/electron-forge-make.js b/src/electron-forge-make.js index 13bfa59941..3807b6a7cd 100644 --- a/src/electron-forge-make.js +++ b/src/electron-forge-make.js @@ -33,13 +33,11 @@ const main = async () => { .parse(process.argv); let forgeConfig; - await asyncOra('Resolving Forge Config', async (resolveSpinner) => { + await asyncOra('Resolving Forge Config', async () => { dir = await resolveDir(dir); if (!dir) { - resolveSpinner.fail(); - console.error('Failed to locate makeable Electron application'.red); - if (global._resolveError) global._resolveError(); - process.exit(1); + // eslint-disable-next-line no-throw-literal + throw 'Failed to locate makeable Electron application'; } forgeConfig = await getForgeConfig(dir); diff --git a/src/electron-forge-package.js b/src/electron-forge-package.js index 18a52de108..06ca846af8 100644 --- a/src/electron-forge-package.js +++ b/src/electron-forge-package.js @@ -44,10 +44,8 @@ const main = async () => { dir = await resolveDir(dir); if (!dir) { - prepareSpinner.fail(); - console.error('Failed to locate compilable Electron application'.red); - if (global._resolveError) global._resolveError(); - process.exit(1); + // eslint-disable-next-line no-throw-literal + throw 'Failed to locate compilable Electron application'; } const packageJSON = await readPackageJSON(dir); diff --git a/src/electron-forge-publish.js b/src/electron-forge-publish.js index 04bf8b36fc..ec3f600369 100644 --- a/src/electron-forge-publish.js +++ b/src/electron-forge-publish.js @@ -35,9 +35,8 @@ const main = async () => { dir = await resolveDir(dir); if (!dir) { - console.error('Failed to locate publishable Electron application'.red); - if (global._resolveError) global._resolveError(); - process.exit(1); + // eslint-disable-next-line no-throw-literal + throw 'Failed to locate publishable Electron application'; } const artifacts = makeResults.reduce((accum, arr) => { diff --git a/src/electron-forge-start.js b/src/electron-forge-start.js index 6f04b87622..63746ec455 100644 --- a/src/electron-forge-start.js +++ b/src/electron-forge-start.js @@ -26,13 +26,11 @@ const main = async () => { }) .parse(process.argv.slice(0, 2)); - await asyncOra('Locating Application', async (locateSpinner) => { + await asyncOra('Locating Application', async () => { dir = await resolveDir(dir); if (!dir) { - locateSpinner.fail(); - console.error('Failed to locate startable Electron application'.red); - if (global._resolveError) global._resolveError(); - process.exit(1); + // eslint-disable-next-line no-throw-literal + throw 'Failed to locate startable Electron application'; } }); diff --git a/src/util/ora-handler.js b/src/util/ora-handler.js index 85021ffca9..7162cd3ac2 100644 --- a/src/util/ora-handler.js +++ b/src/util/ora-handler.js @@ -10,12 +10,12 @@ export default (initalOraValue, asyncFn) => { }).catch((err) => { fnOra.fail(); if (err && err.message && err.stack) { - console.error('\nAn unhandled error has occurred inside Forge:'); + console.error('\nAn unhandled error has occurred inside Forge:'.red); console.error(colors.red(err.message)); console.error(colors.red(err.stack)); } else { console.error('\nElectron forge was terminated:'.red); - console.error(colors.red(JSON.stringify(err))); + console.error(colors.red(typeof err === 'string' ? err : JSON.stringify(err))); } process.exit(1); }); diff --git a/src/util/resolve-dir.js b/src/util/resolve-dir.js index fd10201406..3f1998b151 100644 --- a/src/util/resolve-dir.js +++ b/src/util/resolve-dir.js @@ -17,12 +17,12 @@ export default async (dir) => { if (packageJSON.devDependencies && packageJSON.devDependencies['electron-prebuilt-compile']) { if (!/[0-9]/.test(packageJSON.devDependencies['electron-prebuilt-compile'][0])) { - global._resolveError = () => console.error('You must depend on an EXACT version of "electron-prebuilt-compile" not a range'.red); - return null; + // eslint-disable-next-line no-throw-literal + throw 'You must depend on an EXACT version of "electron-prebuilt-compile" not a range'; } } else { - global._resolveError = () => console.error('You must depend on "electron-prebuilt-compile" in your devDependencies'.red); - return null; + // eslint-disable-next-line no-throw-literal + throw 'You must depend on "electron-prebuilt-compile" in your devDependencies'; } if (packageJSON.config && packageJSON.config.forge) { diff --git a/src/util/terminate.js b/src/util/terminate.js index bd3f4f8bf7..91f07fda96 100644 --- a/src/util/terminate.js +++ b/src/util/terminate.js @@ -5,14 +5,26 @@ import ora from 'ora'; const d = debug('electron-forge:lifecycle'); process.on('unhandledRejection', (err) => { - process.stdout.write('\n\nAn unhandled rejection has occurred inside Forge:\n'); - console.error(colors.red(err.stack || JSON.stringify(err))); + if (err && err.message && err.stack) { + console.error('\nAn unhandled rejection has occurred inside Forge:'.red); + console.error(colors.red(err.message)); + console.error(colors.red(err.stack)); + } else { + console.error('\nElectron forge was terminated:'.red); + console.error(colors.red(typeof err === 'string' ? err : JSON.stringify(err))); + } process.exit(1); }); process.on('uncaughtException', (err) => { - process.stdout.write('\n\nAn unhandled exception has occurred inside Forge:\n'); - console.error(colors.red(err.stack || JSON.stringify(err))); + if (err && err.message && err.stack) { + console.error('\nAn unhandled exception has occurred inside Forge:'.red); + console.error(colors.red(err.message)); + console.error(colors.red(err.stack)); + } else { + console.error('\nElectron forge was terminated:'.red); + console.error(colors.red(typeof err === 'string' ? err : JSON.stringify(err))); + } process.exit(1); });