Skip to content

Commit

Permalink
feat(core): adding register/unregisterForgeConfigForDirectory to utils (
Browse files Browse the repository at this point in the history
  • Loading branch information
IIIMADDINIII authored Sep 19, 2024
1 parent ca6b211 commit 2c081ea
Show file tree
Hide file tree
Showing 5 changed files with 107 additions and 5 deletions.
14 changes: 13 additions & 1 deletion packages/api/core/src/util/forge-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,14 @@ const proxify = <T extends ProxiedObject>(buildIdentifier: string | (() => strin
};
/* eslint-enable @typescript-eslint/no-explicit-any */

export const registeredForgeConfigs: Map<string, ForgeConfig> = new Map();
export function registerForgeConfigForDirectory(dir: string, config: ForgeConfig): void {
registeredForgeConfigs.set(path.resolve(dir), config);
}
export function unregisterForgeConfigForDirectory(dir: string): void {
registeredForgeConfigs.delete(path.resolve(dir));
}

export type BuildIdentifierMap<T> = Record<string, T | undefined>;
export type BuildIdentifierConfig<T> = {
map: BuildIdentifierMap<T>;
Expand Down Expand Up @@ -109,8 +117,12 @@ type MaybeESM<T> = T | { default: T };
type AsyncForgeConfigGenerator = () => Promise<ForgeConfig>;

export default async (dir: string): Promise<ResolvedForgeConfig> => {
let forgeConfig: ForgeConfig | string | null | undefined = registeredForgeConfigs.get(dir);

const packageJSON = await readRawPackageJson(dir);
let forgeConfig: ForgeConfig | string | null = packageJSON.config && packageJSON.config.forge ? packageJSON.config.forge : null;
if (forgeConfig === undefined) {
forgeConfig = packageJSON.config && packageJSON.config.forge ? packageJSON.config.forge : null;
}

if (!forgeConfig || typeof forgeConfig === 'string') {
for (const extension of ['.js', ...Object.keys(interpret.extensions)]) {
Expand Down
26 changes: 25 additions & 1 deletion packages/api/core/src/util/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
import { getElectronVersion, hasYarn, yarnOrNpmSpawn } from '@electron-forge/core-utils';

import { BuildIdentifierConfig, BuildIdentifierMap, fromBuildIdentifier } from './forge-config';
import {
BuildIdentifierConfig,
BuildIdentifierMap,
fromBuildIdentifier,
registerForgeConfigForDirectory,
unregisterForgeConfigForDirectory,
} from './forge-config';

import type { ForgeConfig } from '@electron-forge/shared-types';

export default class ForgeUtils {
/**
Expand All @@ -19,4 +27,20 @@ export default class ForgeUtils {
hasYarn = hasYarn;

yarnOrNpmSpawn = yarnOrNpmSpawn;

/**
* Register a virtual config file for forge to find.
* Takes precedence over other configuration options like a forge.config.js file.
* Dir should point to the folder containing the app.
*/
registerForgeConfigForDirectory(dir: string, config: ForgeConfig): void {
return registerForgeConfigForDirectory(dir, config);
}

/**
* Unregister a forge config previously registered with registerForgeConfigForDirectory.
*/
unregisterForgeConfigForDirectory(dir: string): void {
return unregisterForgeConfigForDirectory(dir);
}
}
9 changes: 7 additions & 2 deletions packages/api/core/src/util/resolve-dir.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { getElectronVersion } from '@electron-forge/core-utils';
import debug from 'debug';
import fs from 'fs-extra';

import { registeredForgeConfigs } from './forge-config';
import { readRawPackageJson } from './read-package-json';

const d = debug('electron-forge:project-resolver');
Expand All @@ -12,15 +13,19 @@ const d = debug('electron-forge:project-resolver');
// and / or forge config then we need to be able to resolve
// the dir without calling getElectronVersion
export default async (dir: string): Promise<string | null> => {
let mDir = dir;
let mDir = path.resolve(dir);
let bestGuessDir: string | null = null;
let lastError: string | null = null;

let prevDir;
while (prevDir !== mDir) {
prevDir = mDir;
const testPath = path.resolve(mDir, 'package.json');
d('searching for project in:', mDir);
if (registeredForgeConfigs.has(mDir)) {
d('virtual config found in:', mDir);
return mDir;
}
const testPath = path.resolve(mDir, 'package.json');
if (await fs.pathExists(testPath)) {
const packageJSON = await readRawPackageJson(mDir);

Expand Down
52 changes: 51 additions & 1 deletion packages/api/core/test/fast/forge-config_spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,12 @@ import path from 'path';
import { ResolvedForgeConfig } from '@electron-forge/shared-types';
import { expect } from 'chai';

import findConfig, { forgeConfigIsValidFilePath, renderConfigTemplate } from '../../src/util/forge-config';
import findConfig, {
forgeConfigIsValidFilePath,
registerForgeConfigForDirectory,
renderConfigTemplate,
unregisterForgeConfigForDirectory,
} from '../../src/util/forge-config';

const defaults = {
packagerConfig: {},
Expand Down Expand Up @@ -47,6 +52,51 @@ describe('forge-config', () => {
expect(config).to.deep.equal(defaults);
});

it('should resolve to the virtual config if present', async () => {
const fixturePath = path.resolve(__dirname, '../fixture/no_forge_config');
try {
registerForgeConfigForDirectory(fixturePath, { outDir: 'magic' });
const config = await findConfig(fixturePath);
delete (config as any).pluginInterface;
expect(config).to.be.deep.equal({
...defaults,
outDir: 'magic',
});
} finally {
unregisterForgeConfigForDirectory(fixturePath);
}
});

it('should resolve virtual config instead of package.json', async () => {
const fixturePath = path.resolve(__dirname, '../fixture/dummy_app');
try {
registerForgeConfigForDirectory(fixturePath, { outDir: 'magic' });
const config = await findConfig(fixturePath);
delete (config as any).pluginInterface;
expect(config).to.be.deep.equal({
...defaults,
outDir: 'magic',
});
} finally {
unregisterForgeConfigForDirectory(fixturePath);
}
});

it('should resolve virtual config instead of forge.config.js', async () => {
const fixturePath = path.resolve(__dirname, '../fixture/async_forge_config');
try {
registerForgeConfigForDirectory(fixturePath, { outDir: 'magic' });
const config = await findConfig(fixturePath);
delete (config as any).pluginInterface;
expect(config).to.be.deep.equal({
...defaults,
outDir: 'magic',
});
} finally {
unregisterForgeConfigForDirectory(fixturePath);
}
});

it('should resolve the object in package.json with defaults if one exists', async () => {
const config = await findConfig(path.resolve(__dirname, '../fixture/dummy_app'));
// eslint-disable-next-line @typescript-eslint/no-explicit-any
Expand Down
11 changes: 11 additions & 0 deletions packages/api/core/test/fast/resolve-dir_spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import path from 'path';

import { expect } from 'chai';

import { registerForgeConfigForDirectory, unregisterForgeConfigForDirectory } from '../../src/util/forge-config';
import resolveDir from '../../src/util/resolve-dir';

describe('resolve-dir', () => {
Expand All @@ -20,4 +21,14 @@ describe('resolve-dir', () => {
expect(await resolveDir(path.resolve(__dirname, '../fixture/dummy_app/foo'))).to.not.be.equal(null);
expect(await resolveDir(path.resolve(__dirname, '../fixture/dummy_app/foo'))).to.be.equal(path.resolve(__dirname, '../fixture/dummy_app'));
});

it('should return a directory if it finds a virtual config', async () => {
try {
registerForgeConfigForDirectory('/foo/var/virtual', {});
expect(await resolveDir('/foo/var/virtual')).to.not.be.equal(null);
expect(await resolveDir(path.resolve(__dirname, '/foo/var/virtual'))).to.be.equal(path.resolve(__dirname, '/foo/var/virtual'));
} finally {
unregisterForgeConfigForDirectory('/foo/var/virtual');
}
});
});

0 comments on commit 2c081ea

Please sign in to comment.