Skip to content

Commit

Permalink
Merge pull request #26210 from storybookjs/valentin/automigration-fixes
Browse files Browse the repository at this point in the history
Automigrations: General fixes for automigrations, blockers and codemods
  • Loading branch information
valentinpalkovic authored Feb 28, 2024
2 parents 436c47e + 0380668 commit a010d45
Show file tree
Hide file tree
Showing 13 changed files with 97 additions and 78 deletions.
15 changes: 10 additions & 5 deletions code/lib/cli/src/autoblock/block-dependencies-versions.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { createBlocker } from './types';
import { dedent } from 'ts-dedent';
import { lt } from 'semver';
import chalk from 'chalk';

const minimalVersionsMap = {
'@angular/core': '15.0.0',
Expand Down Expand Up @@ -48,33 +49,37 @@ export const blocker = createBlocker({
switch (data.packageName) {
case 'react-scripts':
return dedent`
Support react-script < 5.0.0 has been removed.
Support for react-script < 5.0.0 has been removed.
Please see the migration guide for more information:
https://github.com/storybookjs/storybook/blob/next/MIGRATION.md#create-react-app-dropped-cra4-support
${chalk.yellow(
'https://github.com/storybookjs/storybook/blob/next/MIGRATION.md#create-react-app-dropped-cra4-support'
)}
Upgrade to the latest version of react-scripts.
`;
case 'vue':
return dedent`
Support for Vue 2 has been removed.
Please see the migration guide for more information:
https://v3-migration.vuejs.org/
${chalk.yellow('https://v3-migration.vuejs.org/')}
Please upgrade to the latest version of Vue.
`;
case '@angular/core':
return dedent`
Support for Angular < 15 has been removed.
Please see the migration guide for more information:
https://angular.io/guide/update-to-version-15
${chalk.yellow('https://angular.io/guide/update-to-version-15')}
Please upgrade to the latest version of Angular.
`;
case 'next':
return dedent`
Support for Next.js < 13.5 has been removed.
Please see the migration guide for more information:
https://nextjs.org/docs/pages/building-your-application/upgrading/version-13
${chalk.yellow(
'https://nextjs.org/docs/pages/building-your-application/upgrading/version-13'
)}
Please upgrade to the latest version of Next.js.
`;
Expand Down
3 changes: 2 additions & 1 deletion code/lib/cli/src/autoblock/block-node-version.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { createBlocker } from './types';
import { dedent } from 'ts-dedent';
import { lt } from 'semver';
import chalk from 'chalk';

export const blocker = createBlocker({
id: 'minimumNode16',
Expand All @@ -16,7 +17,7 @@ export const blocker = createBlocker({
We've detected you're using Node.js v${data.nodeVersion}.
Storybook needs Node.js 18 or higher.
https://nodejs.org/en/download
${chalk.yellow('https://nodejs.org/en/download')}
`;
},
});
13 changes: 8 additions & 5 deletions code/lib/cli/src/autoblock/block-storystorev6.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { createBlocker } from './types';
import { dedent } from 'ts-dedent';
import type { StorybookConfigRaw } from '@storybook/types';
import chalk from 'chalk';

export const blocker = createBlocker({
id: 'storyStoreV7removal',
Expand All @@ -19,14 +20,16 @@ export const blocker = createBlocker({
StoryStoreV7 feature must be removed from your Storybook configuration.
This feature was removed in Storybook 8.0.0.
Please see the migration guide for more information:
https://github.com/storybookjs/storybook/blob/next/MIGRATION.md#storystorev6-and-storiesof-is-deprecated
${chalk.yellow(
'https://github.com/storybookjs/storybook/blob/next/MIGRATION.md#storystorev6-and-storiesof-is-deprecated'
)}
In your Storybook configuration file you have this code:
In your Storybook configuration we found storyStoryV7 feature defined. For instance:
export default = {
features: {
storyStoreV7: false, <--- remove this line
},
features: {
${chalk.cyan(`storyStoreV7: false`)}, <--- ${chalk.bold('remove this line')}
},
};
You need to remove the storyStoreV7 property.
Expand Down
15 changes: 10 additions & 5 deletions code/lib/cli/src/autoblock/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,12 +74,13 @@ test('1 fail', async () => {
]);

expect(result).toBe('alwaysFail');
expect(logger.plain).toHaveBeenCalledWith(expect.stringContaining('Oh no..'));
expect(stripAnsi(logger.plain.mock.calls[1][0])).toMatchInlineSnapshot(`
"Blocking your upgrade because of the following issues:
expect(stripAnsi(logger.plain.mock.calls[0][0])).toMatchInlineSnapshot(`
"Storybook has found potential blockers in your project that need to be resolved before upgrading:
Always fail
─────────────────────────────────────────────────
Fix the above issues and try running the upgrade command again."
`);
});
Expand All @@ -90,13 +91,17 @@ test('multiple fails', async () => {
Promise.resolve({ blocker: blockers.alwaysFail }),
Promise.resolve({ blocker: blockers.alwaysFail2 }),
]);
expect(stripAnsi(logger.plain.mock.calls[1][0])).toMatchInlineSnapshot(`
"Blocking your upgrade because of the following issues:
expect(stripAnsi(logger.plain.mock.calls[0][0])).toMatchInlineSnapshot(`
"Storybook has found potential blockers in your project that need to be resolved before upgrading:
Always fail
─────────────────────────────────────────────────
Always fail 2
─────────────────────────────────────────────────
Fix the above issues and try running the upgrade command again."
`);

Expand Down
12 changes: 7 additions & 5 deletions code/lib/cli/src/autoblock/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ const blockers: () => BlockerModule<any>[] = () => [

type BlockerModule<T> = Promise<{ blocker: Blocker<T> }>;

const segmentDivider = '\n\n─────────────────────────────────────────────────\n\n';

export const autoblock = async (
options: AutoblockOptions,
list: BlockerModule<any>[] = blockers()
Expand Down Expand Up @@ -44,18 +46,18 @@ export const autoblock = async (

if (faults.length > 0) {
const messages = {
welcome: `Blocking your upgrade because of the following issues:`,
welcome: `Storybook has found potential blockers in your project that need to be resolved before upgrading:`,
reminder: chalk.yellow('Fix the above issues and try running the upgrade command again.'),
};
const borderColor = '#FC521F';

logger.plain('Oh no..');
logger.plain(
boxen(
[messages.welcome]
.concat(faults.map((i) => i.log))
.concat([messages.reminder])
.join('\n\n'),
.concat(['\n\n'])
.concat([faults.map((i) => i.log).join(segmentDivider)])
.concat([segmentDivider, messages.reminder])
.join(''),
{ borderStyle: 'round', padding: 1, borderColor }
)
);
Expand Down
2 changes: 1 addition & 1 deletion code/lib/cli/src/automigrate/fixes/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@ export const allFixes: Fix[] = [
builderVite,
sbBinary,
sbScripts,
removeArgtypesRegex,
removeJestTestingLibrary,
removeArgtypesRegex,
removedGlobalClientAPIs,
mdxgfm,
mdxToCSF,
Expand Down
49 changes: 12 additions & 37 deletions code/lib/cli/src/automigrate/fixes/remove-argtypes-regex.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,50 +34,25 @@ export const removeArgtypesRegex: Fix<{ argTypesRegex: NodePath; previewConfigPa
return argTypesRegex ? { argTypesRegex, previewConfigPath } : null;
},
prompt({ argTypesRegex, previewConfigPath }) {
const snippet = dedent`
import { fn } from '@storybook/test';
export default {
args: { onClick: fn() }, // will log to the action panel when clicked
};`;

// @ts-expect-error File is not yet exposed, see https://github.com/babel/babel/issues/11350#issuecomment-644118606
const file: BabelFile = new babel.File(
{ file: 'story.tsx' },
{ code: snippet, ast: babelParse(snippet) }
);

let formattedSnippet;
file.path.traverse({
Identifier: (path) => {
if (path.node.name === 'fn') {
formattedSnippet = path.buildCodeFrameError(``).message;
}
},
});

return dedent`
${chalk.bold('Attention')}: We've detected that you're using argTypesRegex:
${argTypesRegex.buildCodeFrameError(`${previewConfigPath}`).message}
Since Storybook 8, we recommend removing this regex.
Assign explicit spies with the ${chalk.cyan('fn')} function instead:
${formattedSnippet}
The above pattern is needed when using spies in the play function, ${chalk.bold(
'even'
)} if you keep using argTypesRegex.
Implicit spies (based on a combination of argTypesRegex and docgen) is not supported in Storybook 8.
In Storybook you can write so-called play functions, which are used to render your stories interactively.
Mocking action args in play functions was done implicitly by analyzing the argTypesRegex.
Since Storybook 8, implicit action args mocking isn't supported anymore.
Use the following command to check for spy usages in your play functions:
${chalk.cyan(
'npx storybook migrate find-implicit-spies --glob="**/*.stories.@(js|jsx|ts|tsx)"'
)}
Use the following command to check for mocked action usages in your play functions:
${chalk.cyan(
'npx storybook migrate find-implicit-spies --glob="**/*.stories.@(js|jsx|ts|tsx)"'
)}
Make sure to assign an explicit ${chalk.cyan('fn')} to your args for those usages.
For more information please visit our docs:
https://storybook.js.org/docs/8.0/essentials/actions#via-storybooktest-fn-spy-function
And follow the documentation to migrate your play functions:
${chalk.yellow(
'https://storybook.js.org/docs/8.0/essentials/actions#via-storybooktest-fn-spy-function'
)}
`;
},
};
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ it('should prompt to install the test package and run the codemod', async () =>
main: { addons: ['@storybook/essentials', '@storybook/addon-info'] },
});

await expect(options).toMatchInlineSnapshot(`
expect(options).toMatchInlineSnapshot(`
{
"incompatiblePackages": [
"@storybook/jest",
Expand All @@ -56,9 +56,8 @@ it('should prompt to install the test package and run the codemod', async () =>
- @storybook/jest
- @storybook/testing-library
Install the replacement for those packages: @storybook/test
We will uninstall them for you and install @storybook/test instead.
And run the following codemod:
npx storybook migrate migrate-to-test-package --glob="**/*.stories.@(js|jsx|ts|tsx)"
Also, we can help you migrate your stories to use the new package.
`);
});
43 changes: 36 additions & 7 deletions code/lib/cli/src/automigrate/fixes/remove-jest-testing-library.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
import chalk from 'chalk';
import dedent from 'ts-dedent';
import type { Fix } from '../types';
import { getStorybookVersionSpecifier } from '../../helpers';
import { runCodemod } from '@storybook/codemod';
import prompts from 'prompts';

const logger = console;

export const removeJestTestingLibrary: Fix<{ incompatiblePackages: string[] }> = {
id: 'remove-jest-testing-library',
versionRange: ['<8.0.0-alpha.0', '>=8.0.0-alpha.0'],
promptType: 'manual',
promptType: 'auto',
async check({ packageManager }) {
const deps = await packageManager.getAllDependencies();

Expand All @@ -22,12 +27,36 @@ export const removeJestTestingLibrary: Fix<{ incompatiblePackages: string[] }> =
${incompatiblePackages.map((name) => `- ${chalk.cyan(`${name}`)}`).join('\n')}
Install the replacement for those packages: ${chalk.cyan('@storybook/test')}
And run the following codemod:
${chalk.cyan(
'npx storybook migrate migrate-to-test-package --glob="**/*.stories.@(js|jsx|ts|tsx)"'
)}
We will uninstall them for you and install ${chalk.cyan('@storybook/test')} instead.
Also, we can help you migrate your stories to use the new package.
`;
},
async run({ packageManager, dryRun }) {
if (!dryRun) {
const packageJson = await packageManager.retrievePackageJson();

await packageManager.removeDependencies({ skipInstall: true, packageJson }, [
'@storybook/jest',
'@storybook/testing-library',
]);

const versionToInstall = getStorybookVersionSpecifier(packageJson);

await packageManager.addDependencies({ packageJson }, [
`@storybook/test@${versionToInstall}`,
]);

const { glob: globString } = await prompts({
type: 'text',
name: 'glob',
message: 'Please enter the glob for your stories to migrate to @storybook/test',
initial: './src/**/*.stories.*',
});

if (globString) {
await runCodemod('migrate-to-test-package', { glob: globString, dryRun, logger });
}
}
},
};
6 changes: 3 additions & 3 deletions code/lib/cli/src/automigrate/fixes/remove-legacymdx1.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,14 @@ interface RemoveLegacyMDX1Options {
* If so, prompt them to upgrade to delete it.
*/
export const removeLegacyMDX1: Fix<RemoveLegacyMDX1Options> = {
id: 'builder-vite',
id: 'remove-legacy-mdx1',
versionRange: ['<8.0.0-alpha.0', '>=8.0.0-alpha.0'],

async check({ mainConfig }) {
if (mainConfig.features) {
if (mainConfig.features && Object.hasOwn(mainConfig.features, 'legacyMdx1')) {
//
return {
hasFeature: !!Object.hasOwn(mainConfig.features, 'legacyMdx1'),
hasFeature: true,
};
}

Expand Down
2 changes: 1 addition & 1 deletion code/lib/cli/src/automigrate/fixes/storyshots-migration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import dedent from 'ts-dedent';
import type { Fix } from '../types';

export const storyshotsMigration: Fix = {
id: 'storyshots-migration',
id: 'storyshots',
versionRange: ['<8.0.0-alpha.0', '>=8.0.0-alpha.0'],
promptType: 'manual',

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ describe('getMigrationSummary', () => {
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: https://storybook.js.org/migration-guides/7.0
Please check the changelog and migration guide for manual migrations and more information: https://storybook.js.org/docs/8.0/migration-guide
And reach out on Discord if you need help: https://discord.gg/storybook"
`);
});
Expand All @@ -128,7 +128,7 @@ describe('getMigrationSummary', () => {
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: https://storybook.js.org/migration-guides/7.0
Please check the changelog and migration guide for manual migrations and more information: https://storybook.js.org/docs/8.0/migration-guide
And reach out on Discord if you need help: https://discord.gg/storybook
─────────────────────────────────────────────────
Expand Down Expand Up @@ -176,7 +176,7 @@ describe('getMigrationSummary', () => {
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: https://storybook.js.org/migration-guides/7.0
Please check the changelog and migration guide for manual migrations and more information: https://storybook.js.org/docs/8.0/migration-guide
And reach out on Discord if you need help: https://discord.gg/storybook"
`);
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ export function getMigrationSummary({
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'
'https://storybook.js.org/docs/8.0/migration-guide'
)}
And reach out on Discord if you need help: ${chalk.yellow('https://discord.gg/storybook')}
`);
Expand Down

0 comments on commit a010d45

Please sign in to comment.