Skip to content

Commit

Permalink
small refactor/extraction to isolated functions. Removed additional p…
Browse files Browse the repository at this point in the history
…arameters from `electronDownload` options to make it more simple for end-users/developers
  • Loading branch information
mmaietta committed Feb 5, 2025
1 parent 093861a commit 81050ba
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 54 deletions.
27 changes: 0 additions & 27 deletions packages/app-builder-lib/scheme.json
Original file line number Diff line number Diff line change
Expand Up @@ -957,11 +957,6 @@
},
"type": "object"
},
"Downloader<any>": {
"additionalProperties": false,
"description": "Generic interface for the artifact downloader library.\nThe default implementation is {@link GotDownloader},\nbut any custom downloader can be passed to `@electron/get` via\nthe {@link ElectronDownloadRequestOptions.downloader} option.",
"type": "object"
},
"ElectronBrandingOptions": {
"additionalProperties": false,
"description": "Electron distributables branding options.",
Expand All @@ -978,30 +973,12 @@
"ElectronDownloadOptions": {
"additionalProperties": false,
"properties": {
"cacheMode": {
"description": "Controls the cache read and write behavior.\n\nWhen set to either {@link ElectronDownloadCacheMode.ReadOnlyReadOnly} or\n{@link ElectronDownloadCacheMode.BypassBypass}, the caller is responsible\nfor cleaning up the returned file path once they are done using it\n(e.g. via `fs.remove(path.dirname(pathFromElectronGet))`).\n\nWhen set to either {@link ElectronDownloadCacheMode.WriteOnlyWriteOnly} or\n{@link ElectronDownloadCacheMode.ReadWriteReadWrite} (the default), the caller\nshould not move or delete the file path that is returned as the path\npoints directly to the disk cache.\n\nThis option cannot be used in conjunction with {@link ElectronDownloadRequestOptions.force}.",
"enum": [
0,
1,
2,
3
],
"type": "number"
},
"cacheRoot": {
"description": "The directory that caches Electron artifact downloads.",
"type": "string"
},
"checksums": {
"type": "object"
},
"downloadOptions": {
"description": "Options passed to the downloader module."
},
"downloader": {
"$ref": "#/definitions/Downloader<any>",
"description": "A custom {@link Downloader} class used to download artifacts. Defaults to the\nbuilt-in {@link GotDownloader}."
},
"force": {
"description": "Whether to download an artifact regardless of whether it's in the cache directory.",
"type": "boolean"
Expand All @@ -1014,10 +991,6 @@
"$ref": "#/definitions/MirrorOptions",
"description": "Options related to specifying an artifact mirror."
},
"tempDirectory": {
"description": "A temporary directory for downloads.\nIt is used before artifacts are put into cache.",
"type": "string"
},
"unsafelyDisableChecksums": {
"description": "When set to `true`, disables checking that the artifact download completed successfully\nwith the correct payload.",
"type": "boolean"
Expand Down
75 changes: 48 additions & 27 deletions packages/app-builder-lib/src/electron/ElectronFramework.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,10 @@ export function createBrandingOpts(opts: Configuration): Required<ElectronBrandi
}
}

export type ElectronDownloadOptions = Omit<ElectronPlatformArtifactDetails, "platform" | "arch" | "version" | "artifactName" | "artifactSuffix" | "customFilename"> & {
export type ElectronDownloadOptions = Omit<
ElectronPlatformArtifactDetails,
"platform" | "arch" | "version" | "artifactName" | "artifactSuffix" | "customFilename" | "tempDirectory" | "downloader" | "cacheMode" | "cacheRoot"
> & {
mirrorOptions: Omit<MirrorOptions, "customDir" | "customFilename" | "customVersion">
}

Expand Down Expand Up @@ -119,7 +122,6 @@ class ElectronFramework implements Framework {
}

async prepareApplicationStageDirectory(options: PrepareApplicationStageDirectoryOptions) {
// await unpack(options, createDownloadOpts(options.packager.config, options.platformName, options.arch, this.version), this.distMacOsAppName)
await this.unpack(options, this.version, this.productName)
if (options.packager.config.downloadAlternateFFmpeg) {
await injectFFMPEG(this.progress, options, this.version, this.productName)
Expand All @@ -131,30 +133,24 @@ class ElectronFramework implements Framework {
}

private async unpack(prepareOptions: PrepareApplicationStageDirectoryOptions, version: string, productFilename: string) {
const { platformName, arch } = prepareOptions
const zipFileName = `electron-v${version}-${platformName}-${arch}.zip`

const dist = await this.resolveElectronDist(prepareOptions, zipFileName)
await this.copyOrDownloadElectronDist(dist, prepareOptions, version, zipFileName)

await this.cleanupAfterUnpack(prepareOptions, productFilename)
}

private async copyOrDownloadElectronDist(dist: string | null, prepareOptions: PrepareApplicationStageDirectoryOptions, version: string, zipFileName: string) {
const { packager, appOutDir, platformName, arch } = prepareOptions
const {
config: { electronDownload },
} = packager

const electronDist = packager.config.electronDist || null
let dist: string | null = null
// check if supplied a custom electron distributable/fork/predownloaded directory
if (typeof electronDist === "string") {
let resolvedDist: string
// check if custom electron hook file for import resolving
if ((await statOrNull(electronDist))?.isFile()) {
const customElectronDist: any = await resolveFunction(packager.appInfo.type, electronDist, "electronDist")
resolvedDist = await Promise.resolve(typeof customElectronDist === "function" ? customElectronDist(prepareOptions) : customElectronDist)
} else {
resolvedDist = electronDist
}
dist = path.isAbsolute(resolvedDist) ? resolvedDist : path.resolve(packager.projectDir, resolvedDist)
}
const zipFile = `electron-v${version}-${platformName}-${arch}.zip`
if (dist != null) {
const zipFilePath = path.join(dist, zipFile)
const zipFilePath = path.join(dist, zipFileName)
if (await exists(zipFilePath)) {
log.info({ dist, zipFile }, "resolved electronDist")
log.info({ dist, zipFile: zipFileName }, "resolved electronDist")
dist = zipFilePath
} else if ((await statOrNull(dist))?.isDirectory()) {
const source = path.isAbsolute(dist) ? dist : packager.getElectronSrcDir(dist)
Expand All @@ -167,26 +163,28 @@ class ElectronFramework implements Framework {
dist = null
} else {
log.warn(
{ searchDir: log.filePath(dist), zipTarget: zipFile },
{ searchDir: log.filePath(dist), zipTarget: zipFileName },
"custom `electronDist` provided but no zip or unpacked electron directory found; falling back to official electron app"
)
}
} else {
let cacheEnv = process.env.ELECTRON_BUILDER_CACHE
if (cacheEnv && isEmptyOrSpaces(cacheEnv) && (await exists(cacheEnv))) {
if (!isEmptyOrSpaces(cacheEnv) && (await statOrNull(cacheEnv))?.isDirectory()) {
cacheEnv = path.resolve(cacheEnv)
} else {
cacheEnv = undefined
}

log.info({ zipFile }, "downloading")
const progressBar = this.progress?.createBar(`${" ".repeat(PADDING + 2)}[:bar] :percent | ${chalk.green(zipFile)}`, { total: 100 })
log.info({ zipFile: zipFileName }, "downloading")
const progressBar = this.progress?.createBar(`${" ".repeat(PADDING + 2)}[:bar] :percent | ${chalk.green(zipFileName)}`, { total: 100 })
progressBar?.render()

const tempDirectory = await packager.info.tempDirManager.getTempDir({ prefix: "temp-electron" })
await mkdir(tempDirectory)

const artifactConfig: ElectronPlatformArtifactDetails = {
cacheMode: ElectronDownloadCacheMode.ReadOnly,
cacheRoot: tempDirectory,
cacheMode: cacheEnv ? ElectronDownloadCacheMode.ReadOnly : undefined,
cacheRoot: cacheEnv,
tempDirectory,
...(electronDownload ?? {}),
platform: platformName,
Expand All @@ -210,8 +208,31 @@ class ElectronFramework implements Framework {
await executeAppBuilder(["unzip", "--input", dist, "--output", appOutDir])
log.info(null, "electron unpacked successfully")
}
return dist
}

await this.cleanupAfterUnpack(prepareOptions, productFilename)
private async resolveElectronDist(prepareOptions: PrepareApplicationStageDirectoryOptions, zipFileName: string) {
const { packager } = prepareOptions

const electronDist = packager.config.electronDist || null
let dist: string | null = null
// check if supplied a custom electron distributable/fork/predownloaded directory
if (typeof electronDist === "string") {
let resolvedDist: string
// check if custom electron hook file for import resolving
if ((await statOrNull(electronDist))?.isFile() && !electronDist.endsWith(zipFileName)) {
const customElectronDist = await resolveFunction<string | ((options: PrepareApplicationStageDirectoryOptions) => string)>(
packager.appInfo.type,
electronDist,
"electronDist"
)
resolvedDist = await Promise.resolve(typeof customElectronDist === "function" ? customElectronDist(prepareOptions) : customElectronDist)
} else {
resolvedDist = electronDist
}
dist = path.isAbsolute(resolvedDist) ? resolvedDist : path.resolve(packager.projectDir, resolvedDist)
}
return dist
}

private async cleanupAfterUnpack(prepareOptions: PrepareApplicationStageDirectoryOptions, productFilename: string) {
Expand Down

0 comments on commit 81050ba

Please sign in to comment.