Skip to content

Commit e53f164

Browse files
feat(init-generator): add ability to specify a package manager of choice (#2769)
* feat: add ability to specify a package manager of choice * chore: choose default installer based on the lock file presence * test: update test suite
1 parent 59d644d commit e53f164

File tree

4 files changed

+52
-7
lines changed

4 files changed

+52
-7
lines changed

packages/generators/src/init-generator.ts

+11-2
Original file line numberDiff line numberDiff line change
@@ -99,8 +99,17 @@ export default class InitGenerator extends CustomGenerator {
9999
}
100100
}
101101

102-
public installPlugins(): void {
103-
const packager = this.utils.getPackageManager();
102+
public async installPlugins(): Promise<void> {
103+
// Prompt for the package manager of choice
104+
const defaultPackager = this.utils.getPackageManager();
105+
const { packager } = await Question.List(
106+
this,
107+
"packager",
108+
"Pick a package manager:",
109+
this.utils.getAvailableInstallers(),
110+
defaultPackager,
111+
this.force,
112+
);
104113
const opts: {
105114
dev?: boolean;
106115
"save-dev"?: boolean;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
const { sync } = require("execa");
2+
3+
const utils = require("./");
4+
5+
function hasPmInstalled(packageManager) {
6+
try {
7+
sync(packageManager, ["--version"]);
8+
return packageManager;
9+
} catch (err) {
10+
return false;
11+
}
12+
}
13+
14+
function getAvailableInstallers() {
15+
const installers = ["npm", "yarn", "pnpm"];
16+
const availableInstallers = installers.filter((installer) => hasPmInstalled(installer));
17+
18+
if (!availableInstallers.length) {
19+
utils.logger.error("No package manager found.");
20+
process.exit(2);
21+
}
22+
return availableInstallers;
23+
}
24+
25+
module.exports = getAvailableInstallers;

packages/webpack-cli/lib/utils/index.js

+4
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,10 @@ module.exports = {
2323
return require("./dynamic-import-loader");
2424
},
2525

26+
get getAvailableInstallers() {
27+
return require("./get-available-installers");
28+
},
29+
2630
get getPackageManager() {
2731
return require("./get-package-manager");
2832
},

test/init/init.test.js

+12-5
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ describe("init command", () => {
144144
const { stdout, stderr } = await runPromptWithAnswers(
145145
assetsPath,
146146
["init"],
147-
[`${DOWN}${DOWN}${ENTER}`, `n${ENTER}`, `n${ENTER}`, `n${ENTER}`, ENTER],
147+
[`${DOWN}${DOWN}${ENTER}`, `n${ENTER}`, `n${ENTER}`, `n${ENTER}`, ENTER, ENTER],
148148
);
149149

150150
expect(stdout).toContain("Project has been initialised with webpack!");
@@ -170,7 +170,7 @@ describe("init command", () => {
170170
const { stdout, stderr } = await runPromptWithAnswers(
171171
assetsPath,
172172
["init"],
173-
[`${DOWN}${ENTER}`, `n${ENTER}`, `n${ENTER}`, `n${ENTER}`, ENTER],
173+
[`${DOWN}${ENTER}`, `n${ENTER}`, `n${ENTER}`, `n${ENTER}`, ENTER, ENTER],
174174
);
175175

176176
expect(stdout).toContain("Project has been initialised with webpack!");
@@ -205,6 +205,7 @@ describe("init command", () => {
205205
`n${ENTER}`,
206206
`n${ENTER}`,
207207
`n${ENTER}`,
208+
ENTER,
208209
],
209210
);
210211

@@ -239,6 +240,7 @@ describe("init command", () => {
239240
`n${ENTER}`,
240241
`y${ENTER}`,
241242
`n${ENTER}`,
243+
ENTER,
242244
],
243245
);
244246

@@ -279,6 +281,7 @@ describe("init command", () => {
279281
`n${ENTER}`,
280282
`n${ENTER}`,
281283
`y${ENTER}`,
284+
ENTER,
282285
],
283286
);
284287

@@ -313,6 +316,7 @@ describe("init command", () => {
313316
`y${ENTER}`,
314317
`y${ENTER}`,
315318
`n${ENTER}`,
319+
ENTER,
316320
],
317321
);
318322

@@ -353,6 +357,7 @@ describe("init command", () => {
353357
`n${ENTER}`,
354358
`n${ENTER}`,
355359
`n${ENTER}`,
360+
ENTER,
356361
],
357362
);
358363

@@ -387,6 +392,7 @@ describe("init command", () => {
387392
`n${ENTER}`,
388393
`n${ENTER}`,
389394
`n${ENTER}`,
395+
ENTER,
390396
],
391397
);
392398

@@ -412,7 +418,7 @@ describe("init command", () => {
412418
const { stdout, stderr } = await runPromptWithAnswers(
413419
assetsPath,
414420
["init"],
415-
[ENTER, ENTER, `n${ENTER}`, `n${ENTER}`, ENTER],
421+
[ENTER, ENTER, `n${ENTER}`, `n${ENTER}`, ENTER, ENTER],
416422
);
417423

418424
expect(stdout).toContain("Do you want to use webpack-dev-server?");
@@ -445,6 +451,7 @@ describe("init command", () => {
445451
`${DOWN}${ENTER}`,
446452
ENTER,
447453
`n${ENTER}`,
454+
ENTER,
448455
],
449456
);
450457

@@ -476,7 +483,7 @@ describe("init command", () => {
476483
const { stdout, stderr } = await runPromptWithAnswers(
477484
assetsPath,
478485
["init"],
479-
[ENTER, `n${ENTER}`, ENTER, `n${ENTER}`, ENTER],
486+
[ENTER, `n${ENTER}`, ENTER, `n${ENTER}`, ENTER, ENTER],
480487
);
481488

482489
expect(stdout).toContain(
@@ -504,7 +511,7 @@ describe("init command", () => {
504511
const { stdout, stderr } = await runPromptWithAnswers(
505512
assetsPath,
506513
["init"],
507-
[ENTER, `n${ENTER}`, ENTER, ENTER, ENTER],
514+
[ENTER, `n${ENTER}`, ENTER, ENTER, ENTER, ENTER],
508515
);
509516

510517
expect(stdout).toContain("Do you want to add PWA support?");

0 commit comments

Comments
 (0)