Skip to content

Commit

Permalink
feat: add support for executableName to non-Linux Platforms (#5409)
Browse files Browse the repository at this point in the history
  • Loading branch information
kagawarei authored Jan 15, 2021
1 parent fe70584 commit 106b680
Show file tree
Hide file tree
Showing 11 changed files with 105 additions and 15 deletions.
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 @@ -5029,6 +5036,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
}
}))

0 comments on commit 106b680

Please sign in to comment.