From 68983e8f4bbc51c63520a453693ca510c277a45c Mon Sep 17 00:00:00 2001 From: Shaun Lloyd Date: Mon, 27 Nov 2023 14:51:46 -0500 Subject: [PATCH 01/62] Create function to execute creation script --- code/lib/cli/src/utils.ts | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/code/lib/cli/src/utils.ts b/code/lib/cli/src/utils.ts index fcd861860992..ce08ce45ac5f 100644 --- a/code/lib/cli/src/utils.ts +++ b/code/lib/cli/src/utils.ts @@ -1,8 +1,10 @@ +import chalk from 'chalk'; import type { WriteStream } from 'fs-extra'; import { move, remove, writeFile, readFile, createWriteStream } from 'fs-extra'; import { join } from 'path'; import tempy from 'tempy'; import { rendererPackages } from '@storybook/core-common'; +import { logger } from '@storybook/node-logger'; import type { JsPackageManager } from './js-package-manager'; export function parseList(str: string): string[] { @@ -130,3 +132,32 @@ export const isCorePackage = (pkg: string) => pkg.startsWith('@storybook/') && !pkg.startsWith('@storybook/preset-') && !PACKAGES_EXCLUDED_FROM_CORE.includes(pkg); + +/** + * + * @param command A shell command string to execute. + * @param options Options to pass to the node `spawn` function. + * @returns A promise that resolves when the command has finished executing. + */ +export const exec = async (command: string, options: Record) => { + const { spawn } = await import('cross-spawn'); + return new Promise((resolve, reject) => { + const child = spawn(command, { + ...options, + shell: true, + stdio: 'pipe', + }); + + child.stderr.pipe(process.stdout); + child.stdout.pipe(process.stdout); + + child.on('exit', (code) => { + if (code === 0) { + resolve(undefined); + } else { + logger.error(chalk.red(`An error occurred while executing: \`${command}\``)); + reject(new Error(`Command failed with exit code: ${code}`)); + } + }); + }); +}; From 07f08a36b2996a99b21e2020d36cabf747c49ac7 Mon Sep 17 00:00:00 2001 From: Shaun Lloyd Date: Mon, 27 Nov 2023 14:52:25 -0500 Subject: [PATCH 02/62] Create flow to scaffold a new project --- code/lib/cli/src/scaffold-new-project.ts | 176 +++++++++++++++++++++++ 1 file changed, 176 insertions(+) create mode 100644 code/lib/cli/src/scaffold-new-project.ts diff --git a/code/lib/cli/src/scaffold-new-project.ts b/code/lib/cli/src/scaffold-new-project.ts new file mode 100644 index 000000000000..a837fa7f87ad --- /dev/null +++ b/code/lib/cli/src/scaffold-new-project.ts @@ -0,0 +1,176 @@ +import boxen from 'boxen'; +import chalk from 'chalk'; +import prompts from 'prompts'; +import dedent from 'ts-dedent'; +import { logger } from '@storybook/node-logger'; + +import type { PackageManagerName } from './js-package-manager'; +import { exec } from './utils'; + +type CoercedPackageManagerName = 'npm' | 'yarn' | 'pnpm'; + +interface SupportedProject { + displayName: { + type: string; + builder?: string; + language: string; + }; + createScript: Record; +} + +/** + * The supported projects. + */ +const SUPPORTED_PROJECTS: Record = { + 'react-vite-ts': { + displayName: { + type: 'React', + builder: 'Vite', + language: 'TS', + }, + createScript: { + npm: 'npm create vite@latest --yes . -- --template react-ts', + yarn: 'yarn create vite@latest --yes . --template react-ts', + pnpm: 'pnpm create vite@latest --yes . --template react-ts && pnpm i --prefer-offline', + }, + }, + 'nextjs-ts': { + displayName: { + type: 'Next.js', + language: 'TS', + }, + createScript: { + npm: 'npm create next-app . -- --typescript --use-npm --eslint --tailwind --app --import-alias="@/*" --src-dir', + yarn: 'yarn create next-app . --typescript --use-yarn --eslint --tailwind --app --import-alias="@/*" --src-dir', + pnpm: 'pnpm create next-app . --typescript --use-pnpm --eslint --tailwind --app --import-alias="@/*" --src-dir && pnpm i --prefer-offline', + }, + }, + 'vue-vite-ts': { + displayName: { + type: 'Vue 3', + builder: 'Vite', + language: 'TS', + }, + createScript: { + npm: 'npm create vite@latest --yes . -- --template vue-ts', + yarn: 'yarn create vite@latest --yes . --template vue-ts', + pnpm: 'pnpm create vite@latest --yes . --template vue-ts && pnpm i --prefer-offline', + }, + }, + 'angular-cli': { + displayName: { + type: 'Angular', + language: 'TS', + }, + createScript: { + npm: 'npx -p @angular/cli@latest ng new angular-latest --directory . --routing=true --minimal=true --style=scss --strict --skip-git --skip-install', + yarn: 'yarn dlx -p @angular/cli ng new angular-latest --directory . --routing=true --minimal=true --style=scss --strict --skip-git --package-manager=yarn --skip-install && touch yarn.lock && yarn set version berry && yarn config set nodeLinker node-modules', + pnpm: 'pnpm --package @angular/cli dlx ng new angular-latest --directory . --routing=true --minimal=true --style=scss --strict --skip-git --package-manager=pnpm --skip-install && pnpm i --prefer-offline', + }, + }, + 'lit-vite-ts': { + displayName: { + type: 'Lit', + builder: 'Vite', + language: 'TS', + }, + createScript: { + npm: 'npm create vite@latest --yes . -- --template lit-ts', + yarn: 'yarn create vite . --yes --template lit-ts && touch yarn.lock && yarn set version berry && yarn config set nodeLinker pnp', + pnpm: 'pnpm create vite@latest . --yes --template lit-ts && cd . && pnpm i --prefer-offline', + }, + }, +}; + +const packageManagerToCoercedName = ( + packageManager: PackageManagerName +): CoercedPackageManagerName => { + switch (packageManager) { + case 'npm': + return 'npm'; + case 'pnpm': + return 'pnpm'; + default: + return 'yarn'; + } +}; + +const buildProjectDisplayNameForPrint = ({ displayName }: SupportedProject) => { + const { type, builder, language } = displayName; + return `${chalk.bold.blue(type)} ${builder ? `+ ${builder} ` : ''}(${language})`; +}; + +/** + * Scaffold a new project. + * + * @param packageManager The package manager to use. + */ +export const scaffoldNewProject = async (packageManager: PackageManagerName) => { + const packageManagerName = packageManagerToCoercedName(packageManager); + + logger.plain( + boxen( + dedent` + Would you like to generate a new project from the following list? + + ${chalk.bold('Note:')} + Storybook supports many more frameworks and bundlers than listed below. If you don't see your + preferred setup, you can still generate a project then rerun this command to add Storybook. + + ${chalk.bold('Press ^C at any time to quit.')} + `, + { + title: chalk.bold('πŸ”Ž Empty directory detected'), + padding: 1, + margin: 1, + borderStyle: 'double', + borderColor: 'yellow', + } + ) + ); + + const { project } = await prompts( + { + type: 'select', + name: 'project', + message: 'Choose a project template', + choices: Object.entries(SUPPORTED_PROJECTS).map(([key, value]) => ({ + title: buildProjectDisplayNameForPrint(value), + value: key, + })), + }, + { onCancel: () => process.exit(0) } + ); + + const projectStrategy = SUPPORTED_PROJECTS[project]; + const projectDisplayName = buildProjectDisplayNameForPrint(projectStrategy); + const createScript = projectStrategy.createScript[packageManagerName]; + + try { + logger.plain(''); + logger.plain( + `Creating a new "${projectDisplayName}" project with ${chalk.bold(packageManagerName)}...` + ); + await exec(createScript, { stdio: 'inherit' }); + } catch (e) { + // TODO: replace with categorized error + throw new Error(`Failed to create a new project with ${chalk.bold(packageManagerName)}`); + } + + logger.plain( + boxen( + dedent` + "${projectDisplayName}" project with ${chalk.bold(packageManagerName)} created successfully! + + Continuing with Storybook installation... + `, + { + title: chalk.bold('βœ… Success!'), + padding: 1, + margin: 1, + borderStyle: 'double', + borderColor: 'green', + } + ) + ); +}; From 8817642ea6be357bf9118b6c4622c85b88665b15 Mon Sep 17 00:00:00 2001 From: Shaun Lloyd Date: Mon, 27 Nov 2023 14:54:37 -0500 Subject: [PATCH 03/62] Plug scaffold flow into storybook init --- code/lib/cli/src/initiate.ts | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/code/lib/cli/src/initiate.ts b/code/lib/cli/src/initiate.ts index 8811b88c5d85..870b646216e1 100644 --- a/code/lib/cli/src/initiate.ts +++ b/code/lib/cli/src/initiate.ts @@ -36,6 +36,7 @@ import { JsPackageManagerFactory, useNpmWarning } from './js-package-manager'; import type { NpmOptions } from './NpmOptions'; import type { CommandOptions, GeneratorOptions } from './generators/types'; import { HandledError } from './HandledError'; +import { scaffoldNewProject } from './scaffold-new-project'; const logger = console; @@ -307,15 +308,10 @@ async function doInitiate( updateCheckInterval: 1000 * 60 * 60, // every hour (we could increase this later on.) }); + // Check if the current directory is empty. if (options.force !== true && isEmptyDir) { - logger.log( - boxen(getEmptyDirMessage(packageManager.type), { - borderStyle: 'round', - padding: 1, - borderColor: '#F1618C', - }) - ); - throw new HandledError('Project was initialized in an empty directory.'); + // Prompt the user to create a new project from our list. + await scaffoldNewProject(packageManager.type); } let projectType: ProjectType; From ee01b4438b2cb98a37f2ebaa320b4d360bdd4b2b Mon Sep 17 00:00:00 2001 From: Shaun Lloyd Date: Tue, 28 Nov 2023 09:11:34 -0500 Subject: [PATCH 04/62] Don't use app router --- code/lib/cli/src/scaffold-new-project.ts | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/code/lib/cli/src/scaffold-new-project.ts b/code/lib/cli/src/scaffold-new-project.ts index a837fa7f87ad..b23470d0691d 100644 --- a/code/lib/cli/src/scaffold-new-project.ts +++ b/code/lib/cli/src/scaffold-new-project.ts @@ -3,6 +3,7 @@ import chalk from 'chalk'; import prompts from 'prompts'; import dedent from 'ts-dedent'; import { logger } from '@storybook/node-logger'; +import { GenerateNewProjectOnInitError } from '@storybook/core-events/server-errors'; import type { PackageManagerName } from './js-package-manager'; import { exec } from './utils'; @@ -40,9 +41,9 @@ const SUPPORTED_PROJECTS: Record = { language: 'TS', }, createScript: { - npm: 'npm create next-app . -- --typescript --use-npm --eslint --tailwind --app --import-alias="@/*" --src-dir', - yarn: 'yarn create next-app . --typescript --use-yarn --eslint --tailwind --app --import-alias="@/*" --src-dir', - pnpm: 'pnpm create next-app . --typescript --use-pnpm --eslint --tailwind --app --import-alias="@/*" --src-dir && pnpm i --prefer-offline', + npm: 'npm create next-app . -- --typescript --use-npm --eslint --tailwind --no-app --import-alias="@/*" --src-dir', + yarn: 'yarn create next-app . --typescript --use-yarn --eslint --tailwind --no-app --import-alias="@/*" --src-dir', + pnpm: 'pnpm create next-app . --typescript --use-pnpm --eslint --tailwind --no-app --import-alias="@/*" --src-dir && pnpm i --prefer-offline', }, }, 'vue-vite-ts': { @@ -153,8 +154,11 @@ export const scaffoldNewProject = async (packageManager: PackageManagerName) => ); await exec(createScript, { stdio: 'inherit' }); } catch (e) { - // TODO: replace with categorized error - throw new Error(`Failed to create a new project with ${chalk.bold(packageManagerName)}`); + throw new GenerateNewProjectOnInitError({ + error: e, + packageManager: packageManagerName, + projectType: projectDisplayName, + }); } logger.plain( From 96b624e21af5b05b376743a0fe5a0f367bd0db22 Mon Sep 17 00:00:00 2001 From: Shaun Lloyd Date: Tue, 28 Nov 2023 09:12:01 -0500 Subject: [PATCH 05/62] Add empty project error --- .../core-events/src/errors/server-errors.ts | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/code/lib/core-events/src/errors/server-errors.ts b/code/lib/core-events/src/errors/server-errors.ts index f4ecab544773..bacdd7d6055e 100644 --- a/code/lib/core-events/src/errors/server-errors.ts +++ b/code/lib/core-events/src/errors/server-errors.ts @@ -410,3 +410,25 @@ export class NoMatchingExportError extends StorybookError { `; } } + +export class GenerateNewProjectOnInitError extends StorybookError { + readonly category = Category.CLI_INIT; + + readonly code = 3; + + constructor( + public data: { error: unknown | Error; packageManager: string; projectType: string } + ) { + super(); + } + + template(): string { + return dedent` + There was an error while using ${this.data.packageManager} to create a new ${ + this.data.projectType + } project. + + ${this.data.error instanceof Error ? this.data.error.message : ''} + `; + } +} From 607c52368bc1fb55d5158959f4b056e68231ca9d Mon Sep 17 00:00:00 2001 From: Shaun Lloyd Date: Tue, 28 Nov 2023 09:41:59 -0500 Subject: [PATCH 06/62] Remove prefers offline --- code/lib/cli/src/scaffold-new-project.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/code/lib/cli/src/scaffold-new-project.ts b/code/lib/cli/src/scaffold-new-project.ts index b23470d0691d..ffea00fbc4cb 100644 --- a/code/lib/cli/src/scaffold-new-project.ts +++ b/code/lib/cli/src/scaffold-new-project.ts @@ -32,7 +32,7 @@ const SUPPORTED_PROJECTS: Record = { createScript: { npm: 'npm create vite@latest --yes . -- --template react-ts', yarn: 'yarn create vite@latest --yes . --template react-ts', - pnpm: 'pnpm create vite@latest --yes . --template react-ts && pnpm i --prefer-offline', + pnpm: 'pnpm create vite@latest --yes . --template react-ts && pnpm i', }, }, 'nextjs-ts': { @@ -43,7 +43,7 @@ const SUPPORTED_PROJECTS: Record = { createScript: { npm: 'npm create next-app . -- --typescript --use-npm --eslint --tailwind --no-app --import-alias="@/*" --src-dir', yarn: 'yarn create next-app . --typescript --use-yarn --eslint --tailwind --no-app --import-alias="@/*" --src-dir', - pnpm: 'pnpm create next-app . --typescript --use-pnpm --eslint --tailwind --no-app --import-alias="@/*" --src-dir && pnpm i --prefer-offline', + pnpm: 'pnpm create next-app . --typescript --use-pnpm --eslint --tailwind --no-app --import-alias="@/*" --src-dir && pnpm i', }, }, 'vue-vite-ts': { @@ -55,7 +55,7 @@ const SUPPORTED_PROJECTS: Record = { createScript: { npm: 'npm create vite@latest --yes . -- --template vue-ts', yarn: 'yarn create vite@latest --yes . --template vue-ts', - pnpm: 'pnpm create vite@latest --yes . --template vue-ts && pnpm i --prefer-offline', + pnpm: 'pnpm create vite@latest --yes . --template vue-ts && pnpm i', }, }, 'angular-cli': { @@ -66,7 +66,7 @@ const SUPPORTED_PROJECTS: Record = { createScript: { npm: 'npx -p @angular/cli@latest ng new angular-latest --directory . --routing=true --minimal=true --style=scss --strict --skip-git --skip-install', yarn: 'yarn dlx -p @angular/cli ng new angular-latest --directory . --routing=true --minimal=true --style=scss --strict --skip-git --package-manager=yarn --skip-install && touch yarn.lock && yarn set version berry && yarn config set nodeLinker node-modules', - pnpm: 'pnpm --package @angular/cli dlx ng new angular-latest --directory . --routing=true --minimal=true --style=scss --strict --skip-git --package-manager=pnpm --skip-install && pnpm i --prefer-offline', + pnpm: 'pnpm --package @angular/cli dlx ng new angular-latest --directory . --routing=true --minimal=true --style=scss --strict --skip-git --package-manager=pnpm --skip-install && pnpm i', }, }, 'lit-vite-ts': { @@ -78,7 +78,7 @@ const SUPPORTED_PROJECTS: Record = { createScript: { npm: 'npm create vite@latest --yes . -- --template lit-ts', yarn: 'yarn create vite . --yes --template lit-ts && touch yarn.lock && yarn set version berry && yarn config set nodeLinker pnp', - pnpm: 'pnpm create vite@latest . --yes --template lit-ts && cd . && pnpm i --prefer-offline', + pnpm: 'pnpm create vite@latest . --yes --template lit-ts && cd . && pnpm i', }, }, }; From 6145b5dc5985adb40a61d97c080a5a279b2c7004 Mon Sep 17 00:00:00 2001 From: Shaun Lloyd Date: Tue, 28 Nov 2023 09:52:37 -0500 Subject: [PATCH 07/62] Use execa --- code/lib/cli/src/scaffold-new-project.ts | 9 ++++++-- code/lib/cli/src/utils.ts | 29 ------------------------ 2 files changed, 7 insertions(+), 31 deletions(-) diff --git a/code/lib/cli/src/scaffold-new-project.ts b/code/lib/cli/src/scaffold-new-project.ts index ffea00fbc4cb..440596af04d7 100644 --- a/code/lib/cli/src/scaffold-new-project.ts +++ b/code/lib/cli/src/scaffold-new-project.ts @@ -2,11 +2,11 @@ import boxen from 'boxen'; import chalk from 'chalk'; import prompts from 'prompts'; import dedent from 'ts-dedent'; +import execa from 'execa'; import { logger } from '@storybook/node-logger'; import { GenerateNewProjectOnInitError } from '@storybook/core-events/server-errors'; import type { PackageManagerName } from './js-package-manager'; -import { exec } from './utils'; type CoercedPackageManagerName = 'npm' | 'yarn' | 'pnpm'; @@ -152,7 +152,12 @@ export const scaffoldNewProject = async (packageManager: PackageManagerName) => logger.plain( `Creating a new "${projectDisplayName}" project with ${chalk.bold(packageManagerName)}...` ); - await exec(createScript, { stdio: 'inherit' }); + await execa.command(createScript, { + stdio: 'pipe', + shell: true, + cwd: process.cwd(), + cleanup: true, + }); } catch (e) { throw new GenerateNewProjectOnInitError({ error: e, diff --git a/code/lib/cli/src/utils.ts b/code/lib/cli/src/utils.ts index ce08ce45ac5f..119baed08542 100644 --- a/code/lib/cli/src/utils.ts +++ b/code/lib/cli/src/utils.ts @@ -132,32 +132,3 @@ export const isCorePackage = (pkg: string) => pkg.startsWith('@storybook/') && !pkg.startsWith('@storybook/preset-') && !PACKAGES_EXCLUDED_FROM_CORE.includes(pkg); - -/** - * - * @param command A shell command string to execute. - * @param options Options to pass to the node `spawn` function. - * @returns A promise that resolves when the command has finished executing. - */ -export const exec = async (command: string, options: Record) => { - const { spawn } = await import('cross-spawn'); - return new Promise((resolve, reject) => { - const child = spawn(command, { - ...options, - shell: true, - stdio: 'pipe', - }); - - child.stderr.pipe(process.stdout); - child.stdout.pipe(process.stdout); - - child.on('exit', (code) => { - if (code === 0) { - resolve(undefined); - } else { - logger.error(chalk.red(`An error occurred while executing: \`${command}\``)); - reject(new Error(`Command failed with exit code: ${code}`)); - } - }); - }); -}; From 1c62a97d58a6052cc3757debeaaa6b74e3f832dd Mon Sep 17 00:00:00 2001 From: Shaun Lloyd Date: Tue, 28 Nov 2023 09:59:20 -0500 Subject: [PATCH 08/62] Remove left right margins from boxen --- code/lib/cli/src/scaffold-new-project.ts | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/code/lib/cli/src/scaffold-new-project.ts b/code/lib/cli/src/scaffold-new-project.ts index 440596af04d7..50f5fa987a96 100644 --- a/code/lib/cli/src/scaffold-new-project.ts +++ b/code/lib/cli/src/scaffold-new-project.ts @@ -123,12 +123,12 @@ export const scaffoldNewProject = async (packageManager: PackageManagerName) => { title: chalk.bold('πŸ”Ž Empty directory detected'), padding: 1, - margin: 1, borderStyle: 'double', borderColor: 'yellow', } ) ); + logger.line(1); const { project } = await prompts( { @@ -148,10 +148,11 @@ export const scaffoldNewProject = async (packageManager: PackageManagerName) => const createScript = projectStrategy.createScript[packageManagerName]; try { - logger.plain(''); + logger.line(1); logger.plain( `Creating a new "${projectDisplayName}" project with ${chalk.bold(packageManagerName)}...` ); + logger.line(1); await execa.command(createScript, { stdio: 'pipe', shell: true, @@ -176,10 +177,10 @@ export const scaffoldNewProject = async (packageManager: PackageManagerName) => { title: chalk.bold('βœ… Success!'), padding: 1, - margin: 1, borderStyle: 'double', borderColor: 'green', } ) ); + logger.line(1); }; From 7114d543fdd5e2e1fa8c2c21664732df87be827e Mon Sep 17 00:00:00 2001 From: Shaun Lloyd Date: Tue, 28 Nov 2023 10:29:05 -0500 Subject: [PATCH 09/62] Update docs to remove empty project callout --- docs/get-started/install.md | 17 +---------------- 1 file changed, 1 insertion(+), 16 deletions(-) diff --git a/docs/get-started/install.md b/docs/get-started/install.md index 2d01dfd1a0f2..977a1e122c03 100644 --- a/docs/get-started/install.md +++ b/docs/get-started/install.md @@ -2,7 +2,7 @@ title: 'Install Storybook' --- -Use the Storybook CLI to install it in a single command. Run this inside your _existing project’s_ root directory: +Use the Storybook CLI to install it in a single command. Run this inside your project’s root directory: @@ -16,21 +16,6 @@ Use the Storybook CLI to install it in a single command. Run this inside your _e -
- -storybook init is not made for empty projects - -Storybook needs to be installed into a project that is already set up with a framework. It will not work on an empty project. There are many ways to bootstrap an app in a given framework, including: - -- πŸ“¦ [Create an Angular Workspace](https://angular.io/cli/new) -- πŸ“¦ [Create React App](https://reactjs.org/docs/create-a-new-react-app.html) -- πŸ“¦ [Create a Vue App](https://vuejs.org/guide/quick-start.html) -- πŸ“¦ [Ember CLI](https://guides.emberjs.com/release/getting-started/quick-start/) -- πŸ“¦ [Vite CLI](https://vitejs.dev/guide/#scaffolding-your-first-vite-project) -- Or any other tooling available. - -
- Storybook will look into your project's dependencies during its install process and provide you with the best configuration available. The command above will make the following changes to your local environment: From 43f5be56b6d0d279bc241e1d0599d93571c9198c Mon Sep 17 00:00:00 2001 From: Shaun Lloyd Date: Tue, 28 Nov 2023 10:46:44 -0500 Subject: [PATCH 10/62] Add env var to reselect new project --- code/lib/cli/src/generate.ts | 5 ++++ code/lib/cli/src/scaffold-new-project.ts | 36 +++++++++++++++--------- code/lib/cli/src/utils.ts | 3 +- 3 files changed, 28 insertions(+), 16 deletions(-) diff --git a/code/lib/cli/src/generate.ts b/code/lib/cli/src/generate.ts index bc396ec428b7..54212c8c7371 100644 --- a/code/lib/cli/src/generate.ts +++ b/code/lib/cli/src/generate.ts @@ -55,6 +55,11 @@ command('init') .option('-y --yes', 'Answer yes to all prompts') .option('-b --builder ', 'Builder library') .option('-l --linkable', 'Prepare installation for link (contributor helper)') + .option( + '--scaffold-project ', + 'Scaffold a new project', + process.env.STORYBOOK_SCAFFOLD_PROJECT + ) .action((options: CommandOptions) => { initiate(options, pkg).catch(() => process.exit(1)); }); diff --git a/code/lib/cli/src/scaffold-new-project.ts b/code/lib/cli/src/scaffold-new-project.ts index 50f5fa987a96..4b6d0282126c 100644 --- a/code/lib/cli/src/scaffold-new-project.ts +++ b/code/lib/cli/src/scaffold-new-project.ts @@ -106,7 +106,10 @@ const buildProjectDisplayNameForPrint = ({ displayName }: SupportedProject) => { * * @param packageManager The package manager to use. */ -export const scaffoldNewProject = async (packageManager: PackageManagerName) => { +export const scaffoldNewProject = async ( + packageManager: PackageManagerName, + { scaffoldProject }: { scaffoldProject: string } +) => { const packageManagerName = packageManagerToCoercedName(packageManager); logger.plain( @@ -130,20 +133,25 @@ export const scaffoldNewProject = async (packageManager: PackageManagerName) => ); logger.line(1); - const { project } = await prompts( - { - type: 'select', - name: 'project', - message: 'Choose a project template', - choices: Object.entries(SUPPORTED_PROJECTS).map(([key, value]) => ({ - title: buildProjectDisplayNameForPrint(value), - value: key, - })), - }, - { onCancel: () => process.exit(0) } - ); + let projectStrategy = SUPPORTED_PROJECTS[scaffoldProject]; + + if (!projectStrategy) { + const { project } = await prompts( + { + type: 'select', + name: 'project', + message: 'Choose a project template', + choices: Object.entries(SUPPORTED_PROJECTS).map(([key, value]) => ({ + title: buildProjectDisplayNameForPrint(value), + value: key, + })), + }, + { onCancel: () => process.exit(0) } + ); + + projectStrategy = SUPPORTED_PROJECTS[project]; + } - const projectStrategy = SUPPORTED_PROJECTS[project]; const projectDisplayName = buildProjectDisplayNameForPrint(projectStrategy); const createScript = projectStrategy.createScript[packageManagerName]; diff --git a/code/lib/cli/src/utils.ts b/code/lib/cli/src/utils.ts index 119baed08542..68839b7bfa8d 100644 --- a/code/lib/cli/src/utils.ts +++ b/code/lib/cli/src/utils.ts @@ -1,10 +1,9 @@ -import chalk from 'chalk'; import type { WriteStream } from 'fs-extra'; import { move, remove, writeFile, readFile, createWriteStream } from 'fs-extra'; import { join } from 'path'; import tempy from 'tempy'; import { rendererPackages } from '@storybook/core-common'; -import { logger } from '@storybook/node-logger'; + import type { JsPackageManager } from './js-package-manager'; export function parseList(str: string): string[] { From 33fca510bdb0ecdabfab659bbc3ba0a2dfcbf656 Mon Sep 17 00:00:00 2001 From: Shaun Lloyd Date: Tue, 28 Nov 2023 10:50:20 -0500 Subject: [PATCH 11/62] Add new option to types --- code/lib/cli/src/generators/types.ts | 2 ++ code/lib/cli/src/initiate.ts | 41 +----------------------- code/lib/cli/src/scaffold-new-project.ts | 3 +- 3 files changed, 5 insertions(+), 41 deletions(-) diff --git a/code/lib/cli/src/generators/types.ts b/code/lib/cli/src/generators/types.ts index 2f97a34df126..79a0d7d8ecd9 100644 --- a/code/lib/cli/src/generators/types.ts +++ b/code/lib/cli/src/generators/types.ts @@ -55,4 +55,6 @@ export type CommandOptions = { disableTelemetry?: boolean; enableCrashReports?: boolean; debug?: boolean; + // Automatically pick new project template when creating a new project + scaffoldProject?: string; }; diff --git a/code/lib/cli/src/initiate.ts b/code/lib/cli/src/initiate.ts index 870b646216e1..c135f5820ced 100644 --- a/code/lib/cli/src/initiate.ts +++ b/code/lib/cli/src/initiate.ts @@ -235,45 +235,6 @@ const projectTypeInquirer = async ( process.exit(0); }; -const getEmptyDirMessage = (packageManagerType: PackageManagerName) => { - const generatorCommandsMap = { - vite: { - npm: 'npm create vite@latest', - yarn1: 'yarn create vite', - yarn2: 'yarn create vite', - pnpm: 'pnpm create vite', - }, - angular: { - npm: 'npx -p @angular/cli ng new my-project --package-manager=npm', - yarn1: 'npx -p @angular/cli ng new my-project --package-manager=yarn', - yarn2: 'npx -p @angular/cli ng new my-project --package-manager=yarn', - pnpm: 'npx -p @angular/cli ng new my-project --package-manager=pnpm', - }, - }; - - return dedent` - Storybook cannot be installed into an empty project. We recommend creating a new project with the following: - - πŸ“¦ Vite CLI for React/Vue/Web Components => ${chalk.green( - generatorCommandsMap.vite[packageManagerType] - )} - See ${chalk.yellowBright('https://vitejs.dev/guide/#scaffolding-your-first-vite-project')} - - πŸ“¦ Angular CLI => ${chalk.green(generatorCommandsMap.angular[packageManagerType])} - See ${chalk.yellowBright('https://angular.io/cli/new')} - - πŸ“¦ Any other tooling of your choice - - Once you've created a project, please re-run ${chalk.green( - 'npx storybook@latest init' - )} inside the project root. For more information, see ${chalk.yellowBright( - 'https://storybook.js.org/docs' - )} - - Good luck! πŸš€ - `; -}; - async function doInitiate( options: CommandOptions, pkg: PackageJson @@ -311,7 +272,7 @@ async function doInitiate( // Check if the current directory is empty. if (options.force !== true && isEmptyDir) { // Prompt the user to create a new project from our list. - await scaffoldNewProject(packageManager.type); + await scaffoldNewProject(packageManager.type, options); } let projectType: ProjectType; diff --git a/code/lib/cli/src/scaffold-new-project.ts b/code/lib/cli/src/scaffold-new-project.ts index 4b6d0282126c..a525cb4c3bdf 100644 --- a/code/lib/cli/src/scaffold-new-project.ts +++ b/code/lib/cli/src/scaffold-new-project.ts @@ -7,6 +7,7 @@ import { logger } from '@storybook/node-logger'; import { GenerateNewProjectOnInitError } from '@storybook/core-events/server-errors'; import type { PackageManagerName } from './js-package-manager'; +import type { CommandOptions } from './generators/types'; type CoercedPackageManagerName = 'npm' | 'yarn' | 'pnpm'; @@ -108,7 +109,7 @@ const buildProjectDisplayNameForPrint = ({ displayName }: SupportedProject) => { */ export const scaffoldNewProject = async ( packageManager: PackageManagerName, - { scaffoldProject }: { scaffoldProject: string } + { scaffoldProject }: CommandOptions ) => { const packageManagerName = packageManagerToCoercedName(packageManager); From 8186fa716a621b6e3447733c9f5afd6926003437 Mon Sep 17 00:00:00 2001 From: Shaun Lloyd Date: Tue, 28 Nov 2023 12:59:53 -0500 Subject: [PATCH 12/62] fix linting warning --- code/lib/cli/src/initiate.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/lib/cli/src/initiate.ts b/code/lib/cli/src/initiate.ts index c135f5820ced..f0489b853cbe 100644 --- a/code/lib/cli/src/initiate.ts +++ b/code/lib/cli/src/initiate.ts @@ -31,7 +31,7 @@ import qwikGenerator from './generators/QWIK'; import svelteKitGenerator from './generators/SVELTEKIT'; import solidGenerator from './generators/SOLID'; import serverGenerator from './generators/SERVER'; -import type { JsPackageManager, PackageManagerName } from './js-package-manager'; +import type { JsPackageManager } from './js-package-manager'; import { JsPackageManagerFactory, useNpmWarning } from './js-package-manager'; import type { NpmOptions } from './NpmOptions'; import type { CommandOptions, GeneratorOptions } from './generators/types'; From 156ec8a1dea4f9203c6b48d68f527fa0c8f5b046 Mon Sep 17 00:00:00 2001 From: Shaun Lloyd Date: Tue, 28 Nov 2023 13:18:22 -0500 Subject: [PATCH 13/62] Infer package manager from user agent --- code/lib/cli/src/helpers.test.ts | 35 ++++++++++++++++++++++++++++++++ code/lib/cli/src/helpers.ts | 27 ++++++++++++++++++++++++ code/lib/cli/src/initiate.ts | 7 +++++-- 3 files changed, 67 insertions(+), 2 deletions(-) diff --git a/code/lib/cli/src/helpers.test.ts b/code/lib/cli/src/helpers.test.ts index c15ae604a1a9..d734ea04c4c3 100644 --- a/code/lib/cli/src/helpers.test.ts +++ b/code/lib/cli/src/helpers.test.ts @@ -177,4 +177,39 @@ describe('Helpers', () => { }).toThrowError(`Could not coerce ${invalidSemverString} into a semver.`); }); }); + describe('inferPackageManagerFromUserAgent', () => { + afterEach(() => { + delete process.env.npm_config_user_agent; + }); + + it('should return undefined for invalid user agent', () => { + process.env.npm_config_user_agent = ''; + expect(helpers.inferPackageManagerFromUserAgent()).toBeUndefined(); + }); + + it('should infer pnpm from user agent', () => { + process.env.npm_config_user_agent = 'pnpm/7.4.0'; + expect(helpers.inferPackageManagerFromUserAgent()).toBe('pnpm'); + }); + + it('should infer npm from user agent', () => { + process.env.npm_config_user_agent = 'npm/7.24.0'; + expect(helpers.inferPackageManagerFromUserAgent()).toBe('npm'); + }); + + it('should infer yarn 1 from user agent', () => { + process.env.npm_config_user_agent = 'yarn/1.22.11'; + expect(helpers.inferPackageManagerFromUserAgent()).toBe('yarn1'); + }); + + it('should infer yarn 2 from user agent', () => { + process.env.npm_config_user_agent = 'yarn/2.4.0'; + expect(helpers.inferPackageManagerFromUserAgent()).toBe('yarn2'); + }); + + it('should return undefined for unknown package manager', () => { + process.env.npm_config_user_agent = 'unknown'; + expect(helpers.inferPackageManagerFromUserAgent()).toBeUndefined(); + }); + }); }); diff --git a/code/lib/cli/src/helpers.ts b/code/lib/cli/src/helpers.ts index 605fab2d1849..edf2eb7ea4d0 100644 --- a/code/lib/cli/src/helpers.ts +++ b/code/lib/cli/src/helpers.ts @@ -13,6 +13,7 @@ import type { JsPackageManager, PackageJson, PackageJsonWithDepsAndDevDeps, + PackageManagerName, } from './js-package-manager'; import type { SupportedFrameworks, SupportedRenderers } from './project_types'; import { SupportedLanguage } from './project_types'; @@ -314,3 +315,29 @@ export function coerceSemver(version: string) { invariant(coercedSemver != null, `Could not coerce ${version} into a semver.`); return coercedSemver; } + +/** + * Infer the package manager based on the command the user is running. + * Each package manager sets the `npm_config_user_agent` environment variable with its name and version e.g. "npm/7.24.0" + * Which is really useful when invoking commands via npx/pnpx/yarn create/etc. + */ +export function inferPackageManagerFromUserAgent(): PackageManagerName { + const userAgent = process.env.npm_config_user_agent; + if (!userAgent) return 'npm'; + const packageSpec = userAgent.split(' ')[0]; + const [pkgMgrName, pkgMgrVersion] = packageSpec.split('/'); + + if (pkgMgrName === 'pnpm') { + return 'pnpm'; + } + + if (pkgMgrName === 'npm') { + return 'npm'; + } + + if (pkgMgrName === 'yarn') { + return `yarn${pkgMgrVersion?.startsWith('1.') ? '1' : '2'}`; + } + + return 'npm'; +} diff --git a/code/lib/cli/src/initiate.ts b/code/lib/cli/src/initiate.ts index f0489b853cbe..e8f706affa08 100644 --- a/code/lib/cli/src/initiate.ts +++ b/code/lib/cli/src/initiate.ts @@ -12,7 +12,7 @@ import { readdirSync } from 'fs-extra'; import type { Builder } from './project_types'; import { installableProjectTypes, ProjectType } from './project_types'; import { detect, isStorybookInstantiated, detectLanguage, detectPnp } from './detect'; -import { commandLog, codeLog, paddedLog } from './helpers'; +import { commandLog, codeLog, paddedLog, inferPackageManagerFromUserAgent } from './helpers'; import angularGenerator from './generators/ANGULAR'; import emberGenerator from './generators/EMBER'; import reactGenerator from './generators/REACT'; @@ -258,7 +258,10 @@ async function doInitiate( const isEmptyDir = cwdFolderEntries.length === 0 || cwdFolderEntries.every((entry) => entry.startsWith('.')); - const packageManager = JsPackageManagerFactory.getPackageManager({ force: pkgMgr }); + const packageManager = JsPackageManagerFactory.getPackageManager({ + force: pkgMgr || inferPackageManagerFromUserAgent(), + }); + const welcomeMessage = 'storybook init - the simplest way to add a Storybook to your project.'; logger.log(chalk.inverse(`\n ${welcomeMessage} \n`)); From de3dd2427e4f77c3eef7c7e9ae77f041d9b26bdd Mon Sep 17 00:00:00 2001 From: Shaun Lloyd Date: Wed, 29 Nov 2023 08:29:16 -0500 Subject: [PATCH 14/62] fix merge conflicts --- code/lib/cli/src/helpers.test.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/code/lib/cli/src/helpers.test.ts b/code/lib/cli/src/helpers.test.ts index d734ea04c4c3..ae10b4d115fc 100644 --- a/code/lib/cli/src/helpers.test.ts +++ b/code/lib/cli/src/helpers.test.ts @@ -182,9 +182,9 @@ describe('Helpers', () => { delete process.env.npm_config_user_agent; }); - it('should return undefined for invalid user agent', () => { + it('should return npm for invalid user agent', () => { process.env.npm_config_user_agent = ''; - expect(helpers.inferPackageManagerFromUserAgent()).toBeUndefined(); + expect(helpers.inferPackageManagerFromUserAgent()).toBe('npm'); }); it('should infer pnpm from user agent', () => { @@ -207,9 +207,9 @@ describe('Helpers', () => { expect(helpers.inferPackageManagerFromUserAgent()).toBe('yarn2'); }); - it('should return undefined for unknown package manager', () => { + it('should return npm for unknown package manager', () => { process.env.npm_config_user_agent = 'unknown'; - expect(helpers.inferPackageManagerFromUserAgent()).toBeUndefined(); + expect(helpers.inferPackageManagerFromUserAgent()).toBe('npm'); }); }); }); From e329fb818ddf82c7677d40455bd4ba556e111ac7 Mon Sep 17 00:00:00 2001 From: Shaun Lloyd Date: Wed, 29 Nov 2023 08:35:29 -0500 Subject: [PATCH 15/62] Don't expose testing flag; Only use Env var --- code/lib/cli/src/generate.ts | 5 ----- code/lib/cli/src/initiate.ts | 2 +- code/lib/cli/src/scaffold-new-project.ts | 12 ++++++------ 3 files changed, 7 insertions(+), 12 deletions(-) diff --git a/code/lib/cli/src/generate.ts b/code/lib/cli/src/generate.ts index 54212c8c7371..bc396ec428b7 100644 --- a/code/lib/cli/src/generate.ts +++ b/code/lib/cli/src/generate.ts @@ -55,11 +55,6 @@ command('init') .option('-y --yes', 'Answer yes to all prompts') .option('-b --builder ', 'Builder library') .option('-l --linkable', 'Prepare installation for link (contributor helper)') - .option( - '--scaffold-project ', - 'Scaffold a new project', - process.env.STORYBOOK_SCAFFOLD_PROJECT - ) .action((options: CommandOptions) => { initiate(options, pkg).catch(() => process.exit(1)); }); diff --git a/code/lib/cli/src/initiate.ts b/code/lib/cli/src/initiate.ts index e8f706affa08..959938abe947 100644 --- a/code/lib/cli/src/initiate.ts +++ b/code/lib/cli/src/initiate.ts @@ -275,7 +275,7 @@ async function doInitiate( // Check if the current directory is empty. if (options.force !== true && isEmptyDir) { // Prompt the user to create a new project from our list. - await scaffoldNewProject(packageManager.type, options); + await scaffoldNewProject(packageManager.type); } let projectType: ProjectType; diff --git a/code/lib/cli/src/scaffold-new-project.ts b/code/lib/cli/src/scaffold-new-project.ts index a525cb4c3bdf..30865dc16728 100644 --- a/code/lib/cli/src/scaffold-new-project.ts +++ b/code/lib/cli/src/scaffold-new-project.ts @@ -7,7 +7,6 @@ import { logger } from '@storybook/node-logger'; import { GenerateNewProjectOnInitError } from '@storybook/core-events/server-errors'; import type { PackageManagerName } from './js-package-manager'; -import type { CommandOptions } from './generators/types'; type CoercedPackageManagerName = 'npm' | 'yarn' | 'pnpm'; @@ -107,10 +106,7 @@ const buildProjectDisplayNameForPrint = ({ displayName }: SupportedProject) => { * * @param packageManager The package manager to use. */ -export const scaffoldNewProject = async ( - packageManager: PackageManagerName, - { scaffoldProject }: CommandOptions -) => { +export const scaffoldNewProject = async (packageManager: PackageManagerName) => { const packageManagerName = packageManagerToCoercedName(packageManager); logger.plain( @@ -134,7 +130,11 @@ export const scaffoldNewProject = async ( ); logger.line(1); - let projectStrategy = SUPPORTED_PROJECTS[scaffoldProject]; + let projectStrategy; + + if (process.env.STORYBOOK_INIT_EMPTY_TYPE) { + projectStrategy = SUPPORTED_PROJECTS[process.env.STORYBOOK_INIT_EMPTY_TYPE]; + } if (!projectStrategy) { const { project } = await prompts( From 097a9c604e2d2eb9c3d170a798d6297dd96c49cd Mon Sep 17 00:00:00 2001 From: Shaun Lloyd Date: Wed, 29 Nov 2023 09:16:49 -0500 Subject: [PATCH 16/62] Don't install deps on create for pnpm --- code/lib/cli/src/scaffold-new-project.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/code/lib/cli/src/scaffold-new-project.ts b/code/lib/cli/src/scaffold-new-project.ts index 30865dc16728..a78530e91d1e 100644 --- a/code/lib/cli/src/scaffold-new-project.ts +++ b/code/lib/cli/src/scaffold-new-project.ts @@ -32,7 +32,7 @@ const SUPPORTED_PROJECTS: Record = { createScript: { npm: 'npm create vite@latest --yes . -- --template react-ts', yarn: 'yarn create vite@latest --yes . --template react-ts', - pnpm: 'pnpm create vite@latest --yes . --template react-ts && pnpm i', + pnpm: 'pnpm create vite@latest --yes . --template react-ts', }, }, 'nextjs-ts': { @@ -43,7 +43,7 @@ const SUPPORTED_PROJECTS: Record = { createScript: { npm: 'npm create next-app . -- --typescript --use-npm --eslint --tailwind --no-app --import-alias="@/*" --src-dir', yarn: 'yarn create next-app . --typescript --use-yarn --eslint --tailwind --no-app --import-alias="@/*" --src-dir', - pnpm: 'pnpm create next-app . --typescript --use-pnpm --eslint --tailwind --no-app --import-alias="@/*" --src-dir && pnpm i', + pnpm: 'pnpm create next-app . --typescript --use-pnpm --eslint --tailwind --no-app --import-alias="@/*" --src-dir', }, }, 'vue-vite-ts': { @@ -55,7 +55,7 @@ const SUPPORTED_PROJECTS: Record = { createScript: { npm: 'npm create vite@latest --yes . -- --template vue-ts', yarn: 'yarn create vite@latest --yes . --template vue-ts', - pnpm: 'pnpm create vite@latest --yes . --template vue-ts && pnpm i', + pnpm: 'pnpm create vite@latest --yes . --template vue-ts', }, }, 'angular-cli': { @@ -66,7 +66,7 @@ const SUPPORTED_PROJECTS: Record = { createScript: { npm: 'npx -p @angular/cli@latest ng new angular-latest --directory . --routing=true --minimal=true --style=scss --strict --skip-git --skip-install', yarn: 'yarn dlx -p @angular/cli ng new angular-latest --directory . --routing=true --minimal=true --style=scss --strict --skip-git --package-manager=yarn --skip-install && touch yarn.lock && yarn set version berry && yarn config set nodeLinker node-modules', - pnpm: 'pnpm --package @angular/cli dlx ng new angular-latest --directory . --routing=true --minimal=true --style=scss --strict --skip-git --package-manager=pnpm --skip-install && pnpm i', + pnpm: 'pnpm --package @angular/cli dlx ng new angular-latest --directory . --routing=true --minimal=true --style=scss --strict --skip-git --package-manager=pnpm --skip-install', }, }, 'lit-vite-ts': { @@ -78,7 +78,7 @@ const SUPPORTED_PROJECTS: Record = { createScript: { npm: 'npm create vite@latest --yes . -- --template lit-ts', yarn: 'yarn create vite . --yes --template lit-ts && touch yarn.lock && yarn set version berry && yarn config set nodeLinker pnp', - pnpm: 'pnpm create vite@latest . --yes --template lit-ts && cd . && pnpm i', + pnpm: 'pnpm create vite@latest . --yes --template lit-ts', }, }, }; From 85cd3effd78b8944695907c8941fabd45b4b1a45 Mon Sep 17 00:00:00 2001 From: Shaun Lloyd Date: Wed, 29 Nov 2023 10:55:41 -0500 Subject: [PATCH 17/62] Add empty dir sandboxes --- code/lib/cli/src/initiate.ts | 9 +- code/lib/cli/src/sandbox-templates.ts | 126 +++++++++++++++++++++++ code/lib/cli/src/scaffold-new-project.ts | 33 ++++-- 3 files changed, 151 insertions(+), 17 deletions(-) diff --git a/code/lib/cli/src/initiate.ts b/code/lib/cli/src/initiate.ts index 959938abe947..9ae63ccc71b8 100644 --- a/code/lib/cli/src/initiate.ts +++ b/code/lib/cli/src/initiate.ts @@ -8,7 +8,6 @@ import { NxProjectDetectedError } from '@storybook/core-events/server-errors'; import dedent from 'ts-dedent'; import boxen from 'boxen'; -import { readdirSync } from 'fs-extra'; import type { Builder } from './project_types'; import { installableProjectTypes, ProjectType } from './project_types'; import { detect, isStorybookInstantiated, detectLanguage, detectPnp } from './detect'; @@ -36,7 +35,7 @@ import { JsPackageManagerFactory, useNpmWarning } from './js-package-manager'; import type { NpmOptions } from './NpmOptions'; import type { CommandOptions, GeneratorOptions } from './generators/types'; import { HandledError } from './HandledError'; -import { scaffoldNewProject } from './scaffold-new-project'; +import { currentDirectoryIsEmpty, scaffoldNewProject } from './scaffold-new-project'; const logger = console; @@ -254,10 +253,6 @@ async function doInitiate( pkgMgr = 'npm'; } - const cwdFolderEntries = readdirSync(process.cwd()); - const isEmptyDir = - cwdFolderEntries.length === 0 || cwdFolderEntries.every((entry) => entry.startsWith('.')); - const packageManager = JsPackageManagerFactory.getPackageManager({ force: pkgMgr || inferPackageManagerFromUserAgent(), }); @@ -273,7 +268,7 @@ async function doInitiate( }); // Check if the current directory is empty. - if (options.force !== true && isEmptyDir) { + if (options.force !== true && currentDirectoryIsEmpty()) { // Prompt the user to create a new project from our list. await scaffoldNewProject(packageManager.type); } diff --git a/code/lib/cli/src/sandbox-templates.ts b/code/lib/cli/src/sandbox-templates.ts index 86b28646fb10..23bbc565b03d 100644 --- a/code/lib/cli/src/sandbox-templates.ts +++ b/code/lib/cli/src/sandbox-templates.ts @@ -496,6 +496,111 @@ const internalTemplates = { isInternal: true, skipTasks: ['bench'], }, + 'internal/npm/empty/react-vite/default-ts': { + name: 'Empty React + vite (npm)', + script: 'mkdir {{beforeDir}} && cd {{beforeDir}}', + expected: { ...baseTemplates['react-vite/default-ts'].expected }, + isInternal: true, + skipTasks: ['bench'], + }, + 'internal/pnpm/empty/react-vite/default-ts': { + name: 'Empty React + vite (pnpm)', + script: 'mkdir {{beforeDir}} && cd {{beforeDir}}', + expected: { ...baseTemplates['react-vite/default-ts'].expected }, + isInternal: true, + skipTasks: ['bench'], + }, + 'internal/yarn/empty/react-vite/default-ts': { + name: 'Empty React + vite (pnpm)', + script: 'mkdir {{beforeDir}} && cd {{beforeDir}}', + expected: { ...baseTemplates['react-vite/default-ts'].expected }, + isInternal: true, + skipTasks: ['bench'], + }, + 'internal/npm/empty/nextjs/default-ts': { + name: 'Empty Next.js (npm)', + script: 'mkdir {{beforeDir}} && cd {{beforeDir}}', + expected: { ...baseTemplates['nextjs/default-ts'].expected }, + isInternal: true, + skipTasks: ['bench'], + }, + 'internal/pnpm/empty/nextjs/default-ts': { + name: 'Empty Next.js (pnpm)', + script: 'mkdir {{beforeDir}} && cd {{beforeDir}}', + expected: { ...baseTemplates['nextjs/default-ts'].expected }, + isInternal: true, + skipTasks: ['bench'], + }, + 'internal/yarn/empty/nextjs/default-ts': { + name: 'Empty Next.js (pnpm)', + script: 'mkdir {{beforeDir}} && cd {{beforeDir}}', + expected: { ...baseTemplates['nextjs/default-ts'].expected }, + isInternal: true, + skipTasks: ['bench'], + }, + 'internal/npm/empty/vue3-vite/default-ts': { + name: 'Empty Vue 3 + vite (npm)', + script: 'mkdir {{beforeDir}} && cd {{beforeDir}}', + expected: { ...baseTemplates['vue3-vite/default-ts'].expected }, + isInternal: true, + skipTasks: ['bench'], + }, + 'internal/pnpm/empty/vue3-vite/default-ts': { + name: 'Empty Vue 3 + vite (pnpm)', + script: 'mkdir {{beforeDir}} && cd {{beforeDir}}', + expected: { ...baseTemplates['vue3-vite/default-ts'].expected }, + isInternal: true, + skipTasks: ['bench'], + }, + 'internal/yarn/empty/vue3-vite/default-ts': { + name: 'Empty Vue 3 + vite (pnpm)', + script: 'mkdir {{beforeDir}} && cd {{beforeDir}}', + expected: { ...baseTemplates['vue3-vite/default-ts'].expected }, + isInternal: true, + skipTasks: ['bench'], + }, + 'internal/npm/empty/angular-cli/default-ts': { + name: 'Empty Angular (npm)', + script: 'mkdir {{beforeDir}} && cd {{beforeDir}}', + expected: { ...baseTemplates['angular-cli/default-ts'].expected }, + isInternal: true, + skipTasks: ['bench'], + }, + 'internal/pnpm/empty/angular-cli/default-ts': { + name: 'Empty Angular (pnpm)', + script: 'mkdir {{beforeDir}} && cd {{beforeDir}}', + expected: { ...baseTemplates['angular-cli/default-ts'].expected }, + isInternal: true, + skipTasks: ['bench'], + }, + 'internal/yarn/empty/angular-cli/default-ts': { + name: 'Empty Angular (pnpm)', + script: 'mkdir {{beforeDir}} && cd {{beforeDir}}', + expected: { ...baseTemplates['angular-cli/default-ts'].expected }, + isInternal: true, + skipTasks: ['bench'], + }, + 'internal/npm/empty/lit-vite/default-ts': { + name: 'Empty Lit + vite (npm)', + script: 'mkdir {{beforeDir}} && cd {{beforeDir}}', + expected: { ...baseTemplates['lit-vite/default-ts'].expected }, + isInternal: true, + skipTasks: ['bench'], + }, + 'internal/pnpm/empty/lit-vite/default-ts': { + name: 'Empty Lit + vite (pnpm)', + script: 'mkdir {{beforeDir}} && cd {{beforeDir}}', + expected: { ...baseTemplates['lit-vite/default-ts'].expected }, + isInternal: true, + skipTasks: ['bench'], + }, + 'internal/yarn/empty/lit-vite/default-ts': { + name: 'Empty Lit + vite (pnpm)', + script: 'mkdir {{beforeDir}} && cd {{beforeDir}}', + expected: { ...baseTemplates['lit-vite/default-ts'].expected }, + isInternal: true, + skipTasks: ['bench'], + }, // 'internal/pnp': { // ...baseTemplates['cra/default-ts'], // name: 'PNP (cra/default-ts)', @@ -578,6 +683,7 @@ export const normal: TemplateKey[] = [ 'bench/react-vite-default-ts-test-build', 'bench/react-webpack-18-ts-test-build', ]; + export const merged: TemplateKey[] = [ ...normal, 'react-webpack/18-ts', @@ -588,6 +694,25 @@ export const merged: TemplateKey[] = [ 'html-webpack/default', 'html-vite/default-ts', ]; + +const emptyTemplateKeys: TemplateKey[] = [ + // 'internal/npm/empty/react-vite/default-ts', + // 'internal/pnpm/empty/react-vite/default-ts', + 'internal/yarn/empty/react-vite/default-ts', + // 'internal/npm/empty/nextjs/default-ts', + // 'internal/pnpm/empty/nextjs/default-ts', + 'internal/yarn/empty/nextjs/default-ts', + // 'internal/npm/empty/vue3-vite/default-ts', + // 'internal/pnpm/empty/vue3-vite/default-ts', + 'internal/yarn/empty/vue3-vite/default-ts', + // 'internal/npm/empty/angular-cli/default-ts', + // 'internal/pnpm/empty/angular-cli/default-ts', + 'internal/yarn/empty/angular-cli/default-ts', + // 'internal/npm/empty/lit-vite/default-ts', + // 'internal/pnpm/empty/lit-vite/default-ts', + 'internal/yarn/empty/lit-vite/default-ts', +]; + export const daily: TemplateKey[] = [ ...merged, 'angular-cli/prerelease', @@ -606,6 +731,7 @@ export const daily: TemplateKey[] = [ 'preact-webpack5/default-js', 'preact-vite/default-js', 'html-vite/default-js', + ...emptyTemplateKeys, ]; export const templatesByCadence = { normal, merged, daily }; diff --git a/code/lib/cli/src/scaffold-new-project.ts b/code/lib/cli/src/scaffold-new-project.ts index a78530e91d1e..59df8318ce72 100644 --- a/code/lib/cli/src/scaffold-new-project.ts +++ b/code/lib/cli/src/scaffold-new-project.ts @@ -3,6 +3,8 @@ import chalk from 'chalk'; import prompts from 'prompts'; import dedent from 'ts-dedent'; import execa from 'execa'; +import { readdirSync } from 'fs-extra'; + import { logger } from '@storybook/node-logger'; import { GenerateNewProjectOnInitError } from '@storybook/core-events/server-errors'; @@ -30,9 +32,9 @@ const SUPPORTED_PROJECTS: Record = { language: 'TS', }, createScript: { - npm: 'npm create vite@latest --yes . -- --template react-ts', - yarn: 'yarn create vite@latest --yes . --template react-ts', - pnpm: 'pnpm create vite@latest --yes . --template react-ts', + npm: 'npm create vite@latest . -- --template react-ts', + yarn: 'yarn create vite@latest . --template react-ts', + pnpm: 'pnpm create vite@latest . --template react-ts', }, }, 'nextjs-ts': { @@ -53,9 +55,9 @@ const SUPPORTED_PROJECTS: Record = { language: 'TS', }, createScript: { - npm: 'npm create vite@latest --yes . -- --template vue-ts', - yarn: 'yarn create vite@latest --yes . --template vue-ts', - pnpm: 'pnpm create vite@latest --yes . --template vue-ts', + npm: 'npm create vite@latest . -- --template vue-ts', + yarn: 'yarn create vite@latest . --template vue-ts', + pnpm: 'pnpm create vite@latest . --template vue-ts', }, }, 'angular-cli': { @@ -76,9 +78,9 @@ const SUPPORTED_PROJECTS: Record = { language: 'TS', }, createScript: { - npm: 'npm create vite@latest --yes . -- --template lit-ts', - yarn: 'yarn create vite . --yes --template lit-ts && touch yarn.lock && yarn set version berry && yarn config set nodeLinker pnp', - pnpm: 'pnpm create vite@latest . --yes --template lit-ts', + npm: 'npm create vite@latest . -- --template lit-ts', + yarn: 'yarn create vite . --template lit-ts && touch yarn.lock && yarn set version berry && yarn config set nodeLinker pnp', + pnpm: 'pnpm create vite@latest . --template lit-ts', }, }, }; @@ -107,7 +109,7 @@ const buildProjectDisplayNameForPrint = ({ displayName }: SupportedProject) => { * @param packageManager The package manager to use. */ export const scaffoldNewProject = async (packageManager: PackageManagerName) => { - const packageManagerName = packageManagerToCoercedName(packageManager); + const packageManagerName = 'pnpm'; // packageManagerToCoercedName(packageManager); logger.plain( boxen( @@ -193,3 +195,14 @@ export const scaffoldNewProject = async (packageManager: PackageManagerName) => ); logger.line(1); }; + +const IGNORED_FILES = ['.git', '.gitignore', '.DS_Store']; + +export const currentDirectoryIsEmpty = () => { + const cwdFolderEntries = readdirSync(process.cwd()); + + return ( + cwdFolderEntries.length === 0 || + cwdFolderEntries.every((entry) => IGNORED_FILES.includes(entry)) + ); +}; From b2daaec836df4ecc09627b5a3a2da8baf47d8288 Mon Sep 17 00:00:00 2001 From: Shaun Lloyd Date: Wed, 29 Nov 2023 11:15:44 -0500 Subject: [PATCH 18/62] Add optional env vars to templates --- code/lib/cli/src/sandbox-templates.ts | 49 +++++++++++++++++++++++++++ scripts/sandbox/generate.ts | 17 +++++++--- scripts/sandbox/utils/types.ts | 1 + 3 files changed, 62 insertions(+), 5 deletions(-) diff --git a/code/lib/cli/src/sandbox-templates.ts b/code/lib/cli/src/sandbox-templates.ts index 23bbc565b03d..dc45dce86e4e 100644 --- a/code/lib/cli/src/sandbox-templates.ts +++ b/code/lib/cli/src/sandbox-templates.ts @@ -31,6 +31,10 @@ export type Template = { * This is used to generate projects which are pushed to https://github.com/storybookjs/sandboxes */ script: string; + /** + * Environment variables to set when running the script. + */ + env?: Record; /** * Used to assert various things about the generated template. * If the template is generated with a different expected framework, it will fail, detecting a possible regression. @@ -499,6 +503,9 @@ const internalTemplates = { 'internal/npm/empty/react-vite/default-ts': { name: 'Empty React + vite (npm)', script: 'mkdir {{beforeDir}} && cd {{beforeDir}}', + env: { + STORYBOOK_INIT_EMPTY_TYPE: 'react-vite-ts', + }, expected: { ...baseTemplates['react-vite/default-ts'].expected }, isInternal: true, skipTasks: ['bench'], @@ -506,6 +513,9 @@ const internalTemplates = { 'internal/pnpm/empty/react-vite/default-ts': { name: 'Empty React + vite (pnpm)', script: 'mkdir {{beforeDir}} && cd {{beforeDir}}', + env: { + STORYBOOK_INIT_EMPTY_TYPE: 'react-vite-ts', + }, expected: { ...baseTemplates['react-vite/default-ts'].expected }, isInternal: true, skipTasks: ['bench'], @@ -513,6 +523,9 @@ const internalTemplates = { 'internal/yarn/empty/react-vite/default-ts': { name: 'Empty React + vite (pnpm)', script: 'mkdir {{beforeDir}} && cd {{beforeDir}}', + env: { + STORYBOOK_INIT_EMPTY_TYPE: 'react-vite-ts', + }, expected: { ...baseTemplates['react-vite/default-ts'].expected }, isInternal: true, skipTasks: ['bench'], @@ -520,6 +533,9 @@ const internalTemplates = { 'internal/npm/empty/nextjs/default-ts': { name: 'Empty Next.js (npm)', script: 'mkdir {{beforeDir}} && cd {{beforeDir}}', + env: { + STORYBOOK_INIT_EMPTY_TYPE: 'nextjs-ts', + }, expected: { ...baseTemplates['nextjs/default-ts'].expected }, isInternal: true, skipTasks: ['bench'], @@ -527,6 +543,9 @@ const internalTemplates = { 'internal/pnpm/empty/nextjs/default-ts': { name: 'Empty Next.js (pnpm)', script: 'mkdir {{beforeDir}} && cd {{beforeDir}}', + env: { + STORYBOOK_INIT_EMPTY_TYPE: 'nextjs-ts', + }, expected: { ...baseTemplates['nextjs/default-ts'].expected }, isInternal: true, skipTasks: ['bench'], @@ -534,6 +553,9 @@ const internalTemplates = { 'internal/yarn/empty/nextjs/default-ts': { name: 'Empty Next.js (pnpm)', script: 'mkdir {{beforeDir}} && cd {{beforeDir}}', + env: { + STORYBOOK_INIT_EMPTY_TYPE: 'nextjs-ts', + }, expected: { ...baseTemplates['nextjs/default-ts'].expected }, isInternal: true, skipTasks: ['bench'], @@ -541,6 +563,9 @@ const internalTemplates = { 'internal/npm/empty/vue3-vite/default-ts': { name: 'Empty Vue 3 + vite (npm)', script: 'mkdir {{beforeDir}} && cd {{beforeDir}}', + env: { + STORYBOOK_INIT_EMPTY_TYPE: 'vue-vite-ts', + }, expected: { ...baseTemplates['vue3-vite/default-ts'].expected }, isInternal: true, skipTasks: ['bench'], @@ -548,6 +573,9 @@ const internalTemplates = { 'internal/pnpm/empty/vue3-vite/default-ts': { name: 'Empty Vue 3 + vite (pnpm)', script: 'mkdir {{beforeDir}} && cd {{beforeDir}}', + env: { + STORYBOOK_INIT_EMPTY_TYPE: 'vue-vite-ts', + }, expected: { ...baseTemplates['vue3-vite/default-ts'].expected }, isInternal: true, skipTasks: ['bench'], @@ -555,6 +583,9 @@ const internalTemplates = { 'internal/yarn/empty/vue3-vite/default-ts': { name: 'Empty Vue 3 + vite (pnpm)', script: 'mkdir {{beforeDir}} && cd {{beforeDir}}', + env: { + STORYBOOK_INIT_EMPTY_TYPE: 'vue-vite-ts', + }, expected: { ...baseTemplates['vue3-vite/default-ts'].expected }, isInternal: true, skipTasks: ['bench'], @@ -562,6 +593,9 @@ const internalTemplates = { 'internal/npm/empty/angular-cli/default-ts': { name: 'Empty Angular (npm)', script: 'mkdir {{beforeDir}} && cd {{beforeDir}}', + env: { + STORYBOOK_INIT_EMPTY_TYPE: 'angular-cli', + }, expected: { ...baseTemplates['angular-cli/default-ts'].expected }, isInternal: true, skipTasks: ['bench'], @@ -569,6 +603,9 @@ const internalTemplates = { 'internal/pnpm/empty/angular-cli/default-ts': { name: 'Empty Angular (pnpm)', script: 'mkdir {{beforeDir}} && cd {{beforeDir}}', + env: { + STORYBOOK_INIT_EMPTY_TYPE: 'angular-cli', + }, expected: { ...baseTemplates['angular-cli/default-ts'].expected }, isInternal: true, skipTasks: ['bench'], @@ -576,6 +613,9 @@ const internalTemplates = { 'internal/yarn/empty/angular-cli/default-ts': { name: 'Empty Angular (pnpm)', script: 'mkdir {{beforeDir}} && cd {{beforeDir}}', + env: { + STORYBOOK_INIT_EMPTY_TYPE: 'angular-cli', + }, expected: { ...baseTemplates['angular-cli/default-ts'].expected }, isInternal: true, skipTasks: ['bench'], @@ -583,6 +623,9 @@ const internalTemplates = { 'internal/npm/empty/lit-vite/default-ts': { name: 'Empty Lit + vite (npm)', script: 'mkdir {{beforeDir}} && cd {{beforeDir}}', + env: { + STORYBOOK_INIT_EMPTY_TYPE: 'lit-vite-ts', + }, expected: { ...baseTemplates['lit-vite/default-ts'].expected }, isInternal: true, skipTasks: ['bench'], @@ -590,6 +633,9 @@ const internalTemplates = { 'internal/pnpm/empty/lit-vite/default-ts': { name: 'Empty Lit + vite (pnpm)', script: 'mkdir {{beforeDir}} && cd {{beforeDir}}', + env: { + STORYBOOK_INIT_EMPTY_TYPE: 'lit-vite-ts', + }, expected: { ...baseTemplates['lit-vite/default-ts'].expected }, isInternal: true, skipTasks: ['bench'], @@ -597,6 +643,9 @@ const internalTemplates = { 'internal/yarn/empty/lit-vite/default-ts': { name: 'Empty Lit + vite (pnpm)', script: 'mkdir {{beforeDir}} && cd {{beforeDir}}', + env: { + STORYBOOK_INIT_EMPTY_TYPE: 'lit-vite-ts', + }, expected: { ...baseTemplates['lit-vite/default-ts'].expected }, isInternal: true, skipTasks: ['bench'], diff --git a/scripts/sandbox/generate.ts b/scripts/sandbox/generate.ts index e14b8bac5f04..fc5ba32f03c6 100755 --- a/scripts/sandbox/generate.ts +++ b/scripts/sandbox/generate.ts @@ -28,7 +28,12 @@ import { LOCAL_REGISTRY_URL, } from '../utils/constants'; -const sbInit = async (cwd: string, flags?: string[], debug?: boolean) => { +const sbInit = async ( + cwd: string, + envVars: Record = {}, + flags?: string[], + debug?: boolean +) => { const sbCliBinaryPath = join(__dirname, `../../code/lib/cli/bin/index.js`); console.log(`🎁 Installing storybook`); const env = { STORYBOOK_DISABLE_TELEMETRY: 'true' }; @@ -61,11 +66,13 @@ const addStorybook = async ({ localRegistry, flags, debug, + env = {}, }: { baseDir: string; localRegistry: boolean; flags?: string[]; debug?: boolean; + env?: Record; }) => { const beforeDir = join(baseDir, BEFORE_DIR_NAME); const afterDir = join(baseDir, AFTER_DIR_NAME); @@ -84,10 +91,10 @@ const addStorybook = async ({ jackspeak: '2.1.1', }); - await sbInit(tmpDir, flags, debug); + await sbInit(tmpDir, env, flags, debug); }); } else { - await sbInit(tmpDir, flags, debug); + await sbInit(tmpDir, env, flags, debug); } } catch (e) { await remove(tmpDir); @@ -142,7 +149,7 @@ const runGenerators = async ( const limit = pLimit(1); await Promise.all( - generators.map(({ dirName, name, script, expected }) => + generators.map(({ dirName, name, script, expected, env }) => limit(async () => { let flags: string[] = []; if (expected.renderer === '@storybook/html') flags = ['--type html']; @@ -189,7 +196,7 @@ const runGenerators = async ( // Make sure there are no git projects in the folder await remove(join(beforeDir, '.git')); - await addStorybook({ baseDir, localRegistry, flags, debug }); + await addStorybook({ baseDir, localRegistry, flags, debug, env }); await addDocumentation(baseDir, { name, dirName }); diff --git a/scripts/sandbox/utils/types.ts b/scripts/sandbox/utils/types.ts index a9e61af5715d..39d4594aa6e5 100644 --- a/scripts/sandbox/utils/types.ts +++ b/scripts/sandbox/utils/types.ts @@ -6,4 +6,5 @@ export type GeneratorConfig = { renderer: string; builder: string; }; + env?: Record; }; From 0032ff2db3ceb3d80998dcb47e774b02567437d7 Mon Sep 17 00:00:00 2001 From: Shaun Lloyd Date: Wed, 29 Nov 2023 13:57:57 -0500 Subject: [PATCH 19/62] Skip all empty sandboxes --- code/lib/cli/src/sandbox-templates.ts | 40 +++++++++++++-------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/code/lib/cli/src/sandbox-templates.ts b/code/lib/cli/src/sandbox-templates.ts index dc45dce86e4e..c6eb3d068185 100644 --- a/code/lib/cli/src/sandbox-templates.ts +++ b/code/lib/cli/src/sandbox-templates.ts @@ -508,7 +508,7 @@ const internalTemplates = { }, expected: { ...baseTemplates['react-vite/default-ts'].expected }, isInternal: true, - skipTasks: ['bench'], + skipTasks: ['bench', 'e2e-tests-dev', 'chromatic'], }, 'internal/pnpm/empty/react-vite/default-ts': { name: 'Empty React + vite (pnpm)', @@ -518,7 +518,7 @@ const internalTemplates = { }, expected: { ...baseTemplates['react-vite/default-ts'].expected }, isInternal: true, - skipTasks: ['bench'], + skipTasks: ['bench', 'e2e-tests-dev', 'chromatic'], }, 'internal/yarn/empty/react-vite/default-ts': { name: 'Empty React + vite (pnpm)', @@ -528,7 +528,7 @@ const internalTemplates = { }, expected: { ...baseTemplates['react-vite/default-ts'].expected }, isInternal: true, - skipTasks: ['bench'], + skipTasks: ['bench', 'e2e-tests-dev', 'chromatic'], }, 'internal/npm/empty/nextjs/default-ts': { name: 'Empty Next.js (npm)', @@ -538,7 +538,7 @@ const internalTemplates = { }, expected: { ...baseTemplates['nextjs/default-ts'].expected }, isInternal: true, - skipTasks: ['bench'], + skipTasks: ['bench', 'e2e-tests-dev', 'chromatic'], }, 'internal/pnpm/empty/nextjs/default-ts': { name: 'Empty Next.js (pnpm)', @@ -548,7 +548,7 @@ const internalTemplates = { }, expected: { ...baseTemplates['nextjs/default-ts'].expected }, isInternal: true, - skipTasks: ['bench'], + skipTasks: ['bench', 'e2e-tests-dev', 'chromatic'], }, 'internal/yarn/empty/nextjs/default-ts': { name: 'Empty Next.js (pnpm)', @@ -558,7 +558,7 @@ const internalTemplates = { }, expected: { ...baseTemplates['nextjs/default-ts'].expected }, isInternal: true, - skipTasks: ['bench'], + skipTasks: ['bench', 'e2e-tests-dev', 'chromatic'], }, 'internal/npm/empty/vue3-vite/default-ts': { name: 'Empty Vue 3 + vite (npm)', @@ -568,7 +568,7 @@ const internalTemplates = { }, expected: { ...baseTemplates['vue3-vite/default-ts'].expected }, isInternal: true, - skipTasks: ['bench'], + skipTasks: ['bench', 'e2e-tests-dev', 'chromatic'], }, 'internal/pnpm/empty/vue3-vite/default-ts': { name: 'Empty Vue 3 + vite (pnpm)', @@ -578,7 +578,7 @@ const internalTemplates = { }, expected: { ...baseTemplates['vue3-vite/default-ts'].expected }, isInternal: true, - skipTasks: ['bench'], + skipTasks: ['bench', 'e2e-tests-dev', 'chromatic'], }, 'internal/yarn/empty/vue3-vite/default-ts': { name: 'Empty Vue 3 + vite (pnpm)', @@ -588,7 +588,7 @@ const internalTemplates = { }, expected: { ...baseTemplates['vue3-vite/default-ts'].expected }, isInternal: true, - skipTasks: ['bench'], + skipTasks: ['bench', 'e2e-tests-dev', 'chromatic'], }, 'internal/npm/empty/angular-cli/default-ts': { name: 'Empty Angular (npm)', @@ -598,7 +598,7 @@ const internalTemplates = { }, expected: { ...baseTemplates['angular-cli/default-ts'].expected }, isInternal: true, - skipTasks: ['bench'], + skipTasks: ['bench', 'e2e-tests-dev', 'chromatic'], }, 'internal/pnpm/empty/angular-cli/default-ts': { name: 'Empty Angular (pnpm)', @@ -608,7 +608,7 @@ const internalTemplates = { }, expected: { ...baseTemplates['angular-cli/default-ts'].expected }, isInternal: true, - skipTasks: ['bench'], + skipTasks: ['bench', 'e2e-tests-dev', 'chromatic'], }, 'internal/yarn/empty/angular-cli/default-ts': { name: 'Empty Angular (pnpm)', @@ -618,7 +618,7 @@ const internalTemplates = { }, expected: { ...baseTemplates['angular-cli/default-ts'].expected }, isInternal: true, - skipTasks: ['bench'], + skipTasks: ['bench', 'e2e-tests-dev', 'chromatic'], }, 'internal/npm/empty/lit-vite/default-ts': { name: 'Empty Lit + vite (npm)', @@ -628,7 +628,7 @@ const internalTemplates = { }, expected: { ...baseTemplates['lit-vite/default-ts'].expected }, isInternal: true, - skipTasks: ['bench'], + skipTasks: ['bench', 'e2e-tests-dev', 'chromatic'], }, 'internal/pnpm/empty/lit-vite/default-ts': { name: 'Empty Lit + vite (pnpm)', @@ -638,7 +638,7 @@ const internalTemplates = { }, expected: { ...baseTemplates['lit-vite/default-ts'].expected }, isInternal: true, - skipTasks: ['bench'], + skipTasks: ['bench', 'e2e-tests-dev', 'chromatic'], }, 'internal/yarn/empty/lit-vite/default-ts': { name: 'Empty Lit + vite (pnpm)', @@ -648,7 +648,7 @@ const internalTemplates = { }, expected: { ...baseTemplates['lit-vite/default-ts'].expected }, isInternal: true, - skipTasks: ['bench'], + skipTasks: ['bench', 'e2e-tests-dev', 'chromatic'], }, // 'internal/pnp': { // ...baseTemplates['cra/default-ts'], @@ -747,19 +747,19 @@ export const merged: TemplateKey[] = [ const emptyTemplateKeys: TemplateKey[] = [ // 'internal/npm/empty/react-vite/default-ts', // 'internal/pnpm/empty/react-vite/default-ts', - 'internal/yarn/empty/react-vite/default-ts', + // 'internal/yarn/empty/react-vite/default-ts', // 'internal/npm/empty/nextjs/default-ts', // 'internal/pnpm/empty/nextjs/default-ts', - 'internal/yarn/empty/nextjs/default-ts', + // 'internal/yarn/empty/nextjs/default-ts', // 'internal/npm/empty/vue3-vite/default-ts', // 'internal/pnpm/empty/vue3-vite/default-ts', - 'internal/yarn/empty/vue3-vite/default-ts', + // 'internal/yarn/empty/vue3-vite/default-ts', // 'internal/npm/empty/angular-cli/default-ts', // 'internal/pnpm/empty/angular-cli/default-ts', - 'internal/yarn/empty/angular-cli/default-ts', + // 'internal/yarn/empty/angular-cli/default-ts', // 'internal/npm/empty/lit-vite/default-ts', // 'internal/pnpm/empty/lit-vite/default-ts', - 'internal/yarn/empty/lit-vite/default-ts', + // 'internal/yarn/empty/lit-vite/default-ts', ]; export const daily: TemplateKey[] = [ From 07790cbb5160cf2ffe07ec0af2dae08eff4fb5f8 Mon Sep 17 00:00:00 2001 From: Shaun Lloyd Date: Wed, 29 Nov 2023 14:28:27 -0500 Subject: [PATCH 20/62] Start writing CircleCI script to test empty init --- .circleci/config.yml | 36 ++++++++++++++++++++++++ code/lib/cli/src/generate.ts | 6 +++- code/lib/cli/src/scaffold-new-project.ts | 2 +- 3 files changed, 42 insertions(+), 2 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 6db12bf41959..fade0321ea29 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -472,6 +472,32 @@ jobs: command: yarn upload-bench $(yarn get-template --cadence << pipeline.parameters.workflow >> --task bench) - report-workflow-on-failure: template: $(yarn get-template --cadence << pipeline.parameters.workflow >> --task bench) + test-empty-init: + parameters: + packageManager: + type: string + template: + type: string + parallelism: + type: integer + parallelism: << parameters.parallelism >> + steps: + - git-shallow-clone/checkout_advanced: + clone_options: '--depth 1 --verbose' + - attach_workspace: + at: . + - run: + name: Move to parent directory + command: cd .. + - run: + name: Create empty project + command: mkdir empty-<< parameters.template >> && cd empty-<< parameters.template >> + - run: + name: Run storybook init + command: yarn storybook init + environment: + STORYBOOK_PACKAGE_MANAGER: << parameters.packageManager >> + STORYBOOK_INIT_EMPTY_TYPE: << parameters.template >> workflows: docs: @@ -640,6 +666,16 @@ workflows: parallelism: 31 requires: - build-sandboxes + # TODO: Uncomment when ready to test + # - test-empty-init: + # parallelism: 15 + # requires: + # - build + # matrix: + # parameters: + # packageManager: [yarn2], + # template: ["react-vite-ts", "nextjs-ts", "vue-vite-ts", "angular-cli", "lit-vite-ts"] + # TODO: reenable once we find out the source of flakyness # - test-runner-dev: # parallelism: 4 diff --git a/code/lib/cli/src/generate.ts b/code/lib/cli/src/generate.ts index bc396ec428b7..07620c9ee1e2 100644 --- a/code/lib/cli/src/generate.ts +++ b/code/lib/cli/src/generate.ts @@ -47,7 +47,11 @@ command('init') .description('Initialize Storybook into your project.') .option('-f --force', 'Force add Storybook') .option('-s --skip-install', 'Skip installing deps') - .option('--package-manager ', 'Force package manager for installing deps') + .option( + '--package-manager ', + 'Force package manager for installing deps', + process.env.STORYBOOK_PACKAGE_MANAGER + ) .option('-N --use-npm', 'Use npm to install deps (deprecated)') .option('--use-pnp', 'Enable pnp mode for Yarn 2+') .option('-p --parser ', 'jscodeshift parser') diff --git a/code/lib/cli/src/scaffold-new-project.ts b/code/lib/cli/src/scaffold-new-project.ts index 59df8318ce72..b65301a710d3 100644 --- a/code/lib/cli/src/scaffold-new-project.ts +++ b/code/lib/cli/src/scaffold-new-project.ts @@ -109,7 +109,7 @@ const buildProjectDisplayNameForPrint = ({ displayName }: SupportedProject) => { * @param packageManager The package manager to use. */ export const scaffoldNewProject = async (packageManager: PackageManagerName) => { - const packageManagerName = 'pnpm'; // packageManagerToCoercedName(packageManager); + const packageManagerName = packageManagerToCoercedName(packageManager); logger.plain( boxen( From 3b8cdc4c7ee4752e8819ae9b0c1687c8e95c2315 Mon Sep 17 00:00:00 2001 From: Shaun Lloyd Date: Wed, 29 Nov 2023 14:39:40 -0500 Subject: [PATCH 21/62] Test out empty init circle job --- .circleci/config.yml | 79 +++++++++++++++++++----------------- code/lib/cli/src/generate.ts | 6 +-- 2 files changed, 43 insertions(+), 42 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index fade0321ea29..8a1eef83b2c5 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -494,10 +494,15 @@ jobs: command: mkdir empty-<< parameters.template >> && cd empty-<< parameters.template >> - run: name: Run storybook init - command: yarn storybook init + command: node ../storybook/code/lib/cli/bin.js init --packageManager << parameters.packageManager >> environment: - STORYBOOK_PACKAGE_MANAGER: << parameters.packageManager >> + CI: true STORYBOOK_INIT_EMPTY_TYPE: << parameters.template >> + - run: + name: Run Smoke test + command: node ../storybook/code/lib/cli/bin.js dev --smoke-test + environment: + CI: true workflows: docs: @@ -636,45 +641,45 @@ workflows: - script-checks: requires: - build - - chromatic-internal-storybooks: - requires: - - build - - create-sandboxes: - parallelism: 36 - requires: - - build + # - chromatic-internal-storybooks: + # requires: + # - build + # - create-sandboxes: + # parallelism: 36 + # requires: + # - build # - smoke-test-sandboxes: # disabled for now # requires: # - create-sandboxes - - build-sandboxes: - parallelism: 36 - requires: - - create-sandboxes - - chromatic-sandboxes: - parallelism: 33 - requires: - - build-sandboxes - - e2e-production: - parallelism: 31 - requires: - - build-sandboxes - - e2e-dev: - parallelism: 2 - requires: - - create-sandboxes - - test-runner-production: - parallelism: 31 - requires: - - build-sandboxes - # TODO: Uncomment when ready to test - # - test-empty-init: - # parallelism: 15 + # - build-sandboxes: + # parallelism: 36 # requires: - # - build - # matrix: - # parameters: - # packageManager: [yarn2], - # template: ["react-vite-ts", "nextjs-ts", "vue-vite-ts", "angular-cli", "lit-vite-ts"] + # - create-sandboxes + # - chromatic-sandboxes: + # parallelism: 33 + # requires: + # - build-sandboxes + # - e2e-production: + # parallelism: 31 + # requires: + # - build-sandboxes + # - e2e-dev: + # parallelism: 2 + # requires: + # - create-sandboxes + # - test-runner-production: + # parallelism: 31 + # requires: + # - build-sandboxes + # TODO: Uncomment when ready to test + - test-empty-init: + parallelism: 5 + requires: + - build + matrix: + parameters: + packageManager: [yarn2], + template: ["react-vite-ts", "nextjs-ts", "vue-vite-ts", "angular-cli", "lit-vite-ts"] # TODO: reenable once we find out the source of flakyness # - test-runner-dev: diff --git a/code/lib/cli/src/generate.ts b/code/lib/cli/src/generate.ts index 07620c9ee1e2..bc396ec428b7 100644 --- a/code/lib/cli/src/generate.ts +++ b/code/lib/cli/src/generate.ts @@ -47,11 +47,7 @@ command('init') .description('Initialize Storybook into your project.') .option('-f --force', 'Force add Storybook') .option('-s --skip-install', 'Skip installing deps') - .option( - '--package-manager ', - 'Force package manager for installing deps', - process.env.STORYBOOK_PACKAGE_MANAGER - ) + .option('--package-manager ', 'Force package manager for installing deps') .option('-N --use-npm', 'Use npm to install deps (deprecated)') .option('--use-pnp', 'Enable pnp mode for Yarn 2+') .option('-p --parser ', 'jscodeshift parser') From 8e20a757f9f20c8fc751a6cf413ea9665c02c9c0 Mon Sep 17 00:00:00 2001 From: Shaun Lloyd Date: Wed, 29 Nov 2023 14:46:05 -0500 Subject: [PATCH 22/62] oops --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 8a1eef83b2c5..fc124c51125e 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -678,7 +678,7 @@ workflows: - build matrix: parameters: - packageManager: [yarn2], + packageManager: ["yarn2"], template: ["react-vite-ts", "nextjs-ts", "vue-vite-ts", "angular-cli", "lit-vite-ts"] # TODO: reenable once we find out the source of flakyness From f1158399bf7709bcf62e31da4f278da43bd6439d Mon Sep 17 00:00:00 2001 From: Shaun Lloyd Date: Wed, 29 Nov 2023 14:48:18 -0500 Subject: [PATCH 23/62] try again --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index fc124c51125e..ba723314b10f 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -678,7 +678,7 @@ workflows: - build matrix: parameters: - packageManager: ["yarn2"], + packageManager: ["yarn2"] template: ["react-vite-ts", "nextjs-ts", "vue-vite-ts", "angular-cli", "lit-vite-ts"] # TODO: reenable once we find out the source of flakyness From 4eb0c2bbc62c4464b0a87998d4c578c4b3c9bdf5 Mon Sep 17 00:00:00 2001 From: Shaun Lloyd Date: Wed, 29 Nov 2023 14:54:47 -0500 Subject: [PATCH 24/62] one more time --- .circleci/config.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.circleci/config.yml b/.circleci/config.yml index ba723314b10f..50c9d8d86506 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -473,6 +473,9 @@ jobs: - report-workflow-on-failure: template: $(yarn get-template --cadence << pipeline.parameters.workflow >> --task bench) test-empty-init: + executor: + class: medium + name: sb_node_16_browsers parameters: packageManager: type: string @@ -671,6 +674,7 @@ workflows: # parallelism: 31 # requires: # - build-sandboxes + # TODO: Uncomment when ready to test - test-empty-init: parallelism: 5 From acfc94caffc995bb0fff19e12730c211c88d657e Mon Sep 17 00:00:00 2001 From: Shaun Evening Date: Wed, 29 Nov 2023 14:57:26 -0500 Subject: [PATCH 25/62] Updated config.yml --- .circleci/config.yml | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 50c9d8d86506..8ad1c098c1d8 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -493,19 +493,19 @@ jobs: name: Move to parent directory command: cd .. - run: - name: Create empty project - command: mkdir empty-<< parameters.template >> && cd empty-<< parameters.template >> + name: Create empty project + command: mkdir empty-<< parameters.template >> && cd empty-<< parameters.template >> - run: - name: Run storybook init - command: node ../storybook/code/lib/cli/bin.js init --packageManager << parameters.packageManager >> - environment: - CI: true - STORYBOOK_INIT_EMPTY_TYPE: << parameters.template >> + name: Run storybook init + command: node ../storybook/code/lib/cli/bin.js init --packageManager << parameters.packageManager >> + environment: + CI: true + STORYBOOK_INIT_EMPTY_TYPE: << parameters.template >> - run: - name: Run Smoke test - command: node ../storybook/code/lib/cli/bin.js dev --smoke-test - environment: - CI: true + name: Run Smoke test + command: node ../storybook/code/lib/cli/bin.js dev --smoke-test + environment: + CI: true workflows: docs: From 0b011b97dc48e46481af28e183666d3ee457e420 Mon Sep 17 00:00:00 2001 From: Shaun Lloyd Date: Wed, 29 Nov 2023 15:10:12 -0500 Subject: [PATCH 26/62] Actually get to the right file for the cli bin --- .circleci/config.yml | 58 ++++++++++++++++++++++---------------------- 1 file changed, 29 insertions(+), 29 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 8ad1c098c1d8..0914d6b81d87 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -497,13 +497,13 @@ jobs: command: mkdir empty-<< parameters.template >> && cd empty-<< parameters.template >> - run: name: Run storybook init - command: node ../storybook/code/lib/cli/bin.js init --packageManager << parameters.packageManager >> + command: node ../storybook/code/lib/cli/bin/index.js init --packageManager << parameters.packageManager >> environment: CI: true STORYBOOK_INIT_EMPTY_TYPE: << parameters.template >> - run: name: Run Smoke test - command: node ../storybook/code/lib/cli/bin.js dev --smoke-test + command: node ../storybook/code/lib/cli/bin/index.js dev --smoke-test environment: CI: true @@ -644,36 +644,36 @@ workflows: - script-checks: requires: - build - # - chromatic-internal-storybooks: - # requires: - # - build - # - create-sandboxes: - # parallelism: 36 - # requires: - # - build + - chromatic-internal-storybooks: + requires: + - build + - create-sandboxes: + parallelism: 36 + requires: + - build # - smoke-test-sandboxes: # disabled for now # requires: # - create-sandboxes - # - build-sandboxes: - # parallelism: 36 - # requires: - # - create-sandboxes - # - chromatic-sandboxes: - # parallelism: 33 - # requires: - # - build-sandboxes - # - e2e-production: - # parallelism: 31 - # requires: - # - build-sandboxes - # - e2e-dev: - # parallelism: 2 - # requires: - # - create-sandboxes - # - test-runner-production: - # parallelism: 31 - # requires: - # - build-sandboxes + - build-sandboxes: + parallelism: 36 + requires: + - create-sandboxes + - chromatic-sandboxes: + parallelism: 33 + requires: + - build-sandboxes + - e2e-production: + parallelism: 31 + requires: + - build-sandboxes + - e2e-dev: + parallelism: 2 + requires: + - create-sandboxes + - test-runner-production: + parallelism: 31 + requires: + - build-sandboxes # TODO: Uncomment when ready to test - test-empty-init: From cd20c52231c7a39948193ea601998ef8687668cd Mon Sep 17 00:00:00 2001 From: Shaun Lloyd Date: Wed, 29 Nov 2023 15:18:20 -0500 Subject: [PATCH 27/62] fix package manager flag --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 0914d6b81d87..a069d00bd616 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -497,7 +497,7 @@ jobs: command: mkdir empty-<< parameters.template >> && cd empty-<< parameters.template >> - run: name: Run storybook init - command: node ../storybook/code/lib/cli/bin/index.js init --packageManager << parameters.packageManager >> + command: node ../storybook/code/lib/cli/bin/index.js init --package-manager << parameters.packageManager >> environment: CI: true STORYBOOK_INIT_EMPTY_TYPE: << parameters.template >> From 826ab3da9eb3af45ecfee64adaa2352ab3a51a29 Mon Sep 17 00:00:00 2001 From: Shaun Lloyd Date: Wed, 29 Nov 2023 15:42:45 -0500 Subject: [PATCH 28/62] Make sure empty projects are init in the right dir --- .circleci/config.yml | 24 +++++++----------------- 1 file changed, 7 insertions(+), 17 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index a069d00bd616..8ab32f9f44a8 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -481,31 +481,22 @@ jobs: type: string template: type: string - parallelism: - type: integer - parallelism: << parameters.parallelism >> steps: - git-shallow-clone/checkout_advanced: clone_options: '--depth 1 --verbose' - attach_workspace: at: . - run: - name: Move to parent directory - command: cd .. - - run: - name: Create empty project - command: mkdir empty-<< parameters.template >> && cd empty-<< parameters.template >> - - run: - name: Run storybook init - command: node ../storybook/code/lib/cli/bin/index.js init --package-manager << parameters.packageManager >> + name: Storybook init from empty directory + command: | + cd ../ + mkdir empty-<< parameters.template >> + cd empty-<< parameters.template >> + node ../storybook/code/lib/cli/bin/index.js init --package-manager << parameters.packageManager >> + node ../storybook/code/lib/cli/bin/index.js dev --smoke-test environment: CI: true STORYBOOK_INIT_EMPTY_TYPE: << parameters.template >> - - run: - name: Run Smoke test - command: node ../storybook/code/lib/cli/bin/index.js dev --smoke-test - environment: - CI: true workflows: docs: @@ -677,7 +668,6 @@ workflows: # TODO: Uncomment when ready to test - test-empty-init: - parallelism: 5 requires: - build matrix: From b4250b3cabc90c15c5dd971833f8e757ef820c74 Mon Sep 17 00:00:00 2001 From: Shaun Lloyd Date: Wed, 29 Nov 2023 15:50:34 -0500 Subject: [PATCH 29/62] add --yes --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 8ab32f9f44a8..143f8a7f60c8 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -492,7 +492,7 @@ jobs: cd ../ mkdir empty-<< parameters.template >> cd empty-<< parameters.template >> - node ../storybook/code/lib/cli/bin/index.js init --package-manager << parameters.packageManager >> + node ../storybook/code/lib/cli/bin/index.js init --yes --package-manager << parameters.packageManager >> node ../storybook/code/lib/cli/bin/index.js dev --smoke-test environment: CI: true From 1cfd09ed6f8160627b5cbe310fe28db308b4855b Mon Sep 17 00:00:00 2001 From: Shaun Lloyd Date: Wed, 29 Nov 2023 16:16:36 -0500 Subject: [PATCH 30/62] Try npm instead --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 143f8a7f60c8..b51f17efc9cd 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -672,7 +672,7 @@ workflows: - build matrix: parameters: - packageManager: ["yarn2"] + packageManager: ["npm"] template: ["react-vite-ts", "nextjs-ts", "vue-vite-ts", "angular-cli", "lit-vite-ts"] # TODO: reenable once we find out the source of flakyness From 27252cb6562d42059b1d1de2cec03f653cf00c37 Mon Sep 17 00:00:00 2001 From: Shaun Lloyd Date: Thu, 30 Nov 2023 08:19:12 -0500 Subject: [PATCH 31/62] try adding --yes back --- .circleci/config.yml | 2 +- code/lib/cli/src/scaffold-new-project.ts | 18 +++++++++--------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index b51f17efc9cd..143f8a7f60c8 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -672,7 +672,7 @@ workflows: - build matrix: parameters: - packageManager: ["npm"] + packageManager: ["yarn2"] template: ["react-vite-ts", "nextjs-ts", "vue-vite-ts", "angular-cli", "lit-vite-ts"] # TODO: reenable once we find out the source of flakyness diff --git a/code/lib/cli/src/scaffold-new-project.ts b/code/lib/cli/src/scaffold-new-project.ts index b65301a710d3..96795bd5b5f8 100644 --- a/code/lib/cli/src/scaffold-new-project.ts +++ b/code/lib/cli/src/scaffold-new-project.ts @@ -32,9 +32,9 @@ const SUPPORTED_PROJECTS: Record = { language: 'TS', }, createScript: { - npm: 'npm create vite@latest . -- --template react-ts', - yarn: 'yarn create vite@latest . --template react-ts', - pnpm: 'pnpm create vite@latest . --template react-ts', + npm: 'npm create vite@latest --yes . -- --template react-ts', + yarn: 'yarn create vite@latest --yes . --template react-ts', + pnpm: 'pnpm create vite@latest --yes . --template react-ts', }, }, 'nextjs-ts': { @@ -55,9 +55,9 @@ const SUPPORTED_PROJECTS: Record = { language: 'TS', }, createScript: { - npm: 'npm create vite@latest . -- --template vue-ts', - yarn: 'yarn create vite@latest . --template vue-ts', - pnpm: 'pnpm create vite@latest . --template vue-ts', + npm: 'npm create vite@latest --yes . -- --template vue-ts', + yarn: 'yarn create vite@latest --yes . --template vue-ts', + pnpm: 'pnpm create vite@latest --yes . --template vue-ts', }, }, 'angular-cli': { @@ -78,9 +78,9 @@ const SUPPORTED_PROJECTS: Record = { language: 'TS', }, createScript: { - npm: 'npm create vite@latest . -- --template lit-ts', - yarn: 'yarn create vite . --template lit-ts && touch yarn.lock && yarn set version berry && yarn config set nodeLinker pnp', - pnpm: 'pnpm create vite@latest . --template lit-ts', + npm: 'npm create vite@latest --yes . -- --template lit-ts', + yarn: 'yarn create vite@latest --yes . --template lit-ts && touch yarn.lock && yarn set version berry && yarn config set nodeLinker pnp', + pnpm: 'pnpm create vite@latest --yes . --template lit-ts', }, }, }; From d66e4bce3a75afa06ef09d5addc91c4588cd2bc4 Mon Sep 17 00:00:00 2001 From: Shaun Lloyd Date: Thu, 30 Nov 2023 08:43:21 -0500 Subject: [PATCH 32/62] Try echoing out env var --- .circleci/config.yml | 92 ++++++++++++++++++++++++-------------------- 1 file changed, 50 insertions(+), 42 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 143f8a7f60c8..562fdbd7f4aa 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -492,11 +492,13 @@ jobs: cd ../ mkdir empty-<< parameters.template >> cd empty-<< parameters.template >> + echo empty init type: $STORYBOOK_INIT_EMPTY_TYPE node ../storybook/code/lib/cli/bin/index.js init --yes --package-manager << parameters.packageManager >> node ../storybook/code/lib/cli/bin/index.js dev --smoke-test environment: CI: true STORYBOOK_INIT_EMPTY_TYPE: << parameters.template >> + - report-workflow-on-failure workflows: docs: @@ -621,50 +623,50 @@ workflows: when: equal: [daily, << pipeline.parameters.workflow >>] jobs: - - pretty-docs + # - pretty-docs - build - - lint: - requires: - - build - - check: - requires: - - build - - unit-tests: - requires: - - build - - script-checks: - requires: - - build - - chromatic-internal-storybooks: - requires: - - build - - create-sandboxes: - parallelism: 36 - requires: - - build + # - lint: + # requires: + # - build + # - check: + # requires: + # - build + # - unit-tests: + # requires: + # - build + # - script-checks: + # requires: + # - build + # - chromatic-internal-storybooks: + # requires: + # - build + # - create-sandboxes: + # parallelism: 36 + # requires: + # - build # - smoke-test-sandboxes: # disabled for now # requires: # - create-sandboxes - - build-sandboxes: - parallelism: 36 - requires: - - create-sandboxes - - chromatic-sandboxes: - parallelism: 33 - requires: - - build-sandboxes - - e2e-production: - parallelism: 31 - requires: - - build-sandboxes - - e2e-dev: - parallelism: 2 - requires: - - create-sandboxes - - test-runner-production: - parallelism: 31 - requires: - - build-sandboxes + # - build-sandboxes: + # parallelism: 36 + # requires: + # - create-sandboxes + # - chromatic-sandboxes: + # parallelism: 33 + # requires: + # - build-sandboxes + # - e2e-production: + # parallelism: 31 + # requires: + # - build-sandboxes + # - e2e-dev: + # parallelism: 2 + # requires: + # - create-sandboxes + # - test-runner-production: + # parallelism: 31 + # requires: + # - build-sandboxes # TODO: Uncomment when ready to test - test-empty-init: @@ -672,8 +674,14 @@ workflows: - build matrix: parameters: - packageManager: ["yarn2"] - template: ["react-vite-ts", "nextjs-ts", "vue-vite-ts", "angular-cli", "lit-vite-ts"] + packageManager: + - "yarn2" + template: + - "react-vite-ts" + # - "nextjs-ts" + # - "vue-vite-ts" + # - "angular-cli" + # - "lit-vite-ts" # TODO: reenable once we find out the source of flakyness # - test-runner-dev: From c81c38e27cdc9683dc9ad0d0543bf38bbe9862bf Mon Sep 17 00:00:00 2001 From: Shaun Lloyd Date: Thu, 30 Nov 2023 09:06:30 -0500 Subject: [PATCH 33/62] Print the WD --- .circleci/config.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.circleci/config.yml b/.circleci/config.yml index 562fdbd7f4aa..3121471aea56 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -493,11 +493,13 @@ jobs: mkdir empty-<< parameters.template >> cd empty-<< parameters.template >> echo empty init type: $STORYBOOK_INIT_EMPTY_TYPE + echo pwd node ../storybook/code/lib/cli/bin/index.js init --yes --package-manager << parameters.packageManager >> node ../storybook/code/lib/cli/bin/index.js dev --smoke-test environment: CI: true STORYBOOK_INIT_EMPTY_TYPE: << parameters.template >> + STORYBOOK_DISABLE_TELEMETRY: true - report-workflow-on-failure workflows: From 95c78896f5ae0f32128735ff8ec0b3572d07d418 Mon Sep 17 00:00:00 2001 From: Shaun Lloyd Date: Thu, 30 Nov 2023 09:20:58 -0500 Subject: [PATCH 34/62] Try setting yarn to berry --- .circleci/config.yml | 3 +-- code/lib/cli/src/scaffold-new-project.ts | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 3121471aea56..5527b1e9899b 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -492,8 +492,7 @@ jobs: cd ../ mkdir empty-<< parameters.template >> cd empty-<< parameters.template >> - echo empty init type: $STORYBOOK_INIT_EMPTY_TYPE - echo pwd + yarn set version berry node ../storybook/code/lib/cli/bin/index.js init --yes --package-manager << parameters.packageManager >> node ../storybook/code/lib/cli/bin/index.js dev --smoke-test environment: diff --git a/code/lib/cli/src/scaffold-new-project.ts b/code/lib/cli/src/scaffold-new-project.ts index 96795bd5b5f8..43e11a679857 100644 --- a/code/lib/cli/src/scaffold-new-project.ts +++ b/code/lib/cli/src/scaffold-new-project.ts @@ -196,7 +196,7 @@ export const scaffoldNewProject = async (packageManager: PackageManagerName) => logger.line(1); }; -const IGNORED_FILES = ['.git', '.gitignore', '.DS_Store']; +const IGNORED_FILES = ['.git', '.gitignore', '.DS_Store', '.yarn', '.yarnrc.yml']; export const currentDirectoryIsEmpty = () => { const cwdFolderEntries = readdirSync(process.cwd()); From 71955953390cb691413c10b34dbca228264441c8 Mon Sep 17 00:00:00 2001 From: Shaun Lloyd Date: Thu, 30 Nov 2023 09:28:41 -0500 Subject: [PATCH 35/62] Test npm instead --- .circleci/config.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 5527b1e9899b..22812776c801 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -492,7 +492,6 @@ jobs: cd ../ mkdir empty-<< parameters.template >> cd empty-<< parameters.template >> - yarn set version berry node ../storybook/code/lib/cli/bin/index.js init --yes --package-manager << parameters.packageManager >> node ../storybook/code/lib/cli/bin/index.js dev --smoke-test environment: @@ -676,7 +675,7 @@ workflows: matrix: parameters: packageManager: - - "yarn2" + - "npm" template: - "react-vite-ts" # - "nextjs-ts" From a7ff9e779c31bbc4c7f25f0862ba1b906363a42f Mon Sep 17 00:00:00 2001 From: Shaun Lloyd Date: Thu, 30 Nov 2023 09:39:24 -0500 Subject: [PATCH 36/62] Set in sandbox to true --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 22812776c801..f1490d2920df 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -495,7 +495,7 @@ jobs: node ../storybook/code/lib/cli/bin/index.js init --yes --package-manager << parameters.packageManager >> node ../storybook/code/lib/cli/bin/index.js dev --smoke-test environment: - CI: true + IN_STORYBOOK_SANDBOX: true STORYBOOK_INIT_EMPTY_TYPE: << parameters.template >> STORYBOOK_DISABLE_TELEMETRY: true - report-workflow-on-failure From d36324c2bfb73ae91b2c05452fcd0a0f9d6d2822 Mon Sep 17 00:00:00 2001 From: Shaun Lloyd Date: Thu, 30 Nov 2023 09:45:18 -0500 Subject: [PATCH 37/62] run all empty templates --- .circleci/config.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index f1490d2920df..5000731b2570 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -678,10 +678,10 @@ workflows: - "npm" template: - "react-vite-ts" - # - "nextjs-ts" - # - "vue-vite-ts" - # - "angular-cli" - # - "lit-vite-ts" + - "nextjs-ts" + - "vue-vite-ts" + - "angular-cli" + - "lit-vite-ts" # TODO: reenable once we find out the source of flakyness # - test-runner-dev: From 5175507e621b7754a782a24b4e5aff517fa5e0f6 Mon Sep 17 00:00:00 2001 From: Shaun Lloyd Date: Thu, 30 Nov 2023 11:32:12 -0500 Subject: [PATCH 38/62] Add conditional logic --- .circleci/config.yml | 46 +++++++++++++++++++++++++++++++++++--------- 1 file changed, 37 insertions(+), 9 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 5000731b2570..7d5be7d19430 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -486,14 +486,41 @@ jobs: clone_options: '--depth 1 --verbose' - attach_workspace: at: . - - run: - name: Storybook init from empty directory - command: | - cd ../ - mkdir empty-<< parameters.template >> - cd empty-<< parameters.template >> - node ../storybook/code/lib/cli/bin/index.js init --yes --package-manager << parameters.packageManager >> - node ../storybook/code/lib/cli/bin/index.js dev --smoke-test + - when: + equal: ["npm", << parameters.packageManager >>] + steps: + - run: + name: Storybook init from empty directory (NPM) + command: | + cd ../ + mkdir empty-<< parameters.template >> + cd empty-<< parameters.template >> + node ../storybook/code/lib/cli/bin/index.js init --yes --package-manager npm + npm run storybook -- --smoke-test + - when: + equal: ["yarn2", << parameters.packageManager >>] + steps: + - run: + name: Storybook init from empty directory (Yarn 2) + command: | + cd ../ + mkdir empty-<< parameters.template >> + cd empty-<< parameters.template >> + yarn set version berry + node ../storybook/code/lib/cli/bin/index.js init --yes --package-manager yarn2 + yarn storybook --smoke-test + - when: + equal: ["pnpm", << parameters.packageManager >>] + steps: + - run: + name: Storybook init from empty directory (PNPM) + command: | + cd ../ + mkdir empty-<< parameters.template >> + cd empty-<< parameters.template >> + npm i -g pnpm + node ../storybook/code/lib/cli/bin/index.js init --yes --package-manager pnpm + pnpm run storybook --smoke-test environment: IN_STORYBOOK_SANDBOX: true STORYBOOK_INIT_EMPTY_TYPE: << parameters.template >> @@ -680,7 +707,8 @@ workflows: - "react-vite-ts" - "nextjs-ts" - "vue-vite-ts" - - "angular-cli" + # --smoke-test is not supported for the angular builder right now + # - "angular-cli" - "lit-vite-ts" # TODO: reenable once we find out the source of flakyness From 24b947b67d36723c918ad01b2dae705d1aead8e7 Mon Sep 17 00:00:00 2001 From: Shaun Evening Date: Thu, 30 Nov 2023 11:35:22 -0500 Subject: [PATCH 39/62] Updated config.yml --- .circleci/config.yml | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 7d5be7d19430..d2489fa724d7 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -487,6 +487,7 @@ jobs: - attach_workspace: at: . - when: + condition: equal: ["npm", << parameters.packageManager >>] steps: - run: @@ -497,7 +498,12 @@ jobs: cd empty-<< parameters.template >> node ../storybook/code/lib/cli/bin/index.js init --yes --package-manager npm npm run storybook -- --smoke-test - - when: + environment: + IN_STORYBOOK_SANDBOX: true + STORYBOOK_INIT_EMPTY_TYPE: << parameters.template >> + STORYBOOK_DISABLE_TELEMETRY: true + - when: + condition: equal: ["yarn2", << parameters.packageManager >>] steps: - run: @@ -509,7 +515,12 @@ jobs: yarn set version berry node ../storybook/code/lib/cli/bin/index.js init --yes --package-manager yarn2 yarn storybook --smoke-test - - when: + environment: + IN_STORYBOOK_SANDBOX: true + STORYBOOK_INIT_EMPTY_TYPE: << parameters.template >> + STORYBOOK_DISABLE_TELEMETRY: true + - when: + condition: equal: ["pnpm", << parameters.packageManager >>] steps: - run: @@ -521,10 +532,10 @@ jobs: npm i -g pnpm node ../storybook/code/lib/cli/bin/index.js init --yes --package-manager pnpm pnpm run storybook --smoke-test - environment: - IN_STORYBOOK_SANDBOX: true - STORYBOOK_INIT_EMPTY_TYPE: << parameters.template >> - STORYBOOK_DISABLE_TELEMETRY: true + environment: + IN_STORYBOOK_SANDBOX: true + STORYBOOK_INIT_EMPTY_TYPE: << parameters.template >> + STORYBOOK_DISABLE_TELEMETRY: true - report-workflow-on-failure workflows: From 2956a018f706e41f9b7acd91c0c6ae4352a8429e Mon Sep 17 00:00:00 2001 From: Shaun Lloyd Date: Thu, 30 Nov 2023 11:45:25 -0500 Subject: [PATCH 40/62] Add yarn and pnpm --- .circleci/config.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.circleci/config.yml b/.circleci/config.yml index d2489fa724d7..6150b27d1f80 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -714,6 +714,8 @@ workflows: parameters: packageManager: - "npm" + - "yarn2" + - "pnpm" template: - "react-vite-ts" - "nextjs-ts" From 5cd8fbfc0bd45edc9a8cac36d3443d1d57f30457 Mon Sep 17 00:00:00 2001 From: Shaun Lloyd Date: Thu, 30 Nov 2023 14:16:40 -0500 Subject: [PATCH 41/62] Only run tests for NPM for now --- .circleci/config.yml | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 6150b27d1f80..5e155b7db533 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -502,6 +502,22 @@ jobs: IN_STORYBOOK_SANDBOX: true STORYBOOK_INIT_EMPTY_TYPE: << parameters.template >> STORYBOOK_DISABLE_TELEMETRY: true + - when: + condition: + equal: ["yarn1", << parameters.packageManager >>] + steps: + - run: + name: Storybook init from empty directory (Yarn 1) + command: | + cd ../ + mkdir empty-<< parameters.template >> + cd empty-<< parameters.template >> + node ../storybook/code/lib/cli/bin/index.js init --yes --package-manager yarn1 + yarn storybook --smoke-test + environment: + IN_STORYBOOK_SANDBOX: true + STORYBOOK_INIT_EMPTY_TYPE: << parameters.template >> + STORYBOOK_DISABLE_TELEMETRY: true - when: condition: equal: ["yarn2", << parameters.packageManager >>] @@ -714,8 +730,9 @@ workflows: parameters: packageManager: - "npm" - - "yarn2" - - "pnpm" + # - "yarn1" + # - "yarn2" + # - "pnpm" template: - "react-vite-ts" - "nextjs-ts" From 4114f70f7ebda5310a4bf3e71826f5d20daa9db2 Mon Sep 17 00:00:00 2001 From: Shaun Lloyd Date: Thu, 30 Nov 2023 14:18:06 -0500 Subject: [PATCH 42/62] Re-enable daily flow --- .circleci/config.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.circleci/config.yml b/.circleci/config.yml index 5e155b7db533..d16bff713c96 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -730,6 +730,7 @@ workflows: parameters: packageManager: - "npm" + # TODO: reenable once we find out the source of failure # - "yarn1" # - "yarn2" # - "pnpm" From 96e5271e64a25febf8ffacfab1399f2d10bbd04d Mon Sep 17 00:00:00 2001 From: Shaun Lloyd Date: Thu, 30 Nov 2023 14:18:15 -0500 Subject: [PATCH 43/62] Re-enable daily workflow --- .circleci/config.yml | 86 ++++++++++++++++++++++---------------------- 1 file changed, 43 insertions(+), 43 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index d16bff713c96..55e4086dc04f 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -677,50 +677,50 @@ workflows: when: equal: [daily, << pipeline.parameters.workflow >>] jobs: - # - pretty-docs + - pretty-docs - build - # - lint: - # requires: - # - build - # - check: - # requires: - # - build - # - unit-tests: - # requires: - # - build - # - script-checks: - # requires: - # - build - # - chromatic-internal-storybooks: - # requires: - # - build - # - create-sandboxes: - # parallelism: 36 - # requires: - # - build - # - smoke-test-sandboxes: # disabled for now - # requires: - # - create-sandboxes - # - build-sandboxes: - # parallelism: 36 - # requires: - # - create-sandboxes - # - chromatic-sandboxes: - # parallelism: 33 - # requires: - # - build-sandboxes - # - e2e-production: - # parallelism: 31 - # requires: - # - build-sandboxes - # - e2e-dev: - # parallelism: 2 - # requires: - # - create-sandboxes - # - test-runner-production: - # parallelism: 31 - # requires: - # - build-sandboxes + - lint: + requires: + - build + - check: + requires: + - build + - unit-tests: + requires: + - build + - script-checks: + requires: + - build + - chromatic-internal-storybooks: + requires: + - build + - create-sandboxes: + parallelism: 36 + requires: + - build + - smoke-test-sandboxes: # disabled for now + requires: + - create-sandboxes + - build-sandboxes: + parallelism: 36 + requires: + - create-sandboxes + - chromatic-sandboxes: + parallelism: 33 + requires: + - build-sandboxes + - e2e-production: + parallelism: 31 + requires: + - build-sandboxes + - e2e-dev: + parallelism: 2 + requires: + - create-sandboxes + - test-runner-production: + parallelism: 31 + requires: + - build-sandboxes # TODO: Uncomment when ready to test - test-empty-init: From 7b9b26980f1d8dc200242bb3725998bbc727d193 Mon Sep 17 00:00:00 2001 From: Shaun Evening Date: Thu, 30 Nov 2023 14:21:20 -0500 Subject: [PATCH 44/62] Updated config.yml --- .circleci/config.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 55e4086dc04f..dc5104a02e23 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -698,9 +698,9 @@ workflows: parallelism: 36 requires: - build - - smoke-test-sandboxes: # disabled for now - requires: - - create-sandboxes + # - smoke-test-sandboxes: # disabled for now + # requires: + # - create-sandboxes - build-sandboxes: parallelism: 36 requires: From 2eb8a9a32d453093f3c7c8a4edb89f082edf427b Mon Sep 17 00:00:00 2001 From: Shaun Lloyd Date: Thu, 30 Nov 2023 16:34:08 -0500 Subject: [PATCH 45/62] ignore package.json in pnpm dlx scenario --- code/lib/cli/src/scaffold-new-project.ts | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/code/lib/cli/src/scaffold-new-project.ts b/code/lib/cli/src/scaffold-new-project.ts index 43e11a679857..fbdc3bc9f2c4 100644 --- a/code/lib/cli/src/scaffold-new-project.ts +++ b/code/lib/cli/src/scaffold-new-project.ts @@ -196,13 +196,22 @@ export const scaffoldNewProject = async (packageManager: PackageManagerName) => logger.line(1); }; -const IGNORED_FILES = ['.git', '.gitignore', '.DS_Store', '.yarn', '.yarnrc.yml']; +const BASE_IGNORED_FILES = ['.git', '.gitignore', '.DS_Store']; -export const currentDirectoryIsEmpty = () => { +const IGNORED_FILES_BY_PACKAGE_MANAGER: Record = { + npm: [...BASE_IGNORED_FILES], + yarn: [...BASE_IGNORED_FILES, 'yarn.lock', '.yarnrc.yml', '.yarn'], + pnpm: [...BASE_IGNORED_FILES, 'pnpm-lock.yaml', '.pnpm', 'package.json'], +}; + +export const currentDirectoryIsEmpty = (packageManager: PackageManagerName) => { + const packageManagerName = packageManagerToCoercedName(packageManager); const cwdFolderEntries = readdirSync(process.cwd()); + const filesToIgnore = IGNORED_FILES_BY_PACKAGE_MANAGER[packageManagerName]; + return ( cwdFolderEntries.length === 0 || - cwdFolderEntries.every((entry) => IGNORED_FILES.includes(entry)) + cwdFolderEntries.every((entry) => filesToIgnore.includes(entry)) ); }; From 0046573f2224ad6a5834895c520fdcbf302011f1 Mon Sep 17 00:00:00 2001 From: Shaun Lloyd Date: Thu, 30 Nov 2023 16:51:04 -0500 Subject: [PATCH 46/62] ignore .cache --- code/lib/cli/src/scaffold-new-project.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/lib/cli/src/scaffold-new-project.ts b/code/lib/cli/src/scaffold-new-project.ts index fbdc3bc9f2c4..e1aec8f0e34f 100644 --- a/code/lib/cli/src/scaffold-new-project.ts +++ b/code/lib/cli/src/scaffold-new-project.ts @@ -196,7 +196,7 @@ export const scaffoldNewProject = async (packageManager: PackageManagerName) => logger.line(1); }; -const BASE_IGNORED_FILES = ['.git', '.gitignore', '.DS_Store']; +const BASE_IGNORED_FILES = ['.git', '.gitignore', '.DS_Store', '.cache']; const IGNORED_FILES_BY_PACKAGE_MANAGER: Record = { npm: [...BASE_IGNORED_FILES], From db79ce050ce04215d2769b94e82873492ffb09c7 Mon Sep 17 00:00:00 2001 From: Shaun Lloyd Date: Fri, 1 Dec 2023 11:35:37 -0500 Subject: [PATCH 47/62] Try running verdaccio in CI --- .circleci/config.yml | 85 ++++++++++++------------ code/lib/cli/src/dev.ts | 1 + code/lib/cli/src/initiate.ts | 3 +- code/lib/cli/src/scaffold-new-project.ts | 19 +++--- 4 files changed, 57 insertions(+), 51 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index dc5104a02e23..cfad6a0329d4 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -493,9 +493,12 @@ jobs: - run: name: Storybook init from empty directory (NPM) command: | - cd ../ + cd code + yarn local-registry --open & + cd ../../ mkdir empty-<< parameters.template >> cd empty-<< parameters.template >> + npm set registry http://localhost:6001 node ../storybook/code/lib/cli/bin/index.js init --yes --package-manager npm npm run storybook -- --smoke-test environment: @@ -677,50 +680,50 @@ workflows: when: equal: [daily, << pipeline.parameters.workflow >>] jobs: - - pretty-docs + # - pretty-docs - build - - lint: - requires: - - build - - check: - requires: - - build - - unit-tests: - requires: - - build - - script-checks: - requires: - - build - - chromatic-internal-storybooks: - requires: - - build - - create-sandboxes: - parallelism: 36 - requires: - - build + # - lint: + # requires: + # - build + # - check: + # requires: + # - build + # - unit-tests: + # requires: + # - build + # - script-checks: + # requires: + # - build + # - chromatic-internal-storybooks: + # requires: + # - build + # - create-sandboxes: + # parallelism: 36 + # requires: + # - build # - smoke-test-sandboxes: # disabled for now # requires: # - create-sandboxes - - build-sandboxes: - parallelism: 36 - requires: - - create-sandboxes - - chromatic-sandboxes: - parallelism: 33 - requires: - - build-sandboxes - - e2e-production: - parallelism: 31 - requires: - - build-sandboxes - - e2e-dev: - parallelism: 2 - requires: - - create-sandboxes - - test-runner-production: - parallelism: 31 - requires: - - build-sandboxes + # - build-sandboxes: + # parallelism: 36 + # requires: + # - create-sandboxes + # - chromatic-sandboxes: + # parallelism: 33 + # requires: + # - build-sandboxes + # - e2e-production: + # parallelism: 31 + # requires: + # - build-sandboxes + # - e2e-dev: + # parallelism: 2 + # requires: + # - create-sandboxes + # - test-runner-production: + # parallelism: 31 + # requires: + # - build-sandboxes # TODO: Uncomment when ready to test - test-empty-init: diff --git a/code/lib/cli/src/dev.ts b/code/lib/cli/src/dev.ts index ee82ae2cb7c4..ef507f9b9e34 100644 --- a/code/lib/cli/src/dev.ts +++ b/code/lib/cli/src/dev.ts @@ -38,6 +38,7 @@ function printError(error: any) { } export const dev = async (cliOptions: CLIOptions) => { + console.log('Hey there from dev!'); process.env.NODE_ENV = process.env.NODE_ENV || 'development'; const readUpResult = readUpSync({ cwd: __dirname }); diff --git a/code/lib/cli/src/initiate.ts b/code/lib/cli/src/initiate.ts index 9ae63ccc71b8..4355759575da 100644 --- a/code/lib/cli/src/initiate.ts +++ b/code/lib/cli/src/initiate.ts @@ -268,7 +268,7 @@ async function doInitiate( }); // Check if the current directory is empty. - if (options.force !== true && currentDirectoryIsEmpty()) { + if (options.force !== true && currentDirectoryIsEmpty(packageManager.type)) { // Prompt the user to create a new project from our list. await scaffoldNewProject(packageManager.type); } @@ -377,6 +377,7 @@ async function doInitiate( } export async function initiate(options: CommandOptions, pkg: PackageJson): Promise { + console.log('Hey there!'); const initiateResult = await withTelemetry( 'init', { diff --git a/code/lib/cli/src/scaffold-new-project.ts b/code/lib/cli/src/scaffold-new-project.ts index e1aec8f0e34f..dad37b3b8b5a 100644 --- a/code/lib/cli/src/scaffold-new-project.ts +++ b/code/lib/cli/src/scaffold-new-project.ts @@ -32,9 +32,9 @@ const SUPPORTED_PROJECTS: Record = { language: 'TS', }, createScript: { - npm: 'npm create vite@latest --yes . -- --template react-ts', - yarn: 'yarn create vite@latest --yes . --template react-ts', - pnpm: 'pnpm create vite@latest --yes . --template react-ts', + npm: 'npm create vite@latest . -- --template react-ts', + yarn: 'yarn create vite@latest . --template react-ts', + pnpm: 'pnpm create vite@latest . --template react-ts', }, }, 'nextjs-ts': { @@ -55,9 +55,9 @@ const SUPPORTED_PROJECTS: Record = { language: 'TS', }, createScript: { - npm: 'npm create vite@latest --yes . -- --template vue-ts', - yarn: 'yarn create vite@latest --yes . --template vue-ts', - pnpm: 'pnpm create vite@latest --yes . --template vue-ts', + npm: 'npm create vite@latest . -- --template vue-ts', + yarn: 'yarn create vite@latest . --template vue-ts', + pnpm: 'pnpm create vite@latest . --template vue-ts', }, }, 'angular-cli': { @@ -78,9 +78,9 @@ const SUPPORTED_PROJECTS: Record = { language: 'TS', }, createScript: { - npm: 'npm create vite@latest --yes . -- --template lit-ts', - yarn: 'yarn create vite@latest --yes . --template lit-ts && touch yarn.lock && yarn set version berry && yarn config set nodeLinker pnp', - pnpm: 'pnpm create vite@latest --yes . --template lit-ts', + npm: 'npm create vite@latest . -- --template lit-ts', + yarn: 'yarn create vite@latest . --template lit-ts && touch yarn.lock && yarn set version berry && yarn config set nodeLinker pnp', + pnpm: 'pnpm create vite@latest . --template lit-ts', }, }, }; @@ -210,6 +210,7 @@ export const currentDirectoryIsEmpty = (packageManager: PackageManagerName) => { const filesToIgnore = IGNORED_FILES_BY_PACKAGE_MANAGER[packageManagerName]; + console.log('PAckage manager used: ', packageManager, packageManagerName); return ( cwdFolderEntries.length === 0 || cwdFolderEntries.every((entry) => filesToIgnore.includes(entry)) From 2d4f4948e7458d16b48d1e456d556bdb8969f684 Mon Sep 17 00:00:00 2001 From: Shaun Lloyd Date: Fri, 1 Dec 2023 11:50:46 -0500 Subject: [PATCH 48/62] Update other package managers to use verdaccio --- .circleci/config.yml | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index cfad6a0329d4..9195aeea1ec0 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -512,7 +512,9 @@ jobs: - run: name: Storybook init from empty directory (Yarn 1) command: | - cd ../ + cd code + yarn local-registry --open & + cd ../../ mkdir empty-<< parameters.template >> cd empty-<< parameters.template >> node ../storybook/code/lib/cli/bin/index.js init --yes --package-manager yarn1 @@ -528,10 +530,13 @@ jobs: - run: name: Storybook init from empty directory (Yarn 2) command: | - cd ../ + cd code + yarn local-registry --open & + cd ../../ mkdir empty-<< parameters.template >> cd empty-<< parameters.template >> yarn set version berry + yarn config set registry http://localhost:6001 node ../storybook/code/lib/cli/bin/index.js init --yes --package-manager yarn2 yarn storybook --smoke-test environment: @@ -545,10 +550,13 @@ jobs: - run: name: Storybook init from empty directory (PNPM) command: | - cd ../ + cd code + yarn local-registry --open & + cd ../../ mkdir empty-<< parameters.template >> cd empty-<< parameters.template >> npm i -g pnpm + pnpm config set registry http://localhost:6001 node ../storybook/code/lib/cli/bin/index.js init --yes --package-manager pnpm pnpm run storybook --smoke-test environment: From a6379b09b80eecd9402878f34459131e4945d630 Mon Sep 17 00:00:00 2001 From: Shaun Lloyd Date: Fri, 1 Dec 2023 11:52:42 -0500 Subject: [PATCH 49/62] Try using npx in circleCI --- .circleci/config.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 9195aeea1ec0..a7723ed00b27 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -499,7 +499,7 @@ jobs: mkdir empty-<< parameters.template >> cd empty-<< parameters.template >> npm set registry http://localhost:6001 - node ../storybook/code/lib/cli/bin/index.js init --yes --package-manager npm + npx storybook init --yes --package-manager npm npm run storybook -- --smoke-test environment: IN_STORYBOOK_SANDBOX: true @@ -517,7 +517,7 @@ jobs: cd ../../ mkdir empty-<< parameters.template >> cd empty-<< parameters.template >> - node ../storybook/code/lib/cli/bin/index.js init --yes --package-manager yarn1 + npx storybook init --yes --package-manager yarn1 yarn storybook --smoke-test environment: IN_STORYBOOK_SANDBOX: true @@ -537,7 +537,7 @@ jobs: cd empty-<< parameters.template >> yarn set version berry yarn config set registry http://localhost:6001 - node ../storybook/code/lib/cli/bin/index.js init --yes --package-manager yarn2 + yarn dlx storybook init --yes --package-manager yarn2 yarn storybook --smoke-test environment: IN_STORYBOOK_SANDBOX: true @@ -557,7 +557,7 @@ jobs: cd empty-<< parameters.template >> npm i -g pnpm pnpm config set registry http://localhost:6001 - node ../storybook/code/lib/cli/bin/index.js init --yes --package-manager pnpm + pnpm dlx storybook init --yes --package-manager pnpm pnpm run storybook --smoke-test environment: IN_STORYBOOK_SANDBOX: true From 4ed6f9928bc242723750547e4fffc132565af8ea Mon Sep 17 00:00:00 2001 From: Shaun Lloyd Date: Mon, 4 Dec 2023 09:06:58 -0500 Subject: [PATCH 50/62] Resolve version issue for CLI --- code/lib/cli/src/initiate.ts | 8 +++++++- code/lib/cli/src/scaffold-new-project.ts | 1 - 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/code/lib/cli/src/initiate.ts b/code/lib/cli/src/initiate.ts index 4355759575da..e74b208d1da2 100644 --- a/code/lib/cli/src/initiate.ts +++ b/code/lib/cli/src/initiate.ts @@ -36,6 +36,7 @@ import type { NpmOptions } from './NpmOptions'; import type { CommandOptions, GeneratorOptions } from './generators/types'; import { HandledError } from './HandledError'; import { currentDirectoryIsEmpty, scaffoldNewProject } from './scaffold-new-project'; +import versions from './versions'; const logger = console; @@ -271,6 +272,12 @@ async function doInitiate( if (options.force !== true && currentDirectoryIsEmpty(packageManager.type)) { // Prompt the user to create a new project from our list. await scaffoldNewProject(packageManager.type); + + if (process.env.IN_STORYBOOK_SANDBOX === 'true' || process.env.CI === 'true') { + packageManager.addPackageResolutions({ + '@storybook/telemetry': versions['@storybook/telemetry'], + }); + } } let projectType: ProjectType; @@ -377,7 +384,6 @@ async function doInitiate( } export async function initiate(options: CommandOptions, pkg: PackageJson): Promise { - console.log('Hey there!'); const initiateResult = await withTelemetry( 'init', { diff --git a/code/lib/cli/src/scaffold-new-project.ts b/code/lib/cli/src/scaffold-new-project.ts index dad37b3b8b5a..0e62896e95bc 100644 --- a/code/lib/cli/src/scaffold-new-project.ts +++ b/code/lib/cli/src/scaffold-new-project.ts @@ -210,7 +210,6 @@ export const currentDirectoryIsEmpty = (packageManager: PackageManagerName) => { const filesToIgnore = IGNORED_FILES_BY_PACKAGE_MANAGER[packageManagerName]; - console.log('PAckage manager used: ', packageManager, packageManagerName); return ( cwdFolderEntries.length === 0 || cwdFolderEntries.every((entry) => filesToIgnore.includes(entry)) From ed9cb676743e8d4ecc32dd2f03d7778d4d473902 Mon Sep 17 00:00:00 2001 From: Shaun Lloyd Date: Mon, 4 Dec 2023 15:42:23 -0500 Subject: [PATCH 51/62] Add debug env var --- code/lib/cli/src/scaffold-new-project.ts | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/code/lib/cli/src/scaffold-new-project.ts b/code/lib/cli/src/scaffold-new-project.ts index 0e62896e95bc..833a4e74e335 100644 --- a/code/lib/cli/src/scaffold-new-project.ts +++ b/code/lib/cli/src/scaffold-new-project.ts @@ -164,6 +164,7 @@ export const scaffoldNewProject = async (packageManager: PackageManagerName) => `Creating a new "${projectDisplayName}" project with ${chalk.bold(packageManagerName)}...` ); logger.line(1); + await execa.command(createScript, { stdio: 'pipe', shell: true, @@ -200,14 +201,19 @@ const BASE_IGNORED_FILES = ['.git', '.gitignore', '.DS_Store', '.cache']; const IGNORED_FILES_BY_PACKAGE_MANAGER: Record = { npm: [...BASE_IGNORED_FILES], - yarn: [...BASE_IGNORED_FILES, 'yarn.lock', '.yarnrc.yml', '.yarn'], - pnpm: [...BASE_IGNORED_FILES, 'pnpm-lock.yaml', '.pnpm', 'package.json'], + yarn: [...BASE_IGNORED_FILES, '.yarnrc.yml', '.yarn'], + pnpm: [...BASE_IGNORED_FILES], }; export const currentDirectoryIsEmpty = (packageManager: PackageManagerName) => { const packageManagerName = packageManagerToCoercedName(packageManager); const cwdFolderEntries = readdirSync(process.cwd()); + if (process.env.DEBUG) { + console.log('CWD entries:'); + console.log(cwdFolderEntries); + } + const filesToIgnore = IGNORED_FILES_BY_PACKAGE_MANAGER[packageManagerName]; return ( From a9d54ca4bac76d02ff5a378c9683f7735c7045dd Mon Sep 17 00:00:00 2001 From: Shaun Lloyd Date: Tue, 5 Dec 2023 08:30:30 -0500 Subject: [PATCH 52/62] Create project in temp dir --- code/lib/cli/src/scaffold-new-project.ts | 34 +++++++++++++++++------- 1 file changed, 24 insertions(+), 10 deletions(-) diff --git a/code/lib/cli/src/scaffold-new-project.ts b/code/lib/cli/src/scaffold-new-project.ts index 833a4e74e335..16b84ab5c759 100644 --- a/code/lib/cli/src/scaffold-new-project.ts +++ b/code/lib/cli/src/scaffold-new-project.ts @@ -1,12 +1,13 @@ import boxen from 'boxen'; import chalk from 'chalk'; +import execa from 'execa'; +import { readdirSync, existsSync, move } from 'fs-extra'; import prompts from 'prompts'; +import * as tempy from 'tempy'; import dedent from 'ts-dedent'; -import execa from 'execa'; -import { readdirSync } from 'fs-extra'; -import { logger } from '@storybook/node-logger'; import { GenerateNewProjectOnInitError } from '@storybook/core-events/server-errors'; +import { logger } from '@storybook/node-logger'; import type { PackageManagerName } from './js-package-manager'; @@ -158,19 +159,32 @@ export const scaffoldNewProject = async (packageManager: PackageManagerName) => const projectDisplayName = buildProjectDisplayNameForPrint(projectStrategy); const createScript = projectStrategy.createScript[packageManagerName]; - try { - logger.line(1); - logger.plain( - `Creating a new "${projectDisplayName}" project with ${chalk.bold(packageManagerName)}...` - ); - logger.line(1); + const tempDir = tempy.directory(); + const targetDir = process.cwd(); + + logger.line(1); + logger.plain( + `Creating a new "${projectDisplayName}" project with ${chalk.bold(packageManagerName)}...` + ); + logger.line(1); + try { + // Create new project in temp directory await execa.command(createScript, { stdio: 'pipe', shell: true, - cwd: process.cwd(), + cwd: tempDir, cleanup: true, }); + + // If target directory has a .cache folder, move it to temp directory + // so that it's not overwritten by the move operation below + if (existsSync(`${targetDir}/.cache`)) { + await move(`${targetDir}/.cache`, `${tempDir}/.cache`); + } + + // Move temp directory to target directory + await move(`${tempDir}`, targetDir, { overwrite: true }); } catch (e) { throw new GenerateNewProjectOnInitError({ error: e, From f3766dc1c86bcf419a8ff00442dae08a68073884 Mon Sep 17 00:00:00 2001 From: Shaun Lloyd Date: Tue, 5 Dec 2023 09:13:48 -0500 Subject: [PATCH 53/62] Delete cache folder --- code/lib/cli/src/initiate.ts | 1 + code/lib/cli/src/scaffold-new-project.ts | 28 +++++++----------------- 2 files changed, 9 insertions(+), 20 deletions(-) diff --git a/code/lib/cli/src/initiate.ts b/code/lib/cli/src/initiate.ts index e74b208d1da2..ab0673d78357 100644 --- a/code/lib/cli/src/initiate.ts +++ b/code/lib/cli/src/initiate.ts @@ -360,6 +360,7 @@ async function doInitiate( projectType === ProjectType.ANGULAR ? `ng run ${installResult.projectName}:storybook` : packageManager.getRunStorybookCommand(); + logger.log( boxen( dedent` diff --git a/code/lib/cli/src/scaffold-new-project.ts b/code/lib/cli/src/scaffold-new-project.ts index 16b84ab5c759..eabd944373b8 100644 --- a/code/lib/cli/src/scaffold-new-project.ts +++ b/code/lib/cli/src/scaffold-new-project.ts @@ -1,9 +1,8 @@ import boxen from 'boxen'; import chalk from 'chalk'; import execa from 'execa'; -import { readdirSync, existsSync, move } from 'fs-extra'; +import { readdirSync, remove } from 'fs-extra'; import prompts from 'prompts'; -import * as tempy from 'tempy'; import dedent from 'ts-dedent'; import { GenerateNewProjectOnInitError } from '@storybook/core-events/server-errors'; @@ -159,32 +158,26 @@ export const scaffoldNewProject = async (packageManager: PackageManagerName) => const projectDisplayName = buildProjectDisplayNameForPrint(projectStrategy); const createScript = projectStrategy.createScript[packageManagerName]; - const tempDir = tempy.directory(); - const targetDir = process.cwd(); - logger.line(1); logger.plain( `Creating a new "${projectDisplayName}" project with ${chalk.bold(packageManagerName)}...` ); logger.line(1); + const targetDir = process.cwd(); + try { + // If target directory has a .cache folder, remove it + // so that it does not block the creation of the new project + await remove(`${targetDir}/.cache`); + // Create new project in temp directory await execa.command(createScript, { stdio: 'pipe', shell: true, - cwd: tempDir, + cwd: targetDir, cleanup: true, }); - - // If target directory has a .cache folder, move it to temp directory - // so that it's not overwritten by the move operation below - if (existsSync(`${targetDir}/.cache`)) { - await move(`${targetDir}/.cache`, `${tempDir}/.cache`); - } - - // Move temp directory to target directory - await move(`${tempDir}`, targetDir, { overwrite: true }); } catch (e) { throw new GenerateNewProjectOnInitError({ error: e, @@ -223,11 +216,6 @@ export const currentDirectoryIsEmpty = (packageManager: PackageManagerName) => { const packageManagerName = packageManagerToCoercedName(packageManager); const cwdFolderEntries = readdirSync(process.cwd()); - if (process.env.DEBUG) { - console.log('CWD entries:'); - console.log(cwdFolderEntries); - } - const filesToIgnore = IGNORED_FILES_BY_PACKAGE_MANAGER[packageManagerName]; return ( From ffbff85f9fccc74b14be5496964f83eba42a1f29 Mon Sep 17 00:00:00 2001 From: Shaun Lloyd Date: Tue, 5 Dec 2023 10:11:07 -0500 Subject: [PATCH 54/62] Cleanup --- .circleci/config.yml | 81 +++++++++++++-------------- code/lib/cli/src/dev.ts | 1 - code/lib/cli/src/generators/types.ts | 2 - code/lib/cli/src/sandbox-templates.ts | 31 +++++----- code/lib/cli/src/utils.ts | 1 - 5 files changed, 55 insertions(+), 61 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index a7723ed00b27..c279d66e8bdd 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -688,52 +688,51 @@ workflows: when: equal: [daily, << pipeline.parameters.workflow >>] jobs: - # - pretty-docs + - pretty-docs - build - # - lint: - # requires: - # - build - # - check: - # requires: - # - build - # - unit-tests: - # requires: - # - build - # - script-checks: - # requires: - # - build - # - chromatic-internal-storybooks: - # requires: - # - build - # - create-sandboxes: - # parallelism: 36 - # requires: - # - build + - lint: + requires: + - build + - check: + requires: + - build + - unit-tests: + requires: + - build + - script-checks: + requires: + - build + - chromatic-internal-storybooks: + requires: + - build + - create-sandboxes: + parallelism: 36 + requires: + - build # - smoke-test-sandboxes: # disabled for now # requires: # - create-sandboxes - # - build-sandboxes: - # parallelism: 36 - # requires: - # - create-sandboxes - # - chromatic-sandboxes: - # parallelism: 33 - # requires: - # - build-sandboxes - # - e2e-production: - # parallelism: 31 - # requires: - # - build-sandboxes - # - e2e-dev: - # parallelism: 2 - # requires: - # - create-sandboxes - # - test-runner-production: - # parallelism: 31 - # requires: - # - build-sandboxes + - build-sandboxes: + parallelism: 36 + requires: + - create-sandboxes + - chromatic-sandboxes: + parallelism: 33 + requires: + - build-sandboxes + - e2e-production: + parallelism: 31 + requires: + - build-sandboxes + - e2e-dev: + parallelism: 2 + requires: + - create-sandboxes + - test-runner-production: + parallelism: 31 + requires: + - build-sandboxes - # TODO: Uncomment when ready to test - test-empty-init: requires: - build diff --git a/code/lib/cli/src/dev.ts b/code/lib/cli/src/dev.ts index ef507f9b9e34..ee82ae2cb7c4 100644 --- a/code/lib/cli/src/dev.ts +++ b/code/lib/cli/src/dev.ts @@ -38,7 +38,6 @@ function printError(error: any) { } export const dev = async (cliOptions: CLIOptions) => { - console.log('Hey there from dev!'); process.env.NODE_ENV = process.env.NODE_ENV || 'development'; const readUpResult = readUpSync({ cwd: __dirname }); diff --git a/code/lib/cli/src/generators/types.ts b/code/lib/cli/src/generators/types.ts index 79a0d7d8ecd9..2f97a34df126 100644 --- a/code/lib/cli/src/generators/types.ts +++ b/code/lib/cli/src/generators/types.ts @@ -55,6 +55,4 @@ export type CommandOptions = { disableTelemetry?: boolean; enableCrashReports?: boolean; debug?: boolean; - // Automatically pick new project template when creating a new project - scaffoldProject?: string; }; diff --git a/code/lib/cli/src/sandbox-templates.ts b/code/lib/cli/src/sandbox-templates.ts index c6eb3d068185..7137d40bb6f1 100644 --- a/code/lib/cli/src/sandbox-templates.ts +++ b/code/lib/cli/src/sandbox-templates.ts @@ -745,21 +745,21 @@ export const merged: TemplateKey[] = [ ]; const emptyTemplateKeys: TemplateKey[] = [ - // 'internal/npm/empty/react-vite/default-ts', - // 'internal/pnpm/empty/react-vite/default-ts', - // 'internal/yarn/empty/react-vite/default-ts', - // 'internal/npm/empty/nextjs/default-ts', - // 'internal/pnpm/empty/nextjs/default-ts', - // 'internal/yarn/empty/nextjs/default-ts', - // 'internal/npm/empty/vue3-vite/default-ts', - // 'internal/pnpm/empty/vue3-vite/default-ts', - // 'internal/yarn/empty/vue3-vite/default-ts', - // 'internal/npm/empty/angular-cli/default-ts', - // 'internal/pnpm/empty/angular-cli/default-ts', - // 'internal/yarn/empty/angular-cli/default-ts', - // 'internal/npm/empty/lit-vite/default-ts', - // 'internal/pnpm/empty/lit-vite/default-ts', - // 'internal/yarn/empty/lit-vite/default-ts', + 'internal/npm/empty/react-vite/default-ts', + 'internal/pnpm/empty/react-vite/default-ts', + 'internal/yarn/empty/react-vite/default-ts', + 'internal/npm/empty/nextjs/default-ts', + 'internal/pnpm/empty/nextjs/default-ts', + 'internal/yarn/empty/nextjs/default-ts', + 'internal/npm/empty/vue3-vite/default-ts', + 'internal/pnpm/empty/vue3-vite/default-ts', + 'internal/yarn/empty/vue3-vite/default-ts', + 'internal/npm/empty/angular-cli/default-ts', + 'internal/pnpm/empty/angular-cli/default-ts', + 'internal/yarn/empty/angular-cli/default-ts', + 'internal/npm/empty/lit-vite/default-ts', + 'internal/pnpm/empty/lit-vite/default-ts', + 'internal/yarn/empty/lit-vite/default-ts', ]; export const daily: TemplateKey[] = [ @@ -780,7 +780,6 @@ export const daily: TemplateKey[] = [ 'preact-webpack5/default-js', 'preact-vite/default-js', 'html-vite/default-js', - ...emptyTemplateKeys, ]; export const templatesByCadence = { normal, merged, daily }; diff --git a/code/lib/cli/src/utils.ts b/code/lib/cli/src/utils.ts index 68839b7bfa8d..fcd861860992 100644 --- a/code/lib/cli/src/utils.ts +++ b/code/lib/cli/src/utils.ts @@ -3,7 +3,6 @@ import { move, remove, writeFile, readFile, createWriteStream } from 'fs-extra'; import { join } from 'path'; import tempy from 'tempy'; import { rendererPackages } from '@storybook/core-common'; - import type { JsPackageManager } from './js-package-manager'; export function parseList(str: string): string[] { From 98d1598503a7e8fa2c5d97225c1219c02e162d94 Mon Sep 17 00:00:00 2001 From: Shaun Lloyd Date: Tue, 5 Dec 2023 11:04:44 -0500 Subject: [PATCH 55/62] Comment out empty templates --- code/lib/cli/src/sandbox-templates.ts | 35 ++++++++++++++------------- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/code/lib/cli/src/sandbox-templates.ts b/code/lib/cli/src/sandbox-templates.ts index 7137d40bb6f1..7f5f68561eb4 100644 --- a/code/lib/cli/src/sandbox-templates.ts +++ b/code/lib/cli/src/sandbox-templates.ts @@ -744,23 +744,24 @@ export const merged: TemplateKey[] = [ 'html-vite/default-ts', ]; -const emptyTemplateKeys: TemplateKey[] = [ - 'internal/npm/empty/react-vite/default-ts', - 'internal/pnpm/empty/react-vite/default-ts', - 'internal/yarn/empty/react-vite/default-ts', - 'internal/npm/empty/nextjs/default-ts', - 'internal/pnpm/empty/nextjs/default-ts', - 'internal/yarn/empty/nextjs/default-ts', - 'internal/npm/empty/vue3-vite/default-ts', - 'internal/pnpm/empty/vue3-vite/default-ts', - 'internal/yarn/empty/vue3-vite/default-ts', - 'internal/npm/empty/angular-cli/default-ts', - 'internal/pnpm/empty/angular-cli/default-ts', - 'internal/yarn/empty/angular-cli/default-ts', - 'internal/npm/empty/lit-vite/default-ts', - 'internal/pnpm/empty/lit-vite/default-ts', - 'internal/yarn/empty/lit-vite/default-ts', -]; +// For if we want to use empty sandboxes to test empty init +// const emptyTemplateKeys: TemplateKey[] = [ +// 'internal/npm/empty/react-vite/default-ts', +// 'internal/pnpm/empty/react-vite/default-ts', +// 'internal/yarn/empty/react-vite/default-ts', +// 'internal/npm/empty/nextjs/default-ts', +// 'internal/pnpm/empty/nextjs/default-ts', +// 'internal/yarn/empty/nextjs/default-ts', +// 'internal/npm/empty/vue3-vite/default-ts', +// 'internal/pnpm/empty/vue3-vite/default-ts', +// 'internal/yarn/empty/vue3-vite/default-ts', +// 'internal/npm/empty/angular-cli/default-ts', +// 'internal/pnpm/empty/angular-cli/default-ts', +// 'internal/yarn/empty/angular-cli/default-ts', +// 'internal/npm/empty/lit-vite/default-ts', +// 'internal/pnpm/empty/lit-vite/default-ts', +// 'internal/yarn/empty/lit-vite/default-ts', +// ]; export const daily: TemplateKey[] = [ ...merged, From 41d08038a41164cce63c1b50220954ea119da240 Mon Sep 17 00:00:00 2001 From: Shaun Lloyd Date: Wed, 6 Dec 2023 08:29:12 -0500 Subject: [PATCH 56/62] Use env vars in script --- scripts/sandbox/generate.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/sandbox/generate.ts b/scripts/sandbox/generate.ts index fc5ba32f03c6..0ad2860b536f 100755 --- a/scripts/sandbox/generate.ts +++ b/scripts/sandbox/generate.ts @@ -36,7 +36,7 @@ const sbInit = async ( ) => { const sbCliBinaryPath = join(__dirname, `../../code/lib/cli/bin/index.js`); console.log(`🎁 Installing storybook`); - const env = { STORYBOOK_DISABLE_TELEMETRY: 'true' }; + const env = { STORYBOOK_DISABLE_TELEMETRY: 'true', ...envVars }; const fullFlags = ['--yes', ...(flags || [])]; await runCommand(`${sbCliBinaryPath} init ${fullFlags.join(' ')}`, { cwd, env }, debug); }; From b70226b6244d29e9fcf340710882052c9f4992b1 Mon Sep 17 00:00:00 2001 From: Shaun Lloyd Date: Thu, 7 Dec 2023 11:53:11 -0500 Subject: [PATCH 57/62] Remove unused templates --- code/lib/cli/src/sandbox-templates.ts | 169 -------------------------- 1 file changed, 169 deletions(-) diff --git a/code/lib/cli/src/sandbox-templates.ts b/code/lib/cli/src/sandbox-templates.ts index ddbe71fb5515..8b4d18f2b06c 100644 --- a/code/lib/cli/src/sandbox-templates.ts +++ b/code/lib/cli/src/sandbox-templates.ts @@ -532,156 +532,6 @@ const internalTemplates = { isInternal: true, skipTasks: ['bench'], }, - 'internal/npm/empty/react-vite/default-ts': { - name: 'Empty React + vite (npm)', - script: 'mkdir {{beforeDir}} && cd {{beforeDir}}', - env: { - STORYBOOK_INIT_EMPTY_TYPE: 'react-vite-ts', - }, - expected: { ...baseTemplates['react-vite/default-ts'].expected }, - isInternal: true, - skipTasks: ['bench', 'e2e-tests-dev', 'chromatic'], - }, - 'internal/pnpm/empty/react-vite/default-ts': { - name: 'Empty React + vite (pnpm)', - script: 'mkdir {{beforeDir}} && cd {{beforeDir}}', - env: { - STORYBOOK_INIT_EMPTY_TYPE: 'react-vite-ts', - }, - expected: { ...baseTemplates['react-vite/default-ts'].expected }, - isInternal: true, - skipTasks: ['bench', 'e2e-tests-dev', 'chromatic'], - }, - 'internal/yarn/empty/react-vite/default-ts': { - name: 'Empty React + vite (pnpm)', - script: 'mkdir {{beforeDir}} && cd {{beforeDir}}', - env: { - STORYBOOK_INIT_EMPTY_TYPE: 'react-vite-ts', - }, - expected: { ...baseTemplates['react-vite/default-ts'].expected }, - isInternal: true, - skipTasks: ['bench', 'e2e-tests-dev', 'chromatic'], - }, - 'internal/npm/empty/nextjs/default-ts': { - name: 'Empty Next.js (npm)', - script: 'mkdir {{beforeDir}} && cd {{beforeDir}}', - env: { - STORYBOOK_INIT_EMPTY_TYPE: 'nextjs-ts', - }, - expected: { ...baseTemplates['nextjs/default-ts'].expected }, - isInternal: true, - skipTasks: ['bench', 'e2e-tests-dev', 'chromatic'], - }, - 'internal/pnpm/empty/nextjs/default-ts': { - name: 'Empty Next.js (pnpm)', - script: 'mkdir {{beforeDir}} && cd {{beforeDir}}', - env: { - STORYBOOK_INIT_EMPTY_TYPE: 'nextjs-ts', - }, - expected: { ...baseTemplates['nextjs/default-ts'].expected }, - isInternal: true, - skipTasks: ['bench', 'e2e-tests-dev', 'chromatic'], - }, - 'internal/yarn/empty/nextjs/default-ts': { - name: 'Empty Next.js (pnpm)', - script: 'mkdir {{beforeDir}} && cd {{beforeDir}}', - env: { - STORYBOOK_INIT_EMPTY_TYPE: 'nextjs-ts', - }, - expected: { ...baseTemplates['nextjs/default-ts'].expected }, - isInternal: true, - skipTasks: ['bench', 'e2e-tests-dev', 'chromatic'], - }, - 'internal/npm/empty/vue3-vite/default-ts': { - name: 'Empty Vue 3 + vite (npm)', - script: 'mkdir {{beforeDir}} && cd {{beforeDir}}', - env: { - STORYBOOK_INIT_EMPTY_TYPE: 'vue-vite-ts', - }, - expected: { ...baseTemplates['vue3-vite/default-ts'].expected }, - isInternal: true, - skipTasks: ['bench', 'e2e-tests-dev', 'chromatic'], - }, - 'internal/pnpm/empty/vue3-vite/default-ts': { - name: 'Empty Vue 3 + vite (pnpm)', - script: 'mkdir {{beforeDir}} && cd {{beforeDir}}', - env: { - STORYBOOK_INIT_EMPTY_TYPE: 'vue-vite-ts', - }, - expected: { ...baseTemplates['vue3-vite/default-ts'].expected }, - isInternal: true, - skipTasks: ['bench', 'e2e-tests-dev', 'chromatic'], - }, - 'internal/yarn/empty/vue3-vite/default-ts': { - name: 'Empty Vue 3 + vite (pnpm)', - script: 'mkdir {{beforeDir}} && cd {{beforeDir}}', - env: { - STORYBOOK_INIT_EMPTY_TYPE: 'vue-vite-ts', - }, - expected: { ...baseTemplates['vue3-vite/default-ts'].expected }, - isInternal: true, - skipTasks: ['bench', 'e2e-tests-dev', 'chromatic'], - }, - 'internal/npm/empty/angular-cli/default-ts': { - name: 'Empty Angular (npm)', - script: 'mkdir {{beforeDir}} && cd {{beforeDir}}', - env: { - STORYBOOK_INIT_EMPTY_TYPE: 'angular-cli', - }, - expected: { ...baseTemplates['angular-cli/default-ts'].expected }, - isInternal: true, - skipTasks: ['bench', 'e2e-tests-dev', 'chromatic'], - }, - 'internal/pnpm/empty/angular-cli/default-ts': { - name: 'Empty Angular (pnpm)', - script: 'mkdir {{beforeDir}} && cd {{beforeDir}}', - env: { - STORYBOOK_INIT_EMPTY_TYPE: 'angular-cli', - }, - expected: { ...baseTemplates['angular-cli/default-ts'].expected }, - isInternal: true, - skipTasks: ['bench', 'e2e-tests-dev', 'chromatic'], - }, - 'internal/yarn/empty/angular-cli/default-ts': { - name: 'Empty Angular (pnpm)', - script: 'mkdir {{beforeDir}} && cd {{beforeDir}}', - env: { - STORYBOOK_INIT_EMPTY_TYPE: 'angular-cli', - }, - expected: { ...baseTemplates['angular-cli/default-ts'].expected }, - isInternal: true, - skipTasks: ['bench', 'e2e-tests-dev', 'chromatic'], - }, - 'internal/npm/empty/lit-vite/default-ts': { - name: 'Empty Lit + vite (npm)', - script: 'mkdir {{beforeDir}} && cd {{beforeDir}}', - env: { - STORYBOOK_INIT_EMPTY_TYPE: 'lit-vite-ts', - }, - expected: { ...baseTemplates['lit-vite/default-ts'].expected }, - isInternal: true, - skipTasks: ['bench', 'e2e-tests-dev', 'chromatic'], - }, - 'internal/pnpm/empty/lit-vite/default-ts': { - name: 'Empty Lit + vite (pnpm)', - script: 'mkdir {{beforeDir}} && cd {{beforeDir}}', - env: { - STORYBOOK_INIT_EMPTY_TYPE: 'lit-vite-ts', - }, - expected: { ...baseTemplates['lit-vite/default-ts'].expected }, - isInternal: true, - skipTasks: ['bench', 'e2e-tests-dev', 'chromatic'], - }, - 'internal/yarn/empty/lit-vite/default-ts': { - name: 'Empty Lit + vite (pnpm)', - script: 'mkdir {{beforeDir}} && cd {{beforeDir}}', - env: { - STORYBOOK_INIT_EMPTY_TYPE: 'lit-vite-ts', - }, - expected: { ...baseTemplates['lit-vite/default-ts'].expected }, - isInternal: true, - skipTasks: ['bench', 'e2e-tests-dev', 'chromatic'], - }, // 'internal/pnp': { // ...baseTemplates['cra/default-ts'], // name: 'PNP (cra/default-ts)', @@ -776,25 +626,6 @@ export const merged: TemplateKey[] = [ 'html-vite/default-ts', ]; -// For if we want to use empty sandboxes to test empty init -// const emptyTemplateKeys: TemplateKey[] = [ -// 'internal/npm/empty/react-vite/default-ts', -// 'internal/pnpm/empty/react-vite/default-ts', -// 'internal/yarn/empty/react-vite/default-ts', -// 'internal/npm/empty/nextjs/default-ts', -// 'internal/pnpm/empty/nextjs/default-ts', -// 'internal/yarn/empty/nextjs/default-ts', -// 'internal/npm/empty/vue3-vite/default-ts', -// 'internal/pnpm/empty/vue3-vite/default-ts', -// 'internal/yarn/empty/vue3-vite/default-ts', -// 'internal/npm/empty/angular-cli/default-ts', -// 'internal/pnpm/empty/angular-cli/default-ts', -// 'internal/yarn/empty/angular-cli/default-ts', -// 'internal/npm/empty/lit-vite/default-ts', -// 'internal/pnpm/empty/lit-vite/default-ts', -// 'internal/yarn/empty/lit-vite/default-ts', -// ]; - export const daily: TemplateKey[] = [ ...merged, 'angular-cli/prerelease', From 0a46302360a349be8a1da3aafe7ef91162dcddbb Mon Sep 17 00:00:00 2001 From: Shaun Lloyd Date: Thu, 7 Dec 2023 14:00:23 -0500 Subject: [PATCH 58/62] Move inferPackageManager into JsPackageManager --- code/lib/cli/src/helpers.test.ts | 35 ----------- code/lib/cli/src/helpers.ts | 26 -------- code/lib/cli/src/initiate.ts | 4 +- .../JsPackageManagerFactory.test.ts | 49 ++++++++++----- .../JsPackageManagerFactory.ts | 61 ++++++++++++++++--- 5 files changed, 88 insertions(+), 87 deletions(-) diff --git a/code/lib/cli/src/helpers.test.ts b/code/lib/cli/src/helpers.test.ts index ae10b4d115fc..c15ae604a1a9 100644 --- a/code/lib/cli/src/helpers.test.ts +++ b/code/lib/cli/src/helpers.test.ts @@ -177,39 +177,4 @@ describe('Helpers', () => { }).toThrowError(`Could not coerce ${invalidSemverString} into a semver.`); }); }); - describe('inferPackageManagerFromUserAgent', () => { - afterEach(() => { - delete process.env.npm_config_user_agent; - }); - - it('should return npm for invalid user agent', () => { - process.env.npm_config_user_agent = ''; - expect(helpers.inferPackageManagerFromUserAgent()).toBe('npm'); - }); - - it('should infer pnpm from user agent', () => { - process.env.npm_config_user_agent = 'pnpm/7.4.0'; - expect(helpers.inferPackageManagerFromUserAgent()).toBe('pnpm'); - }); - - it('should infer npm from user agent', () => { - process.env.npm_config_user_agent = 'npm/7.24.0'; - expect(helpers.inferPackageManagerFromUserAgent()).toBe('npm'); - }); - - it('should infer yarn 1 from user agent', () => { - process.env.npm_config_user_agent = 'yarn/1.22.11'; - expect(helpers.inferPackageManagerFromUserAgent()).toBe('yarn1'); - }); - - it('should infer yarn 2 from user agent', () => { - process.env.npm_config_user_agent = 'yarn/2.4.0'; - expect(helpers.inferPackageManagerFromUserAgent()).toBe('yarn2'); - }); - - it('should return npm for unknown package manager', () => { - process.env.npm_config_user_agent = 'unknown'; - expect(helpers.inferPackageManagerFromUserAgent()).toBe('npm'); - }); - }); }); diff --git a/code/lib/cli/src/helpers.ts b/code/lib/cli/src/helpers.ts index edf2eb7ea4d0..d322732aea9a 100644 --- a/code/lib/cli/src/helpers.ts +++ b/code/lib/cli/src/helpers.ts @@ -315,29 +315,3 @@ export function coerceSemver(version: string) { invariant(coercedSemver != null, `Could not coerce ${version} into a semver.`); return coercedSemver; } - -/** - * Infer the package manager based on the command the user is running. - * Each package manager sets the `npm_config_user_agent` environment variable with its name and version e.g. "npm/7.24.0" - * Which is really useful when invoking commands via npx/pnpx/yarn create/etc. - */ -export function inferPackageManagerFromUserAgent(): PackageManagerName { - const userAgent = process.env.npm_config_user_agent; - if (!userAgent) return 'npm'; - const packageSpec = userAgent.split(' ')[0]; - const [pkgMgrName, pkgMgrVersion] = packageSpec.split('/'); - - if (pkgMgrName === 'pnpm') { - return 'pnpm'; - } - - if (pkgMgrName === 'npm') { - return 'npm'; - } - - if (pkgMgrName === 'yarn') { - return `yarn${pkgMgrVersion?.startsWith('1.') ? '1' : '2'}`; - } - - return 'npm'; -} diff --git a/code/lib/cli/src/initiate.ts b/code/lib/cli/src/initiate.ts index ab0673d78357..b566b33dc595 100644 --- a/code/lib/cli/src/initiate.ts +++ b/code/lib/cli/src/initiate.ts @@ -11,7 +11,7 @@ import boxen from 'boxen'; import type { Builder } from './project_types'; import { installableProjectTypes, ProjectType } from './project_types'; import { detect, isStorybookInstantiated, detectLanguage, detectPnp } from './detect'; -import { commandLog, codeLog, paddedLog, inferPackageManagerFromUserAgent } from './helpers'; +import { commandLog, codeLog, paddedLog } from './helpers'; import angularGenerator from './generators/ANGULAR'; import emberGenerator from './generators/EMBER'; import reactGenerator from './generators/REACT'; @@ -255,7 +255,7 @@ async function doInitiate( } const packageManager = JsPackageManagerFactory.getPackageManager({ - force: pkgMgr || inferPackageManagerFromUserAgent(), + force: pkgMgr, }); const welcomeMessage = 'storybook init - the simplest way to add a Storybook to your project.'; diff --git a/code/lib/cli/src/js-package-manager/JsPackageManagerFactory.test.ts b/code/lib/cli/src/js-package-manager/JsPackageManagerFactory.test.ts index 4567987488ef..7e12ac20de6b 100644 --- a/code/lib/cli/src/js-package-manager/JsPackageManagerFactory.test.ts +++ b/code/lib/cli/src/js-package-manager/JsPackageManagerFactory.test.ts @@ -13,20 +13,26 @@ const spawnSyncMock = spawnSync as jest.Mock; jest.mock('find-up'); const findUpSyncMock = findUpSync as unknown as jest.Mock; -describe('JsPackageManagerFactory', () => { +describe('CLASS: JsPackageManagerFactory', () => { beforeEach(() => { findUpSyncMock.mockReturnValue(undefined); + delete process.env.npm_config_user_agent; }); - describe('getPackageManager', () => { - describe('return an NPM proxy', () => { - it('when `force` option is `npm`', () => { + describe('METHOD: getPackageManager', () => { + describe('NPM proxy', () => { + it('FORCE: it should return a NPM proxy when `force` option is `npm`', () => { expect(JsPackageManagerFactory.getPackageManager({ force: 'npm' })).toBeInstanceOf( NPMProxy ); }); - it('when all package managers are ok, but only a `package-lock.json` file', () => { + it('USER AGENT: it should infer npm from the user agent', () => { + process.env.npm_config_user_agent = 'npm/7.24.0'; + expect(JsPackageManagerFactory.getPackageManager()).toBeInstanceOf(NPMProxy); + }); + + it('ALL EXIST: when all package managers are ok, but only a `package-lock.json` file is found', () => { spawnSyncMock.mockImplementation((command) => { // Yarn is ok if (command === 'yarn') { @@ -62,14 +68,19 @@ describe('JsPackageManagerFactory', () => { }); }); - describe('return a PNPM proxy', () => { - it('when `force` option is `pnpm`', () => { + describe('PNPM proxy', () => { + it('FORCE: it should return a PNPM proxy when `force` option is `pnpm`', () => { expect(JsPackageManagerFactory.getPackageManager({ force: 'pnpm' })).toBeInstanceOf( PNPMProxy ); }); - it('when all package managers are ok, but only a `pnpm-lock.yaml` file', () => { + it('USER AGENT: it should infer pnpm from the user agent', () => { + process.env.npm_config_user_agent = 'pnpm/7.4.0'; + expect(JsPackageManagerFactory.getPackageManager()).toBeInstanceOf(PNPMProxy); + }); + + it('ALL EXIST: when all package managers are ok, but only a `pnpm-lock.yaml` file is found', () => { spawnSyncMock.mockImplementation((command) => { // Yarn is ok if (command === 'yarn') { @@ -104,7 +115,7 @@ describe('JsPackageManagerFactory', () => { expect(JsPackageManagerFactory.getPackageManager()).toBeInstanceOf(PNPMProxy); }); - it('when a pnpm-lock.yaml file is closer than a yarn.lock', () => { + it('PNPM LOCK IF CLOSER: when a pnpm-lock.yaml file is closer than a yarn.lock', () => { // Allow find-up to work as normal, we'll set the cwd to our fixture package findUpSyncMock.mockImplementation(jest.requireActual('find-up').sync); @@ -140,13 +151,18 @@ describe('JsPackageManagerFactory', () => { }); }); - describe('return a Yarn 1 proxy', () => { - it('when `force` option is `yarn1`', () => { + describe('Yarn 1 proxy', () => { + it('FORCE: it should return a Yarn1 proxy when `force` option is `yarn1`', () => { expect(JsPackageManagerFactory.getPackageManager({ force: 'yarn1' })).toBeInstanceOf( Yarn1Proxy ); }); + it('USER AGENT: it should infer yarn1 from the user agent', () => { + process.env.npm_config_user_agent = 'yarn/1.22.11'; + expect(JsPackageManagerFactory.getPackageManager()).toBeInstanceOf(Yarn1Proxy); + }); + it('when Yarn command is ok, Yarn version is <2, NPM is ko, PNPM is ko', () => { spawnSyncMock.mockImplementation((command) => { // Yarn is ok @@ -251,14 +267,19 @@ describe('JsPackageManagerFactory', () => { }); }); - describe('return a Yarn 2 proxy', () => { - it('when `force` option is `yarn2`', () => { + describe('Yarn 2 proxy', () => { + it('FORCE: it should return a Yarn2 proxy when `force` option is `yarn2`', () => { expect(JsPackageManagerFactory.getPackageManager({ force: 'yarn2' })).toBeInstanceOf( Yarn2Proxy ); }); - it('when Yarn command is ok, Yarn version is >=2, NPM is ko, PNPM is ko', () => { + it('USER AGENT: it should infer yarn2 from the user agent', () => { + process.env.npm_config_user_agent = 'yarn/2.2.10'; + expect(JsPackageManagerFactory.getPackageManager()).toBeInstanceOf(Yarn2Proxy); + }); + + it('ONLY YARN 2: when Yarn command is ok, Yarn version is >=2, NPM is ko, PNPM is ko', () => { spawnSyncMock.mockImplementation((command) => { // Yarn is ok if (command === 'yarn') { diff --git a/code/lib/cli/src/js-package-manager/JsPackageManagerFactory.ts b/code/lib/cli/src/js-package-manager/JsPackageManagerFactory.ts index 77986fd0c038..f725932fed69 100644 --- a/code/lib/cli/src/js-package-manager/JsPackageManagerFactory.ts +++ b/code/lib/cli/src/js-package-manager/JsPackageManagerFactory.ts @@ -14,24 +14,29 @@ const NPM_LOCKFILE = 'package-lock.json'; const PNPM_LOCKFILE = 'pnpm-lock.yaml'; const YARN_LOCKFILE = 'yarn.lock'; +type PackageManagerProxy = + | typeof NPMProxy + | typeof PNPMProxy + | typeof Yarn1Proxy + | typeof Yarn2Proxy; + export class JsPackageManagerFactory { public static getPackageManager( { force }: { force?: PackageManagerName } = {}, cwd?: string ): JsPackageManager { - if (force === 'npm') { - return new NPMProxy({ cwd }); - } - if (force === 'pnpm') { - return new PNPMProxy({ cwd }); + // Option 1: If the user has provided a forcing flag, we use it + if (force && force in this.PROXY_MAP) { + return new this.PROXY_MAP[force]({ cwd }); } - if (force === 'yarn1') { - return new Yarn1Proxy({ cwd }); - } - if (force === 'yarn2') { - return new Yarn2Proxy({ cwd }); + + // Option 2: If the user is running a command via npx/pnpx/yarn create/etc, we infer the package manager from the command + const inferredPackageManager = this.inferPackageManagerFromUserAgent(); + if (inferredPackageManager && inferredPackageManager in this.PROXY_MAP) { + return new this.PROXY_MAP[inferredPackageManager]({ cwd }); } + // Option 3: We try to infer the package manager from the closest lockfile const yarnVersion = getYarnVersion(cwd); const closestLockfilePath = findUpSync([YARN_LOCKFILE, PNPM_LOCKFILE, NPM_LOCKFILE], { @@ -56,6 +61,42 @@ export class JsPackageManagerFactory { throw new Error('Unable to find a usable package manager within NPM, PNPM, Yarn and Yarn 2'); } + + /** + * Look up map of package manager proxies by name + */ + private static PROXY_MAP: Record = { + npm: NPMProxy, + pnpm: PNPMProxy, + yarn1: Yarn1Proxy, + yarn2: Yarn2Proxy, + }; + + /** + * Infer the package manager based on the command the user is running. + * Each package manager sets the `npm_config_user_agent` environment variable with its name and version e.g. "npm/7.24.0" + * Which is really useful when invoking commands via npx/pnpx/yarn create/etc. + */ + private static inferPackageManagerFromUserAgent(): PackageManagerName | undefined { + const userAgent = process.env.npm_config_user_agent; + if (!userAgent) return 'npm'; + const packageSpec = userAgent.split(' ')[0]; + const [pkgMgrName, pkgMgrVersion] = packageSpec.split('/'); + + if (pkgMgrName === 'pnpm') { + return 'pnpm'; + } + + if (pkgMgrName === 'npm') { + return 'npm'; + } + + if (pkgMgrName === 'yarn') { + return `yarn${pkgMgrVersion?.startsWith('1.') ? '1' : '2'}`; + } + + return undefined; + } } function hasNPM(cwd?: string) { From f8bf4efa515289cb968e3eafa5725d73b585aece Mon Sep 17 00:00:00 2001 From: Shaun Lloyd Date: Thu, 7 Dec 2023 14:09:11 -0500 Subject: [PATCH 59/62] Fix packageManager inference --- .../JsPackageManagerFactory.ts | 23 ++++++++++--------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/code/lib/cli/src/js-package-manager/JsPackageManagerFactory.ts b/code/lib/cli/src/js-package-manager/JsPackageManagerFactory.ts index f725932fed69..b6a6ea297956 100644 --- a/code/lib/cli/src/js-package-manager/JsPackageManagerFactory.ts +++ b/code/lib/cli/src/js-package-manager/JsPackageManagerFactory.ts @@ -79,20 +79,21 @@ export class JsPackageManagerFactory { */ private static inferPackageManagerFromUserAgent(): PackageManagerName | undefined { const userAgent = process.env.npm_config_user_agent; - if (!userAgent) return 'npm'; - const packageSpec = userAgent.split(' ')[0]; - const [pkgMgrName, pkgMgrVersion] = packageSpec.split('/'); + if (userAgent) { + const packageSpec = userAgent.split(' ')[0]; + const [pkgMgrName, pkgMgrVersion] = packageSpec.split('/'); - if (pkgMgrName === 'pnpm') { - return 'pnpm'; - } + if (pkgMgrName === 'pnpm') { + return 'pnpm'; + } - if (pkgMgrName === 'npm') { - return 'npm'; - } + if (pkgMgrName === 'npm') { + return 'npm'; + } - if (pkgMgrName === 'yarn') { - return `yarn${pkgMgrVersion?.startsWith('1.') ? '1' : '2'}`; + if (pkgMgrName === 'yarn') { + return `yarn${pkgMgrVersion?.startsWith('1.') ? '1' : '2'}`; + } } return undefined; From cedc6fb6dc4caec000364fbb02d6381a89a6d1d1 Mon Sep 17 00:00:00 2001 From: Shaun Lloyd Date: Thu, 7 Dec 2023 14:28:49 -0500 Subject: [PATCH 60/62] Remove unused imports --- code/lib/cli/src/helpers.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/code/lib/cli/src/helpers.ts b/code/lib/cli/src/helpers.ts index d322732aea9a..605fab2d1849 100644 --- a/code/lib/cli/src/helpers.ts +++ b/code/lib/cli/src/helpers.ts @@ -13,7 +13,6 @@ import type { JsPackageManager, PackageJson, PackageJsonWithDepsAndDevDeps, - PackageManagerName, } from './js-package-manager'; import type { SupportedFrameworks, SupportedRenderers } from './project_types'; import { SupportedLanguage } from './project_types'; From 8fbd37580b1484d0a1bc39d6572e112d8f23c7a5 Mon Sep 17 00:00:00 2001 From: Michael Shilman Date: Fri, 8 Dec 2023 11:10:39 +0800 Subject: [PATCH 61/62] Break the cache --- code/lib/cli/package.json | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/code/lib/cli/package.json b/code/lib/cli/package.json index b7201c92e647..dd845db3b8c1 100644 --- a/code/lib/cli/package.json +++ b/code/lib/cli/package.json @@ -1,11 +1,13 @@ { "name": "@storybook/cli", "version": "8.0.0-alpha.1", - "description": "Storybook's CLI - easiest method of adding storybook to your projects", + "description": "Storybook's CLI - install, dev, build, upgrade, and more", "keywords": [ "cli", "generator", - "storybook" + "dev", + "build", + "upgrade" ], "homepage": "https://github.com/storybookjs/storybook/tree/next/code/lib/cli", "bugs": { From cc81dadb143e90303d7c945a2f8dd809a2fd44a6 Mon Sep 17 00:00:00 2001 From: Shaun Lloyd Date: Fri, 8 Dec 2023 11:20:13 -0500 Subject: [PATCH 62/62] Add telemetry for successful scaffolding --- code/lib/cli/src/initiate.ts | 2 +- code/lib/cli/src/scaffold-new-project.ts | 26 ++++++++++++++++++------ code/lib/telemetry/src/types.ts | 1 + 3 files changed, 22 insertions(+), 7 deletions(-) diff --git a/code/lib/cli/src/initiate.ts b/code/lib/cli/src/initiate.ts index d5acccbfd36a..5217bca197aa 100644 --- a/code/lib/cli/src/initiate.ts +++ b/code/lib/cli/src/initiate.ts @@ -259,7 +259,7 @@ async function doInitiate( // Check if the current directory is empty. if (options.force !== true && currentDirectoryIsEmpty(packageManager.type)) { // Prompt the user to create a new project from our list. - await scaffoldNewProject(packageManager.type); + await scaffoldNewProject(packageManager.type, options); if (process.env.IN_STORYBOOK_SANDBOX === 'true' || process.env.CI === 'true') { packageManager.addPackageResolutions({ diff --git a/code/lib/cli/src/scaffold-new-project.ts b/code/lib/cli/src/scaffold-new-project.ts index eabd944373b8..d33d82a32d7a 100644 --- a/code/lib/cli/src/scaffold-new-project.ts +++ b/code/lib/cli/src/scaffold-new-project.ts @@ -5,10 +5,13 @@ import { readdirSync, remove } from 'fs-extra'; import prompts from 'prompts'; import dedent from 'ts-dedent'; +import { telemetry } from '@storybook/telemetry'; + import { GenerateNewProjectOnInitError } from '@storybook/core-events/server-errors'; import { logger } from '@storybook/node-logger'; import type { PackageManagerName } from './js-package-manager'; +import type { CommandOptions } from './generators/types'; type CoercedPackageManagerName = 'npm' | 'yarn' | 'pnpm'; @@ -108,7 +111,10 @@ const buildProjectDisplayNameForPrint = ({ displayName }: SupportedProject) => { * * @param packageManager The package manager to use. */ -export const scaffoldNewProject = async (packageManager: PackageManagerName) => { +export const scaffoldNewProject = async ( + packageManager: PackageManagerName, + { disableTelemetry }: CommandOptions +) => { const packageManagerName = packageManagerToCoercedName(packageManager); logger.plain( @@ -135,7 +141,7 @@ export const scaffoldNewProject = async (packageManager: PackageManagerName) => let projectStrategy; if (process.env.STORYBOOK_INIT_EMPTY_TYPE) { - projectStrategy = SUPPORTED_PROJECTS[process.env.STORYBOOK_INIT_EMPTY_TYPE]; + projectStrategy = process.env.STORYBOOK_INIT_EMPTY_TYPE; } if (!projectStrategy) { @@ -152,11 +158,12 @@ export const scaffoldNewProject = async (packageManager: PackageManagerName) => { onCancel: () => process.exit(0) } ); - projectStrategy = SUPPORTED_PROJECTS[project]; + projectStrategy = project; } - const projectDisplayName = buildProjectDisplayNameForPrint(projectStrategy); - const createScript = projectStrategy.createScript[packageManagerName]; + const projectStrategyConfig = SUPPORTED_PROJECTS[projectStrategy]; + const projectDisplayName = buildProjectDisplayNameForPrint(projectStrategyConfig); + const createScript = projectStrategyConfig.createScript[packageManagerName]; logger.line(1); logger.plain( @@ -182,7 +189,14 @@ export const scaffoldNewProject = async (packageManager: PackageManagerName) => throw new GenerateNewProjectOnInitError({ error: e, packageManager: packageManagerName, - projectType: projectDisplayName, + projectType: projectStrategy, + }); + } + + if (!disableTelemetry) { + telemetry('scaffolded-empty', { + packageManager: packageManagerName, + projectType: projectStrategy, }); } diff --git a/code/lib/telemetry/src/types.ts b/code/lib/telemetry/src/types.ts index 35266814dff7..8f091703bcae 100644 --- a/code/lib/telemetry/src/types.ts +++ b/code/lib/telemetry/src/types.ts @@ -9,6 +9,7 @@ export type EventType = | 'build' | 'upgrade' | 'init' + | 'scaffolded-empty' | 'browser' | 'canceled' | 'error'