Skip to content

Commit

Permalink
Merge pull request #758 from electron-userland/custom-executable-name
Browse files Browse the repository at this point in the history
Add option to set the executable name separate from the app name
  • Loading branch information
malept committed Nov 20, 2017
2 parents a636112 + 64caae7 commit 31e1e98
Show file tree
Hide file tree
Showing 9 changed files with 56 additions and 7 deletions.
8 changes: 8 additions & 0 deletions docs/api.md
Expand Up @@ -158,6 +158,14 @@ valid versions. If omitted, it will use the version of the nearest local install
One or more files to be copied directly into the app's `Contents/Resources` directory for OS X
target platforms, and the `resources` directory for other target platforms.

##### `executableName`

*String*

The name of the executable file (sans file extension). Defaults to the value for the [`name`](#name)
parameter. For `darwin` or `mas` target platforms, this does not affect the name of the `.app`
folder - this will use [`name`](#name) parameter.

##### `icon`

*String*
Expand Down
2 changes: 1 addition & 1 deletion linux.js
Expand Up @@ -9,7 +9,7 @@ class LinuxApp extends App {
}

get newElectronName () {
return common.sanitizeAppName(this.opts.name)
return common.sanitizeAppName(this.executableName)
}

create () {
Expand Down
2 changes: 1 addition & 1 deletion mac.js
Expand Up @@ -152,7 +152,7 @@ class MacApp extends App {
return Promise.all(plists.map(plistArgs => this.loadPlist.apply(this, plistArgs)))
.then(() => this.extendAppPlist(this.opts.extendInfo))
.then(() => {
this.appPlist = this.updatePlist(this.appPlist, this.appName, appBundleIdentifier, this.appName)
this.appPlist = this.updatePlist(this.appPlist, this.executableName, appBundleIdentifier, this.appName)
this.helperPlist = this.updateHelperPlist(this.helperPlist)
this.helperEHPlist = this.updateHelperPlist(this.helperEHPlist, 'EH')
this.helperNPPlist = this.updateHelperPlist(this.helperNPPlist, 'NP')
Expand Down
4 changes: 4 additions & 0 deletions platform.js
Expand Up @@ -51,6 +51,10 @@ class App {
throw new Error('Child classes must implement this')
}

get executableName () {
return this.opts.executableName || this.opts.name
}

get stagingPath () {
if (this.opts.tmpdir === false) {
return common.generateFinalPath(this.opts)
Expand Down
20 changes: 20 additions & 0 deletions test/basic.js
Expand Up @@ -380,6 +380,26 @@ util.packagerTest('building for Linux target sanitizes binary name', (t) => {
}).catch(t.end)
})

util.packagerTest('executableName honored when building for Linux target', (t) => {
const opts = {
name: 'PackageName',
executableName: 'my-package',
dir: path.join(__dirname, 'fixtures', 'el-0374'),
electronVersion: '0.37.4',
arch: 'ia32',
platform: 'linux'
}

packager(opts)
.then(paths => {
t.equal(1, paths.length, '1 bundle created')
return fs.stat(path.join(paths[0], 'my-package'))
}).then(stats => {
t.true(stats.isFile(), 'The executableName-based filename should exist')
return t.end()
}).catch(t.end)
})

util.packagerTest('fails with invalid version', util.invalidOptionTest({
name: 'invalidElectronTest',
dir: path.join(__dirname, 'fixtures', 'el-0374'),
Expand Down
8 changes: 5 additions & 3 deletions test/mac.js
Expand Up @@ -117,18 +117,19 @@ function createExtendInfoTest (baseOpts, extraPathOrParams) {
}
}

function createBinaryNameTest (baseOpts, expectedAppName) {
function createBinaryNameTest (baseOpts, expectedExecutableName, expectedAppName) {
return (t) => {
t.timeoutAfter(config.timeout)

const opts = Object.assign({}, baseOpts)
let binaryPath
let appName = expectedAppName || opts.name
const appName = expectedAppName || expectedExecutableName || opts.name
const executableName = expectedExecutableName || opts.name

packager(opts)
.then(paths => {
binaryPath = path.join(paths[0], `${appName}.app`, 'Contents', 'MacOS')
return fs.stat(path.join(binaryPath, appName))
return fs.stat(path.join(binaryPath, executableName))
}).then(stats => {
t.true(stats.isFile(), 'The binary should reflect a sanitized opts.name')
return t.end()
Expand Down Expand Up @@ -440,6 +441,7 @@ module.exports = (baseOpts) => {

util.packagerTest('binary naming test', createBinaryNameTest(baseOpts))
util.packagerTest('sanitized binary naming test', createBinaryNameTest(Object.assign({}, baseOpts, {name: '@username/package-name'}), '@username-package-name'))
util.packagerTest('executableName test', createBinaryNameTest(Object.assign({}, baseOpts, {executableName: 'app-name', name: 'MyAppName'}), 'app-name', 'MyAppName'))

util.packagerTest('CFBundleName is the sanitized app name and CFBundleDisplayName is the non-sanitized app name', (t) => {
t.timeoutAfter(config.timeout)
Expand Down
14 changes: 14 additions & 0 deletions test/win32.js
Expand Up @@ -201,6 +201,20 @@ util.packagerTest('win32 executable name is based on sanitized app name', (t) =>
}).catch(t.end)
})

util.packagerTest('win32 executable name uses executableName when available', t => {
const opts = Object.assign({}, baseOpts, {name: 'PackageName', executableName: 'my-package'})

packager(opts)
.then(paths => {
t.equal(1, paths.length, '1 bundle created')
const appExePath = path.join(paths[0], 'my-package.exe')
return fs.pathExists(appExePath)
}).then(exists => {
t.true(exists, 'the executableName-based filename should exist')
return t.end()
}).catch(t.end)
})

util.packagerTest('win32 build version sets FileVersion test', setFileVersionTest('2.3.4.5'))
util.packagerTest('win32 app version sets ProductVersion test', setProductVersionTest('5.4.3.2'))
util.packagerTest('win32 app copyright sets LegalCopyright test', setCopyrightTest('Copyright Bar'))
Expand Down
3 changes: 2 additions & 1 deletion usage.txt
Expand Up @@ -40,6 +40,7 @@ download a list of sub-options to pass to electron-download. They are
Electron. Defaults to true, use --no-download.strictSSL to disable checks.
electron-version the version of Electron that is being packaged, see
https://github.com/electron/electron/releases
executable-name the name of the executable file, sans file extension. Defaults to appname
extra-resource a file to copy into the app's resources directory
icon the local path to an icon file to use as the icon for the app.
Note: Format depends on platform.
Expand All @@ -48,7 +49,7 @@ ignore do not copy files into app whose filenames RegExp.match this
and --no-prune. Can be specified multiple times
no-deref-symlinks make sure symlinks are not dereferenced within the app source
no-prune do not prune devDependencies from the packaged app
out the dir to put the app into at the end. defaults to current working dir
out the dir to put the app into at the end. Defaults to current working dir
overwrite if output directory for a platform already exists, replaces it rather than
skipping it
package-manager the package manager to use when pruning devDependencies. Supported package
Expand Down
2 changes: 1 addition & 1 deletion win32.js
Expand Up @@ -25,7 +25,7 @@ class WindowsApp extends App {
}

get newElectronName () {
return `${common.sanitizeAppName(this.opts.name)}.exe`
return `${common.sanitizeAppName(this.executableName)}.exe`
}

get electronBinaryPath () {
Expand Down

0 comments on commit 31e1e98

Please sign in to comment.