Skip to content

Commit

Permalink
feat: add pnpm support for package installation (#2040)
Browse files Browse the repository at this point in the history
  • Loading branch information
snitin315 committed Nov 6, 2020
1 parent 69a467a commit 46cba36
Show file tree
Hide file tree
Showing 10 changed files with 40 additions and 3 deletions.
Expand Up @@ -22,7 +22,9 @@ describe('packageUtils', () => {
describe('getPackageManager', () => {
const testYarnLockPath = path.resolve(__dirname, 'test-yarn-lock');
const testNpmLockPath = path.resolve(__dirname, 'test-npm-lock');
const testBothPath = path.resolve(__dirname, 'test-both');
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');

Expand All @@ -33,7 +35,8 @@ 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(testNpmAndPnpmPath, 'package-lock.json'), '');
fs.writeFileSync(path.resolve(testAllPath, 'package-lock.json'), '');
});

beforeEach(() => {
Expand All @@ -52,8 +55,20 @@ 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 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(testBothPath);
cwdSpy.mockReturnValue(testAllPath);
expect(getPackageManager()).toEqual('yarn');
expect(syncMock.mock.calls.length).toEqual(0);
});
Expand Down
Expand Up @@ -60,6 +60,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,
Expand Down
Empty file.
Empty file.
Empty file.
Empty file.
5 changes: 5 additions & 0 deletions packages/webpack-cli/lib/utils/get-package-manager.js
Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions packages/webpack-cli/lib/utils/prompt-installation.js
Expand Up @@ -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(' ')}`;
Expand Down

0 comments on commit 46cba36

Please sign in to comment.