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 Electron branding options #5727

Merged
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
16 changes: 16 additions & 0 deletions packages/app-builder-lib/scheme.json
Original file line number Diff line number Diff line change
Expand Up @@ -897,6 +897,18 @@
},
"type": "object"
},
"ElectronBrandingOptions": {
"additionalProperties": false,
"properties": {
"projectName": {
"type": "string"
},
"productName": {
"type": "string"
}
},
"type": "object"
},
"ElectronDownloadOptions": {
"additionalProperties": false,
"properties": {
Expand Down Expand Up @@ -5778,6 +5790,10 @@
],
"description": "Returns the path to custom Electron build (e.g. `~/electron/out/R`). Zip files must follow the pattern `electron-v${version}-${platformName}-${arch}.zip`, otherwise it will be assumed to be an unpacked Electron app directory"
},
"electronBranding": {
"$ref": "#/definitions/ElectronBrandingOptions",
"description": "The branding used by Electron's distributables. This is needed if a fork has modified Electron's BRANDING.json file."
},
"electronDownload": {
"$ref": "#/definitions/ElectronDownloadOptions",
"description": "The [electron-download](https://github.com/electron-userland/electron-download#usage) options."
Expand Down
7 changes: 6 additions & 1 deletion packages/app-builder-lib/src/configuration.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Arch } from "builder-util"
import { BeforeBuildContext, Target } from "./core"
import { ElectronDownloadOptions } from "./electron/ElectronFramework"
import { ElectronBrandingOptions, ElectronDownloadOptions } from "./electron/ElectronFramework"
import { PrepareApplicationStageDirectoryOptions } from "./Framework"
import { AppXOptions } from "./options/AppXOptions"
import { AppImageOptions, DebOptions, LinuxConfiguration, LinuxTargetSpecificOptions } from "./options/linuxOptions"
Expand Down Expand Up @@ -139,6 +139,11 @@ export interface Configuration extends PlatformSpecificBuildOptions {
*/
readonly electronDownload?: ElectronDownloadOptions

/**
* The branding used by Electron's distributables. This is needed if a fork has modified Electron's BRANDING.json file.
*/
readonly electronBranding?: ElectronBrandingOptions

/**
* The version of electron you are packaging for. Defaults to version of `electron`, `electron-prebuilt` or `electron-prebuilt-compile` dependency.
*/
Expand Down
24 changes: 21 additions & 3 deletions packages/app-builder-lib/src/electron/ElectronFramework.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,22 @@ import { promises as fsPromises } from "fs"

export type ElectronPlatformName = "darwin" | "linux" | "win32" | "mas"

/**
* Electron distributables branding options.
* @see [Electron BRANDING.json](https://github.com/electron/electron/blob/master/shell/app/BRANDING.json).
*/
export interface ElectronBrandingOptions {
projectName?: string
productName?: string
}

export function createBrandingOpts(opts: Configuration): Required<ElectronBrandingOptions> {
return {
projectName: opts.electronBranding?.projectName || "electron",
productName: opts.electronBranding?.productName || "Electron",
}
}

export interface ElectronDownloadOptions {
// https://github.com/electron-userland/electron-builder/issues/3077
// must be optional
Expand Down Expand Up @@ -56,15 +72,16 @@ function createDownloadOpts(opts: Configuration, platform: ElectronPlatformName,
async function beforeCopyExtraFiles(options: BeforeCopyExtraFilesOptions) {
const packager = options.packager
const appOutDir = options.appOutDir
const electronBranding = createBrandingOpts(packager.config)
if (packager.platform === Platform.LINUX) {
if (!isSafeToUnpackElectronOnRemoteBuildServer(packager)) {
const linuxPackager = packager as LinuxPackager
const executable = path.join(appOutDir, linuxPackager.executableName)
await rename(path.join(appOutDir, "electron"), executable)
await rename(path.join(appOutDir, electronBranding.projectName), executable)
}
} else if (packager.platform === Platform.WINDOWS) {
const executable = path.join(appOutDir, `${packager.appInfo.productFilename}.exe`)
await rename(path.join(appOutDir, "electron.exe"), executable)
await rename(path.join(appOutDir, `${electronBranding.projectName}.exe`), executable)
} else {
await createMacApp(packager as MacPackager, appOutDir, options.asarIntegrity, (options.platformName as ElectronPlatformName) === "mas")

Expand Down Expand Up @@ -139,7 +156,8 @@ export async function createElectronFrameworkSupport(configuration: Configuratio
configuration.electronVersion = version
}

return new ElectronFramework("electron", version, "Electron.app")
const branding = createBrandingOpts(configuration)
return new ElectronFramework(branding.projectName, version, `${branding.productName}.app`)
}

async function unpack(prepareOptions: PrepareApplicationStageDirectoryOptions, options: ElectronDownloadOptions, distMacOsAppName: string) {
Expand Down
22 changes: 12 additions & 10 deletions packages/app-builder-lib/src/electron/electronMac.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { AsarIntegrity } from "../asar/integrity"
import MacPackager from "../macPackager"
import { normalizeExt } from "../platformPackager"
import { executeAppBuilderAndWriteJson, executeAppBuilderAsJson } from "../util/appBuilder"
import { createBrandingOpts } from "./ElectronFramework"

function doRename(basePath: string, oldName: string, newName: string) {
return rename(path.join(basePath, oldName), path.join(basePath, newName))
Expand Down Expand Up @@ -50,19 +51,20 @@ function getAvailableHelperSuffixes(
export async function createMacApp(packager: MacPackager, appOutDir: string, asarIntegrity: AsarIntegrity | null, isMas: boolean) {
const appInfo = packager.appInfo
const appFilename = appInfo.productFilename
const electronBranding = createBrandingOpts(packager.config)

const contentsPath = path.join(appOutDir, packager.info.framework.distMacOsAppName, "Contents")
const frameworksPath = path.join(contentsPath, "Frameworks")
const loginItemPath = path.join(contentsPath, "Library", "LoginItems")

const appPlistFilename = path.join(contentsPath, "Info.plist")
const helperPlistFilename = path.join(frameworksPath, "Electron Helper.app", "Contents", "Info.plist")
const helperEHPlistFilename = path.join(frameworksPath, "Electron Helper EH.app", "Contents", "Info.plist")
const helperNPPlistFilename = path.join(frameworksPath, "Electron Helper NP.app", "Contents", "Info.plist")
const helperRendererPlistFilename = path.join(frameworksPath, "Electron Helper (Renderer).app", "Contents", "Info.plist")
const helperPluginPlistFilename = path.join(frameworksPath, "Electron Helper (Plugin).app", "Contents", "Info.plist")
const helperGPUPlistFilename = path.join(frameworksPath, "Electron Helper (GPU).app", "Contents", "Info.plist")
const helperLoginPlistFilename = path.join(loginItemPath, "Electron Login Helper.app", "Contents", "Info.plist")
const helperPlistFilename = path.join(frameworksPath, `${electronBranding.productName} Helper.app`, "Contents", "Info.plist")
const helperEHPlistFilename = path.join(frameworksPath, `${electronBranding.productName} Helper EH.app`, "Contents", "Info.plist")
const helperNPPlistFilename = path.join(frameworksPath, `${electronBranding.productName} Helper NP.app`, "Contents", "Info.plist")
const helperRendererPlistFilename = path.join(frameworksPath, `${electronBranding.productName} Helper (Renderer).app`, "Contents", "Info.plist")
const helperPluginPlistFilename = path.join(frameworksPath, `${electronBranding.productName} Helper (Plugin).app`, "Contents", "Info.plist")
const helperGPUPlistFilename = path.join(frameworksPath, `${electronBranding.productName} Helper (GPU).app`, "Contents", "Info.plist")
const helperLoginPlistFilename = path.join(loginItemPath, `${electronBranding.productName} Login Helper.app`, "Contents", "Info.plist")

const plistContent: Array<any> = await executeAppBuilderAsJson([
"decode-plist",
Expand Down Expand Up @@ -240,15 +242,15 @@ export async function createMacApp(packager: MacPackager, appOutDir: string, asa

await Promise.all([
executeAppBuilderAndWriteJson(["encode-plist"], plistDataToWrite),
doRename(path.join(contentsPath, "MacOS"), "Electron", appPlist.CFBundleExecutable),
doRename(path.join(contentsPath, "MacOS"), electronBranding.productName, appPlist.CFBundleExecutable),
unlinkIfExists(path.join(appOutDir, "LICENSE")),
unlinkIfExists(path.join(appOutDir, "LICENSES.chromium.html")),
])

await moveHelpers(getAvailableHelperSuffixes(helperEHPlist, helperNPPlist, helperRendererPlist, helperPluginPlist, helperGPUPlist), frameworksPath, appFilename, "Electron")
await moveHelpers(getAvailableHelperSuffixes(helperEHPlist, helperNPPlist, helperRendererPlist, helperPluginPlist, helperGPUPlist), frameworksPath, appFilename, electronBranding.productName)

if (helperLoginPlist != null) {
const prefix = "Electron"
const prefix = electronBranding.productName
const suffix = " Login Helper"
const executableBasePath = path.join(loginItemPath, `${prefix}${suffix}.app`, "Contents", "MacOS")
await doRename(executableBasePath, `${prefix}${suffix}`, appFilename + suffix).then(() => doRename(loginItemPath, `${prefix}${suffix}.app`, `${appFilename}${suffix}.app`))
Expand Down
2 changes: 1 addition & 1 deletion packages/app-builder-lib/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ export {
} from "./core"
export { getArchSuffix, Arch, archFromString } from "builder-util"
export { Configuration, AfterPackContext, MetadataDirectories } from "./configuration"
export { ElectronDownloadOptions, ElectronPlatformName } from "./electron/ElectronFramework"
export { ElectronBrandingOptions, ElectronDownloadOptions, ElectronPlatformName } from "./electron/ElectronFramework"
export { PlatformSpecificBuildOptions, AsarOptions, FileSet, Protocol, ReleaseInfo } from "./options/PlatformSpecificBuildOptions"
export { FileAssociation } from "./options/FileAssociation"
export { MacConfiguration, DmgOptions, MasConfiguration, MacOsTargetName, DmgContent, DmgWindow } from "./options/macOptions"
Expand Down
1 change: 1 addition & 0 deletions packages/electron-builder/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ export {
MetadataDirectories,
Protocol,
ReleaseInfo,
ElectronBrandingOptions,
ElectronDownloadOptions,
SnapOptions,
CommonWindowsInstallerConfiguration,
Expand Down