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: Versioned installation of monorepo packages #25517

Merged
merged 10 commits into from
Jan 10, 2024
1 change: 0 additions & 1 deletion code/lib/cli/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,6 @@
"prompts": "^2.4.0",
"read-pkg-up": "^7.0.1",
"semver": "^7.3.7",
"simple-update-notifier": "^2.0.0",
"strip-json-comments": "^3.0.1",
"tempy": "^1.0.1",
"tiny-invariant": "^1.3.1",
Expand Down
2 changes: 1 addition & 1 deletion code/lib/cli/src/generators/NEXTJS/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ const generator: Generator = async (packageManager, npmOptions, options) => {
'react',
{
staticDir,
extraAddons: ['@storybook/addon-onboarding'],
extraAddons: ['@storybook/addon-onboarding@^1.0.0'],
webpackCompiler: ({ builder }) => undefined,
},
'nextjs'
Expand Down
2 changes: 1 addition & 1 deletion code/lib/cli/src/generators/REACT/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ const generator: Generator = async (packageManager, npmOptions, options) => {
await baseGenerator(packageManager, npmOptions, options, 'react', {
extraPackages,
webpackCompiler: ({ builder }) => (builder === CoreBuilder.Webpack5 ? 'swc' : undefined),
extraAddons: ['@storybook/addon-onboarding'],
extraAddons: ['@storybook/addon-onboarding@^1.0.0'],
});
};

Expand Down
4 changes: 2 additions & 2 deletions code/lib/cli/src/generators/REACT_NATIVE/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,14 @@ const generator = async (
'@storybook/addon-controls@^6.5.16',
];

const resolvedPackages = await packageManager.getVersionedPackages(packagesToResolve);
const versionedPackages = await packageManager.getVersionedPackages(packagesToResolve);

const babelDependencies = await getBabelDependencies(packageManager, packageJson);

const packages: string[] = [];
packages.push(...babelDependencies);
packages.push(...packagesWithFixedVersion);
packages.push(...resolvedPackages);
packages.push(...versionedPackages);
if (missingReactDom && reactVersion) {
packages.push(`react-dom@${reactVersion}`);
}
Expand Down
2 changes: 1 addition & 1 deletion code/lib/cli/src/generators/WEBPACK_REACT/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import type { Generator } from '../types';

const generator: Generator = async (packageManager, npmOptions, options) => {
await baseGenerator(packageManager, npmOptions, options, 'react', {
extraAddons: ['@storybook/addon-onboarding'],
extraAddons: ['@storybook/addon-onboarding@^1.0.0'],
webpackCompiler: ({ builder }) => (builder === CoreBuilder.Webpack5 ? 'swc' : undefined),
});
};
Expand Down
9 changes: 4 additions & 5 deletions code/lib/cli/src/generators/baseGenerator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -298,29 +298,28 @@ export async function baseGenerator(
const versionedPackages = await packageManager.getVersionedPackages(packages as string[]);
versionedPackagesSpinner.succeed();

const depsToInstall = [...versionedPackages];

try {
if (process.env.CI !== 'true') {
const { hasEslint, isStorybookPluginInstalled, eslintConfigFile } = await extractEslintInfo(
packageManager
);

if (hasEslint && !isStorybookPluginInstalled) {
depsToInstall.push('eslint-plugin-storybook');
versionedPackages.push('eslint-plugin-storybook');
await configureEslintPlugin(eslintConfigFile ?? undefined, packageManager);
}
}
} catch (err) {
// any failure regarding configuring the eslint plugin should not fail the whole generator
}

if (depsToInstall.length > 0) {
if (versionedPackages.length > 0) {
const addDependenciesSpinner = ora({
indent: 2,
text: 'Installing Storybook dependencies',
}).start();
await packageManager.addDependencies({ ...npmOptions, packageJson }, depsToInstall);

await packageManager.addDependencies({ ...npmOptions, packageJson }, versionedPackages);
addDependenciesSpinner.succeed();
}

Expand Down
35 changes: 27 additions & 8 deletions code/lib/cli/src/initiate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { NxProjectDetectedError } from '@storybook/core-events/server-errors';

import dedent from 'ts-dedent';
import boxen from 'boxen';
import { lt, prerelease } from 'semver';
import type { Builder } from './project_types';
import { installableProjectTypes, ProjectType } from './project_types';
import { detect, isStorybookInstantiated, detectLanguage, detectPnp } from './detect';
Expand Down Expand Up @@ -241,15 +242,33 @@ async function doInitiate(
force: pkgMgr,
});

const welcomeMessage = 'storybook init - the simplest way to add a Storybook to your project.';
logger.log(chalk.inverse(`\n ${welcomeMessage} \n`));
const latestVersion = await packageManager.latestVersion('@storybook/cli');
const currentVersion = versions['@storybook/cli'];
const isPrerelease = prerelease(currentVersion);
const isOutdated = lt(currentVersion, latestVersion);
const borderColor = isOutdated ? '#FC521F' : '#F1618C';

const messages = {
welcome: `Adding Storybook version ${chalk.bold(currentVersion)} to your project..`,
notLatest: chalk.red(dedent`
This version is behind the latest release, which is: ${chalk.bold(latestVersion)}!
You likely ran the init command through npx, which can use a locally cached version, to get the latest please run:
${chalk.bold('npx storybook@latest init')}

You may want to CTRL+C to stop, and run with the latest version instead.
`),
prelease: chalk.yellow('This is a pre-release version.'),
};

// Update notify code.
const { default: updateNotifier } = await import('simple-update-notifier');
await updateNotifier({
pkg: pkg as any,
updateCheckInterval: 1000 * 60 * 60, // every hour (we could increase this later on.)
});
logger.log(
boxen(
[messages.welcome]
.concat(isOutdated && !isPrerelease ? [messages.notLatest] : [])
.concat(isPrerelease ? [messages.prelease] : [])
.join('\n'),
{ borderStyle: 'round', padding: 1, borderColor }
)
);

// Check if the current directory is empty.
if (options.force !== true && currentDirectoryIsEmpty(packageManager.type)) {
Expand Down
18 changes: 17 additions & 1 deletion code/lib/cli/src/js-package-manager/JsPackageManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -330,13 +330,29 @@ export abstract class JsPackageManager {
/**
* Return an array of strings matching following format: `<package_name>@<package_latest_version>`
*
* For packages in the storybook monorepo, when the latest version is equal to the version of the current CLI
* the version is not added to the string.
*
* When a package is in the monorepo, and the version is not equal to the CLI version, the version is taken from the versions.ts file and added to the string.
*
* @param packages
*/
public getVersionedPackages(packages: string[]): Promise<string[]> {
return Promise.all(
packages.map(async (pkg) => {
const [packageName, packageVersion] = getPackageDetails(pkg);
return `${packageName}@${await this.getVersion(packageName, packageVersion)}`;
const latestInRange = await this.latestVersion(packageName, packageVersion);

const k = packageName as keyof typeof storybookPackagesVersions;
const currentVersion = storybookPackagesVersions[k];

if (currentVersion === latestInRange) {
return `${packageName}`;
}
if (currentVersion) {
return `${packageName}@${currentVersion}`;
}
return `${packageName}@^${latestInRange}`;
})
);
}
Expand Down
10 changes: 0 additions & 10 deletions code/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -5313,7 +5313,6 @@ __metadata:
prompts: "npm:^2.4.0"
read-pkg-up: "npm:^7.0.1"
semver: "npm:^7.3.7"
simple-update-notifier: "npm:^2.0.0"
slash: "npm:^5.0.0"
strip-json-comments: "npm:^3.1.1"
tempy: "npm:^1.0.1"
Expand Down Expand Up @@ -25995,15 +25994,6 @@ __metadata:
languageName: node
linkType: hard

"simple-update-notifier@npm:^2.0.0":
version: 2.0.0
resolution: "simple-update-notifier@npm:2.0.0"
dependencies:
semver: "npm:^7.5.3"
checksum: 2a00bd03bfbcbf8a737c47ab230d7920f8bfb92d1159d421bdd194479f6d01ebc995d13fbe13d45dace23066a78a3dc6642999b4e3b38b847e6664191575b20c
languageName: node
linkType: hard

"sisteransi@npm:^1.0.5":
version: 1.0.5
resolution: "sisteransi@npm:1.0.5"
Expand Down