From 77bf6136749a7572855108707466d9952eafd536 Mon Sep 17 00:00:00 2001 From: Yann Braga Date: Tue, 16 Aug 2022 10:36:46 +0200 Subject: [PATCH 01/41] refactor: move write/read package json into JsPackageManager --- .../cli/src/automigrate/fixes/builder-vite.ts | 4 +-- code/lib/cli/src/detect.test.ts | 17 +++++----- code/lib/cli/src/detect.ts | 27 ++++------------ code/lib/cli/src/generators/RAX/index.ts | 3 +- code/lib/cli/src/initiate.ts | 11 +++++-- .../js-package-manager/JsPackageManager.ts | 32 +++++++++++++++---- .../src/js-package-manager/NPMProxy.test.ts | 3 +- .../js-package-manager/PackageJsonHelper.ts | 20 ------------ .../src/js-package-manager/Yarn1Proxy.test.ts | 3 +- .../src/js-package-manager/Yarn2Proxy.test.ts | 3 +- code/lib/cli/src/js-package-manager/index.ts | 1 - 11 files changed, 56 insertions(+), 68 deletions(-) delete mode 100644 code/lib/cli/src/js-package-manager/PackageJsonHelper.ts diff --git a/code/lib/cli/src/automigrate/fixes/builder-vite.ts b/code/lib/cli/src/automigrate/fixes/builder-vite.ts index df264724180e..05d15aa1a36f 100644 --- a/code/lib/cli/src/automigrate/fixes/builder-vite.ts +++ b/code/lib/cli/src/automigrate/fixes/builder-vite.ts @@ -5,7 +5,7 @@ import { ConfigFile, readConfig, writeConfig } from '@storybook/csf-tools'; import { getStorybookInfo } from '@storybook/core-common'; import { Fix } from '../types'; -import { PackageJson, writePackageJson } from '../../js-package-manager'; +import { PackageJson } from '../../js-package-manager'; const logger = console; @@ -70,7 +70,7 @@ export const builderVite: Fix = { if (!dryRun) { delete dependencies['storybook-builder-vite']; delete devDependencies['storybook-builder-vite']; - writePackageJson(packageJson); + packageManager.writePackageJson(packageJson); } logger.info(`Adding '@storybook/builder-vite' as dev dependency`); diff --git a/code/lib/cli/src/detect.test.ts b/code/lib/cli/src/detect.test.ts index 9d83e30be6bb..6caf23f682e3 100644 --- a/code/lib/cli/src/detect.test.ts +++ b/code/lib/cli/src/detect.test.ts @@ -275,22 +275,23 @@ const MOCK_FRAMEWORK_FILES: { describe('Detect', () => { it(`should return type HTML if html option is passed`, () => { (readPackageJson as jest.Mock).mockImplementation(() => true); - expect(detect({ html: true })).toBe(ProjectType.HTML); + expect(detect({ dependencies: {} }, { html: true })).toBe(ProjectType.HTML); }); it(`should return type UNDETECTED if neither packageJson or bowerJson exist`, () => { (readPackageJson as jest.Mock).mockImplementation(() => false); (getBowerJson as jest.Mock).mockImplementation(() => false); - expect(detect()).toBe(ProjectType.UNDETECTED); + expect(detect(undefined)).toBe(ProjectType.UNDETECTED); }); it(`should return language typescript if the dependency is present`, () => { - (readPackageJson as jest.Mock).mockImplementation(() => ({ - dependencies: { - typescript: '1.0.0', - }, - })); - expect(detectLanguage()).toBe(SupportedLanguage.TYPESCRIPT); + expect( + detectLanguage({ + dependencies: { + typescript: '1.0.0', + }, + }) + ).toBe(SupportedLanguage.TYPESCRIPT); }); it(`should return language javascript by default`, () => { diff --git a/code/lib/cli/src/detect.ts b/code/lib/cli/src/detect.ts index d6b5269db697..cf207cc08130 100644 --- a/code/lib/cli/src/detect.ts +++ b/code/lib/cli/src/detect.ts @@ -13,12 +13,7 @@ import { CoreBuilder, } from './project_types'; import { getBowerJson, paddedLog } from './helpers'; -import { - PackageJson, - readPackageJson, - JsPackageManager, - PackageJsonWithMaybeDeps, -} from './js-package-manager'; +import { PackageJson, JsPackageManager, PackageJsonWithMaybeDeps } from './js-package-manager'; import { detectNextJS } from './detect-nextjs'; const viteConfigFiles = ['vite.config.ts', 'vite.config.js', 'vite.config.mjs']; @@ -153,14 +148,9 @@ export function isStorybookInstalled( return false; } -export function detectLanguage() { +export function detectLanguage(packageJson?: PackageJson) { let language = SupportedLanguage.JAVASCRIPT; - let packageJson; - try { - packageJson = readPackageJson(); - } catch (err) { - // - } + const bowerJson = getBowerJson(); if (!packageJson && !bowerJson) { return language; @@ -173,13 +163,10 @@ export function detectLanguage() { return language; } -export function detect(options: { force?: boolean; html?: boolean } = {}) { - let packageJson; - try { - packageJson = readPackageJson(); - } catch (err) { - // - } +export function detect( + packageJson: PackageJson, + options: { force?: boolean; html?: boolean } = {} +) { const bowerJson = getBowerJson(); if (!packageJson && !bowerJson) { diff --git a/code/lib/cli/src/generators/RAX/index.ts b/code/lib/cli/src/generators/RAX/index.ts index 82230e673a20..02ce74816455 100644 --- a/code/lib/cli/src/generators/RAX/index.ts +++ b/code/lib/cli/src/generators/RAX/index.ts @@ -1,6 +1,5 @@ import { baseGenerator } from '../baseGenerator'; import { Generator } from '../types'; -import { writePackageJson } from '../../js-package-manager'; const generator: Generator = async (packageManager, npmOptions, options) => { const [latestRaxVersion] = await packageManager.getVersions('rax'); @@ -17,7 +16,7 @@ const generator: Generator = async (packageManager, npmOptions, options) => { packageJson.dependencies['rax-text'] = packageJson.dependencies['rax-text'] || raxVersion; packageJson.dependencies['rax-view'] = packageJson.dependencies['rax-view'] || raxVersion; - writePackageJson(packageJson); + packageManager.writePackageJson(packageJson); await baseGenerator(packageManager, npmOptions, options, 'rax', { extraPackages: ['rax'], diff --git a/code/lib/cli/src/initiate.ts b/code/lib/cli/src/initiate.ts index 7887e91d879e..c3c60308856e 100644 --- a/code/lib/cli/src/initiate.ts +++ b/code/lib/cli/src/initiate.ts @@ -42,7 +42,14 @@ const installStorybook = ( skipInstall: options.skipInstall, }; - const language = detectLanguage(); + let packageJson; + try { + packageJson = packageManager.readPackageJson(); + } catch (err) { + // + } + + const language = detectLanguage(packageJson); const generatorOptions = { language, @@ -283,7 +290,7 @@ export async function initiate(options: CommandOptions, pkg: Package): Promise) { const packageJson = this.retrievePackageJson(); - writePackageJson({ + this.writePackageJson({ ...packageJson, scripts: { ...packageJson.scripts, diff --git a/code/lib/cli/src/js-package-manager/NPMProxy.test.ts b/code/lib/cli/src/js-package-manager/NPMProxy.test.ts index 789e1f6ee53e..e04fea08cc69 100644 --- a/code/lib/cli/src/js-package-manager/NPMProxy.test.ts +++ b/code/lib/cli/src/js-package-manager/NPMProxy.test.ts @@ -1,5 +1,4 @@ import { NPMProxy } from './NPMProxy'; -import * as PackageJsonHelper from './PackageJsonHelper'; describe('NPM Proxy', () => { let npmProxy: NPMProxy; @@ -107,7 +106,7 @@ describe('NPM Proxy', () => { it('should only change package.json without running install', () => { const executeCommandSpy = jest.spyOn(npmProxy, 'executeCommand').mockReturnValue('7.0.0'); const writePackageSpy = jest - .spyOn(PackageJsonHelper, 'writePackageJson') + .spyOn(npmProxy, 'writePackageJson') .mockImplementation(jest.fn); npmProxy.removeDependencies( diff --git a/code/lib/cli/src/js-package-manager/PackageJsonHelper.ts b/code/lib/cli/src/js-package-manager/PackageJsonHelper.ts deleted file mode 100644 index e013783745e4..000000000000 --- a/code/lib/cli/src/js-package-manager/PackageJsonHelper.ts +++ /dev/null @@ -1,20 +0,0 @@ -import path from 'path'; -import fs from 'fs'; -import type { PackageJson } from '@storybook/core-common'; - -export function readPackageJson(): PackageJson { - const packageJsonPath = path.resolve('package.json'); - if (!fs.existsSync(packageJsonPath)) { - throw new Error(`Could not read package.json file at ${packageJsonPath}`); - } - - 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/code/lib/cli/src/js-package-manager/Yarn1Proxy.test.ts b/code/lib/cli/src/js-package-manager/Yarn1Proxy.test.ts index c6655cd597bb..a95f74e1ed13 100644 --- a/code/lib/cli/src/js-package-manager/Yarn1Proxy.test.ts +++ b/code/lib/cli/src/js-package-manager/Yarn1Proxy.test.ts @@ -1,5 +1,4 @@ import { Yarn1Proxy } from './Yarn1Proxy'; -import * as PackageJsonHelper from './PackageJsonHelper'; describe('Yarn 1 Proxy', () => { let yarn1Proxy: Yarn1Proxy; @@ -62,7 +61,7 @@ describe('Yarn 1 Proxy', () => { it('skipInstall should only change package.json without running install', () => { const executeCommandSpy = jest.spyOn(yarn1Proxy, 'executeCommand').mockReturnValue('7.0.0'); const writePackageSpy = jest - .spyOn(PackageJsonHelper, 'writePackageJson') + .spyOn(yarn1Proxy, 'writePackageJson') .mockImplementation(jest.fn); yarn1Proxy.removeDependencies( diff --git a/code/lib/cli/src/js-package-manager/Yarn2Proxy.test.ts b/code/lib/cli/src/js-package-manager/Yarn2Proxy.test.ts index 30c90f9be32b..09798191699f 100644 --- a/code/lib/cli/src/js-package-manager/Yarn2Proxy.test.ts +++ b/code/lib/cli/src/js-package-manager/Yarn2Proxy.test.ts @@ -1,5 +1,4 @@ import { Yarn2Proxy } from './Yarn2Proxy'; -import * as PackageJsonHelper from './PackageJsonHelper'; describe('Yarn 2 Proxy', () => { let yarn2Proxy: Yarn2Proxy; @@ -62,7 +61,7 @@ describe('Yarn 2 Proxy', () => { it('skipInstall should only change package.json without running install', () => { const executeCommandSpy = jest.spyOn(yarn2Proxy, 'executeCommand').mockReturnValue('7.0.0'); const writePackageSpy = jest - .spyOn(PackageJsonHelper, 'writePackageJson') + .spyOn(yarn2Proxy, 'writePackageJson') .mockImplementation(jest.fn); yarn2Proxy.removeDependencies( diff --git a/code/lib/cli/src/js-package-manager/index.ts b/code/lib/cli/src/js-package-manager/index.ts index 13cc52f4ed04..3a2b877d5030 100644 --- a/code/lib/cli/src/js-package-manager/index.ts +++ b/code/lib/cli/src/js-package-manager/index.ts @@ -1,4 +1,3 @@ export * from './JsPackageManagerFactory'; export * from './JsPackageManager'; export * from './PackageJson'; -export * from './PackageJsonHelper'; From e3a7dbfb973bc0356773fab2bff23fab30af81ce Mon Sep 17 00:00:00 2001 From: Yann Braga Date: Tue, 16 Aug 2022 11:02:31 +0200 Subject: [PATCH 02/41] add package resolutions command to jspackagemanager --- .../js-package-manager/JsPackageManager.ts | 11 ++++++++ .../src/js-package-manager/NPMProxy.test.ts | 26 +++++++++++++++++ .../cli/src/js-package-manager/NPMProxy.ts | 10 +++++++ .../src/js-package-manager/Yarn1Proxy.test.ts | 28 +++++++++++++++++++ .../cli/src/js-package-manager/Yarn1Proxy.ts | 10 +++++++ .../src/js-package-manager/Yarn2Proxy.test.ts | 28 +++++++++++++++++++ .../cli/src/js-package-manager/Yarn2Proxy.ts | 10 +++++++ 7 files changed, 123 insertions(+) diff --git a/code/lib/cli/src/js-package-manager/JsPackageManager.ts b/code/lib/cli/src/js-package-manager/JsPackageManager.ts index 3090983aee39..442d26998766 100644 --- a/code/lib/cli/src/js-package-manager/JsPackageManager.ts +++ b/code/lib/cli/src/js-package-manager/JsPackageManager.ts @@ -326,12 +326,23 @@ export abstract class JsPackageManager { }); } + public addPackageResolutions(versions: Record) { + const packageJson = this.retrievePackageJson(); + const resolutions = this.getResolutions(packageJson, versions); + this.writePackageJson({ ...packageJson, ...resolutions }); + } + protected abstract runInstall(): void; protected abstract runAddDeps(dependencies: string[], installAsDevDependencies: boolean): void; protected abstract runRemoveDeps(dependencies: string[]): void; + protected abstract getResolutions( + packageJson: PackageJson, + versions: Record + ): Record; + /** * Get the latest or all versions of the input package available on npmjs.com * diff --git a/code/lib/cli/src/js-package-manager/NPMProxy.test.ts b/code/lib/cli/src/js-package-manager/NPMProxy.test.ts index e04fea08cc69..49cc2bf1aea1 100644 --- a/code/lib/cli/src/js-package-manager/NPMProxy.test.ts +++ b/code/lib/cli/src/js-package-manager/NPMProxy.test.ts @@ -204,4 +204,30 @@ describe('NPM Proxy', () => { expect(version).toEqual(`^${packageVersion}`); }); }); + + describe('addPackageResolutions', () => { + it('adds resolutions to package.json and account for existing resolutions', () => { + const writePackageSpy = jest.spyOn(npmProxy, 'writePackageJson').mockImplementation(jest.fn); + + jest.spyOn(npmProxy, 'retrievePackageJson').mockImplementation( + jest.fn(() => ({ + overrides: { + bar: 'x.x.x', + }, + })) + ); + + const versions = { + foo: 'x.x.x', + }; + npmProxy.addPackageResolutions(versions); + + expect(writePackageSpy).toHaveBeenCalledWith({ + overrides: { + ...versions, + bar: 'x.x.x', + }, + }); + }); + }); }); diff --git a/code/lib/cli/src/js-package-manager/NPMProxy.ts b/code/lib/cli/src/js-package-manager/NPMProxy.ts index 5c9f76aaae5d..d89726f9d7dc 100644 --- a/code/lib/cli/src/js-package-manager/NPMProxy.ts +++ b/code/lib/cli/src/js-package-manager/NPMProxy.ts @@ -1,5 +1,6 @@ import semver from '@storybook/semver'; import { JsPackageManager } from './JsPackageManager'; +import type { PackageJson } from './PackageJson'; export class NPMProxy extends JsPackageManager { readonly type = 'npm'; @@ -60,6 +61,15 @@ export class NPMProxy extends JsPackageManager { return this.uninstallArgs; } + protected getResolutions(packageJson: PackageJson, versions: Record) { + return { + overrides: { + ...packageJson.overrides, + ...versions, + }, + }; + } + protected runInstall(): void { this.executeCommand('npm', this.getInstallArgs(), 'inherit'); } diff --git a/code/lib/cli/src/js-package-manager/Yarn1Proxy.test.ts b/code/lib/cli/src/js-package-manager/Yarn1Proxy.test.ts index a95f74e1ed13..9afa55a4dc16 100644 --- a/code/lib/cli/src/js-package-manager/Yarn1Proxy.test.ts +++ b/code/lib/cli/src/js-package-manager/Yarn1Proxy.test.ts @@ -125,4 +125,32 @@ describe('Yarn 1 Proxy', () => { await expect(yarn1Proxy.latestVersion('@storybook/addons')).rejects.toThrow(); }); }); + + describe('addPackageResolutions', () => { + it('adds resolutions to package.json and account for existing resolutions', () => { + const writePackageSpy = jest + .spyOn(yarn1Proxy, 'writePackageJson') + .mockImplementation(jest.fn); + + jest.spyOn(yarn1Proxy, 'retrievePackageJson').mockImplementation( + jest.fn(() => ({ + resolutions: { + bar: 'x.x.x', + }, + })) + ); + + const versions = { + foo: 'x.x.x', + }; + yarn1Proxy.addPackageResolutions(versions); + + expect(writePackageSpy).toHaveBeenCalledWith({ + resolutions: { + ...versions, + bar: 'x.x.x', + }, + }); + }); + }); }); diff --git a/code/lib/cli/src/js-package-manager/Yarn1Proxy.ts b/code/lib/cli/src/js-package-manager/Yarn1Proxy.ts index 88368e3f0ea6..789499084c85 100644 --- a/code/lib/cli/src/js-package-manager/Yarn1Proxy.ts +++ b/code/lib/cli/src/js-package-manager/Yarn1Proxy.ts @@ -1,4 +1,5 @@ import { JsPackageManager } from './JsPackageManager'; +import type { PackageJson } from './PackageJson'; export class Yarn1Proxy extends JsPackageManager { readonly type = 'yarn1'; @@ -15,6 +16,15 @@ export class Yarn1Proxy extends JsPackageManager { return `yarn ${command}`; } + protected getResolutions(packageJson: PackageJson, versions: Record) { + return { + resolutions: { + ...packageJson.resolutions, + ...versions, + }, + }; + } + protected runInstall(): void { this.executeCommand('yarn', [], 'inherit'); } diff --git a/code/lib/cli/src/js-package-manager/Yarn2Proxy.test.ts b/code/lib/cli/src/js-package-manager/Yarn2Proxy.test.ts index 09798191699f..11f8749ab726 100644 --- a/code/lib/cli/src/js-package-manager/Yarn2Proxy.test.ts +++ b/code/lib/cli/src/js-package-manager/Yarn2Proxy.test.ts @@ -131,4 +131,32 @@ describe('Yarn 2 Proxy', () => { await expect(yarn2Proxy.latestVersion('@storybook/addons')).rejects.toThrow(); }); }); + + describe('addPackageResolutions', () => { + it('adds resolutions to package.json and account for existing resolutions', () => { + const writePackageSpy = jest + .spyOn(yarn2Proxy, 'writePackageJson') + .mockImplementation(jest.fn); + + jest.spyOn(yarn2Proxy, 'retrievePackageJson').mockImplementation( + jest.fn(() => ({ + resolutions: { + bar: 'x.x.x', + }, + })) + ); + + const versions = { + foo: 'x.x.x', + }; + yarn2Proxy.addPackageResolutions(versions); + + expect(writePackageSpy).toHaveBeenCalledWith({ + resolutions: { + ...versions, + bar: 'x.x.x', + }, + }); + }); + }); }); diff --git a/code/lib/cli/src/js-package-manager/Yarn2Proxy.ts b/code/lib/cli/src/js-package-manager/Yarn2Proxy.ts index 133c384e00b7..63736283424f 100644 --- a/code/lib/cli/src/js-package-manager/Yarn2Proxy.ts +++ b/code/lib/cli/src/js-package-manager/Yarn2Proxy.ts @@ -1,4 +1,5 @@ import { JsPackageManager } from './JsPackageManager'; +import type { PackageJson } from './PackageJson'; export class Yarn2Proxy extends JsPackageManager { readonly type = 'yarn2'; @@ -15,6 +16,15 @@ export class Yarn2Proxy extends JsPackageManager { return `yarn ${command}`; } + protected getResolutions(packageJson: PackageJson, versions: Record) { + return { + resolutions: { + ...packageJson.resolutions, + ...versions, + }, + }; + } + protected runInstall(): void { this.executeCommand('yarn', [], 'inherit'); } From a13f330517202a26eb768cbf37eb9722f91ab6ed Mon Sep 17 00:00:00 2001 From: Yann Braga Date: Tue, 16 Aug 2022 12:15:55 +0200 Subject: [PATCH 03/41] add setRegistryURL to jspackagemanager --- .../src/js-package-manager/JsPackageManager.ts | 2 ++ .../cli/src/js-package-manager/NPMProxy.test.ts | 15 +++++++++++++++ code/lib/cli/src/js-package-manager/NPMProxy.ts | 5 +++++ .../cli/src/js-package-manager/Yarn1Proxy.test.ts | 15 +++++++++++++++ code/lib/cli/src/js-package-manager/Yarn1Proxy.ts | 5 +++++ .../cli/src/js-package-manager/Yarn2Proxy.test.ts | 15 +++++++++++++++ code/lib/cli/src/js-package-manager/Yarn2Proxy.ts | 5 +++++ 7 files changed, 62 insertions(+) diff --git a/code/lib/cli/src/js-package-manager/JsPackageManager.ts b/code/lib/cli/src/js-package-manager/JsPackageManager.ts index 442d26998766..7ee879b75f56 100644 --- a/code/lib/cli/src/js-package-manager/JsPackageManager.ts +++ b/code/lib/cli/src/js-package-manager/JsPackageManager.ts @@ -36,6 +36,8 @@ export abstract class JsPackageManager { public abstract getRunCommand(command: string): string; + public abstract setRegistryURL(url: string): void; + /** * Install dependencies listed in `package.json` */ diff --git a/code/lib/cli/src/js-package-manager/NPMProxy.test.ts b/code/lib/cli/src/js-package-manager/NPMProxy.test.ts index 49cc2bf1aea1..9350b0eae96c 100644 --- a/code/lib/cli/src/js-package-manager/NPMProxy.test.ts +++ b/code/lib/cli/src/js-package-manager/NPMProxy.test.ts @@ -21,6 +21,21 @@ describe('NPM Proxy', () => { }); }); + describe('setRegistryUrl', () => { + it('should run `npm config set registry https://foo.bar`', () => { + const executeCommandSpy = jest.spyOn(npmProxy, 'executeCommand').mockReturnValue(''); + + npmProxy.setRegistryURL('https://foo.bar'); + + expect(executeCommandSpy).toHaveBeenCalledWith('npm', [ + 'config', + 'set', + 'registry', + 'https://foo.bar', + ]); + }); + }); + describe('installDependencies', () => { describe('npm6', () => { it('should run `npm install`', () => { diff --git a/code/lib/cli/src/js-package-manager/NPMProxy.ts b/code/lib/cli/src/js-package-manager/NPMProxy.ts index d89726f9d7dc..6728901a5d8f 100644 --- a/code/lib/cli/src/js-package-manager/NPMProxy.ts +++ b/code/lib/cli/src/js-package-manager/NPMProxy.ts @@ -61,6 +61,11 @@ export class NPMProxy extends JsPackageManager { return this.uninstallArgs; } + setRegistryURL(url: string) { + const args = ['config', 'set', 'registry', url]; + this.executeCommand('npm', args); + } + protected getResolutions(packageJson: PackageJson, versions: Record) { return { overrides: { diff --git a/code/lib/cli/src/js-package-manager/Yarn1Proxy.test.ts b/code/lib/cli/src/js-package-manager/Yarn1Proxy.test.ts index 9afa55a4dc16..90a7df8b9b8c 100644 --- a/code/lib/cli/src/js-package-manager/Yarn1Proxy.test.ts +++ b/code/lib/cli/src/js-package-manager/Yarn1Proxy.test.ts @@ -21,6 +21,21 @@ describe('Yarn 1 Proxy', () => { }); }); + describe('setRegistryUrl', () => { + it('should run `yarn config set npmRegistryServer https://foo.bar`', () => { + const executeCommandSpy = jest.spyOn(yarn1Proxy, 'executeCommand').mockReturnValue(''); + + yarn1Proxy.setRegistryURL('https://foo.bar'); + + expect(executeCommandSpy).toHaveBeenCalledWith('yarn', [ + 'config', + 'set', + 'npmRegistryServer', + 'https://foo.bar', + ]); + }); + }); + describe('installDependencies', () => { it('should run `yarn`', () => { const executeCommandSpy = jest.spyOn(yarn1Proxy, 'executeCommand').mockReturnValue(''); diff --git a/code/lib/cli/src/js-package-manager/Yarn1Proxy.ts b/code/lib/cli/src/js-package-manager/Yarn1Proxy.ts index 789499084c85..2cb60e27578e 100644 --- a/code/lib/cli/src/js-package-manager/Yarn1Proxy.ts +++ b/code/lib/cli/src/js-package-manager/Yarn1Proxy.ts @@ -16,6 +16,11 @@ export class Yarn1Proxy extends JsPackageManager { return `yarn ${command}`; } + setRegistryURL(url: string) { + const args = ['config', 'set', 'npmRegistryServer', url]; + this.executeCommand('yarn', args); + } + protected getResolutions(packageJson: PackageJson, versions: Record) { return { resolutions: { diff --git a/code/lib/cli/src/js-package-manager/Yarn2Proxy.test.ts b/code/lib/cli/src/js-package-manager/Yarn2Proxy.test.ts index 11f8749ab726..93faad9aa82e 100644 --- a/code/lib/cli/src/js-package-manager/Yarn2Proxy.test.ts +++ b/code/lib/cli/src/js-package-manager/Yarn2Proxy.test.ts @@ -31,6 +31,21 @@ describe('Yarn 2 Proxy', () => { }); }); + describe('setRegistryUrl', () => { + it('should run `yarn config set npmRegistryServer https://foo.bar`', () => { + const executeCommandSpy = jest.spyOn(yarn2Proxy, 'executeCommand').mockReturnValue(''); + + yarn2Proxy.setRegistryURL('https://foo.bar'); + + expect(executeCommandSpy).toHaveBeenCalledWith('yarn', [ + 'config', + 'set', + 'npmRegistryServer', + 'https://foo.bar', + ]); + }); + }); + describe('addDependencies', () => { it('with devDep it should run `yarn install -D @storybook/addons`', () => { const executeCommandSpy = jest.spyOn(yarn2Proxy, 'executeCommand').mockReturnValue(''); diff --git a/code/lib/cli/src/js-package-manager/Yarn2Proxy.ts b/code/lib/cli/src/js-package-manager/Yarn2Proxy.ts index 63736283424f..fffc7fa773aa 100644 --- a/code/lib/cli/src/js-package-manager/Yarn2Proxy.ts +++ b/code/lib/cli/src/js-package-manager/Yarn2Proxy.ts @@ -16,6 +16,11 @@ export class Yarn2Proxy extends JsPackageManager { return `yarn ${command}`; } + setRegistryURL(url: string) { + const args = ['config', 'set', 'npmRegistryServer', url]; + this.executeCommand('yarn', args); + } + protected getResolutions(packageJson: PackageJson, versions: Record) { return { resolutions: { From 4a74219ead065b84f5b645ee9dacd2056ab6696b Mon Sep 17 00:00:00 2001 From: Yann Braga Date: Tue, 16 Aug 2022 12:16:39 +0200 Subject: [PATCH 04/41] WIP: add filter and local registry options to generate-repros --- .../next-repro-generators/generate-repros.ts | 60 +++++++++++++++---- 1 file changed, 47 insertions(+), 13 deletions(-) diff --git a/scripts/next-repro-generators/generate-repros.ts b/scripts/next-repro-generators/generate-repros.ts index 5d2f66dfff22..3c696a92818c 100755 --- a/scripts/next-repro-generators/generate-repros.ts +++ b/scripts/next-repro-generators/generate-repros.ts @@ -1,12 +1,14 @@ /* eslint-disable no-console */ import { join, relative } from 'path'; -import program from 'commander'; import { command } from 'execa'; import type { Options as ExecaOptions } from 'execa'; import pLimit from 'p-limit'; import prettyTime from 'pretty-hrtime'; import { copy, emptyDir, ensureDir, rename, writeFile } from 'fs-extra'; +import { program } from 'commander'; import reproTemplates from '../../code/lib/cli/src/repro-templates'; +import storybookVersions from '../../code/lib/cli/src/versions'; +import { JsPackageManagerFactory } from '../../code/lib/cli/src/js-package-manager/JsPackageManagerFactory'; // @ts-ignore import { maxConcurrentTasks } from '../utils/concurrency'; @@ -68,7 +70,10 @@ const addDocumentation = async ( await writeFile(join(afterDir, 'README.md'), contents); }; -const runGenerators = async (generators: (GeneratorConfig & { dirName: string })[]) => { +const runGenerators = async ( + generators: (GeneratorConfig & { dirName: string })[], + localRegistry = true +) => { console.log(`๐Ÿคนโ€โ™‚๏ธ Generating repros with a concurrency of ${maxConcurrentTasks}`); const limit = pLimit(maxConcurrentTasks); @@ -87,10 +92,21 @@ const runGenerators = async (generators: (GeneratorConfig & { dirName: string }) await setupYarn({ cwd: baseDir }); + const packageManager = JsPackageManagerFactory.getPackageManager(); + await runCommand(script, { cwd: beforeDir }); await localizeYarnConfigFiles(baseDir, beforeDir); + if (localRegistry) { + // TODO: find a good way to have all this run in the correct cwd (beforeDir) + console.log(`๐Ÿ“ฆ Configuring local registry`); + packageManager.addPackageResolutions(storybookVersions); + packageManager.setRegistryURL('https://foo.bar'); + // TODO: remove this after we make sure the cwd is correct + process.exit(0); + } + await addStorybook(baseDir); await addDocumentation(baseDir, { name, dirName }); @@ -106,19 +122,37 @@ const runGenerators = async (generators: (GeneratorConfig & { dirName: string }) ); }; -const generate = async () => { - runGenerators( - Object.entries(reproTemplates).map(([dirName, configuration]) => ({ +const generate = async ({ + template, + localRegistry, +}: { + template?: string; + localRegistry?: boolean; +}) => { + const generatorConfigs = Object.entries(reproTemplates) + .map(([dirName, configuration]) => ({ dirName, ...configuration, })) - ); -}; + .filter(({ dirName }) => { + if (template) { + return dirName === template; + } + + return true; + }); -program.description('Create a reproduction from a set of possible templates'); -program.parse(process.argv); + runGenerators(generatorConfigs, localRegistry); +}; -generate().catch((e) => { - console.trace(e); - process.exit(1); -}); +program + .description('Create a reproduction from a set of possible templates') + .option('--template