Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CLI: Improve Storybook packages version management #11342

Merged
merged 7 commits into from
Jul 15, 2020
2 changes: 1 addition & 1 deletion addons/docs/src/frameworks/common/preset.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ type BabelParams = {
function createBabelOptions({ babelOptions, mdxBabelOptions, configureJSX }: BabelParams) {
const babelPlugins = mdxBabelOptions?.plugins || babelOptions?.plugins || [];
const jsxPlugin = [
'@babel/plugin-transform-react-jsx',
require.resolve('@babel/plugin-transform-react-jsx'),
{ pragma: 'React.createElement', pragmaFrag: 'React.Fragment' },
];
const plugins = configureJSX ? [...babelPlugins, jsxPlugin] : babelPlugins;
Expand Down
16 changes: 16 additions & 0 deletions cypress/generated/addon-viewport.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
describe('addon-viewport', () => {
before(() => {
cy.visitStorybook();
});

it('should have viewport button in the toolbar', () => {
cy.navigateToStory('button', 'Text');

// Click on viewport button and select small mobile
cy.get('[title="Change the size of the preview"]').click();
cy.get('#mobile1').click();

// Check that Welcome story is still displayed
cy.getStoryElement().should('contain.text', 'Button');
});
});
30 changes: 2 additions & 28 deletions lib/cli/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,10 @@
"versions.json"
],
"scripts": {
"prepare": "node ../../scripts/prepare.js && node -r esm ./scripts/generate-app-versions.js",
"prepare": "node ../../scripts/prepare.js && node -r esm ./scripts/generate-sb-packages-versions.js",
"test": "cd test && ./run_tests.sh",
"test-yarn-2": "cd test && ./run_tests_yarn_2.sh",
"postversion": "node -r esm ./scripts/generate-app-versions.js"
"postversion": "node -r esm ./scripts/generate-sb-packages-versions.js"
Comment on lines +35 to +38
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@shilman can you confirm that with these 2 lines, versions.json will be recreated during the release process (after the version bump) and then committed to the repo?

},
"dependencies": {
"@babel/core": "^7.9.6",
Expand Down Expand Up @@ -63,32 +63,6 @@
"update-notifier": "^4.0.0"
},
"devDependencies": {
"@storybook/addon-actions": "6.0.0-rc.3",
"@storybook/addon-docs": "6.0.0-rc.3",
"@storybook/addon-essentials": "6.0.0-rc.3",
"@storybook/addon-graphql": "6.0.0-rc.3",
"@storybook/addon-knobs": "6.0.0-rc.3",
"@storybook/addon-links": "6.0.0-rc.3",
"@storybook/addon-storyshots": "6.0.0-rc.3",
"@storybook/addons": "6.0.0-rc.3",
"@storybook/angular": "6.0.0-rc.3",
"@storybook/channel-postmessage": "6.0.0-rc.3",
"@storybook/channel-websocket": "6.0.0-rc.3",
"@storybook/channels": "6.0.0-rc.3",
"@storybook/ember": "6.0.0-rc.3",
"@storybook/html": "6.0.0-rc.3",
"@storybook/marionette": "6.0.0-rc.3",
"@storybook/marko": "6.0.0-rc.3",
"@storybook/mithril": "6.0.0-rc.3",
"@storybook/preact": "6.0.0-rc.3",
"@storybook/rax": "6.0.0-rc.3",
"@storybook/react": "6.0.0-rc.3",
"@storybook/react-native": "6.0.0-alpha.0",
"@storybook/riot": "6.0.0-rc.3",
"@storybook/svelte": "6.0.0-rc.3",
"@storybook/ui": "6.0.0-rc.3",
"@storybook/vue": "6.0.0-rc.3",
"@storybook/web-components": "6.0.0-rc.3",
"@types/cross-spawn": "^6.0.1",
"@types/inquirer": "^6.5.0",
"@types/puppeteer-core": "^2.0.0",
Expand Down
37 changes: 0 additions & 37 deletions lib/cli/scripts/generate-app-versions.js

This file was deleted.

41 changes: 41 additions & 0 deletions lib/cli/scripts/generate-sb-packages-versions.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { writeJson, readJson } from 'fs-extra';
import path from 'path';
import globby from 'globby';

const rootDirectory = path.join(__dirname, '..', '..', '..');

const logger = console;

const run = async () => {
const storybookPackagesPaths = await globby(
`${rootDirectory}/@(app|addons|lib)/**/package.json`,
{
ignore: '**/node_modules/**/*',
}
);

const packageToVersionMap = (
await Promise.all(
storybookPackagesPaths.map(async (storybookPackagePath) => {
const { name, version } = await readJson(storybookPackagePath);

return {
name,
version,
};
})
)
)
// Remove non-`@storybook/XXX` package (like: `cli-sb`, `cli-storybook`)
.filter(({ name }) => /@storybook/.test(name))
// As some previous steps are asynchronous order is not always the same so sort them to avoid that
.sort((package1, package2) => package1.name.localeCompare(package2.name))
.reduce((acc, { name, version }) => ({ ...acc, [name]: version }), {});

await writeJson(path.join(__dirname, '..', 'versions.json'), packageToVersionMap, { spaces: 2 });
};

run().catch((e) => {
logger.error(e);
process.exit(1);
});
6 changes: 3 additions & 3 deletions lib/cli/src/generate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ const logger = console;
program
.command('init')
.description('Initialize Storybook into your project.')
.option('-f --force', 'Force add storybook')
.option('-f --force', 'Force add Storybook')
.option('-s --skip-install', 'Skip installing deps')
.option('-N --use-npm', 'Use npm to install deps')
.option('-p --parser <babel | babylon | flow | ts | tsx>', 'jscodeshift parser')
Expand All @@ -35,7 +35,7 @@ program

program
.command('upgrade')
.description('Upgrade your storybook packages to the latest')
.description('Upgrade your Storybook packages to the latest')
.option('-N --use-npm', 'Use NPM to build the Storybook server')
.option('-n --dry-run', 'Only check for upgrades, do not install')
.option('-p --prerelease', 'Upgrade to the pre-release packages')
Expand All @@ -60,7 +60,7 @@ program

program
.command('migrate [migration]')
.description('Run a storybook codemod migration on your source files')
.description('Run a Storybook codemod migration on your source files')
.option('-l --list', 'List available migrations')
.option('-g --glob <glob>', 'Glob for files upon which to apply the migration', '**/*.js')
.option('-p --parser <babel | babylon | flow | ts | tsx>', 'jscodeshift parser')
Expand Down
4 changes: 4 additions & 0 deletions lib/cli/src/generators/baseGenerator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,11 +49,15 @@ export async function baseGenerator(
'@storybook/addon-essentials',
];

const yarn2Dependencies =
packageManager.type === 'yarn2' ? ['@storybook/addon-docs', '@mdx-js/react'] : [];

const packages = [
`@storybook/${framework}`,
...addons,
...extraPackages,
...extraAddons,
...yarn2Dependencies,
// ⚠️ Some addons have peer deps that must be added too, like '@storybook/addon-docs' => 'react-is'
'react-is',
].filter(Boolean);
Expand Down
50 changes: 25 additions & 25 deletions lib/cli/src/initiate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ const installStorybook = (projectType: ProjectType, options: CommandOptions): Pr
packageManager.installDependencies();
}

logger.log('\nTo run your storybook, type:\n');
logger.log('\nTo run your Storybook, type:\n');
codeLog([packageManager.getRunStorybookCommand()]);
logger.log('\nFor more information visit:', chalk.cyan('https://storybook.js.org'));

Expand All @@ -85,7 +85,7 @@ const installStorybook = (projectType: ProjectType, options: CommandOptions): Pr
switch (projectType) {
case ProjectType.ALREADY_HAS_STORYBOOK:
logger.log();
paddedLog('There seems to be a storybook already available in this project.');
paddedLog('There seems to be a Storybook already available in this project.');
paddedLog('Apply following command to force:\n');
codeLog(['sb init [options] -f']);

Expand All @@ -96,17 +96,17 @@ const installStorybook = (projectType: ProjectType, options: CommandOptions): Pr
case ProjectType.UPDATE_PACKAGE_ORGANIZATIONS:
return updateOrganisationsGenerator(packageManager, options.parser, npmOptions)
.then(() => null) // commmandLog doesn't like to see output
.then(commandLog('Upgrading your project to the new storybook packages.'))
.then(commandLog('Upgrading your project to the new Storybook packages.'))
.then(end);

case ProjectType.REACT_SCRIPTS:
return reactScriptsGenerator(packageManager, npmOptions, generatorOptions)
.then(commandLog('Adding storybook support to your "Create React App" based project'))
.then(commandLog('Adding Storybook support to your "Create React App" based project'))
.then(end);

case ProjectType.REACT:
return reactGenerator(packageManager, npmOptions, generatorOptions)
.then(commandLog('Adding storybook support to your "React" app'))
.then(commandLog('Adding Storybook support to your "React" app'))
.then(end);

case ProjectType.REACT_NATIVE: {
Expand All @@ -117,19 +117,19 @@ const installStorybook = (projectType: ProjectType, options: CommandOptions): Pr
type: 'confirm',
name: 'server',
message:
'Do you want to install dependencies necessary to run storybook server? You can manually do it later by install @storybook/react-native-server',
'Do you want to install dependencies necessary to run Storybook server? You can manually do it later by install @storybook/react-native-server',
default: false,
},
]) as Promise<{ server: boolean }>)
)
.then(({ server }) =>
reactNativeGenerator(packageManager, npmOptions, server, generatorOptions)
)
.then(commandLog('Adding storybook support to your "React Native" app'))
.then(commandLog('Adding Storybook support to your "React Native" app'))
.then(end)
.then(() => {
logger.log(chalk.red('NOTE: installation is not 100% automated.'));
logger.log(`To quickly run storybook, replace contents of your app entry with:\n`);
logger.log(`To quickly run Storybook, replace contents of your app entry with:\n`);
codeLog(["export default from './storybook';"]);
logger.log('\n For more in depth setup instructions, see:\n');
logger.log(chalk.cyan(REACT_NATIVE_DISCUSSION));
Expand All @@ -139,82 +139,82 @@ const installStorybook = (projectType: ProjectType, options: CommandOptions): Pr

case ProjectType.METEOR:
return meteorGenerator(packageManager, npmOptions, generatorOptions)
.then(commandLog('Adding storybook support to your "Meteor" app'))
.then(commandLog('Adding Storybook support to your "Meteor" app'))
.then(end);

case ProjectType.WEBPACK_REACT:
return webpackReactGenerator(packageManager, npmOptions, generatorOptions)
.then(commandLog('Adding storybook support to your "Webpack React" app'))
.then(commandLog('Adding Storybook support to your "Webpack React" app'))
.then(end);

case ProjectType.REACT_PROJECT:
return reactGenerator(packageManager, npmOptions, generatorOptions)
.then(commandLog('Adding storybook support to your "React" library'))
.then(commandLog('Adding Storybook support to your "React" library'))
.then(end);

case ProjectType.SFC_VUE:
return sfcVueGenerator(packageManager, npmOptions, generatorOptions)
.then(commandLog('Adding storybook support to your "Single File Components Vue" app'))
.then(commandLog('Adding Storybook support to your "Single File Components Vue" app'))
.then(end);

case ProjectType.VUE:
return vueGenerator(packageManager, npmOptions, generatorOptions)
.then(commandLog('Adding storybook support to your "Vue" app'))
.then(commandLog('Adding Storybook support to your "Vue" app'))
.then(end);

case ProjectType.ANGULAR:
return angularGenerator(packageManager, npmOptions, generatorOptions)
.then(commandLog('Adding storybook support to your "Angular" app'))
.then(commandLog('Adding Storybook support to your "Angular" app'))
.then(end);

case ProjectType.EMBER:
return emberGenerator(packageManager, npmOptions, generatorOptions)
.then(commandLog('Adding storybook support to your "Ember" app'))
.then(commandLog('Adding Storybook support to your "Ember" app'))
.then(end);

case ProjectType.MITHRIL:
return mithrilGenerator(packageManager, npmOptions, generatorOptions)
.then(commandLog('Adding storybook support to your "Mithril" app'))
.then(commandLog('Adding Storybook support to your "Mithril" app'))
.then(end);

case ProjectType.MARIONETTE:
return marionetteGenerator(packageManager, npmOptions, generatorOptions)
.then(commandLog('Adding storybook support to your "Marionette.js" app'))
.then(commandLog('Adding Storybook support to your "Marionette.js" app'))
.then(end);

case ProjectType.MARKO:
return markoGenerator(packageManager, npmOptions, generatorOptions)
.then(commandLog('Adding storybook support to your "Marko" app'))
.then(commandLog('Adding Storybook support to your "Marko" app'))
.then(end);

case ProjectType.HTML:
return htmlGenerator(packageManager, npmOptions, generatorOptions)
.then(commandLog('Adding storybook support to your "HTML" app'))
.then(commandLog('Adding Storybook support to your "HTML" app'))
.then(end);

case ProjectType.WEB_COMPONENTS:
return webComponentsGenerator(packageManager, npmOptions, generatorOptions)
.then(commandLog('Adding storybook support to your "web components" app'))
.then(commandLog('Adding Storybook support to your "web components" app'))
.then(end);

case ProjectType.RIOT:
return riotGenerator(packageManager, npmOptions, generatorOptions)
.then(commandLog('Adding storybook support to your "riot.js" app'))
.then(commandLog('Adding Storybook support to your "riot.js" app'))
.then(end);

case ProjectType.PREACT:
return preactGenerator(packageManager, npmOptions, generatorOptions)
.then(commandLog('Adding storybook support to your "Preact" app'))
.then(commandLog('Adding Storybook support to your "Preact" app'))
.then(end);

case ProjectType.SVELTE:
return svelteGenerator(packageManager, npmOptions, generatorOptions)
.then(commandLog('Adding storybook support to your "Svelte" app'))
.then(commandLog('Adding Storybook support to your "Svelte" app'))
.then(end);

case ProjectType.RAX:
return raxGenerator(packageManager, npmOptions, generatorOptions)
.then(commandLog('Adding storybook support to your "Rax" app'))
.then(commandLog('Adding Storybook support to your "Rax" app'))
.then(end);

default:
Expand Down Expand Up @@ -263,7 +263,7 @@ const projectTypeInquirer = async (options: { yes?: boolean }) => {
};

export default function (options: CommandOptions, pkg: IPackage): Promise<void> {
const welcomeMessage = 'sb init - the simplest way to add a storybook to your project.';
const welcomeMessage = 'sb init - the simplest way to add a Storybook to your project.';
logger.log(chalk.inverse(`\n ${welcomeMessage} \n`));

// Update notify code.
Expand Down
11 changes: 5 additions & 6 deletions lib/cli/src/js-package-manager/JsPackageManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@ import { readPackageJson, writePackageJson } from './PackageJsonHelper';

const logger = console;
// Cannot be `import` as it's not under TS root dir
const { storybookCLIVersion, devDependencies } = require('../../package.json');
const storybookPackagesVersions = require('../../versions.json');

export abstract class JsPackageManager {
public abstract type: 'npm' | 'yarn' | 'yarn2';
public abstract readonly type: 'npm' | 'yarn1' | 'yarn2';

public abstract initPackageJson(): void;

Expand Down Expand Up @@ -138,10 +138,9 @@ export abstract class JsPackageManager {

public async getVersion(packageName: string, constraint?: string): Promise<string> {
let current;
if (packageName === '@storybook/cli') {
current = storybookCLIVersion;
} else if (/storybook/.test(packageName)) {
current = devDependencies[packageName];

if (/@storybook/.test(packageName)) {
current = storybookPackagesVersions[packageName];
}

let latest;
Expand Down
Loading