diff --git a/NEWS.md b/NEWS.md index 2a4c40a1..a180d69c 100644 --- a/NEWS.md +++ b/NEWS.md @@ -6,6 +6,13 @@ * Promise support for `packager` - function returns a Promise instead of the return value of the callback (#658) +* `win32metadata.CompanyName` defaults to `author` name from nearest `package.json` (#667) +* `win32metadata.FileDescription` defaults to `productName` or `name` from + nearest `package.json` (#667) +* `win32metadata.OriginalFilename` defaults to renamed `.exe` (#667) +* `win32metadata.ProductName` defaults to `productName` or `name` from nearest `package.json` (#667) +* `win32metadata.InternalName` defaults to `productName` or `name` from + nearest `package.json` (#667) ### Removed diff --git a/docs/api.md b/docs/api.md index 0591a577..74eb687e 100644 --- a/docs/api.md +++ b/docs/api.md @@ -373,15 +373,15 @@ option. Maps to the `CFBundleURLName` metadata property. *Object* Object (also known as a "hash") of application metadata to embed into the executable: -- `CompanyName` -- `FileDescription` -- `OriginalFilename` -- `ProductName` -- `InternalName` +- `CompanyName` (defaults to `author` name from the nearest `package.json`) +- `FileDescription` (defaults to either `productName` or `name` from the nearest `package.json`) +- `OriginalFilename` (defaults to renamed `.exe` file) +- `ProductName` (defaults to either `productName` or `name` from the nearest `package.json`) +- `InternalName` (defaults to either `productName` or `name` from the nearest `package.json`) - `requested-execution-level` - `application-manifest` -For more information, see the [node-rcedit module](https://github.com/electron/node-rcedit). +For more information, see the [`node-rcedit` module](https://github.com/electron/node-rcedit). ## callback diff --git a/index.js b/index.js index 44d043c5..018022bf 100644 --- a/index.js +++ b/index.js @@ -150,7 +150,7 @@ module.exports = pify(function packager (opts, cb) { common.camelCase(opts, true) - getMetadataFromPackageJSON(opts, path.resolve(process.cwd(), opts.dir) || process.cwd(), function (err) { + getMetadataFromPackageJSON(platforms, opts, path.resolve(process.cwd(), opts.dir) || process.cwd(), function (err) { if (err) return cb(err) if (/ Helper$/.test(opts.name)) { diff --git a/infer.js b/infer.js index d081ab19..f7545e34 100644 --- a/infer.js +++ b/infer.js @@ -2,6 +2,7 @@ const debug = require('debug')('electron-packager') const getPackageInfo = require('get-package-info') +const parseAuthor = require('parse-author') const path = require('path') const resolve = require('resolve') @@ -61,7 +62,7 @@ function getVersion (opts, electronProp, cb) { } } -module.exports = function getMetadataFromPackageJSON (opts, dir, cb) { +module.exports = function getMetadataFromPackageJSON (platforms, opts, dir, cb) { let props = [] if (!opts.name) props.push(['productName', 'name']) if (!opts.appVersion) props.push('version') @@ -76,6 +77,10 @@ module.exports = function getMetadataFromPackageJSON (opts, dir, cb) { ]) } + if (platforms.indexOf('win32') !== -1 && !(opts.win32metadata && opts.win32metadata.CompanyName)) { + props.push('author') + } + // Name and version provided, no need to infer if (props.length === 0) return cb(null) @@ -110,6 +115,15 @@ module.exports = function getMetadataFromPackageJSON (opts, dir, cb) { opts.appVersion = result.values.version } + if (result.values.author && !opts.win32metadata) { + opts.win32metadata = {} + } + + if (result.values.author) { + debug(`Inferring win32metadata.CompanyName from author in ${result.source.author.src}`) + opts.win32metadata.CompanyName = parseAuthor(result.values.author).name + } + if (result.values['dependencies.electron']) { return getVersion(opts, result.source['dependencies.electron'], cb) } else { diff --git a/package.json b/package.json index 894b9d7d..28c4e208 100644 --- a/package.json +++ b/package.json @@ -25,6 +25,7 @@ "fs-extra": "^3.0.0", "get-package-info": "^1.0.0", "minimist": "^1.1.1", + "parse-author": "^2.0.0", "pify": "^3.0.0", "plist": "^2.0.0", "rcedit": "^0.9.0", diff --git a/test/fixtures/infer-win32metadata/package.json b/test/fixtures/infer-win32metadata/package.json new file mode 100644 index 00000000..088779de --- /dev/null +++ b/test/fixtures/infer-win32metadata/package.json @@ -0,0 +1,9 @@ +{ + "main": "main.js", + "productName": "MainJS", + "author": "Foo Bar ", + "description": "Some description", + "devDependencies": { + "electron-prebuilt-compile": "1.4.15" + } +} diff --git a/test/infer.js b/test/infer.js index f58ceeab..6d4266e0 100644 --- a/test/infer.js +++ b/test/infer.js @@ -19,7 +19,7 @@ function createInferElectronVersionTest (fixture, packageName) { delete opts.electronVersion opts.dir = path.join(__dirname, 'fixtures', fixture) - pify(getMetadataFromPackageJSON)(opts, opts.dir) + pify(getMetadataFromPackageJSON)([], opts, opts.dir) .then((pkg) => { const packageJSON = require(path.join(opts.dir, 'package.json')) t.equal(opts.electronVersion, packageJSON.devDependencies[packageName], `The version should be inferred from installed ${packageName} version`) @@ -71,7 +71,7 @@ function createInferMissingVersionTest (opts) { delete opts.electronVersion opts.dir = dir - return pify(getMetadataFromPackageJSON)(opts, dir) + return pify(getMetadataFromPackageJSON)([], opts, dir) }).then(() => { const packageJSON = require(path.join(opts.dir, 'package.json')) t.equal(opts.electronVersion, packageJSON.devDependencies['electron'], 'The version should be inferred from installed electron module version') @@ -80,6 +80,19 @@ function createInferMissingVersionTest (opts) { } } +function testInferWin32metadata (t, opts, expected, assertionMessage) { + t.timeoutAfter(config.timeout) + copyFixtureToTempDir('infer-win32metadata') + .then((dir) => { + opts.dir = dir + + return pify(getMetadataFromPackageJSON)(['win32'], opts, dir) + }).then(() => { + t.deepEqual(opts.win32metadata, expected, assertionMessage) + return t.end() + }).catch(t.end) +} + function createInferMissingFieldsTest (opts) { return createInferFailureTest(opts, 'infer-missing-fields') } @@ -100,6 +113,21 @@ util.testSinglePlatform('infer using `electron-prebuilt` package', createInferEl util.testSinglePlatform('infer using `electron-prebuilt-compile` package', createInferElectronVersionTest('infer-electron-prebuilt-compile', 'electron-prebuilt-compile')) util.testSinglePlatform('infer using `electron` package only', createInferMissingVersionTest) util.testSinglePlatform('infer where `electron` version is preferred over `electron-prebuilt`', createInferElectronVersionTest('basic-renamed-to-electron', 'electron')) +util.testSinglePlatform('infer win32metadata', (opts) => { + return (t) => { + const expected = {CompanyName: 'Foo Bar'} + + testInferWin32metadata(t, opts, expected, 'win32metadata matches package.json values') + } +}) +util.testSinglePlatform('do not infer win32metadata if it already exists', (opts) => { + return (t) => { + opts.win32metadata = {CompanyName: 'Existing'} + const expected = Object.assign({}, opts.win32metadata) + + testInferWin32metadata(t, opts, expected, 'win32metadata did not update with package.json values') + } +}) util.testSinglePlatform('infer missing fields test', createInferMissingFieldsTest) util.testSinglePlatform('infer with bad fields test', createInferWithBadFieldsTest) util.testSinglePlatform('infer with malformed JSON test', createInferWithMalformedJSONTest) diff --git a/test/win32.js b/test/win32.js index 9f8697d4..64b51a39 100644 --- a/test/win32.js +++ b/test/win32.js @@ -27,9 +27,15 @@ function generateVersionStringTest (metadataProperties, extraOpts, expectedValue expectedValues = [].concat(expectedValues) assertionMsgs = [].concat(assertionMsgs) metadataProperties.forEach((property, i) => { - var value = expectedValues[i] - var msg = assertionMsgs[i] - t.deepEqual(rcOpts[property], value, msg) + const value = expectedValues[i] + const msg = assertionMsgs[i] + if (property === 'version-string') { + for (const subkey in value) { + t.equal(rcOpts[property][subkey], value[subkey], `${msg} (${subkey})`) + } + } else { + t.equal(rcOpts[property], value, msg) + } }) t.end() } @@ -163,6 +169,19 @@ test('error message unchanged when error not about wine', (t) => { t.end() }) +test('win32metadata defaults', (t) => { + const opts = { + name: 'Win32 App' + } + const rcOpts = win32.generateRceditOptionsSansIcon(opts, 'Win32 App.exe') + + t.equal(rcOpts['version-string'].FileDescription, opts.name, 'default FileDescription') + t.equal(rcOpts['version-string'].InternalName, opts.name, 'default InternalName') + t.equal(rcOpts['version-string'].OriginalFilename, 'Win32 App.exe', 'default OriginalFilename') + t.equal(rcOpts['version-string'].ProductName, opts.name, 'default ProductName') + t.end() +}) + util.packagerTest('win32 executable name is based on sanitized app name', (t) => { const opts = Object.assign({}, baseOpts, {name: '@username/package-name'}) diff --git a/usage.txt b/usage.txt index 7f1107d9..c20befcc 100644 --- a/usage.txt +++ b/usage.txt @@ -88,10 +88,10 @@ win32metadata a list of sub-properties used to set the application metadata e.g. --win32metadata.CompanyName="Company Inc." or --win32metadata.ProductName="Product" Properties supported: - - CompanyName - - FileDescription - - OriginalFilename - - ProductName - - InternalName + - CompanyName (default: author name from nearest package.json) + - FileDescription (default: appname) + - OriginalFilename (default: renamed exe) + - ProductName (default: appname) + - InternalName (default: appname) - requested-execution-level (user, asInvoker, or requireAdministrator) - application-manifest diff --git a/win32.js b/win32.js index 64310728..d6e6c5de 100644 --- a/win32.js +++ b/win32.js @@ -5,8 +5,13 @@ const debug = require('debug')('electron-packager') const path = require('path') const series = require('run-series') -function generateRceditOptionsSansIcon (opts) { - const win32metadata = Object.assign({}, opts['version-string'], opts.win32metadata) +function generateRceditOptionsSansIcon (opts, newExeName) { + const win32metadata = Object.assign({ + FileDescription: opts.name, + InternalName: opts.name, + OriginalFilename: newExeName, + ProductName: opts.name + }, opts['version-string'], opts.win32metadata) let rcOpts = {'version-string': win32metadata} @@ -56,7 +61,7 @@ module.exports = { } ] - const rcOpts = generateRceditOptionsSansIcon(opts) + const rcOpts = generateRceditOptionsSansIcon(opts, newExeName) if (opts.icon || opts.win32metadata || opts['version-string'] || opts.appCopyright || opts.appVersion || opts.buildVersion) { operations.push(function (cb) {