1
0
mirror of https://github.com/storybookjs/storybook.git synced 2025-03-20 05:02:37 +08:00
2022-08-14 17:11:47 +08:00

125 lines
3.6 KiB
TypeScript
Executable File

/* eslint-disable no-console */
import { join, relative } from 'path';
import program from 'commander';
import { command } from 'execa';
import type { Options as ExecaOptions } from 'execa';
import pLimit from 'p-limit';
import prettyTime from 'pretty-hrtime';
import { copy, emptyDir, ensureDir, rename, writeFile } from 'fs-extra';
import reproTemplates from '../../code/lib/cli/src/repro-templates';
// @ts-ignore
import { maxConcurrentTasks } from '../utils/concurrency';
import { localizeYarnConfigFiles, setupYarn } from './utils/yarn';
import { GeneratorConfig } from './utils/types';
import { getStackblitzUrl, renderTemplate } from './utils/template';
const OUTPUT_DIRECTORY = join(__dirname, '..', '..', 'repros');
const BEFORE_DIR_NAME = 'before-storybook';
const AFTER_DIR_NAME = 'after-storybook';
const addStorybook = async (baseDir: string) => {
const beforeDir = join(baseDir, BEFORE_DIR_NAME);
const afterDir = join(baseDir, AFTER_DIR_NAME);
const tmpDir = join(baseDir, 'tmp');
await ensureDir(tmpDir);
await emptyDir(tmpDir);
await copy(beforeDir, tmpDir);
const sbCliBinaryPath = join(__dirname, `../../code/lib/cli/bin/index.js`);
await runCommand(`${sbCliBinaryPath} init`, {
cwd: tmpDir,
env: {
STORYBOOK_DISABLE_TELEMETRY: 'true',
},
});
await rename(tmpDir, afterDir);
};
export const runCommand = async (script: string, options: ExecaOptions) => {
const shouldDebug = !!process.env.DEBUG;
if (shouldDebug) {
console.log(`Running command: ${script}`);
}
return command(script, { stdout: shouldDebug ? 'inherit' : 'ignore', ...options });
};
const addDocumentation = async (
baseDir: string,
{ name, dirName }: { name: string; dirName: string }
) => {
const afterDir = join(baseDir, AFTER_DIR_NAME);
const stackblitzConfigPath = join(__dirname, 'templates', '.stackblitzrc');
const readmePath = join(__dirname, 'templates', 'item.ejs');
await copy(stackblitzConfigPath, join(afterDir, '.stackblitzrc'));
const stackblitzUrl = getStackblitzUrl(dirName);
const contents = await renderTemplate(readmePath, {
name,
stackblitzUrl,
});
await writeFile(join(afterDir, 'README.md'), contents);
};
const runGenerators = async (generators: (GeneratorConfig & { dirName: string })[]) => {
console.log(`🤹‍♂️ Generating repros with a concurrency of ${maxConcurrentTasks}`);
const limit = pLimit(maxConcurrentTasks);
return Promise.all(
generators.map(({ dirName, name, script }) =>
limit(async () => {
const time = process.hrtime();
console.log(`🧬 generating ${name}`);
const baseDir = join(OUTPUT_DIRECTORY, dirName);
const beforeDir = join(baseDir, BEFORE_DIR_NAME);
await emptyDir(baseDir);
await ensureDir(beforeDir);
await setupYarn({ cwd: baseDir });
await runCommand(script, { cwd: beforeDir });
await localizeYarnConfigFiles(baseDir, beforeDir);
await addStorybook(baseDir);
await addDocumentation(baseDir, { name, dirName });
console.log(
`✅ Created ${dirName} in ./${relative(
process.cwd(),
baseDir
)} successfully in ${prettyTime(process.hrtime(time))}`
);
})
)
);
};
const generate = async () => {
runGenerators(
Object.entries(reproTemplates).map(([dirName, configuration]) => ({
dirName,
...configuration,
}))
);
};
program.description('Create a reproduction from a set of possible templates');
program.parse(process.argv);
generate().catch((e) => {
console.trace(e);
process.exit(1);
});