Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add support for custom executable file name #5409

Merged
merged 1 commit into from
Jan 15, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 15 additions & 1 deletion packages/app-builder-lib/scheme.json
Original file line number Diff line number Diff line change
Expand Up @@ -1341,7 +1341,7 @@
"description": "The executable parameters. Pass to executableName"
},
"executableName": {
"description": "The executable name. Defaults to `productName`.\nCannot be specified per target, allowed only in the `linux`.",
"description": "The executable name. Defaults to `productName`.",
"type": [
"null",
"string"
Expand Down Expand Up @@ -1829,6 +1829,13 @@
"string"
]
},
"executableName": {
"description": "The executable name. Defaults to `productName`.",
"type": [
"null",
"string"
]
},
"asar": {
"anyOf": [
{
Expand Down Expand Up @@ -5013,6 +5020,13 @@
"string"
]
},
"executableName": {
"description": "The executable name. Defaults to `productName`.",
"type": [
"null",
"string"
]
},
"asar": {
"anyOf": [
{
Expand Down
8 changes: 6 additions & 2 deletions packages/app-builder-lib/src/appInfo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ export class AppInfo {
readonly buildVersion: string

readonly productName: string
readonly sanitizedProductName: string
readonly productFilename: string

constructor(private readonly info: Packager, buildVersion: string | null | undefined, private readonly platformSpecificOptions: PlatformSpecificBuildOptions | null = null) {
Expand All @@ -55,7 +56,10 @@ export class AppInfo {
}

this.productName = info.config.productName || info.metadata.productName || info.metadata.name!!
this.productFilename = sanitizeFileName(this.productName)
this.sanitizedProductName = sanitizeFileName(this.productName)
this.productFilename = platformSpecificOptions?.executableName != null
? sanitizeFileName(platformSpecificOptions.executableName)
: this.sanitizedProductName
}

get channel(): string | null {
Expand Down Expand Up @@ -118,7 +122,7 @@ export class AppInfo {
get linuxPackageName(): string {
const name = this.name
// https://github.com/electron-userland/electron-builder/issues/2963
return name.startsWith("@") ? this.productFilename : name
return name.startsWith("@") ? this.sanitizedProductName : name
}

get sanitizedName(): string {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ export function getEffectiveOptions(options: CommonWindowsInstallerConfiguration
isPerMachine: options.perMachine === true,
isAssisted: options.oneClick === false,

shortcutName: isEmptyOrSpaces(options.shortcutName) ? appInfo.productFilename : packager.expandMacro(options.shortcutName!!),
shortcutName: isEmptyOrSpaces(options.shortcutName) ? appInfo.sanitizedProductName : packager.expandMacro(options.shortcutName!!),
isCreateDesktopShortcut: convertToDesktopShortcutCreationPolicy(options.createDesktopShortcut),
isCreateStartMenuShortcut: options.createStartMenuShortcut !== false,
menuCategory,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,11 @@ export interface PlatformSpecificBuildOptions extends TargetSpecificOptions {
*/
readonly artifactName?: string | null

/**
* The executable name. Defaults to `productName`.
*/
readonly executableName?: string | null

/**
* The compression level. If you want to rapidly test build, `store` can reduce build time significantly. `maximum` doesn't lead to noticeable size difference, but increase build time.
* @default normal
Expand Down
6 changes: 0 additions & 6 deletions packages/app-builder-lib/src/options/linuxOptions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,6 @@ export interface LinuxConfiguration extends CommonLinuxOptions, PlatformSpecific
*/
readonly vendor?: string | null

/**
* The executable name. Defaults to `productName`.
* Cannot be specified per target, allowed only in the `linux`.
*/
readonly executableName?: string | null

/**
* The path to icon set directory or one png file, relative to the [build resources](/configuration/configuration#MetadataDirectories-buildResources) or to the project directory. The icon filename must contain the size (e.g. 32x32.png) of the icon.
* By default will be generated automatically based on the macOS icns file.
Expand Down
3 changes: 1 addition & 2 deletions packages/app-builder-lib/src/targets/LinuxTargetHelper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -94,10 +94,9 @@ export class LinuxTargetHelper {
const packager = this.packager
const appInfo = packager.appInfo

const productFilename = appInfo.productFilename
const executableArgs = targetSpecificOptions.executableArgs
if (exec == null) {
exec = `${installPrefix}/${productFilename}/${packager.executableName}`
exec = `${installPrefix}/${appInfo.sanitizedProductName}/${packager.executableName}`
if (!/^[/0-9A-Za-z._-]+$/.test(exec)) {
exec = `"${exec}"`
}
Expand Down
2 changes: 1 addition & 1 deletion packages/app-builder-lib/src/targets/fpm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ export default class FpmTarget extends Target {

use(options.fpm, it => args.push(...it as any))

args.push(`${appOutDir}/=${installPrefix}/${appInfo.productFilename}`)
args.push(`${appOutDir}/=${installPrefix}/${appInfo.sanitizedProductName}`)
for (const icon of (await this.helper.icons)) {
const extWithDot = path.extname(icon.file)
const sizeName = extWithDot === ".svg" ? "scalable" : `${icon.size}x${icon.size}`
Expand Down
2 changes: 1 addition & 1 deletion packages/app-builder-lib/src/util/macroExpander.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ export function expandMacro(pattern: string, arch: string | null | undefined, ap
return pattern.replace(/\${([_a-zA-Z./*]+)}/g, (match, p1): string => {
switch (p1) {
case "productName":
return isProductNameSanitized ? appInfo.productFilename : appInfo.productName
return isProductNameSanitized ? appInfo.sanitizedProductName : appInfo.productName

case "arch":
if (arch == null) {
Expand Down
2 changes: 1 addition & 1 deletion test/snapshots/mac/macArchiveTest.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ Object {
exports[`invalid target 1`] = `
"Invalid configuration object. electron-builder <appVersion> has been initialized using a configuration object that does not match the API schema.
- configuration.mac should be one of these:
object { appId?, artifactName?, asar?, asarUnpack?, binaries?, bundleShortVersion?, bundleVersion?, category?, compression?, cscInstallerKeyPassword?, cscInstallerLink?, cscKeyPassword?, cscLink?, darkModeSupport?, detectUpdateChannel?, electronLanguages?, electronUpdaterCompatibility?, entitlements?, entitlementsInherit?, entitlementsLoginHelper?, extendInfo?, extraDistFiles?, extraFiles?, extraResources?, fileAssociations?, files?, forceCodeSigning?, gatekeeperAssess?, generateUpdatesFilesForAllChannels?, hardenedRuntime?, helperBundleId?, helperEHBundleId?, helperGPUBundleId?, helperNPBundleId?, helperPluginBundleId?, helperRendererBundleId?, icon?, identity?, minimumSystemVersion?, protocols?, provisioningProfile?, publish?, releaseInfo?, requirements?, signIgnore?, strictVerify?, target?, type? } | null
object { appId?, artifactName?, executableName?, asar?, asarUnpack?, binaries?, bundleShortVersion?, bundleVersion?, category?, compression?, cscInstallerKeyPassword?, cscInstallerLink?, cscKeyPassword?, cscLink?, darkModeSupport?, detectUpdateChannel?, electronLanguages?, electronUpdaterCompatibility?, entitlements?, entitlementsInherit?, entitlementsLoginHelper?, extendInfo?, extraDistFiles?, extraFiles?, extraResources?, fileAssociations?, files?, forceCodeSigning?, gatekeeperAssess?, generateUpdatesFilesForAllChannels?, hardenedRuntime?, helperBundleId?, helperEHBundleId?, helperGPUBundleId?, helperNPBundleId?, helperPluginBundleId?, helperRendererBundleId?, icon?, identity?, minimumSystemVersion?, protocols?, provisioningProfile?, publish?, releaseInfo?, requirements?, signIgnore?, strictVerify?, target?, type? } | null
-> Options related to how build macOS targets.
Details:
* configuration.mac.target[0] should be one of these:
Expand Down
42 changes: 42 additions & 0 deletions test/snapshots/windows/oneClickInstallerTest.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,48 @@ Object {
}
`;

exports[`custom exec name 1`] = `
Object {
"APP_32_NAME": undefined,
"APP_64_NAME": "TestApp-1.1.0-x64.nsis.7z",
"APP_ARM64_NAME": undefined,
"APP_FILENAME": "TestApp",
"APP_ID": "org.electron-builder.testApp",
"APP_PACKAGE_NAME": "TestApp",
"APP_PRODUCT_FILENAME": "Boo",
"COMPANY_NAME": "Foo Bar",
"ONE_CLICK": null,
"PRODUCT_FILENAME": "Boo",
"PRODUCT_NAME": "foo",
"SHORTCUT_NAME": "foo",
"UNINSTALL_DISPLAY_NAME": "foo 1.1.0",
}
`;

exports[`custom exec name 2`] = `
Object {
"win": Array [
Object {
"arch": "x64",
"file": "foo Setup 1.1.0.exe",
"safeArtifactName": "foo-Setup-1.1.0.exe",
"updateInfo": Object {
"sha512": "@sha512",
"size": "@size",
},
},
Object {
"file": "foo Setup 1.1.0.exe.blockmap",
"safeArtifactName": "foo-Setup-1.1.0.exe.blockmap",
"updateInfo": Object {
"sha512": "@sha512",
"size": "@size",
},
},
],
}
`;

exports[`custom guid 1`] = `
Object {
"win": Array [
Expand Down
32 changes: 32 additions & 0 deletions test/src/windows/oneClickInstallerTest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,24 @@ import { checkHelpers, doTest, expectUpdateMetadata } from "../helpers/winHelper

const nsisTarget = Platform.WINDOWS.createTarget(["nsis"])

function pickSnapshotDefines(defines: any) {
return {
"APP_32_NAME": defines.APP_32_NAME,
"APP_64_NAME": defines.APP_64_NAME,
"APP_ARM64_NAME": defines.APP_ARM64_NAME,
"APP_FILENAME": defines.APP_FILENAME,
"APP_ID": defines.APP_ID,
"APP_PACKAGE_NAME": defines.APP_PACKAGE_NAME,
"APP_PRODUCT_FILENAME": defines.APP_PRODUCT_FILENAME,
"COMPANY_NAME": defines.COMPANY_NAME,
"ONE_CLICK": defines.ONE_CLICK,
"PRODUCT_FILENAME": defines.PRODUCT_FILENAME,
"PRODUCT_NAME": defines.PRODUCT_NAME,
"SHORTCUT_NAME": defines.SHORTCUT_NAME,
"UNINSTALL_DISPLAY_NAME": defines.UNINSTALL_DISPLAY_NAME,
};
}

test("one-click", app({
targets: Platform.WINDOWS.createTarget(["nsis"], Arch.x64),
config: {
Expand Down Expand Up @@ -232,4 +250,18 @@ test.ifDevOrLinuxCi("file associations per user", app({
}
],
},
}))

test.ifWindows("custom exec name", app({
targets: nsisTarget,
config: {
productName: "foo",
win: {
executableName: "Boo",
},
},
effectiveOptionComputed: async it => {
expect(pickSnapshotDefines(it[0])).toMatchSnapshot()
return false
}
}))