Skip to content

Commit

Permalink
feat!(core): add required Forge version for templates (#2415)
Browse files Browse the repository at this point in the history
BREAKING CHANGE: Electron Forge templates compatible with v6 must
specify the minimum Forge version supported by the template, using the
`requiredForgeVersion` attribute on the class implementing `ForgeTemplate`.

This is largely to prevent the built-in templates from v5 from being
used with v6.
  • Loading branch information
malept authored Aug 1, 2021
1 parent c0807e8 commit c094d16
Show file tree
Hide file tree
Showing 9 changed files with 59 additions and 2 deletions.
5 changes: 3 additions & 2 deletions packages/api/core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,10 @@
"license": "MIT",
"scripts": {
"coverage:base": "nyc yarn test:base",
"test": "yarn test:base test/**/**/*_spec.ts",
"test": "yarn test:base test/**/*_spec.ts test/**/*_spec_slow.ts",
"test:base": "cross-env TS_NODE_FILES=1 mocha --config ../../../.mocharc.js",
"test:fast": "yarn test:base test/fast/**/*_spec.ts"
"test:fast": "yarn test:base test/fast/**/*_spec.ts",
"test:slow": "yarn test:base test/slow/**/*_spec_slow.ts"
},
"devDependencies": {
"@electron-forge/maker-appx": "6.0.0-beta.59",
Expand Down
15 changes: 15 additions & 0 deletions packages/api/core/src/api/init.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import { asyncOra } from '@electron-forge/async-ora';
import debug from 'debug';
import { ForgeTemplate } from '@electron-forge/shared-types';
import fs from 'fs-extra';
import path from 'path';
import semver from 'semver';

import findTemplate from './init-scripts/find-template';
import initDirectory from './init-scripts/init-directory';
Expand Down Expand Up @@ -36,6 +38,17 @@ export interface InitOptions {
template?: string;
}

async function validateTemplate(template: string, templateModule: ForgeTemplate): Promise<void> {
if (!templateModule.requiredForgeVersion) {
throw new Error(`Cannot use a template (${template}) with this version of Electron Forge, as it does not specify its required Forge version.`);
}

const forgeVersion = (await readRawPackageJson(path.join(__dirname, '..', '..'))).version;
if (!semver.satisfies(forgeVersion, templateModule.requiredForgeVersion)) {
throw new Error(`Template (${template}) is not compatible with this version of Electron Forge (${forgeVersion}), it requires ${templateModule.requiredForgeVersion}`);
}
}

export default async ({
dir = process.cwd(),
interactive = false,
Expand All @@ -51,6 +64,8 @@ export default async ({
await initGit(dir);
const templateModule = await findTemplate(dir, template);

await validateTemplate(template, templateModule);

if (typeof templateModule.initializeTemplate === 'function') {
await templateModule.initializeTemplate(dir, { copyCIFiles });
const packageJSON = await readRawPackageJson(dir);
Expand Down
1 change: 1 addition & 0 deletions packages/api/core/test/fixture/custom_init/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ const fs = require('fs-extra');
const path = require('path');

module.exports = {
requiredForgeVersion: '>= 6.0.0-beta.1',
dependencies: ['debug'],
devDependencies: ['lodash'],
initializeTemplate: async (directory) => {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
module.exports = { requiredForgeVersion: "6.0.0-beta.0" }
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{}
34 changes: 34 additions & 0 deletions packages/api/core/test/slow/api_spec_slow.ts
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,40 @@ for (const nodeInstaller of ['npm', 'yarn']) {
});
});

describe('init (with a templater sans required Forge version)', () => {
before(async () => {
dir = await ensureTestDirIsNonexistent();
});

it('should fail in initializing', async () => {
await expect(forge.init({
dir,
template: path.resolve(__dirname, '../fixture/template-sans-forge-version'),
})).to.eventually.be.rejectedWith(/it does not specify its required Forge version\.$/);
});

after(async () => {
await fs.remove(dir);
});
});

describe('init (with a templater with a non-matching Forge version)', () => {
before(async () => {
dir = await ensureTestDirIsNonexistent();
});

it('should fail in initializing', async () => {
await expect(forge.init({
dir,
template: path.resolve(__dirname, '../fixture/template-nonmatching-forge-version'),
})).to.eventually.be.rejectedWith(/is not compatible with this version of Electron Forge/);
});

after(async () => {
await fs.remove(dir);
});
});

describe('init (with a nonexistent templater)', () => {
before(async () => {
dir = await ensureTestDirIsNonexistent();
Expand Down
2 changes: 2 additions & 0 deletions packages/template/base/src/BaseTemplate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ const tmplDir = path.resolve(__dirname, '../tmpl');
export class BaseTemplate implements ForgeTemplate {
public templateDir = tmplDir;

public requiredForgeVersion = currentForgeVersion;

get devDependencies(): string[] {
const packageJSONPath = path.join(this.templateDir, 'package.json');
if (fs.pathExistsSync(packageJSONPath)) {
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 @@ -124,6 +124,7 @@ export interface InitTemplateOptions {
}

export interface ForgeTemplate {
requiredForgeVersion?: string;
dependencies?: string[];
devDependencies?: string[];
initializeTemplate?: (dir: string, options: InitTemplateOptions) => void;
Expand Down

0 comments on commit c094d16

Please sign in to comment.