Skip to content

Commit

Permalink
Merge pull request #18900 from storybookjs/chore/add-uninstall-deps-c…
Browse files Browse the repository at this point in the history
…ommand

chore(cli): add uninstall deps to jsPackageManager
  • Loading branch information
ndelangen authored Aug 9, 2022
2 parents 97f72c6 + 60e02ab commit f38f4cd
Show file tree
Hide file tree
Showing 7 changed files with 131 additions and 1 deletion.
41 changes: 41 additions & 0 deletions code/lib/cli/src/js-package-manager/JsPackageManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,45 @@ export abstract class JsPackageManager {
}
}

/**
* Remove dependencies from a project using `yarn remove` or `npm uninstall`.
*
* @param {Object} options contains `skipInstall`, `packageJson` and `installAsDevDependencies` which we use to determine how we install packages.
* @param {Array} dependencies contains a list of packages to remove.
* @example
* removeDependencies(options, [
* `@storybook/react`,
* `@storybook/addon-actions`,
* ]);
*/
public removeDependencies(
options: {
skipInstall?: boolean;
packageJson?: PackageJson;
},
dependencies: string[]
): void {
const { skipInstall } = options;

if (skipInstall) {
const { packageJson } = options;

dependencies.forEach((dep) => {
delete packageJson[dep];
}, {});

writePackageJson(packageJson);
} else {
try {
this.runRemoveDeps(dependencies);
} catch (e) {
logger.error('An error occurred while removing dependencies.');
logger.log(e.message);
process.exit(1);
}
}
}

/**
* Return an array of strings matching following format: `<package_name>@<package_latest_version>`
*
Expand Down Expand Up @@ -268,6 +307,8 @@ export abstract class JsPackageManager {

protected abstract runAddDeps(dependencies: string[], installAsDevDependencies: boolean): void;

protected abstract runRemoveDeps(dependencies: string[]): void;

/**
* Get the latest or all versions of the input package available on npmjs.com
*
Expand Down
29 changes: 29 additions & 0 deletions code/lib/cli/src/js-package-manager/NPMProxy.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,35 @@ describe('NPM Proxy', () => {
});
});

describe('removeDependencies', () => {
describe('npm6', () => {
it('with devDep it should run `npm uninstall @storybook/addons`', () => {
const executeCommandSpy = jest.spyOn(npmProxy, 'executeCommand').mockReturnValue('6.0.0');

npmProxy.removeDependencies({}, ['@storybook/addons']);

expect(executeCommandSpy).toHaveBeenLastCalledWith(
'npm',
['uninstall', '@storybook/addons'],
expect.any(String)
);
});
});
describe('npm7', () => {
it('with devDep it should run `npm uninstall @storybook/addons`', () => {
const executeCommandSpy = jest.spyOn(npmProxy, 'executeCommand').mockReturnValue('7.0.0');

npmProxy.removeDependencies({}, ['@storybook/addons']);

expect(executeCommandSpy).toHaveBeenLastCalledWith(
'npm',
['uninstall', '--legacy-peer-deps', '@storybook/addons'],
expect.any(String)
);
});
});
});

describe('latestVersion', () => {
it('without constraint it returns the latest version', async () => {
const executeCommandSpy = jest.spyOn(npmProxy, 'executeCommand').mockReturnValue('"5.3.19"');
Expand Down
17 changes: 17 additions & 0 deletions code/lib/cli/src/js-package-manager/NPMProxy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ export class NPMProxy extends JsPackageManager {

installArgs: string[] | undefined;

uninstallArgs: string[] | undefined;

initPackageJson() {
return this.executeCommand('npm', ['init', '-y']);
}
Expand Down Expand Up @@ -49,6 +51,15 @@ export class NPMProxy extends JsPackageManager {
return this.installArgs;
}

getUninstallArgs(): string[] {
if (!this.uninstallArgs) {
this.uninstallArgs = this.needsLegacyPeerDeps(this.getNpmVersion())
? ['uninstall', '--legacy-peer-deps']
: ['uninstall'];
}
return this.uninstallArgs;
}

protected runInstall(): void {
this.executeCommand('npm', this.getInstallArgs(), 'inherit');
}
Expand All @@ -63,6 +74,12 @@ export class NPMProxy extends JsPackageManager {
this.executeCommand('npm', [...this.getInstallArgs(), ...args], 'inherit');
}

protected runRemoveDeps(dependencies: string[]): void {
const args = [...dependencies];

this.executeCommand('npm', [...this.getUninstallArgs(), ...args], 'inherit');
}

protected runGetVersions<T extends boolean>(
packageName: string,
fetchAllVersions: T
Expand Down
16 changes: 16 additions & 0 deletions code/lib/cli/src/js-package-manager/Yarn1Proxy.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,22 @@ describe('Yarn 1 Proxy', () => {
});
});

describe('removeDependencies', () => {
it('should run `yarn remove --ignore-workspace-root-check @storybook/addons`', () => {
const executeCommandSpy = jest.spyOn(yarn1Proxy, 'executeCommand').mockReturnValue('');

yarn1Proxy.removeDependencies({}, ['@storybook/addons']);

expect(executeCommandSpy).toHaveBeenCalledWith(
'yarn',
['remove', '--ignore-workspace-root-check', '@storybook/addons'],
expect.any(String)
);
});

it.todo('with devDep it should update package json without running yarn remove');
});

describe('latestVersion', () => {
it('without constraint it returns the latest version', async () => {
const executeCommandSpy = jest
Expand Down
6 changes: 6 additions & 0 deletions code/lib/cli/src/js-package-manager/Yarn1Proxy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,12 @@ export class Yarn1Proxy extends JsPackageManager {
this.executeCommand('yarn', ['add', ...args], 'inherit');
}

protected runRemoveDeps(dependencies: string[]): void {
const args = ['--ignore-workspace-root-check', ...dependencies];

this.executeCommand('yarn', ['remove', ...args], 'inherit');
}

protected runGetVersions<T extends boolean>(
packageName: string,
fetchAllVersions: T
Expand Down
17 changes: 16 additions & 1 deletion code/lib/cli/src/js-package-manager/Yarn2Proxy.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Yarn2Proxy } from './Yarn2Proxy';

describe('Yarn 1 Proxy', () => {
describe('Yarn 2 Proxy', () => {
let yarn2Proxy: Yarn2Proxy;

beforeEach(() => {
Expand Down Expand Up @@ -45,6 +45,21 @@ describe('Yarn 1 Proxy', () => {
});
});

describe('removeDependencies', () => {
it('it should run `yarn remove @storybook/addons`', () => {
const executeCommandSpy = jest.spyOn(yarn2Proxy, 'executeCommand').mockReturnValue('');

yarn2Proxy.removeDependencies({}, ['@storybook/addons']);

expect(executeCommandSpy).toHaveBeenCalledWith(
'yarn',
['remove', '@storybook/addons'],
expect.any(String)
);
});
it.todo('with devDep it should update package json without running yarn remove');
});

describe('latestVersion', () => {
it('without constraint it returns the latest version', async () => {
const executeCommandSpy = jest
Expand Down
6 changes: 6 additions & 0 deletions code/lib/cli/src/js-package-manager/Yarn2Proxy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,12 @@ export class Yarn2Proxy extends JsPackageManager {
this.executeCommand('yarn', ['add', ...args], 'inherit');
}

protected runRemoveDeps(dependencies: string[]): void {
const args = [...dependencies];

this.executeCommand('yarn', ['remove', ...args], 'inherit');
}

protected runGetVersions<T extends boolean>(
packageName: string,
fetchAllVersions: T
Expand Down

0 comments on commit f38f4cd

Please sign in to comment.