Skip to content

Commit d3900ee

Browse files
authored
feat(cli): show template sources when initializing (#3895)
1 parent 5329eca commit d3900ee

File tree

3 files changed

+58
-33
lines changed

3 files changed

+58
-33
lines changed

packages/api/core/spec/fast/find-template.spec.ts

+26-20
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import path from 'node:path';
22

3-
import { describe, expect, it, vi } from 'vitest';
3+
import globalDirs from 'global-dirs';
4+
import { beforeEach, describe, expect, it, vi } from 'vitest';
45

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

@@ -14,14 +15,20 @@ describe('findTemplate', () => {
1415
* for the fixtures to be installed in your local `node_modules`.
1516
*/
1617
describe('local modules', () => {
17-
it('should find an @electron-forge/template based on name', async () => {
18-
await expect(findTemplate('fixture')).resolves.toEqual({ name: 'electron-forge-template-fixture' });
18+
it('should find an @electron-forge/template based on partial name', async () => {
19+
await expect(findTemplate('fixture')).resolves.toEqual(expect.objectContaining({ name: '@electron-forge/template-fixture' }));
1920
});
20-
it('should find an @electron-forge/template based on name', async () => {
21-
await expect(findTemplate('fixture-two')).resolves.toEqual({ name: 'electron-forge-template-fixture' });
21+
22+
it('should find an @electron-forge/template based on full name', async () => {
23+
await expect(findTemplate('@electron-forge/template-fixture')).resolves.toEqual(expect.objectContaining({ name: '@electron-forge/template-fixture' }));
2224
});
23-
it('should find an @electron-forge/template based on name', async () => {
24-
await expect(findTemplate('electron-forge-template-fixture-two')).resolves.toEqual({ name: 'electron-forge-template-fixture' });
25+
it('should find an electron-forge-template based on partial name', async () => {
26+
await expect(findTemplate('fixture-two')).resolves.toEqual(expect.objectContaining({ name: 'electron-forge-template-fixture-two' }));
27+
});
28+
it('should find an @electron-forge-template based on full name', async () => {
29+
await expect(findTemplate('electron-forge-template-fixture-two')).resolves.toEqual(
30+
expect.objectContaining({ name: 'electron-forge-template-fixture-two' })
31+
);
2532
});
2633
});
2734

@@ -31,23 +38,22 @@ describe('findTemplate', () => {
3138
* `node_modules` in order for the `require.resolve` custom path to work.
3239
*/
3340
describe('global modules', () => {
34-
vi.mock(import('global-dirs'), async (importOriginal) => {
35-
const mod = await importOriginal();
36-
return {
37-
default: {
38-
...mod.default,
39-
npm: {
40-
...mod.default.npm,
41-
packages: path.resolve(__dirname, '..', 'fixture', 'global-stub', 'node_modules'),
42-
},
43-
},
44-
};
41+
beforeEach(() => {
42+
vi.spyOn(globalDirs, 'npm', 'get').mockReturnValue({
43+
binaries: '',
44+
prefix: '',
45+
packages: path.resolve(__dirname, '..', 'fixture', 'global-stub', 'node_modules'),
46+
});
4547
});
4648
it('should find an @electron-forge/template based on name', async () => {
47-
await expect(findTemplate('global')).resolves.toEqual({ name: 'electron-forge-template-fixture-global' });
49+
await expect(findTemplate('global')).resolves.toEqual(
50+
expect.objectContaining({ template: { name: 'electron-forge-template-fixture-global' }, type: 'global' })
51+
);
4852
});
4953
it('should find an electron-forge-template based on name', async () => {
50-
await expect(findTemplate('global-two')).resolves.toEqual({ name: 'electron-forge-template-fixture-global' });
54+
await expect(findTemplate('global-two')).resolves.toEqual(
55+
expect.objectContaining({ template: { name: 'electron-forge-template-fixture-global' }, type: 'global' })
56+
);
5157
});
5258
});
5359

packages/api/core/src/api/init-scripts/find-template.ts

+26-10
Original file line numberDiff line numberDiff line change
@@ -11,40 +11,56 @@ enum TemplateType {
1111
local = 'local',
1212
}
1313

14-
export const findTemplate = async (template: string): Promise<ForgeTemplate> => {
15-
let templateModulePath!: string;
14+
export interface ForgeTemplateDetails {
15+
name: string;
16+
path: string;
17+
template: ForgeTemplate;
18+
type: TemplateType;
19+
}
20+
21+
export const findTemplate = async (template: string): Promise<ForgeTemplateDetails> => {
22+
let foundTemplate: Omit<ForgeTemplateDetails, 'template'> | null = null;
23+
1624
const resolveTemplateTypes = [
1725
[TemplateType.global, `electron-forge-template-${template}`],
1826
[TemplateType.global, `@electron-forge/template-${template}`],
1927
[TemplateType.local, `electron-forge-template-${template}`],
2028
[TemplateType.local, `@electron-forge/template-${template}`],
2129
[TemplateType.global, template],
2230
[TemplateType.local, template],
23-
];
24-
let foundTemplate = false;
31+
] as const;
2532
for (const [templateType, moduleName] of resolveTemplateTypes) {
2633
try {
2734
d(`Trying ${templateType} template: ${moduleName}`);
35+
let templateModulePath: string;
2836
if (templateType === TemplateType.global) {
2937
templateModulePath = require.resolve(moduleName, {
3038
paths: [globalDirs.npm.packages, globalDirs.yarn.packages],
3139
});
3240
} else {
3341
templateModulePath = require.resolve(moduleName);
3442
}
35-
foundTemplate = true;
43+
foundTemplate = {
44+
path: templateModulePath,
45+
type: templateType,
46+
name: moduleName,
47+
};
3648
break;
3749
} catch (err) {
3850
d(`Error: ${err instanceof Error ? err.message : err}`);
3951
}
4052
}
4153
if (!foundTemplate) {
4254
throw new Error(`Failed to locate custom template: "${template}".`);
43-
}
44-
45-
d(`found template module at: ${templateModulePath}`);
55+
} else {
56+
d(`found template module at: ${foundTemplate.path}`);
4657

47-
const templateModule: PossibleModule<ForgeTemplate> = await import(templateModulePath);
58+
const templateModule: PossibleModule<ForgeTemplate> = await import(foundTemplate.path);
59+
const tmpl = templateModule.default ?? templateModule;
4860

49-
return templateModule.default ?? templateModule;
61+
return {
62+
...foundTemplate,
63+
template: tmpl,
64+
};
65+
}
5066
};

packages/api/core/src/api/init.ts

+6-3
Original file line numberDiff line numberDiff line change
@@ -81,10 +81,13 @@ export default async ({
8181
},
8282
},
8383
{
84-
title: `Locating custom template: "${template}"`,
85-
task: async (ctx) => {
86-
ctx.templateModule = await findTemplate(template);
84+
title: `Resolving template: ${chalk.cyan(template)}`,
85+
task: async (ctx, task) => {
86+
const tmpl = await findTemplate(template);
87+
ctx.templateModule = tmpl.template;
88+
task.output = `Using ${chalk.green(tmpl.name)} (${tmpl.type} module)`;
8789
},
90+
rendererOptions: { persistentOutput: true },
8891
},
8992
{
9093
title: 'Initializing directory',

0 commit comments

Comments
 (0)