From a7531e6e8f46b00d3db9863ba2bbd1ac44dd0e41 Mon Sep 17 00:00:00 2001 From: Mike Maietta Date: Fri, 1 Nov 2024 15:18:03 -0700 Subject: [PATCH 01/19] tmp save --- packages/app-builder-lib/src/asar/asarUtil.ts | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/packages/app-builder-lib/src/asar/asarUtil.ts b/packages/app-builder-lib/src/asar/asarUtil.ts index ffde70952f2..22b06d57e8d 100644 --- a/packages/app-builder-lib/src/asar/asarUtil.ts +++ b/packages/app-builder-lib/src/asar/asarUtil.ts @@ -1,7 +1,7 @@ import { CreateOptions, createPackageWithOptions } from "@electron/asar" import { AsyncTaskManager, log } from "builder-util" import { CancellationToken } from "builder-util-runtime" -import { Filter, MAX_FILE_REQUESTS } from "builder-util/out/fs" +import { FileCopier, Filter, MAX_FILE_REQUESTS } from "builder-util/out/fs" import * as fsNode from "fs" import * as fs from "fs-extra" import * as path from "path" @@ -77,6 +77,7 @@ export class AsarPackager { const taskManager = new AsyncTaskManager(cancellationToken) const unpackedPaths = new Set() const copiedFiles = new Set() + const fileCopier = new FileCopier() const matchUnpacker = (file: string, dest: string, stat: fs.Stats) => { if (this.config.unpackPattern?.(file, stat)) { @@ -96,14 +97,14 @@ export class AsarPackager { copiedFiles.add(destination) // If transformed data, skip symlink logic - if (transformedData) { - return this.copyFileOrData(transformedData, source, destination, stat) + if (transformedData != null) { + return this.copyFileOrData(fileCopier, transformedData, source, destination, stat) } const realPathFile = await fs.realpath(source) if (source === realPathFile) { - return this.copyFileOrData(undefined, source, destination, stat) + return this.copyFileOrData(fileCopier, undefined, source, destination, stat) } const realPathRelative = path.relative(sourceDir, realPathFile) @@ -116,7 +117,7 @@ export class AsarPackager { } const symlinkTarget = path.resolve(this.rootForAppFilesWithoutAsar, realPathRelative) - await this.copyFileOrData(undefined, source, symlinkTarget, stat) + await this.copyFileOrData(fileCopier, undefined, source, symlinkTarget, stat) const target = path.relative(path.dirname(destination), symlinkTarget) fsNode.symlinkSync(target, destination) @@ -150,12 +151,12 @@ export class AsarPackager { } } - private async copyFileOrData(data: string | Buffer | undefined, source: string, destination: string, stat: fs.Stats) { + private async copyFileOrData(fileCopier: FileCopier, data: string | Buffer | undefined, source: string, destination: string, stat: fs.Stats) { await fs.mkdir(path.dirname(destination), { recursive: true }) if (data) { - await fs.writeFile(destination, data, { mode: stat.mode }) + return fs.writeFile(destination, data, { mode: stat.mode }) } else { - await fs.copyFile(source, destination) + return fileCopier.copy(source, destination, stat) } } } From f01dde286ef6f8e6e90cf0f1d9f03354c6912f00 Mon Sep 17 00:00:00 2001 From: Mike Maietta Date: Sun, 3 Nov 2024 17:36:19 -0800 Subject: [PATCH 02/19] tmp save with new testcase of HellowWorld.framework --- packages/app-builder-lib/src/asar/asarUtil.ts | 122 +++++++++++++----- .../app-builder-lib/src/util/appFileCopier.ts | 4 +- .../test-app-symlink-framework/main.js | 1 + .../test-app-symlink-framework/package.json | 18 +++ .../lib/Release/Hello.framework/Headers | 1 + .../lib/Release/Hello.framework/Hello | 1 + .../lib/Release/Hello.framework/Info.plist | 1 + .../lib/Release/Hello.framework/Modules | 1 + .../lib/Release/Hello.framework/Resources | 1 + .../Versions/A/Headers/HelloFramework.h | 2 + .../Release/Hello.framework/Versions/A/Hello | Bin 0 -> 16120 bytes .../Hello.framework/Versions/A/Info.plist | 24 ++++ .../Versions/A/Modules/Hello.abi.json | 82 ++++++++++++ .../Versions/A/Modules/Hello.swiftdoc | Bin 0 -> 408 bytes .../arm64.private.swiftinterface | 12 ++ .../Hello.swiftmodule/arm64.swiftinterface | 12 ++ .../Hello.swiftmodule/arm64.swiftmodule | Bin 0 -> 17940 bytes .../x86_64.private.swiftinterface | 12 ++ .../Hello.swiftmodule/x86_64.swiftinterface | 12 ++ .../Hello.swiftmodule/x86_64.swiftmodule | Bin 0 -> 17944 bytes .../Versions/A/Modules/Hello.swiftsourceinfo | Bin 0 -> 1064 bytes .../Versions/A/Modules/module.modulemap | 4 + .../Release/Hello.framework/Versions/Current | 1 + .../stripped-native-dep/package.json | 8 ++ test/src/globTest.ts | 18 +++ 25 files changed, 306 insertions(+), 31 deletions(-) create mode 100644 test/fixtures/test-app-symlink-framework/main.js create mode 100644 test/fixtures/test-app-symlink-framework/package.json create mode 120000 test/fixtures/test-app-symlink-framework/stripped-native-dep/lib/Release/Hello.framework/Headers create mode 120000 test/fixtures/test-app-symlink-framework/stripped-native-dep/lib/Release/Hello.framework/Hello create mode 120000 test/fixtures/test-app-symlink-framework/stripped-native-dep/lib/Release/Hello.framework/Info.plist create mode 120000 test/fixtures/test-app-symlink-framework/stripped-native-dep/lib/Release/Hello.framework/Modules create mode 120000 test/fixtures/test-app-symlink-framework/stripped-native-dep/lib/Release/Hello.framework/Resources create mode 100755 test/fixtures/test-app-symlink-framework/stripped-native-dep/lib/Release/Hello.framework/Versions/A/Headers/HelloFramework.h create mode 100755 test/fixtures/test-app-symlink-framework/stripped-native-dep/lib/Release/Hello.framework/Versions/A/Hello create mode 100755 test/fixtures/test-app-symlink-framework/stripped-native-dep/lib/Release/Hello.framework/Versions/A/Info.plist create mode 100755 test/fixtures/test-app-symlink-framework/stripped-native-dep/lib/Release/Hello.framework/Versions/A/Modules/Hello.abi.json create mode 100755 test/fixtures/test-app-symlink-framework/stripped-native-dep/lib/Release/Hello.framework/Versions/A/Modules/Hello.swiftdoc create mode 100755 test/fixtures/test-app-symlink-framework/stripped-native-dep/lib/Release/Hello.framework/Versions/A/Modules/Hello.swiftmodule/arm64.private.swiftinterface create mode 100755 test/fixtures/test-app-symlink-framework/stripped-native-dep/lib/Release/Hello.framework/Versions/A/Modules/Hello.swiftmodule/arm64.swiftinterface create mode 100755 test/fixtures/test-app-symlink-framework/stripped-native-dep/lib/Release/Hello.framework/Versions/A/Modules/Hello.swiftmodule/arm64.swiftmodule create mode 100755 test/fixtures/test-app-symlink-framework/stripped-native-dep/lib/Release/Hello.framework/Versions/A/Modules/Hello.swiftmodule/x86_64.private.swiftinterface create mode 100755 test/fixtures/test-app-symlink-framework/stripped-native-dep/lib/Release/Hello.framework/Versions/A/Modules/Hello.swiftmodule/x86_64.swiftinterface create mode 100755 test/fixtures/test-app-symlink-framework/stripped-native-dep/lib/Release/Hello.framework/Versions/A/Modules/Hello.swiftmodule/x86_64.swiftmodule create mode 100755 test/fixtures/test-app-symlink-framework/stripped-native-dep/lib/Release/Hello.framework/Versions/A/Modules/Hello.swiftsourceinfo create mode 100755 test/fixtures/test-app-symlink-framework/stripped-native-dep/lib/Release/Hello.framework/Versions/A/Modules/module.modulemap create mode 120000 test/fixtures/test-app-symlink-framework/stripped-native-dep/lib/Release/Hello.framework/Versions/Current create mode 100644 test/fixtures/test-app-symlink-framework/stripped-native-dep/package.json diff --git a/packages/app-builder-lib/src/asar/asarUtil.ts b/packages/app-builder-lib/src/asar/asarUtil.ts index 22b06d57e8d..73f0f0af6b1 100644 --- a/packages/app-builder-lib/src/asar/asarUtil.ts +++ b/packages/app-builder-lib/src/asar/asarUtil.ts @@ -1,7 +1,9 @@ +import BluebirdPromise from "bluebird-lst" + import { CreateOptions, createPackageWithOptions } from "@electron/asar" import { AsyncTaskManager, log } from "builder-util" import { CancellationToken } from "builder-util-runtime" -import { FileCopier, Filter, MAX_FILE_REQUESTS } from "builder-util/out/fs" +import { CONCURRENCY, copyDir, DO_NOT_USE_HARD_LINKS, FileCopier, Filter, FilterStats, Link, MAX_FILE_REQUESTS } from "builder-util/out/fs" import * as fsNode from "fs" import * as fs from "fs-extra" import * as path from "path" @@ -10,12 +12,15 @@ import { AsarOptions } from "../options/PlatformSpecificBuildOptions" import { PlatformPackager } from "../platformPackager" import { ResolvedFileSet, getDestinationPath } from "../util/appFileCopier" import { detectUnpackedDirs } from "./unpackDetector" +import { platform } from "os" +import { mkdir, readlink, symlink } from "fs-extra" /** @internal */ export class AsarPackager { private readonly outFile: string - private rootForAppFilesWithoutAsar!: string + private readonly rootForAppFilesWithoutAsar: string private readonly tmpDir = new tempFile.TmpDir() + private readonly fileCopier = new FileCopier(DO_NOT_USE_HARD_LINKS) constructor( private readonly config: { @@ -26,10 +31,11 @@ export class AsarPackager { } ) { this.outFile = path.join(config.resourcePath, `app.asar`) + this.rootForAppFilesWithoutAsar = path.join(config.resourcePath, "app") } async pack(fileSets: Array, _packager: PlatformPackager) { - this.rootForAppFilesWithoutAsar = await this.tmpDir.getTempDir({ prefix: "asar-app" }) + // this.rootForAppFilesWithoutAsar = await this.tmpDir.getTempDir({ prefix: "asar-app" }) const cancellationToken = new CancellationToken() cancellationToken.on("cancel", () => this.tmpDir.cleanupSync()) @@ -71,13 +77,13 @@ export class AsarPackager { console.log = consoleLogger await this.tmpDir.cleanup() + fsNode.rmSync(this.rootForAppFilesWithoutAsar, { recursive: true }) } private async detectAndCopy(fileSets: ResolvedFileSet[], cancellationToken: CancellationToken) { const taskManager = new AsyncTaskManager(cancellationToken) const unpackedPaths = new Set() const copiedFiles = new Set() - const fileCopier = new FileCopier() const matchUnpacker = (file: string, dest: string, stat: fs.Stats) => { if (this.config.unpackPattern?.(file, stat)) { @@ -90,21 +96,25 @@ export class AsarPackager { const { transformedData, file: source, - destination, + // destination, stat, - fileSet: { src: sourceDir }, + fileSet: { src: sourceDir, destination: destinationDir }, } = options + const destination = getDestinationPath(source, options.fileSet) + if (copiedFiles.has(destination)) { + return + } copiedFiles.add(destination) // If transformed data, skip symlink logic if (transformedData != null) { - return this.copyFileOrData(fileCopier, transformedData, source, destination, stat) + return this.copyFileOrData(transformedData, source, destination, stat) } const realPathFile = await fs.realpath(source) if (source === realPathFile) { - return this.copyFileOrData(fileCopier, undefined, source, destination, stat) + return this.copyFileOrData(undefined, source, destination, stat) } const realPathRelative = path.relative(sourceDir, realPathFile) @@ -116,9 +126,12 @@ export class AsarPackager { ) } - const symlinkTarget = path.resolve(this.rootForAppFilesWithoutAsar, realPathRelative) - await this.copyFileOrData(fileCopier, undefined, source, symlinkTarget, stat) - const target = path.relative(path.dirname(destination), symlinkTarget) + // await this.copyFileOrData(undefined, source, destination, stat) + // const symlinkTarget = path.resolve(this.rootForAppFilesWithoutAsar, realPathRelative) + const symlinkTarget = path.resolve(path.dirname(destination), realPathRelative) + // await this.copyFileOrData(undefined, source, symlinkTarget, stat) + const target2 = path.relative(path.dirname(destination), symlinkTarget) + const target = fs.readlinkSync(source) fsNode.symlinkSync(target, destination) copiedFiles.add(symlinkTarget) @@ -128,21 +141,59 @@ export class AsarPackager { if (this.config.options.smartUnpack !== false) { detectUnpackedDirs(fileSet, unpackedPaths, this.config.defaultDestination) } - for (let i = 0; i < fileSet.files.length; i++) { - const file = fileSet.files[i] - const transformedData = fileSet.transformedFiles?.get(i) - const metadata = fileSet.metadata.get(file) || (await fs.lstat(file)) - - const relative = path.relative(this.config.defaultDestination, getDestinationPath(file, fileSet)) - const dest = path.resolve(this.rootForAppFilesWithoutAsar, relative) - - matchUnpacker(file, dest, metadata) - taskManager.addTask(writeFileOrSymlink({ transformedData, file, destination: dest, stat: metadata, fileSet })) - - if (taskManager.tasks.length > MAX_FILE_REQUESTS) { - await taskManager.awaitTasks() - } - } + const createdSourceDirs = new Set() + const links: Array = [] + const symlinkType = platform() === "win32" ? "junction" : "file" + + await BluebirdPromise.map( + fileSet.files, + async (file, i) => { + const transformedData = fileSet.transformedFiles?.get(i) + const stat = fileSet.metadata.get(file)! + const destFile = getDestinationPath(file, fileSet) + + matchUnpacker(file, destFile, stat) + + if (!stat.isFile() && !stat.isSymbolicLink()) { + return + } + + const dir = path.dirname(destFile) + if (!createdSourceDirs.has(dir)) { + await mkdir(dir, { recursive: true }) + createdSourceDirs.add(dir) + } + + // const destFile = file.replace(file, destination) + copiedFiles.add(destFile) + if (transformedData != null) { + return fs.writeFile(destFile, transformedData, { mode: stat.mode }) + } else if (stat.isFile()) { + return this.fileCopier.copy(file, destFile, stat) + } else { + links.push({ file: destFile, link: await readlink(file) }) + return + } + }, + CONCURRENCY + ).then(() => BluebirdPromise.map(links, it => symlink(it.link, it.file, symlinkType), CONCURRENCY)) + // for (let i = 0; i < fileSet.files.length; i++) { + // const file = fileSet.files[i] + // const transformedData = fileSet.transformedFiles?.get(i) + // const metadata = fileSet.metadata.get(file)! + + // const relative = path.relative(this.config.defaultDestination, getDestinationPath(file, fileSet)) + // const dest = path.resolve(this.rootForAppFilesWithoutAsar, relative) + + // matchUnpacker(file, dest, metadata) + // // taskManager.addTask( + // await writeFileOrSymlink({ transformedData, file, destination: dest, stat: metadata, fileSet }) + // // ) + + // if (taskManager.tasks.length > MAX_FILE_REQUESTS) { + // await taskManager.awaitTasks() + // } + // } } await taskManager.awaitTasks() return { @@ -151,12 +202,25 @@ export class AsarPackager { } } - private async copyFileOrData(fileCopier: FileCopier, data: string | Buffer | undefined, source: string, destination: string, stat: fs.Stats) { + private async copyFileOrData(data: string | Buffer | undefined, source: string, destination: string, stat: fs.Stats) { + // const sourceStat = stat || fs.statSync(source) + // if (sourceStat.isSymbolicLink()) { + // return copyDir(source, destination) + // } + // if (sourceStat.isSymbolicLink()) { + // const link = fs.readlinkSync(source) + // // const symlinkTarget = path.resolve(this.rootForAppFilesWithoutAsar, realPathRelative) + // // await this.copyFileOrData(undefined, source, symlinkTarget, stat) + // const target = path.relative(path.dirname(destination), link) + // fsNode.symlinkSync(target, destination) + // return + // } await fs.mkdir(path.dirname(destination), { recursive: true }) - if (data) { + if (data != null) { return fs.writeFile(destination, data, { mode: stat.mode }) } else { - return fileCopier.copy(source, destination, stat) + // return fs.copyFile(source, destination) + return this.fileCopier.copy(source, destination, stat) } } } diff --git a/packages/app-builder-lib/src/util/appFileCopier.ts b/packages/app-builder-lib/src/util/appFileCopier.ts index ec21b9faf71..67b6af256a3 100644 --- a/packages/app-builder-lib/src/util/appFileCopier.ts +++ b/packages/app-builder-lib/src/util/appFileCopier.ts @@ -1,5 +1,5 @@ import BluebirdPromise from "bluebird-lst" -import { AsyncTaskManager, log, CONCURRENCY, FileCopier, FileTransformer, Link, MAX_FILE_REQUESTS, statOrNull, walk } from "builder-util" +import { AsyncTaskManager, log, CONCURRENCY, FileCopier, FileTransformer, Link, MAX_FILE_REQUESTS, statOrNull, walk, FilterStats } from "builder-util" import { Stats } from "fs" import { mkdir, readlink } from "fs/promises" import { ensureSymlink } from "fs-extra" @@ -82,7 +82,7 @@ export interface ResolvedFileSet { destination: string files: Array - metadata: Map + metadata: Map transformedFiles?: Map | null } diff --git a/test/fixtures/test-app-symlink-framework/main.js b/test/fixtures/test-app-symlink-framework/main.js new file mode 100644 index 00000000000..73c02658c48 --- /dev/null +++ b/test/fixtures/test-app-symlink-framework/main.js @@ -0,0 +1 @@ +console.log('Hello World'); \ No newline at end of file diff --git a/test/fixtures/test-app-symlink-framework/package.json b/test/fixtures/test-app-symlink-framework/package.json new file mode 100644 index 00000000000..aa01146486a --- /dev/null +++ b/test/fixtures/test-app-symlink-framework/package.json @@ -0,0 +1,18 @@ +{ + "main": "main.js", + "name": "TestApp", + "productName": "Test App ßW", + "version": "1.1.0", + "homepage": "http://foo.example.com", + "description": "Test Application (test quite \" #378)", + "author": "Foo Bar ", + "license": "MIT", + "build": { + "electronVersion": "23.3.10", + "appId": "org.electron-builder.testApp", + "compression": "store" + }, + "dependencies": { + "stripped-native-dep": "file:stripped-native-dep" + } +} diff --git a/test/fixtures/test-app-symlink-framework/stripped-native-dep/lib/Release/Hello.framework/Headers b/test/fixtures/test-app-symlink-framework/stripped-native-dep/lib/Release/Hello.framework/Headers new file mode 120000 index 00000000000..a177d2a6b92 --- /dev/null +++ b/test/fixtures/test-app-symlink-framework/stripped-native-dep/lib/Release/Hello.framework/Headers @@ -0,0 +1 @@ +Versions/Current/Headers \ No newline at end of file diff --git a/test/fixtures/test-app-symlink-framework/stripped-native-dep/lib/Release/Hello.framework/Hello b/test/fixtures/test-app-symlink-framework/stripped-native-dep/lib/Release/Hello.framework/Hello new file mode 120000 index 00000000000..c1f0db26723 --- /dev/null +++ b/test/fixtures/test-app-symlink-framework/stripped-native-dep/lib/Release/Hello.framework/Hello @@ -0,0 +1 @@ +Versions/Current/Hello \ No newline at end of file diff --git a/test/fixtures/test-app-symlink-framework/stripped-native-dep/lib/Release/Hello.framework/Info.plist b/test/fixtures/test-app-symlink-framework/stripped-native-dep/lib/Release/Hello.framework/Info.plist new file mode 120000 index 00000000000..ec889aa3c19 --- /dev/null +++ b/test/fixtures/test-app-symlink-framework/stripped-native-dep/lib/Release/Hello.framework/Info.plist @@ -0,0 +1 @@ +Versions/Current/Info.plist \ No newline at end of file diff --git a/test/fixtures/test-app-symlink-framework/stripped-native-dep/lib/Release/Hello.framework/Modules b/test/fixtures/test-app-symlink-framework/stripped-native-dep/lib/Release/Hello.framework/Modules new file mode 120000 index 00000000000..5736f3186e7 --- /dev/null +++ b/test/fixtures/test-app-symlink-framework/stripped-native-dep/lib/Release/Hello.framework/Modules @@ -0,0 +1 @@ +Versions/Current/Modules \ No newline at end of file diff --git a/test/fixtures/test-app-symlink-framework/stripped-native-dep/lib/Release/Hello.framework/Resources b/test/fixtures/test-app-symlink-framework/stripped-native-dep/lib/Release/Hello.framework/Resources new file mode 120000 index 00000000000..953ee36f3bb --- /dev/null +++ b/test/fixtures/test-app-symlink-framework/stripped-native-dep/lib/Release/Hello.framework/Resources @@ -0,0 +1 @@ +Versions/Current/Resources \ No newline at end of file diff --git a/test/fixtures/test-app-symlink-framework/stripped-native-dep/lib/Release/Hello.framework/Versions/A/Headers/HelloFramework.h b/test/fixtures/test-app-symlink-framework/stripped-native-dep/lib/Release/Hello.framework/Versions/A/Headers/HelloFramework.h new file mode 100755 index 00000000000..1af71a0b025 --- /dev/null +++ b/test/fixtures/test-app-symlink-framework/stripped-native-dep/lib/Release/Hello.framework/Versions/A/Headers/HelloFramework.h @@ -0,0 +1,2 @@ +#import +void hello(void); diff --git a/test/fixtures/test-app-symlink-framework/stripped-native-dep/lib/Release/Hello.framework/Versions/A/Hello b/test/fixtures/test-app-symlink-framework/stripped-native-dep/lib/Release/Hello.framework/Versions/A/Hello new file mode 100755 index 0000000000000000000000000000000000000000..02ae196e4913053a03804ed1e3c8e80e28859c5e GIT binary patch literal 16120 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 literal 0 HcmV?d00001 diff --git a/test/fixtures/test-app-symlink-framework/stripped-native-dep/lib/Release/Hello.framework/Versions/A/Info.plist b/test/fixtures/test-app-symlink-framework/stripped-native-dep/lib/Release/Hello.framework/Versions/A/Info.plist new file mode 100755 index 00000000000..59375bf54f6 --- /dev/null +++ b/test/fixtures/test-app-symlink-framework/stripped-native-dep/lib/Release/Hello.framework/Versions/A/Info.plist @@ -0,0 +1,24 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + Hello + CFBundleIdentifier + com.example.Hello + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + Hello + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + NSHumanReadableCopyright + Copyright © 2024 Hello Company. All rights reserved. + + diff --git a/test/fixtures/test-app-symlink-framework/stripped-native-dep/lib/Release/Hello.framework/Versions/A/Modules/Hello.abi.json b/test/fixtures/test-app-symlink-framework/stripped-native-dep/lib/Release/Hello.framework/Versions/A/Modules/Hello.abi.json new file mode 100755 index 00000000000..54700d0a8a8 --- /dev/null +++ b/test/fixtures/test-app-symlink-framework/stripped-native-dep/lib/Release/Hello.framework/Versions/A/Modules/Hello.abi.json @@ -0,0 +1,82 @@ +{ + "ABIRoot": { + "kind": "Root", + "name": "Hello", + "printedName": "Hello", + "children": [ + { + "kind": "TypeDecl", + "name": "Greeter", + "printedName": "Greeter", + "children": [ + { + "kind": "Constructor", + "name": "init", + "printedName": "init()", + "children": [ + { + "kind": "TypeNominal", + "name": "Greeter", + "printedName": "Hello.Greeter", + "usr": "s:5Hello7GreeterC" + } + ], + "declKind": "Constructor", + "usr": "s:5Hello7GreeterCACycfc", + "mangledName": "$s5Hello7GreeterCACycfc", + "moduleName": "Hello", + "declAttributes": [ + "AccessControl" + ], + "init_kind": "Designated" + }, + { + "kind": "Function", + "name": "hello", + "printedName": "hello()", + "children": [ + { + "kind": "TypeNominal", + "name": "Void", + "printedName": "()" + } + ], + "declKind": "Func", + "usr": "s:5Hello7GreeterC5helloyyF", + "mangledName": "$s5Hello7GreeterC5helloyyF", + "moduleName": "Hello", + "declAttributes": [ + "AccessControl" + ], + "funcSelfKind": "NonMutating" + } + ], + "declKind": "Class", + "usr": "s:5Hello7GreeterC", + "mangledName": "$s5Hello7GreeterC", + "moduleName": "Hello", + "declAttributes": [ + "AccessControl" + ], + "conformances": [ + { + "kind": "Conformance", + "name": "Copyable", + "printedName": "Copyable", + "usr": "s:s8CopyableP", + "mangledName": "$ss8CopyableP" + }, + { + "kind": "Conformance", + "name": "Escapable", + "printedName": "Escapable", + "usr": "s:s9EscapableP", + "mangledName": "$ss9EscapableP" + } + ] + } + ], + "json_format_version": 8 + }, + "ConstValues": [] +} \ No newline at end of file diff --git a/test/fixtures/test-app-symlink-framework/stripped-native-dep/lib/Release/Hello.framework/Versions/A/Modules/Hello.swiftdoc b/test/fixtures/test-app-symlink-framework/stripped-native-dep/lib/Release/Hello.framework/Versions/A/Modules/Hello.swiftdoc new file mode 100755 index 0000000000000000000000000000000000000000..5b333ebebe2736714b0569b511e36a301c387e87 GIT binary patch literal 408 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 G&;J8+5N|{P literal 0 HcmV?d00001 diff --git a/test/fixtures/test-app-symlink-framework/stripped-native-dep/lib/Release/Hello.framework/Versions/A/Modules/Hello.swiftmodule/x86_64.private.swiftinterface b/test/fixtures/test-app-symlink-framework/stripped-native-dep/lib/Release/Hello.framework/Versions/A/Modules/Hello.swiftmodule/x86_64.private.swiftinterface new file mode 100755 index 00000000000..3b82bc74568 --- /dev/null +++ b/test/fixtures/test-app-symlink-framework/stripped-native-dep/lib/Release/Hello.framework/Versions/A/Modules/Hello.swiftmodule/x86_64.private.swiftinterface @@ -0,0 +1,12 @@ +// swift-interface-format-version: 1.0 +// swift-compiler-version: Apple Swift version 6.0.2 effective-5.10 (swiftlang-6.0.2.1.2 clang-1600.0.26.4) +// swift-module-flags: -target x86_64-apple-macosx10.9.0 -enable-objc-interop -enable-library-evolution -module-name Hello +import Swift +import _Concurrency +import _StringProcessing +import _SwiftConcurrencyShims +public class Greeter { + public init() + public func hello() + @objc deinit +} diff --git a/test/fixtures/test-app-symlink-framework/stripped-native-dep/lib/Release/Hello.framework/Versions/A/Modules/Hello.swiftmodule/x86_64.swiftinterface b/test/fixtures/test-app-symlink-framework/stripped-native-dep/lib/Release/Hello.framework/Versions/A/Modules/Hello.swiftmodule/x86_64.swiftinterface new file mode 100755 index 00000000000..3b82bc74568 --- /dev/null +++ b/test/fixtures/test-app-symlink-framework/stripped-native-dep/lib/Release/Hello.framework/Versions/A/Modules/Hello.swiftmodule/x86_64.swiftinterface @@ -0,0 +1,12 @@ +// swift-interface-format-version: 1.0 +// swift-compiler-version: Apple Swift version 6.0.2 effective-5.10 (swiftlang-6.0.2.1.2 clang-1600.0.26.4) +// swift-module-flags: -target x86_64-apple-macosx10.9.0 -enable-objc-interop -enable-library-evolution -module-name Hello +import Swift +import _Concurrency +import _StringProcessing +import _SwiftConcurrencyShims +public class Greeter { + public init() + public func hello() + @objc deinit +} diff --git a/test/fixtures/test-app-symlink-framework/stripped-native-dep/lib/Release/Hello.framework/Versions/A/Modules/Hello.swiftmodule/x86_64.swiftmodule b/test/fixtures/test-app-symlink-framework/stripped-native-dep/lib/Release/Hello.framework/Versions/A/Modules/Hello.swiftmodule/x86_64.swiftmodule new file mode 100755 index 0000000000000000000000000000000000000000..7e6a7ed96c57b7fa84a4bbc91e7bfc3790646745 GIT binary patch literal 17944 zcmb_@4R{mhmF{RHYRHy$Aw)7j2b<|O#T|f6l;#gdgHc;R2h{lBLQkYH1|nmfRAhlaSW7-t%2rC%{_5X z*&u7_iO-Hn<|J!%@oZIV-0Zs9V@01q$r_Fa8#?3mkvQ%&?qC#?4f{tIIi7H z*VxK-`7%Vd$F)Dkm3GJr*gFH2A-XoZQ?kY4wgI*hGTQ^T5G*EHB602Z0m*_fAP{F; zVM>UBWV**P9QRCjbUO?ucy(eYlH6gDJ063*3_pu-y?&bH;UpK0(1ees3|)fZXo@?E zTf7|Ryazo+&gA{g=xwk~ciJANA3sOt+neGJIk@Av6*oD!pW}?5>vC{E^>UplzNpL^ zqRE?w*s2l9+6T=7c32TDCeg{-I@!wMv2(gU3JlgBf`ujXE&_=yB*8ktamO>bkt{>3 zy+2@2#%I$YY7ft(ldSDr+|n7a!5r<9c_41?h|kWr&b9s?bCi5ni96uR5wfgK34=#RPvJ6Pp5UvHP$R%_Q6SCkq%MI=hyS;mei+T+J3#@h+vrjSOx?x(F zQ#8PeS+-B=0jxtnXpHL?xTC;r#9&HBxPy%0uwdvVvl$L}0d)@kFimYMe1TjCaKh%I z;aDm;aWo`+To2FfcNk2q)rKxecW?(%hA2<|HYHbb-Ln5Xy-*kT62kXl{7Dkm#Tf7d z7ZfjcMmTtMuSiP$JmtG>bO30NISGb+JhvBt!XPjW2U1?k7tGgij4=R)#V3z?+ayaX zOR*CQ*dp=SNvSFZ{EmiFVq#dTgeMRtedt6kG2^n*&*g*N12!P1Gj2x63G}(& zrOFrusM=*jvP9WRmoscRhuC8)JL9&|+g(qMIV($tmchNfl11hLnt4X_af)>bVGTxr zZS1YAwLLvSRi71uHr&xiQU66fUPlk}DX9_~7M9^P%JK9?m+$+g1@nc1N)%Aokh0mD z28&Ko_*R1W`e8k^GBJUI;4+FORcq}{C&`{>dA1ZnAIOShnxi+XT|E`gvsEC$q&zMh z9!(qAwe&g2uk2$%Yx$lJE_zwE2ZXoAXYWM6IMHjC5}u~*0Xvj{O$Pxb3hK0X#mN@@ zR=O)zSIvCikAWQwMhH^*6uc|R43t)Q`&$89IBtX2;R{d`oT4b9%5c7Giz#r(p3HqO zRbnK}FCr^EC|Sr=$|$PjVDIaa71J*?nc%55sj81GO4G&N(Le@2!MF2GSP*BI6#41Q z1+!FwK0~l>#xhI)4^iQW1ZE^4!JJX4D(zN}wg`E&2PBu``cj78hyf&G@=lTUvVb|G zl1%q$6x>z>-a!IKKIsEZ45?Z8glPCV$R;H`qfr6bj<^E52W-iVBIah?K}4D!=6_73 zOqV9%v`UFpMQYm0bmXV0pdHl*69lfbFBI(uy?Md7+}?C|;xEB~D&hpl(1FQ$yWQr& zxE&COvw%uCS(V4CVvZFZ6Orx=AjkAg{E?Gp*a`+6kSak2Fzblg-ScMAtDxbO0o1w| zRmaoQ(`+z1BJ-ikyursE2M=eul-`VN6_V`dMmZwgw`n8v6)8;|9ij>ec?V2=s3oKR z(16B15Qiact#KR7rH-*;Gp6U`cB5>9)-8r^(EvjnL#`LqipRu%9a(e`_rZzC(+In? zAHP)`6%3$v7z+7)HwvZ{vIbRSl-g8pdf&ysl4Yl49g?#xrT8(12tHhldCG*zmSU! z2T{%-)1f$&OE}f`rWu1$WjJncMI^FRH>h%5{|gAkY(^2PNM~+n;B%^}&c(-Svf^b!(qKrGpb9>Quw4+@{1Z5u_Bw_o2y)Pb| z052P&n1qtPp`KtkloHOcnao56PQpqcUNspVQwm~uB?~5|@t__XXfRv)J!)K`+Mwb< zl^%O1Kr}T1_@za=oWqa>Pr;UQFO)BEqUqbUJBb=Wq@*}h2I}A`pso+p5wI!j>S})9 z$DxGiig5b@SokhtfVq_NMo9KAs)~P_DwU`w=ae495KOJ8yO&7GrTdzF6J?++^K0sdh(*g?m#Suj{^i_}NNm zx`erBY0i6~2j;x!8|rEA{5I|oA_#s`UI+;E7>x7>RVj{s`;BxF_T|GQrVQy+W*bfF z0J;o!a8tUr$f3K$vlCD(VB-7Jg^Foa#{~Ec#(Gr-0Lb%%Qa7X#sbIUig`UO%E}2)O zA2lF9$O$N5iK38=drnV~d4vO)sS7ZbGJt6II1GRlQjP*H(|5l~US^SuD~UxV6i}!; zDSLw15g7`koaN3(j8{a%4aSr=yyNO3%aGR9A9N)>wULBcI3Qaf zT@S>A|8Y}i#B_x>ejG7gOmdf!#tUBKwHWtF%J`wzl**gSjqSEUfLQAq_AKa2l%-2MEH5dHum_9M07v^?Z>n%34U3pz~a!c9*AiAZR%k ztZUWQcP8rk^5oq=4XnJIF{NV0%MRmtWp+u~=()1RqW#MZR~)AEKI5e!m{E4EXgJ>@ zYr+^lAxD`m38r-AC>O$wVCvB3k=EqArH%YwL$S);`aIWWtq;&&H$Y zxle|ShXvz*Ix@w2TI;vh@01n{ktAElb7#M&K5uC4qUrGFN0@eDS9;$%ZHES}o&_Oo zU1#vlJVXT7OjpJ}=rw*U7-70kbB#XqyVK@=4<@nza2QY~l98v)Luu3bZQOZ>>6mEx zL@>cKc`@T}d(s|C)JNiVtqBs`>#6P2*5?`K{bk(ya5GSv?~}J5?GHE)B+TJ}t5Zt| z%L_g2leYk+Ukz1!(Pf1s0I4Bk4{!W)1jUB&Jn-0IQt_B)laYm{)Dq%TbDbVr60NtmmH=q2srV`U1orDSMUpL(R8Jh`%Exg5=|cnrcYY(UF0qL zq}uR##Q45wI>Zx>|L9dAb<}G@L|g`Q3gneMXD~%qHyX|hrYl~<72b56CoH`mF$yDA42h6-8` zBfS6>!LtBi{r!y22$V2F#bE{Fu!F;NJ!bqYSE~Qr*DO6KY7#C&ytck@LTLKDjr*7} zeFV6Bi7fKq-f{jlTR6A?brLu$=~+PVl$>aDeY(rNb&#zO5vw`L7C7)A1ugi%Q>&n} zSE@~VoDq)`ZSKwCZCeMV+CgZktp|3L8(QOaeZg8JlU|RruYg58ugy?`wL579TY|MN zfwg3Z1Gu@IchBSfEYcDtKq}=buxs1ntt^se-7b%{H=V%-61kvGN_WDVxi>fc*G9u7 z-uPjRyF7$cmY)RpZDDdO#?9k<&(u)Zf;omg3nB@7d(f4(8l^ngWG9gfZp#N$a8~&N z-uP*RyAmOcBR*dRUcLFC_B|7}^#|+v1N9I;fN}C?u%$xcZVVYwQXuCb*kR7|jz+kY=*{|(0hfbW^H*?FkSW$Ra}Y?xIlb)=uExbXpSc8!Q+D-3tW;U%!4f`@Czjs z&y(c^y?mJHJ}*fv+tDi315KdQTwkrTvW9CZV+xgrXu8p2xW*e($o}~`@^?ET(t<(6 za5yq0F!34SwCi3Yos@O> zEPpCLe!34~;IYI&t)4n4fXtOUr{>ubciCrrA9Ip}_;TUw7cFuGi1iKmI3Pm+6AKdmS_5r>=LzLNf;#RxidncLIq6(NXjj$ zJonz(32l%FWOjhYxvu%iGlTTv!`w=N<{CsM2HORZ!Samly+b0p4p%Mq-yptbpD_onnk5a}9u#;TCB0_Q%`tFYgSywx#G)(-eh^#zwdsmgo$&{GHbj6W(tIs#)Ae-?sFZU-e z{EfIaUdyG2p_lI_3Pm8J&PsyQv~@cZ=8zWTTMsJB1@9y4vJgf7hDaG#K;)mqJi9c# z)Gj%xi1vWf>hrQ};)&@!xDTZ(Yzsd2A$QC9J|Bs1zXV5psW9!-=-moAnFoPYPaPg2 zhJ%%ziVuP)a*;7yJ^5wqiXU8{$oMjsy!aE0-YM0^km=!NZ9TGG%yVb1bs9H75+0Ep z#t-vnaMLcx2(fkGq*fVf0Bx>-=8fPx_$md&8m|i`VhD%vMy}IRuissXrz9XY^X#}2 z1sok;Jtv*dofCiQZuw~xuFF%u z_jX!vO>tLZ`L^(1EwP|(Jx6qll80irfMJ`q!ZTkse5!Q`%DVhoJlJ3bFuvfiReW&= zJq<)9=WwD9kDR&gY}mh?LsWo&^PhNk@1Qi_9(Mr@vBFQhi7A~+D#0P4U~PLauQw2# zaGlfUKhkNNZ`v23ERk2cI?it&eb&o+>`1iVbeJ(I431Qn%WyQxe^b2gY=Ck3_p{pFy(=`Dh zRp43isk^>HhPv+}9^pk3`12aF3xdRvU)Cp|e-gzeKtPZ1(4#+IkK8$saCLYV#B!&W zICslYukkZKxZe1AJ`GKH3?7NdPy2Yz$VIGpXBk&GwJhI>`W8h%VSbrK)?yGtyfVr1#gpc8&Ui57}GlX%&Xr~jN0I%s|#6?RUvYQTs<8=e59})$zqP@+EH%1px_6deh zpi}PDhMxbW^43Jobn=4{$_W@(&i#2gTwG8_ufYmb5&!xMJyv<@quP3uBzSb`)7B0q zY<+50&V51mGwU%0ybfbFyI(5IlfI%JnT${kVRT|<`H`NUB7Gd7@^R)JUp{7UfOw51K^}KI|`=P^Si1gBf>1B{lzL_~aEmtR={cR~Ec=4UKNx z(N63v+{2xew?^T;HCBAnTceUXW#_<&6t~ZZH7>3fFW#TQ8)FB(iazY)_F=Vywlz7v z){V1R0m7SQtnpzbEBg-KO>4+_<=^F_wO*A?A!^B0E{YfBcyWx?1N?p(OCI9r;_fkQ zOMA_Xci~u=#YP8gJP2bA702q*i)9$AQCP>}D{kvGrizPuvs2+j~qM^Ojc$ZFqs- z5w}I+cGui9ws3%UWze1r*4ocv#Wyj<{NH|84^0P`(>feBgkja{FjnKR&M-Ye`^m7D zm&q3L+k0gdFxyxi_1Q~qV^_?w`^DVZ{b1c!BiNn59ZIjYW!XQnCVyQ3JK1)_>e-HX zZayu_A8LV$%EpfD;rMx2$J{F~GN@ix9F5t2NB8ARbJ=1dcSo@<8ZEFaG)9%*%*|N_ z%9bH4!vYgPhD{5YHdd5Qw9w3tGk}_KFIIE0!iQ^_S-^u>gTb|LD@T~Rx=@tf1Bq+j zQLp)EsR))miuFd>bH`Htm00-3<)iZA7Ql$T0X^7_>Lr+`h4V%KNGo>$71sJ9SaGIB z&@oGCfSj_7jio(#`<$Dv^yO>RtL)gsj*iT}*>5PO#wwqeJ19^99c$s8hBNYlX8;R2 zHms((=AKl3XYW|kR$x^Y3qD~)iA2~=?->ftS1w=y4%>sULK&6ReL}QbNC^=vLdHFw z?0(83mrMMGJQA%YSu#uSSYmQDpU%3V?mD5pM`LAbAI_IK5~#%DD>lktyXKPxF2`-} z$;-NfthJLxh-Z3xI+fnZICisTYi@TrecOq;=LnQz_5powZ~X& zs?ffr$mtBw?w^qW7$aL+;(~Jd9Y}-4u~gachAbz51vIm~;g`0OVg+kB9@HxPvvz@Y z0<@+K^A5y4la#Xpmtk09waj46zsb7>##5;)GjL*& zGQ@jW*dwE37m(t43x?}su?Sw}TK`tQBz2$E*o9v0+I(T^#vVZy2?j_7_Sgyj8)*6xy&TSw8@t)ulksTgv57z`l#-iw#kT+DcdyaZC%9 z>y;gLc|ky)B~zQzlC)F(N@OZszc4Ij)0T?>cG9IsXj$oySx_|mEX9Eym1KBGr0v?Y zc?7G&*!Y1>WLPg-DX3fez+Rv~B$;mHUzxLzeX!wxc7dl1`@FPk2YDEqj!o}Q83TFN z258FrtjFwJbaiUf9eZkMU@2L)2DVfHQ!t!@{xQ29(>8#`Tp@SP{e{QL*p2RqY#VzI zMXMPDDmz0Ipeoxfl&wnVfJaLH+J{v$V4E}e8MEv`5(a&O%7M_7xLa{WI{G`ni?keG z)f=Flu&xykC?=PUeMsI2v=_+=Ob_Pu%8C5>X^PdEiAhVYr8)ya!UCtKZQ_@*>u%_t`(JlX{0lRD6FZ0+d(8N2^QMZ1h)p% zZ9eLDkAPXN8Y*ibXK#}kX`4k8C2m$Lr|&O(@+_mm1ql_4&&qAQUIE>rlb!kL-) z|3we#80I#fVeVuYrkp!)K*I)OVwnGhSnVA@F}TCoQC@Z+JkGjj+m1&BcZ05rMZd;1 z>(_6<-*HUKe6NTD<#Uk!%&&4()tKj1RXZ%R-7PKa*9iCg(*tX_2>)}JIJmQ@H zz4>!1SCaTj^`fJyw#tFNJJULlNF09~U%4axS_M6$#ouycqflNRK7d2{W5N7q;b?i$ zKtymaYVyt;SJCLT6j$)$b-^8t9n!SMNXMpI=$Eb})YPDxRP8RA$T0HEaG$PRJ^toH z8y;G7&%-S(8#ZmB^HUh+d!7vst$ujZrZo?(ew6xs@18B29(d?}@1_l_*KFR5BkE_T z^JI~%&iAZ);0K#=5uaMfp?L)+YD10uOiy5ZX?b%vA_OD4lBNTEo8S)UO3Eq*OxJ=V z!b19U#uPXEt_53+`m&igQ9fL}yMnK1*vik`IW7>APn;a#EAGOHh57^Agwkt4{S9|$ zMCcF#4QHr7&U7r+KRcsA?tJ6qaPdhOU$HRkxZ!q|>Yj?sXxKR->?#SMXW7yYe)%}J za?^+)ZROwO-J4_)@~>Zyb7vHb)(l`sMN`icXH0>2ghq!!SJFlUNv{Zv&_UV?=>sPA zf6rWqN#aYtXikA&&2$Hp8EPk48!8&1jJa;OSSqW~@7K?iLKV=d{Z{$Ut_o#JI&}Fv zSr^^zxotDhIixFFw3Y6>N5?61w$d!*?pyifB>5bTI$XSR3&z&J535RnGbZ-Ya5_yz^qrVvCJRYH%!I& zMFJ;l-!K*7uOf`j&=JYGjs4vQX2|QrAye7RFf(w0JYYD3*Z{*4r{Hj##JsBnh5szwsN2bx$;e@*&Rht*i0wGnJ^^kb4W0*j z%OUfI8_t2w!aqZWQ*c{MPtIq*-vJV%E&AtW@n zl9%=T92}NEIU@Kb5(qUHF(v4C_tLGr_yXZr?3*fx0I06@Ma|;H{vG8D^%Ds?Pt_ zo*Vvd<=v;CO!XGhX&d2DmQkT^o6$UAvWid6X1D7~$`w1yV3lFdPMV6pkcUY#Pl^Tl zlmPEj6*G(6t=^2^Ybx~OY8_Wn){t~;lVa9eF-uYl(}E5Bjrh$!Nakt9v=&c?>b&Fk zF#C3<3|wW#l@ERd!-XSa9LF1eh+}2qz?W)_6<<#qXGSwWa}|90@LgoAu&(5qcG7b* zbnivv-vM1|O*4!EuVOM&YZ|<5Gs5J>j}>FU-m-C*%-ALo9{kfQFxHHU0aML^Bq?l~ zwNO9h3~bCxB~$he7hBl|3vlARjd0RnD`gj3fmY_o5}@cGiVpZo-+;=i{}mJaWj*Xe zsF-rSwbg%w&UgLWi1-Wqz5m7WC1qi<7xSB?TLmc;)@i!#_v=b#xy5&9Ekxe(>V@A8 z7f-YL9-ClZr{~Y>IL)OOAq;j9PmL#huaj{T&}mk`BoFe|aPds`^gL^mu6_MAWUzAG zfoC)zD))A7Qb`#mAbht7DmT7HQA)V|5w4C1{^93nA)jIATe`l5UAn+ zhQ2VPL{skb!))Ve>~H|L`Zqen05_#Xi^;Xs#Aw!Q{6MdN0Qc*ib=nH=Zm9wKUA*5< zZvHJ(V)Z?FTq6U)&C1N)A#I1lN*2T`Xf^k(uJ?! zT2u=ZE<6qytJIX8{I(mFI7>8OpGBh;Lw z<|;L%-$GN3#=j8_$Nyh#gI;`aoQfkWd+HydYQueK2GEo>`TK0}(HS&bF(dy6IPg2| zf;-lTX57xxEc_7&M0A?>k07)fPzjcPn?|7K?0g!KkW@`g8v$k+u)=Jlrj42-@)2o# zgqpL|T&1Se1r@z6QFPuS2zC=Myh`qkQ}fRpnkUdWp5-W1n2)0-DEW5(J+(H zxb>3=2g1|i^hIE-@JlS<^-F4gMa>{JuT%4DYTiH-I?J*R4`@mj%4Gp1U-i@B_u{A# z-&0d5V^fZ%eBFkxpAH;K4#!dYGhRnU@~yGf^a=Sd)e!2(AH#uPU!q9xmv(4*Rxhd- zGk-idN}n8$Jr8>R1b=HfcaDhh*w=XGPX;{`Dbg{M zb*z7nPUC+l!1$$Q-x8Qd=JU+(bUouY>X=vbEb}H)?Y~9jJH~q_u7zzzaOzp+8~)Q& z5Dwsb3g1omE`(vq@tuH~KQS@je!7L}ATKf+=GY4x9@0~(r)pfQo>%-$_I}vOB&jcb zG|Y>RXHmnUzdWjIRG(Wybh$iT_&L%L?`U8oPuH@goFRPzt~_T7IU<(O zFcRta|KoXF55T0K|Ka*H*ciPD_#Ycs%(x_8kX2eN~yYO4q+F6E7aVs>}sn KQ6}6cfBqkxB5?!& literal 0 HcmV?d00001 diff --git a/test/fixtures/test-app-symlink-framework/stripped-native-dep/lib/Release/Hello.framework/Versions/A/Modules/Hello.swiftsourceinfo b/test/fixtures/test-app-symlink-framework/stripped-native-dep/lib/Release/Hello.framework/Versions/A/Modules/Hello.swiftsourceinfo new file mode 100755 index 0000000000000000000000000000000000000000..97c726d55b0a20e080cc98550d0261ec3f10f2eb GIT binary patch literal 1064 zcmaJ<%Wo245MLHrnx!^K8a2iPp*7iM-wQ0D9PGAHk0jQc2e-?&LWM$L)7qO74jvli zz)cfh^<=fR>5;_dGn$%U(k4y+0}~G(_yagN-%>~$8z-5a$8R3r>`eF7^Jkthipo$F z<@e-;dmp>ZdN#0;WxgnZ&1_&>Vcs{HPxqP4Zs6@Mv#Bs2D#7W%Pqtm>_v=EN=6iK^ z3-fC@nwg&ATeR4qxdwc(cWMXoO+(x=xL%!a7<>zVRrd{c4|5Q8#rNiOw`p)|P=My! znC)QssjF<@+4&CU59`7j$>i2)$dtE?XonUvH=eK!EUaU;M{_Lz z>HYRP>kEIEBW+1~d0E*1ObsK{vk08U~^=RorSPYgYMB?ZC{Ot6#j1SQxa@F+0BPZGff z6aj_I0V_B~B<6ou6mXI^c`B>lci}!42k4vOmKX$ zLZt>Xc_=R0@sJL+YYBIW$y-%~98{epc{CLgR=A62!85a~mTi$b%%7uom(L1G + assertPack("test-app-symlink-framework", + { + targets: Platform.LINUX.createTarget(DIR_TARGET), + }, + { + isInstallDepsBefore: true, + projectDirCreated: projectDir => { + return fs.symlink(path.join(projectDir, "index.js"), path.join(projectDir, "foo.js")) + }, + packed: async context => { + expect((await readAsar(path.join(context.getResources(Platform.LINUX), "app.asar"))).getFile("foo.js", false)).toMatchSnapshot() + }, + } + ) +) + test.ifNotWindows( "outside link", appThrows( From 1d7b57643320d88808faa1db9212f92e7c98069d Mon Sep 17 00:00:00 2001 From: Mike Maietta Date: Sun, 3 Nov 2024 21:15:00 -0800 Subject: [PATCH 03/19] tmp save --- packages/app-builder-lib/src/asar/asarUtil.ts | 16 +- test/snapshots/globTest.js.snap | 280 ++++++++++++++++++ test/src/globTest.ts | 10 +- 3 files changed, 301 insertions(+), 5 deletions(-) diff --git a/packages/app-builder-lib/src/asar/asarUtil.ts b/packages/app-builder-lib/src/asar/asarUtil.ts index 73f0f0af6b1..3934f2c7c98 100644 --- a/packages/app-builder-lib/src/asar/asarUtil.ts +++ b/packages/app-builder-lib/src/asar/asarUtil.ts @@ -171,12 +171,24 @@ export class AsarPackager { } else if (stat.isFile()) { return this.fileCopier.copy(file, destFile, stat) } else { - links.push({ file: destFile, link: await readlink(file) }) + let link = await readlink(file) + if (path.isAbsolute(link)) { + link = path.relative(path.dirname(file), link) + } + links.push({ file: destFile, link }) return } }, CONCURRENCY - ).then(() => BluebirdPromise.map(links, it => symlink(it.link, it.file, symlinkType), CONCURRENCY)) + ).then(() => + BluebirdPromise.map( + links, + it => { + return symlink(it.link, it.file, symlinkType) + }, + CONCURRENCY + ) + ) // for (let i = 0; i < fileSet.files.length; i++) { // const file = fileSet.files[i] // const transformedData = fileSet.transformedFiles?.get(i) diff --git a/test/snapshots/globTest.js.snap b/test/snapshots/globTest.js.snap index 345f1321e95..68e542e81c3 100644 --- a/test/snapshots/globTest.js.snap +++ b/test/snapshots/globTest.js.snap @@ -9792,6 +9792,44 @@ exports[`link 2`] = ` } `; +exports[`link 3`] = ` +{ + "files": { + "app": { + "files": { + "package.json": { + "files": { + "readme.md": { + "offset": "841", + "size": 32, + }, + }, + }, + "readme.md": { + "offset": "5313", + "size": 78, + }, + }, + }, + "foo.js": { + "link": "index.js", + }, + "index.html": { + "offset": "0", + "size": 841, + }, + "index.js": { + "offset": "873", + "size": 4184, + }, + "package.json": { + "offset": "5057", + "size": 256, + }, + }, +} +`; + exports[`local node module with file protocol 1`] = ` { "linux": [], @@ -9800,6 +9838,248 @@ exports[`local node module with file protocol 1`] = ` exports[`outside link 1`] = `"Cannot copy file (foo) symlinked to file (foo) outside the package as that violates asar security integrity"`; +exports[`symlinks everywhere w/ static framework 1`] = ` +{ + "linux": [], +} +`; + +exports[`symlinks everywhere w/ static framework 2`] = ` +{ + "link": "index.js", +} +`; + +exports[`symlinks everywhere w/ static framework 3`] = ` +{ + "files": { + "foo.js": { + "link": "index.js", + }, + "main.js": { + "offset": "14803919", + "size": 27, + }, + "node_modules": { + "files": { + "stripped-native-dep": { + "files": { + "lib": { + "files": { + "Release": { + "files": { + "QtCore.framework": { + "files": { + "QtCore": { + "link": "node_modules/stripped-native-dep/lib/Release/QtCore.framework/Versions/Current/QtCore", + }, + "Resources": { + "link": "node_modules/stripped-native-dep/lib/Release/QtCore.framework/Versions/Current/Resources", + }, + "Versions": { + "files": { + "A": { + "files": { + "QtCore": { + "executable": true, + "offset": "351", + "size": 11404008, + }, + "Resources": { + "files": { + "Info.plist": { + "offset": "11883575", + "size": 764, + }, + "QtCore.prl": { + "offset": "0", + "size": 222, + }, + }, + }, + }, + }, + "Current": { + "link": "node_modules/stripped-native-dep/lib/Release/QtCore.framework/Versions/A", + }, + }, + }, + }, + }, + "QtNetwork.framework": { + "files": { + "QtNetwork": { + "link": "node_modules/stripped-native-dep/lib/Release/QtNetwork.framework/Versions/Current/QtNetwork", + }, + "Resources": { + "link": "node_modules/stripped-native-dep/lib/Release/QtNetwork.framework/Versions/Current/Resources", + }, + "Versions": { + "files": { + "A": { + "files": { + "QtNetwork": { + "executable": true, + "offset": "11884644", + "size": 2918168, + }, + "Resources": { + "files": { + "Info.plist": { + "offset": "14802812", + "size": 770, + }, + "QtNetwork.prl": { + "offset": "11884339", + "size": 305, + }, + }, + }, + }, + }, + "Current": { + "link": "node_modules/stripped-native-dep/lib/Release/QtNetwork.framework/Versions/A", + }, + }, + }, + }, + }, + "qt-plugins": { + "files": { + "tls": { + "files": { + "libqsecuretransportbackend.dylib": { + "offset": "11404359", + "size": 479216, + }, + }, + }, + }, + }, + }, + }, + }, + }, + "package.json": { + "offset": "222", + "size": 129, + }, + }, + }, + }, + }, + "package.json": { + "offset": "14803582", + "size": 337, + }, + "stripped-native-dep": { + "files": { + "lib": { + "files": { + "Release": { + "files": { + "QtCore.framework": { + "files": { + "QtCore": { + "link": "stripped-native-dep/lib/Release/QtCore.framework/Versions/Current/QtCore", + }, + "Resources": { + "link": "stripped-native-dep/lib/Release/QtCore.framework/Versions/Current/Resources", + }, + "Versions": { + "files": { + "A": { + "files": { + "QtCore": { + "executable": true, + "offset": "14804075", + "size": 11404008, + }, + "Resources": { + "files": { + "Info.plist": { + "offset": "29606764", + "size": 764, + }, + "QtCore.prl": { + "offset": "29606542", + "size": 222, + }, + }, + }, + }, + }, + "Current": { + "link": "stripped-native-dep/lib/Release/QtCore.framework/Versions/A", + }, + }, + }, + }, + }, + "QtNetwork.framework": { + "files": { + "QtNetwork": { + "link": "stripped-native-dep/lib/Release/QtNetwork.framework/Versions/Current/QtNetwork", + }, + "Resources": { + "link": "stripped-native-dep/lib/Release/QtNetwork.framework/Versions/Current/Resources", + }, + "Versions": { + "files": { + "A": { + "files": { + "QtNetwork": { + "executable": true, + "offset": "26687299", + "size": 2918168, + }, + "Resources": { + "files": { + "Info.plist": { + "offset": "29605467", + "size": 770, + }, + "QtNetwork.prl": { + "offset": "29606237", + "size": 305, + }, + }, + }, + }, + }, + "Current": { + "link": "stripped-native-dep/lib/Release/QtNetwork.framework/Versions/A", + }, + }, + }, + }, + }, + "qt-plugins": { + "files": { + "tls": { + "files": { + "libqsecuretransportbackend.dylib": { + "offset": "26208083", + "size": 479216, + }, + }, + }, + }, + }, + }, + }, + }, + }, + "package.json": { + "offset": "14803946", + "size": 129, + }, + }, + }, + }, +} +`; + exports[`unpackDir 1`] = ` { "linux": [], diff --git a/test/src/globTest.ts b/test/src/globTest.ts index 66d6a81810e..3c8254756c1 100644 --- a/test/src/globTest.ts +++ b/test/src/globTest.ts @@ -85,7 +85,7 @@ test.ifDevOrLinuxCi("asarUnpack and files ignore", () => { const resourceDir = context.getResources(Platform.LINUX) await Promise.all([assertThat(path.join(resourceDir, "app.asar.unpacked", "node_modules/ffprobe-static/bin/darwin/x64/ffprobe")).doesNotExist()]) - await verifyAsarFileTree(context.getResources(Platform.LINUX)) + await verifyAsarFileTree(resourceDir) }, } ) @@ -102,7 +102,9 @@ test.ifNotWindows( return fs.symlink(path.join(projectDir, "index.js"), path.join(projectDir, "foo.js")) }, packed: async context => { - expect((await readAsar(path.join(context.getResources(Platform.LINUX), "app.asar"))).getFile("foo.js", false)).toMatchSnapshot() + const resources = context.getResources(Platform.LINUX) + expect((await readAsar(path.join(resources, "app.asar"))).getFile("foo.js", false)).toMatchSnapshot() + await verifyAsarFileTree(resources) }, } ) @@ -120,7 +122,9 @@ test.only( return fs.symlink(path.join(projectDir, "index.js"), path.join(projectDir, "foo.js")) }, packed: async context => { - expect((await readAsar(path.join(context.getResources(Platform.LINUX), "app.asar"))).getFile("foo.js", false)).toMatchSnapshot() + const resources = context.getResources(Platform.LINUX) + expect((await readAsar(path.join(resources, "app.asar"))).getFile("foo.js", false)).toMatchSnapshot() + await verifyAsarFileTree(resources) }, } ) From 1c9ea9eb1c9d93973a6cbb2b6e878ab794266a24 Mon Sep 17 00:00:00 2001 From: Mike Maietta Date: Sun, 3 Nov 2024 21:26:53 -0800 Subject: [PATCH 04/19] update offsets --- packages/app-builder-lib/src/asar/asarUtil.ts | 160 +++++++++++------- test/snapshots/globTest.js.snap | 10 +- test/src/globTest.ts | 5 +- 3 files changed, 105 insertions(+), 70 deletions(-) diff --git a/packages/app-builder-lib/src/asar/asarUtil.ts b/packages/app-builder-lib/src/asar/asarUtil.ts index 3934f2c7c98..f3be43237ce 100644 --- a/packages/app-builder-lib/src/asar/asarUtil.ts +++ b/packages/app-builder-lib/src/asar/asarUtil.ts @@ -137,75 +137,109 @@ export class AsarPackager { copiedFiles.add(symlinkTarget) } + const createdSourceDirs = new Set() + const links: Array = [] + const symlinkType = platform() === "win32" ? "junction" : "file" + for await (const fileSet of fileSets) { if (this.config.options.smartUnpack !== false) { detectUnpackedDirs(fileSet, unpackedPaths, this.config.defaultDestination) } - const createdSourceDirs = new Set() - const links: Array = [] - const symlinkType = platform() === "win32" ? "junction" : "file" - - await BluebirdPromise.map( - fileSet.files, - async (file, i) => { - const transformedData = fileSet.transformedFiles?.get(i) - const stat = fileSet.metadata.get(file)! - const destFile = getDestinationPath(file, fileSet) - - matchUnpacker(file, destFile, stat) - - if (!stat.isFile() && !stat.isSymbolicLink()) { - return - } - const dir = path.dirname(destFile) - if (!createdSourceDirs.has(dir)) { - await mkdir(dir, { recursive: true }) - createdSourceDirs.add(dir) + // await BluebirdPromise.map( + // fileSet.files, + // async (file, i) => { + // const transformedData = fileSet.transformedFiles?.get(i) + // const stat = fileSet.metadata.get(file)! + // const destFile = getDestinationPath(file, fileSet) + + // matchUnpacker(file, destFile, stat) + + // if (!stat.isFile() && !stat.isSymbolicLink()) { + // return + // } + + // const dir = path.dirname(destFile) + // if (!createdSourceDirs.has(dir)) { + // await mkdir(dir, { recursive: true }) + // createdSourceDirs.add(dir) + // } + + // // const destFile = file.replace(file, destination) + // copiedFiles.add(destFile) + // if (transformedData != null) { + // return fs.writeFile(destFile, transformedData, { mode: stat.mode }) + // } else if (stat.isFile()) { + // return this.fileCopier.copy(file, destFile, stat) + // } else { + // let link = await readlink(file) + // if (path.isAbsolute(link)) { + // link = path.relative(path.dirname(file), link) + // } + // links.push({ file: destFile, link }) + // return + // } + // }, + // CONCURRENCY + // ).then(() => + // BluebirdPromise.map( + // links, + // it => { + // return symlink(it.link, it.file, symlinkType) + // }, + // CONCURRENCY + // ) + // ) + for (let i = 0; i < fileSet.files.length; i++) { + const file = fileSet.files[i] + const transformedData = fileSet.transformedFiles?.get(i) + const stat = fileSet.metadata.get(file)! + const destFile = getDestinationPath(file, fileSet) + + matchUnpacker(file, destFile, stat) + + if (!stat.isFile() && !stat.isSymbolicLink()) { + continue + } + + const dir = path.dirname(destFile) + if (!createdSourceDirs.has(dir)) { + await mkdir(dir, { recursive: true }) + createdSourceDirs.add(dir) + } + + // const destFile = file.replace(file, destination) + copiedFiles.add(destFile) + if (transformedData != null) { + await fs.writeFile(destFile, transformedData, { mode: stat.mode }) + } else if (stat.isFile()) { + await this.fileCopier.copy(file, destFile, stat) + } else { + let link = await readlink(file) + if (path.isAbsolute(link)) { + link = path.relative(path.dirname(file), link) } - - // const destFile = file.replace(file, destination) - copiedFiles.add(destFile) - if (transformedData != null) { - return fs.writeFile(destFile, transformedData, { mode: stat.mode }) - } else if (stat.isFile()) { - return this.fileCopier.copy(file, destFile, stat) - } else { - let link = await readlink(file) - if (path.isAbsolute(link)) { - link = path.relative(path.dirname(file), link) - } - links.push({ file: destFile, link }) - return - } - }, - CONCURRENCY - ).then(() => - BluebirdPromise.map( - links, - it => { - return symlink(it.link, it.file, symlinkType) - }, - CONCURRENCY - ) - ) - // for (let i = 0; i < fileSet.files.length; i++) { - // const file = fileSet.files[i] - // const transformedData = fileSet.transformedFiles?.get(i) - // const metadata = fileSet.metadata.get(file)! - - // const relative = path.relative(this.config.defaultDestination, getDestinationPath(file, fileSet)) - // const dest = path.resolve(this.rootForAppFilesWithoutAsar, relative) - - // matchUnpacker(file, dest, metadata) - // // taskManager.addTask( - // await writeFileOrSymlink({ transformedData, file, destination: dest, stat: metadata, fileSet }) - // // ) - - // if (taskManager.tasks.length > MAX_FILE_REQUESTS) { - // await taskManager.awaitTasks() - // } - // } + links.push({ file: destFile, link }) + } + // const file = fileSet.files[i] + // const transformedData = fileSet.transformedFiles?.get(i) + // const metadata = fileSet.metadata.get(file)! + + // const relative = path.relative(this.config.defaultDestination, getDestinationPath(file, fileSet)) + // const dest = path.resolve(this.rootForAppFilesWithoutAsar, relative) + + // matchUnpacker(file, dest, metadata) + // // taskManager.addTask( + // await writeFileOrSymlink({ transformedData, file, destination: dest, stat: metadata, fileSet }) + // // ) + + if (taskManager.tasks.length > MAX_FILE_REQUESTS) { + await taskManager.awaitTasks() + } + } + } + for await (const it of links) { + await symlink(it.link, it.file, symlinkType) } await taskManager.awaitTasks() return { diff --git a/test/snapshots/globTest.js.snap b/test/snapshots/globTest.js.snap index 68e542e81c3..75b55f371df 100644 --- a/test/snapshots/globTest.js.snap +++ b/test/snapshots/globTest.js.snap @@ -9800,13 +9800,13 @@ exports[`link 3`] = ` "package.json": { "files": { "readme.md": { - "offset": "841", + "offset": "0", "size": 32, }, }, }, "readme.md": { - "offset": "5313", + "offset": "32", "size": 78, }, }, @@ -9815,15 +9815,15 @@ exports[`link 3`] = ` "link": "index.js", }, "index.html": { - "offset": "0", + "offset": "110", "size": 841, }, "index.js": { - "offset": "873", + "offset": "951", "size": 4184, }, "package.json": { - "offset": "5057", + "offset": "5135", "size": 256, }, }, diff --git a/test/src/globTest.ts b/test/src/globTest.ts index 3c8254756c1..2cc34c9d414 100644 --- a/test/src/globTest.ts +++ b/test/src/globTest.ts @@ -110,7 +110,7 @@ test.ifNotWindows( ) ) -test.only( +test.ifNotWindows( "symlinks everywhere w/ static framework", () => assertPack("test-app-symlink-framework", { @@ -142,7 +142,8 @@ test.ifNotWindows( await outputFile(path.join(tempDir, "foo"), "data") await fs.symlink(tempDir, path.join(projectDir, "o-dir")) }, - } + }, + error => expect(error.message.includes("violates asar security integrity")).toBe(true) ) ) From 5e3c9a897d9f7128d68bf31cdedeb46353957b64 Mon Sep 17 00:00:00 2001 From: Mike Maietta Date: Sun, 3 Nov 2024 21:33:04 -0800 Subject: [PATCH 05/19] regenerating snapshot with helloworld framework --- .../lib/Release/Hello.framework/Resources | 1 - test/snapshots/globTest.js.snap | 286 ++++++++++-------- 2 files changed, 159 insertions(+), 128 deletions(-) delete mode 120000 test/fixtures/test-app-symlink-framework/stripped-native-dep/lib/Release/Hello.framework/Resources diff --git a/test/fixtures/test-app-symlink-framework/stripped-native-dep/lib/Release/Hello.framework/Resources b/test/fixtures/test-app-symlink-framework/stripped-native-dep/lib/Release/Hello.framework/Resources deleted file mode 120000 index 953ee36f3bb..00000000000 --- a/test/fixtures/test-app-symlink-framework/stripped-native-dep/lib/Release/Hello.framework/Resources +++ /dev/null @@ -1 +0,0 @@ -Versions/Current/Resources \ No newline at end of file diff --git a/test/snapshots/globTest.js.snap b/test/snapshots/globTest.js.snap index 75b55f371df..b8fd9c0feed 100644 --- a/test/snapshots/globTest.js.snap +++ b/test/snapshots/globTest.js.snap @@ -9857,7 +9857,7 @@ exports[`symlinks everywhere w/ static framework 3`] = ` "link": "index.js", }, "main.js": { - "offset": "14803919", + "offset": "58489", "size": 27, }, "node_modules": { @@ -9868,89 +9868,105 @@ exports[`symlinks everywhere w/ static framework 3`] = ` "files": { "Release": { "files": { - "QtCore.framework": { + "Hello.framework": { "files": { - "QtCore": { - "link": "node_modules/stripped-native-dep/lib/Release/QtCore.framework/Versions/Current/QtCore", + "Headers": { + "link": "node_modules/stripped-native-dep/lib/Release/Hello.framework/Versions/Current/Headers", }, - "Resources": { - "link": "node_modules/stripped-native-dep/lib/Release/QtCore.framework/Versions/Current/Resources", + "Hello": { + "link": "node_modules/stripped-native-dep/lib/Release/Hello.framework/Versions/Current/Hello", + }, + "Info.plist": { + "link": "node_modules/stripped-native-dep/lib/Release/Hello.framework/Versions/Current/Info.plist", + }, + "Modules": { + "link": "node_modules/stripped-native-dep/lib/Release/Hello.framework/Versions/Current/Modules", }, "Versions": { "files": { "A": { "files": { - "QtCore": { - "executable": true, - "offset": "351", - "size": 11404008, - }, - "Resources": { + "Headers": { "files": { - "Info.plist": { - "offset": "11883575", - "size": 764, - }, - "QtCore.prl": { + "HelloFramework.h": { + "executable": true, "offset": "0", - "size": 222, + "size": 52, }, }, }, - }, - }, - "Current": { - "link": "node_modules/stripped-native-dep/lib/Release/QtCore.framework/Versions/A", - }, - }, - }, - }, - }, - "QtNetwork.framework": { - "files": { - "QtNetwork": { - "link": "node_modules/stripped-native-dep/lib/Release/QtNetwork.framework/Versions/Current/QtNetwork", - }, - "Resources": { - "link": "node_modules/stripped-native-dep/lib/Release/QtNetwork.framework/Versions/Current/Resources", - }, - "Versions": { - "files": { - "A": { - "files": { - "QtNetwork": { + "Hello": { "executable": true, - "offset": "11884644", - "size": 2918168, + "offset": "52", + "size": 16120, }, - "Resources": { + "Info.plist": { + "executable": true, + "offset": "16172", + "size": 809, + }, + "Modules": { "files": { - "Info.plist": { - "offset": "14802812", - "size": 770, + "Hello.abi.json": { + "executable": true, + "offset": "16981", + "size": 2215, + }, + "Hello.swiftdoc": { + "executable": true, + "offset": "19196", + "size": 408, + }, + "Hello.swiftmodule": { + "files": { + "arm64.private.swiftinterface": { + "executable": true, + "offset": "19604", + "size": 435, + }, + "arm64.swiftinterface": { + "executable": true, + "offset": "20039", + "size": 435, + }, + "arm64.swiftmodule": { + "executable": true, + "offset": "20474", + "size": 17940, + }, + "x86_64.private.swiftinterface": { + "executable": true, + "offset": "38414", + "size": 436, + }, + "x86_64.swiftinterface": { + "executable": true, + "offset": "38850", + "size": 436, + }, + "x86_64.swiftmodule": { + "executable": true, + "offset": "39286", + "size": 17944, + }, + }, }, - "QtNetwork.prl": { - "offset": "11884339", - "size": 305, + "Hello.swiftsourceinfo": { + "executable": true, + "offset": "57230", + "size": 1064, + }, + "module.modulemap": { + "executable": true, + "offset": "58294", + "size": 66, }, }, }, }, }, "Current": { - "link": "node_modules/stripped-native-dep/lib/Release/QtNetwork.framework/Versions/A", - }, - }, - }, - }, - }, - "qt-plugins": { - "files": { - "tls": { - "files": { - "libqsecuretransportbackend.dylib": { - "offset": "11404359", - "size": 479216, + "link": "node_modules/stripped-native-dep/lib/Release/Hello.framework/Versions/A", }, }, }, @@ -9961,7 +9977,7 @@ exports[`symlinks everywhere w/ static framework 3`] = ` }, }, "package.json": { - "offset": "222", + "offset": "58360", "size": 129, }, }, @@ -9969,7 +9985,7 @@ exports[`symlinks everywhere w/ static framework 3`] = ` }, }, "package.json": { - "offset": "14803582", + "offset": "58516", "size": 337, }, "stripped-native-dep": { @@ -9978,89 +9994,105 @@ exports[`symlinks everywhere w/ static framework 3`] = ` "files": { "Release": { "files": { - "QtCore.framework": { + "Hello.framework": { "files": { - "QtCore": { - "link": "stripped-native-dep/lib/Release/QtCore.framework/Versions/Current/QtCore", + "Headers": { + "link": "stripped-native-dep/lib/Release/Hello.framework/Versions/Current/Headers", + }, + "Hello": { + "link": "stripped-native-dep/lib/Release/Hello.framework/Versions/Current/Hello", + }, + "Info.plist": { + "link": "stripped-native-dep/lib/Release/Hello.framework/Versions/Current/Info.plist", }, - "Resources": { - "link": "stripped-native-dep/lib/Release/QtCore.framework/Versions/Current/Resources", + "Modules": { + "link": "stripped-native-dep/lib/Release/Hello.framework/Versions/Current/Modules", }, "Versions": { "files": { "A": { "files": { - "QtCore": { - "executable": true, - "offset": "14804075", - "size": 11404008, - }, - "Resources": { + "Headers": { "files": { - "Info.plist": { - "offset": "29606764", - "size": 764, - }, - "QtCore.prl": { - "offset": "29606542", - "size": 222, + "HelloFramework.h": { + "executable": true, + "offset": "58853", + "size": 52, }, }, }, - }, - }, - "Current": { - "link": "stripped-native-dep/lib/Release/QtCore.framework/Versions/A", - }, - }, - }, - }, - }, - "QtNetwork.framework": { - "files": { - "QtNetwork": { - "link": "stripped-native-dep/lib/Release/QtNetwork.framework/Versions/Current/QtNetwork", - }, - "Resources": { - "link": "stripped-native-dep/lib/Release/QtNetwork.framework/Versions/Current/Resources", - }, - "Versions": { - "files": { - "A": { - "files": { - "QtNetwork": { + "Hello": { "executable": true, - "offset": "26687299", - "size": 2918168, + "offset": "58905", + "size": 16120, }, - "Resources": { + "Info.plist": { + "executable": true, + "offset": "75025", + "size": 809, + }, + "Modules": { "files": { - "Info.plist": { - "offset": "29605467", - "size": 770, + "Hello.abi.json": { + "executable": true, + "offset": "75834", + "size": 2215, + }, + "Hello.swiftdoc": { + "executable": true, + "offset": "78049", + "size": 408, + }, + "Hello.swiftmodule": { + "files": { + "arm64.private.swiftinterface": { + "executable": true, + "offset": "78457", + "size": 435, + }, + "arm64.swiftinterface": { + "executable": true, + "offset": "78892", + "size": 435, + }, + "arm64.swiftmodule": { + "executable": true, + "offset": "79327", + "size": 17940, + }, + "x86_64.private.swiftinterface": { + "executable": true, + "offset": "97267", + "size": 436, + }, + "x86_64.swiftinterface": { + "executable": true, + "offset": "97703", + "size": 436, + }, + "x86_64.swiftmodule": { + "executable": true, + "offset": "98139", + "size": 17944, + }, + }, }, - "QtNetwork.prl": { - "offset": "29606237", - "size": 305, + "Hello.swiftsourceinfo": { + "executable": true, + "offset": "116083", + "size": 1064, + }, + "module.modulemap": { + "executable": true, + "offset": "117147", + "size": 66, }, }, }, }, }, "Current": { - "link": "stripped-native-dep/lib/Release/QtNetwork.framework/Versions/A", - }, - }, - }, - }, - }, - "qt-plugins": { - "files": { - "tls": { - "files": { - "libqsecuretransportbackend.dylib": { - "offset": "26208083", - "size": 479216, + "link": "stripped-native-dep/lib/Release/Hello.framework/Versions/A", }, }, }, @@ -10071,7 +10103,7 @@ exports[`symlinks everywhere w/ static framework 3`] = ` }, }, "package.json": { - "offset": "14803946", + "offset": "117213", "size": 129, }, }, From 91992da30edea85bc382fd45bf73917bf5b70bec Mon Sep 17 00:00:00 2001 From: Mike Maietta Date: Sun, 3 Nov 2024 21:44:57 -0800 Subject: [PATCH 06/19] cleanup --- packages/app-builder-lib/src/asar/asarUtil.ts | 60 +++++-------------- .../app-builder-lib/src/util/appFileCopier.ts | 4 +- 2 files changed, 16 insertions(+), 48 deletions(-) diff --git a/packages/app-builder-lib/src/asar/asarUtil.ts b/packages/app-builder-lib/src/asar/asarUtil.ts index f3be43237ce..11a01078e3d 100644 --- a/packages/app-builder-lib/src/asar/asarUtil.ts +++ b/packages/app-builder-lib/src/asar/asarUtil.ts @@ -146,50 +146,7 @@ export class AsarPackager { detectUnpackedDirs(fileSet, unpackedPaths, this.config.defaultDestination) } - // await BluebirdPromise.map( - // fileSet.files, - // async (file, i) => { - // const transformedData = fileSet.transformedFiles?.get(i) - // const stat = fileSet.metadata.get(file)! - // const destFile = getDestinationPath(file, fileSet) - - // matchUnpacker(file, destFile, stat) - - // if (!stat.isFile() && !stat.isSymbolicLink()) { - // return - // } - - // const dir = path.dirname(destFile) - // if (!createdSourceDirs.has(dir)) { - // await mkdir(dir, { recursive: true }) - // createdSourceDirs.add(dir) - // } - - // // const destFile = file.replace(file, destination) - // copiedFiles.add(destFile) - // if (transformedData != null) { - // return fs.writeFile(destFile, transformedData, { mode: stat.mode }) - // } else if (stat.isFile()) { - // return this.fileCopier.copy(file, destFile, stat) - // } else { - // let link = await readlink(file) - // if (path.isAbsolute(link)) { - // link = path.relative(path.dirname(file), link) - // } - // links.push({ file: destFile, link }) - // return - // } - // }, - // CONCURRENCY - // ).then(() => - // BluebirdPromise.map( - // links, - // it => { - // return symlink(it.link, it.file, symlinkType) - // }, - // CONCURRENCY - // ) - // ) + // Don't use BluebirdPromise, we need to retain order of execution/iteration through the ordered fileset for (let i = 0; i < fileSet.files.length; i++) { const file = fileSet.files[i] const transformedData = fileSet.transformedFiles?.get(i) @@ -208,7 +165,6 @@ export class AsarPackager { createdSourceDirs.add(dir) } - // const destFile = file.replace(file, destination) copiedFiles.add(destFile) if (transformedData != null) { await fs.writeFile(destFile, transformedData, { mode: stat.mode }) @@ -219,6 +175,17 @@ export class AsarPackager { if (path.isAbsolute(link)) { link = path.relative(path.dirname(file), link) } + + const realPathFile = await fs.realpath(file) + const realPathRelative = path.relative(fileSet.src, realPathFile) + const isOutsidePackage = realPathRelative.startsWith("..") + if (isOutsidePackage) { + log.error({ source: log.filePath(file), realPathFile: log.filePath(realPathFile) }, `unable to copy, file is symlinked outside the package`) + throw new Error( + `Cannot copy file (${path.basename(file)}) symlinked to file (${path.basename(realPathFile)}) outside the package as that violates asar security integrity` + ) + } + links.push({ file: destFile, link }) } // const file = fileSet.files[i] @@ -238,10 +205,11 @@ export class AsarPackager { } } } + // finish copy then set up all symlinks + await taskManager.awaitTasks() for await (const it of links) { await symlink(it.link, it.file, symlinkType) } - await taskManager.awaitTasks() return { unpackedPaths: Array.from(unpackedPaths), copiedFiles: Array.from(copiedFiles), diff --git a/packages/app-builder-lib/src/util/appFileCopier.ts b/packages/app-builder-lib/src/util/appFileCopier.ts index 67b6af256a3..ec21b9faf71 100644 --- a/packages/app-builder-lib/src/util/appFileCopier.ts +++ b/packages/app-builder-lib/src/util/appFileCopier.ts @@ -1,5 +1,5 @@ import BluebirdPromise from "bluebird-lst" -import { AsyncTaskManager, log, CONCURRENCY, FileCopier, FileTransformer, Link, MAX_FILE_REQUESTS, statOrNull, walk, FilterStats } from "builder-util" +import { AsyncTaskManager, log, CONCURRENCY, FileCopier, FileTransformer, Link, MAX_FILE_REQUESTS, statOrNull, walk } from "builder-util" import { Stats } from "fs" import { mkdir, readlink } from "fs/promises" import { ensureSymlink } from "fs-extra" @@ -82,7 +82,7 @@ export interface ResolvedFileSet { destination: string files: Array - metadata: Map + metadata: Map transformedFiles?: Map | null } From 75b6d0ad5ca03ee6bf488bacca114a662fb8680d Mon Sep 17 00:00:00 2001 From: Mike Maietta Date: Mon, 4 Nov 2024 07:29:02 -0800 Subject: [PATCH 07/19] update logic for queuing symlinks after copying all files --- packages/app-builder-lib/src/asar/asarUtil.ts | 117 ++++++------------ .../{main.js => index.js} | 0 .../test-app-symlink-framework/package.json | 2 +- test/snapshots/globTest.js.snap | 40 +++--- test/src/globTest.ts | 2 +- 5 files changed, 63 insertions(+), 98 deletions(-) rename test/fixtures/test-app-symlink-framework/{main.js => index.js} (100%) diff --git a/packages/app-builder-lib/src/asar/asarUtil.ts b/packages/app-builder-lib/src/asar/asarUtil.ts index 11a01078e3d..af46fae0d31 100644 --- a/packages/app-builder-lib/src/asar/asarUtil.ts +++ b/packages/app-builder-lib/src/asar/asarUtil.ts @@ -85,6 +85,10 @@ export class AsarPackager { const unpackedPaths = new Set() const copiedFiles = new Set() + const createdSourceDirs = new Set() + const links: Array = [] + const symlinkType = platform() === "win32" ? "junction" : "file" + const matchUnpacker = (file: string, dest: string, stat: fs.Stats) => { if (this.config.unpackPattern?.(file, stat)) { log.debug({ file }, "unpacking") @@ -92,55 +96,41 @@ export class AsarPackager { return } } - const writeFileOrSymlink = async (options: { transformedData: string | Buffer | undefined; file: string; destination: string; stat: fs.Stats; fileSet: ResolvedFileSet }) => { - const { - transformedData, - file: source, - // destination, - stat, - fileSet: { src: sourceDir, destination: destinationDir }, - } = options - const destination = getDestinationPath(source, options.fileSet) - if (copiedFiles.has(destination)) { + const writeFileOrQueueSymlink = async (options: { transformedData: string | Buffer | undefined; file: string; destFile: string; stat: fs.Stats; fileSet: ResolvedFileSet }) => { + const { transformedData, file, destFile, stat, fileSet } = options + if (!stat.isFile() && !stat.isSymbolicLink()) { return } - copiedFiles.add(destination) - // If transformed data, skip symlink logic - if (transformedData != null) { - return this.copyFileOrData(transformedData, source, destination, stat) + const dir = path.dirname(destFile) + if (!createdSourceDirs.has(dir)) { + await mkdir(dir, { recursive: true }) + createdSourceDirs.add(dir) } - const realPathFile = await fs.realpath(source) - - if (source === realPathFile) { - return this.copyFileOrData(undefined, source, destination, stat) + copiedFiles.add(destFile) + if (transformedData != null) { + return fs.writeFile(destFile, transformedData, { mode: stat.mode }) + } + if (stat.isFile()) { + return this.fileCopier.copy(file, destFile, stat) + } + let link = await readlink(file) + if (path.isAbsolute(link)) { + link = path.relative(path.dirname(file), link) } - const realPathRelative = path.relative(sourceDir, realPathFile) + const realPathFile = await fs.realpath(file) + const realPathRelative = path.relative(fileSet.src, realPathFile) const isOutsidePackage = realPathRelative.startsWith("..") if (isOutsidePackage) { - log.error({ source: log.filePath(source), realPathFile: log.filePath(realPathFile) }, `unable to copy, file is symlinked outside the package`) - throw new Error( - `Cannot copy file (${path.basename(source)}) symlinked to file (${path.basename(realPathFile)}) outside the package as that violates asar security integrity` - ) + log.error({ source: log.filePath(file), realPathFile: log.filePath(realPathFile) }, `unable to copy, file is symlinked outside the package`) + throw new Error(`Cannot copy file (${path.basename(file)}) symlinked to file (${path.basename(realPathFile)}) outside the package as that violates asar security integrity`) } - // await this.copyFileOrData(undefined, source, destination, stat) - // const symlinkTarget = path.resolve(this.rootForAppFilesWithoutAsar, realPathRelative) - const symlinkTarget = path.resolve(path.dirname(destination), realPathRelative) - // await this.copyFileOrData(undefined, source, symlinkTarget, stat) - const target2 = path.relative(path.dirname(destination), symlinkTarget) - const target = fs.readlinkSync(source) - fsNode.symlinkSync(target, destination) - - copiedFiles.add(symlinkTarget) + links.push({ file: destFile, link }) } - const createdSourceDirs = new Set() - const links: Array = [] - const symlinkType = platform() === "win32" ? "junction" : "file" - for await (const fileSet of fileSets) { if (this.config.options.smartUnpack !== false) { detectUnpackedDirs(fileSet, unpackedPaths, this.config.defaultDestination) @@ -155,50 +145,13 @@ export class AsarPackager { matchUnpacker(file, destFile, stat) - if (!stat.isFile() && !stat.isSymbolicLink()) { - continue - } - - const dir = path.dirname(destFile) - if (!createdSourceDirs.has(dir)) { - await mkdir(dir, { recursive: true }) - createdSourceDirs.add(dir) - } - - copiedFiles.add(destFile) - if (transformedData != null) { - await fs.writeFile(destFile, transformedData, { mode: stat.mode }) - } else if (stat.isFile()) { - await this.fileCopier.copy(file, destFile, stat) - } else { - let link = await readlink(file) - if (path.isAbsolute(link)) { - link = path.relative(path.dirname(file), link) - } - - const realPathFile = await fs.realpath(file) - const realPathRelative = path.relative(fileSet.src, realPathFile) - const isOutsidePackage = realPathRelative.startsWith("..") - if (isOutsidePackage) { - log.error({ source: log.filePath(file), realPathFile: log.filePath(realPathFile) }, `unable to copy, file is symlinked outside the package`) - throw new Error( - `Cannot copy file (${path.basename(file)}) symlinked to file (${path.basename(realPathFile)}) outside the package as that violates asar security integrity` - ) - } - - links.push({ file: destFile, link }) - } - // const file = fileSet.files[i] - // const transformedData = fileSet.transformedFiles?.get(i) - // const metadata = fileSet.metadata.get(file)! - // const relative = path.relative(this.config.defaultDestination, getDestinationPath(file, fileSet)) // const dest = path.resolve(this.rootForAppFilesWithoutAsar, relative) // matchUnpacker(file, dest, metadata) - // // taskManager.addTask( - // await writeFileOrSymlink({ transformedData, file, destination: dest, stat: metadata, fileSet }) - // // ) + // taskManager.addTask( + await writeFileOrQueueSymlink({ transformedData, file, destFile, stat, fileSet }) + // ) if (taskManager.tasks.length > MAX_FILE_REQUESTS) { await taskManager.awaitTasks() @@ -207,9 +160,15 @@ export class AsarPackager { } // finish copy then set up all symlinks await taskManager.awaitTasks() - for await (const it of links) { - await symlink(it.link, it.file, symlinkType) - } + for (const it of links) { + // taskManager.addTask( + await symlink(it.link, it.file, symlinkType) + // ) + if (taskManager.tasks.length > MAX_FILE_REQUESTS) { + await taskManager.awaitTasks() + } + } + await taskManager.awaitTasks() return { unpackedPaths: Array.from(unpackedPaths), copiedFiles: Array.from(copiedFiles), diff --git a/test/fixtures/test-app-symlink-framework/main.js b/test/fixtures/test-app-symlink-framework/index.js similarity index 100% rename from test/fixtures/test-app-symlink-framework/main.js rename to test/fixtures/test-app-symlink-framework/index.js diff --git a/test/fixtures/test-app-symlink-framework/package.json b/test/fixtures/test-app-symlink-framework/package.json index aa01146486a..a7d8e0c10f9 100644 --- a/test/fixtures/test-app-symlink-framework/package.json +++ b/test/fixtures/test-app-symlink-framework/package.json @@ -1,5 +1,4 @@ { - "main": "main.js", "name": "TestApp", "productName": "Test App ßW", "version": "1.1.0", @@ -7,6 +6,7 @@ "description": "Test Application (test quite \" #378)", "author": "Foo Bar ", "license": "MIT", + "main": "index.js", "build": { "electronVersion": "23.3.10", "appId": "org.electron-builder.testApp", diff --git a/test/snapshots/globTest.js.snap b/test/snapshots/globTest.js.snap index b8fd9c0feed..5b4efb7b68e 100644 --- a/test/snapshots/globTest.js.snap +++ b/test/snapshots/globTest.js.snap @@ -9836,7 +9836,13 @@ exports[`local node module with file protocol 1`] = ` } `; -exports[`outside link 1`] = `"Cannot copy file (foo) symlinked to file (foo) outside the package as that violates asar security integrity"`; +exports[`outside link 1`] = ` +{ + "linux": [], +} +`; + +exports[`outside link 2`] = `undefined`; exports[`symlinks everywhere w/ static framework 1`] = ` { @@ -9856,7 +9862,7 @@ exports[`symlinks everywhere w/ static framework 3`] = ` "foo.js": { "link": "index.js", }, - "main.js": { + "index.js": { "offset": "58489", "size": 27, }, @@ -9986,7 +9992,7 @@ exports[`symlinks everywhere w/ static framework 3`] = ` }, "package.json": { "offset": "58516", - "size": 337, + "size": 338, }, "stripped-native-dep": { "files": { @@ -10016,75 +10022,75 @@ exports[`symlinks everywhere w/ static framework 3`] = ` "files": { "HelloFramework.h": { "executable": true, - "offset": "58853", + "offset": "58854", "size": 52, }, }, }, "Hello": { "executable": true, - "offset": "58905", + "offset": "58906", "size": 16120, }, "Info.plist": { "executable": true, - "offset": "75025", + "offset": "75026", "size": 809, }, "Modules": { "files": { "Hello.abi.json": { "executable": true, - "offset": "75834", + "offset": "75835", "size": 2215, }, "Hello.swiftdoc": { "executable": true, - "offset": "78049", + "offset": "78050", "size": 408, }, "Hello.swiftmodule": { "files": { "arm64.private.swiftinterface": { "executable": true, - "offset": "78457", + "offset": "78458", "size": 435, }, "arm64.swiftinterface": { "executable": true, - "offset": "78892", + "offset": "78893", "size": 435, }, "arm64.swiftmodule": { "executable": true, - "offset": "79327", + "offset": "79328", "size": 17940, }, "x86_64.private.swiftinterface": { "executable": true, - "offset": "97267", + "offset": "97268", "size": 436, }, "x86_64.swiftinterface": { "executable": true, - "offset": "97703", + "offset": "97704", "size": 436, }, "x86_64.swiftmodule": { "executable": true, - "offset": "98139", + "offset": "98140", "size": 17944, }, }, }, "Hello.swiftsourceinfo": { "executable": true, - "offset": "116083", + "offset": "116084", "size": 1064, }, "module.modulemap": { "executable": true, - "offset": "117147", + "offset": "117148", "size": 66, }, }, @@ -10103,7 +10109,7 @@ exports[`symlinks everywhere w/ static framework 3`] = ` }, }, "package.json": { - "offset": "117213", + "offset": "117214", "size": 129, }, }, diff --git a/test/src/globTest.ts b/test/src/globTest.ts index 2cc34c9d414..146a8b8343b 100644 --- a/test/src/globTest.ts +++ b/test/src/globTest.ts @@ -143,7 +143,7 @@ test.ifNotWindows( await fs.symlink(tempDir, path.join(projectDir, "o-dir")) }, }, - error => expect(error.message.includes("violates asar security integrity")).toBe(true) + error => expect(error.message).toContain("violates asar security integrity") ) ) From 20d3111870362e98a1255e41fd335a89bd4902ae Mon Sep 17 00:00:00 2001 From: Mike Maietta Date: Mon, 4 Nov 2024 07:48:05 -0800 Subject: [PATCH 08/19] got all globTest working --- packages/app-builder-lib/src/asar/asarUtil.ts | 58 ++++++------------- test/snapshots/globTest.js.snap | 8 --- 2 files changed, 19 insertions(+), 47 deletions(-) diff --git a/packages/app-builder-lib/src/asar/asarUtil.ts b/packages/app-builder-lib/src/asar/asarUtil.ts index af46fae0d31..f07e5726f73 100644 --- a/packages/app-builder-lib/src/asar/asarUtil.ts +++ b/packages/app-builder-lib/src/asar/asarUtil.ts @@ -1,9 +1,7 @@ -import BluebirdPromise from "bluebird-lst" - import { CreateOptions, createPackageWithOptions } from "@electron/asar" import { AsyncTaskManager, log } from "builder-util" import { CancellationToken } from "builder-util-runtime" -import { CONCURRENCY, copyDir, DO_NOT_USE_HARD_LINKS, FileCopier, Filter, FilterStats, Link, MAX_FILE_REQUESTS } from "builder-util/out/fs" +import { DO_NOT_USE_HARD_LINKS, FileCopier, Filter, Link, MAX_FILE_REQUESTS } from "builder-util/out/fs" import * as fsNode from "fs" import * as fs from "fs-extra" import * as path from "path" @@ -101,6 +99,7 @@ export class AsarPackager { if (!stat.isFile() && !stat.isSymbolicLink()) { return } + copiedFiles.add(destFile) const dir = path.dirname(destFile) if (!createdSourceDirs.has(dir)) { @@ -108,17 +107,9 @@ export class AsarPackager { createdSourceDirs.add(dir) } - copiedFiles.add(destFile) if (transformedData != null) { return fs.writeFile(destFile, transformedData, { mode: stat.mode }) } - if (stat.isFile()) { - return this.fileCopier.copy(file, destFile, stat) - } - let link = await readlink(file) - if (path.isAbsolute(link)) { - link = path.relative(path.dirname(file), link) - } const realPathFile = await fs.realpath(file) const realPathRelative = path.relative(fileSet.src, realPathFile) @@ -128,6 +119,17 @@ export class AsarPackager { throw new Error(`Cannot copy file (${path.basename(file)}) symlinked to file (${path.basename(realPathFile)}) outside the package as that violates asar security integrity`) } + // not a symlink + if (file === realPathFile) { + return this.fileCopier.copy(file, destFile, stat) + } + + // must be a symlink + let link = await readlink(file) + if (path.isAbsolute(link)) { + link = path.relative(path.dirname(file), link) + } + links.push({ file: destFile, link }) } @@ -162,40 +164,18 @@ export class AsarPackager { await taskManager.awaitTasks() for (const it of links) { // taskManager.addTask( - await symlink(it.link, it.file, symlinkType) - // ) - if (taskManager.tasks.length > MAX_FILE_REQUESTS) { - await taskManager.awaitTasks() - } + await symlink(it.link, it.file, symlinkType) + // ) + if (taskManager.tasks.length > MAX_FILE_REQUESTS) { + await taskManager.awaitTasks() } - await taskManager.awaitTasks() + } + await taskManager.awaitTasks() return { unpackedPaths: Array.from(unpackedPaths), copiedFiles: Array.from(copiedFiles), } } - - private async copyFileOrData(data: string | Buffer | undefined, source: string, destination: string, stat: fs.Stats) { - // const sourceStat = stat || fs.statSync(source) - // if (sourceStat.isSymbolicLink()) { - // return copyDir(source, destination) - // } - // if (sourceStat.isSymbolicLink()) { - // const link = fs.readlinkSync(source) - // // const symlinkTarget = path.resolve(this.rootForAppFilesWithoutAsar, realPathRelative) - // // await this.copyFileOrData(undefined, source, symlinkTarget, stat) - // const target = path.relative(path.dirname(destination), link) - // fsNode.symlinkSync(target, destination) - // return - // } - await fs.mkdir(path.dirname(destination), { recursive: true }) - if (data != null) { - return fs.writeFile(destination, data, { mode: stat.mode }) - } else { - // return fs.copyFile(source, destination) - return this.fileCopier.copy(source, destination, stat) - } - } } function orderFileSet(fileSet: ResolvedFileSet): ResolvedFileSet { diff --git a/test/snapshots/globTest.js.snap b/test/snapshots/globTest.js.snap index 5b4efb7b68e..8464b2515aa 100644 --- a/test/snapshots/globTest.js.snap +++ b/test/snapshots/globTest.js.snap @@ -9836,14 +9836,6 @@ exports[`local node module with file protocol 1`] = ` } `; -exports[`outside link 1`] = ` -{ - "linux": [], -} -`; - -exports[`outside link 2`] = `undefined`; - exports[`symlinks everywhere w/ static framework 1`] = ` { "linux": [], From 86bfb27b106ac7671570ee69425490cbe6fbf8cd Mon Sep 17 00:00:00 2001 From: Mike Maietta Date: Mon, 4 Nov 2024 07:56:06 -0800 Subject: [PATCH 09/19] add promises to async task manager --- packages/app-builder-lib/src/asar/asarUtil.ts | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/packages/app-builder-lib/src/asar/asarUtil.ts b/packages/app-builder-lib/src/asar/asarUtil.ts index f07e5726f73..553993072b6 100644 --- a/packages/app-builder-lib/src/asar/asarUtil.ts +++ b/packages/app-builder-lib/src/asar/asarUtil.ts @@ -151,9 +151,7 @@ export class AsarPackager { // const dest = path.resolve(this.rootForAppFilesWithoutAsar, relative) // matchUnpacker(file, dest, metadata) - // taskManager.addTask( - await writeFileOrQueueSymlink({ transformedData, file, destFile, stat, fileSet }) - // ) + taskManager.addTask(writeFileOrQueueSymlink({ transformedData, file, destFile, stat, fileSet })) if (taskManager.tasks.length > MAX_FILE_REQUESTS) { await taskManager.awaitTasks() @@ -163,9 +161,8 @@ export class AsarPackager { // finish copy then set up all symlinks await taskManager.awaitTasks() for (const it of links) { - // taskManager.addTask( - await symlink(it.link, it.file, symlinkType) - // ) + taskManager.addTask(symlink(it.link, it.file, symlinkType)) + if (taskManager.tasks.length > MAX_FILE_REQUESTS) { await taskManager.awaitTasks() } From d67153ab307dfc5f15991447cfc8c41e781ae5ee Mon Sep 17 00:00:00 2001 From: Mike Maietta Date: Mon, 4 Nov 2024 08:09:05 -0800 Subject: [PATCH 10/19] cleanup and edit snapshot --- packages/app-builder-lib/src/asar/asarUtil.ts | 18 ++++++++--------- test/snapshots/globTest.js.snap | 20 +++++++++---------- 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/packages/app-builder-lib/src/asar/asarUtil.ts b/packages/app-builder-lib/src/asar/asarUtil.ts index 553993072b6..54cb9752a17 100644 --- a/packages/app-builder-lib/src/asar/asarUtil.ts +++ b/packages/app-builder-lib/src/asar/asarUtil.ts @@ -1,7 +1,7 @@ import { CreateOptions, createPackageWithOptions } from "@electron/asar" import { AsyncTaskManager, log } from "builder-util" import { CancellationToken } from "builder-util-runtime" -import { DO_NOT_USE_HARD_LINKS, FileCopier, Filter, Link, MAX_FILE_REQUESTS } from "builder-util/out/fs" +import { FileCopier, Filter, Link, MAX_FILE_REQUESTS } from "builder-util/out/fs" import * as fsNode from "fs" import * as fs from "fs-extra" import * as path from "path" @@ -18,7 +18,7 @@ export class AsarPackager { private readonly outFile: string private readonly rootForAppFilesWithoutAsar: string private readonly tmpDir = new tempFile.TmpDir() - private readonly fileCopier = new FileCopier(DO_NOT_USE_HARD_LINKS) + private readonly fileCopier = new FileCopier() constructor( private readonly config: { @@ -36,7 +36,7 @@ export class AsarPackager { // this.rootForAppFilesWithoutAsar = await this.tmpDir.getTempDir({ prefix: "asar-app" }) const cancellationToken = new CancellationToken() - cancellationToken.on("cancel", () => this.tmpDir.cleanupSync()) + cancellationToken.on("cancel", () => this.cleanup()) const orderedFileSets = [ // Write dependencies first to minimize offset changes to asar header @@ -74,8 +74,12 @@ export class AsarPackager { await createPackageWithOptions(this.rootForAppFilesWithoutAsar, this.outFile, options) console.log = consoleLogger - await this.tmpDir.cleanup() + this.cleanup() + } + + private cleanup() { fsNode.rmSync(this.rootForAppFilesWithoutAsar, { recursive: true }) + this.tmpDir.cleanupSync() } private async detectAndCopy(fileSets: ResolvedFileSet[], cancellationToken: CancellationToken) { @@ -107,6 +111,7 @@ export class AsarPackager { createdSourceDirs.add(dir) } + // write any data if provided, skip symlink check if (transformedData != null) { return fs.writeFile(destFile, transformedData, { mode: stat.mode }) } @@ -146,11 +151,6 @@ export class AsarPackager { const destFile = getDestinationPath(file, fileSet) matchUnpacker(file, destFile, stat) - - // const relative = path.relative(this.config.defaultDestination, getDestinationPath(file, fileSet)) - // const dest = path.resolve(this.rootForAppFilesWithoutAsar, relative) - - // matchUnpacker(file, dest, metadata) taskManager.addTask(writeFileOrQueueSymlink({ transformedData, file, destFile, stat, fileSet })) if (taskManager.tasks.length > MAX_FILE_REQUESTS) { diff --git a/test/snapshots/globTest.js.snap b/test/snapshots/globTest.js.snap index 8464b2515aa..249f26b6e70 100644 --- a/test/snapshots/globTest.js.snap +++ b/test/snapshots/globTest.js.snap @@ -9869,16 +9869,16 @@ exports[`symlinks everywhere w/ static framework 3`] = ` "Hello.framework": { "files": { "Headers": { - "link": "node_modules/stripped-native-dep/lib/Release/Hello.framework/Versions/Current/Headers", + "link": "Versions/Current/Headers", }, "Hello": { - "link": "node_modules/stripped-native-dep/lib/Release/Hello.framework/Versions/Current/Hello", + "link": "Versions/Current/Hello", }, "Info.plist": { - "link": "node_modules/stripped-native-dep/lib/Release/Hello.framework/Versions/Current/Info.plist", + "link": "Versions/Current/Info.plist", }, "Modules": { - "link": "node_modules/stripped-native-dep/lib/Release/Hello.framework/Versions/Current/Modules", + "link": "Versions/Current/Modules", }, "Versions": { "files": { @@ -9964,7 +9964,7 @@ exports[`symlinks everywhere w/ static framework 3`] = ` }, }, "Current": { - "link": "node_modules/stripped-native-dep/lib/Release/Hello.framework/Versions/A", + "link": "Versions/A", }, }, }, @@ -9995,16 +9995,16 @@ exports[`symlinks everywhere w/ static framework 3`] = ` "Hello.framework": { "files": { "Headers": { - "link": "stripped-native-dep/lib/Release/Hello.framework/Versions/Current/Headers", + "link": "Versions/Current/Headers", }, "Hello": { - "link": "stripped-native-dep/lib/Release/Hello.framework/Versions/Current/Hello", + "link": "Versions/Current/Hello", }, "Info.plist": { - "link": "stripped-native-dep/lib/Release/Hello.framework/Versions/Current/Info.plist", + "link": "Versions/Current/Info.plist", }, "Modules": { - "link": "stripped-native-dep/lib/Release/Hello.framework/Versions/Current/Modules", + "link": "Versions/Current/Modules", }, "Versions": { "files": { @@ -10090,7 +10090,7 @@ exports[`symlinks everywhere w/ static framework 3`] = ` }, }, "Current": { - "link": "stripped-native-dep/lib/Release/Hello.framework/Versions/A", + "link": "Versions/A", }, }, }, From 0d7f693dc367266de27128b0fde383659d6521eb Mon Sep 17 00:00:00 2001 From: Mike Maietta Date: Mon, 4 Nov 2024 08:38:57 -0800 Subject: [PATCH 11/19] rename to hello-world. add compilation script for transparency --- packages/app-builder-lib/src/asar/asarUtil.ts | 10 +- .../hello-world/hello-world-framework.sh | 222 ++++++++++++++++++ .../lib/Release/Hello.framework/Headers | 0 .../lib/Release/Hello.framework/Hello | 0 .../lib/Release/Hello.framework/Info.plist | 0 .../lib/Release/Hello.framework/Modules | 0 .../Versions/A/Headers/HelloFramework.h | 0 .../Release/Hello.framework/Versions/A/Hello | Bin .../Hello.framework/Versions/A/Info.plist | 0 .../Versions/A/Modules/Hello.abi.json | 0 .../Versions/A/Modules/Hello.swiftdoc | Bin .../arm64.private.swiftinterface | 0 .../Hello.swiftmodule/arm64.swiftinterface | 0 .../Hello.swiftmodule/arm64.swiftmodule | Bin .../x86_64.private.swiftinterface | 0 .../Hello.swiftmodule/x86_64.swiftinterface | 0 .../Hello.swiftmodule/x86_64.swiftmodule | Bin .../Versions/A/Modules/Hello.swiftsourceinfo | Bin .../Versions/A/Modules/module.modulemap | 0 .../Release/Hello.framework/Versions/Current | 0 .../package.json | 0 test/src/globTest.ts | 4 + 22 files changed, 233 insertions(+), 3 deletions(-) create mode 100644 test/fixtures/test-app-symlink-framework/hello-world/hello-world-framework.sh rename test/fixtures/test-app-symlink-framework/{stripped-native-dep => hello-world}/lib/Release/Hello.framework/Headers (100%) rename test/fixtures/test-app-symlink-framework/{stripped-native-dep => hello-world}/lib/Release/Hello.framework/Hello (100%) rename test/fixtures/test-app-symlink-framework/{stripped-native-dep => hello-world}/lib/Release/Hello.framework/Info.plist (100%) rename test/fixtures/test-app-symlink-framework/{stripped-native-dep => hello-world}/lib/Release/Hello.framework/Modules (100%) rename test/fixtures/test-app-symlink-framework/{stripped-native-dep => hello-world}/lib/Release/Hello.framework/Versions/A/Headers/HelloFramework.h (100%) rename test/fixtures/test-app-symlink-framework/{stripped-native-dep => hello-world}/lib/Release/Hello.framework/Versions/A/Hello (100%) rename test/fixtures/test-app-symlink-framework/{stripped-native-dep => hello-world}/lib/Release/Hello.framework/Versions/A/Info.plist (100%) rename test/fixtures/test-app-symlink-framework/{stripped-native-dep => hello-world}/lib/Release/Hello.framework/Versions/A/Modules/Hello.abi.json (100%) rename test/fixtures/test-app-symlink-framework/{stripped-native-dep => hello-world}/lib/Release/Hello.framework/Versions/A/Modules/Hello.swiftdoc (100%) rename test/fixtures/test-app-symlink-framework/{stripped-native-dep => hello-world}/lib/Release/Hello.framework/Versions/A/Modules/Hello.swiftmodule/arm64.private.swiftinterface (100%) rename test/fixtures/test-app-symlink-framework/{stripped-native-dep => hello-world}/lib/Release/Hello.framework/Versions/A/Modules/Hello.swiftmodule/arm64.swiftinterface (100%) rename test/fixtures/test-app-symlink-framework/{stripped-native-dep => hello-world}/lib/Release/Hello.framework/Versions/A/Modules/Hello.swiftmodule/arm64.swiftmodule (100%) rename test/fixtures/test-app-symlink-framework/{stripped-native-dep => hello-world}/lib/Release/Hello.framework/Versions/A/Modules/Hello.swiftmodule/x86_64.private.swiftinterface (100%) rename test/fixtures/test-app-symlink-framework/{stripped-native-dep => hello-world}/lib/Release/Hello.framework/Versions/A/Modules/Hello.swiftmodule/x86_64.swiftinterface (100%) rename test/fixtures/test-app-symlink-framework/{stripped-native-dep => hello-world}/lib/Release/Hello.framework/Versions/A/Modules/Hello.swiftmodule/x86_64.swiftmodule (100%) rename test/fixtures/test-app-symlink-framework/{stripped-native-dep => hello-world}/lib/Release/Hello.framework/Versions/A/Modules/Hello.swiftsourceinfo (100%) rename test/fixtures/test-app-symlink-framework/{stripped-native-dep => hello-world}/lib/Release/Hello.framework/Versions/A/Modules/module.modulemap (100%) rename test/fixtures/test-app-symlink-framework/{stripped-native-dep => hello-world}/lib/Release/Hello.framework/Versions/Current (100%) rename test/fixtures/test-app-symlink-framework/{stripped-native-dep => hello-world}/package.json (100%) diff --git a/packages/app-builder-lib/src/asar/asarUtil.ts b/packages/app-builder-lib/src/asar/asarUtil.ts index 54cb9752a17..ebd93e4a041 100644 --- a/packages/app-builder-lib/src/asar/asarUtil.ts +++ b/packages/app-builder-lib/src/asar/asarUtil.ts @@ -49,6 +49,12 @@ export class AsarPackager { const { unpackedPaths, copiedFiles } = await this.detectAndCopy(orderedFileSets, cancellationToken) const unpackGlob = unpackedPaths.length > 1 ? `{${unpackedPaths.join(",")}}` : unpackedPaths.pop() + await this.executeElectronAsar(copiedFiles, unpackGlob) + + this.cleanup() + } + + private async executeElectronAsar(copiedFiles: string[], unpackGlob: string | undefined) { let ordering = this.config.options.ordering || undefined if (!ordering) { // `copiedFiles` are already ordered due to `orderedFileSets` input, so we just map to their relative paths (via substring) within the asar. @@ -73,8 +79,6 @@ export class AsarPackager { } await createPackageWithOptions(this.rootForAppFilesWithoutAsar, this.outFile, options) console.log = consoleLogger - - this.cleanup() } private cleanup() { @@ -132,7 +136,7 @@ export class AsarPackager { // must be a symlink let link = await readlink(file) if (path.isAbsolute(link)) { - link = path.relative(path.dirname(file), link) + link = path.relative(fileSet.src, link) } links.push({ file: destFile, link }) diff --git a/test/fixtures/test-app-symlink-framework/hello-world/hello-world-framework.sh b/test/fixtures/test-app-symlink-framework/hello-world/hello-world-framework.sh new file mode 100644 index 00000000000..de4ff8d2587 --- /dev/null +++ b/test/fixtures/test-app-symlink-framework/hello-world/hello-world-framework.sh @@ -0,0 +1,222 @@ +#!/bin/bash + +set -ex + +# Ignore lines that start with a hash (#) +# setopt INTERACTIVE_COMMENTS + +# # Skip commands where the glob pattern does not match any files +# setopt null_glob + +# Prepare an empty folder +BUILD_DIR="$(pwd)/lib/Release/Hello" +rm -rf "${BUILD_DIR}" +mkdir -p "${BUILD_DIR}" +cd "${BUILD_DIR}" + +# BUILD DYNAMIC LIBRARY + +# Compile the library source +cat << EOF > Greeter.swift +public class Greeter { + public init() {} + public func hello() { + print("Hello World!") + } +} +EOF + +# Create directories for each architecture +mkdir -p arm64 x86_64 + +# Compile Hello.swift to object files and generate module files for each architecture +swiftc -parse-as-library \ + -emit-object -o arm64/Hello.o \ + -emit-module -module-name Hello -emit-module-path arm64/Hello.swiftmodule \ + -enable-library-evolution -emit-module-interface-path arm64/Hello.swiftinterface \ + -target arm64-apple-macosx10.9.0 \ + Greeter.swift + +swiftc -parse-as-library \ + -emit-object -o x86_64/Hello.o \ + -emit-module -module-name Hello -emit-module-path x86_64/Hello.swiftmodule \ + -enable-library-evolution -emit-module-interface-path x86_64/Hello.swiftinterface \ + -target x86_64-apple-macosx10.9.0 \ + Greeter.swift + +# Create a universal (fat) static library from the object files +lipo -create arm64/Hello.o x86_64/Hello.o -output Hello.o +libtool -static -o libHello.a Hello.o +rm Hello.o + + +# BUILD STATIC FRAMEWORK + +# Create framework structure +mkdir -p Hello.framework/Versions/A/ +mkdir -p Hello.framework/Versions/A/Modules +mkdir -p Hello.framework/Versions/A/Modules/Hello.swiftmodule +mkdir -p Hello.framework/Versions/A/Headers +mkdir -p Hello.framework/Versions/A/Resources + +# Move static library +mv libHello.a Hello.framework/Versions/A/Hello + +# Move module files +mv arm64/Hello.swiftdoc Hello.framework/Versions/A/Modules/ +mv arm64/Hello.abi.json Hello.framework/Versions/A/Modules/ +mv arm64/Hello.swiftsourceinfo Hello.framework/Versions/A/Modules/ + +mv arm64/Hello.swiftmodule Hello.framework/Versions/A/Modules/Hello.swiftmodule/arm64.swiftmodule +mv arm64/Hello.swiftinterface Hello.framework/Versions/A/Modules/Hello.swiftmodule/arm64.swiftinterface +mv arm64/Hello.private.swiftinterface Hello.framework/Versions/A/Modules/Hello.swiftmodule/arm64.private.swiftinterface + +mv x86_64/Hello.swiftmodule Hello.framework/Versions/A/Modules/Hello.swiftmodule/x86_64.swiftmodule +mv x86_64/Hello.swiftinterface Hello.framework/Versions/A/Modules/Hello.swiftmodule/x86_64.swiftinterface +mv x86_64/Hello.private.swiftinterface Hello.framework/Versions/A/Modules/Hello.swiftmodule/x86_64.private.swiftinterface + +# This modulemap is superfluous unless you use the library from Objetive-C. +cat << EOF > Hello.framework/Versions/A/Modules/module.modulemap +framework module Hello { + header "HelloFramework.h" + export * +} +EOF + +# This header is superfluous unless you use the library from Objetive-C. +cat << EOF > Hello.framework/Versions/A/Headers/HelloFramework.h +#import +void hello(void); +EOF + +cat << EOF > Hello.framework/Versions/A/Info.plist + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + Hello + CFBundleIdentifier + com.example.Hello + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + Hello + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + NSHumanReadableCopyright + Copyright © 2024 Hello Company. All rights reserved. + + +EOF + +# Create symbolic links to speed up access +cd Hello.framework/Versions +ln -s A Current +cd .. +ln -s Versions/Current/Hello Hello +ln -s Versions/Current/Headers Headers +ln -s Versions/Current/Info.plist Info.plist +ln -s Versions/Current/Resources Resources +ln -s Versions/Current/Modules Modules + +cd .. +chmod -R 755 Hello.framework + + +# BUILD THE CLIENT + +# Create UseHello.swift +cat << EOF > UseHello.swift +import Hello +@main +public struct UseHello { + public static func main() { + let greeter = Greeter() + greeter.hello() + } +} +EOF + +# Compile UseHello.swift into executables for each architecture +swiftc -parse-as-library \ + -o UseHello-arm64 UseHello.swift \ + -target arm64-apple-macosx10.9.0 \ + -F. -framework Hello -I Hello.framework/Modules/arm64 + +swiftc -parse-as-library \ + -o UseHello-x86_64 UseHello.swift \ + -target x86_64-apple-macosx10.9.0 \ + -F. -framework Hello -I Hello.framework/Modules/x86_64 + +# Create a universal (fat) binary +lipo -create UseHello-arm64 UseHello-x86_64 -output UseHello + +# Clean up intermediate files +rm UseHello-arm64 UseHello-x86_64 + +# cleanup +rm -rf arm64 +rm -rf x86_64 + + +# EXECUTE + +# Execute +./UseHello + + +# CREATE EXECUTABLE PACKAGE + +# Encapsulate the libHello.a in a xcframework +xcodebuild -create-xcframework \ + -framework Hello.framework \ + -output Hello.xcframework + +# Optionally sign the framework +# security find-identity -v -p codesigning +# codesign --sign "YOUR_ID_HERE" --timestamp --options runtime Hello.xcframework + +# Remove everything except the xcframework +# I’m discarding the message 'rm: Hello.xcframework: is a directory' +rm * 2>/dev/null + +# Create an executable +swift package init --type executable --name UseHello + +# Overwrite the Package.swift to add the dependency +cat << EOF > Package.swift +// swift-tools-version: 6.0 +import PackageDescription + +let package = Package( + name: "UseHello", + platforms: [.macOS(.v15)], + products: [ + .executable(name: "UseHello", targets: ["UseHello"]) + ], + dependencies: [], + targets: [ + .executableTarget(name: "UseHello", dependencies: ["Hello"]), + .binaryTarget(name: "Hello", path: "./Hello.xcframework") + ] +) +EOF + +# Replace the default main.swift file. +rm Sources/main.swift +mkdir -p Sources/UseHello +cat << EOF > Sources/UseHello/main.swift +import Hello +Greeter().hello() +EOF + +swift run --arch x86_64 +swift run --arch arm64 +swift build --arch x86_64 --arch arm64 \ No newline at end of file diff --git a/test/fixtures/test-app-symlink-framework/stripped-native-dep/lib/Release/Hello.framework/Headers b/test/fixtures/test-app-symlink-framework/hello-world/lib/Release/Hello.framework/Headers similarity index 100% rename from test/fixtures/test-app-symlink-framework/stripped-native-dep/lib/Release/Hello.framework/Headers rename to test/fixtures/test-app-symlink-framework/hello-world/lib/Release/Hello.framework/Headers diff --git a/test/fixtures/test-app-symlink-framework/stripped-native-dep/lib/Release/Hello.framework/Hello b/test/fixtures/test-app-symlink-framework/hello-world/lib/Release/Hello.framework/Hello similarity index 100% rename from test/fixtures/test-app-symlink-framework/stripped-native-dep/lib/Release/Hello.framework/Hello rename to test/fixtures/test-app-symlink-framework/hello-world/lib/Release/Hello.framework/Hello diff --git a/test/fixtures/test-app-symlink-framework/stripped-native-dep/lib/Release/Hello.framework/Info.plist b/test/fixtures/test-app-symlink-framework/hello-world/lib/Release/Hello.framework/Info.plist similarity index 100% rename from test/fixtures/test-app-symlink-framework/stripped-native-dep/lib/Release/Hello.framework/Info.plist rename to test/fixtures/test-app-symlink-framework/hello-world/lib/Release/Hello.framework/Info.plist diff --git a/test/fixtures/test-app-symlink-framework/stripped-native-dep/lib/Release/Hello.framework/Modules b/test/fixtures/test-app-symlink-framework/hello-world/lib/Release/Hello.framework/Modules similarity index 100% rename from test/fixtures/test-app-symlink-framework/stripped-native-dep/lib/Release/Hello.framework/Modules rename to test/fixtures/test-app-symlink-framework/hello-world/lib/Release/Hello.framework/Modules diff --git a/test/fixtures/test-app-symlink-framework/stripped-native-dep/lib/Release/Hello.framework/Versions/A/Headers/HelloFramework.h b/test/fixtures/test-app-symlink-framework/hello-world/lib/Release/Hello.framework/Versions/A/Headers/HelloFramework.h similarity index 100% rename from test/fixtures/test-app-symlink-framework/stripped-native-dep/lib/Release/Hello.framework/Versions/A/Headers/HelloFramework.h rename to test/fixtures/test-app-symlink-framework/hello-world/lib/Release/Hello.framework/Versions/A/Headers/HelloFramework.h diff --git a/test/fixtures/test-app-symlink-framework/stripped-native-dep/lib/Release/Hello.framework/Versions/A/Hello b/test/fixtures/test-app-symlink-framework/hello-world/lib/Release/Hello.framework/Versions/A/Hello similarity index 100% rename from test/fixtures/test-app-symlink-framework/stripped-native-dep/lib/Release/Hello.framework/Versions/A/Hello rename to test/fixtures/test-app-symlink-framework/hello-world/lib/Release/Hello.framework/Versions/A/Hello diff --git a/test/fixtures/test-app-symlink-framework/stripped-native-dep/lib/Release/Hello.framework/Versions/A/Info.plist b/test/fixtures/test-app-symlink-framework/hello-world/lib/Release/Hello.framework/Versions/A/Info.plist similarity index 100% rename from test/fixtures/test-app-symlink-framework/stripped-native-dep/lib/Release/Hello.framework/Versions/A/Info.plist rename to test/fixtures/test-app-symlink-framework/hello-world/lib/Release/Hello.framework/Versions/A/Info.plist diff --git a/test/fixtures/test-app-symlink-framework/stripped-native-dep/lib/Release/Hello.framework/Versions/A/Modules/Hello.abi.json b/test/fixtures/test-app-symlink-framework/hello-world/lib/Release/Hello.framework/Versions/A/Modules/Hello.abi.json similarity index 100% rename from test/fixtures/test-app-symlink-framework/stripped-native-dep/lib/Release/Hello.framework/Versions/A/Modules/Hello.abi.json rename to test/fixtures/test-app-symlink-framework/hello-world/lib/Release/Hello.framework/Versions/A/Modules/Hello.abi.json diff --git a/test/fixtures/test-app-symlink-framework/stripped-native-dep/lib/Release/Hello.framework/Versions/A/Modules/Hello.swiftdoc b/test/fixtures/test-app-symlink-framework/hello-world/lib/Release/Hello.framework/Versions/A/Modules/Hello.swiftdoc similarity index 100% rename from test/fixtures/test-app-symlink-framework/stripped-native-dep/lib/Release/Hello.framework/Versions/A/Modules/Hello.swiftdoc rename to test/fixtures/test-app-symlink-framework/hello-world/lib/Release/Hello.framework/Versions/A/Modules/Hello.swiftdoc diff --git a/test/fixtures/test-app-symlink-framework/stripped-native-dep/lib/Release/Hello.framework/Versions/A/Modules/Hello.swiftmodule/arm64.private.swiftinterface b/test/fixtures/test-app-symlink-framework/hello-world/lib/Release/Hello.framework/Versions/A/Modules/Hello.swiftmodule/arm64.private.swiftinterface similarity index 100% rename from test/fixtures/test-app-symlink-framework/stripped-native-dep/lib/Release/Hello.framework/Versions/A/Modules/Hello.swiftmodule/arm64.private.swiftinterface rename to test/fixtures/test-app-symlink-framework/hello-world/lib/Release/Hello.framework/Versions/A/Modules/Hello.swiftmodule/arm64.private.swiftinterface diff --git a/test/fixtures/test-app-symlink-framework/stripped-native-dep/lib/Release/Hello.framework/Versions/A/Modules/Hello.swiftmodule/arm64.swiftinterface b/test/fixtures/test-app-symlink-framework/hello-world/lib/Release/Hello.framework/Versions/A/Modules/Hello.swiftmodule/arm64.swiftinterface similarity index 100% rename from test/fixtures/test-app-symlink-framework/stripped-native-dep/lib/Release/Hello.framework/Versions/A/Modules/Hello.swiftmodule/arm64.swiftinterface rename to test/fixtures/test-app-symlink-framework/hello-world/lib/Release/Hello.framework/Versions/A/Modules/Hello.swiftmodule/arm64.swiftinterface diff --git a/test/fixtures/test-app-symlink-framework/stripped-native-dep/lib/Release/Hello.framework/Versions/A/Modules/Hello.swiftmodule/arm64.swiftmodule b/test/fixtures/test-app-symlink-framework/hello-world/lib/Release/Hello.framework/Versions/A/Modules/Hello.swiftmodule/arm64.swiftmodule similarity index 100% rename from test/fixtures/test-app-symlink-framework/stripped-native-dep/lib/Release/Hello.framework/Versions/A/Modules/Hello.swiftmodule/arm64.swiftmodule rename to test/fixtures/test-app-symlink-framework/hello-world/lib/Release/Hello.framework/Versions/A/Modules/Hello.swiftmodule/arm64.swiftmodule diff --git a/test/fixtures/test-app-symlink-framework/stripped-native-dep/lib/Release/Hello.framework/Versions/A/Modules/Hello.swiftmodule/x86_64.private.swiftinterface b/test/fixtures/test-app-symlink-framework/hello-world/lib/Release/Hello.framework/Versions/A/Modules/Hello.swiftmodule/x86_64.private.swiftinterface similarity index 100% rename from test/fixtures/test-app-symlink-framework/stripped-native-dep/lib/Release/Hello.framework/Versions/A/Modules/Hello.swiftmodule/x86_64.private.swiftinterface rename to test/fixtures/test-app-symlink-framework/hello-world/lib/Release/Hello.framework/Versions/A/Modules/Hello.swiftmodule/x86_64.private.swiftinterface diff --git a/test/fixtures/test-app-symlink-framework/stripped-native-dep/lib/Release/Hello.framework/Versions/A/Modules/Hello.swiftmodule/x86_64.swiftinterface b/test/fixtures/test-app-symlink-framework/hello-world/lib/Release/Hello.framework/Versions/A/Modules/Hello.swiftmodule/x86_64.swiftinterface similarity index 100% rename from test/fixtures/test-app-symlink-framework/stripped-native-dep/lib/Release/Hello.framework/Versions/A/Modules/Hello.swiftmodule/x86_64.swiftinterface rename to test/fixtures/test-app-symlink-framework/hello-world/lib/Release/Hello.framework/Versions/A/Modules/Hello.swiftmodule/x86_64.swiftinterface diff --git a/test/fixtures/test-app-symlink-framework/stripped-native-dep/lib/Release/Hello.framework/Versions/A/Modules/Hello.swiftmodule/x86_64.swiftmodule b/test/fixtures/test-app-symlink-framework/hello-world/lib/Release/Hello.framework/Versions/A/Modules/Hello.swiftmodule/x86_64.swiftmodule similarity index 100% rename from test/fixtures/test-app-symlink-framework/stripped-native-dep/lib/Release/Hello.framework/Versions/A/Modules/Hello.swiftmodule/x86_64.swiftmodule rename to test/fixtures/test-app-symlink-framework/hello-world/lib/Release/Hello.framework/Versions/A/Modules/Hello.swiftmodule/x86_64.swiftmodule diff --git a/test/fixtures/test-app-symlink-framework/stripped-native-dep/lib/Release/Hello.framework/Versions/A/Modules/Hello.swiftsourceinfo b/test/fixtures/test-app-symlink-framework/hello-world/lib/Release/Hello.framework/Versions/A/Modules/Hello.swiftsourceinfo similarity index 100% rename from test/fixtures/test-app-symlink-framework/stripped-native-dep/lib/Release/Hello.framework/Versions/A/Modules/Hello.swiftsourceinfo rename to test/fixtures/test-app-symlink-framework/hello-world/lib/Release/Hello.framework/Versions/A/Modules/Hello.swiftsourceinfo diff --git a/test/fixtures/test-app-symlink-framework/stripped-native-dep/lib/Release/Hello.framework/Versions/A/Modules/module.modulemap b/test/fixtures/test-app-symlink-framework/hello-world/lib/Release/Hello.framework/Versions/A/Modules/module.modulemap similarity index 100% rename from test/fixtures/test-app-symlink-framework/stripped-native-dep/lib/Release/Hello.framework/Versions/A/Modules/module.modulemap rename to test/fixtures/test-app-symlink-framework/hello-world/lib/Release/Hello.framework/Versions/A/Modules/module.modulemap diff --git a/test/fixtures/test-app-symlink-framework/stripped-native-dep/lib/Release/Hello.framework/Versions/Current b/test/fixtures/test-app-symlink-framework/hello-world/lib/Release/Hello.framework/Versions/Current similarity index 100% rename from test/fixtures/test-app-symlink-framework/stripped-native-dep/lib/Release/Hello.framework/Versions/Current rename to test/fixtures/test-app-symlink-framework/hello-world/lib/Release/Hello.framework/Versions/Current diff --git a/test/fixtures/test-app-symlink-framework/stripped-native-dep/package.json b/test/fixtures/test-app-symlink-framework/hello-world/package.json similarity index 100% rename from test/fixtures/test-app-symlink-framework/stripped-native-dep/package.json rename to test/fixtures/test-app-symlink-framework/hello-world/package.json diff --git a/test/src/globTest.ts b/test/src/globTest.ts index 146a8b8343b..26b1812a15c 100644 --- a/test/src/globTest.ts +++ b/test/src/globTest.ts @@ -115,6 +115,10 @@ test.ifNotWindows( assertPack("test-app-symlink-framework", { targets: Platform.LINUX.createTarget(DIR_TARGET), + config: { + asarUnpack: ["**/*.framework"], + files: ["!hello-world"] + } }, { isInstallDepsBefore: true, From f864ac175abc2b57cefe3bbff7ceda462ddc866c Mon Sep 17 00:00:00 2001 From: Mike Maietta Date: Mon, 4 Nov 2024 08:43:10 -0800 Subject: [PATCH 12/19] rename to hello-world and regen snapshot --- .../test-app-symlink-framework/package.json | 2 +- test/snapshots/globTest.js.snap | 170 +++--------------- 2 files changed, 28 insertions(+), 144 deletions(-) diff --git a/test/fixtures/test-app-symlink-framework/package.json b/test/fixtures/test-app-symlink-framework/package.json index a7d8e0c10f9..3e23fae548a 100644 --- a/test/fixtures/test-app-symlink-framework/package.json +++ b/test/fixtures/test-app-symlink-framework/package.json @@ -13,6 +13,6 @@ "compression": "store" }, "dependencies": { - "stripped-native-dep": "file:stripped-native-dep" + "hello-world": "file:hello-world" } } diff --git a/test/snapshots/globTest.js.snap b/test/snapshots/globTest.js.snap index 249f26b6e70..ec1f75e4c00 100644 --- a/test/snapshots/globTest.js.snap +++ b/test/snapshots/globTest.js.snap @@ -9855,13 +9855,17 @@ exports[`symlinks everywhere w/ static framework 3`] = ` "link": "index.js", }, "index.js": { - "offset": "58489", + "offset": "64834", "size": 27, }, "node_modules": { "files": { - "stripped-native-dep": { + "hello-world": { "files": { + "hello-world-framework.sh": { + "offset": "0", + "size": 6345, + }, "lib": { "files": { "Release": { @@ -9869,16 +9873,16 @@ exports[`symlinks everywhere w/ static framework 3`] = ` "Hello.framework": { "files": { "Headers": { - "link": "Versions/Current/Headers", + "link": "node_modules/hello-world/lib/Release/Hello.framework/Versions/Current/Headers", }, "Hello": { - "link": "Versions/Current/Hello", + "link": "node_modules/hello-world/lib/Release/Hello.framework/Versions/Current/Hello", }, "Info.plist": { - "link": "Versions/Current/Info.plist", + "link": "node_modules/hello-world/lib/Release/Hello.framework/Versions/Current/Info.plist", }, "Modules": { - "link": "Versions/Current/Modules", + "link": "node_modules/hello-world/lib/Release/Hello.framework/Versions/Current/Modules", }, "Versions": { "files": { @@ -9888,75 +9892,75 @@ exports[`symlinks everywhere w/ static framework 3`] = ` "files": { "HelloFramework.h": { "executable": true, - "offset": "0", + "offset": "6345", "size": 52, }, }, }, "Hello": { "executable": true, - "offset": "52", + "offset": "6397", "size": 16120, }, "Info.plist": { "executable": true, - "offset": "16172", + "offset": "22517", "size": 809, }, "Modules": { "files": { "Hello.abi.json": { "executable": true, - "offset": "16981", + "offset": "23326", "size": 2215, }, "Hello.swiftdoc": { "executable": true, - "offset": "19196", + "offset": "25541", "size": 408, }, "Hello.swiftmodule": { "files": { "arm64.private.swiftinterface": { "executable": true, - "offset": "19604", + "offset": "25949", "size": 435, }, "arm64.swiftinterface": { "executable": true, - "offset": "20039", + "offset": "26384", "size": 435, }, "arm64.swiftmodule": { "executable": true, - "offset": "20474", + "offset": "26819", "size": 17940, }, "x86_64.private.swiftinterface": { "executable": true, - "offset": "38414", + "offset": "44759", "size": 436, }, "x86_64.swiftinterface": { "executable": true, - "offset": "38850", + "offset": "45195", "size": 436, }, "x86_64.swiftmodule": { "executable": true, - "offset": "39286", + "offset": "45631", "size": 17944, }, }, }, "Hello.swiftsourceinfo": { "executable": true, - "offset": "57230", + "offset": "63575", "size": 1064, }, "module.modulemap": { "executable": true, - "offset": "58294", + "offset": "64639", "size": 66, }, }, @@ -9964,7 +9968,7 @@ exports[`symlinks everywhere w/ static framework 3`] = ` }, }, "Current": { - "link": "Versions/A", + "link": "node_modules/hello-world/lib/Release/Hello.framework/Versions/A", }, }, }, @@ -9975,7 +9979,7 @@ exports[`symlinks everywhere w/ static framework 3`] = ` }, }, "package.json": { - "offset": "58360", + "offset": "64705", "size": 129, }, }, @@ -9983,128 +9987,8 @@ exports[`symlinks everywhere w/ static framework 3`] = ` }, }, "package.json": { - "offset": "58516", - "size": 338, - }, - "stripped-native-dep": { - "files": { - "lib": { - "files": { - "Release": { - "files": { - "Hello.framework": { - "files": { - "Headers": { - "link": "Versions/Current/Headers", - }, - "Hello": { - "link": "Versions/Current/Hello", - }, - "Info.plist": { - "link": "Versions/Current/Info.plist", - }, - "Modules": { - "link": "Versions/Current/Modules", - }, - "Versions": { - "files": { - "A": { - "files": { - "Headers": { - "files": { - "HelloFramework.h": { - "executable": true, - "offset": "58854", - "size": 52, - }, - }, - }, - "Hello": { - "executable": true, - "offset": "58906", - "size": 16120, - }, - "Info.plist": { - "executable": true, - "offset": "75026", - "size": 809, - }, - "Modules": { - "files": { - "Hello.abi.json": { - "executable": true, - "offset": "75835", - "size": 2215, - }, - "Hello.swiftdoc": { - "executable": true, - "offset": "78050", - "size": 408, - }, - "Hello.swiftmodule": { - "files": { - "arm64.private.swiftinterface": { - "executable": true, - "offset": "78458", - "size": 435, - }, - "arm64.swiftinterface": { - "executable": true, - "offset": "78893", - "size": 435, - }, - "arm64.swiftmodule": { - "executable": true, - "offset": "79328", - "size": 17940, - }, - "x86_64.private.swiftinterface": { - "executable": true, - "offset": "97268", - "size": 436, - }, - "x86_64.swiftinterface": { - "executable": true, - "offset": "97704", - "size": 436, - }, - "x86_64.swiftmodule": { - "executable": true, - "offset": "98140", - "size": 17944, - }, - }, - }, - "Hello.swiftsourceinfo": { - "executable": true, - "offset": "116084", - "size": 1064, - }, - "module.modulemap": { - "executable": true, - "offset": "117148", - "size": 66, - }, - }, - }, - }, - }, - "Current": { - "link": "Versions/A", - }, - }, - }, - }, - }, - }, - }, - }, - }, - "package.json": { - "offset": "117214", - "size": 129, - }, - }, + "offset": "64861", + "size": 322, }, }, } From 09eb16c6bd06239c372f6edfbd85a5d16e9baf82 Mon Sep 17 00:00:00 2001 From: Mike Maietta Date: Mon, 4 Nov 2024 08:53:36 -0800 Subject: [PATCH 13/19] snapshot --- packages/app-builder-lib/src/asar/asarUtil.ts | 2 - test/snapshots/globTest.js.snap | 103 ++++++++++++------ test/src/globTest.ts | 11 +- 3 files changed, 77 insertions(+), 39 deletions(-) diff --git a/packages/app-builder-lib/src/asar/asarUtil.ts b/packages/app-builder-lib/src/asar/asarUtil.ts index ebd93e4a041..e6bdbf12cbe 100644 --- a/packages/app-builder-lib/src/asar/asarUtil.ts +++ b/packages/app-builder-lib/src/asar/asarUtil.ts @@ -33,8 +33,6 @@ export class AsarPackager { } async pack(fileSets: Array, _packager: PlatformPackager) { - // this.rootForAppFilesWithoutAsar = await this.tmpDir.getTempDir({ prefix: "asar-app" }) - const cancellationToken = new CancellationToken() cancellationToken.on("cancel", () => this.cleanup()) diff --git a/test/snapshots/globTest.js.snap b/test/snapshots/globTest.js.snap index ec1f75e4c00..897d306549f 100644 --- a/test/snapshots/globTest.js.snap +++ b/test/snapshots/globTest.js.snap @@ -9855,16 +9855,47 @@ exports[`symlinks everywhere w/ static framework 3`] = ` "link": "index.js", }, "index.js": { - "offset": "64834", - "size": 27, + "size": "", }, "node_modules": { "files": { + "debug": { + "files": { + "LICENSE": { + "size": "", + }, + "dist": { + "files": { + "debug.js": { + "size": "", + }, + }, + }, + "package.json": { + "size": "", + }, + "src": { + "files": { + "browser.js": { + "size": "", + }, + "common.js": { + "size": "", + }, + "index.js": { + "size": "", + }, + "node.js": { + "size": "", + }, + }, + }, + }, + }, "hello-world": { "files": { "hello-world-framework.sh": { - "offset": "0", - "size": 6345, + "size": "", }, "lib": { "files": { @@ -9892,76 +9923,63 @@ exports[`symlinks everywhere w/ static framework 3`] = ` "files": { "HelloFramework.h": { "executable": true, - "offset": "6345", - "size": 52, + "size": "", }, }, }, "Hello": { "executable": true, - "offset": "6397", - "size": 16120, + "size": "", }, "Info.plist": { "executable": true, - "offset": "22517", - "size": 809, + "size": "", }, "Modules": { "files": { "Hello.abi.json": { "executable": true, - "offset": "23326", - "size": 2215, + "size": "", }, "Hello.swiftdoc": { "executable": true, - "offset": "25541", - "size": 408, + "size": "", }, "Hello.swiftmodule": { "files": { "arm64.private.swiftinterface": { "executable": true, - "offset": "25949", - "size": 435, + "size": "", }, "arm64.swiftinterface": { "executable": true, - "offset": "26384", - "size": 435, + "size": "", }, "arm64.swiftmodule": { "executable": true, - "offset": "26819", - "size": 17940, + "size": "", }, "x86_64.private.swiftinterface": { "executable": true, - "offset": "44759", - "size": 436, + "size": "", }, "x86_64.swiftinterface": { "executable": true, - "offset": "45195", - "size": 436, + "size": "", }, "x86_64.swiftmodule": { "executable": true, - "offset": "45631", - "size": 17944, + "size": "", }, }, }, "Hello.swiftsourceinfo": { "executable": true, - "offset": "63575", - "size": 1064, + "size": "", }, "module.modulemap": { "executable": true, - "offset": "64639", - "size": 66, + "size": "", }, }, }, @@ -9979,21 +9997,38 @@ exports[`symlinks everywhere w/ static framework 3`] = ` }, }, "package.json": { - "offset": "64705", - "size": 129, + "size": "", + }, + }, + }, + "ms": { + "files": { + "index.js": { + "size": "", + }, + "license.md": { + "size": "", + }, + "package.json": { + "size": "", }, }, }, }, }, "package.json": { - "offset": "64861", - "size": 322, + "size": "", }, }, } `; +exports[`symlinks everywhere w/ static framework 4`] = ` +[ + "app.asar", +] +`; + exports[`unpackDir 1`] = ` { "linux": [], diff --git a/test/src/globTest.ts b/test/src/globTest.ts index 26b1812a15c..973e2359fc4 100644 --- a/test/src/globTest.ts +++ b/test/src/globTest.ts @@ -116,19 +116,24 @@ test.ifNotWindows( { targets: Platform.LINUX.createTarget(DIR_TARGET), config: { - asarUnpack: ["**/*.framework"], files: ["!hello-world"] } }, { isInstallDepsBefore: true, - projectDirCreated: projectDir => { + projectDirCreated: async projectDir => { + await modifyPackageJson(projectDir, data => { + data.dependencies = { + debug: "4.1.1", + ...data.dependencies + } + }) return fs.symlink(path.join(projectDir, "index.js"), path.join(projectDir, "foo.js")) }, packed: async context => { const resources = context.getResources(Platform.LINUX) expect((await readAsar(path.join(resources, "app.asar"))).getFile("foo.js", false)).toMatchSnapshot() - await verifyAsarFileTree(resources) + await verifySmartUnpack(resources) }, } ) From 6c0a4b8e31451b7213a2de65bccf349eaabfa51d Mon Sep 17 00:00:00 2001 From: Mike Maietta Date: Mon, 4 Nov 2024 15:45:32 -0800 Subject: [PATCH 14/19] tmp save --- packages/app-builder-lib/package.json | 2 +- pnpm-lock.yaml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/app-builder-lib/package.json b/packages/app-builder-lib/package.json index c1e79ac69ba..ca5903c6fc9 100644 --- a/packages/app-builder-lib/package.json +++ b/packages/app-builder-lib/package.json @@ -48,7 +48,7 @@ "dependencies": { "@develar/schema-utils": "~2.6.5", "@electron/fuses": "^1.8.0", - "@electron/asar": "^3.2.13", + "@electron/asar": "3.2.13", "@electron/notarize": "2.5.0", "@electron/osx-sign": "1.3.1", "@electron/rebuild": "3.7.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index caf52373e6f..d76e81941c5 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -84,7 +84,7 @@ importers: specifier: ~2.6.5 version: 2.6.5 '@electron/asar': - specifier: ^3.2.13 + specifier: 3.2.13 version: 3.2.13 '@electron/fuses': specifier: ^1.8.0 @@ -8723,7 +8723,7 @@ snapshots: '@types/yauzl@2.10.3': dependencies: - '@types/node': 20.16.10 + '@types/node': 22.7.4 optional: true '@typescript-eslint/eslint-plugin@8.7.0(@typescript-eslint/parser@8.7.0(eslint@9.11.1)(typescript@5.6.2))(eslint@9.11.1)(typescript@5.6.2)': From 2620941c69cfa211013236da68bf66ad8f47f810 Mon Sep 17 00:00:00 2001 From: Mike Maietta Date: Mon, 4 Nov 2024 19:11:17 -0800 Subject: [PATCH 15/19] tmp save --- packages/app-builder-lib/src/asar/asarUtil.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/app-builder-lib/src/asar/asarUtil.ts b/packages/app-builder-lib/src/asar/asarUtil.ts index e6bdbf12cbe..b1225d24e00 100644 --- a/packages/app-builder-lib/src/asar/asarUtil.ts +++ b/packages/app-builder-lib/src/asar/asarUtil.ts @@ -126,15 +126,15 @@ export class AsarPackager { throw new Error(`Cannot copy file (${path.basename(file)}) symlinked to file (${path.basename(realPathFile)}) outside the package as that violates asar security integrity`) } - // not a symlink + // not a symlink, copy directly if (file === realPathFile) { return this.fileCopier.copy(file, destFile, stat) } - // must be a symlink + // okay, it must be a symlink. evaluate link to be relative to source file in asar let link = await readlink(file) if (path.isAbsolute(link)) { - link = path.relative(fileSet.src, link) + link = path.relative(path.dirname(file), link) } links.push({ file: destFile, link }) From aeee16529b250ef5bc4b5b2ef66d7154a08976f4 Mon Sep 17 00:00:00 2001 From: Mike Maietta Date: Tue, 5 Nov 2024 08:51:04 -0800 Subject: [PATCH 16/19] use packager cancellation token, cleanup listener, rename function, rename variables --- packages/app-builder-lib/src/asar/asarUtil.ts | 43 +++++++++++-------- 1 file changed, 26 insertions(+), 17 deletions(-) diff --git a/packages/app-builder-lib/src/asar/asarUtil.ts b/packages/app-builder-lib/src/asar/asarUtil.ts index b1225d24e00..66eea6e0bf5 100644 --- a/packages/app-builder-lib/src/asar/asarUtil.ts +++ b/packages/app-builder-lib/src/asar/asarUtil.ts @@ -1,17 +1,17 @@ import { CreateOptions, createPackageWithOptions } from "@electron/asar" import { AsyncTaskManager, log } from "builder-util" import { CancellationToken } from "builder-util-runtime" -import { FileCopier, Filter, Link, MAX_FILE_REQUESTS } from "builder-util/out/fs" +import { FileCopier, Filter, Link, MAX_FILE_REQUESTS, statOrNull } from "builder-util/out/fs" import * as fsNode from "fs" import * as fs from "fs-extra" +import { mkdir, readlink, symlink } from "fs-extra" +import { platform } from "os" import * as path from "path" import * as tempFile from "temp-file" import { AsarOptions } from "../options/PlatformSpecificBuildOptions" import { PlatformPackager } from "../platformPackager" import { ResolvedFileSet, getDestinationPath } from "../util/appFileCopier" import { detectUnpackedDirs } from "./unpackDetector" -import { platform } from "os" -import { mkdir, readlink, symlink } from "fs-extra" /** @internal */ export class AsarPackager { @@ -33,8 +33,8 @@ export class AsarPackager { } async pack(fileSets: Array, _packager: PlatformPackager) { - const cancellationToken = new CancellationToken() - cancellationToken.on("cancel", () => this.cleanup()) + const cancellationToken = _packager.info.cancellationToken + cancellationToken.addListener("cancel", this.cleanup) const orderedFileSets = [ // Write dependencies first to minimize offset changes to asar header @@ -50,6 +50,7 @@ export class AsarPackager { await this.executeElectronAsar(copiedFiles, unpackGlob) this.cleanup() + cancellationToken.removeListener("cancel", this.cleanup) } private async executeElectronAsar(copiedFiles: string[], unpackGlob: string | undefined) { @@ -79,8 +80,10 @@ export class AsarPackager { console.log = consoleLogger } - private cleanup() { - fsNode.rmSync(this.rootForAppFilesWithoutAsar, { recursive: true }) + private readonly cleanup = () => { + if (statOrNull(this.rootForAppFilesWithoutAsar) != null) { + fsNode.rmSync(this.rootForAppFilesWithoutAsar, { recursive: true }) + } this.tmpDir.cleanupSync() } @@ -100,14 +103,20 @@ export class AsarPackager { return } } - const writeFileOrQueueSymlink = async (options: { transformedData: string | Buffer | undefined; file: string; destFile: string; stat: fs.Stats; fileSet: ResolvedFileSet }) => { - const { transformedData, file, destFile, stat, fileSet } = options + const writeFileOrProcessSymlink = async (options: { + file: string + destination: string + stat: fs.Stats + fileSet: ResolvedFileSet + transformedData: string | Buffer | undefined + }) => { + const { transformedData, file, destination, stat, fileSet } = options if (!stat.isFile() && !stat.isSymbolicLink()) { return } - copiedFiles.add(destFile) + copiedFiles.add(destination) - const dir = path.dirname(destFile) + const dir = path.dirname(destination) if (!createdSourceDirs.has(dir)) { await mkdir(dir, { recursive: true }) createdSourceDirs.add(dir) @@ -115,7 +124,7 @@ export class AsarPackager { // write any data if provided, skip symlink check if (transformedData != null) { - return fs.writeFile(destFile, transformedData, { mode: stat.mode }) + return fs.writeFile(destination, transformedData, { mode: stat.mode }) } const realPathFile = await fs.realpath(file) @@ -128,7 +137,7 @@ export class AsarPackager { // not a symlink, copy directly if (file === realPathFile) { - return this.fileCopier.copy(file, destFile, stat) + return this.fileCopier.copy(file, destination, stat) } // okay, it must be a symlink. evaluate link to be relative to source file in asar @@ -137,7 +146,7 @@ export class AsarPackager { link = path.relative(path.dirname(file), link) } - links.push({ file: destFile, link }) + links.push({ file: destination, link }) } for await (const fileSet of fileSets) { @@ -150,10 +159,10 @@ export class AsarPackager { const file = fileSet.files[i] const transformedData = fileSet.transformedFiles?.get(i) const stat = fileSet.metadata.get(file)! - const destFile = getDestinationPath(file, fileSet) + const destination = getDestinationPath(file, fileSet) - matchUnpacker(file, destFile, stat) - taskManager.addTask(writeFileOrQueueSymlink({ transformedData, file, destFile, stat, fileSet })) + matchUnpacker(file, destination, stat) + taskManager.addTask(writeFileOrProcessSymlink({ transformedData, file, destination, stat, fileSet })) if (taskManager.tasks.length > MAX_FILE_REQUESTS) { await taskManager.awaitTasks() From ff1126a61061a5d1687c356cc344c0bc98194596 Mon Sep 17 00:00:00 2001 From: Mike Maietta Date: Tue, 5 Nov 2024 09:34:15 -0800 Subject: [PATCH 17/19] use tmp dir provided via `packager` --- packages/app-builder-lib/src/asar/asarUtil.ts | 24 +++++++++---------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/packages/app-builder-lib/src/asar/asarUtil.ts b/packages/app-builder-lib/src/asar/asarUtil.ts index 66eea6e0bf5..d234c0f50a4 100644 --- a/packages/app-builder-lib/src/asar/asarUtil.ts +++ b/packages/app-builder-lib/src/asar/asarUtil.ts @@ -16,10 +16,14 @@ import { detectUnpackedDirs } from "./unpackDetector" /** @internal */ export class AsarPackager { private readonly outFile: string - private readonly rootForAppFilesWithoutAsar: string + private rootForAppFilesWithoutAsar!: string private readonly tmpDir = new tempFile.TmpDir() private readonly fileCopier = new FileCopier() + private readonly cleanup = () => { + this.tmpDir.cleanupSync() + } + constructor( private readonly config: { defaultDestination: string @@ -29,11 +33,11 @@ export class AsarPackager { } ) { this.outFile = path.join(config.resourcePath, `app.asar`) - this.rootForAppFilesWithoutAsar = path.join(config.resourcePath, "app") } - async pack(fileSets: Array, _packager: PlatformPackager) { - const cancellationToken = _packager.info.cancellationToken + async pack(fileSets: Array, packager: PlatformPackager) { + this.rootForAppFilesWithoutAsar = await packager.info.tempDirManager.getTempDir({ prefix: "asar-app" }) + const cancellationToken = packager.info.cancellationToken cancellationToken.addListener("cancel", this.cleanup) const orderedFileSets = [ @@ -80,13 +84,6 @@ export class AsarPackager { console.log = consoleLogger } - private readonly cleanup = () => { - if (statOrNull(this.rootForAppFilesWithoutAsar) != null) { - fsNode.rmSync(this.rootForAppFilesWithoutAsar, { recursive: true }) - } - this.tmpDir.cleanupSync() - } - private async detectAndCopy(fileSets: ResolvedFileSet[], cancellationToken: CancellationToken) { const taskManager = new AsyncTaskManager(cancellationToken) const unpackedPaths = new Set() @@ -145,7 +142,6 @@ export class AsarPackager { if (path.isAbsolute(link)) { link = path.relative(path.dirname(file), link) } - links.push({ file: destination, link }) } @@ -159,7 +155,9 @@ export class AsarPackager { const file = fileSet.files[i] const transformedData = fileSet.transformedFiles?.get(i) const stat = fileSet.metadata.get(file)! - const destination = getDestinationPath(file, fileSet) + + const relative = path.relative(this.config.defaultDestination, getDestinationPath(file, fileSet)) + const destination = path.resolve(this.rootForAppFilesWithoutAsar, relative) matchUnpacker(file, destination, stat) taskManager.addTask(writeFileOrProcessSymlink({ transformedData, file, destination, stat, fileSet })) From 359a7e6fb07c089b9eafa4730f38fd4523e0a121 Mon Sep 17 00:00:00 2001 From: Mike Maietta Date: Tue, 5 Nov 2024 09:36:57 -0800 Subject: [PATCH 18/19] organize imports --- packages/app-builder-lib/src/asar/asarUtil.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/app-builder-lib/src/asar/asarUtil.ts b/packages/app-builder-lib/src/asar/asarUtil.ts index d234c0f50a4..2e6007e26f6 100644 --- a/packages/app-builder-lib/src/asar/asarUtil.ts +++ b/packages/app-builder-lib/src/asar/asarUtil.ts @@ -1,8 +1,7 @@ import { CreateOptions, createPackageWithOptions } from "@electron/asar" import { AsyncTaskManager, log } from "builder-util" import { CancellationToken } from "builder-util-runtime" -import { FileCopier, Filter, Link, MAX_FILE_REQUESTS, statOrNull } from "builder-util/out/fs" -import * as fsNode from "fs" +import { FileCopier, Filter, Link, MAX_FILE_REQUESTS } from "builder-util/out/fs" import * as fs from "fs-extra" import { mkdir, readlink, symlink } from "fs-extra" import { platform } from "os" From 130a1c2a2a5ca7f867d4e684a3d29ddc90b14fab Mon Sep 17 00:00:00 2001 From: Mike Maietta Date: Tue, 5 Nov 2024 14:06:05 -0800 Subject: [PATCH 19/19] cleanup to use correct tmpdir --- packages/app-builder-lib/src/asar/asarUtil.ts | 25 ++++++++----------- .../app-builder-lib/src/platformPackager.ts | 4 +-- 2 files changed, 12 insertions(+), 17 deletions(-) diff --git a/packages/app-builder-lib/src/asar/asarUtil.ts b/packages/app-builder-lib/src/asar/asarUtil.ts index 2e6007e26f6..790a8179a30 100644 --- a/packages/app-builder-lib/src/asar/asarUtil.ts +++ b/packages/app-builder-lib/src/asar/asarUtil.ts @@ -16,14 +16,12 @@ import { detectUnpackedDirs } from "./unpackDetector" export class AsarPackager { private readonly outFile: string private rootForAppFilesWithoutAsar!: string - private readonly tmpDir = new tempFile.TmpDir() private readonly fileCopier = new FileCopier() - - private readonly cleanup = () => { - this.tmpDir.cleanupSync() - } + private readonly tmpDir: tempFile.TmpDir + private readonly cancellationToken: CancellationToken constructor( + readonly packager: PlatformPackager, private readonly config: { defaultDestination: string resourcePath: string @@ -32,12 +30,12 @@ export class AsarPackager { } ) { this.outFile = path.join(config.resourcePath, `app.asar`) + this.tmpDir = packager.info.tempDirManager + this.cancellationToken = packager.info.cancellationToken } - async pack(fileSets: Array, packager: PlatformPackager) { - this.rootForAppFilesWithoutAsar = await packager.info.tempDirManager.getTempDir({ prefix: "asar-app" }) - const cancellationToken = packager.info.cancellationToken - cancellationToken.addListener("cancel", this.cleanup) + async pack(fileSets: Array) { + this.rootForAppFilesWithoutAsar = await this.tmpDir.getTempDir({ prefix: "asar-app" }) const orderedFileSets = [ // Write dependencies first to minimize offset changes to asar header @@ -47,13 +45,10 @@ export class AsarPackager { fileSets[0], ].map(orderFileSet) - const { unpackedPaths, copiedFiles } = await this.detectAndCopy(orderedFileSets, cancellationToken) + const { unpackedPaths, copiedFiles } = await this.detectAndCopy(orderedFileSets) const unpackGlob = unpackedPaths.length > 1 ? `{${unpackedPaths.join(",")}}` : unpackedPaths.pop() await this.executeElectronAsar(copiedFiles, unpackGlob) - - this.cleanup() - cancellationToken.removeListener("cancel", this.cleanup) } private async executeElectronAsar(copiedFiles: string[], unpackGlob: string | undefined) { @@ -83,8 +78,8 @@ export class AsarPackager { console.log = consoleLogger } - private async detectAndCopy(fileSets: ResolvedFileSet[], cancellationToken: CancellationToken) { - const taskManager = new AsyncTaskManager(cancellationToken) + private async detectAndCopy(fileSets: ResolvedFileSet[]) { + const taskManager = new AsyncTaskManager(this.cancellationToken) const unpackedPaths = new Set() const copiedFiles = new Set() diff --git a/packages/app-builder-lib/src/platformPackager.ts b/packages/app-builder-lib/src/platformPackager.ts index 7edec89fc25..db7e17281be 100644 --- a/packages/app-builder-lib/src/platformPackager.ts +++ b/packages/app-builder-lib/src/platformPackager.ts @@ -504,12 +504,12 @@ export abstract class PlatformPackager await transformFiles(transformer, fileSet) } - await new AsarPackager({ + await new AsarPackager(this, { defaultDestination, resourcePath, options: asarOptions, unpackPattern: fileMatcher?.createFilter(), - }).pack(fileSets, this) + }).pack(fileSets) }) ) }