From cd26aac61670882398a0901bc07883faa6311849 Mon Sep 17 00:00:00 2001 From: Mark Lee Date: Fri, 10 May 2019 17:25:01 -0700 Subject: [PATCH 1/7] refactor: drop mz/pify in favor of util.promisify --- package.json | 6 ++---- src/installer.js | 14 ++++---------- test/installer.js | 7 +++++-- 3 files changed, 11 insertions(+), 16 deletions(-) diff --git a/package.json b/package.json index 13fd043..3b3f757 100644 --- a/package.json +++ b/package.json @@ -30,7 +30,7 @@ "test": "npm run lint && npm run spec" }, "engines": { - "node": ">=6.0.0" + "node": ">= 8.0.0" }, "dependencies": { "debug": "^4.1.1", @@ -38,7 +38,6 @@ "fs-extra": "^7.0.1", "get-folder-size": "^2.0.1", "lodash": "^4.17.4", - "pify": "^4.0.1", "word-wrap": "^1.2.3", "yargs": "^13.2.2" }, @@ -47,11 +46,10 @@ "eslint": "^5.12.1", "eslint-config-standard": "^12.0.0", "eslint-plugin-import": "^2.7.0", - "eslint-plugin-node": "^8.0.1", + "eslint-plugin-node": "^9.0.1", "eslint-plugin-promise": "^4.0.1", "eslint-plugin-standard": "^4.0.0", "mocha": "^6.0.0", - "mz": "^2.7.0", "nyc": "^14.0.0", "promise-retry": "^1.1.1", "tmp-promise": "^1.0.5" diff --git a/src/installer.js b/src/installer.js index 0676207..a4ff69a 100644 --- a/src/installer.js +++ b/src/installer.js @@ -1,13 +1,14 @@ 'use strict' +const { promisify } = require('util') + const _ = require('lodash') const common = require('electron-installer-common') const debug = require('debug') const fs = require('fs-extra') -const fsize = require('get-folder-size') +const fsize = promisify(require('get-folder-size')) const parseAuthor = require('parse-author') const path = require('path') -const pify = require('pify') const wrap = require('word-wrap') const debianDependencies = require('./dependencies') @@ -120,7 +121,7 @@ class DebianInstaller extends common.ElectronInstaller { generateDefaults () { return Promise.all([ common.readMetadata(this.userSupplied), - this.getSize(this.userSupplied.src), + fsize(this.userSupplied.src), common.readElectronVersion(this.userSupplied.src) ]).then(([pkg, size, electronVersion]) => { pkg = pkg || {} @@ -187,13 +188,6 @@ class DebianInstaller extends common.ElectronInstaller { } } - /** - * Get the size of the app. - */ - getSize (appDir) { - return pify(fsize)(appDir) - } - /** * Normalize the description by replacing all newlines in the description with spaces, since it's * supposed to be one line. diff --git a/test/installer.js b/test/installer.js index 9f8176a..67e2086 100644 --- a/test/installer.js +++ b/test/installer.js @@ -1,8 +1,9 @@ 'use strict' const chai = require('chai') -const { exec } = require('mz/child_process') +const childProcess = require('child_process') const path = require('path') +const { promisify } = require('util') const installer = require('..') @@ -10,6 +11,8 @@ const access = require('./helpers/access') const describeInstaller = require('./helpers/describe_installer') const { cleanupOutputDir, describeInstallerWithException, tempOutputDir, testInstallerOptions } = require('./helpers/describe_installer') +const exec = promisify(childProcess.exec) + const assertASARDebExists = outputDir => access(path.join(outputDir, 'footest_i386.deb')) @@ -153,7 +156,7 @@ describe('module', function () { outputDir => assertASARDebExists(outputDir) .then(() => exec(`lintian ${path.join(outputDir, 'footest_i386.deb')}`)) - .then(stdout => { + .then(({stdout}) => { const lineCount = stdout.toString().match(/\n/g).length if (lineCount > 1) { throw new Error('Warnings not overriding:\n' + stdout.toString()) From 9d0ec2d4bcbebb9b8371cf8226fd1df23e2b0251 Mon Sep 17 00:00:00 2001 From: Mark Lee Date: Tue, 14 May 2019 23:11:46 -0700 Subject: [PATCH 2/7] feat: use Node 8 syntax BREAKING CHANGE: drop support for Node < 8. --- .travis.yml | 5 +- README.md | 18 ++++---- package.json | 2 +- src/installer.js | 102 ++++++++++++++++++++--------------------- src/spawn.js | 2 +- test/helpers/access.js | 2 +- test/installer.js | 18 ++++---- test/spawn.js | 11 +++-- 8 files changed, 79 insertions(+), 81 deletions(-) diff --git a/.travis.yml b/.travis.yml index 7b45202..cfb3744 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,11 +2,8 @@ language: node_js node_js: - '10' - '8' -- '6' dist: xenial -cache: - directories: - - node_modules +cache: npm branches: only: - master diff --git a/README.md b/README.md index a385b26..a6c1a48 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,7 @@ ## Requirements -This tool requires Node 6 or greater, `fakeroot`, and `dpkg` to build the `.deb` package. +This tool requires Node 8 or greater, `fakeroot`, and `dpkg` to build the `.deb` package. I'd recommend building your packages on your target platform, but if you insist on using Mac OS X, you can install these tools through [Homebrew](http://brew.sh/): @@ -168,18 +168,20 @@ const options = { console.log('Creating package (this may take a while)') -installer(options) - .then(() => console.log(`Successfully created package at ${options.dest}`)) - .catch(err => { - console.error(err, err.stack) - process.exit(1) - }) +try { + await installer(options) + console.log(`Successfully created package at ${options.dest}`) +} catch (err) { + console.error(err, err.stack) + process.exit(1) +} ``` You'll end up with the package at `dist/installers/app_0.0.1_amd64.deb`. _Note: As of 1.0.0, the Node-style callback pattern is no longer available. You can use -[`nodeify`](https://npm.im/nodeify) if this is required for your use case._ +[`util.callbackify`](https://nodejs.org/api/util.html#util_util_callbackify_original) if this is +required for your use case._ ### Options diff --git a/package.json b/package.json index 3b3f757..23d73f0 100644 --- a/package.json +++ b/package.json @@ -34,7 +34,7 @@ }, "dependencies": { "debug": "^4.1.1", - "electron-installer-common": "^0.6.2", + "electron-installer-common": "electron-userland/electron-installer-common#drop-node-6", "fs-extra": "^7.0.1", "get-folder-size": "^2.0.1", "lodash": "^4.17.4", diff --git a/src/installer.js b/src/installer.js index a4ff69a..2f727a4 100644 --- a/src/installer.js +++ b/src/installer.js @@ -55,9 +55,9 @@ class DebianInstaller extends common.ElectronInstaller { /** * Copy the application into the package. */ - copyApplication () { - return super.copyApplication(src => src !== path.join(this.options.src, 'LICENSE')) - .then(() => this.updateSandboxHelperPermissions()) + async copyApplication () { + await super.copyApplication(src => src !== path.join(this.options.src, 'LICENSE')) + return this.updateSandboxHelperPermissions() } /** @@ -66,16 +66,18 @@ class DebianInstaller extends common.ElectronInstaller { copyScripts () { const scriptNames = ['preinst', 'postinst', 'prerm', 'postrm'] - return Promise.all(_.map(this.options.scripts, (item, key) => { - if (_.includes(scriptNames, key)) { - const scriptFile = path.join(this.stagingDir, 'DEBIAN', key) - this.options.logger(`Creating script file at ${scriptFile}`) - - return fs.copy(item, scriptFile) - } else { - throw new Error(`Wrong executable script name: ${key}`) - } - })).catch(common.wrapError('creating script files')) + return common.wrapError('creating script files', async () => + Promise.all(_.map(this.options.scripts, (item, key) => { + if (scriptNames.includes(key)) { + const scriptFile = path.join(this.stagingDir, 'DEBIAN', key) + this.options.logger(`Creating script file at ${scriptFile}`) + + return fs.copy(item, scriptFile) + } else { + throw new Error(`Wrong executable script name: ${key}`) + } + })) + ) } /** @@ -88,59 +90,55 @@ class DebianInstaller extends common.ElectronInstaller { const dest = path.join(this.stagingDir, 'DEBIAN', 'control') this.options.logger(`Creating control file at ${dest}`) - return this.createTemplatedFile(src, dest) - .catch(common.wrapError('creating control file')) + return common.wrapError('creating control file', async () => this.createTemplatedFile(src, dest)) } /** * Create lintian overrides for the package. */ - createOverrides () { + async createOverrides () { const src = path.resolve(__dirname, '../resources/overrides.ejs') const dest = path.join(this.stagingDir, this.baseAppDir, 'share/lintian/overrides', this.options.name) this.options.logger(`Creating lintian overrides at ${dest}`) - return this.createTemplatedFile(src, dest, '0644') - .catch(common.wrapError('creating lintian overrides file')) + return common.wrapError('creating lintian overrides file', async () => this.createTemplatedFile(src, dest, '0644')) } /** * Package everything using `dpkg` and `fakeroot`. */ - createPackage () { + async createPackage () { this.options.logger(`Creating package at ${this.stagingDir}`) - return spawn('fakeroot', ['dpkg-deb', '--build', this.stagingDir], this.options.logger) - .then(output => this.options.logger(`dpkg-deb output: ${output}`)) + const output = await spawn('fakeroot', ['dpkg-deb', '--build', this.stagingDir], this.options.logger) + this.options.logger(`dpkg-deb output: ${output}`) } /** * Get the hash of default options for the installer. Some come from the info * read from `package.json`, and some are hardcoded. */ - generateDefaults () { - return Promise.all([ - common.readMetadata(this.userSupplied), + async generateDefaults () { + const [pkg, size, electronVersion] = await Promise.all([ + (async () => (await common.readMetadata(this.userSupplied)) || {})(), fsize(this.userSupplied.src), common.readElectronVersion(this.userSupplied.src) - ]).then(([pkg, size, electronVersion]) => { - pkg = pkg || {} + ]) - this.defaults = Object.assign(common.getDefaultsFromPackageJSON(pkg), { - version: transformVersion(pkg.version || '0.0.0'), + this.defaults = Object.assign(common.getDefaultsFromPackageJSON(pkg), { + version: transformVersion(pkg.version || '0.0.0'), - section: 'utils', - priority: 'optional', - size: Math.ceil((size || 0) / 1024), + section: 'utils', + priority: 'optional', + size: Math.ceil((size || 0) / 1024), - maintainer: this.getMaintainer(pkg.author), + maintainer: this.getMaintainer(pkg.author), - icon: path.resolve(__dirname, '../resources/icon.png'), - lintianOverrides: [] - }, debianDependencies.forElectron(electronVersion)) + icon: path.resolve(__dirname, '../resources/icon.png'), + lintianOverrides: [] + }, debianDependencies.forElectron(electronVersion)) - return this.defaults - }) + return this.defaults } /** @@ -229,7 +227,7 @@ class DebianInstaller extends common.ElectronInstaller { /* ************************************************************************** */ -module.exports = data => { +module.exports = async data => { data.rename = data.rename || defaultRename data.logger = data.logger || defaultLogger @@ -239,20 +237,20 @@ module.exports = data => { const installer = new DebianInstaller(data) - return installer.generateDefaults() - .then(() => installer.generateOptions()) - .then(() => data.logger(`Creating package with options\n${JSON.stringify(installer.options, null, 2)}`)) - .then(() => installer.createStagingDir()) - .then(() => installer.createContents()) - .then(() => installer.createPackage()) - .then(() => installer.movePackage()) - .then(() => { - data.logger(`Successfully created package at ${installer.options.dest}`) - return installer.options - }).catch(err => { - data.logger(common.errorMessage('creating package', err)) - throw err - }) + // try { + await installer.generateDefaults() + await installer.generateOptions() + data.logger(`Creating package with options\n${JSON.stringify(installer.options, null, 2)}`) + await installer.createStagingDir() + await installer.createContents() + await installer.createPackage() + await installer.movePackage() + data.logger(`Successfully created package at ${installer.options.dest}`) + return installer.options + // } catch (err) { + // data.logger(common.errorMessage('creating package', err)) + // throw err + // } } module.exports.Installer = DebianInstaller diff --git a/src/spawn.js b/src/spawn.js index 8cfe05e..66fe63e 100644 --- a/src/spawn.js +++ b/src/spawn.js @@ -16,6 +16,6 @@ function updateExecutableMissingException (err, updateError) { } } -module.exports = function (cmd, args, logger) { +module.exports = async function (cmd, args, logger) { return spawn(cmd, args, logger, updateExecutableMissingException) } diff --git a/test/helpers/access.js b/test/helpers/access.js index 6dd4462..ad4dda6 100644 --- a/test/helpers/access.js +++ b/test/helpers/access.js @@ -6,7 +6,7 @@ const retry = require('promise-retry') /** * `fs.access` which retries three times. */ -module.exports = function (path) { +module.exports = async function (path) { return retry((retry, number) => { return fs.access(path) .catch(retry) diff --git a/test/installer.js b/test/installer.js index 67e2086..7d3d139 100644 --- a/test/installer.js +++ b/test/installer.js @@ -153,16 +153,14 @@ describe('module', function () { } }, 'passes lintian checks', - outputDir => - assertASARDebExists(outputDir) - .then(() => exec(`lintian ${path.join(outputDir, 'footest_i386.deb')}`)) - .then(({stdout}) => { - const lineCount = stdout.toString().match(/\n/g).length - if (lineCount > 1) { - throw new Error('Warnings not overriding:\n' + stdout.toString()) - } - return Promise.resolve() - }) + async outputDir => { + await assertASARDebExists(outputDir) + const { stdout } = await exec(`lintian ${path.join(outputDir, 'footest_i386.deb')}`) + const lineCount = stdout.toString().match(/\n/g).length + if (lineCount > 1) { + throw new Error(`Warnings not overriding:\n${stdout.toString()}`) + } + } ) describeInstallerWithException( diff --git a/test/spawn.js b/test/spawn.js index 0bd2767..75bbea0 100644 --- a/test/spawn.js +++ b/test/spawn.js @@ -11,10 +11,13 @@ describe('spawn', () => { process.env.PATH = '/non-existent-path' }) - it('should throw a human-friendly error when it cannot find dpkg or fakeroot', () => { - return spawn('dpkg', ['--version'], msg => {}) - .then(() => { throw new Error('dpkg should not have been executed') }) - .catch(error => chai.expect(error.message).to.match(/Error executing command \(Your system is missing the dpkg package/)) + it('should throw a human-friendly error when it cannot find dpkg or fakeroot', async () => { + try { + await spawn('dpkg', ['--version'], msg => {}) + throw new Error('dpkg should not have been executed') + } catch (error) { + chai.expect(error.message).to.match(/Error executing command \(Your system is missing the dpkg package/) + } }) after(() => { From e40f1ae7a9aec931e64e4fc4c38b989a7f3ba887 Mon Sep 17 00:00:00 2001 From: Mark Lee Date: Tue, 14 May 2019 23:15:27 -0700 Subject: [PATCH 3/7] Remove commented out code --- src/installer.js | 23 +++++++++-------------- 1 file changed, 9 insertions(+), 14 deletions(-) diff --git a/src/installer.js b/src/installer.js index 2f727a4..f3793ab 100644 --- a/src/installer.js +++ b/src/installer.js @@ -237,20 +237,15 @@ module.exports = async data => { const installer = new DebianInstaller(data) - // try { - await installer.generateDefaults() - await installer.generateOptions() - data.logger(`Creating package with options\n${JSON.stringify(installer.options, null, 2)}`) - await installer.createStagingDir() - await installer.createContents() - await installer.createPackage() - await installer.movePackage() - data.logger(`Successfully created package at ${installer.options.dest}`) - return installer.options - // } catch (err) { - // data.logger(common.errorMessage('creating package', err)) - // throw err - // } + await installer.generateDefaults() + await installer.generateOptions() + data.logger(`Creating package with options\n${JSON.stringify(installer.options, null, 2)}`) + await installer.createStagingDir() + await installer.createContents() + await installer.createPackage() + await installer.movePackage() + data.logger(`Successfully created package at ${installer.options.dest}`) + return installer.options } module.exports.Installer = DebianInstaller From 84e7bbcec86c1ab0fb15daa37aa0177db3562ba9 Mon Sep 17 00:00:00 2001 From: Mark Lee Date: Fri, 24 May 2019 18:44:47 -0700 Subject: [PATCH 4/7] Use released electron-installer-common & fix lintian test --- package.json | 2 +- test/installer.js | 13 +++++++++---- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 23d73f0..d895b48 100644 --- a/package.json +++ b/package.json @@ -34,7 +34,7 @@ }, "dependencies": { "debug": "^4.1.1", - "electron-installer-common": "electron-userland/electron-installer-common#drop-node-6", + "electron-installer-common": "^0.7.0", "fs-extra": "^7.0.1", "get-folder-size": "^2.0.1", "lodash": "^4.17.4", diff --git a/test/installer.js b/test/installer.js index 7d3d139..1d1e88c 100644 --- a/test/installer.js +++ b/test/installer.js @@ -147,6 +147,7 @@ describe('module', function () { }, lintianOverrides: [ 'binary-without-manpage', + 'changelog-file-missing-in-native-package', 'debian-changelog-file-missing', 'executable-not-elf-or-script' ] @@ -155,10 +156,14 @@ describe('module', function () { 'passes lintian checks', async outputDir => { await assertASARDebExists(outputDir) - const { stdout } = await exec(`lintian ${path.join(outputDir, 'footest_i386.deb')}`) - const lineCount = stdout.toString().match(/\n/g).length - if (lineCount > 1) { - throw new Error(`Warnings not overriding:\n${stdout.toString()}`) + try { + await exec(`lintian ${path.join(outputDir, 'footest_i386.deb')}`) + } catch (err) { + const stdout = err.stdout.toString() + const lineCount = stdout.match(/\n/g).length + if (lineCount > 1) { + throw new Error(`Warnings not overriding:\n${stdout}`) + } } } ) From ed9f209eb34c6ff5aca6236aa39e4bc8c8237039 Mon Sep 17 00:00:00 2001 From: Mark Lee Date: Fri, 24 May 2019 18:47:37 -0700 Subject: [PATCH 5/7] chore: upgrade dependencies --- package.json | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index d895b48..029dd56 100644 --- a/package.json +++ b/package.json @@ -35,7 +35,7 @@ "dependencies": { "debug": "^4.1.1", "electron-installer-common": "^0.7.0", - "fs-extra": "^7.0.1", + "fs-extra": "^8.0.1", "get-folder-size": "^2.0.1", "lodash": "^4.17.4", "word-wrap": "^1.2.3", @@ -43,15 +43,15 @@ }, "devDependencies": { "chai": "^4.1.2", - "eslint": "^5.12.1", + "eslint": "^5.16.0", "eslint-config-standard": "^12.0.0", - "eslint-plugin-import": "^2.7.0", + "eslint-plugin-import": "^2.17.3", "eslint-plugin-node": "^9.0.1", - "eslint-plugin-promise": "^4.0.1", + "eslint-plugin-promise": "^4.1.1", "eslint-plugin-standard": "^4.0.0", "mocha": "^6.0.0", "nyc": "^14.0.0", "promise-retry": "^1.1.1", - "tmp-promise": "^1.0.5" + "tmp-promise": "^2.0.1" } } From 70b0aa0176bdc4c713fafa607374dfd81f92ec7d Mon Sep 17 00:00:00 2001 From: Mark Lee Date: Fri, 24 May 2019 18:56:21 -0700 Subject: [PATCH 6/7] Remove unnecessary override --- test/installer.js | 1 - 1 file changed, 1 deletion(-) diff --git a/test/installer.js b/test/installer.js index 1d1e88c..01779b6 100644 --- a/test/installer.js +++ b/test/installer.js @@ -148,7 +148,6 @@ describe('module', function () { lintianOverrides: [ 'binary-without-manpage', 'changelog-file-missing-in-native-package', - 'debian-changelog-file-missing', 'executable-not-elf-or-script' ] } From 5023df68e89ec74368b2a67ad64acdf7d4052288 Mon Sep 17 00:00:00 2001 From: Mark Lee Date: Fri, 24 May 2019 19:29:22 -0700 Subject: [PATCH 7/7] People copy/paste, so don't use top-level await code --- README.md | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index a6c1a48..2d832ef 100644 --- a/README.md +++ b/README.md @@ -118,7 +118,7 @@ $ npm install --save-dev electron-installer-debian Edit the `scripts` section of your `package.json`: -```js +```json { "name": "app", "description": "An awesome app!", @@ -166,15 +166,17 @@ const options = { arch: 'amd64' } -console.log('Creating package (this may take a while)') - -try { - await installer(options) - console.log(`Successfully created package at ${options.dest}`) -} catch (err) { - console.error(err, err.stack) - process.exit(1) +async function main (options) { + console.log('Creating package (this may take a while)') + try { + await installer(options) + console.log(`Successfully created package at ${options.dest}`) + } catch (err) { + console.error(err, err.stack) + process.exit(1) + } } +main(options) ``` You'll end up with the package at `dist/installers/app_0.0.1_amd64.deb`.