mirror of
https://github.com/storybookjs/storybook.git
synced 2025-04-05 07:31:19 +08:00
169 lines
4.6 KiB
TypeScript
169 lines
4.6 KiB
TypeScript
import prompts from 'prompts';
|
|
import fs from 'fs';
|
|
import path from 'path';
|
|
import chalk from 'chalk';
|
|
import boxen from 'boxen';
|
|
import dedent from 'ts-dedent';
|
|
import { createAndInit, Parameters, exec } from './repro-generators/scripts';
|
|
import * as configs from './repro-generators/configs';
|
|
import { SupportedFrameworks } from './project_types';
|
|
|
|
const logger = console;
|
|
|
|
interface ReproOptions {
|
|
outputDirectory: string;
|
|
framework?: SupportedFrameworks;
|
|
list?: boolean;
|
|
template?: string;
|
|
e2e?: boolean;
|
|
generator?: string;
|
|
pnp?: boolean;
|
|
}
|
|
|
|
const TEMPLATES = configs as Record<string, Parameters>;
|
|
|
|
const FRAMEWORKS = Object.values(configs).reduce<Record<SupportedFrameworks, Parameters[]>>(
|
|
(acc, cur) => {
|
|
acc[cur.framework] = [...(acc[cur.framework] || []), cur];
|
|
return acc;
|
|
},
|
|
{} as Record<SupportedFrameworks, Parameters[]>
|
|
);
|
|
|
|
export const repro = async ({
|
|
outputDirectory,
|
|
list,
|
|
template,
|
|
framework,
|
|
generator,
|
|
e2e,
|
|
pnp,
|
|
}: ReproOptions) => {
|
|
logger.info(
|
|
boxen(
|
|
dedent`
|
|
🤗 Welcome to ${chalk.yellow('sb repro')}! 🤗
|
|
|
|
Create a ${chalk.green('new project')} to minimally reproduce Storybook issues.
|
|
|
|
1. select an environment that most closely matches your project setup.
|
|
2. select a location for the reproduction, outside of your project.
|
|
|
|
After the reproduction is ready, we'll guide you through the next steps.
|
|
`.trim(),
|
|
{ borderStyle: 'round', padding: 1, borderColor: '#F1618C' } as any
|
|
)
|
|
);
|
|
if (list) {
|
|
logger.info('🌈 Available templates');
|
|
Object.entries(FRAMEWORKS).forEach(([fmwrk, templates]) => {
|
|
logger.info(fmwrk);
|
|
templates.forEach((t) => logger.info(`- ${t.name}`));
|
|
if (fmwrk === 'other') {
|
|
logger.info('- blank');
|
|
}
|
|
});
|
|
return;
|
|
}
|
|
|
|
let selectedTemplate = template;
|
|
let selectedFramework = framework;
|
|
if (!selectedTemplate && !generator) {
|
|
if (!selectedFramework) {
|
|
const { framework: frameworkOpt } = await prompts({
|
|
type: 'select',
|
|
message: '🌈 Select the repro framework',
|
|
name: 'framework',
|
|
choices: Object.keys(FRAMEWORKS).map((f) => ({ title: f, value: f })),
|
|
});
|
|
selectedFramework = frameworkOpt;
|
|
}
|
|
if (!selectedFramework) {
|
|
throw new Error('🚨 Repro: please select a framework!');
|
|
}
|
|
selectedTemplate = (
|
|
await prompts({
|
|
type: 'select',
|
|
message: '📝 Select the repro base template',
|
|
name: 'template',
|
|
choices: FRAMEWORKS[selectedFramework as SupportedFrameworks].map((f) => ({
|
|
title: f.name,
|
|
value: f.name,
|
|
})),
|
|
})
|
|
).template;
|
|
}
|
|
|
|
const selectedConfig = !generator
|
|
? TEMPLATES[selectedTemplate]
|
|
: {
|
|
name: 'custom',
|
|
version: 'custom',
|
|
generator,
|
|
};
|
|
|
|
if (!selectedConfig) {
|
|
throw new Error('🚨 Repro: please specify a valid template type');
|
|
}
|
|
|
|
let selectedDirectory = outputDirectory;
|
|
if (!selectedDirectory) {
|
|
const { directory } = await prompts({
|
|
type: 'text',
|
|
message: 'Enter the output directory',
|
|
name: 'directory',
|
|
});
|
|
selectedDirectory = directory;
|
|
if (fs.existsSync(selectedDirectory)) {
|
|
throw new Error(`🚨 Repro: ${selectedDirectory} already exists`);
|
|
}
|
|
}
|
|
|
|
try {
|
|
const cwd = path.isAbsolute(selectedDirectory)
|
|
? selectedDirectory
|
|
: path.join(process.cwd(), selectedDirectory);
|
|
|
|
logger.info(`🏃 Running ${selectedTemplate} into ${cwd}`);
|
|
|
|
await createAndInit(cwd, selectedConfig, {
|
|
e2e: !!e2e,
|
|
pnp: !!pnp,
|
|
});
|
|
|
|
if (!e2e) {
|
|
await initGitRepo(cwd);
|
|
}
|
|
|
|
logger.info(
|
|
boxen(
|
|
dedent`
|
|
🎉 Your Storybook reproduction project is ready to use! 🎉
|
|
|
|
${chalk.yellow(`cd ${selectedDirectory}`)}
|
|
${chalk.yellow(`yarn storybook`)}
|
|
|
|
Once you've recreated the problem you're experiencing, please:
|
|
|
|
1. Document any additional steps in ${chalk.cyan('README.md')}
|
|
2. Publish the repository to github
|
|
3. Link to the repro repository in your issue
|
|
|
|
Having a clean repro helps us solve your issue faster! 🙏
|
|
`.trim(),
|
|
{ borderStyle: 'round', padding: 1, borderColor: '#F1618C' } as any
|
|
)
|
|
);
|
|
} catch (error) {
|
|
logger.error('🚨 Failed to create repro');
|
|
}
|
|
};
|
|
|
|
const initGitRepo = async (cwd: string) => {
|
|
await exec('git init', { cwd });
|
|
await exec('echo "node_modules" >> .gitignore', { cwd });
|
|
await exec('git add --all', { cwd });
|
|
await exec('git commit -am "added storybook"', { cwd });
|
|
await exec('git tag repro-base', { cwd });
|
|
};
|