From ed79e5bb42d831a33fe1a461f06582c22045c00c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABtan=20Maisse?= Date: Fri, 5 Jun 2020 20:43:59 +0200 Subject: [PATCH 01/22] refactor: introduce a JsPackageManager abstract class and specialized subclasses for NPM, Yarn and Yarn 2. The goal of this will be to use the Factory Pattern to encapsulate everything specific to a package manager in a single class. Then a factory will return an instance of NPM, Yarn or Yarn 2 proxy class according to the package manager used/prefered in end project. All CLI code will be package manager agnostic and will just call functions of JsPackageManager interface. --- .../js-package-manager/JsPackageManager.ts | 3 ++ .../src/js-package-manager/NPMProxy.test.ts | 45 +++++++++++++++++++ lib/cli/src/js-package-manager/NPMProxy.ts | 14 ++++++ .../src/js-package-manager/Yarn1Proxy.test.ts | 37 +++++++++++++++ lib/cli/src/js-package-manager/Yarn1Proxy.ts | 14 ++++++ .../src/js-package-manager/Yarn2Proxy.test.ts | 35 +++++++++++++++ lib/cli/src/js-package-manager/Yarn2Proxy.ts | 14 ++++++ 7 files changed, 162 insertions(+) create mode 100644 lib/cli/src/js-package-manager/JsPackageManager.ts create mode 100644 lib/cli/src/js-package-manager/NPMProxy.test.ts create mode 100644 lib/cli/src/js-package-manager/NPMProxy.ts create mode 100644 lib/cli/src/js-package-manager/Yarn1Proxy.test.ts create mode 100644 lib/cli/src/js-package-manager/Yarn1Proxy.ts create mode 100644 lib/cli/src/js-package-manager/Yarn2Proxy.test.ts create mode 100644 lib/cli/src/js-package-manager/Yarn2Proxy.ts diff --git a/lib/cli/src/js-package-manager/JsPackageManager.ts b/lib/cli/src/js-package-manager/JsPackageManager.ts new file mode 100644 index 000000000000..8a407c6c8d83 --- /dev/null +++ b/lib/cli/src/js-package-manager/JsPackageManager.ts @@ -0,0 +1,3 @@ +export abstract class JsPackageManager { + public abstract initPackageJson(): void; +} diff --git a/lib/cli/src/js-package-manager/NPMProxy.test.ts b/lib/cli/src/js-package-manager/NPMProxy.test.ts new file mode 100644 index 000000000000..09f444f22b46 --- /dev/null +++ b/lib/cli/src/js-package-manager/NPMProxy.test.ts @@ -0,0 +1,45 @@ +import { sync } from 'cross-spawn'; +import dedent from 'ts-dedent'; +import { NPMProxy } from './NPMProxy'; + +jest.mock('cross-spawn'); +const syncMock = sync as jest.Mock; + +describe('NPM Proxy', () => { + const npmProxy = new NPMProxy(); + + describe('initPackageJson', () => { + it('should call spawn.sync and return console output', () => { + const consoleOutput = dedent`Wrote to /Users/johndoe/Documents/package.json: + { + "name": "toto", + "version": "1.0.0", + "description": "", + "main": "index.js", + "scripts": { + "test": "echo \\"Error: no test specified\\" && exit 1" + }, + "keywords": [], + "author": "", + "license": "ISC" + }`; + + syncMock.mockReturnValueOnce({ stdout: consoleOutput }); + + const result = npmProxy.initPackageJson(); + + expect(syncMock).toHaveBeenCalledWith( + 'npm', + ['init', '-y'], + expect.objectContaining({ + cwd: process.cwd(), + env: process.env, + stdio: 'pipe', + encoding: 'utf-8', + }) + ); + + expect(result).toEqual(expect.any(String)); + }); + }); +}); diff --git a/lib/cli/src/js-package-manager/NPMProxy.ts b/lib/cli/src/js-package-manager/NPMProxy.ts new file mode 100644 index 000000000000..2e4ca422c080 --- /dev/null +++ b/lib/cli/src/js-package-manager/NPMProxy.ts @@ -0,0 +1,14 @@ +import spawn from 'cross-spawn'; +import { JsPackageManager } from './JsPackageManager'; + +export class NPMProxy extends JsPackageManager { + initPackageJson() { + const results = spawn.sync('npm', ['init', '-y'], { + cwd: process.cwd(), + env: process.env, + stdio: 'pipe', + encoding: 'utf-8', + }); + return results.stdout; + } +} diff --git a/lib/cli/src/js-package-manager/Yarn1Proxy.test.ts b/lib/cli/src/js-package-manager/Yarn1Proxy.test.ts new file mode 100644 index 000000000000..e5588f8f337a --- /dev/null +++ b/lib/cli/src/js-package-manager/Yarn1Proxy.test.ts @@ -0,0 +1,37 @@ +import { sync } from 'cross-spawn'; +import dedent from 'ts-dedent'; +import { Yarn1Proxy } from './Yarn1Proxy'; + +jest.mock('cross-spawn'); +const syncMock = sync as jest.Mock; + +describe('Yarn Proxy', () => { + const yarnProxy = new Yarn1Proxy(); + + describe('initPackageJson', () => { + it('should call spawn.sync and return console output', () => { + const consoleOutput = dedent` + yarn init v1.22.4 + warning The yes flag has been set. This will automatically answer yes to all questions, which may have security implications. + success Saved package.json + ✨ Done in 0.02s.`; + + syncMock.mockReturnValueOnce({ stdout: consoleOutput }); + + const result = yarnProxy.initPackageJson(); + + expect(syncMock).toHaveBeenCalledWith( + 'yarn', + ['init', '-y'], + expect.objectContaining({ + cwd: process.cwd(), + env: process.env, + stdio: 'pipe', + encoding: 'utf-8', + }) + ); + + expect(result).toEqual(expect.any(String)); + }); + }); +}); diff --git a/lib/cli/src/js-package-manager/Yarn1Proxy.ts b/lib/cli/src/js-package-manager/Yarn1Proxy.ts new file mode 100644 index 000000000000..fc2a3bec73a7 --- /dev/null +++ b/lib/cli/src/js-package-manager/Yarn1Proxy.ts @@ -0,0 +1,14 @@ +import spawn from 'cross-spawn'; +import { JsPackageManager } from './JsPackageManager'; + +export class Yarn1Proxy extends JsPackageManager { + initPackageJson() { + const results = spawn.sync('yarn', ['init', '-y'], { + cwd: process.cwd(), + env: process.env, + stdio: 'pipe', + encoding: 'utf-8', + }); + return results.stdout; + } +} diff --git a/lib/cli/src/js-package-manager/Yarn2Proxy.test.ts b/lib/cli/src/js-package-manager/Yarn2Proxy.test.ts new file mode 100644 index 000000000000..3518595e99b5 --- /dev/null +++ b/lib/cli/src/js-package-manager/Yarn2Proxy.test.ts @@ -0,0 +1,35 @@ +import { sync } from 'cross-spawn'; +import dedent from 'ts-dedent'; +import { Yarn2Proxy } from './Yarn2Proxy'; + +jest.mock('cross-spawn'); +const syncMock = sync as jest.Mock; + +describe('Yarn 2 Proxy', () => { + const yarn2Proxy = new Yarn2Proxy(); + + describe('initPackageJson', () => { + it('should call spawn.sync and return console output', () => { + const consoleOutput = dedent`{ + name: 'test' + }`; + + syncMock.mockReturnValueOnce({ stdout: consoleOutput }); + + const result = yarn2Proxy.initPackageJson(); + + expect(syncMock).toHaveBeenCalledWith( + 'yarn', + ['init'], + expect.objectContaining({ + cwd: process.cwd(), + env: process.env, + stdio: 'pipe', + encoding: 'utf-8', + }) + ); + + expect(result).toEqual(expect.any(String)); + }); + }); +}); diff --git a/lib/cli/src/js-package-manager/Yarn2Proxy.ts b/lib/cli/src/js-package-manager/Yarn2Proxy.ts new file mode 100644 index 000000000000..86ea0b70378d --- /dev/null +++ b/lib/cli/src/js-package-manager/Yarn2Proxy.ts @@ -0,0 +1,14 @@ +import spawn from 'cross-spawn'; +import { JsPackageManager } from './JsPackageManager'; + +export class Yarn2Proxy extends JsPackageManager { + initPackageJson() { + const results = spawn.sync('yarn', ['init'], { + cwd: process.cwd(), + env: process.env, + stdio: 'pipe', + encoding: 'utf-8', + }); + return results.stdout; + } +} From 0334c801fe4e1a4f7bbdc385d697b958050188ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABtan=20Maisse?= Date: Fri, 5 Jun 2020 21:51:25 +0200 Subject: [PATCH 02/22] refactor: create a JsPackageManagerFactory It returns an NPMProxy, YarnProxy or Yarn2Proxy according to user project setup: Are `yarn` or `npm` command available? Is there any `yarn.lock` file? --- .../JsPackageManagerFactory.test.ts | 136 ++++++++++++++++++ .../JsPackageManagerFactory.ts | 46 ++++++ lib/cli/src/js-package-manager/index.ts | 2 + 3 files changed, 184 insertions(+) create mode 100644 lib/cli/src/js-package-manager/JsPackageManagerFactory.test.ts create mode 100644 lib/cli/src/js-package-manager/JsPackageManagerFactory.ts create mode 100644 lib/cli/src/js-package-manager/index.ts diff --git a/lib/cli/src/js-package-manager/JsPackageManagerFactory.test.ts b/lib/cli/src/js-package-manager/JsPackageManagerFactory.test.ts new file mode 100644 index 000000000000..8bbe8481ecc7 --- /dev/null +++ b/lib/cli/src/js-package-manager/JsPackageManagerFactory.test.ts @@ -0,0 +1,136 @@ +import { sync as spawnSync } from 'cross-spawn'; +import { sync as findUpSync } from 'find-up'; +import { JsPackageManagerFactory } from './JsPackageManagerFactory'; +import { NPMProxy } from './NPMProxy'; +import { Yarn1Proxy } from './Yarn1Proxy'; +import { Yarn2Proxy } from './Yarn2Proxy'; + +jest.mock('cross-spawn'); +const spawnSyncMock = spawnSync as jest.Mock; + +jest.mock('find-up'); +const findUpSyncMock = (findUpSync as unknown) as jest.Mock; +findUpSyncMock.mockReturnValue(undefined); + +describe('JsPackageManagerFactory', () => { + describe('getPackageManager', () => { + describe('return an NPM proxy', () => { + it('when `useNpm` option is used', () => { + expect(JsPackageManagerFactory.getPackageManager(true)).toBeInstanceOf(NPMProxy); + }); + + it('when NPM command is ok, Yarn is ok, there is no `yarn.lock` file', () => { + spawnSyncMock.mockImplementation((command) => { + return command === 'yarn' + ? { + // Yarn is ok + status: 0, + output: '1.22.4', + } + : { + // NPM is ok + status: 0, + output: '6.5.12', + }; + }); + + // There is no yarn.lock + findUpSyncMock.mockImplementation((file) => (file === 'yarn.lock' ? undefined : '')); + + expect(JsPackageManagerFactory.getPackageManager(false)).toBeInstanceOf(NPMProxy); + }); + }); + + describe('return a Yarn 1 proxy', () => { + it('when Yarn command is ok, Yarn version is <2, NPM is ko', () => { + spawnSyncMock.mockImplementation((command) => { + return command === 'yarn' + ? { + // Yarn is ok + status: 0, + output: '1.22.4', + } + : { + // NPM is ko + status: 1, + }; + }); + + // there is no + findUpSyncMock.mockReturnValue(undefined); + + expect(JsPackageManagerFactory.getPackageManager(false)).toBeInstanceOf(Yarn1Proxy); + }); + + it('when Yarn command is ok, Yarn version is <2, NPM is ok, there is a `yarn.lock` file', () => { + spawnSyncMock.mockImplementation((command) => { + return command === 'yarn' + ? { + // Yarn is ok + status: 0, + output: '1.22.4', + } + : { + // NPM is ok + status: 0, + output: '6.5.12', + }; + }); + + // There is a yarn.lock + findUpSyncMock.mockImplementation((file) => + file === 'yarn.lock' ? '/Users/johndoe/Documents/yarn.lock' : undefined + ); + + expect(JsPackageManagerFactory.getPackageManager(false)).toBeInstanceOf(Yarn1Proxy); + }); + }); + + describe('return a Yarn 2 proxy', () => { + it('when Yarn command is ok, Yarn version is >=2, NPM is ko', () => { + spawnSyncMock.mockImplementation((command) => { + return command === 'yarn' + ? { + // Yarn is ok + status: 0, + output: '2.0.0-rc.33', + } + : { + // NPM is ko + status: 1, + }; + }); + + expect(JsPackageManagerFactory.getPackageManager(false)).toBeInstanceOf(Yarn2Proxy); + }); + + it('when Yarn command is ok, Yarn version is >=2, NPM is ok, there is a `yarn.lock` file', () => { + spawnSyncMock.mockImplementation((command) => { + return command === 'yarn' + ? { + // Yarn is ok + status: 0, + output: '2.0.0-rc.33', + } + : { + // NPM is ok + status: 0, + output: '6.5.12', + }; + }); + + // There is a yarn.lock + findUpSyncMock.mockImplementation((file) => + file === 'yarn.lock' ? '/Users/johndoe/Documents/yarn.lock' : undefined + ); + + expect(JsPackageManagerFactory.getPackageManager(false)).toBeInstanceOf(Yarn2Proxy); + }); + }); + + it('throws an error if Yarn is ko and NPM is ko', () => { + spawnSyncMock.mockReturnValue({ status: 1 }); + expect(() => JsPackageManagerFactory.getPackageManager(false)).toThrow(); + }); + }); +}); diff --git a/lib/cli/src/js-package-manager/JsPackageManagerFactory.ts b/lib/cli/src/js-package-manager/JsPackageManagerFactory.ts new file mode 100644 index 000000000000..6a7c9d38840b --- /dev/null +++ b/lib/cli/src/js-package-manager/JsPackageManagerFactory.ts @@ -0,0 +1,46 @@ +import { sync as spawnSync } from 'cross-spawn'; +import { sync as findUpSync } from 'find-up'; +import { NPMProxy } from './NPMProxy'; +import { JsPackageManager } from './JsPackageManager'; +import { Yarn2Proxy } from './Yarn2Proxy'; +import { Yarn1Proxy } from './Yarn1Proxy'; + +export class JsPackageManagerFactory { + public static getPackageManager(forceNpmUsage = false): JsPackageManager { + if (forceNpmUsage) { + return new NPMProxy(); + } + + const yarnVersion = getYarnVersion(); + const hasYarnLockFile = findUpSync('yarn.lock'); + + const hasNPMCommand = hasNPM(); + + if (yarnVersion && (hasYarnLockFile || !hasNPMCommand)) { + return yarnVersion === 1 ? new Yarn1Proxy() : new Yarn2Proxy(); + } + + if (hasNPMCommand) { + return new NPMProxy(); + } + + throw new Error('Unable to find a usable package manager within NPM, Yarn and Yarn 2'); + } +} + +function hasNPM() { + const npmVersionCommand = spawnSync('npm', ['--version']); + return npmVersionCommand.status === 0; +} + +function getYarnVersion(): 1 | 2 | undefined { + const yarnVersionCommand = spawnSync('yarn', ['--version']); + + if (yarnVersionCommand.status !== 0) { + return undefined; + } + + const yarnVersion = yarnVersionCommand.output.toString().replace(/,/g, '').replace(/"/g, ''); + + return /^1\.+/.test(yarnVersion) ? 1 : 2; +} diff --git a/lib/cli/src/js-package-manager/index.ts b/lib/cli/src/js-package-manager/index.ts new file mode 100644 index 000000000000..691b1e0b805b --- /dev/null +++ b/lib/cli/src/js-package-manager/index.ts @@ -0,0 +1,2 @@ +export * from './JsPackageManagerFactory'; +export * from './JsPackageManager'; From 100ffac29c46a67d28b014e09aad5fffb0bc2b9d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABtan=20Maisse?= Date: Sun, 7 Jun 2020 18:29:41 +0200 Subject: [PATCH 03/22] refactor: use `getRunStorybookCommand` from package manager It avoids to use a ternary expression to define the displayed string and encapsulate specific package managers behaviors in their own classes. --- lib/cli/src/initiate.ts | 9 ++++----- lib/cli/src/js-package-manager/JsPackageManager.ts | 2 ++ lib/cli/src/js-package-manager/NPMProxy.ts | 4 ++++ lib/cli/src/js-package-manager/Yarn1Proxy.ts | 4 ++++ lib/cli/src/js-package-manager/Yarn2Proxy.ts | 4 ++++ 5 files changed, 18 insertions(+), 5 deletions(-) diff --git a/lib/cli/src/initiate.ts b/lib/cli/src/initiate.ts index edaf6127e75e..61d2daf5eec9 100644 --- a/lib/cli/src/initiate.ts +++ b/lib/cli/src/initiate.ts @@ -36,6 +36,7 @@ import preactGenerator from './generators/PREACT'; import svelteGenerator from './generators/SVELTE'; import raxGenerator from './generators/RAX'; import { warn } from './warn'; +import { JsPackageManagerFactory } from './js-package-manager/JsPackageManagerFactory'; const logger = console; @@ -51,10 +52,10 @@ type CommandOptions = { }; const installStorybook = (projectType: ProjectType, options: CommandOptions): Promise => { - const useYarn = Boolean(options.useNpm !== true) && hasYarn(); + const packageManager = JsPackageManagerFactory.getPackageManager(options.useNpm); const npmOptions = { - useYarn, + useYarn: Boolean(options.useNpm !== true) && hasYarn(), installAsDevDependencies: true, skipInstall: options.skipInstall, }; @@ -69,15 +70,13 @@ const installStorybook = (projectType: ProjectType, options: CommandOptions): Pr storyFormat: options.storyFormat || defaultStoryFormat, }; - const runStorybookCommand = useYarn ? 'yarn storybook' : 'npm run storybook'; - const end = () => { if (!options.skipInstall) { installDepsFromPackageJson(npmOptions); } logger.log('\nTo run your storybook, type:\n'); - codeLog([runStorybookCommand]); + codeLog([packageManager.getRunStorybookCommand()]); logger.log('\nFor more information visit:', chalk.cyan('https://storybook.js.org')); // Add a new line for the clear visibility. diff --git a/lib/cli/src/js-package-manager/JsPackageManager.ts b/lib/cli/src/js-package-manager/JsPackageManager.ts index 8a407c6c8d83..bcf1cbcd8827 100644 --- a/lib/cli/src/js-package-manager/JsPackageManager.ts +++ b/lib/cli/src/js-package-manager/JsPackageManager.ts @@ -1,3 +1,5 @@ export abstract class JsPackageManager { public abstract initPackageJson(): void; + + public abstract getRunStorybookCommand(): string; } diff --git a/lib/cli/src/js-package-manager/NPMProxy.ts b/lib/cli/src/js-package-manager/NPMProxy.ts index 2e4ca422c080..6145675570fc 100644 --- a/lib/cli/src/js-package-manager/NPMProxy.ts +++ b/lib/cli/src/js-package-manager/NPMProxy.ts @@ -11,4 +11,8 @@ export class NPMProxy extends JsPackageManager { }); return results.stdout; } + + getRunStorybookCommand(): string { + return 'npm run storybook'; + } } diff --git a/lib/cli/src/js-package-manager/Yarn1Proxy.ts b/lib/cli/src/js-package-manager/Yarn1Proxy.ts index fc2a3bec73a7..c90b77fa5a45 100644 --- a/lib/cli/src/js-package-manager/Yarn1Proxy.ts +++ b/lib/cli/src/js-package-manager/Yarn1Proxy.ts @@ -11,4 +11,8 @@ export class Yarn1Proxy extends JsPackageManager { }); return results.stdout; } + + getRunStorybookCommand(): string { + return 'yarn storybook'; + } } diff --git a/lib/cli/src/js-package-manager/Yarn2Proxy.ts b/lib/cli/src/js-package-manager/Yarn2Proxy.ts index 86ea0b70378d..6965239f62ac 100644 --- a/lib/cli/src/js-package-manager/Yarn2Proxy.ts +++ b/lib/cli/src/js-package-manager/Yarn2Proxy.ts @@ -11,4 +11,8 @@ export class Yarn2Proxy extends JsPackageManager { }); return results.stdout; } + + getRunStorybookCommand(): string { + return 'yarn storybook'; + } } From aa02e872dc22e43a2427e4ca7cbf5fe732aea667 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABtan=20Maisse?= Date: Sun, 7 Jun 2020 18:39:54 +0200 Subject: [PATCH 04/22] refactor: add tmp extract check to avoid issue in unit tests As `hasYarn` function is called when `npm_init.ts` is parsed and loaded there are some issue with mock in unit tests. --- lib/cli/src/has_yarn.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/cli/src/has_yarn.ts b/lib/cli/src/has_yarn.ts index 62991684dd1a..b427eb1ee9d3 100644 --- a/lib/cli/src/has_yarn.ts +++ b/lib/cli/src/has_yarn.ts @@ -9,7 +9,7 @@ export function hasYarn() { const lockFile = findUp.sync(['yarn.lock', 'package-lock.json']); const hasYarnLock = lockFile && path.basename(lockFile) === 'yarn.lock'; - if (yarnAvailable.status === 0 && (hasYarnLock || npmAvailable.status !== 0)) { + if (yarnAvailable && yarnAvailable.status === 0 && (hasYarnLock || npmAvailable.status !== 0)) { return true; } return false; From a858990fa6ab45144f416a1d487b1e50829d706a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABtan=20Maisse?= Date: Sun, 7 Jun 2020 18:40:31 +0200 Subject: [PATCH 05/22] refactor: move `installDepsFromPackageJson` function to JsPackageManager class and subclasses --- lib/cli/src/helpers.ts | 21 ------------------ lib/cli/src/initiate.ts | 13 ++++------- .../js-package-manager/JsPackageManager.ts | 22 +++++++++++++++++++ lib/cli/src/js-package-manager/NPMProxy.ts | 8 +++++-- lib/cli/src/js-package-manager/Yarn1Proxy.ts | 8 +++++-- lib/cli/src/js-package-manager/Yarn2Proxy.ts | 8 +++++-- 6 files changed, 44 insertions(+), 36 deletions(-) diff --git a/lib/cli/src/helpers.ts b/lib/cli/src/helpers.ts index 63eca144909c..2893ecd8d6bb 100644 --- a/lib/cli/src/helpers.ts +++ b/lib/cli/src/helpers.ts @@ -182,27 +182,6 @@ export function codeLog(codeLines: string[], leftPadAmount?: number) { logger.log(finalResult); } -export function installDepsFromPackageJson(options: NpmOptions) { - let done = commandLog('Preparing to install dependencies'); - done(); - logger.log(); - - let result; - if (options.useYarn) { - result = spawnSync('yarn', { stdio: 'inherit' }); - } else { - result = spawnSync('npm', ['install'], { stdio: 'inherit' }); - } - - logger.log(); - done = commandLog('Installing dependencies'); - if (result.status !== 0) { - done('An error occurred while installing dependencies.'); - process.exit(1); - } - done(); -} - /** * Add dependencies to a project using `yarn add` or `npm install`. * diff --git a/lib/cli/src/initiate.ts b/lib/cli/src/initiate.ts index 61d2daf5eec9..e63cdc60c3ce 100644 --- a/lib/cli/src/initiate.ts +++ b/lib/cli/src/initiate.ts @@ -9,13 +9,7 @@ import { StoryFormat, SupportedLanguage, } from './project_types'; -import { - commandLog, - codeLog, - paddedLog, - installDepsFromPackageJson, - getPackageJson, -} from './helpers'; +import { commandLog, codeLog, paddedLog, getPackageJson } from './helpers'; import angularGenerator from './generators/ANGULAR'; import emberGenerator from './generators/EMBER'; import meteorGenerator from './generators/METEOR'; @@ -37,6 +31,7 @@ import svelteGenerator from './generators/SVELTE'; import raxGenerator from './generators/RAX'; import { warn } from './warn'; import { JsPackageManagerFactory } from './js-package-manager/JsPackageManagerFactory'; +import { NpmOptions } from './NpmOptions'; const logger = console; @@ -54,7 +49,7 @@ type CommandOptions = { const installStorybook = (projectType: ProjectType, options: CommandOptions): Promise => { const packageManager = JsPackageManagerFactory.getPackageManager(options.useNpm); - const npmOptions = { + const npmOptions: NpmOptions = { useYarn: Boolean(options.useNpm !== true) && hasYarn(), installAsDevDependencies: true, skipInstall: options.skipInstall, @@ -72,7 +67,7 @@ const installStorybook = (projectType: ProjectType, options: CommandOptions): Pr const end = () => { if (!options.skipInstall) { - installDepsFromPackageJson(npmOptions); + packageManager.installDependencies(); } logger.log('\nTo run your storybook, type:\n'); diff --git a/lib/cli/src/js-package-manager/JsPackageManager.ts b/lib/cli/src/js-package-manager/JsPackageManager.ts index bcf1cbcd8827..446025897e18 100644 --- a/lib/cli/src/js-package-manager/JsPackageManager.ts +++ b/lib/cli/src/js-package-manager/JsPackageManager.ts @@ -1,5 +1,27 @@ +import { commandLog } from '../helpers'; + +const logger = console; + export abstract class JsPackageManager { public abstract initPackageJson(): void; public abstract getRunStorybookCommand(): string; + + public installDependencies(): void { + let done = commandLog('Preparing to install dependencies'); + done(); + logger.log(); + + const result = this.runInstall(); + + logger.log(); + done = commandLog('Installing dependencies'); + if (result.status !== 0) { + done('An error occurred while installing dependencies.'); + process.exit(1); + } + done(); + } + + protected abstract runInstall(): { status: number }; } diff --git a/lib/cli/src/js-package-manager/NPMProxy.ts b/lib/cli/src/js-package-manager/NPMProxy.ts index 6145675570fc..b3d4b46d7ade 100644 --- a/lib/cli/src/js-package-manager/NPMProxy.ts +++ b/lib/cli/src/js-package-manager/NPMProxy.ts @@ -1,9 +1,9 @@ -import spawn from 'cross-spawn'; +import { sync as spawnSync } from 'cross-spawn'; import { JsPackageManager } from './JsPackageManager'; export class NPMProxy extends JsPackageManager { initPackageJson() { - const results = spawn.sync('npm', ['init', '-y'], { + const results = spawnSync('npm', ['init', '-y'], { cwd: process.cwd(), env: process.env, stdio: 'pipe', @@ -15,4 +15,8 @@ export class NPMProxy extends JsPackageManager { getRunStorybookCommand(): string { return 'npm run storybook'; } + + protected runInstall(): { status: number } { + return spawnSync('npm', ['install'], { stdio: 'inherit' }); + } } diff --git a/lib/cli/src/js-package-manager/Yarn1Proxy.ts b/lib/cli/src/js-package-manager/Yarn1Proxy.ts index c90b77fa5a45..c1d8fdf93536 100644 --- a/lib/cli/src/js-package-manager/Yarn1Proxy.ts +++ b/lib/cli/src/js-package-manager/Yarn1Proxy.ts @@ -1,9 +1,9 @@ -import spawn from 'cross-spawn'; +import { sync as spawnSync } from 'cross-spawn'; import { JsPackageManager } from './JsPackageManager'; export class Yarn1Proxy extends JsPackageManager { initPackageJson() { - const results = spawn.sync('yarn', ['init', '-y'], { + const results = spawnSync('yarn', ['init', '-y'], { cwd: process.cwd(), env: process.env, stdio: 'pipe', @@ -15,4 +15,8 @@ export class Yarn1Proxy extends JsPackageManager { getRunStorybookCommand(): string { return 'yarn storybook'; } + + protected runInstall(): { status: number } { + return spawnSync('yarn', { stdio: 'inherit' }); + } } diff --git a/lib/cli/src/js-package-manager/Yarn2Proxy.ts b/lib/cli/src/js-package-manager/Yarn2Proxy.ts index 6965239f62ac..e29d2a17ad30 100644 --- a/lib/cli/src/js-package-manager/Yarn2Proxy.ts +++ b/lib/cli/src/js-package-manager/Yarn2Proxy.ts @@ -1,9 +1,9 @@ -import spawn from 'cross-spawn'; +import { sync as spawnSync } from 'cross-spawn'; import { JsPackageManager } from './JsPackageManager'; export class Yarn2Proxy extends JsPackageManager { initPackageJson() { - const results = spawn.sync('yarn', ['init'], { + const results = spawnSync('yarn', ['init'], { cwd: process.cwd(), env: process.env, stdio: 'pipe', @@ -15,4 +15,8 @@ export class Yarn2Proxy extends JsPackageManager { getRunStorybookCommand(): string { return 'yarn storybook'; } + + protected runInstall(): { status: number } { + return spawnSync('yarn', { stdio: 'inherit' }); + } } From 10e4101b20808b2c4de23b4e2820cf21e46c7a9f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABtan=20Maisse?= Date: Sun, 7 Jun 2020 18:54:52 +0200 Subject: [PATCH 06/22] refactor: introduce JsPackageManager in all generators --- lib/cli/src/generators/ANGULAR/index.ts | 2 +- lib/cli/src/generators/AURELIA/index.ts | 6 ++- lib/cli/src/generators/EMBER/index.ts | 2 +- lib/cli/src/generators/Generator.ts | 7 +++- lib/cli/src/generators/HTML/index.ts | 2 +- lib/cli/src/generators/MARIONETTE/index.ts | 2 +- lib/cli/src/generators/MARKO/index.ts | 2 +- lib/cli/src/generators/METEOR/index.ts | 2 +- lib/cli/src/generators/MITHRIL/index.ts | 2 +- lib/cli/src/generators/PREACT/index.ts | 2 +- lib/cli/src/generators/RAX/index.ts | 2 +- lib/cli/src/generators/REACT/index.ts | 2 +- lib/cli/src/generators/REACT_NATIVE/index.ts | 2 + lib/cli/src/generators/REACT_SCRIPTS/index.ts | 2 +- lib/cli/src/generators/RIOT/index.ts | 2 +- lib/cli/src/generators/SFC_VUE/index.ts | 2 +- lib/cli/src/generators/SVELTE/index.ts | 2 +- lib/cli/src/generators/VUE/index.ts | 2 +- .../src/generators/WEB-COMPONENTS/index.ts | 2 +- lib/cli/src/generators/WEBPACK_REACT/index.ts | 2 +- lib/cli/src/initiate.ts | 42 ++++++++++--------- 21 files changed, 52 insertions(+), 39 deletions(-) diff --git a/lib/cli/src/generators/ANGULAR/index.ts b/lib/cli/src/generators/ANGULAR/index.ts index cc9d5921366f..6ea7aab11808 100644 --- a/lib/cli/src/generators/ANGULAR/index.ts +++ b/lib/cli/src/generators/ANGULAR/index.ts @@ -64,7 +64,7 @@ function editAngularAppTsConfig() { writeFileAsJson(getAngularAppTsConfigPath(), tsConfigJson); } -const generator: Generator = async (npmOptions, { storyFormat }) => { +const generator: Generator = async (_packageManager, npmOptions, { storyFormat }) => { if (!isDefaultProjectSet()) { throw new Error( 'Could not find a default project in your Angular workspace.\nSet a defaultProject in your angular.json and re-run the installation.' diff --git a/lib/cli/src/generators/AURELIA/index.ts b/lib/cli/src/generators/AURELIA/index.ts index 3f7362f13759..ec6ef6323a1c 100644 --- a/lib/cli/src/generators/AURELIA/index.ts +++ b/lib/cli/src/generators/AURELIA/index.ts @@ -26,7 +26,11 @@ function addStorybookExcludeGlobToTsConfig() { tsConfigJson.exclude = [...exclude, glob]; writeFileAsJson('tsconfig.json', tsConfigJson); } -const generator: Generator = async (npmOptions, { storyFormat = StoryFormat.CSF }) => { +const generator: Generator = async ( + _packageManager, + npmOptions, + { storyFormat = StoryFormat.CSF } +) => { copyTemplate(__dirname, storyFormat); const packages = [ '@storybook/aurelia', diff --git a/lib/cli/src/generators/EMBER/index.ts b/lib/cli/src/generators/EMBER/index.ts index 874e81e6e2e7..7d0e7adb6052 100644 --- a/lib/cli/src/generators/EMBER/index.ts +++ b/lib/cli/src/generators/EMBER/index.ts @@ -8,7 +8,7 @@ import { } from '../../helpers'; import { Generator } from '../Generator'; -const generator: Generator = async (npmOptions, { storyFormat }) => { +const generator: Generator = async (_packageManager, npmOptions, { storyFormat }) => { const [ storybookVersion, babelPluginEmberModulePolyfillVersion, diff --git a/lib/cli/src/generators/Generator.ts b/lib/cli/src/generators/Generator.ts index b6143c0c92dc..7d081f55c9a2 100644 --- a/lib/cli/src/generators/Generator.ts +++ b/lib/cli/src/generators/Generator.ts @@ -1,8 +1,13 @@ import { NpmOptions } from '../NpmOptions'; import { StoryFormat } from '../project_types'; +import { JsPackageManager } from '../js-package-manager'; export type GeneratorOptions = { storyFormat: StoryFormat; }; -export type Generator = (npmOptions: NpmOptions, options: GeneratorOptions) => Promise; +export type Generator = ( + packageManager: JsPackageManager, + npmOptions: NpmOptions, + options: GeneratorOptions +) => Promise; diff --git a/lib/cli/src/generators/HTML/index.ts b/lib/cli/src/generators/HTML/index.ts index 25d850192b6c..84fc3d2eb1da 100755 --- a/lib/cli/src/generators/HTML/index.ts +++ b/lib/cli/src/generators/HTML/index.ts @@ -9,7 +9,7 @@ import { import { StoryFormat } from '../../project_types'; import { Generator } from '../Generator'; -const generator: Generator = async (npmOptions, { storyFormat }) => { +const generator: Generator = async (_packageManager, npmOptions, { storyFormat }) => { const packages = ['@storybook/html', '@storybook/addon-actions', '@storybook/addon-links']; const versionedPackages = await getVersionedPackages(npmOptions, ...packages); diff --git a/lib/cli/src/generators/MARIONETTE/index.ts b/lib/cli/src/generators/MARIONETTE/index.ts index e3ce805931a8..f75b549993be 100644 --- a/lib/cli/src/generators/MARIONETTE/index.ts +++ b/lib/cli/src/generators/MARIONETTE/index.ts @@ -9,7 +9,7 @@ import { } from '../../helpers'; import { Generator } from '../Generator'; -const generator: Generator = async (npmOptions) => { +const generator: Generator = async (_packageManager, npmOptions) => { const storybookVersion = await getVersion(npmOptions, '@storybook/marionette'); fse.copySync(path.resolve(__dirname, 'template/'), '.', { overwrite: true }); diff --git a/lib/cli/src/generators/MARKO/index.ts b/lib/cli/src/generators/MARKO/index.ts index b8a3bc0e40e1..47e319e16196 100644 --- a/lib/cli/src/generators/MARKO/index.ts +++ b/lib/cli/src/generators/MARKO/index.ts @@ -8,7 +8,7 @@ import { } from '../../helpers'; import { Generator } from '../Generator'; -const generator: Generator = async (npmOptions, { storyFormat }) => { +const generator: Generator = async (_packageManager, npmOptions, { storyFormat }) => { const [storybookVersion, addonActionVersion, addonKnobsVersion] = await getVersions( npmOptions, '@storybook/marko', diff --git a/lib/cli/src/generators/METEOR/index.ts b/lib/cli/src/generators/METEOR/index.ts index 6420a01f0b03..7ba2392a8c58 100644 --- a/lib/cli/src/generators/METEOR/index.ts +++ b/lib/cli/src/generators/METEOR/index.ts @@ -10,7 +10,7 @@ import { } from '../../helpers'; import { Generator } from '../Generator'; -const generator: Generator = async (npmOptions, { storyFormat }) => { +const generator: Generator = async (_packageManager, npmOptions, { storyFormat }) => { const [ storybookVersion, actionsVersion, diff --git a/lib/cli/src/generators/MITHRIL/index.ts b/lib/cli/src/generators/MITHRIL/index.ts index d6bff9454643..e4f9fd2045a1 100644 --- a/lib/cli/src/generators/MITHRIL/index.ts +++ b/lib/cli/src/generators/MITHRIL/index.ts @@ -8,7 +8,7 @@ import { } from '../../helpers'; import { Generator } from '../Generator'; -const generator: Generator = async (npmOptions, { storyFormat }) => { +const generator: Generator = async (_packageManager, npmOptions, { storyFormat }) => { const [ storybookVersion, actionsVersion, diff --git a/lib/cli/src/generators/PREACT/index.ts b/lib/cli/src/generators/PREACT/index.ts index 42c9eb416c9d..902a2d31f1ee 100644 --- a/lib/cli/src/generators/PREACT/index.ts +++ b/lib/cli/src/generators/PREACT/index.ts @@ -8,7 +8,7 @@ import { } from '../../helpers'; import { Generator } from '../Generator'; -const generator: Generator = async (npmOptions, { storyFormat }) => { +const generator: Generator = async (_packageManager, npmOptions, { storyFormat }) => { const [storybookVersion, actionsVersion, linksVersion, addonsVersion] = await getVersions( npmOptions, '@storybook/preact', diff --git a/lib/cli/src/generators/RAX/index.ts b/lib/cli/src/generators/RAX/index.ts index 4ac18e259ab9..780ce27e4d48 100644 --- a/lib/cli/src/generators/RAX/index.ts +++ b/lib/cli/src/generators/RAX/index.ts @@ -8,7 +8,7 @@ import { } from '../../helpers'; import { Generator } from '../Generator'; -const generator: Generator = async (npmOptions, { storyFormat }) => { +const generator: Generator = async (_packageManager, npmOptions, { storyFormat }) => { const [ storybookVersion, actionsVersion, diff --git a/lib/cli/src/generators/REACT/index.ts b/lib/cli/src/generators/REACT/index.ts index 586dac39814b..7f6182cfed29 100644 --- a/lib/cli/src/generators/REACT/index.ts +++ b/lib/cli/src/generators/REACT/index.ts @@ -9,7 +9,7 @@ import { import { StoryFormat } from '../../project_types'; import { Generator } from '../Generator'; -const generator: Generator = async (npmOptions, { storyFormat }) => { +const generator: Generator = async (_packageManager, npmOptions, { storyFormat }) => { const packages = [ '@storybook/react', '@storybook/addon-actions', diff --git a/lib/cli/src/generators/REACT_NATIVE/index.ts b/lib/cli/src/generators/REACT_NATIVE/index.ts index aad02bcb16c6..e58b31b9a965 100644 --- a/lib/cli/src/generators/REACT_NATIVE/index.ts +++ b/lib/cli/src/generators/REACT_NATIVE/index.ts @@ -11,8 +11,10 @@ import { } from '../../helpers'; import { NpmOptions } from '../../NpmOptions'; import { GeneratorOptions } from '../Generator'; +import { JsPackageManager } from '../../js-package-manager'; export default async ( + _packageManager: JsPackageManager, npmOptions: NpmOptions, installServer: boolean, { storyFormat }: GeneratorOptions diff --git a/lib/cli/src/generators/REACT_SCRIPTS/index.ts b/lib/cli/src/generators/REACT_SCRIPTS/index.ts index cc43eafdb98e..d5ff30f9ff98 100644 --- a/lib/cli/src/generators/REACT_SCRIPTS/index.ts +++ b/lib/cli/src/generators/REACT_SCRIPTS/index.ts @@ -11,7 +11,7 @@ import { import { StoryFormat } from '../../project_types'; import { Generator } from '../Generator'; -const generator: Generator = async (npmOptions, { storyFormat }) => { +const generator: Generator = async (_packageManager, npmOptions, { storyFormat }) => { const packages = [ '@storybook/react', '@storybook/preset-create-react-app', diff --git a/lib/cli/src/generators/RIOT/index.ts b/lib/cli/src/generators/RIOT/index.ts index 2c624431018a..75e2c9e544c6 100644 --- a/lib/cli/src/generators/RIOT/index.ts +++ b/lib/cli/src/generators/RIOT/index.ts @@ -8,7 +8,7 @@ import { } from '../../helpers'; import { Generator } from '../Generator'; -const generator: Generator = async (npmOptions, { storyFormat }) => { +const generator: Generator = async (_packageManager, npmOptions, { storyFormat }) => { const [ storybookVersion, actionsVersion, diff --git a/lib/cli/src/generators/SFC_VUE/index.ts b/lib/cli/src/generators/SFC_VUE/index.ts index 0f85dbce6b12..ebb8d3fcb5da 100644 --- a/lib/cli/src/generators/SFC_VUE/index.ts +++ b/lib/cli/src/generators/SFC_VUE/index.ts @@ -9,7 +9,7 @@ import { import { StoryFormat } from '../../project_types'; import { Generator } from '../Generator'; -const generator: Generator = async (npmOptions, { storyFormat }) => { +const generator: Generator = async (_packageManager, npmOptions, { storyFormat }) => { const packages = [ '@storybook/vue', '@storybook/addon-actions', diff --git a/lib/cli/src/generators/SVELTE/index.ts b/lib/cli/src/generators/SVELTE/index.ts index 9da7bfa15463..9b4933e83411 100644 --- a/lib/cli/src/generators/SVELTE/index.ts +++ b/lib/cli/src/generators/SVELTE/index.ts @@ -8,7 +8,7 @@ import { } from '../../helpers'; import { Generator } from '../Generator'; -const generator: Generator = async (npmOptions, { storyFormat }) => { +const generator: Generator = async (_packageManager, npmOptions, { storyFormat }) => { const [ storybookVersion, actionsVersion, diff --git a/lib/cli/src/generators/VUE/index.ts b/lib/cli/src/generators/VUE/index.ts index d35af935858a..122dbacb2378 100644 --- a/lib/cli/src/generators/VUE/index.ts +++ b/lib/cli/src/generators/VUE/index.ts @@ -11,7 +11,7 @@ import { import { StoryFormat } from '../../project_types'; import { Generator } from '../Generator'; -const generator: Generator = async (npmOptions, { storyFormat }) => { +const generator: Generator = async (_packageManager, npmOptions, { storyFormat }) => { const packages = [ '@storybook/vue', '@storybook/addon-actions', diff --git a/lib/cli/src/generators/WEB-COMPONENTS/index.ts b/lib/cli/src/generators/WEB-COMPONENTS/index.ts index 373eac327a67..1cd2e2597b46 100755 --- a/lib/cli/src/generators/WEB-COMPONENTS/index.ts +++ b/lib/cli/src/generators/WEB-COMPONENTS/index.ts @@ -10,7 +10,7 @@ import { import { StoryFormat } from '../../project_types'; import { Generator } from '../Generator'; -const generator: Generator = async (npmOptions, { storyFormat }) => { +const generator: Generator = async (_packageManager, npmOptions, { storyFormat }) => { const packages = [ '@storybook/web-components', '@storybook/addon-actions', diff --git a/lib/cli/src/generators/WEBPACK_REACT/index.ts b/lib/cli/src/generators/WEBPACK_REACT/index.ts index 75bec7324ed2..abd2babbcbe9 100644 --- a/lib/cli/src/generators/WEBPACK_REACT/index.ts +++ b/lib/cli/src/generators/WEBPACK_REACT/index.ts @@ -9,7 +9,7 @@ import { import { StoryFormat } from '../../project_types'; import { Generator } from '../Generator'; -const generator: Generator = async (npmOptions, { storyFormat }) => { +const generator: Generator = async (_packageManager, npmOptions, { storyFormat }) => { const packages = [ '@storybook/react', '@storybook/addon-actions', diff --git a/lib/cli/src/initiate.ts b/lib/cli/src/initiate.ts index e63cdc60c3ce..b166b2c90bcb 100644 --- a/lib/cli/src/initiate.ts +++ b/lib/cli/src/initiate.ts @@ -30,7 +30,7 @@ import preactGenerator from './generators/PREACT'; import svelteGenerator from './generators/SVELTE'; import raxGenerator from './generators/RAX'; import { warn } from './warn'; -import { JsPackageManagerFactory } from './js-package-manager/JsPackageManagerFactory'; +import { JsPackageManagerFactory } from './js-package-manager'; import { NpmOptions } from './NpmOptions'; const logger = console; @@ -100,12 +100,12 @@ const installStorybook = (projectType: ProjectType, options: CommandOptions): Pr .then(end); case ProjectType.REACT_SCRIPTS: - return reactScriptsGenerator(npmOptions, generatorOptions) + return reactScriptsGenerator(packageManager, npmOptions, generatorOptions) .then(commandLog('Adding storybook support to your "Create React App" based project')) .then(end); case ProjectType.REACT: - return reactGenerator(npmOptions, generatorOptions) + return reactGenerator(packageManager, npmOptions, generatorOptions) .then(commandLog('Adding storybook support to your "React" app')) .then(end); @@ -122,7 +122,9 @@ const installStorybook = (projectType: ProjectType, options: CommandOptions): Pr }, ]) as Promise<{ server: boolean }>) ) - .then(({ server }) => reactNativeGenerator(npmOptions, server, generatorOptions)) + .then(({ server }) => + reactNativeGenerator(packageManager, npmOptions, server, generatorOptions) + ) .then(commandLog('Adding storybook support to your "React Native" app')) .then(end) .then(() => { @@ -136,82 +138,82 @@ const installStorybook = (projectType: ProjectType, options: CommandOptions): Pr } case ProjectType.METEOR: - return meteorGenerator(npmOptions, generatorOptions) + return meteorGenerator(packageManager, npmOptions, generatorOptions) .then(commandLog('Adding storybook support to your "Meteor" app')) .then(end); case ProjectType.WEBPACK_REACT: - return webpackReactGenerator(npmOptions, generatorOptions) + return webpackReactGenerator(packageManager, npmOptions, generatorOptions) .then(commandLog('Adding storybook support to your "Webpack React" app')) .then(end); case ProjectType.REACT_PROJECT: - return reactGenerator(npmOptions, generatorOptions) + return reactGenerator(packageManager, npmOptions, generatorOptions) .then(commandLog('Adding storybook support to your "React" library')) .then(end); case ProjectType.SFC_VUE: - return sfcVueGenerator(npmOptions, generatorOptions) + return sfcVueGenerator(packageManager, npmOptions, generatorOptions) .then(commandLog('Adding storybook support to your "Single File Components Vue" app')) .then(end); case ProjectType.VUE: - return vueGenerator(npmOptions, generatorOptions) + return vueGenerator(packageManager, npmOptions, generatorOptions) .then(commandLog('Adding storybook support to your "Vue" app')) .then(end); case ProjectType.ANGULAR: - return angularGenerator(npmOptions, generatorOptions) + return angularGenerator(packageManager, npmOptions, generatorOptions) .then(commandLog('Adding storybook support to your "Angular" app')) .then(end); case ProjectType.EMBER: - return emberGenerator(npmOptions, generatorOptions) + return emberGenerator(packageManager, npmOptions, generatorOptions) .then(commandLog('Adding storybook support to your "Ember" app')) .then(end); case ProjectType.MITHRIL: - return mithrilGenerator(npmOptions, generatorOptions) + return mithrilGenerator(packageManager, npmOptions, generatorOptions) .then(commandLog('Adding storybook support to your "Mithril" app')) .then(end); case ProjectType.MARIONETTE: - return marionetteGenerator(npmOptions, generatorOptions) + return marionetteGenerator(packageManager, npmOptions, generatorOptions) .then(commandLog('Adding storybook support to your "Marionette.js" app')) .then(end); case ProjectType.MARKO: - return markoGenerator(npmOptions, generatorOptions) + return markoGenerator(packageManager, npmOptions, generatorOptions) .then(commandLog('Adding storybook support to your "Marko" app')) .then(end); case ProjectType.HTML: - return htmlGenerator(npmOptions, generatorOptions) + return htmlGenerator(packageManager, npmOptions, generatorOptions) .then(commandLog('Adding storybook support to your "HTML" app')) .then(end); case ProjectType.WEB_COMPONENTS: - return webComponentsGenerator(npmOptions, generatorOptions) + return webComponentsGenerator(packageManager, npmOptions, generatorOptions) .then(commandLog('Adding storybook support to your "web components" app')) .then(end); case ProjectType.RIOT: - return riotGenerator(npmOptions, generatorOptions) + return riotGenerator(packageManager, npmOptions, generatorOptions) .then(commandLog('Adding storybook support to your "riot.js" app')) .then(end); case ProjectType.PREACT: - return preactGenerator(npmOptions, generatorOptions) + return preactGenerator(packageManager, npmOptions, generatorOptions) .then(commandLog('Adding storybook support to your "Preact" app')) .then(end); case ProjectType.SVELTE: - return svelteGenerator(npmOptions, generatorOptions) + return svelteGenerator(packageManager, npmOptions, generatorOptions) .then(commandLog('Adding storybook support to your "Svelte" app')) .then(end); case ProjectType.RAX: - return raxGenerator(npmOptions, generatorOptions) + return raxGenerator(packageManager, npmOptions, generatorOptions) .then(commandLog('Adding storybook support to your "Rax" app')) .then(end); From 56de607807bda6a81ac0d6f0a73bc606e63c1b54 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABtan=20Maisse?= Date: Sun, 7 Jun 2020 19:25:56 +0200 Subject: [PATCH 07/22] refactor: move `retrievePackageJson` to JsPackageManager --- lib/cli/src/PackageJson.ts | 1 + lib/cli/src/generators/ANGULAR/index.ts | 14 ++++++---- lib/cli/src/generators/AURELIA/index.ts | 5 ++-- lib/cli/src/generators/EMBER/index.ts | 5 ++-- lib/cli/src/generators/HTML/index.ts | 5 ++-- lib/cli/src/generators/MARIONETTE/index.ts | 5 ++-- lib/cli/src/generators/MARKO/index.ts | 5 ++-- lib/cli/src/generators/METEOR/index.ts | 5 ++-- lib/cli/src/generators/MITHRIL/index.ts | 5 ++-- lib/cli/src/generators/PREACT/index.ts | 5 ++-- lib/cli/src/generators/RAX/index.ts | 5 ++-- lib/cli/src/generators/REACT/index.ts | 5 ++-- lib/cli/src/generators/REACT_NATIVE/index.ts | 5 ++-- lib/cli/src/generators/REACT_SCRIPTS/index.ts | 5 ++-- lib/cli/src/generators/RIOT/index.ts | 5 ++-- lib/cli/src/generators/SFC_VUE/index.ts | 5 ++-- lib/cli/src/generators/SVELTE/index.ts | 5 ++-- lib/cli/src/generators/VUE/index.ts | 5 ++-- .../src/generators/WEB-COMPONENTS/index.ts | 5 ++-- lib/cli/src/generators/WEBPACK_REACT/index.ts | 5 ++-- lib/cli/src/helpers.test.ts | 4 --- lib/cli/src/helpers.ts | 14 ---------- .../js-package-manager/JsPackageManager.ts | 26 +++++++++++++++++++ lib/cli/src/npm_init.ts | 14 ---------- 24 files changed, 72 insertions(+), 91 deletions(-) delete mode 100644 lib/cli/src/npm_init.ts diff --git a/lib/cli/src/PackageJson.ts b/lib/cli/src/PackageJson.ts index 2acfc43a55b5..d2313640227d 100644 --- a/lib/cli/src/PackageJson.ts +++ b/lib/cli/src/PackageJson.ts @@ -2,4 +2,5 @@ export type PackageJson = { dependencies?: Record; devDependencies?: Record; peerDependencies?: Record; + scripts?: Record; }; diff --git a/lib/cli/src/generators/ANGULAR/index.ts b/lib/cli/src/generators/ANGULAR/index.ts index 6ea7aab11808..631a07e66226 100644 --- a/lib/cli/src/generators/ANGULAR/index.ts +++ b/lib/cli/src/generators/ANGULAR/index.ts @@ -6,7 +6,6 @@ import { getAngularAppTsConfigPath, } from './angular-helpers'; import { - retrievePackageJson, getVersionedPackages, writePackageJson, getBabelDependencies, @@ -17,8 +16,13 @@ import { import { StoryFormat } from '../../project_types'; import { NpmOptions } from '../../NpmOptions'; import { Generator, GeneratorOptions } from '../Generator'; +import { JsPackageManager } from '../../js-package-manager'; -async function addDependencies(npmOptions: NpmOptions, { storyFormat }: GeneratorOptions) { +async function addDependencies( + packageManager: JsPackageManager, + npmOptions: NpmOptions, + { storyFormat }: GeneratorOptions +) { const packages = [ '@storybook/angular', '@storybook/addon-actions', @@ -32,7 +36,7 @@ async function addDependencies(npmOptions: NpmOptions, { storyFormat }: Generato const versionedPackages = await getVersionedPackages(npmOptions, ...packages); - const packageJson = await retrievePackageJson(); + const packageJson = packageManager.retrievePackageJson(); packageJson.dependencies = packageJson.dependencies || {}; packageJson.devDependencies = packageJson.devDependencies || {}; @@ -64,7 +68,7 @@ function editAngularAppTsConfig() { writeFileAsJson(getAngularAppTsConfigPath(), tsConfigJson); } -const generator: Generator = async (_packageManager, npmOptions, { storyFormat }) => { +const generator: Generator = async (packageManager, npmOptions, { storyFormat }) => { if (!isDefaultProjectSet()) { throw new Error( 'Could not find a default project in your Angular workspace.\nSet a defaultProject in your angular.json and re-run the installation.' @@ -73,7 +77,7 @@ const generator: Generator = async (_packageManager, npmOptions, { storyFormat } copyTemplate(__dirname, storyFormat); - await addDependencies(npmOptions, { storyFormat }); + await addDependencies(packageManager, npmOptions, { storyFormat }); editAngularAppTsConfig(); editStorybookTsConfig(path.resolve('./.storybook/tsconfig.json')); }; diff --git a/lib/cli/src/generators/AURELIA/index.ts b/lib/cli/src/generators/AURELIA/index.ts index ec6ef6323a1c..ebfef2c1cd79 100644 --- a/lib/cli/src/generators/AURELIA/index.ts +++ b/lib/cli/src/generators/AURELIA/index.ts @@ -3,7 +3,6 @@ import { writePackageJson, getBabelDependencies, installDependencies, - getPackageJson, writeFileAsJson, copyTemplate, readFileAsJson, @@ -27,7 +26,7 @@ function addStorybookExcludeGlobToTsConfig() { writeFileAsJson('tsconfig.json', tsConfigJson); } const generator: Generator = async ( - _packageManager, + packageManager, npmOptions, { storyFormat = StoryFormat.CSF } ) => { @@ -50,7 +49,7 @@ const generator: Generator = async ( } const versionedPackages = await getVersionedPackages(npmOptions, ...packages); - const packageJson = getPackageJson(); + const packageJson = packageManager.retrievePackageJson(); packageJson.dependencies = packageJson.dependencies || {}; packageJson.devDependencies = packageJson.devDependencies || {}; packageJson.scripts = packageJson.scripts || {}; diff --git a/lib/cli/src/generators/EMBER/index.ts b/lib/cli/src/generators/EMBER/index.ts index 7d0e7adb6052..c1a5e5f03afe 100644 --- a/lib/cli/src/generators/EMBER/index.ts +++ b/lib/cli/src/generators/EMBER/index.ts @@ -1,6 +1,5 @@ import { getVersions, - retrievePackageJson, writePackageJson, getBabelDependencies, installDependencies, @@ -8,7 +7,7 @@ import { } from '../../helpers'; import { Generator } from '../Generator'; -const generator: Generator = async (_packageManager, npmOptions, { storyFormat }) => { +const generator: Generator = async (packageManager, npmOptions, { storyFormat }) => { const [ storybookVersion, babelPluginEmberModulePolyfillVersion, @@ -30,7 +29,7 @@ const generator: Generator = async (_packageManager, npmOptions, { storyFormat } copyTemplate(__dirname, storyFormat); - const packageJson = await retrievePackageJson(); + const packageJson = packageManager.retrievePackageJson(); packageJson.dependencies = packageJson.dependencies || {}; packageJson.devDependencies = packageJson.devDependencies || {}; diff --git a/lib/cli/src/generators/HTML/index.ts b/lib/cli/src/generators/HTML/index.ts index 84fc3d2eb1da..0963ae7738d8 100755 --- a/lib/cli/src/generators/HTML/index.ts +++ b/lib/cli/src/generators/HTML/index.ts @@ -1,5 +1,4 @@ import { - retrievePackageJson, getVersionedPackages, writePackageJson, getBabelDependencies, @@ -9,7 +8,7 @@ import { import { StoryFormat } from '../../project_types'; import { Generator } from '../Generator'; -const generator: Generator = async (_packageManager, npmOptions, { storyFormat }) => { +const generator: Generator = async (packageManager, npmOptions, { storyFormat }) => { const packages = ['@storybook/html', '@storybook/addon-actions', '@storybook/addon-links']; const versionedPackages = await getVersionedPackages(npmOptions, ...packages); @@ -19,7 +18,7 @@ const generator: Generator = async (_packageManager, npmOptions, { storyFormat } copyTemplate(__dirname, storyFormat); - const packageJson = await retrievePackageJson(); + const packageJson = packageManager.retrievePackageJson(); packageJson.dependencies = packageJson.dependencies || {}; packageJson.devDependencies = packageJson.devDependencies || {}; diff --git a/lib/cli/src/generators/MARIONETTE/index.ts b/lib/cli/src/generators/MARIONETTE/index.ts index f75b549993be..c3a806ac76fc 100644 --- a/lib/cli/src/generators/MARIONETTE/index.ts +++ b/lib/cli/src/generators/MARIONETTE/index.ts @@ -5,15 +5,14 @@ import { writePackageJson, getBabelDependencies, installDependencies, - retrievePackageJson, } from '../../helpers'; import { Generator } from '../Generator'; -const generator: Generator = async (_packageManager, npmOptions) => { +const generator: Generator = async (packageManager, npmOptions) => { const storybookVersion = await getVersion(npmOptions, '@storybook/marionette'); fse.copySync(path.resolve(__dirname, 'template/'), '.', { overwrite: true }); - const packageJson = await retrievePackageJson(); + const packageJson = packageManager.retrievePackageJson(); packageJson.dependencies = packageJson.dependencies || {}; packageJson.devDependencies = packageJson.devDependencies || {}; diff --git a/lib/cli/src/generators/MARKO/index.ts b/lib/cli/src/generators/MARKO/index.ts index 47e319e16196..30501b685cbb 100644 --- a/lib/cli/src/generators/MARKO/index.ts +++ b/lib/cli/src/generators/MARKO/index.ts @@ -1,6 +1,5 @@ import { getVersions, - retrievePackageJson, writePackageJson, getBabelDependencies, installDependencies, @@ -8,7 +7,7 @@ import { } from '../../helpers'; import { Generator } from '../Generator'; -const generator: Generator = async (_packageManager, npmOptions, { storyFormat }) => { +const generator: Generator = async (packageManager, npmOptions, { storyFormat }) => { const [storybookVersion, addonActionVersion, addonKnobsVersion] = await getVersions( npmOptions, '@storybook/marko', @@ -18,7 +17,7 @@ const generator: Generator = async (_packageManager, npmOptions, { storyFormat } copyTemplate(__dirname, storyFormat); - const packageJson = await retrievePackageJson(); + const packageJson = packageManager.retrievePackageJson(); packageJson.dependencies = packageJson.dependencies || {}; packageJson.devDependencies = packageJson.devDependencies || {}; diff --git a/lib/cli/src/generators/METEOR/index.ts b/lib/cli/src/generators/METEOR/index.ts index 7ba2392a8c58..793ffcd6710d 100644 --- a/lib/cli/src/generators/METEOR/index.ts +++ b/lib/cli/src/generators/METEOR/index.ts @@ -2,7 +2,6 @@ import fs from 'fs'; import JSON5 from 'json5'; import { getVersions, - retrievePackageJson, writePackageJson, getBabelDependencies, installDependencies, @@ -10,7 +9,7 @@ import { } from '../../helpers'; import { Generator } from '../Generator'; -const generator: Generator = async (_packageManager, npmOptions, { storyFormat }) => { +const generator: Generator = async (packageManager, npmOptions, { storyFormat }) => { const [ storybookVersion, actionsVersion, @@ -36,7 +35,7 @@ const generator: Generator = async (_packageManager, npmOptions, { storyFormat } copyTemplate(__dirname, storyFormat); - const packageJson = await retrievePackageJson(); + const packageJson = packageManager.retrievePackageJson(); packageJson.devDependencies = packageJson.devDependencies || {}; packageJson.scripts = packageJson.scripts || {}; diff --git a/lib/cli/src/generators/MITHRIL/index.ts b/lib/cli/src/generators/MITHRIL/index.ts index e4f9fd2045a1..118208839f36 100644 --- a/lib/cli/src/generators/MITHRIL/index.ts +++ b/lib/cli/src/generators/MITHRIL/index.ts @@ -1,6 +1,5 @@ import { getVersions, - retrievePackageJson, writePackageJson, getBabelDependencies, installDependencies, @@ -8,7 +7,7 @@ import { } from '../../helpers'; import { Generator } from '../Generator'; -const generator: Generator = async (_packageManager, npmOptions, { storyFormat }) => { +const generator: Generator = async (packageManager, npmOptions, { storyFormat }) => { const [ storybookVersion, actionsVersion, @@ -26,7 +25,7 @@ const generator: Generator = async (_packageManager, npmOptions, { storyFormat } copyTemplate(__dirname, storyFormat); - const packageJson = await retrievePackageJson(); + const packageJson = packageManager.retrievePackageJson(); packageJson.dependencies = packageJson.dependencies || {}; packageJson.devDependencies = packageJson.devDependencies || {}; diff --git a/lib/cli/src/generators/PREACT/index.ts b/lib/cli/src/generators/PREACT/index.ts index 902a2d31f1ee..dba811ad5373 100644 --- a/lib/cli/src/generators/PREACT/index.ts +++ b/lib/cli/src/generators/PREACT/index.ts @@ -1,6 +1,5 @@ import { getVersions, - retrievePackageJson, writePackageJson, getBabelDependencies, installDependencies, @@ -8,7 +7,7 @@ import { } from '../../helpers'; import { Generator } from '../Generator'; -const generator: Generator = async (_packageManager, npmOptions, { storyFormat }) => { +const generator: Generator = async (packageManager, npmOptions, { storyFormat }) => { const [storybookVersion, actionsVersion, linksVersion, addonsVersion] = await getVersions( npmOptions, '@storybook/preact', @@ -19,7 +18,7 @@ const generator: Generator = async (_packageManager, npmOptions, { storyFormat } copyTemplate(__dirname, storyFormat); - const packageJson = await retrievePackageJson(); + const packageJson = packageManager.retrievePackageJson(); packageJson.dependencies = packageJson.dependencies || {}; packageJson.devDependencies = packageJson.devDependencies || {}; diff --git a/lib/cli/src/generators/RAX/index.ts b/lib/cli/src/generators/RAX/index.ts index 780ce27e4d48..154d92cc3fda 100644 --- a/lib/cli/src/generators/RAX/index.ts +++ b/lib/cli/src/generators/RAX/index.ts @@ -1,6 +1,5 @@ import { getVersions, - retrievePackageJson, writePackageJson, getBabelDependencies, installDependencies, @@ -8,7 +7,7 @@ import { } from '../../helpers'; import { Generator } from '../Generator'; -const generator: Generator = async (_packageManager, npmOptions, { storyFormat }) => { +const generator: Generator = async (packageManager, npmOptions, { storyFormat }) => { const [ storybookVersion, actionsVersion, @@ -26,7 +25,7 @@ const generator: Generator = async (_packageManager, npmOptions, { storyFormat } copyTemplate(__dirname, storyFormat); - const packageJson = await retrievePackageJson(); + const packageJson = packageManager.retrievePackageJson(); packageJson.dependencies = packageJson.dependencies || {}; packageJson.devDependencies = packageJson.devDependencies || {}; diff --git a/lib/cli/src/generators/REACT/index.ts b/lib/cli/src/generators/REACT/index.ts index 7f6182cfed29..0b4ddcb463b5 100644 --- a/lib/cli/src/generators/REACT/index.ts +++ b/lib/cli/src/generators/REACT/index.ts @@ -1,6 +1,5 @@ import { getVersionedPackages, - retrievePackageJson, writePackageJson, getBabelDependencies, installDependencies, @@ -9,7 +8,7 @@ import { import { StoryFormat } from '../../project_types'; import { Generator } from '../Generator'; -const generator: Generator = async (_packageManager, npmOptions, { storyFormat }) => { +const generator: Generator = async (packageManager, npmOptions, { storyFormat }) => { const packages = [ '@storybook/react', '@storybook/addon-actions', @@ -24,7 +23,7 @@ const generator: Generator = async (_packageManager, npmOptions, { storyFormat } copyTemplate(__dirname, storyFormat); - const packageJson = await retrievePackageJson(); + const packageJson = packageManager.retrievePackageJson(); packageJson.dependencies = packageJson.dependencies || {}; packageJson.devDependencies = packageJson.devDependencies || {}; diff --git a/lib/cli/src/generators/REACT_NATIVE/index.ts b/lib/cli/src/generators/REACT_NATIVE/index.ts index e58b31b9a965..16c19d25133f 100644 --- a/lib/cli/src/generators/REACT_NATIVE/index.ts +++ b/lib/cli/src/generators/REACT_NATIVE/index.ts @@ -2,7 +2,6 @@ import shell from 'shelljs'; import chalk from 'chalk'; import { getVersions, - retrievePackageJson, writePackageJson, paddedLog, getBabelDependencies, @@ -14,7 +13,7 @@ import { GeneratorOptions } from '../Generator'; import { JsPackageManager } from '../../js-package-manager'; export default async ( - _packageManager: JsPackageManager, + packageManager: JsPackageManager, npmOptions: NpmOptions, installServer: boolean, { storyFormat }: GeneratorOptions @@ -47,7 +46,7 @@ export default async ( } } - const packageJson = await retrievePackageJson(); + const packageJson = packageManager.retrievePackageJson(); packageJson.dependencies = packageJson.dependencies || {}; packageJson.devDependencies = packageJson.devDependencies || {}; diff --git a/lib/cli/src/generators/REACT_SCRIPTS/index.ts b/lib/cli/src/generators/REACT_SCRIPTS/index.ts index d5ff30f9ff98..4f8f8dee6540 100644 --- a/lib/cli/src/generators/REACT_SCRIPTS/index.ts +++ b/lib/cli/src/generators/REACT_SCRIPTS/index.ts @@ -1,7 +1,6 @@ import path from 'path'; import fs from 'fs'; import { - retrievePackageJson, getVersionedPackages, writePackageJson, getBabelDependencies, @@ -11,7 +10,7 @@ import { import { StoryFormat } from '../../project_types'; import { Generator } from '../Generator'; -const generator: Generator = async (_packageManager, npmOptions, { storyFormat }) => { +const generator: Generator = async (packageManager, npmOptions, { storyFormat }) => { const packages = [ '@storybook/react', '@storybook/preset-create-react-app', @@ -28,7 +27,7 @@ const generator: Generator = async (_packageManager, npmOptions, { storyFormat } copyTemplate(__dirname, storyFormat); - const packageJson = await retrievePackageJson(); + const packageJson = packageManager.retrievePackageJson(); packageJson.dependencies = packageJson.dependencies || {}; packageJson.devDependencies = packageJson.devDependencies || {}; diff --git a/lib/cli/src/generators/RIOT/index.ts b/lib/cli/src/generators/RIOT/index.ts index 75e2c9e544c6..1309ab14aa8f 100644 --- a/lib/cli/src/generators/RIOT/index.ts +++ b/lib/cli/src/generators/RIOT/index.ts @@ -1,6 +1,5 @@ import { getVersions, - retrievePackageJson, writePackageJson, getBabelDependencies, installDependencies, @@ -8,7 +7,7 @@ import { } from '../../helpers'; import { Generator } from '../Generator'; -const generator: Generator = async (_packageManager, npmOptions, { storyFormat }) => { +const generator: Generator = async (packageManager, npmOptions, { storyFormat }) => { const [ storybookVersion, actionsVersion, @@ -26,7 +25,7 @@ const generator: Generator = async (_packageManager, npmOptions, { storyFormat } copyTemplate(__dirname, storyFormat); - const packageJson = await retrievePackageJson(); + const packageJson = packageManager.retrievePackageJson(); packageJson.dependencies = packageJson.dependencies || {}; packageJson.devDependencies = packageJson.devDependencies || {}; diff --git a/lib/cli/src/generators/SFC_VUE/index.ts b/lib/cli/src/generators/SFC_VUE/index.ts index ebb8d3fcb5da..9aece304530c 100644 --- a/lib/cli/src/generators/SFC_VUE/index.ts +++ b/lib/cli/src/generators/SFC_VUE/index.ts @@ -1,5 +1,4 @@ import { - retrievePackageJson, getVersionedPackages, writePackageJson, getBabelDependencies, @@ -9,7 +8,7 @@ import { import { StoryFormat } from '../../project_types'; import { Generator } from '../Generator'; -const generator: Generator = async (_packageManager, npmOptions, { storyFormat }) => { +const generator: Generator = async (packageManager, npmOptions, { storyFormat }) => { const packages = [ '@storybook/vue', '@storybook/addon-actions', @@ -23,7 +22,7 @@ const generator: Generator = async (_packageManager, npmOptions, { storyFormat } copyTemplate(__dirname, storyFormat); - const packageJson = await retrievePackageJson(); + const packageJson = packageManager.retrievePackageJson(); packageJson.dependencies = packageJson.dependencies || {}; packageJson.devDependencies = packageJson.devDependencies || {}; diff --git a/lib/cli/src/generators/SVELTE/index.ts b/lib/cli/src/generators/SVELTE/index.ts index 9b4933e83411..ad4dda969330 100644 --- a/lib/cli/src/generators/SVELTE/index.ts +++ b/lib/cli/src/generators/SVELTE/index.ts @@ -1,6 +1,5 @@ import { getVersions, - retrievePackageJson, writePackageJson, getBabelDependencies, installDependencies, @@ -8,7 +7,7 @@ import { } from '../../helpers'; import { Generator } from '../Generator'; -const generator: Generator = async (_packageManager, npmOptions, { storyFormat }) => { +const generator: Generator = async (packageManager, npmOptions, { storyFormat }) => { const [ storybookVersion, actionsVersion, @@ -28,7 +27,7 @@ const generator: Generator = async (_packageManager, npmOptions, { storyFormat } copyTemplate(__dirname, storyFormat); - const packageJson = await retrievePackageJson(); + const packageJson = packageManager.retrievePackageJson(); packageJson.dependencies = packageJson.dependencies || {}; packageJson.devDependencies = packageJson.devDependencies || {}; diff --git a/lib/cli/src/generators/VUE/index.ts b/lib/cli/src/generators/VUE/index.ts index 122dbacb2378..05c4ca742775 100644 --- a/lib/cli/src/generators/VUE/index.ts +++ b/lib/cli/src/generators/VUE/index.ts @@ -1,5 +1,4 @@ import { - retrievePackageJson, getVersion, getVersionedPackages, writePackageJson, @@ -11,7 +10,7 @@ import { import { StoryFormat } from '../../project_types'; import { Generator } from '../Generator'; -const generator: Generator = async (_packageManager, npmOptions, { storyFormat }) => { +const generator: Generator = async (packageManager, npmOptions, { storyFormat }) => { const packages = [ '@storybook/vue', '@storybook/addon-actions', @@ -26,7 +25,7 @@ const generator: Generator = async (_packageManager, npmOptions, { storyFormat } copyTemplate(__dirname, storyFormat); - const packageJson = await retrievePackageJson(); + const packageJson = packageManager.retrievePackageJson(); packageJson.dependencies = packageJson.dependencies || {}; packageJson.devDependencies = packageJson.devDependencies || {}; diff --git a/lib/cli/src/generators/WEB-COMPONENTS/index.ts b/lib/cli/src/generators/WEB-COMPONENTS/index.ts index 1cd2e2597b46..5d56da5d61a7 100755 --- a/lib/cli/src/generators/WEB-COMPONENTS/index.ts +++ b/lib/cli/src/generators/WEB-COMPONENTS/index.ts @@ -2,7 +2,6 @@ import fse from 'fs-extra'; import path from 'path'; import { getVersionedPackages, - retrievePackageJson, writePackageJson, getBabelDependencies, installDependencies, @@ -10,7 +9,7 @@ import { import { StoryFormat } from '../../project_types'; import { Generator } from '../Generator'; -const generator: Generator = async (_packageManager, npmOptions, { storyFormat }) => { +const generator: Generator = async (packageManager, npmOptions, { storyFormat }) => { const packages = [ '@storybook/web-components', '@storybook/addon-actions', @@ -26,7 +25,7 @@ const generator: Generator = async (_packageManager, npmOptions, { storyFormat } // TODO: handle adding of docs mode } - const packageJson = await retrievePackageJson(); + const packageJson = packageManager.retrievePackageJson(); packageJson.dependencies = packageJson.dependencies || {}; packageJson.devDependencies = packageJson.devDependencies || {}; diff --git a/lib/cli/src/generators/WEBPACK_REACT/index.ts b/lib/cli/src/generators/WEBPACK_REACT/index.ts index abd2babbcbe9..376e1eaf0b5e 100644 --- a/lib/cli/src/generators/WEBPACK_REACT/index.ts +++ b/lib/cli/src/generators/WEBPACK_REACT/index.ts @@ -1,5 +1,4 @@ import { - retrievePackageJson, getVersionedPackages, writePackageJson, getBabelDependencies, @@ -9,7 +8,7 @@ import { import { StoryFormat } from '../../project_types'; import { Generator } from '../Generator'; -const generator: Generator = async (_packageManager, npmOptions, { storyFormat }) => { +const generator: Generator = async (packageManager, npmOptions, { storyFormat }) => { const packages = [ '@storybook/react', '@storybook/addon-actions', @@ -23,7 +22,7 @@ const generator: Generator = async (_packageManager, npmOptions, { storyFormat } copyTemplate(__dirname, storyFormat); - const packageJson = await retrievePackageJson(); + const packageJson = packageManager.retrievePackageJson(); packageJson.dependencies = packageJson.dependencies || {}; packageJson.devDependencies = packageJson.devDependencies || {}; diff --git a/lib/cli/src/helpers.test.ts b/lib/cli/src/helpers.test.ts index f71887a352f7..8f8886dceabd 100644 --- a/lib/cli/src/helpers.test.ts +++ b/lib/cli/src/helpers.test.ts @@ -17,10 +17,6 @@ jest.mock('path', () => ({ resolve: jest.fn((_, p) => p), })); -jest.mock('./npm_init', () => ({ - npmInit: jest.fn(), -})); - jest.mock('./has_yarn', () => ({ hasYarn2: jest.fn(() => false), })); diff --git a/lib/cli/src/helpers.ts b/lib/cli/src/helpers.ts index 2893ecd8d6bb..fb66eb73258e 100644 --- a/lib/cli/src/helpers.ts +++ b/lib/cli/src/helpers.ts @@ -8,7 +8,6 @@ import { gt, satisfies } from '@storybook/semver'; import stripJsonComments from 'strip-json-comments'; import { latestVersion } from './latest_version'; -import { npmInit } from './npm_init'; import { StoryFormat } from './project_types'; import { PackageJson } from './PackageJson'; import { NpmOptions } from './NpmOptions'; @@ -69,19 +68,6 @@ export function getPackageJson() { return JSON.parse(jsonContent); } -export async function retrievePackageJson() { - const existing = getPackageJson(); - if (existing) { - return existing; - } - - // npmInit will create a new package.json file - npmInit(); - - // read the newly created package.json file - return getPackageJson() || {}; -} - export function getBowerJson() { const bowerJsonPath = path.resolve('bower.json'); if (!fs.existsSync(bowerJsonPath)) { diff --git a/lib/cli/src/js-package-manager/JsPackageManager.ts b/lib/cli/src/js-package-manager/JsPackageManager.ts index 446025897e18..622526a9bf49 100644 --- a/lib/cli/src/js-package-manager/JsPackageManager.ts +++ b/lib/cli/src/js-package-manager/JsPackageManager.ts @@ -1,4 +1,7 @@ +import path from 'path'; +import fs from 'fs'; import { commandLog } from '../helpers'; +import { PackageJson } from '../PackageJson'; const logger = console; @@ -23,5 +26,28 @@ export abstract class JsPackageManager { done(); } + public retrievePackageJson(): PackageJson { + const existing = JsPackageManager.getPackageJson(); + if (existing) { + return existing; + } + + // It will create a new package.json file + this.initPackageJson(); + + // read the newly created package.json file + return JsPackageManager.getPackageJson() || {}; + } + protected abstract runInstall(): { status: number }; + + private static getPackageJson(): PackageJson | false { + const packageJsonPath = path.resolve('package.json'); + if (!fs.existsSync(packageJsonPath)) { + return false; + } + + const jsonContent = fs.readFileSync(packageJsonPath, 'utf8'); + return JSON.parse(jsonContent); + } } diff --git a/lib/cli/src/npm_init.ts b/lib/cli/src/npm_init.ts deleted file mode 100644 index f409557809fc..000000000000 --- a/lib/cli/src/npm_init.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { sync } from 'cross-spawn'; -import { hasYarn } from './has_yarn'; - -const packageManager = hasYarn() ? 'yarn' : 'npm'; - -export function npmInit(): string { - const results = sync(packageManager, ['init', '-y'], { - cwd: process.cwd(), - env: process.env, - stdio: 'pipe', - encoding: 'utf-8', - }); - return results.stdout; -} From c714aca14594e41fb5c8ef7f1ede027dc2a4f625 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABtan=20Maisse?= Date: Sun, 7 Jun 2020 19:50:10 +0200 Subject: [PATCH 08/22] refactor: move `installDependencies` to JsPackageManager Also rename it to `addDependencies` (a.k.a. `yarn add`) to avoid confusion with `installDepsFromPackageJson` (a.k.a. `yarn install`). --- lib/cli/src/generators/ANGULAR/index.ts | 6 +- lib/cli/src/generators/AURELIA/index.ts | 6 +- lib/cli/src/generators/EMBER/index.ts | 10 +-- lib/cli/src/generators/HTML/index.ts | 6 +- lib/cli/src/generators/MARIONETTE/index.ts | 9 +-- lib/cli/src/generators/MARKO/index.ts | 10 +-- lib/cli/src/generators/METEOR/index.ts | 15 ++-- lib/cli/src/generators/MITHRIL/index.ts | 10 +-- lib/cli/src/generators/PREACT/index.ts | 10 +-- lib/cli/src/generators/RAX/index.ts | 10 +-- lib/cli/src/generators/REACT/index.ts | 6 +- lib/cli/src/generators/REACT_NATIVE/index.ts | 6 +- lib/cli/src/generators/REACT_SCRIPTS/index.ts | 6 +- lib/cli/src/generators/RIOT/index.ts | 13 ++-- lib/cli/src/generators/SFC_VUE/index.ts | 6 +- lib/cli/src/generators/SVELTE/index.ts | 10 +-- .../UPDATE_PACKAGE_ORGANIZATIONS/index.ts | 10 +-- lib/cli/src/generators/VUE/index.ts | 6 +- .../src/generators/WEB-COMPONENTS/index.ts | 12 ++-- lib/cli/src/generators/WEBPACK_REACT/index.ts | 6 +- lib/cli/src/helpers.ts | 71 ------------------- lib/cli/src/initiate.ts | 2 +- .../js-package-manager/JsPackageManager.ts | 68 +++++++++++++++++- lib/cli/src/js-package-manager/NPMProxy.ts | 13 ++++ lib/cli/src/js-package-manager/Yarn1Proxy.ts | 13 ++++ lib/cli/src/js-package-manager/Yarn2Proxy.ts | 13 ++++ 26 files changed, 178 insertions(+), 175 deletions(-) diff --git a/lib/cli/src/generators/ANGULAR/index.ts b/lib/cli/src/generators/ANGULAR/index.ts index 631a07e66226..7dcd9a4eb921 100644 --- a/lib/cli/src/generators/ANGULAR/index.ts +++ b/lib/cli/src/generators/ANGULAR/index.ts @@ -9,7 +9,6 @@ import { getVersionedPackages, writePackageJson, getBabelDependencies, - installDependencies, writeFileAsJson, copyTemplate, } from '../../helpers'; @@ -49,7 +48,10 @@ async function addDependencies( const babelDependencies = await getBabelDependencies(npmOptions, packageJson); - installDependencies({ ...npmOptions, packageJson }, [...versionedPackages, ...babelDependencies]); + packageManager.addDependencies({ ...npmOptions, packageJson }, [ + ...versionedPackages, + ...babelDependencies, + ]); } function editAngularAppTsConfig() { diff --git a/lib/cli/src/generators/AURELIA/index.ts b/lib/cli/src/generators/AURELIA/index.ts index ebfef2c1cd79..78f1d41b2eac 100644 --- a/lib/cli/src/generators/AURELIA/index.ts +++ b/lib/cli/src/generators/AURELIA/index.ts @@ -2,7 +2,6 @@ import { getVersionedPackages, writePackageJson, getBabelDependencies, - installDependencies, writeFileAsJson, copyTemplate, readFileAsJson, @@ -58,7 +57,10 @@ const generator: Generator = async ( writePackageJson(packageJson); addStorybookExcludeGlobToTsConfig(); const babelDependencies = await getBabelDependencies(npmOptions, packageJson); - installDependencies({ ...npmOptions, packageJson }, [...versionedPackages, ...babelDependencies]); + packageManager.addDependencies({ ...npmOptions, packageJson }, [ + ...versionedPackages, + ...babelDependencies, + ]); }; export default generator; diff --git a/lib/cli/src/generators/EMBER/index.ts b/lib/cli/src/generators/EMBER/index.ts index c1a5e5f03afe..9c8b2c4bcf4f 100644 --- a/lib/cli/src/generators/EMBER/index.ts +++ b/lib/cli/src/generators/EMBER/index.ts @@ -1,10 +1,4 @@ -import { - getVersions, - writePackageJson, - getBabelDependencies, - installDependencies, - copyTemplate, -} from '../../helpers'; +import { getVersions, writePackageJson, getBabelDependencies, copyTemplate } from '../../helpers'; import { Generator } from '../Generator'; const generator: Generator = async (packageManager, npmOptions, { storyFormat }) => { @@ -46,7 +40,7 @@ const generator: Generator = async (packageManager, npmOptions, { storyFormat }) const babelDependencies = await getBabelDependencies(npmOptions, packageJson); - installDependencies({ ...npmOptions, packageJson }, [ + packageManager.addDependencies({ ...npmOptions, packageJson }, [ `@storybook/ember@${storybookVersion}`, `@storybook/addon-actions@${actionsVersion}`, `@storybook/addon-links@${linksVersion}`, diff --git a/lib/cli/src/generators/HTML/index.ts b/lib/cli/src/generators/HTML/index.ts index 0963ae7738d8..2aa38a22709b 100755 --- a/lib/cli/src/generators/HTML/index.ts +++ b/lib/cli/src/generators/HTML/index.ts @@ -2,7 +2,6 @@ import { getVersionedPackages, writePackageJson, getBabelDependencies, - installDependencies, copyTemplate, } from '../../helpers'; import { StoryFormat } from '../../project_types'; @@ -31,7 +30,10 @@ const generator: Generator = async (packageManager, npmOptions, { storyFormat }) const babelDependencies = await getBabelDependencies(npmOptions, packageJson); - installDependencies({ ...npmOptions, packageJson }, [...versionedPackages, ...babelDependencies]); + packageManager.addDependencies({ ...npmOptions, packageJson }, [ + ...versionedPackages, + ...babelDependencies, + ]); }; export default generator; diff --git a/lib/cli/src/generators/MARIONETTE/index.ts b/lib/cli/src/generators/MARIONETTE/index.ts index c3a806ac76fc..13bb96b798ad 100644 --- a/lib/cli/src/generators/MARIONETTE/index.ts +++ b/lib/cli/src/generators/MARIONETTE/index.ts @@ -1,11 +1,6 @@ import fse from 'fs-extra'; import path from 'path'; -import { - getVersion, - writePackageJson, - getBabelDependencies, - installDependencies, -} from '../../helpers'; +import { getVersion, writePackageJson, getBabelDependencies } from '../../helpers'; import { Generator } from '../Generator'; const generator: Generator = async (packageManager, npmOptions) => { @@ -25,7 +20,7 @@ const generator: Generator = async (packageManager, npmOptions) => { const babelDependencies = await getBabelDependencies(npmOptions, packageJson); - installDependencies({ ...npmOptions, packageJson }, [ + packageManager.addDependencies({ ...npmOptions, packageJson }, [ `@storybook/marionette@${storybookVersion}`, ...babelDependencies, ]); diff --git a/lib/cli/src/generators/MARKO/index.ts b/lib/cli/src/generators/MARKO/index.ts index 30501b685cbb..ed4e6874b00b 100644 --- a/lib/cli/src/generators/MARKO/index.ts +++ b/lib/cli/src/generators/MARKO/index.ts @@ -1,10 +1,4 @@ -import { - getVersions, - writePackageJson, - getBabelDependencies, - installDependencies, - copyTemplate, -} from '../../helpers'; +import { getVersions, writePackageJson, getBabelDependencies, copyTemplate } from '../../helpers'; import { Generator } from '../Generator'; const generator: Generator = async (packageManager, npmOptions, { storyFormat }) => { @@ -30,7 +24,7 @@ const generator: Generator = async (packageManager, npmOptions, { storyFormat }) const babelDependencies = await getBabelDependencies(npmOptions, packageJson); - installDependencies({ ...npmOptions, packageJson }, [ + packageManager.addDependencies({ ...npmOptions, packageJson }, [ `@storybook/marko@${storybookVersion}`, `@storybook/addon-actions@${addonActionVersion}`, `@storybook/addon-knobs@${addonKnobsVersion}`, diff --git a/lib/cli/src/generators/METEOR/index.ts b/lib/cli/src/generators/METEOR/index.ts index 793ffcd6710d..0e64017c6bb0 100644 --- a/lib/cli/src/generators/METEOR/index.ts +++ b/lib/cli/src/generators/METEOR/index.ts @@ -1,12 +1,6 @@ import fs from 'fs'; import JSON5 from 'json5'; -import { - getVersions, - writePackageJson, - getBabelDependencies, - installDependencies, - copyTemplate, -} from '../../helpers'; +import { getVersions, writePackageJson, getBabelDependencies, copyTemplate } from '../../helpers'; import { Generator } from '../Generator'; const generator: Generator = async (packageManager, npmOptions, { storyFormat }) => { @@ -86,13 +80,16 @@ const generator: Generator = async (packageManager, npmOptions, { storyFormat }) } if (dependencies.length > 0) { - installDependencies( + packageManager.addDependencies( { ...npmOptions, packageJson, installAsDevDependencies: false }, dependencies ); } - installDependencies({ ...npmOptions, packageJson }, [...devDependencies, ...babelDependencies]); + packageManager.addDependencies({ ...npmOptions, packageJson }, [ + ...devDependencies, + ...babelDependencies, + ]); }; export default generator; diff --git a/lib/cli/src/generators/MITHRIL/index.ts b/lib/cli/src/generators/MITHRIL/index.ts index 118208839f36..af10db13b145 100644 --- a/lib/cli/src/generators/MITHRIL/index.ts +++ b/lib/cli/src/generators/MITHRIL/index.ts @@ -1,10 +1,4 @@ -import { - getVersions, - writePackageJson, - getBabelDependencies, - installDependencies, - copyTemplate, -} from '../../helpers'; +import { getVersions, writePackageJson, getBabelDependencies, copyTemplate } from '../../helpers'; import { Generator } from '../Generator'; const generator: Generator = async (packageManager, npmOptions, { storyFormat }) => { @@ -38,7 +32,7 @@ const generator: Generator = async (packageManager, npmOptions, { storyFormat }) const babelDependencies = await getBabelDependencies(npmOptions, packageJson); - installDependencies({ ...npmOptions, packageJson }, [ + packageManager.addDependencies({ ...npmOptions, packageJson }, [ `@storybook/mithril@${storybookVersion}`, `@storybook/addon-actions@${actionsVersion}`, `@storybook/addon-links@${linksVersion}`, diff --git a/lib/cli/src/generators/PREACT/index.ts b/lib/cli/src/generators/PREACT/index.ts index dba811ad5373..ee87f70ed37c 100644 --- a/lib/cli/src/generators/PREACT/index.ts +++ b/lib/cli/src/generators/PREACT/index.ts @@ -1,10 +1,4 @@ -import { - getVersions, - writePackageJson, - getBabelDependencies, - installDependencies, - copyTemplate, -} from '../../helpers'; +import { getVersions, writePackageJson, getBabelDependencies, copyTemplate } from '../../helpers'; import { Generator } from '../Generator'; const generator: Generator = async (packageManager, npmOptions, { storyFormat }) => { @@ -31,7 +25,7 @@ const generator: Generator = async (packageManager, npmOptions, { storyFormat }) const babelDependencies = await getBabelDependencies(npmOptions, packageJson); - installDependencies({ ...npmOptions, packageJson }, [ + packageManager.addDependencies({ ...npmOptions, packageJson }, [ `@storybook/preact@${storybookVersion}`, `@storybook/addon-actions@${actionsVersion}`, `@storybook/addon-links@${linksVersion}`, diff --git a/lib/cli/src/generators/RAX/index.ts b/lib/cli/src/generators/RAX/index.ts index 154d92cc3fda..30756e9779db 100644 --- a/lib/cli/src/generators/RAX/index.ts +++ b/lib/cli/src/generators/RAX/index.ts @@ -1,10 +1,4 @@ -import { - getVersions, - writePackageJson, - getBabelDependencies, - installDependencies, - copyTemplate, -} from '../../helpers'; +import { getVersions, writePackageJson, getBabelDependencies, copyTemplate } from '../../helpers'; import { Generator } from '../Generator'; const generator: Generator = async (packageManager, npmOptions, { storyFormat }) => { @@ -49,7 +43,7 @@ const generator: Generator = async (packageManager, npmOptions, { storyFormat }) const babelDependencies = await getBabelDependencies(npmOptions, packageJson); - installDependencies({ ...npmOptions, packageJson }, [ + packageManager.addDependencies({ ...npmOptions, packageJson }, [ `@storybook/rax@${storybookVersion}`, `@storybook/addon-actions@${actionsVersion}`, `@storybook/addon-links@${linksVersion}`, diff --git a/lib/cli/src/generators/REACT/index.ts b/lib/cli/src/generators/REACT/index.ts index 0b4ddcb463b5..8e02494924a6 100644 --- a/lib/cli/src/generators/REACT/index.ts +++ b/lib/cli/src/generators/REACT/index.ts @@ -2,7 +2,6 @@ import { getVersionedPackages, writePackageJson, getBabelDependencies, - installDependencies, copyTemplate, } from '../../helpers'; import { StoryFormat } from '../../project_types'; @@ -36,7 +35,10 @@ const generator: Generator = async (packageManager, npmOptions, { storyFormat }) const babelDependencies = await getBabelDependencies(npmOptions, packageJson); - installDependencies({ ...npmOptions, packageJson }, [...versionedPackages, ...babelDependencies]); + packageManager.addDependencies({ ...npmOptions, packageJson }, [ + ...versionedPackages, + ...babelDependencies, + ]); }; export default generator; diff --git a/lib/cli/src/generators/REACT_NATIVE/index.ts b/lib/cli/src/generators/REACT_NATIVE/index.ts index 16c19d25133f..6342dc418507 100644 --- a/lib/cli/src/generators/REACT_NATIVE/index.ts +++ b/lib/cli/src/generators/REACT_NATIVE/index.ts @@ -5,7 +5,6 @@ import { writePackageJson, paddedLog, getBabelDependencies, - installDependencies, copyTemplate, } from '../../helpers'; import { NpmOptions } from '../../NpmOptions'; @@ -78,5 +77,8 @@ export default async ( const babelDependencies = await getBabelDependencies(npmOptions, packageJson); - installDependencies({ ...npmOptions, packageJson }, [...devDependencies, ...babelDependencies]); + packageManager.addDependencies({ ...npmOptions, packageJson }, [ + ...devDependencies, + ...babelDependencies, + ]); }; diff --git a/lib/cli/src/generators/REACT_SCRIPTS/index.ts b/lib/cli/src/generators/REACT_SCRIPTS/index.ts index 4f8f8dee6540..0913ab153bda 100644 --- a/lib/cli/src/generators/REACT_SCRIPTS/index.ts +++ b/lib/cli/src/generators/REACT_SCRIPTS/index.ts @@ -4,7 +4,6 @@ import { getVersionedPackages, writePackageJson, getBabelDependencies, - installDependencies, copyTemplate, } from '../../helpers'; import { StoryFormat } from '../../project_types'; @@ -46,7 +45,10 @@ const generator: Generator = async (packageManager, npmOptions, { storyFormat }) const babelDependencies = await getBabelDependencies(npmOptions, packageJson); - installDependencies({ ...npmOptions, packageJson }, [...versionedPackages, ...babelDependencies]); + packageManager.addDependencies({ ...npmOptions, packageJson }, [ + ...versionedPackages, + ...babelDependencies, + ]); }; export default generator; diff --git a/lib/cli/src/generators/RIOT/index.ts b/lib/cli/src/generators/RIOT/index.ts index 1309ab14aa8f..ddb2a568a6fe 100644 --- a/lib/cli/src/generators/RIOT/index.ts +++ b/lib/cli/src/generators/RIOT/index.ts @@ -1,10 +1,4 @@ -import { - getVersions, - writePackageJson, - getBabelDependencies, - installDependencies, - copyTemplate, -} from '../../helpers'; +import { getVersions, writePackageJson, getBabelDependencies, copyTemplate } from '../../helpers'; import { Generator } from '../Generator'; const generator: Generator = async (packageManager, npmOptions, { storyFormat }) => { @@ -50,7 +44,10 @@ const generator: Generator = async (packageManager, npmOptions, { storyFormat }) const babelDependencies = await getBabelDependencies(npmOptions, packageJson); - installDependencies({ ...npmOptions, packageJson }, [...dependencies, ...babelDependencies]); + packageManager.addDependencies({ ...npmOptions, packageJson }, [ + ...dependencies, + ...babelDependencies, + ]); }; export default generator; diff --git a/lib/cli/src/generators/SFC_VUE/index.ts b/lib/cli/src/generators/SFC_VUE/index.ts index 9aece304530c..c9c32c143717 100644 --- a/lib/cli/src/generators/SFC_VUE/index.ts +++ b/lib/cli/src/generators/SFC_VUE/index.ts @@ -2,7 +2,6 @@ import { getVersionedPackages, writePackageJson, getBabelDependencies, - installDependencies, copyTemplate, } from '../../helpers'; import { StoryFormat } from '../../project_types'; @@ -35,7 +34,10 @@ const generator: Generator = async (packageManager, npmOptions, { storyFormat }) const babelDependencies = await getBabelDependencies(npmOptions, packageJson); - installDependencies({ ...npmOptions, packageJson }, [...versionedPackages, ...babelDependencies]); + packageManager.addDependencies({ ...npmOptions, packageJson }, [ + ...versionedPackages, + ...babelDependencies, + ]); }; export default generator; diff --git a/lib/cli/src/generators/SVELTE/index.ts b/lib/cli/src/generators/SVELTE/index.ts index ad4dda969330..54b073f05569 100644 --- a/lib/cli/src/generators/SVELTE/index.ts +++ b/lib/cli/src/generators/SVELTE/index.ts @@ -1,10 +1,4 @@ -import { - getVersions, - writePackageJson, - getBabelDependencies, - installDependencies, - copyTemplate, -} from '../../helpers'; +import { getVersions, writePackageJson, getBabelDependencies, copyTemplate } from '../../helpers'; import { Generator } from '../Generator'; const generator: Generator = async (packageManager, npmOptions, { storyFormat }) => { @@ -40,7 +34,7 @@ const generator: Generator = async (packageManager, npmOptions, { storyFormat }) const babelDependencies = await getBabelDependencies(npmOptions, packageJson); - installDependencies({ ...npmOptions, packageJson }, [ + packageManager.addDependencies({ ...npmOptions, packageJson }, [ `@storybook/svelte@${storybookVersion}`, `@storybook/addon-actions@${actionsVersion}`, `@storybook/addon-links@${linksVersion}`, diff --git a/lib/cli/src/generators/UPDATE_PACKAGE_ORGANIZATIONS/index.ts b/lib/cli/src/generators/UPDATE_PACKAGE_ORGANIZATIONS/index.ts index ab3a1e0fcf79..5a7eedf3e726 100644 --- a/lib/cli/src/generators/UPDATE_PACKAGE_ORGANIZATIONS/index.ts +++ b/lib/cli/src/generators/UPDATE_PACKAGE_ORGANIZATIONS/index.ts @@ -7,11 +7,11 @@ import { getPackageJson, getVersion, getVersions, - installDependencies, writePackageJson, } from '../../helpers'; import { PackageJson } from '../../PackageJson'; import { NpmOptions } from '../../NpmOptions'; +import { JsPackageManager } from '../../js-package-manager'; async function updatePackage( devDependencies: PackageJson['devDependencies'], @@ -25,7 +25,7 @@ async function updatePackage( } } -async function updatePackageJson(npmOptions: NpmOptions) { +async function updatePackageJson(packageManager: JsPackageManager, npmOptions: NpmOptions) { const packageJson = getPackageJson(); const { devDependencies } = packageJson; @@ -54,7 +54,7 @@ async function updatePackageJson(npmOptions: NpmOptions) { const babelDependencies = await getBabelDependencies(npmOptions, packageJson); if (babelDependencies.length > 0) { - installDependencies({ ...npmOptions, packageJson }, babelDependencies); + packageManager.addDependencies({ ...npmOptions, packageJson }, babelDependencies); } } @@ -76,7 +76,7 @@ function updateSourceCode(parser: string) { }); } -export default async (parser: string, npmOptions: NpmOptions) => { - await updatePackageJson(npmOptions); +export default async (packageManager: JsPackageManager, parser: string, npmOptions: NpmOptions) => { + await updatePackageJson(packageManager, npmOptions); updateSourceCode(parser); }; diff --git a/lib/cli/src/generators/VUE/index.ts b/lib/cli/src/generators/VUE/index.ts index 05c4ca742775..e13b7ae06e22 100644 --- a/lib/cli/src/generators/VUE/index.ts +++ b/lib/cli/src/generators/VUE/index.ts @@ -3,7 +3,6 @@ import { getVersionedPackages, writePackageJson, getBabelDependencies, - installDependencies, addToDevDependenciesIfNotPresent, copyTemplate, } from '../../helpers'; @@ -51,7 +50,10 @@ const generator: Generator = async (packageManager, npmOptions, { storyFormat }) writePackageJson(packageJson); const babelDependencies = await getBabelDependencies(npmOptions, packageJson); - installDependencies({ ...npmOptions, packageJson }, [...versionedPackages, ...babelDependencies]); + packageManager.addDependencies({ ...npmOptions, packageJson }, [ + ...versionedPackages, + ...babelDependencies, + ]); }; export default generator; diff --git a/lib/cli/src/generators/WEB-COMPONENTS/index.ts b/lib/cli/src/generators/WEB-COMPONENTS/index.ts index 5d56da5d61a7..82a4454f8edf 100755 --- a/lib/cli/src/generators/WEB-COMPONENTS/index.ts +++ b/lib/cli/src/generators/WEB-COMPONENTS/index.ts @@ -1,11 +1,6 @@ import fse from 'fs-extra'; import path from 'path'; -import { - getVersionedPackages, - writePackageJson, - getBabelDependencies, - installDependencies, -} from '../../helpers'; +import { getVersionedPackages, writePackageJson, getBabelDependencies } from '../../helpers'; import { StoryFormat } from '../../project_types'; import { Generator } from '../Generator'; @@ -38,7 +33,10 @@ const generator: Generator = async (packageManager, npmOptions, { storyFormat }) const babelDependencies = await getBabelDependencies(npmOptions, packageJson); - installDependencies({ ...npmOptions, packageJson }, [...versionedPackages, ...babelDependencies]); + packageManager.addDependencies({ ...npmOptions, packageJson }, [ + ...versionedPackages, + ...babelDependencies, + ]); }; export default generator; diff --git a/lib/cli/src/generators/WEBPACK_REACT/index.ts b/lib/cli/src/generators/WEBPACK_REACT/index.ts index 376e1eaf0b5e..ff2a01e50f64 100644 --- a/lib/cli/src/generators/WEBPACK_REACT/index.ts +++ b/lib/cli/src/generators/WEBPACK_REACT/index.ts @@ -2,7 +2,6 @@ import { getVersionedPackages, writePackageJson, getBabelDependencies, - installDependencies, copyTemplate, } from '../../helpers'; import { StoryFormat } from '../../project_types'; @@ -35,7 +34,10 @@ const generator: Generator = async (packageManager, npmOptions, { storyFormat }) const babelDependencies = await getBabelDependencies(npmOptions, packageJson); - installDependencies({ ...npmOptions, packageJson }, [...versionedPackages, ...babelDependencies]); + packageManager.addDependencies({ ...npmOptions, packageJson }, [ + ...versionedPackages, + ...babelDependencies, + ]); }; export default generator; diff --git a/lib/cli/src/helpers.ts b/lib/cli/src/helpers.ts index fb66eb73258e..f20e67f516fe 100644 --- a/lib/cli/src/helpers.ts +++ b/lib/cli/src/helpers.ts @@ -3,7 +3,6 @@ import path from 'path'; import fs from 'fs'; import fse from 'fs-extra'; import chalk from 'chalk'; -import { sync as spawnSync } from 'cross-spawn'; import { gt, satisfies } from '@storybook/semver'; import stripJsonComments from 'strip-json-comments'; @@ -11,7 +10,6 @@ import { latestVersion } from './latest_version'; import { StoryFormat } from './project_types'; import { PackageJson } from './PackageJson'; import { NpmOptions } from './NpmOptions'; -import { hasYarn2 } from './has_yarn'; // Cannot be `import` as it's not under TS root dir const { version, devDependencies } = require('../package.json'); @@ -168,75 +166,6 @@ export function codeLog(codeLines: string[], leftPadAmount?: number) { logger.log(finalResult); } -/** - * Add dependencies to a project using `yarn add` or `npm install`. - * - * @param {Object} options contains `useYarn`, `runInstall` and `installAsDevDependencies` which we use to determine how we install packages. - * @param {Array} dependencies contains a list of packages to add. - * @example - * installDependencies(options, [ - * `@storybook/react@${storybookVersion}`, - * `@storybook/addon-actions@${actionsVersion}`, - * `@storybook/addon-links@${linksVersion}`, - * `@storybook/addons@${addonsVersion}`, - * ]); - */ -export function installDependencies( - options: NpmOptions & { packageJson: PackageJson }, - dependencies: string[] -) { - const { skipInstall } = options; - - if (skipInstall) { - const { packageJson } = options; - - const dependenciesMap = dependencies.reduce((acc, dep) => { - const idx = dep.lastIndexOf('@'); - const packageName = dep.slice(0, idx); - const packageVersion = dep.slice(idx + 1); - - return { ...acc, [packageName]: packageVersion }; - }, {}); - - if (options.installAsDevDependencies) { - packageJson.devDependencies = { - ...packageJson.devDependencies, - ...dependenciesMap, - }; - } else { - packageJson.dependencies = { - ...packageJson.dependencies, - ...dependenciesMap, - }; - } - - writePackageJson(packageJson); - } else { - const spawnCommand = options.useYarn ? 'yarn' : 'npm'; - const installCommand = options.useYarn ? 'add' : 'install'; - - const installArgs = [installCommand, ...dependencies]; - - if (options.installAsDevDependencies) { - installArgs.push('-D'); - } - - if (options.useYarn && !hasYarn2()) { - installArgs.push('--ignore-workspace-root-check'); - } - - const dependencyResult = spawnSync(spawnCommand, installArgs, { - stdio: 'inherit', - }); - - if (dependencyResult.status !== 0) { - logger.error('An error occurred while installing dependencies.'); - logger.log(dependencyResult); - process.exit(1); - } - } -} - /** * Detect if any babel dependencies need to be added to the project * @param {Object} npmOptions Passed along to `latestVersion` and `getVersion` diff --git a/lib/cli/src/initiate.ts b/lib/cli/src/initiate.ts index b166b2c90bcb..694049ae0761 100644 --- a/lib/cli/src/initiate.ts +++ b/lib/cli/src/initiate.ts @@ -94,7 +94,7 @@ const installStorybook = (projectType: ProjectType, options: CommandOptions): Pr return Promise.resolve(); case ProjectType.UPDATE_PACKAGE_ORGANIZATIONS: - return updateOrganisationsGenerator(options.parser, npmOptions) + return updateOrganisationsGenerator(packageManager, options.parser, npmOptions) .then(() => null) // commmandLog doesn't like to see output .then(commandLog('Upgrading your project to the new storybook packages.')) .then(end); diff --git a/lib/cli/src/js-package-manager/JsPackageManager.ts b/lib/cli/src/js-package-manager/JsPackageManager.ts index 622526a9bf49..2622ded412f2 100644 --- a/lib/cli/src/js-package-manager/JsPackageManager.ts +++ b/lib/cli/src/js-package-manager/JsPackageManager.ts @@ -1,6 +1,6 @@ import path from 'path'; import fs from 'fs'; -import { commandLog } from '../helpers'; +import { commandLog, writePackageJson } from '../helpers'; import { PackageJson } from '../PackageJson'; const logger = console; @@ -10,6 +10,9 @@ export abstract class JsPackageManager { public abstract getRunStorybookCommand(): string; + /** + * Install dependencies listed in `package.json` + */ public installDependencies(): void { let done = commandLog('Preparing to install dependencies'); done(); @@ -39,8 +42,71 @@ export abstract class JsPackageManager { return JsPackageManager.getPackageJson() || {}; } + /** + * Add dependencies to a project using `yarn add` or `npm install`. + * + * @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 add. + * @example + * addDependencies(options, [ + * `@storybook/react@${storybookVersion}`, + * `@storybook/addon-actions@${actionsVersion}`, + * `@storybook/addon-links@${linksVersion}`, + * `@storybook/addons@${addonsVersion}`, + * ]); + */ + public addDependencies( + options: { + skipInstall?: boolean; + installAsDevDependencies?: boolean; + packageJson: PackageJson; + }, + dependencies: string[] + ): void { + const { skipInstall } = options; + + if (skipInstall) { + const { packageJson } = options; + + const dependenciesMap = dependencies.reduce((acc, dep) => { + const idx = dep.lastIndexOf('@'); + const packageName = dep.slice(0, idx); + const packageVersion = dep.slice(idx + 1); + + return { ...acc, [packageName]: packageVersion }; + }, {}); + + if (options.installAsDevDependencies) { + packageJson.devDependencies = { + ...packageJson.devDependencies, + ...dependenciesMap, + }; + } else { + packageJson.dependencies = { + ...packageJson.dependencies, + ...dependenciesMap, + }; + } + + writePackageJson(packageJson); + } else { + const dependencyResult = this.runAddDeps(dependencies, options.installAsDevDependencies); + + if (dependencyResult.status !== 0) { + logger.error('An error occurred while installing dependencies.'); + logger.log(dependencyResult); + process.exit(1); + } + } + } + protected abstract runInstall(): { status: number }; + protected abstract runAddDeps( + dependencies: string[], + installAsDevDependencies: boolean + ): { status: number }; + private static getPackageJson(): PackageJson | false { const packageJsonPath = path.resolve('package.json'); if (!fs.existsSync(packageJsonPath)) { diff --git a/lib/cli/src/js-package-manager/NPMProxy.ts b/lib/cli/src/js-package-manager/NPMProxy.ts index b3d4b46d7ade..6ad49230cea9 100644 --- a/lib/cli/src/js-package-manager/NPMProxy.ts +++ b/lib/cli/src/js-package-manager/NPMProxy.ts @@ -19,4 +19,17 @@ export class NPMProxy extends JsPackageManager { protected runInstall(): { status: number } { return spawnSync('npm', ['install'], { stdio: 'inherit' }); } + + protected runAddDeps( + dependencies: string[], + installAsDevDependencies: boolean + ): { status: number } { + const args = ['install', ...dependencies]; + + if (installAsDevDependencies) { + args.push('-D'); + } + + return spawnSync('npm', args, { stdio: 'inherit' }); + } } diff --git a/lib/cli/src/js-package-manager/Yarn1Proxy.ts b/lib/cli/src/js-package-manager/Yarn1Proxy.ts index c1d8fdf93536..681e91d6af1a 100644 --- a/lib/cli/src/js-package-manager/Yarn1Proxy.ts +++ b/lib/cli/src/js-package-manager/Yarn1Proxy.ts @@ -19,4 +19,17 @@ export class Yarn1Proxy extends JsPackageManager { protected runInstall(): { status: number } { return spawnSync('yarn', { stdio: 'inherit' }); } + + protected runAddDeps( + dependencies: string[], + installAsDevDependencies: boolean + ): { status: number } { + const args = ['add', '--ignore-workspace-root-check', ...dependencies]; + + if (installAsDevDependencies) { + args.push('-D'); + } + + return spawnSync('yarn', args, { stdio: 'inherit' }); + } } diff --git a/lib/cli/src/js-package-manager/Yarn2Proxy.ts b/lib/cli/src/js-package-manager/Yarn2Proxy.ts index e29d2a17ad30..623d74b89eb1 100644 --- a/lib/cli/src/js-package-manager/Yarn2Proxy.ts +++ b/lib/cli/src/js-package-manager/Yarn2Proxy.ts @@ -19,4 +19,17 @@ export class Yarn2Proxy extends JsPackageManager { protected runInstall(): { status: number } { return spawnSync('yarn', { stdio: 'inherit' }); } + + protected runAddDeps( + dependencies: string[], + installAsDevDependencies: boolean + ): { status: number } { + const args = ['add', ...dependencies]; + + if (installAsDevDependencies) { + args.push('-D'); + } + + return spawnSync('yarn', args, { stdio: 'inherit' }); + } } From b6497c2fec260ae5efb93f316fe0731b3dccbffd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABtan=20Maisse?= Date: Sun, 7 Jun 2020 20:33:34 +0200 Subject: [PATCH 09/22] refactor: move `getVersionedPackages` to JsPackageManager --- lib/cli/src/generators/ANGULAR/index.ts | 3 +-- lib/cli/src/generators/AURELIA/index.ts | 3 +-- lib/cli/src/generators/HTML/index.ts | 9 ++------- lib/cli/src/generators/REACT/index.ts | 9 ++------- lib/cli/src/generators/REACT_SCRIPTS/index.ts | 9 ++------- lib/cli/src/generators/SFC_VUE/index.ts | 9 ++------- lib/cli/src/generators/VUE/index.ts | 3 +-- .../src/generators/WEB-COMPONENTS/index.ts | 4 ++-- lib/cli/src/generators/WEBPACK_REACT/index.ts | 9 ++------- lib/cli/src/helpers.ts | 8 -------- .../js-package-manager/JsPackageManager.ts | 20 ++++++++++++++++++- 11 files changed, 34 insertions(+), 52 deletions(-) diff --git a/lib/cli/src/generators/ANGULAR/index.ts b/lib/cli/src/generators/ANGULAR/index.ts index 7dcd9a4eb921..3c5a102725c4 100644 --- a/lib/cli/src/generators/ANGULAR/index.ts +++ b/lib/cli/src/generators/ANGULAR/index.ts @@ -6,7 +6,6 @@ import { getAngularAppTsConfigPath, } from './angular-helpers'; import { - getVersionedPackages, writePackageJson, getBabelDependencies, writeFileAsJson, @@ -33,7 +32,7 @@ async function addDependencies( packages.push('@storybook/addon-docs'); } - const versionedPackages = await getVersionedPackages(npmOptions, ...packages); + const versionedPackages = await packageManager.getVersionedPackages(npmOptions, ...packages); const packageJson = packageManager.retrievePackageJson(); diff --git a/lib/cli/src/generators/AURELIA/index.ts b/lib/cli/src/generators/AURELIA/index.ts index 78f1d41b2eac..72a4324b8762 100644 --- a/lib/cli/src/generators/AURELIA/index.ts +++ b/lib/cli/src/generators/AURELIA/index.ts @@ -1,5 +1,4 @@ import { - getVersionedPackages, writePackageJson, getBabelDependencies, writeFileAsJson, @@ -47,7 +46,7 @@ const generator: Generator = async ( packages.push('@storybook/addon-docs'); } - const versionedPackages = await getVersionedPackages(npmOptions, ...packages); + const versionedPackages = await packageManager.getVersionedPackages(npmOptions, ...packages); const packageJson = packageManager.retrievePackageJson(); packageJson.dependencies = packageJson.dependencies || {}; packageJson.devDependencies = packageJson.devDependencies || {}; diff --git a/lib/cli/src/generators/HTML/index.ts b/lib/cli/src/generators/HTML/index.ts index 2aa38a22709b..29abcd82b355 100755 --- a/lib/cli/src/generators/HTML/index.ts +++ b/lib/cli/src/generators/HTML/index.ts @@ -1,16 +1,11 @@ -import { - getVersionedPackages, - writePackageJson, - getBabelDependencies, - copyTemplate, -} from '../../helpers'; +import { writePackageJson, getBabelDependencies, copyTemplate } from '../../helpers'; import { StoryFormat } from '../../project_types'; import { Generator } from '../Generator'; const generator: Generator = async (packageManager, npmOptions, { storyFormat }) => { const packages = ['@storybook/html', '@storybook/addon-actions', '@storybook/addon-links']; - const versionedPackages = await getVersionedPackages(npmOptions, ...packages); + const versionedPackages = await packageManager.getVersionedPackages(npmOptions, ...packages); if (storyFormat === StoryFormat.MDX) { packages.push('@storybook/addon-docs'); } diff --git a/lib/cli/src/generators/REACT/index.ts b/lib/cli/src/generators/REACT/index.ts index 8e02494924a6..454b36a56727 100644 --- a/lib/cli/src/generators/REACT/index.ts +++ b/lib/cli/src/generators/REACT/index.ts @@ -1,9 +1,4 @@ -import { - getVersionedPackages, - writePackageJson, - getBabelDependencies, - copyTemplate, -} from '../../helpers'; +import { writePackageJson, getBabelDependencies, copyTemplate } from '../../helpers'; import { StoryFormat } from '../../project_types'; import { Generator } from '../Generator'; @@ -18,7 +13,7 @@ const generator: Generator = async (packageManager, npmOptions, { storyFormat }) packages.push('@storybook/addon-docs'); } - const versionedPackages = await getVersionedPackages(npmOptions, ...packages); + const versionedPackages = await packageManager.getVersionedPackages(npmOptions, ...packages); copyTemplate(__dirname, storyFormat); diff --git a/lib/cli/src/generators/REACT_SCRIPTS/index.ts b/lib/cli/src/generators/REACT_SCRIPTS/index.ts index 0913ab153bda..8c7115744a7d 100644 --- a/lib/cli/src/generators/REACT_SCRIPTS/index.ts +++ b/lib/cli/src/generators/REACT_SCRIPTS/index.ts @@ -1,11 +1,6 @@ import path from 'path'; import fs from 'fs'; -import { - getVersionedPackages, - writePackageJson, - getBabelDependencies, - copyTemplate, -} from '../../helpers'; +import { writePackageJson, getBabelDependencies, copyTemplate } from '../../helpers'; import { StoryFormat } from '../../project_types'; import { Generator } from '../Generator'; @@ -22,7 +17,7 @@ const generator: Generator = async (packageManager, npmOptions, { storyFormat }) packages.push('@storybook/addon-docs'); } - const versionedPackages = await getVersionedPackages(npmOptions, ...packages); + const versionedPackages = await packageManager.getVersionedPackages(npmOptions, ...packages); copyTemplate(__dirname, storyFormat); diff --git a/lib/cli/src/generators/SFC_VUE/index.ts b/lib/cli/src/generators/SFC_VUE/index.ts index c9c32c143717..6c53d3127810 100644 --- a/lib/cli/src/generators/SFC_VUE/index.ts +++ b/lib/cli/src/generators/SFC_VUE/index.ts @@ -1,9 +1,4 @@ -import { - getVersionedPackages, - writePackageJson, - getBabelDependencies, - copyTemplate, -} from '../../helpers'; +import { writePackageJson, getBabelDependencies, copyTemplate } from '../../helpers'; import { StoryFormat } from '../../project_types'; import { Generator } from '../Generator'; @@ -17,7 +12,7 @@ const generator: Generator = async (packageManager, npmOptions, { storyFormat }) if (storyFormat === StoryFormat.MDX) { packages.push('@storybook/addon-docs'); } - const versionedPackages = await getVersionedPackages(npmOptions, ...packages); + const versionedPackages = await packageManager.getVersionedPackages(npmOptions, ...packages); copyTemplate(__dirname, storyFormat); diff --git a/lib/cli/src/generators/VUE/index.ts b/lib/cli/src/generators/VUE/index.ts index e13b7ae06e22..cc9bc112aa0b 100644 --- a/lib/cli/src/generators/VUE/index.ts +++ b/lib/cli/src/generators/VUE/index.ts @@ -1,6 +1,5 @@ import { getVersion, - getVersionedPackages, writePackageJson, getBabelDependencies, addToDevDependenciesIfNotPresent, @@ -20,7 +19,7 @@ const generator: Generator = async (packageManager, npmOptions, { storyFormat }) if (storyFormat === StoryFormat.MDX) { packages.push('@storybook/addon-docs'); } - const versionedPackages = await getVersionedPackages(npmOptions, ...packages); + const versionedPackages = await packageManager.getVersionedPackages(npmOptions, ...packages); copyTemplate(__dirname, storyFormat); diff --git a/lib/cli/src/generators/WEB-COMPONENTS/index.ts b/lib/cli/src/generators/WEB-COMPONENTS/index.ts index 82a4454f8edf..2c6ae2983a7c 100755 --- a/lib/cli/src/generators/WEB-COMPONENTS/index.ts +++ b/lib/cli/src/generators/WEB-COMPONENTS/index.ts @@ -1,6 +1,6 @@ import fse from 'fs-extra'; import path from 'path'; -import { getVersionedPackages, writePackageJson, getBabelDependencies } from '../../helpers'; +import { writePackageJson, getBabelDependencies } from '../../helpers'; import { StoryFormat } from '../../project_types'; import { Generator } from '../Generator'; @@ -12,7 +12,7 @@ const generator: Generator = async (packageManager, npmOptions, { storyFormat }) 'lit-html', ]; - const versionedPackages = await getVersionedPackages(npmOptions, ...packages); + const versionedPackages = await packageManager.getVersionedPackages(npmOptions, ...packages); fse.copySync(path.resolve(__dirname, 'template/'), '.', { overwrite: true }); diff --git a/lib/cli/src/generators/WEBPACK_REACT/index.ts b/lib/cli/src/generators/WEBPACK_REACT/index.ts index ff2a01e50f64..12da87432981 100644 --- a/lib/cli/src/generators/WEBPACK_REACT/index.ts +++ b/lib/cli/src/generators/WEBPACK_REACT/index.ts @@ -1,9 +1,4 @@ -import { - getVersionedPackages, - writePackageJson, - getBabelDependencies, - copyTemplate, -} from '../../helpers'; +import { writePackageJson, getBabelDependencies, copyTemplate } from '../../helpers'; import { StoryFormat } from '../../project_types'; import { Generator } from '../Generator'; @@ -17,7 +12,7 @@ const generator: Generator = async (packageManager, npmOptions, { storyFormat }) if (storyFormat === StoryFormat.MDX) { packages.push('@storybook/addon-docs'); } - const versionedPackages = await getVersionedPackages(npmOptions, ...packages); + const versionedPackages = await packageManager.getVersionedPackages(npmOptions, ...packages); copyTemplate(__dirname, storyFormat); diff --git a/lib/cli/src/helpers.ts b/lib/cli/src/helpers.ts index f20e67f516fe..9a6f4c8f3b75 100644 --- a/lib/cli/src/helpers.ts +++ b/lib/cli/src/helpers.ts @@ -48,14 +48,6 @@ export function getVersions(npmOptions: NpmOptions, ...packageNames: string[]) { return Promise.all(packageNames.map((packageName) => getVersion(npmOptions, packageName))); } -export function getVersionedPackages(npmOptions: NpmOptions, ...packageNames: string[]) { - return Promise.all( - packageNames.map( - async (packageName) => `${packageName}@${await getVersion(npmOptions, packageName)}` - ) - ); -} - export function getPackageJson() { const packageJsonPath = path.resolve('package.json'); if (!fs.existsSync(packageJsonPath)) { diff --git a/lib/cli/src/js-package-manager/JsPackageManager.ts b/lib/cli/src/js-package-manager/JsPackageManager.ts index 2622ded412f2..f220fb3fcd53 100644 --- a/lib/cli/src/js-package-manager/JsPackageManager.ts +++ b/lib/cli/src/js-package-manager/JsPackageManager.ts @@ -1,7 +1,8 @@ import path from 'path'; import fs from 'fs'; -import { commandLog, writePackageJson } from '../helpers'; +import { commandLog, getVersion, writePackageJson } from '../helpers'; import { PackageJson } from '../PackageJson'; +import { NpmOptions } from '../NpmOptions'; const logger = console; @@ -100,6 +101,23 @@ export abstract class JsPackageManager { } } + /** + * Return an array of strings matching following format: `@` + * + * @param npmOptions + * @param packageNames + */ + public getVersionedPackages( + npmOptions: NpmOptions, + ...packageNames: string[] + ): Promise { + return Promise.all( + packageNames.map( + async (packageName) => `${packageName}@${await getVersion(npmOptions, packageName)}` + ) + ); + } + protected abstract runInstall(): { status: number }; protected abstract runAddDeps( From 2760021aa1df8c52b53aeef7661a0cf35008bc76 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABtan=20Maisse?= Date: Sun, 7 Jun 2020 20:42:21 +0200 Subject: [PATCH 10/22] refactor: move `getVersions` to JsPackageManager --- lib/cli/src/generators/EMBER/index.ts | 4 ++-- lib/cli/src/generators/MARKO/index.ts | 8 ++++++-- lib/cli/src/generators/METEOR/index.ts | 4 ++-- lib/cli/src/generators/MITHRIL/index.ts | 4 ++-- lib/cli/src/generators/PREACT/index.ts | 9 +++++++-- lib/cli/src/generators/RAX/index.ts | 4 ++-- lib/cli/src/generators/REACT_NATIVE/index.ts | 15 +++++++-------- lib/cli/src/generators/RIOT/index.ts | 4 ++-- lib/cli/src/generators/SVELTE/index.ts | 4 ++-- .../UPDATE_PACKAGE_ORGANIZATIONS/index.ts | 10 ++-------- lib/cli/src/helpers.ts | 4 ---- .../src/js-package-manager/JsPackageManager.ts | 11 +++++++++++ 12 files changed, 45 insertions(+), 36 deletions(-) diff --git a/lib/cli/src/generators/EMBER/index.ts b/lib/cli/src/generators/EMBER/index.ts index 9c8b2c4bcf4f..ab31dd2f406f 100644 --- a/lib/cli/src/generators/EMBER/index.ts +++ b/lib/cli/src/generators/EMBER/index.ts @@ -1,4 +1,4 @@ -import { getVersions, writePackageJson, getBabelDependencies, copyTemplate } from '../../helpers'; +import { writePackageJson, getBabelDependencies, copyTemplate } from '../../helpers'; import { Generator } from '../Generator'; const generator: Generator = async (packageManager, npmOptions, { storyFormat }) => { @@ -9,7 +9,7 @@ const generator: Generator = async (packageManager, npmOptions, { storyFormat }) linksVersion, actionsVersion, addonsVersion, - ] = await getVersions( + ] = await packageManager.getVersions( npmOptions, '@storybook/ember', // babel-plugin-ember-modules-api-polyfill is a peerDep of @storybook/ember diff --git a/lib/cli/src/generators/MARKO/index.ts b/lib/cli/src/generators/MARKO/index.ts index ed4e6874b00b..e34f7af984d8 100644 --- a/lib/cli/src/generators/MARKO/index.ts +++ b/lib/cli/src/generators/MARKO/index.ts @@ -1,8 +1,12 @@ -import { getVersions, writePackageJson, getBabelDependencies, copyTemplate } from '../../helpers'; +import { writePackageJson, getBabelDependencies, copyTemplate } from '../../helpers'; import { Generator } from '../Generator'; const generator: Generator = async (packageManager, npmOptions, { storyFormat }) => { - const [storybookVersion, addonActionVersion, addonKnobsVersion] = await getVersions( + const [ + storybookVersion, + addonActionVersion, + addonKnobsVersion, + ] = await packageManager.getVersions( npmOptions, '@storybook/marko', '@storybook/addon-actions', diff --git a/lib/cli/src/generators/METEOR/index.ts b/lib/cli/src/generators/METEOR/index.ts index 0e64017c6bb0..0881f11598b3 100644 --- a/lib/cli/src/generators/METEOR/index.ts +++ b/lib/cli/src/generators/METEOR/index.ts @@ -1,6 +1,6 @@ import fs from 'fs'; import JSON5 from 'json5'; -import { getVersions, writePackageJson, getBabelDependencies, copyTemplate } from '../../helpers'; +import { writePackageJson, getBabelDependencies, copyTemplate } from '../../helpers'; import { Generator } from '../Generator'; const generator: Generator = async (packageManager, npmOptions, { storyFormat }) => { @@ -14,7 +14,7 @@ const generator: Generator = async (packageManager, npmOptions, { storyFormat }) reactDomVersion, presetEnvVersion, presetReactVersion, - ] = await getVersions( + ] = await packageManager.getVersions( npmOptions, '@storybook/react', '@storybook/addon-actions', diff --git a/lib/cli/src/generators/MITHRIL/index.ts b/lib/cli/src/generators/MITHRIL/index.ts index af10db13b145..cc96397cf822 100644 --- a/lib/cli/src/generators/MITHRIL/index.ts +++ b/lib/cli/src/generators/MITHRIL/index.ts @@ -1,4 +1,4 @@ -import { getVersions, writePackageJson, getBabelDependencies, copyTemplate } from '../../helpers'; +import { writePackageJson, getBabelDependencies, copyTemplate } from '../../helpers'; import { Generator } from '../Generator'; const generator: Generator = async (packageManager, npmOptions, { storyFormat }) => { @@ -8,7 +8,7 @@ const generator: Generator = async (packageManager, npmOptions, { storyFormat }) linksVersion, knobsVersion, addonsVersion, - ] = await getVersions( + ] = await packageManager.getVersions( npmOptions, '@storybook/mithril', '@storybook/addon-actions', diff --git a/lib/cli/src/generators/PREACT/index.ts b/lib/cli/src/generators/PREACT/index.ts index ee87f70ed37c..2135b6fb13e4 100644 --- a/lib/cli/src/generators/PREACT/index.ts +++ b/lib/cli/src/generators/PREACT/index.ts @@ -1,8 +1,13 @@ -import { getVersions, writePackageJson, getBabelDependencies, copyTemplate } from '../../helpers'; +import { writePackageJson, getBabelDependencies, copyTemplate } from '../../helpers'; import { Generator } from '../Generator'; const generator: Generator = async (packageManager, npmOptions, { storyFormat }) => { - const [storybookVersion, actionsVersion, linksVersion, addonsVersion] = await getVersions( + const [ + storybookVersion, + actionsVersion, + linksVersion, + addonsVersion, + ] = await packageManager.getVersions( npmOptions, '@storybook/preact', '@storybook/addon-actions', diff --git a/lib/cli/src/generators/RAX/index.ts b/lib/cli/src/generators/RAX/index.ts index 30756e9779db..d8d9abf22784 100644 --- a/lib/cli/src/generators/RAX/index.ts +++ b/lib/cli/src/generators/RAX/index.ts @@ -1,4 +1,4 @@ -import { getVersions, writePackageJson, getBabelDependencies, copyTemplate } from '../../helpers'; +import { writePackageJson, getBabelDependencies, copyTemplate } from '../../helpers'; import { Generator } from '../Generator'; const generator: Generator = async (packageManager, npmOptions, { storyFormat }) => { @@ -8,7 +8,7 @@ const generator: Generator = async (packageManager, npmOptions, { storyFormat }) linksVersion, addonsVersion, latestRaxVersion, - ] = await getVersions( + ] = await packageManager.getVersions( npmOptions, '@storybook/rax', '@storybook/addon-actions', diff --git a/lib/cli/src/generators/REACT_NATIVE/index.ts b/lib/cli/src/generators/REACT_NATIVE/index.ts index 6342dc418507..1f791ab07389 100644 --- a/lib/cli/src/generators/REACT_NATIVE/index.ts +++ b/lib/cli/src/generators/REACT_NATIVE/index.ts @@ -1,12 +1,6 @@ import shell from 'shelljs'; import chalk from 'chalk'; -import { - getVersions, - writePackageJson, - paddedLog, - getBabelDependencies, - copyTemplate, -} from '../../helpers'; +import { writePackageJson, paddedLog, getBabelDependencies, copyTemplate } from '../../helpers'; import { NpmOptions } from '../../NpmOptions'; import { GeneratorOptions } from '../Generator'; import { JsPackageManager } from '../../js-package-manager'; @@ -17,7 +11,12 @@ export default async ( installServer: boolean, { storyFormat }: GeneratorOptions ) => { - const [storybookVersion, addonsVersion, actionsVersion, linksVersion] = await getVersions( + const [ + storybookVersion, + addonsVersion, + actionsVersion, + linksVersion, + ] = await packageManager.getVersions( npmOptions, '@storybook/react-native', '@storybook/addons', diff --git a/lib/cli/src/generators/RIOT/index.ts b/lib/cli/src/generators/RIOT/index.ts index ddb2a568a6fe..4f0a783e2a28 100644 --- a/lib/cli/src/generators/RIOT/index.ts +++ b/lib/cli/src/generators/RIOT/index.ts @@ -1,4 +1,4 @@ -import { getVersions, writePackageJson, getBabelDependencies, copyTemplate } from '../../helpers'; +import { writePackageJson, getBabelDependencies, copyTemplate } from '../../helpers'; import { Generator } from '../Generator'; const generator: Generator = async (packageManager, npmOptions, { storyFormat }) => { @@ -8,7 +8,7 @@ const generator: Generator = async (packageManager, npmOptions, { storyFormat }) linksVersion, addonsVersion, tagLoaderVersion, - ] = await getVersions( + ] = await packageManager.getVersions( npmOptions, '@storybook/riot', '@storybook/addon-actions', diff --git a/lib/cli/src/generators/SVELTE/index.ts b/lib/cli/src/generators/SVELTE/index.ts index 54b073f05569..64341d76830e 100644 --- a/lib/cli/src/generators/SVELTE/index.ts +++ b/lib/cli/src/generators/SVELTE/index.ts @@ -1,4 +1,4 @@ -import { getVersions, writePackageJson, getBabelDependencies, copyTemplate } from '../../helpers'; +import { writePackageJson, getBabelDependencies, copyTemplate } from '../../helpers'; import { Generator } from '../Generator'; const generator: Generator = async (packageManager, npmOptions, { storyFormat }) => { @@ -9,7 +9,7 @@ const generator: Generator = async (packageManager, npmOptions, { storyFormat }) addonsVersion, svelte, svelteLoader, - ] = await getVersions( + ] = await packageManager.getVersions( npmOptions, '@storybook/svelte', '@storybook/addon-actions', diff --git a/lib/cli/src/generators/UPDATE_PACKAGE_ORGANIZATIONS/index.ts b/lib/cli/src/generators/UPDATE_PACKAGE_ORGANIZATIONS/index.ts index 5a7eedf3e726..c6e4a237419d 100644 --- a/lib/cli/src/generators/UPDATE_PACKAGE_ORGANIZATIONS/index.ts +++ b/lib/cli/src/generators/UPDATE_PACKAGE_ORGANIZATIONS/index.ts @@ -2,13 +2,7 @@ import path from 'path'; import { sync as spawnSync } from 'cross-spawn'; import { packageNames } from '@storybook/codemod'; -import { - getBabelDependencies, - getPackageJson, - getVersion, - getVersions, - writePackageJson, -} from '../../helpers'; +import { getBabelDependencies, getPackageJson, getVersion, writePackageJson } from '../../helpers'; import { PackageJson } from '../../PackageJson'; import { NpmOptions } from '../../NpmOptions'; import { JsPackageManager } from '../../js-package-manager'; @@ -29,7 +23,7 @@ async function updatePackageJson(packageManager: JsPackageManager, npmOptions: N const packageJson = getPackageJson(); const { devDependencies } = packageJson; - const [actionsVersion, linksVersion] = await getVersions( + const [actionsVersion, linksVersion] = await packageManager.getVersions( npmOptions, '@storybook/addon-actions', '@storybook/addon-links' diff --git a/lib/cli/src/helpers.ts b/lib/cli/src/helpers.ts index 9a6f4c8f3b75..19a88d6dc264 100644 --- a/lib/cli/src/helpers.ts +++ b/lib/cli/src/helpers.ts @@ -44,10 +44,6 @@ export async function getVersion(npmOptions: NpmOptions, packageName: string, co return `^${versionToUse}`; } -export function getVersions(npmOptions: NpmOptions, ...packageNames: string[]) { - return Promise.all(packageNames.map((packageName) => getVersion(npmOptions, packageName))); -} - export function getPackageJson() { const packageJsonPath = path.resolve('package.json'); if (!fs.existsSync(packageJsonPath)) { diff --git a/lib/cli/src/js-package-manager/JsPackageManager.ts b/lib/cli/src/js-package-manager/JsPackageManager.ts index f220fb3fcd53..918e5c582908 100644 --- a/lib/cli/src/js-package-manager/JsPackageManager.ts +++ b/lib/cli/src/js-package-manager/JsPackageManager.ts @@ -118,6 +118,17 @@ export abstract class JsPackageManager { ); } + /** + * Return an array of string standing for the latest version of the input packages. + * To be able to identify which version goes with which package the order of the input array is keep. + * + * @param npmOptions + * @param packageNames + */ + public getVersions(npmOptions: NpmOptions, ...packageNames: string[]): Promise { + return Promise.all(packageNames.map((packageName) => getVersion(npmOptions, packageName))); + } + protected abstract runInstall(): { status: number }; protected abstract runAddDeps( From 126e7e2ea8736bc4160f9cb0d58a9c5fe6c2660a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABtan=20Maisse?= Date: Sun, 7 Jun 2020 20:50:33 +0200 Subject: [PATCH 11/22] refactor: move `getVersion` to JsPackageManager --- lib/cli/src/generators/ANGULAR/index.ts | 2 +- lib/cli/src/generators/AURELIA/index.ts | 2 +- lib/cli/src/generators/EMBER/index.ts | 2 +- lib/cli/src/generators/HTML/index.ts | 2 +- lib/cli/src/generators/MARIONETTE/index.ts | 6 +-- lib/cli/src/generators/MARKO/index.ts | 2 +- lib/cli/src/generators/METEOR/index.ts | 2 +- lib/cli/src/generators/MITHRIL/index.ts | 2 +- lib/cli/src/generators/PREACT/index.ts | 2 +- lib/cli/src/generators/RAX/index.ts | 2 +- lib/cli/src/generators/REACT/index.ts | 2 +- lib/cli/src/generators/REACT_NATIVE/index.ts | 2 +- lib/cli/src/generators/REACT_SCRIPTS/index.ts | 2 +- lib/cli/src/generators/RIOT/index.ts | 2 +- lib/cli/src/generators/SFC_VUE/index.ts | 2 +- lib/cli/src/generators/SVELTE/index.ts | 2 +- .../UPDATE_PACKAGE_ORGANIZATIONS/index.ts | 9 ++-- lib/cli/src/generators/VUE/index.ts | 5 +- .../src/generators/WEB-COMPONENTS/index.ts | 2 +- lib/cli/src/generators/WEBPACK_REACT/index.ts | 2 +- lib/cli/src/helpers.ts | 46 ++++--------------- .../js-package-manager/JsPackageManager.ts | 43 +++++++++++++++-- 22 files changed, 77 insertions(+), 66 deletions(-) diff --git a/lib/cli/src/generators/ANGULAR/index.ts b/lib/cli/src/generators/ANGULAR/index.ts index 3c5a102725c4..032180767193 100644 --- a/lib/cli/src/generators/ANGULAR/index.ts +++ b/lib/cli/src/generators/ANGULAR/index.ts @@ -45,7 +45,7 @@ async function addDependencies( writePackageJson(packageJson); - const babelDependencies = await getBabelDependencies(npmOptions, packageJson); + const babelDependencies = await getBabelDependencies(packageManager, npmOptions, packageJson); packageManager.addDependencies({ ...npmOptions, packageJson }, [ ...versionedPackages, diff --git a/lib/cli/src/generators/AURELIA/index.ts b/lib/cli/src/generators/AURELIA/index.ts index 72a4324b8762..76aaa17f5f8d 100644 --- a/lib/cli/src/generators/AURELIA/index.ts +++ b/lib/cli/src/generators/AURELIA/index.ts @@ -55,7 +55,7 @@ const generator: Generator = async ( packageJson.scripts['build-storybook'] = 'build-storybook'; writePackageJson(packageJson); addStorybookExcludeGlobToTsConfig(); - const babelDependencies = await getBabelDependencies(npmOptions, packageJson); + const babelDependencies = await getBabelDependencies(packageManager, npmOptions, packageJson); packageManager.addDependencies({ ...npmOptions, packageJson }, [ ...versionedPackages, ...babelDependencies, diff --git a/lib/cli/src/generators/EMBER/index.ts b/lib/cli/src/generators/EMBER/index.ts index ab31dd2f406f..4ce0b1521004 100644 --- a/lib/cli/src/generators/EMBER/index.ts +++ b/lib/cli/src/generators/EMBER/index.ts @@ -38,7 +38,7 @@ const generator: Generator = async (packageManager, npmOptions, { storyFormat }) writePackageJson(packageJson); - const babelDependencies = await getBabelDependencies(npmOptions, packageJson); + const babelDependencies = await getBabelDependencies(packageManager, npmOptions, packageJson); packageManager.addDependencies({ ...npmOptions, packageJson }, [ `@storybook/ember@${storybookVersion}`, diff --git a/lib/cli/src/generators/HTML/index.ts b/lib/cli/src/generators/HTML/index.ts index 29abcd82b355..38b304ed5b9d 100755 --- a/lib/cli/src/generators/HTML/index.ts +++ b/lib/cli/src/generators/HTML/index.ts @@ -23,7 +23,7 @@ const generator: Generator = async (packageManager, npmOptions, { storyFormat }) writePackageJson(packageJson); - const babelDependencies = await getBabelDependencies(npmOptions, packageJson); + const babelDependencies = await getBabelDependencies(packageManager, npmOptions, packageJson); packageManager.addDependencies({ ...npmOptions, packageJson }, [ ...versionedPackages, diff --git a/lib/cli/src/generators/MARIONETTE/index.ts b/lib/cli/src/generators/MARIONETTE/index.ts index 13bb96b798ad..a2ea776f3a67 100644 --- a/lib/cli/src/generators/MARIONETTE/index.ts +++ b/lib/cli/src/generators/MARIONETTE/index.ts @@ -1,10 +1,10 @@ import fse from 'fs-extra'; import path from 'path'; -import { getVersion, writePackageJson, getBabelDependencies } from '../../helpers'; +import { writePackageJson, getBabelDependencies } from '../../helpers'; import { Generator } from '../Generator'; const generator: Generator = async (packageManager, npmOptions) => { - const storybookVersion = await getVersion(npmOptions, '@storybook/marionette'); + const storybookVersion = await packageManager.getVersion(npmOptions, '@storybook/marionette'); fse.copySync(path.resolve(__dirname, 'template/'), '.', { overwrite: true }); const packageJson = packageManager.retrievePackageJson(); @@ -18,7 +18,7 @@ const generator: Generator = async (packageManager, npmOptions) => { writePackageJson(packageJson); - const babelDependencies = await getBabelDependencies(npmOptions, packageJson); + const babelDependencies = await getBabelDependencies(packageManager, npmOptions, packageJson); packageManager.addDependencies({ ...npmOptions, packageJson }, [ `@storybook/marionette@${storybookVersion}`, diff --git a/lib/cli/src/generators/MARKO/index.ts b/lib/cli/src/generators/MARKO/index.ts index e34f7af984d8..3fd43a39eb01 100644 --- a/lib/cli/src/generators/MARKO/index.ts +++ b/lib/cli/src/generators/MARKO/index.ts @@ -26,7 +26,7 @@ const generator: Generator = async (packageManager, npmOptions, { storyFormat }) writePackageJson(packageJson); - const babelDependencies = await getBabelDependencies(npmOptions, packageJson); + const babelDependencies = await getBabelDependencies(packageManager, npmOptions, packageJson); packageManager.addDependencies({ ...npmOptions, packageJson }, [ `@storybook/marko@${storybookVersion}`, diff --git a/lib/cli/src/generators/METEOR/index.ts b/lib/cli/src/generators/METEOR/index.ts index 0881f11598b3..a8aab312975b 100644 --- a/lib/cli/src/generators/METEOR/index.ts +++ b/lib/cli/src/generators/METEOR/index.ts @@ -68,7 +68,7 @@ const generator: Generator = async (packageManager, npmOptions, { storyFormat }) writePackageJson(packageJson); - const babelDependencies = await getBabelDependencies(npmOptions, packageJson); + const babelDependencies = await getBabelDependencies(packageManager, npmOptions, packageJson); // add react packages. const dependencies = []; diff --git a/lib/cli/src/generators/MITHRIL/index.ts b/lib/cli/src/generators/MITHRIL/index.ts index cc96397cf822..eab1d199b97d 100644 --- a/lib/cli/src/generators/MITHRIL/index.ts +++ b/lib/cli/src/generators/MITHRIL/index.ts @@ -30,7 +30,7 @@ const generator: Generator = async (packageManager, npmOptions, { storyFormat }) writePackageJson(packageJson); - const babelDependencies = await getBabelDependencies(npmOptions, packageJson); + const babelDependencies = await getBabelDependencies(packageManager, npmOptions, packageJson); packageManager.addDependencies({ ...npmOptions, packageJson }, [ `@storybook/mithril@${storybookVersion}`, diff --git a/lib/cli/src/generators/PREACT/index.ts b/lib/cli/src/generators/PREACT/index.ts index 2135b6fb13e4..21dbd67c47f1 100644 --- a/lib/cli/src/generators/PREACT/index.ts +++ b/lib/cli/src/generators/PREACT/index.ts @@ -28,7 +28,7 @@ const generator: Generator = async (packageManager, npmOptions, { storyFormat }) writePackageJson(packageJson); - const babelDependencies = await getBabelDependencies(npmOptions, packageJson); + const babelDependencies = await getBabelDependencies(packageManager, npmOptions, packageJson); packageManager.addDependencies({ ...npmOptions, packageJson }, [ `@storybook/preact@${storybookVersion}`, diff --git a/lib/cli/src/generators/RAX/index.ts b/lib/cli/src/generators/RAX/index.ts index d8d9abf22784..44056461ee34 100644 --- a/lib/cli/src/generators/RAX/index.ts +++ b/lib/cli/src/generators/RAX/index.ts @@ -41,7 +41,7 @@ const generator: Generator = async (packageManager, npmOptions, { storyFormat }) writePackageJson(packageJson); - const babelDependencies = await getBabelDependencies(npmOptions, packageJson); + const babelDependencies = await getBabelDependencies(packageManager, npmOptions, packageJson); packageManager.addDependencies({ ...npmOptions, packageJson }, [ `@storybook/rax@${storybookVersion}`, diff --git a/lib/cli/src/generators/REACT/index.ts b/lib/cli/src/generators/REACT/index.ts index 454b36a56727..3874aff4eab8 100644 --- a/lib/cli/src/generators/REACT/index.ts +++ b/lib/cli/src/generators/REACT/index.ts @@ -28,7 +28,7 @@ const generator: Generator = async (packageManager, npmOptions, { storyFormat }) writePackageJson(packageJson); - const babelDependencies = await getBabelDependencies(npmOptions, packageJson); + const babelDependencies = await getBabelDependencies(packageManager, npmOptions, packageJson); packageManager.addDependencies({ ...npmOptions, packageJson }, [ ...versionedPackages, diff --git a/lib/cli/src/generators/REACT_NATIVE/index.ts b/lib/cli/src/generators/REACT_NATIVE/index.ts index 1f791ab07389..c695f0a0bbaf 100644 --- a/lib/cli/src/generators/REACT_NATIVE/index.ts +++ b/lib/cli/src/generators/REACT_NATIVE/index.ts @@ -74,7 +74,7 @@ export default async ( writePackageJson(packageJson); - const babelDependencies = await getBabelDependencies(npmOptions, packageJson); + const babelDependencies = await getBabelDependencies(packageManager, npmOptions, packageJson); packageManager.addDependencies({ ...npmOptions, packageJson }, [ ...devDependencies, diff --git a/lib/cli/src/generators/REACT_SCRIPTS/index.ts b/lib/cli/src/generators/REACT_SCRIPTS/index.ts index 8c7115744a7d..5a65d5b13ad9 100644 --- a/lib/cli/src/generators/REACT_SCRIPTS/index.ts +++ b/lib/cli/src/generators/REACT_SCRIPTS/index.ts @@ -38,7 +38,7 @@ const generator: Generator = async (packageManager, npmOptions, { storyFormat }) writePackageJson(packageJson); - const babelDependencies = await getBabelDependencies(npmOptions, packageJson); + const babelDependencies = await getBabelDependencies(packageManager, npmOptions, packageJson); packageManager.addDependencies({ ...npmOptions, packageJson }, [ ...versionedPackages, diff --git a/lib/cli/src/generators/RIOT/index.ts b/lib/cli/src/generators/RIOT/index.ts index 4f0a783e2a28..b6e5107b74cc 100644 --- a/lib/cli/src/generators/RIOT/index.ts +++ b/lib/cli/src/generators/RIOT/index.ts @@ -42,7 +42,7 @@ const generator: Generator = async (packageManager, npmOptions, { storyFormat }) writePackageJson(packageJson); - const babelDependencies = await getBabelDependencies(npmOptions, packageJson); + const babelDependencies = await getBabelDependencies(packageManager, npmOptions, packageJson); packageManager.addDependencies({ ...npmOptions, packageJson }, [ ...dependencies, diff --git a/lib/cli/src/generators/SFC_VUE/index.ts b/lib/cli/src/generators/SFC_VUE/index.ts index 6c53d3127810..b6b8985bdf10 100644 --- a/lib/cli/src/generators/SFC_VUE/index.ts +++ b/lib/cli/src/generators/SFC_VUE/index.ts @@ -27,7 +27,7 @@ const generator: Generator = async (packageManager, npmOptions, { storyFormat }) writePackageJson(packageJson); - const babelDependencies = await getBabelDependencies(npmOptions, packageJson); + const babelDependencies = await getBabelDependencies(packageManager, npmOptions, packageJson); packageManager.addDependencies({ ...npmOptions, packageJson }, [ ...versionedPackages, diff --git a/lib/cli/src/generators/SVELTE/index.ts b/lib/cli/src/generators/SVELTE/index.ts index 64341d76830e..bb340b260d74 100644 --- a/lib/cli/src/generators/SVELTE/index.ts +++ b/lib/cli/src/generators/SVELTE/index.ts @@ -32,7 +32,7 @@ const generator: Generator = async (packageManager, npmOptions, { storyFormat }) writePackageJson(packageJson); - const babelDependencies = await getBabelDependencies(npmOptions, packageJson); + const babelDependencies = await getBabelDependencies(packageManager, npmOptions, packageJson); packageManager.addDependencies({ ...npmOptions, packageJson }, [ `@storybook/svelte@${storybookVersion}`, diff --git a/lib/cli/src/generators/UPDATE_PACKAGE_ORGANIZATIONS/index.ts b/lib/cli/src/generators/UPDATE_PACKAGE_ORGANIZATIONS/index.ts index c6e4a237419d..209fd8835bd1 100644 --- a/lib/cli/src/generators/UPDATE_PACKAGE_ORGANIZATIONS/index.ts +++ b/lib/cli/src/generators/UPDATE_PACKAGE_ORGANIZATIONS/index.ts @@ -2,12 +2,13 @@ import path from 'path'; import { sync as spawnSync } from 'cross-spawn'; import { packageNames } from '@storybook/codemod'; -import { getBabelDependencies, getPackageJson, getVersion, writePackageJson } from '../../helpers'; +import { getBabelDependencies, getPackageJson, writePackageJson } from '../../helpers'; import { PackageJson } from '../../PackageJson'; import { NpmOptions } from '../../NpmOptions'; import { JsPackageManager } from '../../js-package-manager'; async function updatePackage( + packageManager: JsPackageManager, devDependencies: PackageJson['devDependencies'], oldName: string, newName: string, @@ -15,7 +16,7 @@ async function updatePackage( ) { if (devDependencies[oldName]) { delete devDependencies[oldName]; - devDependencies[newName] = await getVersion(npmOptions, newName); + devDependencies[newName] = await packageManager.getVersion(npmOptions, newName); } } @@ -35,7 +36,7 @@ async function updatePackageJson(packageManager: JsPackageManager, npmOptions: N await Promise.all( Object.keys(packageNames).map((oldName) => { const newName = packageNames[oldName]; - return updatePackage(devDependencies, oldName, newName, npmOptions); + return updatePackage(packageManager, devDependencies, oldName, newName, npmOptions); }) ); @@ -45,7 +46,7 @@ async function updatePackageJson(packageManager: JsPackageManager, npmOptions: N writePackageJson(packageJson); - const babelDependencies = await getBabelDependencies(npmOptions, packageJson); + const babelDependencies = await getBabelDependencies(packageManager, npmOptions, packageJson); if (babelDependencies.length > 0) { packageManager.addDependencies({ ...npmOptions, packageJson }, babelDependencies); diff --git a/lib/cli/src/generators/VUE/index.ts b/lib/cli/src/generators/VUE/index.ts index cc9bc112aa0b..c6de37a9dddf 100644 --- a/lib/cli/src/generators/VUE/index.ts +++ b/lib/cli/src/generators/VUE/index.ts @@ -1,5 +1,4 @@ import { - getVersion, writePackageJson, getBabelDependencies, addToDevDependenciesIfNotPresent, @@ -38,7 +37,7 @@ const generator: Generator = async (packageManager, npmOptions, { storyFormat }) addToDevDependenciesIfNotPresent( packageJson, '@babel/core', - await getVersion(npmOptions, '@babel/core') + await packageManager.getVersion(npmOptions, '@babel/core') ); } @@ -48,7 +47,7 @@ const generator: Generator = async (packageManager, npmOptions, { storyFormat }) writePackageJson(packageJson); - const babelDependencies = await getBabelDependencies(npmOptions, packageJson); + const babelDependencies = await getBabelDependencies(packageManager, npmOptions, packageJson); packageManager.addDependencies({ ...npmOptions, packageJson }, [ ...versionedPackages, ...babelDependencies, diff --git a/lib/cli/src/generators/WEB-COMPONENTS/index.ts b/lib/cli/src/generators/WEB-COMPONENTS/index.ts index 2c6ae2983a7c..ec44d1b22b7a 100755 --- a/lib/cli/src/generators/WEB-COMPONENTS/index.ts +++ b/lib/cli/src/generators/WEB-COMPONENTS/index.ts @@ -31,7 +31,7 @@ const generator: Generator = async (packageManager, npmOptions, { storyFormat }) writePackageJson(packageJson); - const babelDependencies = await getBabelDependencies(npmOptions, packageJson); + const babelDependencies = await getBabelDependencies(packageManager, npmOptions, packageJson); packageManager.addDependencies({ ...npmOptions, packageJson }, [ ...versionedPackages, diff --git a/lib/cli/src/generators/WEBPACK_REACT/index.ts b/lib/cli/src/generators/WEBPACK_REACT/index.ts index 12da87432981..c29d4b5f53bb 100644 --- a/lib/cli/src/generators/WEBPACK_REACT/index.ts +++ b/lib/cli/src/generators/WEBPACK_REACT/index.ts @@ -27,7 +27,7 @@ const generator: Generator = async (packageManager, npmOptions, { storyFormat }) writePackageJson(packageJson); - const babelDependencies = await getBabelDependencies(npmOptions, packageJson); + const babelDependencies = await getBabelDependencies(packageManager, npmOptions, packageJson); packageManager.addDependencies({ ...npmOptions, packageJson }, [ ...versionedPackages, diff --git a/lib/cli/src/helpers.ts b/lib/cli/src/helpers.ts index 19a88d6dc264..62d81958aa2d 100644 --- a/lib/cli/src/helpers.ts +++ b/lib/cli/src/helpers.ts @@ -3,47 +3,17 @@ import path from 'path'; import fs from 'fs'; import fse from 'fs-extra'; import chalk from 'chalk'; -import { gt, satisfies } from '@storybook/semver'; +import { satisfies } from '@storybook/semver'; import stripJsonComments from 'strip-json-comments'; import { latestVersion } from './latest_version'; import { StoryFormat } from './project_types'; import { PackageJson } from './PackageJson'; import { NpmOptions } from './NpmOptions'; - -// Cannot be `import` as it's not under TS root dir -const { version, devDependencies } = require('../package.json'); +import { JsPackageManager } from './js-package-manager'; const logger = console; -export async function getVersion(npmOptions: NpmOptions, packageName: string, constraint?: any) { - let current; - if (packageName === '@storybook/cli') { - current = version; - } else if (/storybook/.test(packageName)) { - current = devDependencies[packageName]; - } - - let latest; - try { - latest = await latestVersion(npmOptions, packageName, constraint); - } catch (e) { - if (current) { - logger.warn(`\n ${chalk.yellow(e.message)}`); - return current; - } - - logger.error(`\n ${chalk.red(e.message)}`); - process.exit(1); - } - - const versionToUse = - current && (!constraint || satisfies(current, constraint)) && gt(current, latest) - ? current - : latest; - return `^${versionToUse}`; -} - export function getPackageJson() { const packageJsonPath = path.resolve('package.json'); if (!fs.existsSync(packageJsonPath)) { @@ -160,14 +130,18 @@ export function codeLog(codeLines: string[], leftPadAmount?: number) { * @param {Object} packageJson The current package.json so we can inspect its contents * @returns {Array} Contains the packages and versions that need to be installed * @example - * const babelDependencies = await getBabelDependencies(npmOptions, packageJson); + * const babelDependencies = await getBabelDependencies(packageManager, npmOptions, packageJson); * // you can then spread the result when using installDependencies * installDependencies(npmOptions, [ * `@storybook/react@${storybookVersion}`, * ...babelDependencies, * ]); */ -export async function getBabelDependencies(npmOptions: NpmOptions, packageJson: PackageJson) { +export async function getBabelDependencies( + packageManager: JsPackageManager, + npmOptions: NpmOptions, + packageJson: PackageJson +) { const dependenciesToAdd = []; let babelLoaderVersion = '^8.0.0-0'; @@ -176,7 +150,7 @@ export async function getBabelDependencies(npmOptions: NpmOptions, packageJson: if (!babelCoreVersion) { if (!packageJson.dependencies['@babel/core'] && !packageJson.devDependencies['@babel/core']) { - const babelCoreInstallVersion = await getVersion(npmOptions, '@babel/core'); + const babelCoreInstallVersion = await packageManager.getVersion(npmOptions, '@babel/core'); dependenciesToAdd.push(`@babel/core@${babelCoreInstallVersion}`); } } else { @@ -192,7 +166,7 @@ export async function getBabelDependencies(npmOptions: NpmOptions, packageJson: } if (!packageJson.dependencies['babel-loader'] && !packageJson.devDependencies['babel-loader']) { - const babelLoaderInstallVersion = await getVersion( + const babelLoaderInstallVersion = await packageManager.getVersion( npmOptions, 'babel-loader', babelLoaderVersion diff --git a/lib/cli/src/js-package-manager/JsPackageManager.ts b/lib/cli/src/js-package-manager/JsPackageManager.ts index 918e5c582908..1165f3676edb 100644 --- a/lib/cli/src/js-package-manager/JsPackageManager.ts +++ b/lib/cli/src/js-package-manager/JsPackageManager.ts @@ -1,10 +1,15 @@ import path from 'path'; import fs from 'fs'; -import { commandLog, getVersion, writePackageJson } from '../helpers'; +import chalk from 'chalk'; +import { gt, satisfies } from '@storybook/semver'; +import { commandLog, writePackageJson } from '../helpers'; import { PackageJson } from '../PackageJson'; import { NpmOptions } from '../NpmOptions'; +import { latestVersion } from '../latest_version'; const logger = console; +// Cannot be `import` as it's not under TS root dir +const { version, devDependencies } = require('../../package.json'); export abstract class JsPackageManager { public abstract initPackageJson(): void; @@ -113,7 +118,7 @@ export abstract class JsPackageManager { ): Promise { return Promise.all( packageNames.map( - async (packageName) => `${packageName}@${await getVersion(npmOptions, packageName)}` + async (packageName) => `${packageName}@${await this.getVersion(npmOptions, packageName)}` ) ); } @@ -126,7 +131,39 @@ export abstract class JsPackageManager { * @param packageNames */ public getVersions(npmOptions: NpmOptions, ...packageNames: string[]): Promise { - return Promise.all(packageNames.map((packageName) => getVersion(npmOptions, packageName))); + return Promise.all(packageNames.map((packageName) => this.getVersion(npmOptions, packageName))); + } + + public async getVersion( + npmOptions: NpmOptions, + packageName: string, + constraint?: string + ): Promise { + let current; + if (packageName === '@storybook/cli') { + current = version; + } else if (/storybook/.test(packageName)) { + current = devDependencies[packageName]; + } + + let latest; + try { + latest = await latestVersion(npmOptions, packageName, constraint); + } catch (e) { + if (current) { + logger.warn(`\n ${chalk.yellow(e.message)}`); + return current; + } + + logger.error(`\n ${chalk.red(e.message)}`); + process.exit(1); + } + + const versionToUse = + current && (!constraint || satisfies(current, constraint)) && gt(current, latest) + ? current + : latest; + return `^${versionToUse}`; } protected abstract runInstall(): { status: number }; From a23e4a0846b6fd662c5525d4cd2a17463cdd258f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABtan=20Maisse?= Date: Sun, 7 Jun 2020 21:20:39 +0200 Subject: [PATCH 12/22] refactor: move `latestVersion` to JsPackageManager and split specific behavior in NPM, Yarn 1 and Yarn 2 classes. --- lib/cli/src/add.ts | 19 ++- lib/cli/src/helpers.ts | 3 +- .../js-package-manager/JsPackageManager.ts | 43 +++++- lib/cli/src/js-package-manager/NPMProxy.ts | 33 ++++ lib/cli/src/js-package-manager/Yarn1Proxy.ts | 30 ++++ lib/cli/src/js-package-manager/Yarn2Proxy.ts | 29 ++++ lib/cli/src/latest_version.ts | 144 ------------------ 7 files changed, 145 insertions(+), 156 deletions(-) delete mode 100644 lib/cli/src/latest_version.ts diff --git a/lib/cli/src/add.ts b/lib/cli/src/add.ts index 01d82738c583..9232a7753edf 100644 --- a/lib/cli/src/add.ts +++ b/lib/cli/src/add.ts @@ -2,29 +2,33 @@ import path from 'path'; import fs from 'fs'; import { sync as spawnSync } from 'cross-spawn'; import { hasYarn } from './has_yarn'; -import { latestVersion } from './latest_version'; import { commandLog, getPackageJson } from './helpers'; import { PackageJson } from './PackageJson'; +import { JsPackageManager, JsPackageManagerFactory } from './js-package-manager'; const logger = console; export const storybookAddonScope = '@storybook/addon-'; const isAddon = async ( + packageManager: JsPackageManager, name: string, npmOptions: { useYarn: boolean; } ) => { try { - await latestVersion(npmOptions, name); + await packageManager.latestVersion(npmOptions, name); return true; } catch (e) { return false; } }; -const isStorybookAddon = async (name: string, npmOptions: { useYarn: boolean }) => - isAddon(`${storybookAddonScope}${name}`, npmOptions); +const isStorybookAddon = async ( + packageManager: JsPackageManager, + name: string, + npmOptions: { useYarn: boolean } +) => isAddon(packageManager, `${storybookAddonScope}${name}`, npmOptions); export const getPackageName = (addonName: string, isOfficialAddon: boolean) => isOfficialAddon ? storybookAddonScope + addonName : addonName; @@ -154,10 +158,13 @@ export async function add( const npmOptions = { useYarn, }; + + const packageManager = JsPackageManagerFactory.getPackageManager(options.useNpm); + const addonCheckDone = commandLog(`Verifying that ${addonName} is an addon`); - const isOfficialAddon = await isStorybookAddon(addonName, npmOptions); + const isOfficialAddon = await isStorybookAddon(packageManager, addonName, npmOptions); if (!isOfficialAddon) { - if (!(await isAddon(addonName, npmOptions))) { + if (!(await isAddon(packageManager, addonName, npmOptions))) { addonCheckDone(`The provided package was not a Storybook addon: ${addonName}.`); return; } diff --git a/lib/cli/src/helpers.ts b/lib/cli/src/helpers.ts index 62d81958aa2d..8af17a88dabf 100644 --- a/lib/cli/src/helpers.ts +++ b/lib/cli/src/helpers.ts @@ -6,7 +6,6 @@ import chalk from 'chalk'; import { satisfies } from '@storybook/semver'; import stripJsonComments from 'strip-json-comments'; -import { latestVersion } from './latest_version'; import { StoryFormat } from './project_types'; import { PackageJson } from './PackageJson'; import { NpmOptions } from './NpmOptions'; @@ -154,7 +153,7 @@ export async function getBabelDependencies( dependenciesToAdd.push(`@babel/core@${babelCoreInstallVersion}`); } } else { - const latestCompatibleBabelVersion = await latestVersion( + const latestCompatibleBabelVersion = await packageManager.latestVersion( npmOptions, 'babel-core', babelCoreVersion diff --git a/lib/cli/src/js-package-manager/JsPackageManager.ts b/lib/cli/src/js-package-manager/JsPackageManager.ts index 1165f3676edb..ffa9898e1656 100644 --- a/lib/cli/src/js-package-manager/JsPackageManager.ts +++ b/lib/cli/src/js-package-manager/JsPackageManager.ts @@ -5,11 +5,10 @@ import { gt, satisfies } from '@storybook/semver'; import { commandLog, writePackageJson } from '../helpers'; import { PackageJson } from '../PackageJson'; import { NpmOptions } from '../NpmOptions'; -import { latestVersion } from '../latest_version'; const logger = console; // Cannot be `import` as it's not under TS root dir -const { version, devDependencies } = require('../../package.json'); +const { storybookCLIVersion, devDependencies } = require('../../package.json'); export abstract class JsPackageManager { public abstract initPackageJson(): void; @@ -141,14 +140,14 @@ export abstract class JsPackageManager { ): Promise { let current; if (packageName === '@storybook/cli') { - current = version; + current = storybookCLIVersion; } else if (/storybook/.test(packageName)) { current = devDependencies[packageName]; } let latest; try { - latest = await latestVersion(npmOptions, packageName, constraint); + latest = await this.latestVersion(npmOptions, packageName, constraint); } catch (e) { if (current) { logger.warn(`\n ${chalk.yellow(e.message)}`); @@ -166,6 +165,30 @@ export abstract class JsPackageManager { return `^${versionToUse}`; } + /** + * Get the latest version of the package available on npmjs.com. + * If constraint is set then it returns a version satisfying it, otherwise the latest version available is returned. + * + * @param npmOptions Object containing a `useYarn: boolean` attribute + * @param packageName Name of the package + * @param constraint Version range to use to constraint the returned version + */ + public async latestVersion( + // @ts-ignore + npmOptions: { useYarn: boolean }, + packageName: string, + constraint?: string + ): Promise { + if (!constraint) { + return this.runGetVersions(packageName, false); + } + + const versions = await this.runGetVersions(packageName, true); + + // Get the latest version satisfying the constraint + return versions.reverse().find((version) => satisfies(version, constraint)); + } + protected abstract runInstall(): { status: number }; protected abstract runAddDeps( @@ -173,6 +196,18 @@ export abstract class JsPackageManager { installAsDevDependencies: boolean ): { status: number }; + /** + * Get the latest or all versions of the input package available on npmjs.com + * + * @param packageName Name of the package + * @param fetchAllVersions Should return + */ + protected abstract runGetVersions( + packageName: string, + fetchAllVersions: T + ): // Use generic and conditional type to force `string[]` if fetchAllVersions is true and `string` if false + Promise; + private static getPackageJson(): PackageJson | false { const packageJsonPath = path.resolve('package.json'); if (!fs.existsSync(packageJsonPath)) { diff --git a/lib/cli/src/js-package-manager/NPMProxy.ts b/lib/cli/src/js-package-manager/NPMProxy.ts index 6ad49230cea9..e8a57f52c86c 100644 --- a/lib/cli/src/js-package-manager/NPMProxy.ts +++ b/lib/cli/src/js-package-manager/NPMProxy.ts @@ -32,4 +32,37 @@ export class NPMProxy extends JsPackageManager { return spawnSync('npm', args, { stdio: 'inherit' }); } + + protected runGetVersions( + packageName: string, + fetchAllVersions: T + ): Promise { + const commandResult = spawnSync( + 'npm', + ['info', packageName, fetchAllVersions ? 'versions' : 'version', '--json'], + { + cwd: process.cwd(), + env: process.env, + stdio: 'pipe', + encoding: 'utf-8', + } + ); + + if (commandResult.status !== 0) { + throw new Error(commandResult.stderr.toString()); + } + + try { + const parsedOutput = JSON.parse(commandResult.stdout.toString()); + + if (parsedOutput.error) { + // FIXME: improve error handling + throw new Error(parsedOutput.error.summary); + } else { + return parsedOutput; + } + } catch (e) { + throw new Error(`Unable to find versions of ${packageName} using yarn`); + } + } } diff --git a/lib/cli/src/js-package-manager/Yarn1Proxy.ts b/lib/cli/src/js-package-manager/Yarn1Proxy.ts index 681e91d6af1a..c39b3f3505f1 100644 --- a/lib/cli/src/js-package-manager/Yarn1Proxy.ts +++ b/lib/cli/src/js-package-manager/Yarn1Proxy.ts @@ -32,4 +32,34 @@ export class Yarn1Proxy extends JsPackageManager { return spawnSync('yarn', args, { stdio: 'inherit' }); } + + protected runGetVersions( + packageName: string, + fetchAllVersions: T + ): Promise { + const commandResult = spawnSync( + 'yarn', + ['info', packageName, fetchAllVersions ? 'versions' : 'version', '--json'], + { + cwd: process.cwd(), + env: process.env, + stdio: 'pipe', + encoding: 'utf-8', + } + ); + + if (commandResult.status !== 0) { + throw new Error(commandResult.stderr.toString()); + } + + try { + const parsedOutput = JSON.parse(commandResult.stdout.toString()); + if (parsedOutput.type === 'inspect') { + return parsedOutput.data; + } + throw new Error(`Unable to find versions of ${packageName} using yarn`); + } catch (e) { + throw new Error(`Unable to find versions of ${packageName} using yarn`); + } + } } diff --git a/lib/cli/src/js-package-manager/Yarn2Proxy.ts b/lib/cli/src/js-package-manager/Yarn2Proxy.ts index 623d74b89eb1..20cccdbfecea 100644 --- a/lib/cli/src/js-package-manager/Yarn2Proxy.ts +++ b/lib/cli/src/js-package-manager/Yarn2Proxy.ts @@ -32,4 +32,33 @@ export class Yarn2Proxy extends JsPackageManager { return spawnSync('yarn', args, { stdio: 'inherit' }); } + + protected runGetVersions( + packageName: string, + fetchAllVersions: T + ): Promise { + const field = fetchAllVersions ? 'versions' : 'version'; + + const commandResult = spawnSync( + 'yarn', + ['npm', 'info', packageName, '--fields', field, '--json'], + { + cwd: process.cwd(), + env: process.env, + stdio: 'pipe', + encoding: 'utf-8', + } + ); + + if (commandResult.status !== 0) { + throw new Error(commandResult.stderr.toString()); + } + + try { + const parsedOutput = JSON.parse(commandResult.stdout.toString()); + return parsedOutput[field]; + } catch (e) { + throw new Error(`Unable to find versions of ${packageName} using yarn 2`); + } + } } diff --git a/lib/cli/src/latest_version.ts b/lib/cli/src/latest_version.ts deleted file mode 100644 index 7015aa68c287..000000000000 --- a/lib/cli/src/latest_version.ts +++ /dev/null @@ -1,144 +0,0 @@ -import { spawn, sync } from 'cross-spawn'; -import { satisfies } from '@storybook/semver'; -import { hasYarn2 } from './has_yarn'; - -/** - * Get the latest version of the package available on npmjs.com. - * If constraint is set then it returns a version satisfying it, otherwise the latest version available is returned. - * - * @param {Object} npmOptions Object containing a `useYarn: boolean` attribute - * @param {string} packageName Name of the package - * @param {Object} constraint Version range to use to constraint the returned version - * @return {Promise} Promise resolved with a version - */ -export async function latestVersion( - npmOptions: { useYarn: boolean }, - packageName: string, - constraint?: any -): Promise { - let versions: string | string[]; - - // TODO: Refactor things to hide the package manager details: - // Create a `PackageManager` interface that expose some functions like `version`, `add` etc - // and then create classes that handle the npm/yarn/yarn2 specific behavior - if (npmOptions.useYarn) { - if (hasYarn2()) { - versions = await spawnVersionsWithYarn2(packageName, constraint); - } else { - versions = await spawnVersionsWithYarn(packageName, constraint); - } - } else { - versions = await spawnVersionsWithNpm(packageName, constraint); - } - - if (!constraint) { - return versions as string; - } - - return (versions as string[]).reverse().find((version) => satisfies(version, constraint)); -} - -/** - * Get latest version(s) of the package available on npmjs.com using NPM - * - * @param {string} packageName Name of the package - * @param {Object} constraint Version range to use to constraint the returned version - * @returns {Promise>} versions Promise resolved with a version or an array of versions - */ -function spawnVersionsWithNpm(packageName: string, constraint: any): Promise { - return new Promise((resolve, reject) => { - const command = spawn( - 'npm', - ['info', packageName, constraint ? 'versions' : 'version', '--json', '--silent'], - { - cwd: process.cwd(), - env: process.env, - stdio: 'pipe', - } - ); - - command.stdout.on('data', (data) => { - try { - const info = JSON.parse(data); - if (info.error) { - reject(new Error(info.error.summary)); - } else { - resolve(info); - } - } catch (e) { - reject(new Error(`Unable to find versions of ${packageName} using npm`)); - } - }); - }); -} - -/** - * Get latest version(s) of the package available on npmjs.com using Yarn - * - * @param {string} packageName Name of the package - * @param {Object} constraint Version range to use to constraint the returned version - * @returns {Promise>} versions Promise resolved with a version or an array of versions - */ -function spawnVersionsWithYarn(packageName: string, constraint: any): Promise { - return new Promise((resolve, reject) => { - const command = spawn( - 'yarn', - ['info', packageName, constraint ? 'versions' : 'version', '--json', '--silent'], - { - cwd: process.cwd(), - env: process.env, - stdio: 'pipe', - } - ); - - command.stdout.on('data', (data) => { - try { - const info = JSON.parse(data); - if (info.type === 'inspect') { - resolve(info.data); - } - } catch (e) { - reject(new Error(`Unable to find versions of ${packageName} using yarn`)); - } - }); - - command.stderr.on('data', (data) => { - const info = JSON.parse(data); - if (info.type === 'error') { - reject(new Error(info.data)); - } - }); - }); -} - -/** - * Get latest version(s) of the package available on npmjs.com using Yarn 2 a.k.a Berry - * - * @param {string} packageName Name of the package - * @param {Object} constraint Version range to use to constraint the returned version - * @returns {Promise>} versions Promise resolved with a version or an array of versions - */ -async function spawnVersionsWithYarn2( - packageName: string, - constraint: any -): Promise { - const field = constraint ? 'versions' : 'version'; - - const commandResult = sync('yarn', ['npm', 'info', packageName, '--fields', field, '--json'], { - cwd: process.cwd(), - env: process.env, - stdio: 'pipe', - encoding: 'utf-8', - }); - - if (commandResult.status !== 0) { - throw new Error(commandResult.stderr.toString()); - } - - try { - const parsedOutput = JSON.parse(commandResult.stdout.toString()); - return parsedOutput[field]; - } catch (e) { - throw new Error(`Unable to find versions of ${packageName} using yarn 2`); - } -} From 2912bcbefeaa5c002a67340f724112e5acfc90d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABtan=20Maisse?= Date: Sun, 7 Jun 2020 21:30:03 +0200 Subject: [PATCH 13/22] refactor: remove unneeded params and variables All this variables were used to check if user was running Yarn and do this accordingly. Now we use the factory to get the "right" version of JsPackageManager instance so there is no need to worry anywhere about that. --- lib/cli/src/NpmOptions.ts | 1 - lib/cli/src/add.ts | 21 ++++--------- lib/cli/src/generators/ANGULAR/index.ts | 4 +-- lib/cli/src/generators/AURELIA/index.ts | 4 +-- lib/cli/src/generators/EMBER/index.ts | 3 +- lib/cli/src/generators/HTML/index.ts | 4 +-- lib/cli/src/generators/MARIONETTE/index.ts | 4 +-- lib/cli/src/generators/MARKO/index.ts | 3 +- lib/cli/src/generators/METEOR/index.ts | 3 +- lib/cli/src/generators/MITHRIL/index.ts | 3 +- lib/cli/src/generators/PREACT/index.ts | 3 +- lib/cli/src/generators/RAX/index.ts | 3 +- lib/cli/src/generators/REACT/index.ts | 4 +-- lib/cli/src/generators/REACT_NATIVE/index.ts | 3 +- lib/cli/src/generators/REACT_SCRIPTS/index.ts | 4 +-- lib/cli/src/generators/RIOT/index.ts | 3 +- lib/cli/src/generators/SFC_VUE/index.ts | 4 +-- lib/cli/src/generators/SVELTE/index.ts | 3 +- .../UPDATE_PACKAGE_ORGANIZATIONS/index.ts | 10 +++---- lib/cli/src/generators/VUE/index.ts | 6 ++-- .../src/generators/WEB-COMPONENTS/index.ts | 4 +-- lib/cli/src/generators/WEBPACK_REACT/index.ts | 4 +-- lib/cli/src/has_yarn.ts | 10 ------- lib/cli/src/helpers.ts | 7 +---- lib/cli/src/initiate.ts | 2 -- .../js-package-manager/JsPackageManager.ts | 30 +++++-------------- 26 files changed, 48 insertions(+), 102 deletions(-) diff --git a/lib/cli/src/NpmOptions.ts b/lib/cli/src/NpmOptions.ts index f397f5f2f7a6..1f2114144623 100644 --- a/lib/cli/src/NpmOptions.ts +++ b/lib/cli/src/NpmOptions.ts @@ -1,5 +1,4 @@ export type NpmOptions = { - useYarn: boolean; skipInstall?: boolean; installAsDevDependencies?: boolean; }; diff --git a/lib/cli/src/add.ts b/lib/cli/src/add.ts index 9232a7753edf..a1b3ac47aee5 100644 --- a/lib/cli/src/add.ts +++ b/lib/cli/src/add.ts @@ -9,26 +9,17 @@ import { JsPackageManager, JsPackageManagerFactory } from './js-package-manager' const logger = console; export const storybookAddonScope = '@storybook/addon-'; -const isAddon = async ( - packageManager: JsPackageManager, - name: string, - npmOptions: { - useYarn: boolean; - } -) => { +const isAddon = async (packageManager: JsPackageManager, name: string) => { try { - await packageManager.latestVersion(npmOptions, name); + await packageManager.latestVersion(name); return true; } catch (e) { return false; } }; -const isStorybookAddon = async ( - packageManager: JsPackageManager, - name: string, - npmOptions: { useYarn: boolean } -) => isAddon(packageManager, `${storybookAddonScope}${name}`, npmOptions); +const isStorybookAddon = async (packageManager: JsPackageManager, name: string) => + isAddon(packageManager, `${storybookAddonScope}${name}`); export const getPackageName = (addonName: string, isOfficialAddon: boolean) => isOfficialAddon ? storybookAddonScope + addonName : addonName; @@ -162,9 +153,9 @@ export async function add( const packageManager = JsPackageManagerFactory.getPackageManager(options.useNpm); const addonCheckDone = commandLog(`Verifying that ${addonName} is an addon`); - const isOfficialAddon = await isStorybookAddon(packageManager, addonName, npmOptions); + const isOfficialAddon = await isStorybookAddon(packageManager, addonName); if (!isOfficialAddon) { - if (!(await isAddon(packageManager, addonName, npmOptions))) { + if (!(await isAddon(packageManager, addonName))) { addonCheckDone(`The provided package was not a Storybook addon: ${addonName}.`); return; } diff --git a/lib/cli/src/generators/ANGULAR/index.ts b/lib/cli/src/generators/ANGULAR/index.ts index 032180767193..608101c05817 100644 --- a/lib/cli/src/generators/ANGULAR/index.ts +++ b/lib/cli/src/generators/ANGULAR/index.ts @@ -32,7 +32,7 @@ async function addDependencies( packages.push('@storybook/addon-docs'); } - const versionedPackages = await packageManager.getVersionedPackages(npmOptions, ...packages); + const versionedPackages = await packageManager.getVersionedPackages(...packages); const packageJson = packageManager.retrievePackageJson(); @@ -45,7 +45,7 @@ async function addDependencies( writePackageJson(packageJson); - const babelDependencies = await getBabelDependencies(packageManager, npmOptions, packageJson); + const babelDependencies = await getBabelDependencies(packageManager, packageJson); packageManager.addDependencies({ ...npmOptions, packageJson }, [ ...versionedPackages, diff --git a/lib/cli/src/generators/AURELIA/index.ts b/lib/cli/src/generators/AURELIA/index.ts index 76aaa17f5f8d..76afc978e2d5 100644 --- a/lib/cli/src/generators/AURELIA/index.ts +++ b/lib/cli/src/generators/AURELIA/index.ts @@ -46,7 +46,7 @@ const generator: Generator = async ( packages.push('@storybook/addon-docs'); } - const versionedPackages = await packageManager.getVersionedPackages(npmOptions, ...packages); + const versionedPackages = await packageManager.getVersionedPackages(...packages); const packageJson = packageManager.retrievePackageJson(); packageJson.dependencies = packageJson.dependencies || {}; packageJson.devDependencies = packageJson.devDependencies || {}; @@ -55,7 +55,7 @@ const generator: Generator = async ( packageJson.scripts['build-storybook'] = 'build-storybook'; writePackageJson(packageJson); addStorybookExcludeGlobToTsConfig(); - const babelDependencies = await getBabelDependencies(packageManager, npmOptions, packageJson); + const babelDependencies = await getBabelDependencies(packageManager, packageJson); packageManager.addDependencies({ ...npmOptions, packageJson }, [ ...versionedPackages, ...babelDependencies, diff --git a/lib/cli/src/generators/EMBER/index.ts b/lib/cli/src/generators/EMBER/index.ts index 4ce0b1521004..c698d21394b2 100644 --- a/lib/cli/src/generators/EMBER/index.ts +++ b/lib/cli/src/generators/EMBER/index.ts @@ -10,7 +10,6 @@ const generator: Generator = async (packageManager, npmOptions, { storyFormat }) actionsVersion, addonsVersion, ] = await packageManager.getVersions( - npmOptions, '@storybook/ember', // babel-plugin-ember-modules-api-polyfill is a peerDep of @storybook/ember 'babel-plugin-ember-modules-api-polyfill', @@ -38,7 +37,7 @@ const generator: Generator = async (packageManager, npmOptions, { storyFormat }) writePackageJson(packageJson); - const babelDependencies = await getBabelDependencies(packageManager, npmOptions, packageJson); + const babelDependencies = await getBabelDependencies(packageManager, packageJson); packageManager.addDependencies({ ...npmOptions, packageJson }, [ `@storybook/ember@${storybookVersion}`, diff --git a/lib/cli/src/generators/HTML/index.ts b/lib/cli/src/generators/HTML/index.ts index 38b304ed5b9d..4f502dfcde20 100755 --- a/lib/cli/src/generators/HTML/index.ts +++ b/lib/cli/src/generators/HTML/index.ts @@ -5,7 +5,7 @@ import { Generator } from '../Generator'; const generator: Generator = async (packageManager, npmOptions, { storyFormat }) => { const packages = ['@storybook/html', '@storybook/addon-actions', '@storybook/addon-links']; - const versionedPackages = await packageManager.getVersionedPackages(npmOptions, ...packages); + const versionedPackages = await packageManager.getVersionedPackages(...packages); if (storyFormat === StoryFormat.MDX) { packages.push('@storybook/addon-docs'); } @@ -23,7 +23,7 @@ const generator: Generator = async (packageManager, npmOptions, { storyFormat }) writePackageJson(packageJson); - const babelDependencies = await getBabelDependencies(packageManager, npmOptions, packageJson); + const babelDependencies = await getBabelDependencies(packageManager, packageJson); packageManager.addDependencies({ ...npmOptions, packageJson }, [ ...versionedPackages, diff --git a/lib/cli/src/generators/MARIONETTE/index.ts b/lib/cli/src/generators/MARIONETTE/index.ts index a2ea776f3a67..71fc48b1095a 100644 --- a/lib/cli/src/generators/MARIONETTE/index.ts +++ b/lib/cli/src/generators/MARIONETTE/index.ts @@ -4,7 +4,7 @@ import { writePackageJson, getBabelDependencies } from '../../helpers'; import { Generator } from '../Generator'; const generator: Generator = async (packageManager, npmOptions) => { - const storybookVersion = await packageManager.getVersion(npmOptions, '@storybook/marionette'); + const storybookVersion = await packageManager.getVersion('@storybook/marionette'); fse.copySync(path.resolve(__dirname, 'template/'), '.', { overwrite: true }); const packageJson = packageManager.retrievePackageJson(); @@ -18,7 +18,7 @@ const generator: Generator = async (packageManager, npmOptions) => { writePackageJson(packageJson); - const babelDependencies = await getBabelDependencies(packageManager, npmOptions, packageJson); + const babelDependencies = await getBabelDependencies(packageManager, packageJson); packageManager.addDependencies({ ...npmOptions, packageJson }, [ `@storybook/marionette@${storybookVersion}`, diff --git a/lib/cli/src/generators/MARKO/index.ts b/lib/cli/src/generators/MARKO/index.ts index 3fd43a39eb01..584675033a2f 100644 --- a/lib/cli/src/generators/MARKO/index.ts +++ b/lib/cli/src/generators/MARKO/index.ts @@ -7,7 +7,6 @@ const generator: Generator = async (packageManager, npmOptions, { storyFormat }) addonActionVersion, addonKnobsVersion, ] = await packageManager.getVersions( - npmOptions, '@storybook/marko', '@storybook/addon-actions', '@storybook/addon-knobs' @@ -26,7 +25,7 @@ const generator: Generator = async (packageManager, npmOptions, { storyFormat }) writePackageJson(packageJson); - const babelDependencies = await getBabelDependencies(packageManager, npmOptions, packageJson); + const babelDependencies = await getBabelDependencies(packageManager, packageJson); packageManager.addDependencies({ ...npmOptions, packageJson }, [ `@storybook/marko@${storybookVersion}`, diff --git a/lib/cli/src/generators/METEOR/index.ts b/lib/cli/src/generators/METEOR/index.ts index a8aab312975b..18bffe046b04 100644 --- a/lib/cli/src/generators/METEOR/index.ts +++ b/lib/cli/src/generators/METEOR/index.ts @@ -15,7 +15,6 @@ const generator: Generator = async (packageManager, npmOptions, { storyFormat }) presetEnvVersion, presetReactVersion, ] = await packageManager.getVersions( - npmOptions, '@storybook/react', '@storybook/addon-actions', '@storybook/addon-links', @@ -68,7 +67,7 @@ const generator: Generator = async (packageManager, npmOptions, { storyFormat }) writePackageJson(packageJson); - const babelDependencies = await getBabelDependencies(packageManager, npmOptions, packageJson); + const babelDependencies = await getBabelDependencies(packageManager, packageJson); // add react packages. const dependencies = []; diff --git a/lib/cli/src/generators/MITHRIL/index.ts b/lib/cli/src/generators/MITHRIL/index.ts index eab1d199b97d..edb5c89e18e7 100644 --- a/lib/cli/src/generators/MITHRIL/index.ts +++ b/lib/cli/src/generators/MITHRIL/index.ts @@ -9,7 +9,6 @@ const generator: Generator = async (packageManager, npmOptions, { storyFormat }) knobsVersion, addonsVersion, ] = await packageManager.getVersions( - npmOptions, '@storybook/mithril', '@storybook/addon-actions', '@storybook/addon-links', @@ -30,7 +29,7 @@ const generator: Generator = async (packageManager, npmOptions, { storyFormat }) writePackageJson(packageJson); - const babelDependencies = await getBabelDependencies(packageManager, npmOptions, packageJson); + const babelDependencies = await getBabelDependencies(packageManager, packageJson); packageManager.addDependencies({ ...npmOptions, packageJson }, [ `@storybook/mithril@${storybookVersion}`, diff --git a/lib/cli/src/generators/PREACT/index.ts b/lib/cli/src/generators/PREACT/index.ts index 21dbd67c47f1..2ec2c956ed8c 100644 --- a/lib/cli/src/generators/PREACT/index.ts +++ b/lib/cli/src/generators/PREACT/index.ts @@ -8,7 +8,6 @@ const generator: Generator = async (packageManager, npmOptions, { storyFormat }) linksVersion, addonsVersion, ] = await packageManager.getVersions( - npmOptions, '@storybook/preact', '@storybook/addon-actions', '@storybook/addon-links', @@ -28,7 +27,7 @@ const generator: Generator = async (packageManager, npmOptions, { storyFormat }) writePackageJson(packageJson); - const babelDependencies = await getBabelDependencies(packageManager, npmOptions, packageJson); + const babelDependencies = await getBabelDependencies(packageManager, packageJson); packageManager.addDependencies({ ...npmOptions, packageJson }, [ `@storybook/preact@${storybookVersion}`, diff --git a/lib/cli/src/generators/RAX/index.ts b/lib/cli/src/generators/RAX/index.ts index 44056461ee34..8eabdeaf5d91 100644 --- a/lib/cli/src/generators/RAX/index.ts +++ b/lib/cli/src/generators/RAX/index.ts @@ -9,7 +9,6 @@ const generator: Generator = async (packageManager, npmOptions, { storyFormat }) addonsVersion, latestRaxVersion, ] = await packageManager.getVersions( - npmOptions, '@storybook/rax', '@storybook/addon-actions', '@storybook/addon-links', @@ -41,7 +40,7 @@ const generator: Generator = async (packageManager, npmOptions, { storyFormat }) writePackageJson(packageJson); - const babelDependencies = await getBabelDependencies(packageManager, npmOptions, packageJson); + const babelDependencies = await getBabelDependencies(packageManager, packageJson); packageManager.addDependencies({ ...npmOptions, packageJson }, [ `@storybook/rax@${storybookVersion}`, diff --git a/lib/cli/src/generators/REACT/index.ts b/lib/cli/src/generators/REACT/index.ts index 3874aff4eab8..8dd954481fe6 100644 --- a/lib/cli/src/generators/REACT/index.ts +++ b/lib/cli/src/generators/REACT/index.ts @@ -13,7 +13,7 @@ const generator: Generator = async (packageManager, npmOptions, { storyFormat }) packages.push('@storybook/addon-docs'); } - const versionedPackages = await packageManager.getVersionedPackages(npmOptions, ...packages); + const versionedPackages = await packageManager.getVersionedPackages(...packages); copyTemplate(__dirname, storyFormat); @@ -28,7 +28,7 @@ const generator: Generator = async (packageManager, npmOptions, { storyFormat }) writePackageJson(packageJson); - const babelDependencies = await getBabelDependencies(packageManager, npmOptions, packageJson); + const babelDependencies = await getBabelDependencies(packageManager, packageJson); packageManager.addDependencies({ ...npmOptions, packageJson }, [ ...versionedPackages, diff --git a/lib/cli/src/generators/REACT_NATIVE/index.ts b/lib/cli/src/generators/REACT_NATIVE/index.ts index c695f0a0bbaf..4938527b8e9b 100644 --- a/lib/cli/src/generators/REACT_NATIVE/index.ts +++ b/lib/cli/src/generators/REACT_NATIVE/index.ts @@ -17,7 +17,6 @@ export default async ( actionsVersion, linksVersion, ] = await packageManager.getVersions( - npmOptions, '@storybook/react-native', '@storybook/addons', '@storybook/addon-actions', @@ -74,7 +73,7 @@ export default async ( writePackageJson(packageJson); - const babelDependencies = await getBabelDependencies(packageManager, npmOptions, packageJson); + const babelDependencies = await getBabelDependencies(packageManager, packageJson); packageManager.addDependencies({ ...npmOptions, packageJson }, [ ...devDependencies, diff --git a/lib/cli/src/generators/REACT_SCRIPTS/index.ts b/lib/cli/src/generators/REACT_SCRIPTS/index.ts index 5a65d5b13ad9..67fadf36e82c 100644 --- a/lib/cli/src/generators/REACT_SCRIPTS/index.ts +++ b/lib/cli/src/generators/REACT_SCRIPTS/index.ts @@ -17,7 +17,7 @@ const generator: Generator = async (packageManager, npmOptions, { storyFormat }) packages.push('@storybook/addon-docs'); } - const versionedPackages = await packageManager.getVersionedPackages(npmOptions, ...packages); + const versionedPackages = await packageManager.getVersionedPackages(...packages); copyTemplate(__dirname, storyFormat); @@ -38,7 +38,7 @@ const generator: Generator = async (packageManager, npmOptions, { storyFormat }) writePackageJson(packageJson); - const babelDependencies = await getBabelDependencies(packageManager, npmOptions, packageJson); + const babelDependencies = await getBabelDependencies(packageManager, packageJson); packageManager.addDependencies({ ...npmOptions, packageJson }, [ ...versionedPackages, diff --git a/lib/cli/src/generators/RIOT/index.ts b/lib/cli/src/generators/RIOT/index.ts index b6e5107b74cc..262298956169 100644 --- a/lib/cli/src/generators/RIOT/index.ts +++ b/lib/cli/src/generators/RIOT/index.ts @@ -9,7 +9,6 @@ const generator: Generator = async (packageManager, npmOptions, { storyFormat }) addonsVersion, tagLoaderVersion, ] = await packageManager.getVersions( - npmOptions, '@storybook/riot', '@storybook/addon-actions', '@storybook/addon-links', @@ -42,7 +41,7 @@ const generator: Generator = async (packageManager, npmOptions, { storyFormat }) writePackageJson(packageJson); - const babelDependencies = await getBabelDependencies(packageManager, npmOptions, packageJson); + const babelDependencies = await getBabelDependencies(packageManager, packageJson); packageManager.addDependencies({ ...npmOptions, packageJson }, [ ...dependencies, diff --git a/lib/cli/src/generators/SFC_VUE/index.ts b/lib/cli/src/generators/SFC_VUE/index.ts index b6b8985bdf10..90b109fbe95a 100644 --- a/lib/cli/src/generators/SFC_VUE/index.ts +++ b/lib/cli/src/generators/SFC_VUE/index.ts @@ -12,7 +12,7 @@ const generator: Generator = async (packageManager, npmOptions, { storyFormat }) if (storyFormat === StoryFormat.MDX) { packages.push('@storybook/addon-docs'); } - const versionedPackages = await packageManager.getVersionedPackages(npmOptions, ...packages); + const versionedPackages = await packageManager.getVersionedPackages(...packages); copyTemplate(__dirname, storyFormat); @@ -27,7 +27,7 @@ const generator: Generator = async (packageManager, npmOptions, { storyFormat }) writePackageJson(packageJson); - const babelDependencies = await getBabelDependencies(packageManager, npmOptions, packageJson); + const babelDependencies = await getBabelDependencies(packageManager, packageJson); packageManager.addDependencies({ ...npmOptions, packageJson }, [ ...versionedPackages, diff --git a/lib/cli/src/generators/SVELTE/index.ts b/lib/cli/src/generators/SVELTE/index.ts index bb340b260d74..3b2accf677b6 100644 --- a/lib/cli/src/generators/SVELTE/index.ts +++ b/lib/cli/src/generators/SVELTE/index.ts @@ -10,7 +10,6 @@ const generator: Generator = async (packageManager, npmOptions, { storyFormat }) svelte, svelteLoader, ] = await packageManager.getVersions( - npmOptions, '@storybook/svelte', '@storybook/addon-actions', '@storybook/addon-links', @@ -32,7 +31,7 @@ const generator: Generator = async (packageManager, npmOptions, { storyFormat }) writePackageJson(packageJson); - const babelDependencies = await getBabelDependencies(packageManager, npmOptions, packageJson); + const babelDependencies = await getBabelDependencies(packageManager, packageJson); packageManager.addDependencies({ ...npmOptions, packageJson }, [ `@storybook/svelte@${storybookVersion}`, diff --git a/lib/cli/src/generators/UPDATE_PACKAGE_ORGANIZATIONS/index.ts b/lib/cli/src/generators/UPDATE_PACKAGE_ORGANIZATIONS/index.ts index 209fd8835bd1..7ee89a194274 100644 --- a/lib/cli/src/generators/UPDATE_PACKAGE_ORGANIZATIONS/index.ts +++ b/lib/cli/src/generators/UPDATE_PACKAGE_ORGANIZATIONS/index.ts @@ -11,12 +11,11 @@ async function updatePackage( packageManager: JsPackageManager, devDependencies: PackageJson['devDependencies'], oldName: string, - newName: string, - npmOptions: NpmOptions + newName: string ) { if (devDependencies[oldName]) { delete devDependencies[oldName]; - devDependencies[newName] = await packageManager.getVersion(npmOptions, newName); + devDependencies[newName] = await packageManager.getVersion(newName); } } @@ -25,7 +24,6 @@ async function updatePackageJson(packageManager: JsPackageManager, npmOptions: N const { devDependencies } = packageJson; const [actionsVersion, linksVersion] = await packageManager.getVersions( - npmOptions, '@storybook/addon-actions', '@storybook/addon-links' ); @@ -36,7 +34,7 @@ async function updatePackageJson(packageManager: JsPackageManager, npmOptions: N await Promise.all( Object.keys(packageNames).map((oldName) => { const newName = packageNames[oldName]; - return updatePackage(packageManager, devDependencies, oldName, newName, npmOptions); + return updatePackage(packageManager, devDependencies, oldName, newName); }) ); @@ -46,7 +44,7 @@ async function updatePackageJson(packageManager: JsPackageManager, npmOptions: N writePackageJson(packageJson); - const babelDependencies = await getBabelDependencies(packageManager, npmOptions, packageJson); + const babelDependencies = await getBabelDependencies(packageManager, packageJson); if (babelDependencies.length > 0) { packageManager.addDependencies({ ...npmOptions, packageJson }, babelDependencies); diff --git a/lib/cli/src/generators/VUE/index.ts b/lib/cli/src/generators/VUE/index.ts index c6de37a9dddf..86899a4fe064 100644 --- a/lib/cli/src/generators/VUE/index.ts +++ b/lib/cli/src/generators/VUE/index.ts @@ -18,7 +18,7 @@ const generator: Generator = async (packageManager, npmOptions, { storyFormat }) if (storyFormat === StoryFormat.MDX) { packages.push('@storybook/addon-docs'); } - const versionedPackages = await packageManager.getVersionedPackages(npmOptions, ...packages); + const versionedPackages = await packageManager.getVersionedPackages(...packages); copyTemplate(__dirname, storyFormat); @@ -37,7 +37,7 @@ const generator: Generator = async (packageManager, npmOptions, { storyFormat }) addToDevDependenciesIfNotPresent( packageJson, '@babel/core', - await packageManager.getVersion(npmOptions, '@babel/core') + await packageManager.getVersion('@babel/core') ); } @@ -47,7 +47,7 @@ const generator: Generator = async (packageManager, npmOptions, { storyFormat }) writePackageJson(packageJson); - const babelDependencies = await getBabelDependencies(packageManager, npmOptions, packageJson); + const babelDependencies = await getBabelDependencies(packageManager, packageJson); packageManager.addDependencies({ ...npmOptions, packageJson }, [ ...versionedPackages, ...babelDependencies, diff --git a/lib/cli/src/generators/WEB-COMPONENTS/index.ts b/lib/cli/src/generators/WEB-COMPONENTS/index.ts index ec44d1b22b7a..721d88e7522f 100755 --- a/lib/cli/src/generators/WEB-COMPONENTS/index.ts +++ b/lib/cli/src/generators/WEB-COMPONENTS/index.ts @@ -12,7 +12,7 @@ const generator: Generator = async (packageManager, npmOptions, { storyFormat }) 'lit-html', ]; - const versionedPackages = await packageManager.getVersionedPackages(npmOptions, ...packages); + const versionedPackages = await packageManager.getVersionedPackages(...packages); fse.copySync(path.resolve(__dirname, 'template/'), '.', { overwrite: true }); @@ -31,7 +31,7 @@ const generator: Generator = async (packageManager, npmOptions, { storyFormat }) writePackageJson(packageJson); - const babelDependencies = await getBabelDependencies(packageManager, npmOptions, packageJson); + const babelDependencies = await getBabelDependencies(packageManager, packageJson); packageManager.addDependencies({ ...npmOptions, packageJson }, [ ...versionedPackages, diff --git a/lib/cli/src/generators/WEBPACK_REACT/index.ts b/lib/cli/src/generators/WEBPACK_REACT/index.ts index c29d4b5f53bb..433015afdd34 100644 --- a/lib/cli/src/generators/WEBPACK_REACT/index.ts +++ b/lib/cli/src/generators/WEBPACK_REACT/index.ts @@ -12,7 +12,7 @@ const generator: Generator = async (packageManager, npmOptions, { storyFormat }) if (storyFormat === StoryFormat.MDX) { packages.push('@storybook/addon-docs'); } - const versionedPackages = await packageManager.getVersionedPackages(npmOptions, ...packages); + const versionedPackages = await packageManager.getVersionedPackages(...packages); copyTemplate(__dirname, storyFormat); @@ -27,7 +27,7 @@ const generator: Generator = async (packageManager, npmOptions, { storyFormat }) writePackageJson(packageJson); - const babelDependencies = await getBabelDependencies(packageManager, npmOptions, packageJson); + const babelDependencies = await getBabelDependencies(packageManager, packageJson); packageManager.addDependencies({ ...npmOptions, packageJson }, [ ...versionedPackages, diff --git a/lib/cli/src/has_yarn.ts b/lib/cli/src/has_yarn.ts index b427eb1ee9d3..c58706cb101f 100644 --- a/lib/cli/src/has_yarn.ts +++ b/lib/cli/src/has_yarn.ts @@ -14,13 +14,3 @@ export function hasYarn() { } return false; } - -export function hasYarn2() { - const yarnVersion = sync('yarn', ['--version']) - // @ts-ignore - .output.toString('utf8') - .replace(/,/g, '') - .replace(/"/g, ''); - - return !/^1\.+/.test(yarnVersion); -} diff --git a/lib/cli/src/helpers.ts b/lib/cli/src/helpers.ts index 8af17a88dabf..862dd9adf410 100644 --- a/lib/cli/src/helpers.ts +++ b/lib/cli/src/helpers.ts @@ -8,7 +8,6 @@ import stripJsonComments from 'strip-json-comments'; import { StoryFormat } from './project_types'; import { PackageJson } from './PackageJson'; -import { NpmOptions } from './NpmOptions'; import { JsPackageManager } from './js-package-manager'; const logger = console; @@ -125,7 +124,6 @@ export function codeLog(codeLines: string[], leftPadAmount?: number) { /** * Detect if any babel dependencies need to be added to the project - * @param {Object} npmOptions Passed along to `latestVersion` and `getVersion` * @param {Object} packageJson The current package.json so we can inspect its contents * @returns {Array} Contains the packages and versions that need to be installed * @example @@ -138,7 +136,6 @@ export function codeLog(codeLines: string[], leftPadAmount?: number) { */ export async function getBabelDependencies( packageManager: JsPackageManager, - npmOptions: NpmOptions, packageJson: PackageJson ) { const dependenciesToAdd = []; @@ -149,12 +146,11 @@ export async function getBabelDependencies( if (!babelCoreVersion) { if (!packageJson.dependencies['@babel/core'] && !packageJson.devDependencies['@babel/core']) { - const babelCoreInstallVersion = await packageManager.getVersion(npmOptions, '@babel/core'); + const babelCoreInstallVersion = await packageManager.getVersion('@babel/core'); dependenciesToAdd.push(`@babel/core@${babelCoreInstallVersion}`); } } else { const latestCompatibleBabelVersion = await packageManager.latestVersion( - npmOptions, 'babel-core', babelCoreVersion ); @@ -166,7 +162,6 @@ export async function getBabelDependencies( if (!packageJson.dependencies['babel-loader'] && !packageJson.devDependencies['babel-loader']) { const babelLoaderInstallVersion = await packageManager.getVersion( - npmOptions, 'babel-loader', babelLoaderVersion ); diff --git a/lib/cli/src/initiate.ts b/lib/cli/src/initiate.ts index 694049ae0761..4ddc76d5fa35 100644 --- a/lib/cli/src/initiate.ts +++ b/lib/cli/src/initiate.ts @@ -2,7 +2,6 @@ import { UpdateNotifier, IPackage } from 'update-notifier'; import chalk from 'chalk'; import inquirer from 'inquirer'; import { detect, isStorybookInstalled, detectLanguage } from './detect'; -import { hasYarn } from './has_yarn'; import { installableProjectTypes, ProjectType, @@ -50,7 +49,6 @@ const installStorybook = (projectType: ProjectType, options: CommandOptions): Pr const packageManager = JsPackageManagerFactory.getPackageManager(options.useNpm); const npmOptions: NpmOptions = { - useYarn: Boolean(options.useNpm !== true) && hasYarn(), installAsDevDependencies: true, skipInstall: options.skipInstall, }; diff --git a/lib/cli/src/js-package-manager/JsPackageManager.ts b/lib/cli/src/js-package-manager/JsPackageManager.ts index ffa9898e1656..8d0f51032938 100644 --- a/lib/cli/src/js-package-manager/JsPackageManager.ts +++ b/lib/cli/src/js-package-manager/JsPackageManager.ts @@ -4,7 +4,6 @@ import chalk from 'chalk'; import { gt, satisfies } from '@storybook/semver'; import { commandLog, writePackageJson } from '../helpers'; import { PackageJson } from '../PackageJson'; -import { NpmOptions } from '../NpmOptions'; const logger = console; // Cannot be `import` as it's not under TS root dir @@ -108,16 +107,12 @@ export abstract class JsPackageManager { /** * Return an array of strings matching following format: `@` * - * @param npmOptions * @param packageNames */ - public getVersionedPackages( - npmOptions: NpmOptions, - ...packageNames: string[] - ): Promise { + public getVersionedPackages(...packageNames: string[]): Promise { return Promise.all( packageNames.map( - async (packageName) => `${packageName}@${await this.getVersion(npmOptions, packageName)}` + async (packageName) => `${packageName}@${await this.getVersion(packageName)}` ) ); } @@ -126,18 +121,13 @@ export abstract class JsPackageManager { * Return an array of string standing for the latest version of the input packages. * To be able to identify which version goes with which package the order of the input array is keep. * - * @param npmOptions * @param packageNames */ - public getVersions(npmOptions: NpmOptions, ...packageNames: string[]): Promise { - return Promise.all(packageNames.map((packageName) => this.getVersion(npmOptions, packageName))); + public getVersions(...packageNames: string[]): Promise { + return Promise.all(packageNames.map((packageName) => this.getVersion(packageName))); } - public async getVersion( - npmOptions: NpmOptions, - packageName: string, - constraint?: string - ): Promise { + public async getVersion(packageName: string, constraint?: string): Promise { let current; if (packageName === '@storybook/cli') { current = storybookCLIVersion; @@ -147,7 +137,7 @@ export abstract class JsPackageManager { let latest; try { - latest = await this.latestVersion(npmOptions, packageName, constraint); + latest = await this.latestVersion(packageName, constraint); } catch (e) { if (current) { logger.warn(`\n ${chalk.yellow(e.message)}`); @@ -169,16 +159,10 @@ export abstract class JsPackageManager { * Get the latest version of the package available on npmjs.com. * If constraint is set then it returns a version satisfying it, otherwise the latest version available is returned. * - * @param npmOptions Object containing a `useYarn: boolean` attribute * @param packageName Name of the package * @param constraint Version range to use to constraint the returned version */ - public async latestVersion( - // @ts-ignore - npmOptions: { useYarn: boolean }, - packageName: string, - constraint?: string - ): Promise { + public async latestVersion(packageName: string, constraint?: string): Promise { if (!constraint) { return this.runGetVersions(packageName, false); } From d4000030c3e167515fd9c50a483c47fb3619f1c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABtan=20Maisse?= Date: Sun, 7 Jun 2020 21:35:51 +0200 Subject: [PATCH 14/22] refactor: remove usage of `has_yarn` --- lib/cli/src/add.ts | 25 +++++-------------- lib/cli/src/has_yarn.ts | 16 ------------ lib/cli/src/helpers.test.ts | 4 --- .../js-package-manager/JsPackageManager.ts | 2 +- 4 files changed, 7 insertions(+), 40 deletions(-) delete mode 100644 lib/cli/src/has_yarn.ts diff --git a/lib/cli/src/add.ts b/lib/cli/src/add.ts index a1b3ac47aee5..c88b6f4f6136 100644 --- a/lib/cli/src/add.ts +++ b/lib/cli/src/add.ts @@ -1,7 +1,6 @@ import path from 'path'; import fs from 'fs'; import { sync as spawnSync } from 'cross-spawn'; -import { hasYarn } from './has_yarn'; import { commandLog, getPackageJson } from './helpers'; import { PackageJson } from './PackageJson'; import { JsPackageManager, JsPackageManagerFactory } from './js-package-manager'; @@ -46,29 +45,22 @@ export const getPackageArg = ( }; const installAddon = ( + packageManager: JsPackageManager, addonName: string, - npmOptions: { useYarn: boolean }, isOfficialAddon: boolean ) => { const prepareDone = commandLog(`Preparing to install the ${addonName} Storybook addon`); prepareDone(); logger.log(); - let result; const packageArg = getPackageArg(addonName, isOfficialAddon, getPackageJson()); - if (npmOptions.useYarn) { - result = spawnSync('yarn', ['add', packageArg, '--dev'], { - stdio: 'inherit', - }); - } else { - result = spawnSync('npm', ['install', packageArg, '--save-dev'], { - stdio: 'inherit', - }); - } logger.log(); const installDone = commandLog(`Installing the ${addonName} Storybook addon`); - if (result.status !== 0) { + + try { + packageManager.addDependencies({}, [packageArg]); + } catch (e) { installDone( `Something went wrong installing the addon: "${getPackageName(addonName, isOfficialAddon)}"` ); @@ -145,11 +137,6 @@ export async function add( addonName: string, options: { useNpm: boolean; skipPostinstall: boolean } ) { - const useYarn = Boolean(options.useNpm !== true) && hasYarn(); - const npmOptions = { - useYarn, - }; - const packageManager = JsPackageManagerFactory.getPackageManager(options.useNpm); const addonCheckDone = commandLog(`Verifying that ${addonName} is an addon`); @@ -161,7 +148,7 @@ export async function add( } } addonCheckDone(); - installAddon(addonName, npmOptions, isOfficialAddon); + installAddon(packageManager, addonName, isOfficialAddon); if (!options.skipPostinstall) { await postinstallAddon(addonName, isOfficialAddon); } diff --git a/lib/cli/src/has_yarn.ts b/lib/cli/src/has_yarn.ts deleted file mode 100644 index c58706cb101f..000000000000 --- a/lib/cli/src/has_yarn.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { sync } from 'cross-spawn'; -import path from 'path'; -import findUp from 'find-up'; - -export function hasYarn() { - const yarnAvailable = sync('yarn', ['--version']); - const npmAvailable = sync('npm', ['--version']); - - const lockFile = findUp.sync(['yarn.lock', 'package-lock.json']); - const hasYarnLock = lockFile && path.basename(lockFile) === 'yarn.lock'; - - if (yarnAvailable && yarnAvailable.status === 0 && (hasYarnLock || npmAvailable.status !== 0)) { - return true; - } - return false; -} diff --git a/lib/cli/src/helpers.test.ts b/lib/cli/src/helpers.test.ts index 8f8886dceabd..675733fe7597 100644 --- a/lib/cli/src/helpers.test.ts +++ b/lib/cli/src/helpers.test.ts @@ -17,10 +17,6 @@ jest.mock('path', () => ({ resolve: jest.fn((_, p) => p), })); -jest.mock('./has_yarn', () => ({ - hasYarn2: jest.fn(() => false), -})); - describe('Helpers', () => { describe('copyTemplate', () => { it(`should fall back to ${StoryFormat.CSF} diff --git a/lib/cli/src/js-package-manager/JsPackageManager.ts b/lib/cli/src/js-package-manager/JsPackageManager.ts index 8d0f51032938..f92142166f09 100644 --- a/lib/cli/src/js-package-manager/JsPackageManager.ts +++ b/lib/cli/src/js-package-manager/JsPackageManager.ts @@ -63,7 +63,7 @@ export abstract class JsPackageManager { options: { skipInstall?: boolean; installAsDevDependencies?: boolean; - packageJson: PackageJson; + packageJson?: PackageJson; }, dependencies: string[] ): void { From 41dc95791b5ae4481aca2de499d602809ce1e15a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABtan=20Maisse?= Date: Sun, 7 Jun 2020 21:40:58 +0200 Subject: [PATCH 15/22] refactor: move PackageJson.ts inside `js-package-manager` directory --- lib/cli/src/add.ts | 2 +- lib/cli/src/detect.ts | 2 +- lib/cli/src/generators/UPDATE_PACKAGE_ORGANIZATIONS/index.ts | 2 +- lib/cli/src/helpers.ts | 2 +- lib/cli/src/js-package-manager/JsPackageManager.ts | 2 +- lib/cli/src/{ => js-package-manager}/PackageJson.ts | 0 lib/cli/src/js-package-manager/index.ts | 1 + 7 files changed, 6 insertions(+), 5 deletions(-) rename lib/cli/src/{ => js-package-manager}/PackageJson.ts (100%) diff --git a/lib/cli/src/add.ts b/lib/cli/src/add.ts index c88b6f4f6136..a4bac2a6cfe3 100644 --- a/lib/cli/src/add.ts +++ b/lib/cli/src/add.ts @@ -2,7 +2,7 @@ import path from 'path'; import fs from 'fs'; import { sync as spawnSync } from 'cross-spawn'; import { commandLog, getPackageJson } from './helpers'; -import { PackageJson } from './PackageJson'; +import { PackageJson } from './js-package-manager/PackageJson'; import { JsPackageManager, JsPackageManagerFactory } from './js-package-manager'; const logger = console; diff --git a/lib/cli/src/detect.ts b/lib/cli/src/detect.ts index 9fccbacb74d8..8d7b64daace2 100644 --- a/lib/cli/src/detect.ts +++ b/lib/cli/src/detect.ts @@ -10,7 +10,7 @@ import { TemplateMatcher, } from './project_types'; import { getBowerJson, getPackageJson } from './helpers'; -import { PackageJson } from './PackageJson'; +import { PackageJson } from './js-package-manager/PackageJson'; const hasDependency = (packageJson: PackageJson, name: string) => { return !!packageJson.dependencies?.[name] || !!packageJson.devDependencies?.[name]; diff --git a/lib/cli/src/generators/UPDATE_PACKAGE_ORGANIZATIONS/index.ts b/lib/cli/src/generators/UPDATE_PACKAGE_ORGANIZATIONS/index.ts index 7ee89a194274..d42ede6fd135 100644 --- a/lib/cli/src/generators/UPDATE_PACKAGE_ORGANIZATIONS/index.ts +++ b/lib/cli/src/generators/UPDATE_PACKAGE_ORGANIZATIONS/index.ts @@ -3,7 +3,7 @@ import path from 'path'; import { sync as spawnSync } from 'cross-spawn'; import { packageNames } from '@storybook/codemod'; import { getBabelDependencies, getPackageJson, writePackageJson } from '../../helpers'; -import { PackageJson } from '../../PackageJson'; +import { PackageJson } from '../../js-package-manager/PackageJson'; import { NpmOptions } from '../../NpmOptions'; import { JsPackageManager } from '../../js-package-manager'; diff --git a/lib/cli/src/helpers.ts b/lib/cli/src/helpers.ts index 862dd9adf410..b51be53b75a6 100644 --- a/lib/cli/src/helpers.ts +++ b/lib/cli/src/helpers.ts @@ -7,7 +7,7 @@ import { satisfies } from '@storybook/semver'; import stripJsonComments from 'strip-json-comments'; import { StoryFormat } from './project_types'; -import { PackageJson } from './PackageJson'; +import { PackageJson } from './js-package-manager/PackageJson'; import { JsPackageManager } from './js-package-manager'; const logger = console; diff --git a/lib/cli/src/js-package-manager/JsPackageManager.ts b/lib/cli/src/js-package-manager/JsPackageManager.ts index f92142166f09..f93acc82aaeb 100644 --- a/lib/cli/src/js-package-manager/JsPackageManager.ts +++ b/lib/cli/src/js-package-manager/JsPackageManager.ts @@ -3,7 +3,7 @@ import fs from 'fs'; import chalk from 'chalk'; import { gt, satisfies } from '@storybook/semver'; import { commandLog, writePackageJson } from '../helpers'; -import { PackageJson } from '../PackageJson'; +import { PackageJson } from './PackageJson'; const logger = console; // Cannot be `import` as it's not under TS root dir diff --git a/lib/cli/src/PackageJson.ts b/lib/cli/src/js-package-manager/PackageJson.ts similarity index 100% rename from lib/cli/src/PackageJson.ts rename to lib/cli/src/js-package-manager/PackageJson.ts diff --git a/lib/cli/src/js-package-manager/index.ts b/lib/cli/src/js-package-manager/index.ts index 691b1e0b805b..3a2b877d5030 100644 --- a/lib/cli/src/js-package-manager/index.ts +++ b/lib/cli/src/js-package-manager/index.ts @@ -1,2 +1,3 @@ export * from './JsPackageManagerFactory'; export * from './JsPackageManager'; +export * from './PackageJson'; From 94620167cc64978825743ea3dac106fc5c1ee230 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABtan=20Maisse?= Date: Sun, 7 Jun 2020 22:07:37 +0200 Subject: [PATCH 16/22] refactor: create function to add SB command in `scripts` attribute of package.json --- lib/cli/src/generators/ANGULAR/index.ts | 6 ++--- lib/cli/src/generators/AURELIA/index.ts | 5 ++--- lib/cli/src/generators/EMBER/index.ts | 10 ++------- lib/cli/src/generators/HTML/index.ts | 13 ++++------- lib/cli/src/generators/MARIONETTE/index.ts | 6 ++--- lib/cli/src/generators/MARKO/index.ts | 6 ++--- lib/cli/src/generators/METEOR/index.ts | 6 ++--- lib/cli/src/generators/MITHRIL/index.ts | 6 ++--- lib/cli/src/generators/PREACT/index.ts | 6 ++--- lib/cli/src/generators/RAX/index.ts | 6 ++--- lib/cli/src/generators/REACT/index.ts | 6 ++--- lib/cli/src/generators/REACT_SCRIPTS/index.ts | 15 +++++-------- lib/cli/src/generators/RIOT/index.ts | 9 ++++---- lib/cli/src/generators/SFC_VUE/index.ts | 6 ++--- lib/cli/src/generators/SVELTE/index.ts | 6 ++--- lib/cli/src/generators/VUE/index.ts | 6 ++--- .../src/generators/WEB-COMPONENTS/index.ts | 6 ++--- lib/cli/src/generators/WEBPACK_REACT/index.ts | 6 ++--- .../js-package-manager/JsPackageManager.ts | 22 +++++++++++++++++++ 19 files changed, 65 insertions(+), 87 deletions(-) diff --git a/lib/cli/src/generators/ANGULAR/index.ts b/lib/cli/src/generators/ANGULAR/index.ts index 608101c05817..f7feb24a3ed7 100644 --- a/lib/cli/src/generators/ANGULAR/index.ts +++ b/lib/cli/src/generators/ANGULAR/index.ts @@ -39,10 +39,6 @@ async function addDependencies( packageJson.dependencies = packageJson.dependencies || {}; packageJson.devDependencies = packageJson.devDependencies || {}; - packageJson.scripts = packageJson.scripts || {}; - packageJson.scripts.storybook = 'start-storybook -p 6006'; - packageJson.scripts['build-storybook'] = 'build-storybook'; - writePackageJson(packageJson); const babelDependencies = await getBabelDependencies(packageManager, packageJson); @@ -51,6 +47,8 @@ async function addDependencies( ...versionedPackages, ...babelDependencies, ]); + + packageManager.addStorybookCommandInScripts(); } function editAngularAppTsConfig() { diff --git a/lib/cli/src/generators/AURELIA/index.ts b/lib/cli/src/generators/AURELIA/index.ts index 76afc978e2d5..ab6b85389805 100644 --- a/lib/cli/src/generators/AURELIA/index.ts +++ b/lib/cli/src/generators/AURELIA/index.ts @@ -50,9 +50,6 @@ const generator: Generator = async ( const packageJson = packageManager.retrievePackageJson(); packageJson.dependencies = packageJson.dependencies || {}; packageJson.devDependencies = packageJson.devDependencies || {}; - packageJson.scripts = packageJson.scripts || {}; - packageJson.scripts.storybook = 'start-storybook -p 6006'; - packageJson.scripts['build-storybook'] = 'build-storybook'; writePackageJson(packageJson); addStorybookExcludeGlobToTsConfig(); const babelDependencies = await getBabelDependencies(packageManager, packageJson); @@ -60,6 +57,8 @@ const generator: Generator = async ( ...versionedPackages, ...babelDependencies, ]); + + packageManager.addStorybookCommandInScripts(); }; export default generator; diff --git a/lib/cli/src/generators/EMBER/index.ts b/lib/cli/src/generators/EMBER/index.ts index c698d21394b2..d8256d6de73d 100644 --- a/lib/cli/src/generators/EMBER/index.ts +++ b/lib/cli/src/generators/EMBER/index.ts @@ -27,14 +27,6 @@ const generator: Generator = async (packageManager, npmOptions, { storyFormat }) packageJson.dependencies = packageJson.dependencies || {}; packageJson.devDependencies = packageJson.devDependencies || {}; - packageJson.scripts = { - ...packageJson.scripts, - ...{ - storybook: 'start-storybook -p 6006 -s dist', - 'build-storybook': 'build-storybook -s dist', - }, - }; - writePackageJson(packageJson); const babelDependencies = await getBabelDependencies(packageManager, packageJson); @@ -48,6 +40,8 @@ const generator: Generator = async (packageManager, npmOptions, { storyFormat }) `babel-plugin-htmlbars-inline-precompile@${babelPluginHtmlBarsInlinePrecompileVersion}`, ...babelDependencies, ]); + + packageManager.addStorybookCommandInScripts(); }; export default generator; diff --git a/lib/cli/src/generators/HTML/index.ts b/lib/cli/src/generators/HTML/index.ts index 4f502dfcde20..d0c74e9ddac7 100755 --- a/lib/cli/src/generators/HTML/index.ts +++ b/lib/cli/src/generators/HTML/index.ts @@ -4,31 +4,26 @@ import { Generator } from '../Generator'; const generator: Generator = async (packageManager, npmOptions, { storyFormat }) => { const packages = ['@storybook/html', '@storybook/addon-actions', '@storybook/addon-links']; - - const versionedPackages = await packageManager.getVersionedPackages(...packages); if (storyFormat === StoryFormat.MDX) { packages.push('@storybook/addon-docs'); } + const versionedPackages = await packageManager.getVersionedPackages(...packages); + copyTemplate(__dirname, storyFormat); const packageJson = packageManager.retrievePackageJson(); - packageJson.dependencies = packageJson.dependencies || {}; packageJson.devDependencies = packageJson.devDependencies || {}; - - packageJson.scripts = packageJson.scripts || {}; - packageJson.scripts.storybook = 'start-storybook -p 6006'; - packageJson.scripts['build-storybook'] = 'build-storybook'; - writePackageJson(packageJson); const babelDependencies = await getBabelDependencies(packageManager, packageJson); - packageManager.addDependencies({ ...npmOptions, packageJson }, [ ...versionedPackages, ...babelDependencies, ]); + + packageManager.addStorybookCommandInScripts(); }; export default generator; diff --git a/lib/cli/src/generators/MARIONETTE/index.ts b/lib/cli/src/generators/MARIONETTE/index.ts index 71fc48b1095a..aaad0fa50f47 100644 --- a/lib/cli/src/generators/MARIONETTE/index.ts +++ b/lib/cli/src/generators/MARIONETTE/index.ts @@ -12,10 +12,6 @@ const generator: Generator = async (packageManager, npmOptions) => { packageJson.dependencies = packageJson.dependencies || {}; packageJson.devDependencies = packageJson.devDependencies || {}; - packageJson.scripts = packageJson.scripts || {}; - packageJson.scripts.storybook = 'start-storybook -p 6006'; - packageJson.scripts['build-storybook'] = 'build-storybook'; - writePackageJson(packageJson); const babelDependencies = await getBabelDependencies(packageManager, packageJson); @@ -24,6 +20,8 @@ const generator: Generator = async (packageManager, npmOptions) => { `@storybook/marionette@${storybookVersion}`, ...babelDependencies, ]); + + packageManager.addStorybookCommandInScripts(); }; export default generator; diff --git a/lib/cli/src/generators/MARKO/index.ts b/lib/cli/src/generators/MARKO/index.ts index 584675033a2f..16fb753a0638 100644 --- a/lib/cli/src/generators/MARKO/index.ts +++ b/lib/cli/src/generators/MARKO/index.ts @@ -19,10 +19,6 @@ const generator: Generator = async (packageManager, npmOptions, { storyFormat }) packageJson.dependencies = packageJson.dependencies || {}; packageJson.devDependencies = packageJson.devDependencies || {}; - packageJson.scripts = packageJson.scripts || {}; - packageJson.scripts.storybook = 'start-storybook -p 6006'; - packageJson.scripts['build-storybook'] = 'build-storybook'; - writePackageJson(packageJson); const babelDependencies = await getBabelDependencies(packageManager, packageJson); @@ -33,6 +29,8 @@ const generator: Generator = async (packageManager, npmOptions, { storyFormat }) `@storybook/addon-knobs@${addonKnobsVersion}`, ...babelDependencies, ]); + + packageManager.addStorybookCommandInScripts(); }; export default generator; diff --git a/lib/cli/src/generators/METEOR/index.ts b/lib/cli/src/generators/METEOR/index.ts index 18bffe046b04..e5744031f3e0 100644 --- a/lib/cli/src/generators/METEOR/index.ts +++ b/lib/cli/src/generators/METEOR/index.ts @@ -31,7 +31,6 @@ const generator: Generator = async (packageManager, npmOptions, { storyFormat }) const packageJson = packageManager.retrievePackageJson(); packageJson.devDependencies = packageJson.devDependencies || {}; - packageJson.scripts = packageJson.scripts || {}; packageJson.dependencies = packageJson.dependencies || {}; const devDependencies = [ @@ -62,9 +61,6 @@ const generator: Generator = async (packageManager, npmOptions, { storyFormat }) fs.writeFileSync('.babelrc', JSON.stringify(babelrc, null, 2), 'utf8'); - packageJson.scripts.storybook = 'start-storybook -p 6006'; - packageJson.scripts['build-storybook'] = 'build-storybook'; - writePackageJson(packageJson); const babelDependencies = await getBabelDependencies(packageManager, packageJson); @@ -89,6 +85,8 @@ const generator: Generator = async (packageManager, npmOptions, { storyFormat }) ...devDependencies, ...babelDependencies, ]); + + packageManager.addStorybookCommandInScripts(); }; export default generator; diff --git a/lib/cli/src/generators/MITHRIL/index.ts b/lib/cli/src/generators/MITHRIL/index.ts index edb5c89e18e7..a5a9325c9a6c 100644 --- a/lib/cli/src/generators/MITHRIL/index.ts +++ b/lib/cli/src/generators/MITHRIL/index.ts @@ -23,10 +23,6 @@ const generator: Generator = async (packageManager, npmOptions, { storyFormat }) packageJson.dependencies = packageJson.dependencies || {}; packageJson.devDependencies = packageJson.devDependencies || {}; - packageJson.scripts = packageJson.scripts || {}; - packageJson.scripts.storybook = 'start-storybook -p 6006'; - packageJson.scripts['build-storybook'] = 'build-storybook'; - writePackageJson(packageJson); const babelDependencies = await getBabelDependencies(packageManager, packageJson); @@ -39,6 +35,8 @@ const generator: Generator = async (packageManager, npmOptions, { storyFormat }) `@storybook/addons@${addonsVersion}`, ...babelDependencies, ]); + + packageManager.addStorybookCommandInScripts(); }; export default generator; diff --git a/lib/cli/src/generators/PREACT/index.ts b/lib/cli/src/generators/PREACT/index.ts index 2ec2c956ed8c..3c325c371593 100644 --- a/lib/cli/src/generators/PREACT/index.ts +++ b/lib/cli/src/generators/PREACT/index.ts @@ -21,10 +21,6 @@ const generator: Generator = async (packageManager, npmOptions, { storyFormat }) packageJson.dependencies = packageJson.dependencies || {}; packageJson.devDependencies = packageJson.devDependencies || {}; - packageJson.scripts = packageJson.scripts || {}; - packageJson.scripts.storybook = 'start-storybook -p 6006'; - packageJson.scripts['build-storybook'] = 'build-storybook'; - writePackageJson(packageJson); const babelDependencies = await getBabelDependencies(packageManager, packageJson); @@ -36,6 +32,8 @@ const generator: Generator = async (packageManager, npmOptions, { storyFormat }) `@storybook/addons@${addonsVersion}`, ...babelDependencies, ]); + + packageManager.addStorybookCommandInScripts(); }; export default generator; diff --git a/lib/cli/src/generators/RAX/index.ts b/lib/cli/src/generators/RAX/index.ts index 8eabdeaf5d91..8a5e3689ede0 100644 --- a/lib/cli/src/generators/RAX/index.ts +++ b/lib/cli/src/generators/RAX/index.ts @@ -34,10 +34,6 @@ const generator: Generator = async (packageManager, npmOptions, { storyFormat }) packageJson.dependencies['rax-text'] = packageJson.dependencies['rax-text'] || raxVersion; packageJson.dependencies['rax-view'] = packageJson.dependencies['rax-view'] || raxVersion; - packageJson.scripts = packageJson.scripts || {}; - packageJson.scripts.storybook = 'start-storybook -p 6006'; - packageJson.scripts['build-storybook'] = 'build-storybook'; - writePackageJson(packageJson); const babelDependencies = await getBabelDependencies(packageManager, packageJson); @@ -49,6 +45,8 @@ const generator: Generator = async (packageManager, npmOptions, { storyFormat }) `@storybook/addons@${addonsVersion}`, ...babelDependencies, ]); + + packageManager.addStorybookCommandInScripts(); }; export default generator; diff --git a/lib/cli/src/generators/REACT/index.ts b/lib/cli/src/generators/REACT/index.ts index 8dd954481fe6..14202faef18a 100644 --- a/lib/cli/src/generators/REACT/index.ts +++ b/lib/cli/src/generators/REACT/index.ts @@ -22,10 +22,6 @@ const generator: Generator = async (packageManager, npmOptions, { storyFormat }) packageJson.dependencies = packageJson.dependencies || {}; packageJson.devDependencies = packageJson.devDependencies || {}; - packageJson.scripts = packageJson.scripts || {}; - packageJson.scripts.storybook = 'start-storybook -p 6006'; - packageJson.scripts['build-storybook'] = 'build-storybook'; - writePackageJson(packageJson); const babelDependencies = await getBabelDependencies(packageManager, packageJson); @@ -34,6 +30,8 @@ const generator: Generator = async (packageManager, npmOptions, { storyFormat }) ...versionedPackages, ...babelDependencies, ]); + + packageManager.addStorybookCommandInScripts(); }; export default generator; diff --git a/lib/cli/src/generators/REACT_SCRIPTS/index.ts b/lib/cli/src/generators/REACT_SCRIPTS/index.ts index 67fadf36e82c..8fa81ff1c5fe 100644 --- a/lib/cli/src/generators/REACT_SCRIPTS/index.ts +++ b/lib/cli/src/generators/REACT_SCRIPTS/index.ts @@ -26,16 +26,6 @@ const generator: Generator = async (packageManager, npmOptions, { storyFormat }) packageJson.dependencies = packageJson.dependencies || {}; packageJson.devDependencies = packageJson.devDependencies || {}; - packageJson.scripts = packageJson.scripts || {}; - packageJson.scripts.storybook = 'start-storybook -p 9009'; - packageJson.scripts['build-storybook'] = 'build-storybook'; - - if (fs.existsSync(path.resolve('./public'))) { - // has a public folder and add support to it. - packageJson.scripts.storybook += ' -s public'; - packageJson.scripts['build-storybook'] += ' -s public'; - } - writePackageJson(packageJson); const babelDependencies = await getBabelDependencies(packageManager, packageJson); @@ -44,6 +34,11 @@ const generator: Generator = async (packageManager, npmOptions, { storyFormat }) ...versionedPackages, ...babelDependencies, ]); + + packageManager.addStorybookCommandInScripts({ + port: 9009, + staticFolder: fs.existsSync(path.resolve('./public')) ? 'public' : undefined, + }); }; export default generator; diff --git a/lib/cli/src/generators/RIOT/index.ts b/lib/cli/src/generators/RIOT/index.ts index 262298956169..f0335fc6742b 100644 --- a/lib/cli/src/generators/RIOT/index.ts +++ b/lib/cli/src/generators/RIOT/index.ts @@ -32,12 +32,9 @@ const generator: Generator = async (packageManager, npmOptions, { storyFormat }) if ( !packageJson.devDependencies['riot-tag-loader'] && !packageJson.dependencies['riot-tag-loader'] - ) + ) { dependencies.push(`riot-tag-loader@${tagLoaderVersion}`); - - packageJson.scripts = packageJson.scripts || {}; - packageJson.scripts.storybook = 'start-storybook -p 6006'; - packageJson.scripts['build-storybook'] = 'build-storybook'; + } writePackageJson(packageJson); @@ -47,6 +44,8 @@ const generator: Generator = async (packageManager, npmOptions, { storyFormat }) ...dependencies, ...babelDependencies, ]); + + packageManager.addStorybookCommandInScripts(); }; export default generator; diff --git a/lib/cli/src/generators/SFC_VUE/index.ts b/lib/cli/src/generators/SFC_VUE/index.ts index 90b109fbe95a..b55947f6599f 100644 --- a/lib/cli/src/generators/SFC_VUE/index.ts +++ b/lib/cli/src/generators/SFC_VUE/index.ts @@ -21,10 +21,6 @@ const generator: Generator = async (packageManager, npmOptions, { storyFormat }) packageJson.dependencies = packageJson.dependencies || {}; packageJson.devDependencies = packageJson.devDependencies || {}; - packageJson.scripts = packageJson.scripts || {}; - packageJson.scripts.storybook = 'start-storybook -p 6006'; - packageJson.scripts['build-storybook'] = 'build-storybook'; - writePackageJson(packageJson); const babelDependencies = await getBabelDependencies(packageManager, packageJson); @@ -33,6 +29,8 @@ const generator: Generator = async (packageManager, npmOptions, { storyFormat }) ...versionedPackages, ...babelDependencies, ]); + + packageManager.addStorybookCommandInScripts(); }; export default generator; diff --git a/lib/cli/src/generators/SVELTE/index.ts b/lib/cli/src/generators/SVELTE/index.ts index 3b2accf677b6..4025449f86a4 100644 --- a/lib/cli/src/generators/SVELTE/index.ts +++ b/lib/cli/src/generators/SVELTE/index.ts @@ -25,10 +25,6 @@ const generator: Generator = async (packageManager, npmOptions, { storyFormat }) packageJson.dependencies = packageJson.dependencies || {}; packageJson.devDependencies = packageJson.devDependencies || {}; - packageJson.scripts = packageJson.scripts || {}; - packageJson.scripts.storybook = 'start-storybook -p 6006'; - packageJson.scripts['build-storybook'] = 'build-storybook'; - writePackageJson(packageJson); const babelDependencies = await getBabelDependencies(packageManager, packageJson); @@ -42,6 +38,8 @@ const generator: Generator = async (packageManager, npmOptions, { storyFormat }) `svelte-loader@${svelteLoader}`, ...babelDependencies, ]); + + packageManager.addStorybookCommandInScripts(); }; export default generator; diff --git a/lib/cli/src/generators/VUE/index.ts b/lib/cli/src/generators/VUE/index.ts index 86899a4fe064..4655bf7d1bd6 100644 --- a/lib/cli/src/generators/VUE/index.ts +++ b/lib/cli/src/generators/VUE/index.ts @@ -41,10 +41,6 @@ const generator: Generator = async (packageManager, npmOptions, { storyFormat }) ); } - packageJson.scripts = packageJson.scripts || {}; - packageJson.scripts.storybook = 'start-storybook -p 6006'; - packageJson.scripts['build-storybook'] = 'build-storybook'; - writePackageJson(packageJson); const babelDependencies = await getBabelDependencies(packageManager, packageJson); @@ -52,6 +48,8 @@ const generator: Generator = async (packageManager, npmOptions, { storyFormat }) ...versionedPackages, ...babelDependencies, ]); + + packageManager.addStorybookCommandInScripts(); }; export default generator; diff --git a/lib/cli/src/generators/WEB-COMPONENTS/index.ts b/lib/cli/src/generators/WEB-COMPONENTS/index.ts index 721d88e7522f..88b525ffe5d6 100755 --- a/lib/cli/src/generators/WEB-COMPONENTS/index.ts +++ b/lib/cli/src/generators/WEB-COMPONENTS/index.ts @@ -25,10 +25,6 @@ const generator: Generator = async (packageManager, npmOptions, { storyFormat }) packageJson.dependencies = packageJson.dependencies || {}; packageJson.devDependencies = packageJson.devDependencies || {}; - packageJson.scripts = packageJson.scripts || {}; - packageJson.scripts.storybook = 'start-storybook -p 6006'; - packageJson.scripts['build-storybook'] = 'build-storybook'; - writePackageJson(packageJson); const babelDependencies = await getBabelDependencies(packageManager, packageJson); @@ -37,6 +33,8 @@ const generator: Generator = async (packageManager, npmOptions, { storyFormat }) ...versionedPackages, ...babelDependencies, ]); + + packageManager.addStorybookCommandInScripts(); }; export default generator; diff --git a/lib/cli/src/generators/WEBPACK_REACT/index.ts b/lib/cli/src/generators/WEBPACK_REACT/index.ts index 433015afdd34..c8585774d071 100644 --- a/lib/cli/src/generators/WEBPACK_REACT/index.ts +++ b/lib/cli/src/generators/WEBPACK_REACT/index.ts @@ -21,10 +21,6 @@ const generator: Generator = async (packageManager, npmOptions, { storyFormat }) packageJson.dependencies = packageJson.dependencies || {}; packageJson.devDependencies = packageJson.devDependencies || {}; - packageJson.scripts = packageJson.scripts || {}; - packageJson.scripts.storybook = 'start-storybook -p 6006'; - packageJson.scripts['build-storybook'] = 'build-storybook'; - writePackageJson(packageJson); const babelDependencies = await getBabelDependencies(packageManager, packageJson); @@ -33,6 +29,8 @@ const generator: Generator = async (packageManager, npmOptions, { storyFormat }) ...versionedPackages, ...babelDependencies, ]); + + packageManager.addStorybookCommandInScripts(); }; export default generator; diff --git a/lib/cli/src/js-package-manager/JsPackageManager.ts b/lib/cli/src/js-package-manager/JsPackageManager.ts index f93acc82aaeb..881a64821963 100644 --- a/lib/cli/src/js-package-manager/JsPackageManager.ts +++ b/lib/cli/src/js-package-manager/JsPackageManager.ts @@ -173,6 +173,28 @@ export abstract class JsPackageManager { return versions.reverse().find((version) => satisfies(version, constraint)); } + public addStorybookCommandInScripts(options?: { port: number; staticFolder?: string }) { + const packageJson = this.retrievePackageJson(); + + const sbPort = options?.port ?? 6006; + const storybookCmd = options?.staticFolder + ? `start-storybook -p ${sbPort} -s ${options.staticFolder}` + : `start-storybook -p ${sbPort}`; + + const buildStorybookCmd = options?.staticFolder + ? `build-storybook -s ${options.staticFolder}` + : 'build-storybook'; + + writePackageJson({ + ...packageJson, + scripts: { + ...packageJson.scripts, + storybook: storybookCmd, + 'build-storybook': buildStorybookCmd, + }, + }); + } + protected abstract runInstall(): { status: number }; protected abstract runAddDeps( From 6c383a048081caf8b150c783306ddb7183764e42 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABtan=20Maisse?= Date: Mon, 8 Jun 2020 18:43:20 +0200 Subject: [PATCH 17/22] fix: update versions.json --- lib/cli/versions.json | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/lib/cli/versions.json b/lib/cli/versions.json index 12aa22d7684a..484f75880689 100644 --- a/lib/cli/versions.json +++ b/lib/cli/versions.json @@ -1,17 +1,17 @@ { - "@storybook/angular": "6.0.0-beta.22", - "@storybook/aurelia": "6.0.0-beta.22", - "@storybook/ember": "6.0.0-beta.22", - "@storybook/html": "6.0.0-beta.22", - "@storybook/marionette": "6.0.0-beta.22", - "@storybook/marko": "6.0.0-beta.22", - "@storybook/mithril": "6.0.0-beta.22", - "@storybook/preact": "6.0.0-beta.22", - "@storybook/rax": "6.0.0-beta.22", - "@storybook/react": "6.0.0-beta.22", - "@storybook/riot": "6.0.0-beta.22", - "@storybook/server": "6.0.0-beta.22", - "@storybook/svelte": "6.0.0-beta.22", - "@storybook/vue": "6.0.0-beta.22", - "@storybook/web-components": "6.0.0-beta.22" + "@storybook/angular": "6.0.0-beta.23", + "@storybook/aurelia": "6.0.0-beta.23", + "@storybook/ember": "6.0.0-beta.23", + "@storybook/html": "6.0.0-beta.23", + "@storybook/marionette": "6.0.0-beta.23", + "@storybook/marko": "6.0.0-beta.23", + "@storybook/mithril": "6.0.0-beta.23", + "@storybook/preact": "6.0.0-beta.23", + "@storybook/rax": "6.0.0-beta.23", + "@storybook/react": "6.0.0-beta.23", + "@storybook/riot": "6.0.0-beta.23", + "@storybook/server": "6.0.0-beta.23", + "@storybook/svelte": "6.0.0-beta.23", + "@storybook/vue": "6.0.0-beta.23", + "@storybook/web-components": "6.0.0-beta.23" } \ No newline at end of file From 0c1a9740dc961328d7febecfac7c9f96dd03a855 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABtan=20Maisse?= Date: Mon, 8 Jun 2020 18:43:42 +0200 Subject: [PATCH 18/22] refactor: update signature of `runInstall` function --- lib/cli/src/js-package-manager/JsPackageManager.ts | 9 +++++---- lib/cli/src/js-package-manager/NPMProxy.ts | 8 ++++++-- lib/cli/src/js-package-manager/Yarn1Proxy.ts | 8 ++++++-- lib/cli/src/js-package-manager/Yarn2Proxy.ts | 8 ++++++-- 4 files changed, 23 insertions(+), 10 deletions(-) diff --git a/lib/cli/src/js-package-manager/JsPackageManager.ts b/lib/cli/src/js-package-manager/JsPackageManager.ts index 881a64821963..d4e23adcb3c3 100644 --- a/lib/cli/src/js-package-manager/JsPackageManager.ts +++ b/lib/cli/src/js-package-manager/JsPackageManager.ts @@ -22,11 +22,12 @@ export abstract class JsPackageManager { done(); logger.log(); - const result = this.runInstall(); - logger.log(); done = commandLog('Installing dependencies'); - if (result.status !== 0) { + + try { + this.runInstall(); + } catch (e) { done('An error occurred while installing dependencies.'); process.exit(1); } @@ -195,7 +196,7 @@ export abstract class JsPackageManager { }); } - protected abstract runInstall(): { status: number }; + protected abstract runInstall(): void; protected abstract runAddDeps( dependencies: string[], diff --git a/lib/cli/src/js-package-manager/NPMProxy.ts b/lib/cli/src/js-package-manager/NPMProxy.ts index e8a57f52c86c..fa3df940e9ef 100644 --- a/lib/cli/src/js-package-manager/NPMProxy.ts +++ b/lib/cli/src/js-package-manager/NPMProxy.ts @@ -16,8 +16,12 @@ export class NPMProxy extends JsPackageManager { return 'npm run storybook'; } - protected runInstall(): { status: number } { - return spawnSync('npm', ['install'], { stdio: 'inherit' }); + protected runInstall(): void { + const commandResult = spawnSync('npm', ['install'], { stdio: 'inherit' }); + + if (commandResult.status !== 0) { + throw new Error(commandResult.stderr.toString()); + } } protected runAddDeps( diff --git a/lib/cli/src/js-package-manager/Yarn1Proxy.ts b/lib/cli/src/js-package-manager/Yarn1Proxy.ts index c39b3f3505f1..5dccaa4059c2 100644 --- a/lib/cli/src/js-package-manager/Yarn1Proxy.ts +++ b/lib/cli/src/js-package-manager/Yarn1Proxy.ts @@ -16,8 +16,12 @@ export class Yarn1Proxy extends JsPackageManager { return 'yarn storybook'; } - protected runInstall(): { status: number } { - return spawnSync('yarn', { stdio: 'inherit' }); + protected runInstall(): void { + const commandResult = spawnSync('yarn', { stdio: 'inherit' }); + + if (commandResult.status !== 0) { + throw new Error(commandResult.stderr.toString()); + } } protected runAddDeps( diff --git a/lib/cli/src/js-package-manager/Yarn2Proxy.ts b/lib/cli/src/js-package-manager/Yarn2Proxy.ts index 20cccdbfecea..e8bbaa6ecfa5 100644 --- a/lib/cli/src/js-package-manager/Yarn2Proxy.ts +++ b/lib/cli/src/js-package-manager/Yarn2Proxy.ts @@ -16,8 +16,12 @@ export class Yarn2Proxy extends JsPackageManager { return 'yarn storybook'; } - protected runInstall(): { status: number } { - return spawnSync('yarn', { stdio: 'inherit' }); + protected runInstall(): void { + const commandResult = spawnSync('yarn', { stdio: 'inherit' }); + + if (commandResult.status !== 0) { + throw new Error(commandResult.stderr.toString()); + } } protected runAddDeps( From f5c788b92be28434274c0e501ee9d98dbf4d3364 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABtan=20Maisse?= Date: Mon, 8 Jun 2020 18:47:29 +0200 Subject: [PATCH 19/22] refactor: update signature of `runAddDeps` function --- lib/cli/src/js-package-manager/JsPackageManager.ts | 13 +++++-------- lib/cli/src/js-package-manager/NPMProxy.ts | 11 ++++++----- lib/cli/src/js-package-manager/Yarn1Proxy.ts | 11 ++++++----- lib/cli/src/js-package-manager/Yarn2Proxy.ts | 11 ++++++----- 4 files changed, 23 insertions(+), 23 deletions(-) diff --git a/lib/cli/src/js-package-manager/JsPackageManager.ts b/lib/cli/src/js-package-manager/JsPackageManager.ts index d4e23adcb3c3..60715eb16022 100644 --- a/lib/cli/src/js-package-manager/JsPackageManager.ts +++ b/lib/cli/src/js-package-manager/JsPackageManager.ts @@ -95,11 +95,11 @@ export abstract class JsPackageManager { writePackageJson(packageJson); } else { - const dependencyResult = this.runAddDeps(dependencies, options.installAsDevDependencies); - - if (dependencyResult.status !== 0) { + try { + this.runAddDeps(dependencies, options.installAsDevDependencies); + } catch (e) { logger.error('An error occurred while installing dependencies.'); - logger.log(dependencyResult); + logger.log(e.message); process.exit(1); } } @@ -198,10 +198,7 @@ export abstract class JsPackageManager { protected abstract runInstall(): void; - protected abstract runAddDeps( - dependencies: string[], - installAsDevDependencies: boolean - ): { status: number }; + protected abstract runAddDeps(dependencies: string[], installAsDevDependencies: boolean): void; /** * Get the latest or all versions of the input package available on npmjs.com diff --git a/lib/cli/src/js-package-manager/NPMProxy.ts b/lib/cli/src/js-package-manager/NPMProxy.ts index fa3df940e9ef..8bdd2b44de8e 100644 --- a/lib/cli/src/js-package-manager/NPMProxy.ts +++ b/lib/cli/src/js-package-manager/NPMProxy.ts @@ -24,17 +24,18 @@ export class NPMProxy extends JsPackageManager { } } - protected runAddDeps( - dependencies: string[], - installAsDevDependencies: boolean - ): { status: number } { + protected runAddDeps(dependencies: string[], installAsDevDependencies: boolean): void { const args = ['install', ...dependencies]; if (installAsDevDependencies) { args.push('-D'); } - return spawnSync('npm', args, { stdio: 'inherit' }); + const commandResult = spawnSync('npm', args, { stdio: 'inherit' }); + + if (commandResult.status !== 0) { + throw new Error(commandResult.stderr.toString()); + } } protected runGetVersions( diff --git a/lib/cli/src/js-package-manager/Yarn1Proxy.ts b/lib/cli/src/js-package-manager/Yarn1Proxy.ts index 5dccaa4059c2..0fbdcfbf65d0 100644 --- a/lib/cli/src/js-package-manager/Yarn1Proxy.ts +++ b/lib/cli/src/js-package-manager/Yarn1Proxy.ts @@ -24,17 +24,18 @@ export class Yarn1Proxy extends JsPackageManager { } } - protected runAddDeps( - dependencies: string[], - installAsDevDependencies: boolean - ): { status: number } { + protected runAddDeps(dependencies: string[], installAsDevDependencies: boolean): void { const args = ['add', '--ignore-workspace-root-check', ...dependencies]; if (installAsDevDependencies) { args.push('-D'); } - return spawnSync('yarn', args, { stdio: 'inherit' }); + const commandResult = spawnSync('yarn', args, { stdio: 'inherit' }); + + if (commandResult.status !== 0) { + throw new Error(commandResult.stderr.toString()); + } } protected runGetVersions( diff --git a/lib/cli/src/js-package-manager/Yarn2Proxy.ts b/lib/cli/src/js-package-manager/Yarn2Proxy.ts index e8bbaa6ecfa5..e673cd194d01 100644 --- a/lib/cli/src/js-package-manager/Yarn2Proxy.ts +++ b/lib/cli/src/js-package-manager/Yarn2Proxy.ts @@ -24,17 +24,18 @@ export class Yarn2Proxy extends JsPackageManager { } } - protected runAddDeps( - dependencies: string[], - installAsDevDependencies: boolean - ): { status: number } { + protected runAddDeps(dependencies: string[], installAsDevDependencies: boolean): void { const args = ['add', ...dependencies]; if (installAsDevDependencies) { args.push('-D'); } - return spawnSync('yarn', args, { stdio: 'inherit' }); + const commandResult = spawnSync('yarn', args, { stdio: 'inherit' }); + + if (commandResult.status !== 0) { + throw new Error(commandResult.stderr.toString()); + } } protected runGetVersions( From b0e1d93eca245b82bc15b82697af95a443054838 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABtan=20Maisse?= Date: Mon, 8 Jun 2020 20:07:37 +0200 Subject: [PATCH 20/22] refactor: create a `executeCommand` function and use it for every `yarn` or `npm` calls It move the `spawnSync` usage to only a single place which is simpler to maintain. It also simplify testing as there is no more need to mock an external dep --- .../js-package-manager/JsPackageManager.ts | 14 +++ .../src/js-package-manager/NPMProxy.test.ts | 104 ++++++++++++------ lib/cli/src/js-package-manager/NPMProxy.ts | 42 ++----- .../src/js-package-manager/Yarn1Proxy.test.ts | 92 ++++++++++++---- lib/cli/src/js-package-manager/Yarn1Proxy.ts | 42 ++----- .../src/js-package-manager/Yarn2Proxy.test.ts | 96 ++++++++++++---- lib/cli/src/js-package-manager/Yarn2Proxy.ts | 43 ++------ 7 files changed, 252 insertions(+), 181 deletions(-) diff --git a/lib/cli/src/js-package-manager/JsPackageManager.ts b/lib/cli/src/js-package-manager/JsPackageManager.ts index 60715eb16022..286db0ca44fb 100644 --- a/lib/cli/src/js-package-manager/JsPackageManager.ts +++ b/lib/cli/src/js-package-manager/JsPackageManager.ts @@ -2,6 +2,7 @@ import path from 'path'; import fs from 'fs'; import chalk from 'chalk'; import { gt, satisfies } from '@storybook/semver'; +import { sync as spawnSync } from 'cross-spawn'; import { commandLog, writePackageJson } from '../helpers'; import { PackageJson } from './PackageJson'; @@ -221,4 +222,17 @@ export abstract class JsPackageManager { const jsonContent = fs.readFileSync(packageJsonPath, 'utf8'); return JSON.parse(jsonContent); } + + public executeCommand(command: string, args: string[], stdio?: 'pipe' | 'inherit'): string { + const commandResult = spawnSync(command, args, { + stdio: stdio ?? 'pipe', + encoding: 'utf-8', + }); + + if (commandResult.status !== 0) { + throw new Error(commandResult.stderr ?? ''); + } + + return commandResult.stdout ?? ''; + } } diff --git a/lib/cli/src/js-package-manager/NPMProxy.test.ts b/lib/cli/src/js-package-manager/NPMProxy.test.ts index 09f444f22b46..e152732bab9e 100644 --- a/lib/cli/src/js-package-manager/NPMProxy.test.ts +++ b/lib/cli/src/js-package-manager/NPMProxy.test.ts @@ -1,45 +1,81 @@ -import { sync } from 'cross-spawn'; -import dedent from 'ts-dedent'; import { NPMProxy } from './NPMProxy'; -jest.mock('cross-spawn'); -const syncMock = sync as jest.Mock; - describe('NPM Proxy', () => { - const npmProxy = new NPMProxy(); + let npmProxy: NPMProxy; + + beforeEach(() => { + npmProxy = new NPMProxy(); + }); describe('initPackageJson', () => { - it('should call spawn.sync and return console output', () => { - const consoleOutput = dedent`Wrote to /Users/johndoe/Documents/package.json: - { - "name": "toto", - "version": "1.0.0", - "description": "", - "main": "index.js", - "scripts": { - "test": "echo \\"Error: no test specified\\" && exit 1" - }, - "keywords": [], - "author": "", - "license": "ISC" - }`; - - syncMock.mockReturnValueOnce({ stdout: consoleOutput }); - - const result = npmProxy.initPackageJson(); - - expect(syncMock).toHaveBeenCalledWith( + it('should run `npm init -y`', () => { + const executeCommandSpy = jest.spyOn(npmProxy, 'executeCommand').mockReturnValue(''); + + npmProxy.initPackageJson(); + + expect(executeCommandSpy).toHaveBeenCalledWith('npm', ['init', '-y']); + }); + }); + + describe('installDependencies', () => { + it('should run `npm install`', () => { + const executeCommandSpy = jest.spyOn(npmProxy, 'executeCommand').mockReturnValue(''); + + npmProxy.installDependencies(); + + expect(executeCommandSpy).toHaveBeenCalledWith('npm', ['install'], expect.any(String)); + }); + }); + + describe('addDependencies', () => { + it('with devDep it should run `npm install -D @storybook/addons`', () => { + const executeCommandSpy = jest.spyOn(npmProxy, 'executeCommand').mockReturnValue(''); + + npmProxy.addDependencies({ installAsDevDependencies: true }, ['@storybook/addons']); + + expect(executeCommandSpy).toHaveBeenCalledWith( 'npm', - ['init', '-y'], - expect.objectContaining({ - cwd: process.cwd(), - env: process.env, - stdio: 'pipe', - encoding: 'utf-8', - }) + ['install', '-D', '@storybook/addons'], + expect.any(String) ); + }); + }); + + describe('latestVersion', () => { + it('without contraint it returns the latest version', async () => { + const executeCommandSpy = jest.spyOn(npmProxy, 'executeCommand').mockReturnValue('"5.3.19"'); + + const version = await npmProxy.latestVersion('@storybook/addons'); + + expect(executeCommandSpy).toHaveBeenCalledWith('npm', [ + 'info', + '@storybook/addons', + 'version', + '--json', + ]); + expect(version).toEqual('5.3.19'); + }); + + it('with contraint it returns the latest version satisfying the constraint', async () => { + const executeCommandSpy = jest + .spyOn(npmProxy, 'executeCommand') + .mockReturnValue('["4.25.3","5.3.19","6.0.0-beta.23"]'); + + const version = await npmProxy.latestVersion('@storybook/addons', '5.X'); + + expect(executeCommandSpy).toHaveBeenCalledWith('npm', [ + 'info', + '@storybook/addons', + 'versions', + '--json', + ]); + expect(version).toEqual('5.3.19'); + }); + + it('throws an error if command output is not a valid JSON', async () => { + jest.spyOn(npmProxy, 'executeCommand').mockReturnValue('NOT A JSON'); - expect(result).toEqual(expect.any(String)); + await expect(npmProxy.latestVersion('@storybook/addons')).rejects.toThrow(); }); }); }); diff --git a/lib/cli/src/js-package-manager/NPMProxy.ts b/lib/cli/src/js-package-manager/NPMProxy.ts index 8bdd2b44de8e..a8e4765954ee 100644 --- a/lib/cli/src/js-package-manager/NPMProxy.ts +++ b/lib/cli/src/js-package-manager/NPMProxy.ts @@ -1,15 +1,8 @@ -import { sync as spawnSync } from 'cross-spawn'; import { JsPackageManager } from './JsPackageManager'; export class NPMProxy extends JsPackageManager { initPackageJson() { - const results = spawnSync('npm', ['init', '-y'], { - cwd: process.cwd(), - env: process.env, - stdio: 'pipe', - encoding: 'utf-8', - }); - return results.stdout; + return this.executeCommand('npm', ['init', '-y']); } getRunStorybookCommand(): string { @@ -17,48 +10,29 @@ export class NPMProxy extends JsPackageManager { } protected runInstall(): void { - const commandResult = spawnSync('npm', ['install'], { stdio: 'inherit' }); - - if (commandResult.status !== 0) { - throw new Error(commandResult.stderr.toString()); - } + this.executeCommand('npm', ['install'], 'inherit'); } protected runAddDeps(dependencies: string[], installAsDevDependencies: boolean): void { - const args = ['install', ...dependencies]; + let args = [...dependencies]; if (installAsDevDependencies) { - args.push('-D'); + args = ['-D', ...args]; } - const commandResult = spawnSync('npm', args, { stdio: 'inherit' }); - - if (commandResult.status !== 0) { - throw new Error(commandResult.stderr.toString()); - } + this.executeCommand('npm', ['install', ...args], 'inherit'); } protected runGetVersions( packageName: string, fetchAllVersions: T ): Promise { - const commandResult = spawnSync( - 'npm', - ['info', packageName, fetchAllVersions ? 'versions' : 'version', '--json'], - { - cwd: process.cwd(), - env: process.env, - stdio: 'pipe', - encoding: 'utf-8', - } - ); + const args = [fetchAllVersions ? 'versions' : 'version', '--json']; - if (commandResult.status !== 0) { - throw new Error(commandResult.stderr.toString()); - } + const commandResult = this.executeCommand('npm', ['info', packageName, ...args]); try { - const parsedOutput = JSON.parse(commandResult.stdout.toString()); + const parsedOutput = JSON.parse(commandResult); if (parsedOutput.error) { // FIXME: improve error handling diff --git a/lib/cli/src/js-package-manager/Yarn1Proxy.test.ts b/lib/cli/src/js-package-manager/Yarn1Proxy.test.ts index e5588f8f337a..0db351c79bff 100644 --- a/lib/cli/src/js-package-manager/Yarn1Proxy.test.ts +++ b/lib/cli/src/js-package-manager/Yarn1Proxy.test.ts @@ -1,37 +1,83 @@ -import { sync } from 'cross-spawn'; -import dedent from 'ts-dedent'; import { Yarn1Proxy } from './Yarn1Proxy'; -jest.mock('cross-spawn'); -const syncMock = sync as jest.Mock; +describe('Yarn 1 Proxy', () => { + let yarn1Proxy: Yarn1Proxy; -describe('Yarn Proxy', () => { - const yarnProxy = new Yarn1Proxy(); + beforeEach(() => { + yarn1Proxy = new Yarn1Proxy(); + }); describe('initPackageJson', () => { - it('should call spawn.sync and return console output', () => { - const consoleOutput = dedent` - yarn init v1.22.4 - warning The yes flag has been set. This will automatically answer yes to all questions, which may have security implications. - success Saved package.json - ✨ Done in 0.02s.`; + it('should run `yarn init -y`', () => { + const executeCommandSpy = jest.spyOn(yarn1Proxy, 'executeCommand').mockReturnValue(''); + + yarn1Proxy.initPackageJson(); + + expect(executeCommandSpy).toHaveBeenCalledWith('yarn', ['init', '-y']); + }); + }); - syncMock.mockReturnValueOnce({ stdout: consoleOutput }); + describe('installDependencies', () => { + it('should run `yarn`', () => { + const executeCommandSpy = jest.spyOn(yarn1Proxy, 'executeCommand').mockReturnValue(''); - const result = yarnProxy.initPackageJson(); + yarn1Proxy.installDependencies(); - expect(syncMock).toHaveBeenCalledWith( + expect(executeCommandSpy).toHaveBeenCalledWith('yarn', [], expect.any(String)); + }); + }); + + describe('addDependencies', () => { + it('with devDep it should run `yarn install -D --ignore-workspace-root-check @storybook/addons`', () => { + const executeCommandSpy = jest.spyOn(yarn1Proxy, 'executeCommand').mockReturnValue(''); + + yarn1Proxy.addDependencies({ installAsDevDependencies: true }, ['@storybook/addons']); + + expect(executeCommandSpy).toHaveBeenCalledWith( 'yarn', - ['init', '-y'], - expect.objectContaining({ - cwd: process.cwd(), - env: process.env, - stdio: 'pipe', - encoding: 'utf-8', - }) + ['add', '-D', '--ignore-workspace-root-check', '@storybook/addons'], + expect.any(String) ); + }); + }); + + describe('latestVersion', () => { + it('without contraint it returns the latest version', async () => { + const executeCommandSpy = jest + .spyOn(yarn1Proxy, 'executeCommand') + .mockReturnValue('{"type":"inspect","data":"5.3.19"}'); + + const version = await yarn1Proxy.latestVersion('@storybook/addons'); + + expect(executeCommandSpy).toHaveBeenCalledWith('yarn', [ + 'info', + '@storybook/addons', + 'version', + '--json', + ]); + expect(version).toEqual('5.3.19'); + }); + + it('with contraint it returns the latest version satisfying the constraint', async () => { + const executeCommandSpy = jest + .spyOn(yarn1Proxy, 'executeCommand') + .mockReturnValue('{"type":"inspect","data":["4.25.3","5.3.19","6.0.0-beta.23"]}'); + + const version = await yarn1Proxy.latestVersion('@storybook/addons', '5.X'); + + expect(executeCommandSpy).toHaveBeenCalledWith('yarn', [ + 'info', + '@storybook/addons', + 'versions', + '--json', + ]); + expect(version).toEqual('5.3.19'); + }); + + it('throws an error if command output is not a valid JSON', async () => { + jest.spyOn(yarn1Proxy, 'executeCommand').mockReturnValue('NOT A JSON'); - expect(result).toEqual(expect.any(String)); + await expect(yarn1Proxy.latestVersion('@storybook/addons')).rejects.toThrow(); }); }); }); diff --git a/lib/cli/src/js-package-manager/Yarn1Proxy.ts b/lib/cli/src/js-package-manager/Yarn1Proxy.ts index 0fbdcfbf65d0..af09bf197214 100644 --- a/lib/cli/src/js-package-manager/Yarn1Proxy.ts +++ b/lib/cli/src/js-package-manager/Yarn1Proxy.ts @@ -1,15 +1,8 @@ -import { sync as spawnSync } from 'cross-spawn'; import { JsPackageManager } from './JsPackageManager'; export class Yarn1Proxy extends JsPackageManager { initPackageJson() { - const results = spawnSync('yarn', ['init', '-y'], { - cwd: process.cwd(), - env: process.env, - stdio: 'pipe', - encoding: 'utf-8', - }); - return results.stdout; + return this.executeCommand('yarn', ['init', '-y']); } getRunStorybookCommand(): string { @@ -17,48 +10,29 @@ export class Yarn1Proxy extends JsPackageManager { } protected runInstall(): void { - const commandResult = spawnSync('yarn', { stdio: 'inherit' }); - - if (commandResult.status !== 0) { - throw new Error(commandResult.stderr.toString()); - } + this.executeCommand('yarn', [], 'inherit'); } protected runAddDeps(dependencies: string[], installAsDevDependencies: boolean): void { - const args = ['add', '--ignore-workspace-root-check', ...dependencies]; + let args = ['--ignore-workspace-root-check', ...dependencies]; if (installAsDevDependencies) { - args.push('-D'); + args = ['-D', ...args]; } - const commandResult = spawnSync('yarn', args, { stdio: 'inherit' }); - - if (commandResult.status !== 0) { - throw new Error(commandResult.stderr.toString()); - } + this.executeCommand('yarn', ['add', ...args], 'inherit'); } protected runGetVersions( packageName: string, fetchAllVersions: T ): Promise { - const commandResult = spawnSync( - 'yarn', - ['info', packageName, fetchAllVersions ? 'versions' : 'version', '--json'], - { - cwd: process.cwd(), - env: process.env, - stdio: 'pipe', - encoding: 'utf-8', - } - ); + const args = [fetchAllVersions ? 'versions' : 'version', '--json']; - if (commandResult.status !== 0) { - throw new Error(commandResult.stderr.toString()); - } + const commandResult = this.executeCommand('yarn', ['info', packageName, ...args]); try { - const parsedOutput = JSON.parse(commandResult.stdout.toString()); + const parsedOutput = JSON.parse(commandResult); if (parsedOutput.type === 'inspect') { return parsedOutput.data; } diff --git a/lib/cli/src/js-package-manager/Yarn2Proxy.test.ts b/lib/cli/src/js-package-manager/Yarn2Proxy.test.ts index 3518595e99b5..3c3fc17ba799 100644 --- a/lib/cli/src/js-package-manager/Yarn2Proxy.test.ts +++ b/lib/cli/src/js-package-manager/Yarn2Proxy.test.ts @@ -1,35 +1,89 @@ -import { sync } from 'cross-spawn'; -import dedent from 'ts-dedent'; import { Yarn2Proxy } from './Yarn2Proxy'; -jest.mock('cross-spawn'); -const syncMock = sync as jest.Mock; +describe('Yarn 1 Proxy', () => { + let yarn2Proxy: Yarn2Proxy; -describe('Yarn 2 Proxy', () => { - const yarn2Proxy = new Yarn2Proxy(); + beforeEach(() => { + yarn2Proxy = new Yarn2Proxy(); + }); describe('initPackageJson', () => { - it('should call spawn.sync and return console output', () => { - const consoleOutput = dedent`{ - name: 'test' - }`; + it('should run `yarn init`', () => { + const executeCommandSpy = jest.spyOn(yarn2Proxy, 'executeCommand').mockReturnValue(''); + + yarn2Proxy.initPackageJson(); + + expect(executeCommandSpy).toHaveBeenCalledWith('yarn', ['init']); + }); + }); - syncMock.mockReturnValueOnce({ stdout: consoleOutput }); + describe('installDependencies', () => { + it('should run `yarn`', () => { + const executeCommandSpy = jest.spyOn(yarn2Proxy, 'executeCommand').mockReturnValue(''); - const result = yarn2Proxy.initPackageJson(); + yarn2Proxy.installDependencies(); - expect(syncMock).toHaveBeenCalledWith( + expect(executeCommandSpy).toHaveBeenCalledWith('yarn', [], expect.any(String)); + }); + }); + + describe('addDependencies', () => { + it('with devDep it should run `yarn install -D @storybook/addons`', () => { + const executeCommandSpy = jest.spyOn(yarn2Proxy, 'executeCommand').mockReturnValue(''); + + yarn2Proxy.addDependencies({ installAsDevDependencies: true }, ['@storybook/addons']); + + expect(executeCommandSpy).toHaveBeenCalledWith( 'yarn', - ['init'], - expect.objectContaining({ - cwd: process.cwd(), - env: process.env, - stdio: 'pipe', - encoding: 'utf-8', - }) + ['add', '-D', '@storybook/addons'], + expect.any(String) ); + }); + }); + + describe('latestVersion', () => { + it('without contraint it returns the latest version', async () => { + const executeCommandSpy = jest + .spyOn(yarn2Proxy, 'executeCommand') + .mockReturnValue('{"name":"@storybook/addons","version":"5.3.19"}'); + + const version = await yarn2Proxy.latestVersion('@storybook/addons'); + + expect(executeCommandSpy).toHaveBeenCalledWith('yarn', [ + 'npm', + 'info', + '@storybook/addons', + '--fields', + 'version', + '--json', + ]); + expect(version).toEqual('5.3.19'); + }); + + it('with contraint it returns the latest version satisfying the constraint', async () => { + const executeCommandSpy = jest + .spyOn(yarn2Proxy, 'executeCommand') + .mockReturnValue( + '{"name":"@storybook/addons","versions":["4.25.3","5.3.19","6.0.0-beta.23"]}' + ); + + const version = await yarn2Proxy.latestVersion('@storybook/addons', '5.X'); + + expect(executeCommandSpy).toHaveBeenCalledWith('yarn', [ + 'npm', + 'info', + '@storybook/addons', + '--fields', + 'versions', + '--json', + ]); + expect(version).toEqual('5.3.19'); + }); + + it('throws an error if command output is not a valid JSON', async () => { + jest.spyOn(yarn2Proxy, 'executeCommand').mockReturnValue('NOT A JSON'); - expect(result).toEqual(expect.any(String)); + await expect(yarn2Proxy.latestVersion('@storybook/addons')).rejects.toThrow(); }); }); }); diff --git a/lib/cli/src/js-package-manager/Yarn2Proxy.ts b/lib/cli/src/js-package-manager/Yarn2Proxy.ts index e673cd194d01..2b7783bb58be 100644 --- a/lib/cli/src/js-package-manager/Yarn2Proxy.ts +++ b/lib/cli/src/js-package-manager/Yarn2Proxy.ts @@ -1,15 +1,8 @@ -import { sync as spawnSync } from 'cross-spawn'; import { JsPackageManager } from './JsPackageManager'; export class Yarn2Proxy extends JsPackageManager { initPackageJson() { - const results = spawnSync('yarn', ['init'], { - cwd: process.cwd(), - env: process.env, - stdio: 'pipe', - encoding: 'utf-8', - }); - return results.stdout; + return this.executeCommand('yarn', ['init']); } getRunStorybookCommand(): string { @@ -17,25 +10,17 @@ export class Yarn2Proxy extends JsPackageManager { } protected runInstall(): void { - const commandResult = spawnSync('yarn', { stdio: 'inherit' }); - - if (commandResult.status !== 0) { - throw new Error(commandResult.stderr.toString()); - } + this.executeCommand('yarn', [], 'inherit'); } protected runAddDeps(dependencies: string[], installAsDevDependencies: boolean): void { - const args = ['add', ...dependencies]; + let args = [...dependencies]; if (installAsDevDependencies) { - args.push('-D'); + args = ['-D', ...args]; } - const commandResult = spawnSync('yarn', args, { stdio: 'inherit' }); - - if (commandResult.status !== 0) { - throw new Error(commandResult.stderr.toString()); - } + this.executeCommand('yarn', ['add', ...args], 'inherit'); } protected runGetVersions( @@ -43,24 +28,12 @@ export class Yarn2Proxy extends JsPackageManager { fetchAllVersions: T ): Promise { const field = fetchAllVersions ? 'versions' : 'version'; + const args = ['--fields', field, '--json']; - const commandResult = spawnSync( - 'yarn', - ['npm', 'info', packageName, '--fields', field, '--json'], - { - cwd: process.cwd(), - env: process.env, - stdio: 'pipe', - encoding: 'utf-8', - } - ); - - if (commandResult.status !== 0) { - throw new Error(commandResult.stderr.toString()); - } + const commandResult = this.executeCommand('yarn', ['npm', 'info', packageName, ...args]); try { - const parsedOutput = JSON.parse(commandResult.stdout.toString()); + const parsedOutput = JSON.parse(commandResult); return parsedOutput[field]; } catch (e) { throw new Error(`Unable to find versions of ${packageName} using yarn 2`); From 26dd11bf60fbbaf1540292c11cc0635954c40b9a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABtan=20Maisse?= Date: Mon, 8 Jun 2020 20:25:49 +0200 Subject: [PATCH 21/22] refactor: move `readPackageJson` and `writePackageJson` in their own helper --- lib/cli/src/add.ts | 11 ++++++---- lib/cli/src/detect.test.ts | 16 +++++++++------ lib/cli/src/detect.ts | 10 +++++----- lib/cli/src/generators/ANGULAR/index.ts | 9 ++------- lib/cli/src/generators/AURELIA/index.ts | 9 ++------- lib/cli/src/generators/EMBER/index.ts | 3 ++- lib/cli/src/generators/HTML/index.ts | 3 ++- lib/cli/src/generators/MARIONETTE/index.ts | 3 ++- lib/cli/src/generators/MARKO/index.ts | 3 ++- lib/cli/src/generators/METEOR/index.ts | 3 ++- lib/cli/src/generators/MITHRIL/index.ts | 3 ++- lib/cli/src/generators/PREACT/index.ts | 3 ++- lib/cli/src/generators/RAX/index.ts | 3 ++- lib/cli/src/generators/REACT/index.ts | 3 ++- lib/cli/src/generators/REACT_NATIVE/index.ts | 4 ++-- lib/cli/src/generators/REACT_SCRIPTS/index.ts | 3 ++- lib/cli/src/generators/RIOT/index.ts | 3 ++- lib/cli/src/generators/SFC_VUE/index.ts | 3 ++- lib/cli/src/generators/SVELTE/index.ts | 3 ++- .../UPDATE_PACKAGE_ORGANIZATIONS/index.ts | 7 +++---- lib/cli/src/generators/VUE/index.ts | 2 +- .../src/generators/WEB-COMPONENTS/index.ts | 3 ++- lib/cli/src/generators/WEBPACK_REACT/index.ts | 3 ++- lib/cli/src/helpers.ts | 20 +------------------ lib/cli/src/initiate.ts | 6 +++--- .../js-package-manager/JsPackageManager.ts | 19 ++++-------------- .../js-package-manager/PackageJsonHelper.ts | 20 +++++++++++++++++++ lib/cli/src/js-package-manager/index.ts | 1 + 28 files changed, 91 insertions(+), 88 deletions(-) create mode 100644 lib/cli/src/js-package-manager/PackageJsonHelper.ts diff --git a/lib/cli/src/add.ts b/lib/cli/src/add.ts index a4bac2a6cfe3..300a23039668 100644 --- a/lib/cli/src/add.ts +++ b/lib/cli/src/add.ts @@ -1,9 +1,8 @@ import path from 'path'; import fs from 'fs'; import { sync as spawnSync } from 'cross-spawn'; -import { commandLog, getPackageJson } from './helpers'; -import { PackageJson } from './js-package-manager/PackageJson'; -import { JsPackageManager, JsPackageManagerFactory } from './js-package-manager'; +import { commandLog } from './helpers'; +import { JsPackageManager, JsPackageManagerFactory, PackageJson } from './js-package-manager'; const logger = console; export const storybookAddonScope = '@storybook/addon-'; @@ -53,7 +52,11 @@ const installAddon = ( prepareDone(); logger.log(); - const packageArg = getPackageArg(addonName, isOfficialAddon, getPackageJson()); + const packageArg = getPackageArg( + addonName, + isOfficialAddon, + packageManager.retrievePackageJson() + ); logger.log(); const installDone = commandLog(`Installing the ${addonName} Storybook addon`); diff --git a/lib/cli/src/detect.test.ts b/lib/cli/src/detect.test.ts index 98bb4a026ffd..ae652a6a00d0 100644 --- a/lib/cli/src/detect.test.ts +++ b/lib/cli/src/detect.test.ts @@ -1,12 +1,16 @@ import fs from 'fs'; -import { getBowerJson, getPackageJson } from './helpers'; +import { getBowerJson } from './helpers'; import { isStorybookInstalled, detectFrameworkPreset, detect, detectLanguage } from './detect'; import { ProjectType, SUPPORTED_FRAMEWORKS, SupportedLanguage } from './project_types'; +import { readPackageJson } from './js-package-manager'; jest.mock('./helpers', () => ({ getBowerJson: jest.fn(), - getPackageJson: jest.fn(), +})); + +jest.mock('./js-package-manager', () => ({ + readPackageJson: jest.fn(), })); jest.mock('fs', () => ({ @@ -209,18 +213,18 @@ const MOCK_FRAMEWORK_FILES = [ describe('Detect', () => { it(`should return type HTML if html option is passed`, () => { - (getPackageJson as jest.Mock).mockImplementation(() => true); + (readPackageJson as jest.Mock).mockImplementation(() => true); expect(detect({ html: true })).toBe(ProjectType.HTML); }); it(`should return type UNDETECTED if neither packageJson or bowerJson exist`, () => { - (getPackageJson as jest.Mock).mockImplementation(() => false); + (readPackageJson as jest.Mock).mockImplementation(() => false); (getBowerJson as jest.Mock).mockImplementation(() => false); expect(detect()).toBe(ProjectType.UNDETECTED); }); it(`should return language typescript if the dependency is present`, () => { - (getPackageJson as jest.Mock).mockImplementation(() => ({ + (readPackageJson as jest.Mock).mockImplementation(() => ({ dependencies: { typescript: '1.0.0', }, @@ -229,7 +233,7 @@ describe('Detect', () => { }); it(`should return language javascript by default`, () => { - (getPackageJson as jest.Mock).mockImplementation(() => true); + (readPackageJson as jest.Mock).mockImplementation(() => true); expect(detectLanguage()).toBe(SupportedLanguage.JAVASCRIPT); }); diff --git a/lib/cli/src/detect.ts b/lib/cli/src/detect.ts index 8d7b64daace2..05528cb8767a 100644 --- a/lib/cli/src/detect.ts +++ b/lib/cli/src/detect.ts @@ -9,8 +9,8 @@ import { TemplateConfiguration, TemplateMatcher, } from './project_types'; -import { getBowerJson, getPackageJson } from './helpers'; -import { PackageJson } from './js-package-manager/PackageJson'; +import { getBowerJson } from './helpers'; +import { PackageJson, readPackageJson } from './js-package-manager'; const hasDependency = (packageJson: PackageJson, name: string) => { return !!packageJson.dependencies?.[name] || !!packageJson.devDependencies?.[name]; @@ -55,7 +55,7 @@ export function detectFrameworkPreset(packageJson = {}) { return result ? result.preset : ProjectType.UNDETECTED; } -export function isStorybookInstalled(dependencies: PackageJson, force?: boolean) { +export function isStorybookInstalled(dependencies: PackageJson | false, force?: boolean) { if (!dependencies) { return false; } @@ -83,7 +83,7 @@ export function isStorybookInstalled(dependencies: PackageJson, force?: boolean) export function detectLanguage() { let language = SupportedLanguage.JAVASCRIPT; - const packageJson = getPackageJson(); + const packageJson = readPackageJson(); const bowerJson = getBowerJson(); if (!packageJson && !bowerJson) { return language; @@ -97,7 +97,7 @@ export function detectLanguage() { } export function detect(options: { force?: boolean; html?: boolean } = {}) { - const packageJson = getPackageJson(); + const packageJson = readPackageJson(); const bowerJson = getBowerJson(); if (!packageJson && !bowerJson) { diff --git a/lib/cli/src/generators/ANGULAR/index.ts b/lib/cli/src/generators/ANGULAR/index.ts index f7feb24a3ed7..ded6299eb15f 100644 --- a/lib/cli/src/generators/ANGULAR/index.ts +++ b/lib/cli/src/generators/ANGULAR/index.ts @@ -5,16 +5,11 @@ import { getAngularAppTsConfigJson, getAngularAppTsConfigPath, } from './angular-helpers'; -import { - writePackageJson, - getBabelDependencies, - writeFileAsJson, - copyTemplate, -} from '../../helpers'; +import { getBabelDependencies, writeFileAsJson, copyTemplate } from '../../helpers'; import { StoryFormat } from '../../project_types'; import { NpmOptions } from '../../NpmOptions'; import { Generator, GeneratorOptions } from '../Generator'; -import { JsPackageManager } from '../../js-package-manager'; +import { JsPackageManager, writePackageJson } from '../../js-package-manager'; async function addDependencies( packageManager: JsPackageManager, diff --git a/lib/cli/src/generators/AURELIA/index.ts b/lib/cli/src/generators/AURELIA/index.ts index ab6b85389805..b1c3a6197947 100644 --- a/lib/cli/src/generators/AURELIA/index.ts +++ b/lib/cli/src/generators/AURELIA/index.ts @@ -1,12 +1,7 @@ -import { - writePackageJson, - getBabelDependencies, - writeFileAsJson, - copyTemplate, - readFileAsJson, -} from '../../helpers'; +import { getBabelDependencies, writeFileAsJson, copyTemplate, readFileAsJson } from '../../helpers'; import { Generator } from '../Generator'; import { StoryFormat } from '../../project_types'; +import { writePackageJson } from '../../js-package-manager'; function addStorybookExcludeGlobToTsConfig() { const tsConfigJson = readFileAsJson('tsconfig.json', true); diff --git a/lib/cli/src/generators/EMBER/index.ts b/lib/cli/src/generators/EMBER/index.ts index d8256d6de73d..be3576407ade 100644 --- a/lib/cli/src/generators/EMBER/index.ts +++ b/lib/cli/src/generators/EMBER/index.ts @@ -1,5 +1,6 @@ -import { writePackageJson, getBabelDependencies, copyTemplate } from '../../helpers'; +import { getBabelDependencies, copyTemplate } from '../../helpers'; import { Generator } from '../Generator'; +import { writePackageJson } from '../../js-package-manager'; const generator: Generator = async (packageManager, npmOptions, { storyFormat }) => { const [ diff --git a/lib/cli/src/generators/HTML/index.ts b/lib/cli/src/generators/HTML/index.ts index d0c74e9ddac7..5b8684f165b9 100755 --- a/lib/cli/src/generators/HTML/index.ts +++ b/lib/cli/src/generators/HTML/index.ts @@ -1,6 +1,7 @@ -import { writePackageJson, getBabelDependencies, copyTemplate } from '../../helpers'; +import { getBabelDependencies, copyTemplate } from '../../helpers'; import { StoryFormat } from '../../project_types'; import { Generator } from '../Generator'; +import { writePackageJson } from '../../js-package-manager'; const generator: Generator = async (packageManager, npmOptions, { storyFormat }) => { const packages = ['@storybook/html', '@storybook/addon-actions', '@storybook/addon-links']; diff --git a/lib/cli/src/generators/MARIONETTE/index.ts b/lib/cli/src/generators/MARIONETTE/index.ts index aaad0fa50f47..3eb86c1f8ae4 100644 --- a/lib/cli/src/generators/MARIONETTE/index.ts +++ b/lib/cli/src/generators/MARIONETTE/index.ts @@ -1,7 +1,8 @@ import fse from 'fs-extra'; import path from 'path'; -import { writePackageJson, getBabelDependencies } from '../../helpers'; +import { getBabelDependencies } from '../../helpers'; import { Generator } from '../Generator'; +import { writePackageJson } from '../../js-package-manager'; const generator: Generator = async (packageManager, npmOptions) => { const storybookVersion = await packageManager.getVersion('@storybook/marionette'); diff --git a/lib/cli/src/generators/MARKO/index.ts b/lib/cli/src/generators/MARKO/index.ts index 16fb753a0638..6f5a91b48264 100644 --- a/lib/cli/src/generators/MARKO/index.ts +++ b/lib/cli/src/generators/MARKO/index.ts @@ -1,5 +1,6 @@ -import { writePackageJson, getBabelDependencies, copyTemplate } from '../../helpers'; +import { getBabelDependencies, copyTemplate } from '../../helpers'; import { Generator } from '../Generator'; +import { writePackageJson } from '../../js-package-manager'; const generator: Generator = async (packageManager, npmOptions, { storyFormat }) => { const [ diff --git a/lib/cli/src/generators/METEOR/index.ts b/lib/cli/src/generators/METEOR/index.ts index e5744031f3e0..e44a102fca69 100644 --- a/lib/cli/src/generators/METEOR/index.ts +++ b/lib/cli/src/generators/METEOR/index.ts @@ -1,7 +1,8 @@ import fs from 'fs'; import JSON5 from 'json5'; -import { writePackageJson, getBabelDependencies, copyTemplate } from '../../helpers'; +import { getBabelDependencies, copyTemplate } from '../../helpers'; import { Generator } from '../Generator'; +import { writePackageJson } from '../../js-package-manager'; const generator: Generator = async (packageManager, npmOptions, { storyFormat }) => { const [ diff --git a/lib/cli/src/generators/MITHRIL/index.ts b/lib/cli/src/generators/MITHRIL/index.ts index a5a9325c9a6c..b90a1a5b837d 100644 --- a/lib/cli/src/generators/MITHRIL/index.ts +++ b/lib/cli/src/generators/MITHRIL/index.ts @@ -1,5 +1,6 @@ -import { writePackageJson, getBabelDependencies, copyTemplate } from '../../helpers'; +import { getBabelDependencies, copyTemplate } from '../../helpers'; import { Generator } from '../Generator'; +import { writePackageJson } from '../../js-package-manager'; const generator: Generator = async (packageManager, npmOptions, { storyFormat }) => { const [ diff --git a/lib/cli/src/generators/PREACT/index.ts b/lib/cli/src/generators/PREACT/index.ts index 3c325c371593..b733d04fa94f 100644 --- a/lib/cli/src/generators/PREACT/index.ts +++ b/lib/cli/src/generators/PREACT/index.ts @@ -1,5 +1,6 @@ -import { writePackageJson, getBabelDependencies, copyTemplate } from '../../helpers'; +import { getBabelDependencies, copyTemplate } from '../../helpers'; import { Generator } from '../Generator'; +import { writePackageJson } from '../../js-package-manager'; const generator: Generator = async (packageManager, npmOptions, { storyFormat }) => { const [ diff --git a/lib/cli/src/generators/RAX/index.ts b/lib/cli/src/generators/RAX/index.ts index 8a5e3689ede0..76c3552db151 100644 --- a/lib/cli/src/generators/RAX/index.ts +++ b/lib/cli/src/generators/RAX/index.ts @@ -1,5 +1,6 @@ -import { writePackageJson, getBabelDependencies, copyTemplate } from '../../helpers'; +import { getBabelDependencies, copyTemplate } from '../../helpers'; import { Generator } from '../Generator'; +import { writePackageJson } from '../../js-package-manager'; const generator: Generator = async (packageManager, npmOptions, { storyFormat }) => { const [ diff --git a/lib/cli/src/generators/REACT/index.ts b/lib/cli/src/generators/REACT/index.ts index 14202faef18a..5fde4ca7af59 100644 --- a/lib/cli/src/generators/REACT/index.ts +++ b/lib/cli/src/generators/REACT/index.ts @@ -1,6 +1,7 @@ -import { writePackageJson, getBabelDependencies, copyTemplate } from '../../helpers'; +import { getBabelDependencies, copyTemplate } from '../../helpers'; import { StoryFormat } from '../../project_types'; import { Generator } from '../Generator'; +import { writePackageJson } from '../../js-package-manager'; const generator: Generator = async (packageManager, npmOptions, { storyFormat }) => { const packages = [ diff --git a/lib/cli/src/generators/REACT_NATIVE/index.ts b/lib/cli/src/generators/REACT_NATIVE/index.ts index 4938527b8e9b..a47856934c78 100644 --- a/lib/cli/src/generators/REACT_NATIVE/index.ts +++ b/lib/cli/src/generators/REACT_NATIVE/index.ts @@ -1,9 +1,9 @@ import shell from 'shelljs'; import chalk from 'chalk'; -import { writePackageJson, paddedLog, getBabelDependencies, copyTemplate } from '../../helpers'; +import { paddedLog, getBabelDependencies, copyTemplate } from '../../helpers'; import { NpmOptions } from '../../NpmOptions'; import { GeneratorOptions } from '../Generator'; -import { JsPackageManager } from '../../js-package-manager'; +import { JsPackageManager, writePackageJson } from '../../js-package-manager'; export default async ( packageManager: JsPackageManager, diff --git a/lib/cli/src/generators/REACT_SCRIPTS/index.ts b/lib/cli/src/generators/REACT_SCRIPTS/index.ts index 8fa81ff1c5fe..776f24156dec 100644 --- a/lib/cli/src/generators/REACT_SCRIPTS/index.ts +++ b/lib/cli/src/generators/REACT_SCRIPTS/index.ts @@ -1,8 +1,9 @@ import path from 'path'; import fs from 'fs'; -import { writePackageJson, getBabelDependencies, copyTemplate } from '../../helpers'; +import { getBabelDependencies, copyTemplate } from '../../helpers'; import { StoryFormat } from '../../project_types'; import { Generator } from '../Generator'; +import { writePackageJson } from '../../js-package-manager'; const generator: Generator = async (packageManager, npmOptions, { storyFormat }) => { const packages = [ diff --git a/lib/cli/src/generators/RIOT/index.ts b/lib/cli/src/generators/RIOT/index.ts index f0335fc6742b..404eb4aeacf6 100644 --- a/lib/cli/src/generators/RIOT/index.ts +++ b/lib/cli/src/generators/RIOT/index.ts @@ -1,5 +1,6 @@ -import { writePackageJson, getBabelDependencies, copyTemplate } from '../../helpers'; +import { getBabelDependencies, copyTemplate } from '../../helpers'; import { Generator } from '../Generator'; +import { writePackageJson } from '../../js-package-manager'; const generator: Generator = async (packageManager, npmOptions, { storyFormat }) => { const [ diff --git a/lib/cli/src/generators/SFC_VUE/index.ts b/lib/cli/src/generators/SFC_VUE/index.ts index b55947f6599f..081f23ab303d 100644 --- a/lib/cli/src/generators/SFC_VUE/index.ts +++ b/lib/cli/src/generators/SFC_VUE/index.ts @@ -1,6 +1,7 @@ -import { writePackageJson, getBabelDependencies, copyTemplate } from '../../helpers'; +import { getBabelDependencies, copyTemplate } from '../../helpers'; import { StoryFormat } from '../../project_types'; import { Generator } from '../Generator'; +import { writePackageJson } from '../../js-package-manager'; const generator: Generator = async (packageManager, npmOptions, { storyFormat }) => { const packages = [ diff --git a/lib/cli/src/generators/SVELTE/index.ts b/lib/cli/src/generators/SVELTE/index.ts index 4025449f86a4..ded5f825eb36 100644 --- a/lib/cli/src/generators/SVELTE/index.ts +++ b/lib/cli/src/generators/SVELTE/index.ts @@ -1,5 +1,6 @@ -import { writePackageJson, getBabelDependencies, copyTemplate } from '../../helpers'; +import { getBabelDependencies, copyTemplate } from '../../helpers'; import { Generator } from '../Generator'; +import { writePackageJson } from '../../js-package-manager'; const generator: Generator = async (packageManager, npmOptions, { storyFormat }) => { const [ diff --git a/lib/cli/src/generators/UPDATE_PACKAGE_ORGANIZATIONS/index.ts b/lib/cli/src/generators/UPDATE_PACKAGE_ORGANIZATIONS/index.ts index d42ede6fd135..0bd448f3f2f5 100644 --- a/lib/cli/src/generators/UPDATE_PACKAGE_ORGANIZATIONS/index.ts +++ b/lib/cli/src/generators/UPDATE_PACKAGE_ORGANIZATIONS/index.ts @@ -2,10 +2,9 @@ import path from 'path'; import { sync as spawnSync } from 'cross-spawn'; import { packageNames } from '@storybook/codemod'; -import { getBabelDependencies, getPackageJson, writePackageJson } from '../../helpers'; -import { PackageJson } from '../../js-package-manager/PackageJson'; +import { getBabelDependencies } from '../../helpers'; import { NpmOptions } from '../../NpmOptions'; -import { JsPackageManager } from '../../js-package-manager'; +import { JsPackageManager, PackageJson, writePackageJson } from '../../js-package-manager'; async function updatePackage( packageManager: JsPackageManager, @@ -20,7 +19,7 @@ async function updatePackage( } async function updatePackageJson(packageManager: JsPackageManager, npmOptions: NpmOptions) { - const packageJson = getPackageJson(); + const packageJson = packageManager.retrievePackageJson(); const { devDependencies } = packageJson; const [actionsVersion, linksVersion] = await packageManager.getVersions( diff --git a/lib/cli/src/generators/VUE/index.ts b/lib/cli/src/generators/VUE/index.ts index 4655bf7d1bd6..9a2e31d10674 100644 --- a/lib/cli/src/generators/VUE/index.ts +++ b/lib/cli/src/generators/VUE/index.ts @@ -1,11 +1,11 @@ import { - writePackageJson, getBabelDependencies, addToDevDependenciesIfNotPresent, copyTemplate, } from '../../helpers'; import { StoryFormat } from '../../project_types'; import { Generator } from '../Generator'; +import { writePackageJson } from '../../js-package-manager'; const generator: Generator = async (packageManager, npmOptions, { storyFormat }) => { const packages = [ diff --git a/lib/cli/src/generators/WEB-COMPONENTS/index.ts b/lib/cli/src/generators/WEB-COMPONENTS/index.ts index 88b525ffe5d6..a8a8c93662f6 100755 --- a/lib/cli/src/generators/WEB-COMPONENTS/index.ts +++ b/lib/cli/src/generators/WEB-COMPONENTS/index.ts @@ -1,8 +1,9 @@ import fse from 'fs-extra'; import path from 'path'; -import { writePackageJson, getBabelDependencies } from '../../helpers'; +import { getBabelDependencies } from '../../helpers'; import { StoryFormat } from '../../project_types'; import { Generator } from '../Generator'; +import { writePackageJson } from '../../js-package-manager'; const generator: Generator = async (packageManager, npmOptions, { storyFormat }) => { const packages = [ diff --git a/lib/cli/src/generators/WEBPACK_REACT/index.ts b/lib/cli/src/generators/WEBPACK_REACT/index.ts index c8585774d071..0447fc15b47d 100644 --- a/lib/cli/src/generators/WEBPACK_REACT/index.ts +++ b/lib/cli/src/generators/WEBPACK_REACT/index.ts @@ -1,6 +1,7 @@ -import { writePackageJson, getBabelDependencies, copyTemplate } from '../../helpers'; +import { getBabelDependencies, copyTemplate } from '../../helpers'; import { StoryFormat } from '../../project_types'; import { Generator } from '../Generator'; +import { writePackageJson } from '../../js-package-manager'; const generator: Generator = async (packageManager, npmOptions, { storyFormat }) => { const packages = [ diff --git a/lib/cli/src/helpers.ts b/lib/cli/src/helpers.ts index b51be53b75a6..4bea186fe075 100644 --- a/lib/cli/src/helpers.ts +++ b/lib/cli/src/helpers.ts @@ -7,21 +7,10 @@ import { satisfies } from '@storybook/semver'; import stripJsonComments from 'strip-json-comments'; import { StoryFormat } from './project_types'; -import { PackageJson } from './js-package-manager/PackageJson'; -import { JsPackageManager } from './js-package-manager'; +import { JsPackageManager, PackageJson } from './js-package-manager'; const logger = console; -export function getPackageJson() { - const packageJsonPath = path.resolve('package.json'); - if (!fs.existsSync(packageJsonPath)) { - return false; - } - - const jsonContent = fs.readFileSync(packageJsonPath, 'utf8'); - return JSON.parse(jsonContent); -} - export function getBowerJson() { const bowerJsonPath = path.resolve('bower.json'); if (!fs.existsSync(bowerJsonPath)) { @@ -53,13 +42,6 @@ export const writeFileAsJson = (jsonPath: string, content: unknown) => { return true; }; -export function writePackageJson(packageJson: object) { - const content = `${JSON.stringify(packageJson, null, 2)}\n`; - const packageJsonPath = path.resolve('package.json'); - - fs.writeFileSync(packageJsonPath, content, 'utf8'); -} - export const commandLog = (message: string) => { process.stdout.write(chalk.cyan(' • ') + message); diff --git a/lib/cli/src/initiate.ts b/lib/cli/src/initiate.ts index 4ddc76d5fa35..a204d606a33f 100644 --- a/lib/cli/src/initiate.ts +++ b/lib/cli/src/initiate.ts @@ -8,7 +8,7 @@ import { StoryFormat, SupportedLanguage, } from './project_types'; -import { commandLog, codeLog, paddedLog, getPackageJson } from './helpers'; +import { commandLog, codeLog, paddedLog } from './helpers'; import angularGenerator from './generators/ANGULAR'; import emberGenerator from './generators/EMBER'; import meteorGenerator from './generators/METEOR'; @@ -29,7 +29,7 @@ import preactGenerator from './generators/PREACT'; import svelteGenerator from './generators/SVELTE'; import raxGenerator from './generators/RAX'; import { warn } from './warn'; -import { JsPackageManagerFactory } from './js-package-manager'; +import { JsPackageManagerFactory, readPackageJson } from './js-package-manager'; import { NpmOptions } from './NpmOptions'; const logger = console; @@ -280,7 +280,7 @@ export default function (options: CommandOptions, pkg: IPackage): Promise try { if (projectTypeProvided) { if (installableProjectTypes.includes(options.type)) { - const storybookInstalled = isStorybookInstalled(getPackageJson(), options.force); + const storybookInstalled = isStorybookInstalled(readPackageJson(), options.force); projectType = storybookInstalled ? ProjectType.ALREADY_HAS_STORYBOOK : options.type.toUpperCase(); diff --git a/lib/cli/src/js-package-manager/JsPackageManager.ts b/lib/cli/src/js-package-manager/JsPackageManager.ts index 286db0ca44fb..40dcc31e1e81 100644 --- a/lib/cli/src/js-package-manager/JsPackageManager.ts +++ b/lib/cli/src/js-package-manager/JsPackageManager.ts @@ -1,10 +1,9 @@ -import path from 'path'; -import fs from 'fs'; import chalk from 'chalk'; import { gt, satisfies } from '@storybook/semver'; import { sync as spawnSync } from 'cross-spawn'; -import { commandLog, writePackageJson } from '../helpers'; +import { commandLog } from '../helpers'; import { PackageJson } from './PackageJson'; +import { readPackageJson, writePackageJson } from './PackageJsonHelper'; const logger = console; // Cannot be `import` as it's not under TS root dir @@ -36,7 +35,7 @@ export abstract class JsPackageManager { } public retrievePackageJson(): PackageJson { - const existing = JsPackageManager.getPackageJson(); + const existing = readPackageJson(); if (existing) { return existing; } @@ -45,7 +44,7 @@ export abstract class JsPackageManager { this.initPackageJson(); // read the newly created package.json file - return JsPackageManager.getPackageJson() || {}; + return readPackageJson() || {}; } /** @@ -213,16 +212,6 @@ export abstract class JsPackageManager { ): // Use generic and conditional type to force `string[]` if fetchAllVersions is true and `string` if false Promise; - private static getPackageJson(): PackageJson | false { - const packageJsonPath = path.resolve('package.json'); - if (!fs.existsSync(packageJsonPath)) { - return false; - } - - const jsonContent = fs.readFileSync(packageJsonPath, 'utf8'); - return JSON.parse(jsonContent); - } - public executeCommand(command: string, args: string[], stdio?: 'pipe' | 'inherit'): string { const commandResult = spawnSync(command, args, { stdio: stdio ?? 'pipe', diff --git a/lib/cli/src/js-package-manager/PackageJsonHelper.ts b/lib/cli/src/js-package-manager/PackageJsonHelper.ts new file mode 100644 index 000000000000..17fa72935f0e --- /dev/null +++ b/lib/cli/src/js-package-manager/PackageJsonHelper.ts @@ -0,0 +1,20 @@ +import path from 'path'; +import fs from 'fs'; +import { PackageJson } from './PackageJson'; + +export function readPackageJson(): PackageJson | false { + const packageJsonPath = path.resolve('package.json'); + if (!fs.existsSync(packageJsonPath)) { + return false; + } + + const jsonContent = fs.readFileSync(packageJsonPath, 'utf8'); + return JSON.parse(jsonContent); +} + +export function writePackageJson(packageJson: PackageJson) { + const content = `${JSON.stringify(packageJson, null, 2)}\n`; + const packageJsonPath = path.resolve('package.json'); + + fs.writeFileSync(packageJsonPath, content, 'utf8'); +} diff --git a/lib/cli/src/js-package-manager/index.ts b/lib/cli/src/js-package-manager/index.ts index 3a2b877d5030..13cc52f4ed04 100644 --- a/lib/cli/src/js-package-manager/index.ts +++ b/lib/cli/src/js-package-manager/index.ts @@ -1,3 +1,4 @@ export * from './JsPackageManagerFactory'; export * from './JsPackageManager'; export * from './PackageJson'; +export * from './PackageJsonHelper'; From 9dc7c554f45b224c3a1d360da4b6bc5e628995db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABtan=20Maisse?= Date: Mon, 8 Jun 2020 20:49:31 +0200 Subject: [PATCH 22/22] refactor: ensure `dep` and `devDeps` are always defined when retrieving `package.json` Doing this just after having read the file enable us to remove duplication and unneeded calls to `writePackageJson`. --- lib/cli/src/generators/ANGULAR/index.ts | 7 +----- lib/cli/src/generators/AURELIA/index.ts | 4 ---- lib/cli/src/generators/EMBER/index.ts | 7 ------ lib/cli/src/generators/HTML/index.ts | 5 ---- lib/cli/src/generators/MARIONETTE/index.ts | 6 ----- lib/cli/src/generators/MARKO/index.ts | 6 ----- lib/cli/src/generators/METEOR/index.ts | 3 --- lib/cli/src/generators/MITHRIL/index.ts | 6 ----- lib/cli/src/generators/PREACT/index.ts | 6 ----- lib/cli/src/generators/RAX/index.ts | 3 --- lib/cli/src/generators/REACT/index.ts | 6 ----- lib/cli/src/generators/REACT_SCRIPTS/index.ts | 6 ----- lib/cli/src/generators/SFC_VUE/index.ts | 6 ----- lib/cli/src/generators/SVELTE/index.ts | 6 ----- lib/cli/src/generators/VUE/index.ts | 3 --- .../src/generators/WEB-COMPONENTS/index.ts | 6 ----- lib/cli/src/generators/WEBPACK_REACT/index.ts | 6 ----- lib/cli/src/helpers.ts | 4 ++-- .../js-package-manager/JsPackageManager.ts | 24 +++++++++++-------- lib/cli/src/js-package-manager/PackageJson.ts | 3 +++ 20 files changed, 20 insertions(+), 103 deletions(-) diff --git a/lib/cli/src/generators/ANGULAR/index.ts b/lib/cli/src/generators/ANGULAR/index.ts index ded6299eb15f..9ab5196a0192 100644 --- a/lib/cli/src/generators/ANGULAR/index.ts +++ b/lib/cli/src/generators/ANGULAR/index.ts @@ -9,7 +9,7 @@ import { getBabelDependencies, writeFileAsJson, copyTemplate } from '../../helpe import { StoryFormat } from '../../project_types'; import { NpmOptions } from '../../NpmOptions'; import { Generator, GeneratorOptions } from '../Generator'; -import { JsPackageManager, writePackageJson } from '../../js-package-manager'; +import { JsPackageManager } from '../../js-package-manager'; async function addDependencies( packageManager: JsPackageManager, @@ -31,11 +31,6 @@ async function addDependencies( const packageJson = packageManager.retrievePackageJson(); - packageJson.dependencies = packageJson.dependencies || {}; - packageJson.devDependencies = packageJson.devDependencies || {}; - - writePackageJson(packageJson); - const babelDependencies = await getBabelDependencies(packageManager, packageJson); packageManager.addDependencies({ ...npmOptions, packageJson }, [ diff --git a/lib/cli/src/generators/AURELIA/index.ts b/lib/cli/src/generators/AURELIA/index.ts index b1c3a6197947..04ec62b89ed8 100644 --- a/lib/cli/src/generators/AURELIA/index.ts +++ b/lib/cli/src/generators/AURELIA/index.ts @@ -1,7 +1,6 @@ import { getBabelDependencies, writeFileAsJson, copyTemplate, readFileAsJson } from '../../helpers'; import { Generator } from '../Generator'; import { StoryFormat } from '../../project_types'; -import { writePackageJson } from '../../js-package-manager'; function addStorybookExcludeGlobToTsConfig() { const tsConfigJson = readFileAsJson('tsconfig.json', true); @@ -43,9 +42,6 @@ const generator: Generator = async ( const versionedPackages = await packageManager.getVersionedPackages(...packages); const packageJson = packageManager.retrievePackageJson(); - packageJson.dependencies = packageJson.dependencies || {}; - packageJson.devDependencies = packageJson.devDependencies || {}; - writePackageJson(packageJson); addStorybookExcludeGlobToTsConfig(); const babelDependencies = await getBabelDependencies(packageManager, packageJson); packageManager.addDependencies({ ...npmOptions, packageJson }, [ diff --git a/lib/cli/src/generators/EMBER/index.ts b/lib/cli/src/generators/EMBER/index.ts index be3576407ade..36fb1c1ef533 100644 --- a/lib/cli/src/generators/EMBER/index.ts +++ b/lib/cli/src/generators/EMBER/index.ts @@ -1,6 +1,5 @@ import { getBabelDependencies, copyTemplate } from '../../helpers'; import { Generator } from '../Generator'; -import { writePackageJson } from '../../js-package-manager'; const generator: Generator = async (packageManager, npmOptions, { storyFormat }) => { const [ @@ -24,12 +23,6 @@ const generator: Generator = async (packageManager, npmOptions, { storyFormat }) copyTemplate(__dirname, storyFormat); const packageJson = packageManager.retrievePackageJson(); - - packageJson.dependencies = packageJson.dependencies || {}; - packageJson.devDependencies = packageJson.devDependencies || {}; - - writePackageJson(packageJson); - const babelDependencies = await getBabelDependencies(packageManager, packageJson); packageManager.addDependencies({ ...npmOptions, packageJson }, [ diff --git a/lib/cli/src/generators/HTML/index.ts b/lib/cli/src/generators/HTML/index.ts index 5b8684f165b9..eb96ae0ff49f 100755 --- a/lib/cli/src/generators/HTML/index.ts +++ b/lib/cli/src/generators/HTML/index.ts @@ -1,7 +1,6 @@ import { getBabelDependencies, copyTemplate } from '../../helpers'; import { StoryFormat } from '../../project_types'; import { Generator } from '../Generator'; -import { writePackageJson } from '../../js-package-manager'; const generator: Generator = async (packageManager, npmOptions, { storyFormat }) => { const packages = ['@storybook/html', '@storybook/addon-actions', '@storybook/addon-links']; @@ -14,10 +13,6 @@ const generator: Generator = async (packageManager, npmOptions, { storyFormat }) copyTemplate(__dirname, storyFormat); const packageJson = packageManager.retrievePackageJson(); - packageJson.dependencies = packageJson.dependencies || {}; - packageJson.devDependencies = packageJson.devDependencies || {}; - writePackageJson(packageJson); - const babelDependencies = await getBabelDependencies(packageManager, packageJson); packageManager.addDependencies({ ...npmOptions, packageJson }, [ ...versionedPackages, diff --git a/lib/cli/src/generators/MARIONETTE/index.ts b/lib/cli/src/generators/MARIONETTE/index.ts index 3eb86c1f8ae4..c29c891b00ed 100644 --- a/lib/cli/src/generators/MARIONETTE/index.ts +++ b/lib/cli/src/generators/MARIONETTE/index.ts @@ -2,7 +2,6 @@ import fse from 'fs-extra'; import path from 'path'; import { getBabelDependencies } from '../../helpers'; import { Generator } from '../Generator'; -import { writePackageJson } from '../../js-package-manager'; const generator: Generator = async (packageManager, npmOptions) => { const storybookVersion = await packageManager.getVersion('@storybook/marionette'); @@ -10,11 +9,6 @@ const generator: Generator = async (packageManager, npmOptions) => { const packageJson = packageManager.retrievePackageJson(); - packageJson.dependencies = packageJson.dependencies || {}; - packageJson.devDependencies = packageJson.devDependencies || {}; - - writePackageJson(packageJson); - const babelDependencies = await getBabelDependencies(packageManager, packageJson); packageManager.addDependencies({ ...npmOptions, packageJson }, [ diff --git a/lib/cli/src/generators/MARKO/index.ts b/lib/cli/src/generators/MARKO/index.ts index 6f5a91b48264..f28c62ff86d1 100644 --- a/lib/cli/src/generators/MARKO/index.ts +++ b/lib/cli/src/generators/MARKO/index.ts @@ -1,6 +1,5 @@ import { getBabelDependencies, copyTemplate } from '../../helpers'; import { Generator } from '../Generator'; -import { writePackageJson } from '../../js-package-manager'; const generator: Generator = async (packageManager, npmOptions, { storyFormat }) => { const [ @@ -17,11 +16,6 @@ const generator: Generator = async (packageManager, npmOptions, { storyFormat }) const packageJson = packageManager.retrievePackageJson(); - packageJson.dependencies = packageJson.dependencies || {}; - packageJson.devDependencies = packageJson.devDependencies || {}; - - writePackageJson(packageJson); - const babelDependencies = await getBabelDependencies(packageManager, packageJson); packageManager.addDependencies({ ...npmOptions, packageJson }, [ diff --git a/lib/cli/src/generators/METEOR/index.ts b/lib/cli/src/generators/METEOR/index.ts index e44a102fca69..95ae01834906 100644 --- a/lib/cli/src/generators/METEOR/index.ts +++ b/lib/cli/src/generators/METEOR/index.ts @@ -31,9 +31,6 @@ const generator: Generator = async (packageManager, npmOptions, { storyFormat }) const packageJson = packageManager.retrievePackageJson(); - packageJson.devDependencies = packageJson.devDependencies || {}; - packageJson.dependencies = packageJson.dependencies || {}; - const devDependencies = [ `@storybook/react@${storybookVersion}`, `@storybook/addon-actions@${actionsVersion}`, diff --git a/lib/cli/src/generators/MITHRIL/index.ts b/lib/cli/src/generators/MITHRIL/index.ts index b90a1a5b837d..329b521c9d7f 100644 --- a/lib/cli/src/generators/MITHRIL/index.ts +++ b/lib/cli/src/generators/MITHRIL/index.ts @@ -1,6 +1,5 @@ import { getBabelDependencies, copyTemplate } from '../../helpers'; import { Generator } from '../Generator'; -import { writePackageJson } from '../../js-package-manager'; const generator: Generator = async (packageManager, npmOptions, { storyFormat }) => { const [ @@ -21,11 +20,6 @@ const generator: Generator = async (packageManager, npmOptions, { storyFormat }) const packageJson = packageManager.retrievePackageJson(); - packageJson.dependencies = packageJson.dependencies || {}; - packageJson.devDependencies = packageJson.devDependencies || {}; - - writePackageJson(packageJson); - const babelDependencies = await getBabelDependencies(packageManager, packageJson); packageManager.addDependencies({ ...npmOptions, packageJson }, [ diff --git a/lib/cli/src/generators/PREACT/index.ts b/lib/cli/src/generators/PREACT/index.ts index b733d04fa94f..f6ceceac04d8 100644 --- a/lib/cli/src/generators/PREACT/index.ts +++ b/lib/cli/src/generators/PREACT/index.ts @@ -1,6 +1,5 @@ import { getBabelDependencies, copyTemplate } from '../../helpers'; import { Generator } from '../Generator'; -import { writePackageJson } from '../../js-package-manager'; const generator: Generator = async (packageManager, npmOptions, { storyFormat }) => { const [ @@ -19,11 +18,6 @@ const generator: Generator = async (packageManager, npmOptions, { storyFormat }) const packageJson = packageManager.retrievePackageJson(); - packageJson.dependencies = packageJson.dependencies || {}; - packageJson.devDependencies = packageJson.devDependencies || {}; - - writePackageJson(packageJson); - const babelDependencies = await getBabelDependencies(packageManager, packageJson); packageManager.addDependencies({ ...npmOptions, packageJson }, [ diff --git a/lib/cli/src/generators/RAX/index.ts b/lib/cli/src/generators/RAX/index.ts index 76c3552db151..ed0b4bdfa3cb 100644 --- a/lib/cli/src/generators/RAX/index.ts +++ b/lib/cli/src/generators/RAX/index.ts @@ -21,9 +21,6 @@ const generator: Generator = async (packageManager, npmOptions, { storyFormat }) const packageJson = packageManager.retrievePackageJson(); - packageJson.dependencies = packageJson.dependencies || {}; - packageJson.devDependencies = packageJson.devDependencies || {}; - const raxVersion = packageJson.dependencies.rax || latestRaxVersion; // in case Rax project is not detected, `rax` package is not available either diff --git a/lib/cli/src/generators/REACT/index.ts b/lib/cli/src/generators/REACT/index.ts index 5fde4ca7af59..2a6606bc4d2b 100644 --- a/lib/cli/src/generators/REACT/index.ts +++ b/lib/cli/src/generators/REACT/index.ts @@ -1,7 +1,6 @@ import { getBabelDependencies, copyTemplate } from '../../helpers'; import { StoryFormat } from '../../project_types'; import { Generator } from '../Generator'; -import { writePackageJson } from '../../js-package-manager'; const generator: Generator = async (packageManager, npmOptions, { storyFormat }) => { const packages = [ @@ -20,11 +19,6 @@ const generator: Generator = async (packageManager, npmOptions, { storyFormat }) const packageJson = packageManager.retrievePackageJson(); - packageJson.dependencies = packageJson.dependencies || {}; - packageJson.devDependencies = packageJson.devDependencies || {}; - - writePackageJson(packageJson); - const babelDependencies = await getBabelDependencies(packageManager, packageJson); packageManager.addDependencies({ ...npmOptions, packageJson }, [ diff --git a/lib/cli/src/generators/REACT_SCRIPTS/index.ts b/lib/cli/src/generators/REACT_SCRIPTS/index.ts index 776f24156dec..bba68ba18b73 100644 --- a/lib/cli/src/generators/REACT_SCRIPTS/index.ts +++ b/lib/cli/src/generators/REACT_SCRIPTS/index.ts @@ -3,7 +3,6 @@ import fs from 'fs'; import { getBabelDependencies, copyTemplate } from '../../helpers'; import { StoryFormat } from '../../project_types'; import { Generator } from '../Generator'; -import { writePackageJson } from '../../js-package-manager'; const generator: Generator = async (packageManager, npmOptions, { storyFormat }) => { const packages = [ @@ -24,11 +23,6 @@ const generator: Generator = async (packageManager, npmOptions, { storyFormat }) const packageJson = packageManager.retrievePackageJson(); - packageJson.dependencies = packageJson.dependencies || {}; - packageJson.devDependencies = packageJson.devDependencies || {}; - - writePackageJson(packageJson); - const babelDependencies = await getBabelDependencies(packageManager, packageJson); packageManager.addDependencies({ ...npmOptions, packageJson }, [ diff --git a/lib/cli/src/generators/SFC_VUE/index.ts b/lib/cli/src/generators/SFC_VUE/index.ts index 081f23ab303d..df945f683faa 100644 --- a/lib/cli/src/generators/SFC_VUE/index.ts +++ b/lib/cli/src/generators/SFC_VUE/index.ts @@ -1,7 +1,6 @@ import { getBabelDependencies, copyTemplate } from '../../helpers'; import { StoryFormat } from '../../project_types'; import { Generator } from '../Generator'; -import { writePackageJson } from '../../js-package-manager'; const generator: Generator = async (packageManager, npmOptions, { storyFormat }) => { const packages = [ @@ -19,11 +18,6 @@ const generator: Generator = async (packageManager, npmOptions, { storyFormat }) const packageJson = packageManager.retrievePackageJson(); - packageJson.dependencies = packageJson.dependencies || {}; - packageJson.devDependencies = packageJson.devDependencies || {}; - - writePackageJson(packageJson); - const babelDependencies = await getBabelDependencies(packageManager, packageJson); packageManager.addDependencies({ ...npmOptions, packageJson }, [ diff --git a/lib/cli/src/generators/SVELTE/index.ts b/lib/cli/src/generators/SVELTE/index.ts index ded5f825eb36..646e234961c6 100644 --- a/lib/cli/src/generators/SVELTE/index.ts +++ b/lib/cli/src/generators/SVELTE/index.ts @@ -1,6 +1,5 @@ import { getBabelDependencies, copyTemplate } from '../../helpers'; import { Generator } from '../Generator'; -import { writePackageJson } from '../../js-package-manager'; const generator: Generator = async (packageManager, npmOptions, { storyFormat }) => { const [ @@ -23,11 +22,6 @@ const generator: Generator = async (packageManager, npmOptions, { storyFormat }) const packageJson = packageManager.retrievePackageJson(); - packageJson.dependencies = packageJson.dependencies || {}; - packageJson.devDependencies = packageJson.devDependencies || {}; - - writePackageJson(packageJson); - const babelDependencies = await getBabelDependencies(packageManager, packageJson); packageManager.addDependencies({ ...npmOptions, packageJson }, [ diff --git a/lib/cli/src/generators/VUE/index.ts b/lib/cli/src/generators/VUE/index.ts index 9a2e31d10674..0efb2d56bb0f 100644 --- a/lib/cli/src/generators/VUE/index.ts +++ b/lib/cli/src/generators/VUE/index.ts @@ -24,9 +24,6 @@ const generator: Generator = async (packageManager, npmOptions, { storyFormat }) const packageJson = packageManager.retrievePackageJson(); - packageJson.dependencies = packageJson.dependencies || {}; - packageJson.devDependencies = packageJson.devDependencies || {}; - const packageBabelCoreVersion = packageJson.dependencies['babel-core'] || packageJson.devDependencies['babel-core']; diff --git a/lib/cli/src/generators/WEB-COMPONENTS/index.ts b/lib/cli/src/generators/WEB-COMPONENTS/index.ts index a8a8c93662f6..03ced0f5e0c3 100755 --- a/lib/cli/src/generators/WEB-COMPONENTS/index.ts +++ b/lib/cli/src/generators/WEB-COMPONENTS/index.ts @@ -3,7 +3,6 @@ import path from 'path'; import { getBabelDependencies } from '../../helpers'; import { StoryFormat } from '../../project_types'; import { Generator } from '../Generator'; -import { writePackageJson } from '../../js-package-manager'; const generator: Generator = async (packageManager, npmOptions, { storyFormat }) => { const packages = [ @@ -23,11 +22,6 @@ const generator: Generator = async (packageManager, npmOptions, { storyFormat }) const packageJson = packageManager.retrievePackageJson(); - packageJson.dependencies = packageJson.dependencies || {}; - packageJson.devDependencies = packageJson.devDependencies || {}; - - writePackageJson(packageJson); - const babelDependencies = await getBabelDependencies(packageManager, packageJson); packageManager.addDependencies({ ...npmOptions, packageJson }, [ diff --git a/lib/cli/src/generators/WEBPACK_REACT/index.ts b/lib/cli/src/generators/WEBPACK_REACT/index.ts index 0447fc15b47d..5c030def1ee4 100644 --- a/lib/cli/src/generators/WEBPACK_REACT/index.ts +++ b/lib/cli/src/generators/WEBPACK_REACT/index.ts @@ -1,7 +1,6 @@ import { getBabelDependencies, copyTemplate } from '../../helpers'; import { StoryFormat } from '../../project_types'; import { Generator } from '../Generator'; -import { writePackageJson } from '../../js-package-manager'; const generator: Generator = async (packageManager, npmOptions, { storyFormat }) => { const packages = [ @@ -19,11 +18,6 @@ const generator: Generator = async (packageManager, npmOptions, { storyFormat }) const packageJson = packageManager.retrievePackageJson(); - packageJson.dependencies = packageJson.dependencies || {}; - packageJson.devDependencies = packageJson.devDependencies || {}; - - writePackageJson(packageJson); - const babelDependencies = await getBabelDependencies(packageManager, packageJson); packageManager.addDependencies({ ...npmOptions, packageJson }, [ diff --git a/lib/cli/src/helpers.ts b/lib/cli/src/helpers.ts index 4bea186fe075..9f32d3c4facc 100644 --- a/lib/cli/src/helpers.ts +++ b/lib/cli/src/helpers.ts @@ -7,7 +7,7 @@ import { satisfies } from '@storybook/semver'; import stripJsonComments from 'strip-json-comments'; import { StoryFormat } from './project_types'; -import { JsPackageManager, PackageJson } from './js-package-manager'; +import { JsPackageManager, PackageJson, PackageJsonWithDepsAndDevDeps } from './js-package-manager'; const logger = console; @@ -118,7 +118,7 @@ export function codeLog(codeLines: string[], leftPadAmount?: number) { */ export async function getBabelDependencies( packageManager: JsPackageManager, - packageJson: PackageJson + packageJson: PackageJsonWithDepsAndDevDeps ) { const dependenciesToAdd = []; let babelLoaderVersion = '^8.0.0-0'; diff --git a/lib/cli/src/js-package-manager/JsPackageManager.ts b/lib/cli/src/js-package-manager/JsPackageManager.ts index 40dcc31e1e81..eeb52bfa4be7 100644 --- a/lib/cli/src/js-package-manager/JsPackageManager.ts +++ b/lib/cli/src/js-package-manager/JsPackageManager.ts @@ -2,7 +2,7 @@ import chalk from 'chalk'; import { gt, satisfies } from '@storybook/semver'; import { sync as spawnSync } from 'cross-spawn'; import { commandLog } from '../helpers'; -import { PackageJson } from './PackageJson'; +import { PackageJson, PackageJsonWithDepsAndDevDeps } from './PackageJson'; import { readPackageJson, writePackageJson } from './PackageJsonHelper'; const logger = console; @@ -34,17 +34,21 @@ export abstract class JsPackageManager { done(); } - public retrievePackageJson(): PackageJson { - const existing = readPackageJson(); - if (existing) { - return existing; - } + public retrievePackageJson(): PackageJsonWithDepsAndDevDeps { + let packageJson = readPackageJson(); + if (!packageJson) { + // It will create a new package.json file + this.initPackageJson(); - // It will create a new package.json file - this.initPackageJson(); + // read the newly created package.json file + packageJson = readPackageJson() || {}; + } - // read the newly created package.json file - return readPackageJson() || {}; + return { + ...packageJson, + dependencies: { ...packageJson.dependencies }, + devDependencies: { ...packageJson.devDependencies }, + }; } /** diff --git a/lib/cli/src/js-package-manager/PackageJson.ts b/lib/cli/src/js-package-manager/PackageJson.ts index d2313640227d..3a1cf2c9d2a1 100644 --- a/lib/cli/src/js-package-manager/PackageJson.ts +++ b/lib/cli/src/js-package-manager/PackageJson.ts @@ -4,3 +4,6 @@ export type PackageJson = { peerDependencies?: Record; scripts?: Record; }; + +export type PackageJsonWithDepsAndDevDeps = PackageJson & + Required>;