|
1 | 1 | import { asArray, copyDir, DO_NOT_USE_HARD_LINKS, executeAppBuilder, log, MAX_FILE_REQUESTS, statOrNull, unlinkIfExists } from "builder-util" |
2 | | -import { emptyDir, readdir, rename } from "fs-extra" |
3 | | -import * as fs from "fs/promises" |
| 2 | +import { emptyDir, readdir, rename, rm } from "fs-extra" |
4 | 3 | import * as path from "path" |
5 | 4 | import asyncPool from "tiny-async-pool" |
6 | 5 | import { Configuration } from "../configuration" |
@@ -107,7 +106,7 @@ async function removeUnusedLanguagesIfNeeded(options: BeforeCopyExtraFilesOption |
107 | 106 |
|
108 | 107 | const language = path.basename(file, langFileExt) |
109 | 108 | if (!wantedLanguages.includes(language)) { |
110 | | - return fs.rm(path.join(dir, file), { recursive: true, force: true }) |
| 109 | + return rm(path.join(dir, file), { recursive: true, force: true }) |
111 | 110 | } |
112 | 111 | return |
113 | 112 | }) |
@@ -149,7 +148,9 @@ class ElectronFramework implements Framework { |
149 | 148 | } |
150 | 149 |
|
151 | 150 | async prepareApplicationStageDirectory(options: PrepareApplicationStageDirectoryOptions) { |
152 | | - await unpack(options, createDownloadOpts(options.packager.config, options.platformName, options.arch, this.version), this.distMacOsAppName) |
| 151 | + const downloadOptions = createDownloadOpts(options.packager.config, options.platformName, options.arch, this.version) |
| 152 | + const shouldCleanup = await unpack(options, downloadOptions, this.distMacOsAppName) |
| 153 | + await cleanupAfterUnpack(options, this.distMacOsAppName, shouldCleanup) |
153 | 154 | if (options.packager.config.downloadAlternateFFmpeg) { |
154 | 155 | await injectFFMPEG(options, this.version) |
155 | 156 | } |
@@ -179,49 +180,79 @@ export async function createElectronFrameworkSupport(configuration: Configuratio |
179 | 180 | return new ElectronFramework(branding.projectName, version, `${branding.productName}.app`) |
180 | 181 | } |
181 | 182 |
|
182 | | -async function unpack(prepareOptions: PrepareApplicationStageDirectoryOptions, options: ElectronDownloadOptions, distMacOsAppName: string) { |
| 183 | +/** |
| 184 | + * Unpacks a custom or default Electron distribution into the app output directory. |
| 185 | + */ |
| 186 | +async function unpack(prepareOptions: PrepareApplicationStageDirectoryOptions, downloadOptions: ElectronDownloadOptions, distMacOsAppName: string) { |
| 187 | + const downloadUsingAdjustedConfig = (options: ElectronDownloadOptions) => { |
| 188 | + return executeAppBuilder(["unpack-electron", "--configuration", JSON.stringify([options]), "--output", appOutDir, "--distMacOsAppName", distMacOsAppName]) |
| 189 | + } |
| 190 | + |
183 | 191 | const { packager, appOutDir, platformName } = prepareOptions |
| 192 | + const { version, arch } = downloadOptions |
| 193 | + const defaultZipName = `electron-v${version}-${platformName}-${arch}.zip` |
184 | 194 |
|
185 | | - const electronDist = packager.config.electronDist || null |
186 | | - let dist: string | null = null |
187 | | - // check if supplied a custom electron distributable/fork/predownloaded directory |
188 | | - if (typeof electronDist === "string") { |
189 | | - let resolvedDist: string |
190 | | - // check if custom electron hook file for import resolving |
191 | | - if ((await statOrNull(electronDist))?.isFile()) { |
192 | | - const customElectronDist: any = await resolveFunction(packager.appInfo.type, electronDist, "electronDist") |
193 | | - resolvedDist = await Promise.resolve(typeof customElectronDist === "function" ? customElectronDist(prepareOptions) : customElectronDist) |
194 | | - } else { |
195 | | - resolvedDist = electronDist |
196 | | - } |
197 | | - dist = path.isAbsolute(resolvedDist) ? resolvedDist : path.resolve(packager.projectDir, resolvedDist) |
198 | | - } |
199 | | - if (dist != null) { |
200 | | - const zipFile = `electron-v${options.version}-${platformName}-${options.arch}.zip` |
201 | | - if ((await statOrNull(path.join(dist, zipFile))) != null) { |
202 | | - log.info({ dist, zipFile }, "resolved electronDist") |
203 | | - options.cache = dist |
204 | | - dist = null |
205 | | - } else { |
206 | | - log.info({ electronDist: log.filePath(dist), expectedFile: zipFile }, "custom electronDist provided but no zip found; assuming unpacked electron directory.") |
207 | | - } |
| 195 | + let resolvedDist: string | null = null |
| 196 | + try { |
| 197 | + const electronDistHook: any = await resolveFunction(packager.appInfo.type, packager.config.electronDist, "electronDist") |
| 198 | + resolvedDist = typeof electronDistHook === "function" ? await Promise.resolve(electronDistHook(prepareOptions)) : electronDistHook |
| 199 | + } catch (error: any) { |
| 200 | + throw new Error("Failed to resolve electronDist: " + error.message) |
208 | 201 | } |
209 | 202 |
|
210 | | - let isFullCleanup = false |
211 | | - if (dist == null) { |
212 | | - await executeAppBuilder(["unpack-electron", "--configuration", JSON.stringify([options]), "--output", appOutDir, "--distMacOsAppName", distMacOsAppName]) |
213 | | - } else { |
214 | | - isFullCleanup = true |
215 | | - const source = packager.getElectronSrcDir(dist) |
216 | | - const destination = packager.getElectronDestinationDir(appOutDir) |
217 | | - log.info({ source, destination }, "copying Electron") |
218 | | - await emptyDir(appOutDir) |
219 | | - await copyDir(source, destination, { |
220 | | - isUseHardLink: DO_NOT_USE_HARD_LINKS, |
| 203 | + if (resolvedDist == null) { |
| 204 | + // if no custom electronDist is provided, use the default unpack logic |
| 205 | + log.debug(null, "no custom electronDist provided, unpacking default Electron distribution") |
| 206 | + await downloadUsingAdjustedConfig(downloadOptions) |
| 207 | + return true // indicates that we should clean up after unpacking |
| 208 | + } |
| 209 | + |
| 210 | + if (!path.isAbsolute(resolvedDist)) { |
| 211 | + // if it's a relative path, resolve it against the project directory |
| 212 | + resolvedDist = path.resolve(packager.projectDir, resolvedDist) |
| 213 | + } |
| 214 | + |
| 215 | + const electronDistStats = await statOrNull(resolvedDist) |
| 216 | + if (!electronDistStats) { |
| 217 | + throw new Error(`The specified electronDist does not exist: ${resolvedDist}. Please provide a valid path to the Electron zip file or cache directory.`) |
| 218 | + } |
| 219 | + |
| 220 | + if (resolvedDist.endsWith(".zip")) { |
| 221 | + log.info({ zipFile: resolvedDist }, "using custom electronDist zip file") |
| 222 | + await downloadUsingAdjustedConfig({ |
| 223 | + ...downloadOptions, |
| 224 | + cache: path.dirname(resolvedDist), // set custom directory to the zip file's directory |
| 225 | + customFilename: path.basename(resolvedDist), // set custom filename to the zip file's name |
221 | 226 | }) |
| 227 | + return false // do not clean up after unpacking, it's a custom bundle and we should respect its configuration/contents as required |
222 | 228 | } |
223 | 229 |
|
224 | | - await cleanupAfterUnpack(prepareOptions, distMacOsAppName, isFullCleanup) |
| 230 | + if (electronDistStats.isDirectory()) { |
| 231 | + // backward compatibility: if electronDist is a directory, check for the default zip file inside it |
| 232 | + const files = await readdir(resolvedDist) |
| 233 | + if (files.includes(defaultZipName)) { |
| 234 | + log.info({ electronDist: log.filePath(resolvedDist) }, "using custom electronDist directory") |
| 235 | + await downloadUsingAdjustedConfig({ |
| 236 | + ...downloadOptions, |
| 237 | + cache: resolvedDist, |
| 238 | + customFilename: defaultZipName, |
| 239 | + }) |
| 240 | + return false |
| 241 | + } |
| 242 | + } |
| 243 | + |
| 244 | + // if we reach here, it means the provided electronDist is neither a zip file nor a directory with the default zip file |
| 245 | + // e.g. we treat it as a custom already-unpacked Electron distribution |
| 246 | + log.info({ electronDist: log.filePath(resolvedDist) }, "using custom unpacked Electron distribution") |
| 247 | + const source = packager.getElectronSrcDir(resolvedDist) |
| 248 | + const destination = packager.getElectronDestinationDir(appOutDir) |
| 249 | + log.info({ source, destination }, "copying unpacked Electron") |
| 250 | + await emptyDir(appOutDir) |
| 251 | + await copyDir(source, destination, { |
| 252 | + isUseHardLink: DO_NOT_USE_HARD_LINKS, |
| 253 | + }) |
| 254 | + |
| 255 | + return false |
225 | 256 | } |
226 | 257 |
|
227 | 258 | function cleanupAfterUnpack(prepareOptions: PrepareApplicationStageDirectoryOptions, distMacOsAppName: string, isFullCleanup: boolean) { |
|
0 commit comments