From 8df23cc7046459e3f29da53e1f99e035cc6681c9 Mon Sep 17 00:00:00 2001 From: Nitin Kumar Date: Thu, 5 Nov 2020 07:40:55 +0530 Subject: [PATCH 1/3] feat: add pnpm support for package installation --- .../utils/__tests__/get-package-manager.test.js | 7 +++++++ .../utils/__tests__/prompt-installation.test.js | 16 ++++++++++++++++ .../__tests__/test-pnpm-lock/pnpm-lock.yaml | 0 .../webpack-cli/lib/utils/get-package-manager.js | 5 +++++ .../webpack-cli/lib/utils/prompt-installation.js | 1 + 5 files changed, 29 insertions(+) create mode 100644 packages/webpack-cli/lib/utils/__tests__/test-pnpm-lock/pnpm-lock.yaml diff --git a/packages/webpack-cli/lib/utils/__tests__/get-package-manager.test.js b/packages/webpack-cli/lib/utils/__tests__/get-package-manager.test.js index 61350f3e520..f97b9bf0fd3 100644 --- a/packages/webpack-cli/lib/utils/__tests__/get-package-manager.test.js +++ b/packages/webpack-cli/lib/utils/__tests__/get-package-manager.test.js @@ -22,6 +22,7 @@ describe('packageUtils', () => { describe('getPackageManager', () => { const testYarnLockPath = path.resolve(__dirname, 'test-yarn-lock'); const testNpmLockPath = path.resolve(__dirname, 'test-npm-lock'); + const testPnpmLockPath = path.resolve(__dirname, 'test-pnpm-lock'); const testBothPath = path.resolve(__dirname, 'test-both'); const cwdSpy = jest.spyOn(process, 'cwd'); @@ -52,6 +53,12 @@ describe('packageUtils', () => { expect(syncMock.mock.calls.length).toEqual(0); }); + it('should find pnpm-lock.yaml', () => { + cwdSpy.mockReturnValue(testPnpmLockPath); + expect(getPackageManager()).toEqual('pnpm'); + expect(syncMock.mock.calls.length).toEqual(0); + }); + it('should prioritize yarn with many lock files', () => { cwdSpy.mockReturnValue(testBothPath); expect(getPackageManager()).toEqual('yarn'); diff --git a/packages/webpack-cli/lib/utils/__tests__/prompt-installation.test.js b/packages/webpack-cli/lib/utils/__tests__/prompt-installation.test.js index 6a0b54e3f25..4208e1c39f7 100644 --- a/packages/webpack-cli/lib/utils/__tests__/prompt-installation.test.js +++ b/packages/webpack-cli/lib/utils/__tests__/prompt-installation.test.js @@ -64,6 +64,22 @@ describe('promptInstallation', () => { expect(runCommand.mock.calls[0][0]).toEqual('yarn add -D test-package'); }); + it('should prompt to install using pnpm if pnpm is package manager', async () => { + prompt.mockReturnValue({ + installConfirm: true, + }); + getPackageManager.mockReturnValue('pnpm'); + const preMessage = jest.fn(); + const promptResult = await promptInstallation('test-package', preMessage); + expect(promptResult).toBeTruthy(); + expect(preMessage.mock.calls.length).toEqual(1); + expect(prompt.mock.calls.length).toEqual(1); + expect(runCommand.mock.calls.length).toEqual(1); + expect(prompt.mock.calls[0][0][0].message).toMatch(/Would you like to install test-package\?/); + // install the package using npm + expect(runCommand.mock.calls[0][0]).toEqual('pnpm install -D test-package'); + }); + it('should not install if install is not confirmed', async () => { prompt.mockReturnValue({ installConfirm: false, diff --git a/packages/webpack-cli/lib/utils/__tests__/test-pnpm-lock/pnpm-lock.yaml b/packages/webpack-cli/lib/utils/__tests__/test-pnpm-lock/pnpm-lock.yaml new file mode 100644 index 00000000000..e69de29bb2d diff --git a/packages/webpack-cli/lib/utils/get-package-manager.js b/packages/webpack-cli/lib/utils/get-package-manager.js index 9d6b4125604..4c165664f4b 100644 --- a/packages/webpack-cli/lib/utils/get-package-manager.js +++ b/packages/webpack-cli/lib/utils/get-package-manager.js @@ -12,11 +12,16 @@ const { sync } = require('execa'); function getPackageManager() { const hasLocalYarn = fs.existsSync(path.resolve(process.cwd(), 'yarn.lock')); const hasLocalNpm = fs.existsSync(path.resolve(process.cwd(), 'package-lock.json')); + const hasLocalPnpm = fs.existsSync(path.resolve(process.cwd(), 'pnpm-lock.yaml')); + if (hasLocalYarn) { return 'yarn'; } else if (hasLocalNpm) { return 'npm'; + } else if (hasLocalPnpm) { + return 'pnpm'; } + try { // if the sync function below fails because yarn is not installed, // an error will be thrown diff --git a/packages/webpack-cli/lib/utils/prompt-installation.js b/packages/webpack-cli/lib/utils/prompt-installation.js index 377e58e7d3b..663fa6722bf 100644 --- a/packages/webpack-cli/lib/utils/prompt-installation.js +++ b/packages/webpack-cli/lib/utils/prompt-installation.js @@ -11,6 +11,7 @@ const { packageExists } = require('./package-exists'); */ async function promptInstallation(packageName, preMessage) { const packageManager = getPackageManager(); + // yarn uses 'add' command, rest npm and pnpm both use 'install' const options = [packageManager === 'yarn' ? 'add' : 'install', '-D', packageName]; const commandToBeRun = `${packageManager} ${options.join(' ')}`; From 805c72bbf1459320049a40d71c42be0f48d27e71 Mon Sep 17 00:00:00 2001 From: Nitin Kumar Date: Thu, 5 Nov 2020 08:03:28 +0530 Subject: [PATCH 2/3] tests: updates --- .../lib/utils/__tests__/get-package-manager.test.js | 6 +++--- .../{test-both => test-all-lock}/package-lock.json | 0 .../{test-both/yarn.lock => test-all-lock/pnpm-lock.yaml} | 0 .../webpack-cli/lib/utils/__tests__/test-all-lock/yarn.lock | 0 4 files changed, 3 insertions(+), 3 deletions(-) rename packages/webpack-cli/lib/utils/__tests__/{test-both => test-all-lock}/package-lock.json (100%) rename packages/webpack-cli/lib/utils/__tests__/{test-both/yarn.lock => test-all-lock/pnpm-lock.yaml} (100%) create mode 100644 packages/webpack-cli/lib/utils/__tests__/test-all-lock/yarn.lock diff --git a/packages/webpack-cli/lib/utils/__tests__/get-package-manager.test.js b/packages/webpack-cli/lib/utils/__tests__/get-package-manager.test.js index f97b9bf0fd3..bfcb5a07109 100644 --- a/packages/webpack-cli/lib/utils/__tests__/get-package-manager.test.js +++ b/packages/webpack-cli/lib/utils/__tests__/get-package-manager.test.js @@ -23,7 +23,7 @@ describe('packageUtils', () => { const testYarnLockPath = path.resolve(__dirname, 'test-yarn-lock'); const testNpmLockPath = path.resolve(__dirname, 'test-npm-lock'); const testPnpmLockPath = path.resolve(__dirname, 'test-pnpm-lock'); - const testBothPath = path.resolve(__dirname, 'test-both'); + const testAllPath = path.resolve(__dirname, 'test-all-lock'); const cwdSpy = jest.spyOn(process, 'cwd'); @@ -34,7 +34,7 @@ describe('packageUtils', () => { fs.mkdirSync(testNpmLockPath); } fs.writeFileSync(path.resolve(testNpmLockPath, 'package-lock.json'), ''); - fs.writeFileSync(path.resolve(testBothPath, 'package-lock.json'), ''); + fs.writeFileSync(path.resolve(testAllPath, 'package-lock.json'), ''); }); beforeEach(() => { @@ -60,7 +60,7 @@ describe('packageUtils', () => { }); it('should prioritize yarn with many lock files', () => { - cwdSpy.mockReturnValue(testBothPath); + cwdSpy.mockReturnValue(testAllPath); expect(getPackageManager()).toEqual('yarn'); expect(syncMock.mock.calls.length).toEqual(0); }); diff --git a/packages/webpack-cli/lib/utils/__tests__/test-both/package-lock.json b/packages/webpack-cli/lib/utils/__tests__/test-all-lock/package-lock.json similarity index 100% rename from packages/webpack-cli/lib/utils/__tests__/test-both/package-lock.json rename to packages/webpack-cli/lib/utils/__tests__/test-all-lock/package-lock.json diff --git a/packages/webpack-cli/lib/utils/__tests__/test-both/yarn.lock b/packages/webpack-cli/lib/utils/__tests__/test-all-lock/pnpm-lock.yaml similarity index 100% rename from packages/webpack-cli/lib/utils/__tests__/test-both/yarn.lock rename to packages/webpack-cli/lib/utils/__tests__/test-all-lock/pnpm-lock.yaml diff --git a/packages/webpack-cli/lib/utils/__tests__/test-all-lock/yarn.lock b/packages/webpack-cli/lib/utils/__tests__/test-all-lock/yarn.lock new file mode 100644 index 00000000000..e69de29bb2d From 3a5981177e654c387450a970e5aba11c04243c0a Mon Sep 17 00:00:00 2001 From: Nitin Kumar Date: Thu, 5 Nov 2020 08:07:46 +0530 Subject: [PATCH 3/3] tests: update --- .../lib/utils/__tests__/get-package-manager.test.js | 8 ++++++++ .../utils/__tests__/test-npm-and-pnpm/package-lock.json | 0 .../lib/utils/__tests__/test-npm-and-pnpm/pnpm-lock.yaml | 0 3 files changed, 8 insertions(+) create mode 100644 packages/webpack-cli/lib/utils/__tests__/test-npm-and-pnpm/package-lock.json create mode 100644 packages/webpack-cli/lib/utils/__tests__/test-npm-and-pnpm/pnpm-lock.yaml diff --git a/packages/webpack-cli/lib/utils/__tests__/get-package-manager.test.js b/packages/webpack-cli/lib/utils/__tests__/get-package-manager.test.js index bfcb5a07109..3abe09e9c46 100644 --- a/packages/webpack-cli/lib/utils/__tests__/get-package-manager.test.js +++ b/packages/webpack-cli/lib/utils/__tests__/get-package-manager.test.js @@ -23,6 +23,7 @@ describe('packageUtils', () => { const testYarnLockPath = path.resolve(__dirname, 'test-yarn-lock'); const testNpmLockPath = path.resolve(__dirname, 'test-npm-lock'); const testPnpmLockPath = path.resolve(__dirname, 'test-pnpm-lock'); + const testNpmAndPnpmPath = path.resolve(__dirname, 'test-npm-and-pnpm'); const testAllPath = path.resolve(__dirname, 'test-all-lock'); const cwdSpy = jest.spyOn(process, 'cwd'); @@ -34,6 +35,7 @@ describe('packageUtils', () => { fs.mkdirSync(testNpmLockPath); } fs.writeFileSync(path.resolve(testNpmLockPath, 'package-lock.json'), ''); + fs.writeFileSync(path.resolve(testNpmAndPnpmPath, 'package-lock.json'), ''); fs.writeFileSync(path.resolve(testAllPath, 'package-lock.json'), ''); }); @@ -59,6 +61,12 @@ describe('packageUtils', () => { expect(syncMock.mock.calls.length).toEqual(0); }); + it('should prioritize npm over pnpm', () => { + cwdSpy.mockReturnValue(testNpmAndPnpmPath); + expect(getPackageManager()).toEqual('npm'); + expect(syncMock.mock.calls.length).toEqual(0); + }); + it('should prioritize yarn with many lock files', () => { cwdSpy.mockReturnValue(testAllPath); expect(getPackageManager()).toEqual('yarn'); diff --git a/packages/webpack-cli/lib/utils/__tests__/test-npm-and-pnpm/package-lock.json b/packages/webpack-cli/lib/utils/__tests__/test-npm-and-pnpm/package-lock.json new file mode 100644 index 00000000000..e69de29bb2d diff --git a/packages/webpack-cli/lib/utils/__tests__/test-npm-and-pnpm/pnpm-lock.yaml b/packages/webpack-cli/lib/utils/__tests__/test-npm-and-pnpm/pnpm-lock.yaml new file mode 100644 index 00000000000..e69de29bb2d