Skip to content

Commit

Permalink
Merge branch 'main' into pnpmpnpmpnpmpnpm
Browse files Browse the repository at this point in the history
  • Loading branch information
erickzhao authored Jan 29, 2025
2 parents dacb4e5 + f084010 commit 3dc34f3
Show file tree
Hide file tree
Showing 23 changed files with 196 additions and 113 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@
"find-up": "^5.0.0",
"form-data": "^4.0.0",
"fs-extra": "^10.0.0",
"global-dirs": "^3.0.0",
"got": "^11.8.5",
"html-webpack-plugin": "^5.5.3",
"interpret": "^3.1.1",
Expand All @@ -67,7 +68,6 @@
"node-fetch": "^2.6.7",
"parse-author": "^2.0.0",
"rechoir": "^0.8.0",
"resolve-package": "^1.0.1",
"semver": "^7.2.1",
"source-map-support": "^0.5.13",
"sudo-prompt": "^9.1.1",
Expand Down
5 changes: 3 additions & 2 deletions packages/api/core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,12 @@
"@electron-forge/maker-squirrel": "7.6.1",
"@electron-forge/maker-wix": "7.6.1",
"@electron-forge/maker-zip": "7.6.1",
"@electron-forge/template-fixture": "file:./spec/fixture/electron-forge-template-fixture",
"@electron-forge/test-utils": "7.6.1",
"@types/interpret": "^1.1.1",
"@types/progress": "^2.0.5",
"@types/rechoir": "^0.6.1",
"cross-env": "^7.0.2",
"electron-forge-template-fixture-two": "file:./spec/fixture/electron-forge-template-fixture",
"electron-installer-common": "^0.10.2",
"vitest": "^3.0.3",
"yaml-hook": "^1.0.0"
Expand Down Expand Up @@ -49,14 +50,14 @@
"filenamify": "^4.1.0",
"find-up": "^5.0.0",
"fs-extra": "^10.0.0",
"global-dirs": "^3.0.0",
"got": "^11.8.5",
"interpret": "^3.1.1",
"listr2": "^7.0.2",
"lodash": "^4.17.20",
"log-symbols": "^4.0.0",
"node-fetch": "^2.6.7",
"rechoir": "^0.8.0",
"resolve-package": "^1.0.1",
"semver": "^7.2.1",
"source-map-support": "^0.5.13",
"sudo-prompt": "^9.1.1",
Expand Down
57 changes: 57 additions & 0 deletions packages/api/core/spec/fast/find-template.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import path from 'node:path';

import { describe, expect, it, vi } from 'vitest';

import { findTemplate } from '../../src/api/init-scripts/find-template';

describe('findTemplate', () => {
/**
* Note: this test suite does not mock `require.resolve`. Instead, it uses
* fixture dependencies defined in this module's package.json file to
* actually resolve a local template.
*
* If you modify the fixtures, you may need to re-run `yarn install` in order
* for the fixtures to be installed in your local `node_modules`.
*/
describe('local modules', () => {
it('should find an @electron-forge/template based on name', async () => {
await expect(findTemplate('fixture')).resolves.toEqual({ name: 'electron-forge-template-fixture' });
});
it('should find an @electron-forge/template based on name', async () => {
await expect(findTemplate('fixture-two')).resolves.toEqual({ name: 'electron-forge-template-fixture' });
});
it('should find an @electron-forge/template based on name', async () => {
await expect(findTemplate('electron-forge-template-fixture-two')).resolves.toEqual({ name: 'electron-forge-template-fixture' });
});
});

/**
* For global modules, we re-route the global NPM `node_modules` directory to
* a folder in our fixture directory. Note that the folder _needs_ to be called
* `node_modules` in order for the `require.resolve` custom path to work.
*/
describe('global modules', () => {
vi.mock(import('global-dirs'), async (importOriginal) => {
const mod = await importOriginal();
return {
default: {
...mod.default,
npm: {
...mod.default.npm,
packages: path.resolve(__dirname, '..', 'fixture', 'global-stub', 'node_modules'),
},
},
};
});
it('should find an @electron-forge/template based on name', async () => {
await expect(findTemplate('global')).resolves.toEqual({ name: 'electron-forge-template-fixture-global' });
});
it('should find an electron-forge-template based on name', async () => {
await expect(findTemplate('global-two')).resolves.toEqual({ name: 'electron-forge-template-fixture-global' });
});
});

it('should error if there are no valid templates', async () => {
await expect(findTemplate('non-existent-template')).rejects.toThrowError('Failed to locate custom template: "non-existent-template".');
});
});
4 changes: 2 additions & 2 deletions packages/api/core/spec/fixture/custom_init/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ const fs = require('fs-extra');

module.exports = {
requiredForgeVersion: '>= 6.0.0-beta.1',
dependencies: ['debug'],
devDependencies: ['lodash'],
dependencies: [...baseTemplate.dependencies, 'debug'],
devDependencies: [...baseTemplate.devDependencies, 'lodash'],
initializeTemplate: async (directory) => {
const tasks = await baseTemplate.initializeTemplate(directory, {});
return [
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
module.exports = { name: 'electron-forge-template-fixture' };
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"main": "index.js",
"type": "commonjs",
"version": "13.3.7"
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

32 changes: 19 additions & 13 deletions packages/api/core/src/api/init-scripts/find-template.ts
Original file line number Diff line number Diff line change
@@ -1,28 +1,35 @@
import { ForgeTemplate } from '@electron-forge/shared-types';
import debug from 'debug';
import resolvePackage from 'resolve-package';
import globalDirs from 'global-dirs';

import { PossibleModule } from '../../util/import-search';

const d = debug('electron-forge:init:find-template');

export const findTemplate = async (dir: string, template: string): Promise<ForgeTemplate> => {
enum TemplateType {
global = 'global',
local = 'local',
}

export const findTemplate = async (template: string): Promise<ForgeTemplate> => {
let templateModulePath!: string;
const resolveTemplateTypes = [
['global', `electron-forge-template-${template}`],
['global', `@electron-forge/template-${template}`],
['local', `electron-forge-template-${template}`],
['local', `@electron-forge/template-${template}`],
['local', template],
[TemplateType.global, `electron-forge-template-${template}`],
[TemplateType.global, `@electron-forge/template-${template}`],
[TemplateType.local, `electron-forge-template-${template}`],
[TemplateType.local, `@electron-forge/template-${template}`],
[TemplateType.global, template],
[TemplateType.local, template],
];
let foundTemplate = false;
for (const [templateType, moduleName] of resolveTemplateTypes) {
try {
d(`Trying ${templateType} template: ${moduleName}`);
if (templateType === 'global') {
templateModulePath = await resolvePackage(moduleName);
if (templateType === TemplateType.global) {
templateModulePath = require.resolve(moduleName, {
paths: [globalDirs.npm.packages, globalDirs.yarn.packages],
});
} else {
// local
templateModulePath = require.resolve(moduleName);
}
foundTemplate = true;
Expand All @@ -37,8 +44,7 @@ export const findTemplate = async (dir: string, template: string): Promise<Forge

d(`found template module at: ${templateModulePath}`);

// eslint-disable-next-line @typescript-eslint/no-require-imports
const templateModule: PossibleModule<ForgeTemplate> = require(templateModulePath);
const templateModule: PossibleModule<ForgeTemplate> = await import(templateModulePath);

return templateModule.default || templateModule;
return templateModule.default ?? templateModule;
};
4 changes: 2 additions & 2 deletions packages/api/core/src/api/init.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ export default async ({ dir = process.cwd(), interactive = false, copyCIFiles =
{
title: `Locating custom template: "${template}"`,
task: async (ctx) => {
ctx.templateModule = await findTemplate(dir, template);
ctx.templateModule = await findTemplate(template);
},
},
{
Expand All @@ -86,7 +86,7 @@ export default async ({ dir = process.cwd(), interactive = false, copyCIFiles =
title: 'Initializing template',
task: async ({ templateModule }, task) => {
if (typeof templateModule.initializeTemplate === 'function') {
const tasks = await templateModule.initializeTemplate(dir, { copyCIFiles });
const tasks = await templateModule.initializeTemplate(dir, { copyCIFiles, force });
if (tasks) {
return task.newListr(tasks, { concurrent: false });
}
Expand Down
20 changes: 18 additions & 2 deletions packages/template/base/src/BaseTemplate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,23 @@ export class BaseTemplate implements ForgeTemplate {

public requiredForgeVersion = currentForgeVersion;

get dependencies(): string[] {
const packageJSONPath = path.join(this.templateDir, 'package.json');
if (fs.pathExistsSync(packageJSONPath)) {
const deps = fs.readJsonSync(packageJSONPath).dependencies;
if (deps) {
return Object.entries(deps).map(([packageName, version]) => {
if (version === 'ELECTRON_FORGE/VERSION') {
version = `^${currentForgeVersion}`;
}
return `${packageName}@${version}`;
});
}
}

return [];
}

get devDependencies(): string[] {
const packageJSONPath = path.join(this.templateDir, 'package.json');
if (fs.pathExistsSync(packageJSONPath)) {
Expand Down Expand Up @@ -78,8 +95,7 @@ export class BaseTemplate implements ForgeTemplate {
}

async copyTemplateFile(destDir: string, basename: string): Promise<void> {
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
await this.copy(path.join(this.templateDir!, basename), path.resolve(destDir, basename));
await this.copy(path.join(this.templateDir, basename), path.resolve(destDir, basename));
}

async initializePackageJSON(directory: string): Promise<void> {
Expand Down
7 changes: 3 additions & 4 deletions packages/template/base/tmpl/index.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import { app, BrowserWindow } from 'electron';
import path from 'node:path';
import started from 'electron-squirrel-startup';
const { app, BrowserWindow } = require('electron');
const path = require('node:path');

// Handle creating/removing shortcuts on Windows when installing/uninstalling.
if (started) {
if (require('electron-squirrel-startup')) {
app.quit();
}

Expand Down
4 changes: 0 additions & 4 deletions packages/template/base/tmpl/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,6 @@
"make": "electron-forge make",
"publish": "electron-forge publish"
},
"devDependencies": {
"@electron/fuses": "^1.7.0",
"@electron-forge/plugin-fuses": "^7.2.0"
},
"keywords": [],
"author": "",
"license": "MIT"
Expand Down
2 changes: 0 additions & 2 deletions packages/template/vite-typescript/tmpl/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
{
"devDependencies": {
"@electron/fuses": "^1.7.0",
"@electron-forge/plugin-fuses": "ELECTRON_FORGE/VERSION",
"@electron-forge/plugin-vite": "ELECTRON_FORGE/VERSION",
"@typescript-eslint/eslint-plugin": "^5.0.0",
"@typescript-eslint/parser": "^5.0.0",
Expand Down
3 changes: 2 additions & 1 deletion packages/template/vite/src/ViteTemplate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ class ViteTemplate extends BaseTemplate {
await this.copyTemplateFile(directory, 'vite.renderer.config.mjs');
await this.copyTemplateFile(path.join(directory, 'src'), 'renderer.js');
await this.copyTemplateFile(path.join(directory, 'src'), 'preload.js');
await this.copyTemplateFile(path.join(directory, 'src'), 'index.js');

await this.updateFileByLine(
path.resolve(directory, 'src', 'index.js'),
Expand All @@ -42,7 +43,7 @@ class ViteTemplate extends BaseTemplate {

// TODO: Compatible with any path entry.
// Vite uses index.html under the root path as the entry point.
fs.moveSync(path.join(directory, 'src', 'index.html'), path.join(directory, 'index.html'));
fs.moveSync(path.join(directory, 'src', 'index.html'), path.join(directory, 'index.html'), { overwrite: options.force });
await this.updateFileByLine(path.join(directory, 'index.html'), (line) => {
if (line.includes('link rel="stylesheet"')) return '';
if (line.includes('</body>')) return ' <script type="module" src="/src/renderer.js"></script>\n </body>';
Expand Down
52 changes: 52 additions & 0 deletions packages/template/vite/tmpl/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import { app, BrowserWindow } from 'electron';
import path from 'node:path';
import started from 'electron-squirrel-startup';

// Handle creating/removing shortcuts on Windows when installing/uninstalling.
if (started) {
app.quit();
}

const createWindow = () => {
// Create the browser window.
const mainWindow = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
preload: path.join(__dirname, 'preload.js'),
},
});

// and load the index.html of the app.
mainWindow.loadFile(path.join(__dirname, 'index.html'));

// Open the DevTools.
mainWindow.webContents.openDevTools();
};

// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
// Some APIs can only be used after this event occurs.
app.whenReady().then(() => {
createWindow();

// On OS X it's common to re-create a window in the app when the
// dock icon is clicked and there are no other windows open.
app.on('activate', () => {
if (BrowserWindow.getAllWindows().length === 0) {
createWindow();
}
});
});

// Quit when all windows are closed, except on macOS. There, it's common
// for applications and their menu bar to stay active until the user quits
// explicitly with Cmd + Q.
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
app.quit();
}
});

// In this file you can include the rest of your app's specific main process
// code. You can also put them in separate files and import them here.
1 change: 0 additions & 1 deletion packages/template/vite/tmpl/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
{
"devDependencies": {
"@electron/fuses": "^1.7.0",
"@electron-forge/plugin-fuses": "ELECTRON_FORGE/VERSION",
"@electron-forge/plugin-vite": "ELECTRON_FORGE/VERSION",
"vite": "^5.0.12"
}
Expand Down
2 changes: 0 additions & 2 deletions packages/template/webpack-typescript/tmpl/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
{
"devDependencies": {
"@electron/fuses": "^1.7.0",
"@electron-forge/plugin-fuses": "ELECTRON_FORGE/VERSION",
"@electron-forge/plugin-webpack": "ELECTRON_FORGE/VERSION",
"@typescript-eslint/eslint-plugin": "^5.0.0",
"@typescript-eslint/parser": "^5.0.0",
Expand Down
1 change: 1 addition & 0 deletions packages/utils/types/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,7 @@ export type StartResult = InnerStartResult | { tasks: ForgeListrTaskDefinition[]

export interface InitTemplateOptions {
copyCIFiles?: boolean;
force?: boolean;
}

// eslint-disable-next-line @typescript-eslint/no-explicit-any
Expand Down
4 changes: 0 additions & 4 deletions typings/resolve-package/index.d.ts

This file was deleted.

Loading

0 comments on commit 3dc34f3

Please sign in to comment.