Skip to content

Commit

Permalink
cleanup merge conflict overwrites
Browse files Browse the repository at this point in the history
  • Loading branch information
mmaietta committed Feb 22, 2025
1 parent 70dd4ab commit 61eb5ac
Show file tree
Hide file tree
Showing 3 changed files with 127 additions and 113 deletions.
6 changes: 3 additions & 3 deletions jest.setup.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import * as fs from 'fs-extra';
import * as path from 'path';
import { appsPath, asarsDir, templateApp } from './test/util';
import { appsDir, asarsDir, templateApp } from './test/util';

export default async () => {
await fs.remove(appsPath);
await fs.mkdirp(appsPath);
await fs.remove(appsDir);
await fs.mkdirp(appsDir);
await templateApp('Arm64Asar.app', 'arm64', async (appPath) => {
await fs.copy(
path.resolve(asarsDir, 'app.asar'),
Expand Down
220 changes: 117 additions & 103 deletions test/index.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,12 @@ import * as fs from 'fs-extra';
import * as path from 'path';

import { makeUniversalApp } from '../dist/cjs/index';
import {
appsPath,
appsOutPath,
createTestApp,
templateApp,
VERIFY_APP_TIMEOUT,
verifyApp,
} from './util';
import { createTestApp, templateApp, VERIFY_APP_TIMEOUT, verifyApp } from './util';
import { createPackage, createPackageWithOptions } from '@electron/asar';

const appsPath = path.resolve(__dirname, 'fixtures', 'apps');
const appsOutPath = path.resolve(__dirname, 'fixtures', 'apps', 'out');

// See `jest.setup.ts` for app fixture setup process
describe('makeUniversalApp', () => {
afterEach(async () => {
Expand Down Expand Up @@ -160,110 +156,128 @@ describe('makeUniversalApp', () => {
},
VERIFY_APP_TIMEOUT,
);
it('should generate AsarIntegrity for all asars in the application', async () => {
const { testPath } = await createTestApp('app-2');
const testAsarPath = path.resolve(appsOutPath, 'app-2.asar');
await createPackage(testPath, testAsarPath);

const arm64AppPath = await templateApp('Arm64-2.app', 'arm64', async (appPath) => {
await fs.copyFile(testAsarPath, path.resolve(appPath, 'Contents', 'Resources', 'app.asar'));
await fs.copyFile(
testAsarPath,
path.resolve(appPath, 'Contents', 'Resources', 'webapp.asar'),
);
});
const x64AppPath = await templateApp('X64-2.app', 'x64', async (appPath) => {
await fs.copyFile(testAsarPath, path.resolve(appPath, 'Contents', 'Resources', 'app.asar'));
await fs.copyFile(
testAsarPath,
path.resolve(appPath, 'Contents', 'Resources', 'webbapp.asar'),
);
});
const outAppPath = path.resolve(appsOutPath, 'MultipleAsars.app');
// TODO: Investigate if this should even be allowed.
// Current logic detects all unpacked files as APP_CODE, which doesn't seem correct since it could also be a macho file requiring lipo
// https://github.com/electron/universal/blob/d90d573ccf69a5b14b91aa818c8b97e0e6840399/src/file-utils.ts#L48-L49
it.skip(
'should shim asars with different unpacked dirs',
async () => {
const arm64AppPath = await templateApp('UnpackedArm64.app', 'arm64', async (appPath) => {
const { testPath } = await createTestApp('UnpackedAppArm64');
await createPackageWithOptions(
testPath,
path.resolve(appPath, 'Contents', 'Resources', 'app.asar'),
{
unpackDir: 'var',
unpack: '*.txt',
},
);
});

it(
'should shim asars with different unpacked dirs',
async () => {
const arm64AppPath = await templateApp('UnpackedArm64.app', 'arm64', async (appPath) => {
const { testPath } = await createTestApp('UnpackedAppArm64');
await createPackageWithOptions(
testPath,
path.resolve(appPath, 'Contents', 'Resources', 'app.asar'),
{
unpackDir: 'var',
unpack: '*.txt',
},
);
});
const x64AppPath = await templateApp('UnpackedX64.app', 'x64', async (appPath) => {
const { testPath } = await createTestApp('UnpackedAppX64');
await createPackageWithOptions(
testPath,
path.resolve(appPath, 'Contents', 'Resources', 'app.asar'),
{},
);
});

const x64AppPath = await templateApp('UnpackedX64.app', 'x64', async (appPath) => {
const { testPath } = await createTestApp('UnpackedAppX64');
await createPackageWithOptions(
testPath,
path.resolve(appPath, 'Contents', 'Resources', 'app.asar'),
{},
);
});
const outAppPath = path.resolve(appsOutPath, 'UnpackedDir.app');
await makeUniversalApp({
x64AppPath,
arm64AppPath,
outAppPath,
});
await verifyApp(outAppPath);
},
VERIFY_APP_TIMEOUT,
);

const outAppPath = path.resolve(appsOutPath, 'UnpackedDir.app');
await makeUniversalApp({
x64AppPath,
arm64AppPath,
outAppPath,
mergeASARs: true,
});
await verifyApp(outAppPath);
},
VERIFY_APP_TIMEOUT,
);
});
it(
'should generate AsarIntegrity for all asars in the application',
async () => {
const { testPath } = await createTestApp('app-2');
const testAsarPath = path.resolve(appsOutPath, 'app-2.asar');
await createPackage(testPath, testAsarPath);

describe('no asar mode', () => {
it(
'should correctly merge two identical app folders',
async () => {
const out = path.resolve(appsOutPath, 'MergedNoAsar.app');
await makeUniversalApp({
x64AppPath: path.resolve(appsPath, 'X64NoAsar.app'),
arm64AppPath: path.resolve(appsPath, 'Arm64NoAsar.app'),
outAppPath: out,
});
await verifyApp(out);
},
VERIFY_APP_TIMEOUT,
);
const arm64AppPath = await templateApp('Arm64-2.app', 'arm64', async (appPath) => {
await fs.copyFile(
testAsarPath,
path.resolve(appPath, 'Contents', 'Resources', 'app.asar'),
);
await fs.copyFile(
testAsarPath,
path.resolve(appPath, 'Contents', 'Resources', 'webapp.asar'),
);
});
const x64AppPath = await templateApp('X64-2.app', 'x64', async (appPath) => {
await fs.copyFile(
testAsarPath,
path.resolve(appPath, 'Contents', 'Resources', 'app.asar'),
);
await fs.copyFile(
testAsarPath,
path.resolve(appPath, 'Contents', 'Resources', 'webbapp.asar'),
);
});
const outAppPath = path.resolve(appsOutPath, 'MultipleAsars.app');
await makeUniversalApp({
x64AppPath,
arm64AppPath,
outAppPath,
mergeASARs: true,
});
await verifyApp(outAppPath);
},
VERIFY_APP_TIMEOUT,
);
});

it(
'should shim two different app folders',
async () => {
const arm64AppPath = await templateApp('ShimArm64.app', 'arm64', async (appPath) => {
const { testPath } = await createTestApp('shimArm64', {
'i-aint-got-no-rhythm.bin': 'boomshakalaka',
});
await fs.copy(testPath, path.resolve(appPath, 'Contents', 'Resources', 'app'));
});
describe('no asar mode', () => {
it(
'should correctly merge two identical app folders',
async () => {
const out = path.resolve(appsOutPath, 'MergedNoAsar.app');
await makeUniversalApp({
x64AppPath: path.resolve(appsPath, 'X64NoAsar.app'),
arm64AppPath: path.resolve(appsPath, 'Arm64NoAsar.app'),
outAppPath: out,
});
await verifyApp(out);
},
VERIFY_APP_TIMEOUT,
);

const x64AppPath = await templateApp('ShimX64.app', 'x64', async (appPath) => {
const { testPath } = await createTestApp('shimX64', {
'hello-world.bin': 'Hello World',
});
await fs.copy(testPath, path.resolve(appPath, 'Contents', 'Resources', 'app'));
it(
'should shim two different app folders',
async () => {
const arm64AppPath = await templateApp('ShimArm64.app', 'arm64', async (appPath) => {
const { testPath } = await createTestApp('shimArm64', {
'i-aint-got-no-rhythm.bin': 'boomshakalaka',
});
await fs.copy(testPath, path.resolve(appPath, 'Contents', 'Resources', 'app'));
});

const outAppPath = path.resolve(appsOutPath, 'ShimNoAsar.app');
await makeUniversalApp({
x64AppPath,
arm64AppPath,
outAppPath,
});
await verifyApp(outAppPath);
},
VERIFY_APP_TIMEOUT,
);
});
const x64AppPath = await templateApp('ShimX64.app', 'x64', async (appPath) => {
const { testPath } = await createTestApp('shimX64', { 'hello-world.bin': 'Hello World' });
await fs.copy(testPath, path.resolve(appPath, 'Contents', 'Resources', 'app'));
});

// TODO: Add tests for
// * different app dirs with different macho files
// * identical app dirs with universal macho files
const outAppPath = path.resolve(appsOutPath, 'ShimNoAsar.app');
await makeUniversalApp({
x64AppPath,
arm64AppPath,
outAppPath,
});
await verifyApp(outAppPath);
},
VERIFY_APP_TIMEOUT,
);
});

// TODO: Add tests for
// * different app dirs with different macho files
// * identical app dirs with universal macho files
});
14 changes: 7 additions & 7 deletions test/util.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
import { getRawHeader } from '@electron/asar';
import { downloadArtifact } from '@electron/get';
import { spawn } from '@malept/cross-spawn-promise';
import * as zip from 'cross-zip';
import * as fs from 'fs-extra';
import * as path from 'path';
import plist from 'plist';
import * as fileUtils from '../dist/cjs/file-utils';
import { getRawHeader } from '@electron/asar';

// We do a LOT of verifications in `verifyApp` 😅
// exec universal binary -> verify ALL asars -> verify ALL app dirs -> verify ALL asar integrity entries
// plus some tests create fixtures at runtime
export const VERIFY_APP_TIMEOUT = 80 * 1000;

export const asarsDir = path.resolve(__dirname, 'fixtures', 'asars');
export const appsPath = path.resolve(__dirname, 'fixtures', 'apps');
export const appsOutPath = path.resolve(appsPath, 'out');
export const appsDir = path.resolve(__dirname, 'fixtures', 'apps');
export const appsOutPath = path.resolve(appsDir, 'out');

export const verifyApp = async (appPath: string) => {
await ensureUniversal(appPath);
Expand Down Expand Up @@ -130,7 +130,7 @@ export const createTestApp = async (
additionalFiles: Record<string, string> = {},
) => {
const outDir = (testName || 'app') + Math.floor(Math.random() * 100); // tests run in parallel, randomize dir suffix to prevent naming collisions
const testPath = path.join(appsPath, outDir);
const testPath = path.join(appsDir, outDir);
await fs.remove(testPath);

await fs.copy(path.join(asarsDir, 'app'), testPath);
Expand Down Expand Up @@ -171,9 +171,9 @@ export const templateApp = async (
platform: 'darwin',
arch,
});
const appPath = path.resolve(appsPath, name);
zip.unzipSync(electronZip, appsPath);
await fs.rename(path.resolve(appsPath, 'Electron.app'), appPath);
const appPath = path.resolve(appsDir, name);
zip.unzipSync(electronZip, appsDir);
await fs.rename(path.resolve(appsDir, 'Electron.app'), appPath);
await fs.remove(path.resolve(appPath, 'Contents', 'Resources', 'default_app.asar'));
await modify(appPath);

Expand Down

0 comments on commit 61eb5ac

Please sign in to comment.