From 82acb6fc723a2787168d77f961fe4707ad34851a Mon Sep 17 00:00:00 2001 From: Niels Leenheer Date: Thu, 19 Nov 2020 18:34:14 +0100 Subject: [PATCH] fix: no asar support (#4), renamed directories (#5) and check if we need to duplicate asar's (#2) (#8) * fix: no asar support (#4), renamed directories (#5) and check if we need to duplicate asar's (#1) * Add missing newline --- entry-asar/has-asar.js | 7 +++++ entry-asar/index.js | 7 ----- entry-asar/no-asar.js | 7 +++++ package.json | 1 + src/index.ts | 63 ++++++++++++++++++++++++++---------------- 5 files changed, 54 insertions(+), 31 deletions(-) create mode 100644 entry-asar/has-asar.js delete mode 100644 entry-asar/index.js create mode 100644 entry-asar/no-asar.js diff --git a/entry-asar/has-asar.js b/entry-asar/has-asar.js new file mode 100644 index 0000000..9e37f7d --- /dev/null +++ b/entry-asar/has-asar.js @@ -0,0 +1,7 @@ +if (process.arch === 'arm64') { + process._archPath = require.resolve('../app-arm64.asar'); +} else { + process._archPath = require.resolve('../app-x64.asar'); +} + +require(process._archPath); diff --git a/entry-asar/index.js b/entry-asar/index.js deleted file mode 100644 index 4cb9dc9..0000000 --- a/entry-asar/index.js +++ /dev/null @@ -1,7 +0,0 @@ -if (process.arch === 'arm64') { - process._asarPath = require.resolve('../arm64.app.asar'); -} else { - process._asarPath = require.resolve('../x64.app.asar'); -} - -require(process._asarPath); diff --git a/entry-asar/no-asar.js b/entry-asar/no-asar.js new file mode 100644 index 0000000..5391363 --- /dev/null +++ b/entry-asar/no-asar.js @@ -0,0 +1,7 @@ +if (process.arch === 'arm64') { + process._archPath = require.resolve('../app-arm64'); +} else { + process._archPath = require.resolve('../app-x64'); +} + +require(process._archPath); diff --git a/package.json b/package.json index ba4b0ec..2b2dde9 100644 --- a/package.json +++ b/package.json @@ -38,6 +38,7 @@ "dependencies": { "@malept/cross-spawn-promise": "^1.1.0", "asar": "^3.0.3", + "dir-compare": "^2.4.0", "fs-extra": "^9.0.1" } } diff --git a/src/index.ts b/src/index.ts index 0a22e79..b8fb994 100644 --- a/src/index.ts +++ b/src/index.ts @@ -4,6 +4,7 @@ import * as crypto from 'crypto'; import * as fs from 'fs-extra'; import * as os from 'os'; import * as path from 'path'; +import * as dircompare from 'dir-compare'; const MACHO_PREFIX = 'Mach-O '; @@ -174,34 +175,48 @@ export const makeUniversalApp = async (opts: MakeUniversalOpts): Promise = } if (x64AsarMode === AsarMode.NO_ASAR) { - await fs.move(path.resolve(tmpApp, 'Contents', 'Resources', 'app'), path.resolve(tmpApp, 'Contents', 'Resources', 'x64.app')); - await fs.copy(path.resolve(opts.arm64AppPath, 'Contents', 'Resources', 'app'), path.resolve(tmpApp, 'Contents', 'Resources', 'arm64.app')); - } else { - await fs.move(path.resolve(tmpApp, 'Contents', 'Resources', 'app.asar'), path.resolve(tmpApp, 'Contents', 'Resources', 'x64.app.asar')); - const x64Unpacked = path.resolve(tmpApp, 'Contents', 'Resources', 'app.asar.unpacked'); - if (await fs.pathExists(x64Unpacked)) { - await fs.move(x64Unpacked, path.resolve(tmpApp, 'Contents', 'Resources', 'x64.app.asar.unpacked')); - } - - await fs.copy(path.resolve(opts.arm64AppPath, 'Contents', 'Resources', 'app.asar'), path.resolve(tmpApp, 'Contents', 'Resources', 'arm64.app.asar')); - const arm64Unpacked = path.resolve(opts.arm64AppPath, 'Contents', 'Resources', 'app.asar.unpacked'); - if (await fs.pathExists(arm64Unpacked)) { - await fs.copy(arm64Unpacked, path.resolve(tmpApp, 'Contents', 'Resources', 'arm64.app.asar.unpacked')); + const comparison = dircompare.compareSync(path.resolve(tmpApp, 'Contents', 'Resources', 'app'), path.resolve(opts.arm64AppPath, 'Contents', 'Resources', 'app'), { compareSize: true, compareContent: true }); + + if (!comparison.same) { + await fs.move(path.resolve(tmpApp, 'Contents', 'Resources', 'app'), path.resolve(tmpApp, 'Contents', 'Resources', 'app-x64')); + await fs.copy(path.resolve(opts.arm64AppPath, 'Contents', 'Resources', 'app'), path.resolve(tmpApp, 'Contents', 'Resources', 'app-arm64')); + + const entryAsar = path.resolve(tmpDir, 'entry-asar'); + await fs.mkdir(entryAsar); + await fs.copy(path.resolve(__dirname, '..', '..', 'entry-asar', 'no-asar.js'), path.resolve(entryAsar, 'index.js')); + let pj = await fs.readJson(path.resolve(opts.x64AppPath, 'Contents', 'Resources', 'app', 'package.json')); + pj.main = 'index.js'; + await fs.writeJson(path.resolve(entryAsar, 'package.json'), pj); + await asar.createPackage(entryAsar, path.resolve(tmpApp, 'Contents', 'Resources', 'app.asar')); } } - const entryAsar = path.resolve(tmpDir, 'entry-asar'); - await fs.mkdir(entryAsar); - await fs.copy(path.resolve(__dirname, '..', '..', 'entry-asar', 'index.js'), path.resolve(entryAsar, 'index.js')); - let pj: any; - if (x64AsarMode === AsarMode.NO_ASAR) { - pj = await fs.readJson(path.resolve(opts.x64AppPath, 'Contents', 'Resources', 'app', 'package.json')); - } else { - pj = JSON.parse((await asar.extractFile(path.resolve(opts.x64AppPath, 'Contents', 'Resources', 'app.asar'), 'package.json')).toString('utf8')); + if (x64AsarMode === AsarMode.HAS_ASAR) { + const x64AsarSha = await sha(path.resolve(tmpApp, 'Contents', 'Resources', 'app.asar')); + const arm64AsarSha = await sha(path.resolve(opts.arm64AppPath, 'Contents', 'Resources', 'app.asar')); + + if (x64AsarSha !== arm64AsarSha) { + await fs.move(path.resolve(tmpApp, 'Contents', 'Resources', 'app.asar'), path.resolve(tmpApp, 'Contents', 'Resources', 'app-x64.asar')); + const x64Unpacked = path.resolve(tmpApp, 'Contents', 'Resources', 'app.asar.unpacked'); + if (await fs.pathExists(x64Unpacked)) { + await fs.move(x64Unpacked, path.resolve(tmpApp, 'Contents', 'Resources', 'app-x64.asar.unpacked')); + } + + await fs.copy(path.resolve(opts.arm64AppPath, 'Contents', 'Resources', 'app.asar'), path.resolve(tmpApp, 'Contents', 'Resources', 'app-arm64.asar')); + const arm64Unpacked = path.resolve(opts.arm64AppPath, 'Contents', 'Resources', 'app.asar.unpacked'); + if (await fs.pathExists(arm64Unpacked)) { + await fs.copy(arm64Unpacked, path.resolve(tmpApp, 'Contents', 'Resources', 'app-arm64.asar.unpacked')); + } + + const entryAsar = path.resolve(tmpDir, 'entry-asar'); + await fs.mkdir(entryAsar); + await fs.copy(path.resolve(__dirname, '..', '..', 'entry-asar', 'has-asar.js'), path.resolve(entryAsar, 'index.js')); + let pj = JSON.parse((await asar.extractFile(path.resolve(opts.x64AppPath, 'Contents', 'Resources', 'app.asar'), 'package.json')).toString('utf8')); + pj.main = 'index.js'; + await fs.writeJson(path.resolve(entryAsar, 'package.json'), pj); + await asar.createPackage(entryAsar, path.resolve(tmpApp, 'Contents', 'Resources', 'app.asar')); + } } - pj.main = 'index.js'; - await fs.writeJson(path.resolve(entryAsar, 'package.json'), pj); - await asar.createPackage(entryAsar, path.resolve(tmpApp, 'Contents', 'Resources', 'app.asar')); for (const snapshotsFile of arm64Files.filter(f => f.type === AppFileType.SNAPSHOT)) { await fs.copy(path.resolve(opts.arm64AppPath, snapshotsFile.relativePath), path.resolve(tmpApp, snapshotsFile.relativePath));