Skip to content

Commit

Permalink
feat: Moved electronLanguages to global config to support win/linux (
Browse files Browse the repository at this point in the history
…#7516)

* Removing `remoteBuild` functionality, it stopped working long ago when the service died.
* Moved `electronLanguages` to global config to support win/linux
  • Loading branch information
mmaietta committed Apr 5, 2023
1 parent 63772e1 commit 1533501
Show file tree
Hide file tree
Showing 15 changed files with 108 additions and 445 deletions.
5 changes: 5 additions & 0 deletions .changeset/brave-crabs-guess.md
@@ -0,0 +1,5 @@
---
"app-builder-lib": minor
---

feat: Moved `electronLanguages` to global config to support win/linux
16 changes: 9 additions & 7 deletions docs/configuration/configuration.md
Expand Up @@ -175,13 +175,15 @@ Env file `electron-builder.env` in the current dir ([example](https://github.com
<p><code id="Configuration-beforeBuild">beforeBuild</code> (context: BeforeBuildContext) =&gt; Promise | null - The function (or path to file or module id) to be run before dependencies are installed or rebuilt. Works when <code>npmRebuild</code> is set to <code>true</code>. Resolving to <code>false</code> will skip dependencies install or rebuild.</p>
<p>If provided and <code>node_modules</code> are missing, it will not invoke production dependencies check.</p>
</li>
</ul>
<hr>
<ul>
<li><code id="Configuration-remoteBuild">remoteBuild</code> = <code>true</code> Boolean - Whether to build using Electron Build Service if target not supported on current OS.</li>
<li><code id="Configuration-includePdb">includePdb</code> = <code>false</code> Boolean - Whether to include PDB files.</li>
<li><code id="Configuration-removePackageScripts">removePackageScripts</code> = <code>true</code> Boolean - Whether to remove <code>scripts</code> field from <code>package.json</code> files.</li>
<li><code id="Configuration-removePackageKeywords">removePackageKeywords</code> = <code>true</code> Boolean - Whether to remove <code>keywords</code> field from <code>package.json</code> files.</li>
<li>
<p><code id="Configuration-includePdb">includePdb</code> = <code>false</code> Boolean - Whether to include PDB files.</p>
</li>
<li>
<p><code id="Configuration-removePackageScripts">removePackageScripts</code> = <code>true</code> Boolean - Whether to remove <code>scripts</code> field from <code>package.json</code> files.</p>
</li>
<li>
<p><code id="Configuration-removePackageKeywords">removePackageKeywords</code> = <code>true</code> Boolean - Whether to remove <code>keywords</code> field from <code>package.json</code> files.</p>
</li>
</ul>

<!-- end of generated block -->
Expand Down
3 changes: 0 additions & 3 deletions docs/configuration/mac.md
Expand Up @@ -72,9 +72,6 @@ The top-level [mac](configuration.md#Configuration-mac) key contains set of opti
<p><code id="MacConfiguration-requirements">requirements</code> String | “undefined” - Path of <a href="https://developer.apple.com/library/mac/documentation/Security/Conceptual/CodeSigningGuide/RequirementLang/RequirementLang.html">requirements file</a> used in signing. Not applicable for MAS.</p>
</li>
<li>
<p><code id="MacConfiguration-electronLanguages">electronLanguages</code> Array&lt;String&gt; | String - The electron locales. By default Electron locales used as is.</p>
</li>
<li>
<p><code id="MacConfiguration-extraDistFiles">extraDistFiles</code> Array&lt;String&gt; | String | “undefined” - Extra files to put in archive. Not applicable for <code>tar.*</code>.</p>
</li>
<li>
Expand Down
1 change: 1 addition & 0 deletions docs/generated/PlatformSpecificBuildOptions.md
Expand Up @@ -66,6 +66,7 @@
<li><code id="Protocol-role">role</code> = <code>Editor</code> “Editor” | “Viewer” | “Shell” | “None” - <em>macOS-only</em> The app’s role with respect to the type.</li>
</ul>
</li>
<li><code id="PlatformSpecificBuildOptions-electronLanguages">electronLanguages</code> Array&lt;String&gt; | String - The electron locales to keep. By default, all Electron locales used as-is.</li>
</ul>
<hr>
<ul>
Expand Down
51 changes: 44 additions & 7 deletions packages/app-builder-lib/scheme.json
Expand Up @@ -1731,6 +1731,20 @@
"description": "Whether to infer update channel from application version pre-release components. e.g. if version `0.12.1-alpha.1`, channel will be set to `alpha`. Otherwise to `latest`.",
"type": "boolean"
},
"electronLanguages": {
"anyOf": [
{
"items": {
"type": "string"
},
"type": "array"
},
{
"type": "string"
}
],
"description": "The electron locales to keep. By default, all Electron locales used as-is."
},
"electronUpdaterCompatibility": {
"description": "The [electron-updater compatibility](/auto-update#compatibility) semver range.",
"type": [
Expand Down Expand Up @@ -2394,7 +2408,7 @@
"type": "string"
}
],
"description": "The electron locales. By default Electron locales used as is."
"description": "The electron locales to keep. By default, all Electron locales used as-is."
},
"electronUpdaterCompatibility": {
"description": "The [electron-updater compatibility](/auto-update#compatibility) semver range.",
Expand Down Expand Up @@ -3019,7 +3033,7 @@
"type": "string"
}
],
"description": "The electron locales. By default Electron locales used as is."
"description": "The electron locales to keep. By default, all Electron locales used as-is."
},
"electronUpdaterCompatibility": {
"description": "The [electron-updater compatibility](/auto-update#compatibility) semver range.",
Expand Down Expand Up @@ -6006,6 +6020,20 @@
"description": "Whether to infer update channel from application version pre-release components. e.g. if version `0.12.1-alpha.1`, channel will be set to `alpha`. Otherwise to `latest`.",
"type": "boolean"
},
"electronLanguages": {
"anyOf": [
{
"items": {
"type": "string"
},
"type": "array"
},
{
"type": "string"
}
],
"description": "The electron locales to keep. By default, all Electron locales used as-is."
},
"electronUpdaterCompatibility": {
"description": "The [electron-updater compatibility](/auto-update#compatibility) semver range.",
"type": [
Expand Down Expand Up @@ -6667,6 +6695,20 @@
"$ref": "#/definitions/ElectronDownloadOptions",
"description": "The [electron-download](https://github.com/electron-userland/electron-download#usage) options."
},
"electronLanguages": {
"anyOf": [
{
"items": {
"type": "string"
},
"type": "array"
},
{
"type": "string"
}
],
"description": "The electron locales to keep. By default, all Electron locales used as-is."
},
"electronUpdaterCompatibility": {
"description": "The [electron-updater compatibility](/auto-update#compatibility) semver range.",
"type": [
Expand Down Expand Up @@ -7142,11 +7184,6 @@
"$ref": "#/definitions/ReleaseInfo",
"description": "The release info. Intended for command line usage:\n\n```\n-c.releaseInfo.releaseNotes=\"new features\"\n```"
},
"remoteBuild": {
"default": true,
"description": "Whether to build using Electron Build Service if target not supported on current OS.",
"type": "boolean"
},
"removePackageKeywords": {
"default": true,
"description": "Whether to remove `keywords` field from `package.json` files.",
Expand Down
6 changes: 0 additions & 6 deletions packages/app-builder-lib/src/configuration.ts
Expand Up @@ -255,12 +255,6 @@ export interface Configuration extends PlatformSpecificBuildOptions {
*/
readonly beforeBuild?: ((context: BeforeBuildContext) => Promise<any>) | string | null

/**
* Whether to build using Electron Build Service if target not supported on current OS.
* @default true
*/
readonly remoteBuild?: boolean

/**
* Whether to include PDB files.
* @default false
Expand Down
73 changes: 40 additions & 33 deletions packages/app-builder-lib/src/electron/ElectronFramework.ts
Expand Up @@ -8,7 +8,6 @@ import { BeforeCopyExtraFilesOptions, Framework, PrepareApplicationStageDirector
import { Packager, Platform } from "../index"
import { LinuxPackager } from "../linuxPackager"
import MacPackager from "../macPackager"
import { isSafeToUnpackElectronOnRemoteBuildServer } from "../platformPackager"
import { getTemplatePath } from "../util/pathManager"
import { createMacApp } from "./electronMac"
import { computeElectronVersion, getElectronVersionFromInstalled } from "./electronVersion"
Expand Down Expand Up @@ -70,44 +69,55 @@ function createDownloadOpts(opts: Configuration, platform: ElectronPlatformName,
}

async function beforeCopyExtraFiles(options: BeforeCopyExtraFilesOptions) {
const packager = options.packager
const appOutDir = options.appOutDir
const { appOutDir, packager } = options
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, electronBranding.projectName), executable)
}
const linuxPackager = packager as LinuxPackager
const executable = path.join(appOutDir, linuxPackager.executableName)
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, `${electronBranding.projectName}.exe`), executable)
} else {
await createMacApp(packager as MacPackager, appOutDir, options.asarIntegrity, (options.platformName as ElectronPlatformName) === "mas")
}
await removeUnusedLanguagesIfNeeded(options)
}

const wantedLanguages = asArray(packager.platformSpecificBuildOptions.electronLanguages)
if (wantedLanguages.length === 0) {
return
}
async function removeUnusedLanguagesIfNeeded(options: BeforeCopyExtraFilesOptions) {
const {
packager: { config, platformSpecificBuildOptions },
} = options
const wantedLanguages = asArray(platformSpecificBuildOptions.electronLanguages || config.electronLanguages)
if (!wantedLanguages.length) {
return
}

// noinspection SpellCheckingInspection
const langFileExt = ".lproj"
const resourcesDir = packager.getResourcesDir(appOutDir)
await BluebirdPromise.map(
readdir(resourcesDir),
file => {
if (!file.endsWith(langFileExt)) {
return
}

const language = file.substring(0, file.length - langFileExt.length)
if (!wantedLanguages.includes(language)) {
return fs.rm(path.join(resourcesDir, file), { recursive: true, force: true })
}
const { dir, langFileExt } = getLocalesConfig(options)
// noinspection SpellCheckingInspection
await BluebirdPromise.map(
readdir(dir),
file => {
if (!file.endsWith(langFileExt)) {
return
},
CONCURRENCY
)
}

const language = file.substring(0, file.length - langFileExt.length)
if (!wantedLanguages.includes(language)) {
return fs.rm(path.join(dir, file), { recursive: true, force: true })
}
return
},
CONCURRENCY
)

function getLocalesConfig(options: BeforeCopyExtraFilesOptions) {
const { appOutDir, packager } = options
if (packager.platform === Platform.MAC) {
return { dir: packager.getResourcesDir(appOutDir), langFileExt: ".lproj" }
} else {
return { dir: path.join(packager.getResourcesDir(appOutDir), "..", "locales"), langFileExt: ".pak" }
}
}
}

Expand Down Expand Up @@ -172,17 +182,14 @@ async function unpack(prepareOptions: PrepareApplicationStageDirectoryOptions, o
const zipFile = `electron-v${options.version}-${platformName}-${options.arch}.zip`
const resolvedDist = path.isAbsolute(dist) ? dist : path.resolve(packager.projectDir, dist)
if ((await statOrNull(path.join(resolvedDist, zipFile))) != null) {
log.info({ resolvedDist, zipFile }, "Resolved electronDist")
log.info({ resolvedDist, zipFile }, "resolved electronDist")
options.cache = resolvedDist
dist = null
}
}

let isFullCleanup = false
if (dist == null) {
if (isSafeToUnpackElectronOnRemoteBuildServer(packager)) {
return
}
await executeAppBuilder(["unpack-electron", "--configuration", JSON.stringify([options]), "--output", appOutDir, "--distMacOsAppName", distMacOsAppName])
} else {
isFullCleanup = true
Expand Down
53 changes: 3 additions & 50 deletions packages/app-builder-lib/src/linuxPackager.ts
@@ -1,9 +1,8 @@
import { Arch, AsyncTaskManager, log } from "builder-util"
import { DIR_TARGET, Platform, Target, TargetSpecificOptions } from "./core"
import { Arch } from "builder-util"
import { DIR_TARGET, Platform, Target } from "./core"
import { LinuxConfiguration } from "./options/linuxOptions"
import { Packager } from "./packager"
import { PlatformPackager } from "./platformPackager"
import { RemoteBuilder } from "./remoteBuilder/RemoteBuilder"
import AppImageTarget from "./targets/AppImageTarget"
import FlatpakTarget from "./targets/FlatpakTarget"
import FpmTarget from "./targets/FpmTarget"
Expand Down Expand Up @@ -35,8 +34,6 @@ export class LinuxPackager extends PlatformPackager<LinuxConfiguration> {
return helper
}

let remoteBuilder: RemoteBuilder | null = null

for (const name of targets) {
if (name === DIR_TARGET) {
continue
Expand Down Expand Up @@ -68,56 +65,12 @@ export class LinuxPackager extends PlatformPackager<LinuxConfiguration> {
return createCommonTarget(name, outDir, this)
}

const target = new targetClass(name, this, getHelper(), outDir)
if (process.platform === "win32" || process.env._REMOTE_BUILD) {
if (remoteBuilder == null) {
remoteBuilder = new RemoteBuilder(this)
}
// return remoteBuilder.buildTarget(this, arch, appOutDir, this.packager)
return new RemoteTarget(target, remoteBuilder)
}
return target
return new targetClass(name, this, getHelper(), outDir)
})
}
}
}

class RemoteTarget extends Target {
private buildTaskManager = new AsyncTaskManager(this.remoteBuilder.packager.info.cancellationToken)

get options(): TargetSpecificOptions | null | undefined {
return this.target.options
}

get outDir(): string {
return this.target.outDir
}

constructor(private readonly target: Target, private readonly remoteBuilder: RemoteBuilder) {
super(
target.name,
true /* all must be scheduled in time (so, on finishBuild RemoteBuilder will have all targets added - so, we must set isAsyncSupported to true (resolved promise is returned)) */
)
}

async finishBuild() {
await this.buildTaskManager.awaitTasks()
await this.remoteBuilder.build()
}

build(appOutDir: string, arch: Arch) {
const promise = this.doBuild(appOutDir, arch)
this.buildTaskManager.addTask(promise)
return promise
}

private async doBuild(appOutDir: string, arch: Arch) {
log.info({ target: this.target.name, arch: Arch[arch] }, "scheduling remote build")
await this.target.checkOptions()
this.remoteBuilder.scheduleBuild(this.target, arch, appOutDir)
}
}

export function toAppImageOrSnapArch(arch: Arch): string {
switch (arch) {
case Arch.x64:
Expand Down
Expand Up @@ -79,6 +79,11 @@ export interface PlatformSpecificBuildOptions extends TargetSpecificOptions {
*/
readonly protocols?: Array<Protocol> | Protocol

/**
* The electron locales to keep. By default, all Electron locales used as-is.
*/
readonly electronLanguages?: Array<string> | string

/**
* Whether to fail if app will be not code signed.
*/
Expand Down
5 changes: 0 additions & 5 deletions packages/app-builder-lib/src/options/macOptions.ts
Expand Up @@ -136,11 +136,6 @@ export interface MacConfiguration extends PlatformSpecificBuildOptions {
*/
readonly requirements?: string | null

/**
* The electron locales. By default Electron locales used as is.
*/
readonly electronLanguages?: Array<string> | string

/** @private */
readonly cscInstallerLink?: string | null
/** @private */
Expand Down
13 changes: 1 addition & 12 deletions packages/app-builder-lib/src/platformPackager.ts
@@ -1,5 +1,5 @@
import BluebirdPromise from "bluebird-lst"
import { Arch, asArray, AsyncTaskManager, debug, DebugLogger, deepAssign, getArchSuffix, InvalidConfigurationError, isEmptyOrSpaces, log, isEnvTrue } from "builder-util"
import { Arch, asArray, AsyncTaskManager, debug, DebugLogger, deepAssign, getArchSuffix, InvalidConfigurationError, isEmptyOrSpaces, log } from "builder-util"
import { defaultArchFromString, getArtifactArchName } from "builder-util/out/arch"
import { FileTransformer, statOrNull } from "builder-util/out/fs"
import { orIfFileNotExist } from "builder-util/out/promise"
Expand Down Expand Up @@ -786,14 +786,3 @@ export function chooseNotNull(v1: string | null | undefined, v2: string | null |
function capitalizeFirstLetter(text: string) {
return text.charAt(0).toUpperCase() + text.slice(1)
}

export function isSafeToUnpackElectronOnRemoteBuildServer(packager: PlatformPackager<any>) {
if (packager.platform !== Platform.LINUX || packager.config.remoteBuild === false) {
return false
}

if (process.platform === "win32" || isEnvTrue(process.env._REMOTE_BUILD)) {
return packager.config.electronDist == null && packager.config.electronDownload == null
}
return false
}

0 comments on commit 1533501

Please sign in to comment.