From c2f27f30655899c5fb1817256d569c37798102e7 Mon Sep 17 00:00:00 2001 From: Michael Shilman Date: Mon, 17 May 2021 01:04:07 +0800 Subject: [PATCH] CLI: Add sb link --local option --- lib/cli/src/generate.ts | 9 +++---- lib/cli/src/link.ts | 52 ++++++++++++++++++++++++++++------------- 2 files changed, 41 insertions(+), 20 deletions(-) diff --git a/lib/cli/src/generate.ts b/lib/cli/src/generate.ts index 4686b3326d52..01209a82f6fd 100644 --- a/lib/cli/src/generate.ts +++ b/lib/cli/src/generate.ts @@ -110,10 +110,11 @@ program ); program - .command('link ') - .description('Pull down a repro from a URL, link it, and run storybook') - .action((reproUrl) => - link({ reproUrl }).catch((e) => { + .command('link ') + .description('Pull down a repro from a URL (or a local directory), link it, and run storybook') + .option('--local', 'Link a local directory already in your file system') + .action((target, { local }) => + link({ target, local }).catch((e) => { logger.error(e); process.exit(1); }) diff --git a/lib/cli/src/link.ts b/lib/cli/src/link.ts index 64e2ae748752..b54f2e89acc8 100644 --- a/lib/cli/src/link.ts +++ b/lib/cli/src/link.ts @@ -1,14 +1,16 @@ import fse from 'fs-extra'; import path from 'path'; +import { sync as spawnSync } from 'cross-spawn'; import { logger } from '@storybook/node-logger'; import { exec } from './repro-generators/scripts'; interface LinkOptions { - reproUrl: string; + target: string; + local?: boolean; } -export const link = async ({ reproUrl }: LinkOptions) => { - const storybookDirectory = process.cwd(); +export const link = async ({ target, local }: LinkOptions) => { + const storybookDir = process.cwd(); try { const packageJson = JSON.parse(fse.readFileSync('package.json', 'utf8')); if (packageJson.name !== '@storybook/root') throw new Error(); @@ -16,28 +18,46 @@ export const link = async ({ reproUrl }: LinkOptions) => { throw new Error('Expected to run link from the root of the storybook monorepo'); } - const reprosDirectory = path.join(storybookDirectory, '../storybook-repros'); - logger.info(`Ensuring directory ${reprosDirectory}`); - fse.ensureDirSync(reprosDirectory); + let reproDir = target; + let reproName = path.basename(target); - logger.info(`Cloning ${reproUrl}`); - await exec(`git clone ${reproUrl}`, { cwd: reprosDirectory }); - // Extract a repro name from url given as input (take the last part of the path and remove the extension) - const reproName = path.basename(reproUrl, path.extname(reproUrl)); - const repro = path.join(reprosDirectory, reproName); + if (!local) { + const reprosDir = path.join(storybookDir, '../storybook-repros'); + logger.info(`Ensuring directory ${reprosDir}`); + fse.ensureDirSync(reprosDir); - logger.info(`Linking ${repro}`); - await exec(`yarn link --all ${storybookDirectory}`, { cwd: repro }); + logger.info(`Cloning ${target}`); + await exec(`git clone ${target}`, { cwd: reprosDir }); + // Extract a repro name from url given as input (take the last part of the path and remove the extension) + reproName = path.basename(target, path.extname(target)); + reproDir = path.join(reprosDir, reproName); + } + + const version = spawnSync('yarn', ['--version'], { + cwd: reproDir, + stdio: 'pipe', + }).stdout.toString(); + + if (!version.startsWith('2.')) { + logger.warn(`🚨 Expected yarn 2 in ${reproDir}!`); + logger.warn(''); + logger.warn('Please set it up with `yarn set version berry`,'); + logger.warn(`then link '${reproDir}' with the '--local' flag.`); + return; + } + + logger.info(`Linking ${reproDir}`); + await exec(`yarn link --all ${storybookDir}`, { cwd: reproDir }); logger.info(`Installing ${reproName}`); - await exec(`yarn install`, { cwd: repro }); + await exec(`yarn install`, { cwd: reproDir }); // ⚠️ TODO: Fix peer deps in `@storybook/preset-create-react-app` logger.info( `Magic stuff related to @storybook/preset-create-react-app, we need to fix peerDependencies` ); - await exec(`yarn add -D webpack-hot-middleware`, { cwd: repro }); + await exec(`yarn add -D webpack-hot-middleware`, { cwd: reproDir }); logger.info(`Running ${reproName} storybook`); - await exec(`yarn run storybook`, { cwd: repro }); + await exec(`yarn run storybook`, { cwd: reproDir }); };