diff --git a/code/lib/cli/src/automigrate/index.ts b/code/lib/cli/src/automigrate/index.ts index fd142694f649..a9278e931e18 100644 --- a/code/lib/cli/src/automigrate/index.ts +++ b/code/lib/cli/src/automigrate/index.ts @@ -6,6 +6,7 @@ import { JsPackageManagerFactory, type PackageManagerName } from '../js-package- import type { Fix } from './fixes'; import { fixes } from './fixes'; +import dedent from 'ts-dedent'; const logger = console; @@ -33,26 +34,27 @@ export const automigrate = async ({ fixId, dryRun, yes, useNpm, force }: FixOpti logger.info('šŸ”Ž checking possible migrations..'); const fixResults = {} as Record; + const fixSummary = { succeeded: [], failed: {} } as { succeeded: FixId[], failed: Record}; for (let i = 0; i < filtered.length; i += 1) { const f = fixes[i] as Fix; let result; - let fixStatus; + let fixStatus = FixStatus.UNNECESSARY; + try { result = await f.check({ packageManager }); - } catch (e) { + } catch (error) { + logger.info(`āš ļø failed to check fix ${chalk.bold(f.id)}`); fixStatus = FixStatus.CHECK_FAILED; - logger.info(`failed to check fix: ${f.id}`); + fixSummary.failed[f.id] = error.message; } - if (!result) { - fixStatus = FixStatus.UNNECESSARY; - } else { - logger.info(`šŸ”Ž found a '${chalk.cyan(f.id)}' migration:`); - logger.info(); + + if (result) { + logger.info(`\nšŸ”Ž found a '${chalk.cyan(f.id)}' migration:`); const message = f.prompt(result); logger.info( - boxen(message, { borderStyle: 'round', padding: 1, borderColor: '#F1618C' } as any) + boxen(message, { borderStyle: 'round', padding: 1, borderColor: '#F1618C' }) ); let runAnswer: { fix: boolean }; @@ -75,8 +77,10 @@ export const automigrate = async ({ fixId, dryRun, yes, useNpm, force }: FixOpti await f.run({ result, packageManager, dryRun }); logger.info(`āœ… ran ${chalk.cyan(f.id)} migration`); fixStatus = FixStatus.SUCCEEDED; + fixSummary.succeeded.push(f.id); } catch (error) { fixStatus = FixStatus.FAILED; + fixSummary.failed[f.id] = error.message; logger.info(`āŒ error when running ${chalk.cyan(f.id)} migration:`); logger.info(error); logger.info(); @@ -91,12 +95,46 @@ export const automigrate = async ({ fixId, dryRun, yes, useNpm, force }: FixOpti } } - fixResults[f.id] = fixStatus; + fixResults[f.id] = fixStatus } - logger.info(); - logger.info('āœ… migration check successfully ran'); - logger.info(); + logger.info() + logger.info(getMigrationSummary(fixResults, fixSummary)); + logger.info() return fixResults; }; + +function getMigrationSummary(fixResults: Record, fixSummary: { succeeded: FixId[]; failed: Record; }) { + const hasNoFixes = Object.values(fixResults).every((r) => r === FixStatus.UNNECESSARY); + const hasFailures = Object.values(fixResults).some((r) => r === FixStatus.FAILED || r === FixStatus.CHECK_FAILED); + let title = hasNoFixes ? 'No migrations were applicable to your project' : hasFailures ? 'Migration check ran with failures' : 'Migration check ran successfully'; + + let successfulFixesMessage = fixSummary.succeeded.length > 0 + ? ` + ${chalk.bold('Migrations that succeeded:')}\n\n ${fixSummary.succeeded.map(m => chalk.magenta(m)).join(', ')} + ` + : ''; + + let failedFixesMessage = Object.keys(fixSummary.failed).length > 0 + ? ` + ${chalk.bold('Migrations that failed:')}\n ${Object.entries(fixSummary.failed).reduce((acc, [id, error]) => { + return acc + `\n${chalk.magenta(id)}:\n${error}`; + }, '')} + \n` + : ''; + + const divider = hasNoFixes ? '' : '\nā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€\n\n'; + + let summaryMessage = dedent` + ${successfulFixesMessage}${failedFixesMessage}${divider}If you'd like to run the migrations again, you can do so by running '${chalk.cyan('npx storybook@next automigrate')}' + + The automigrations try to migrate common patterns in your project, but might not contain everything needed to migrate to the latest version of Storybook. + + Please check the changelog and migration guide for manual migrations and more information: ${chalk.yellow('https://storybook.js.org/migration-guides/7.0')} + And reach out on Discord if you need help: ${chalk.yellow('https://discord.gg/storybook')} + `; + + return boxen(summaryMessage, { borderStyle: 'round', padding: 1, title, borderColor: hasFailures ? 'red' : 'green' }); +} +