From 583232af331300ec841894d753fe58bd3297d3e3 Mon Sep 17 00:00:00 2001 From: Doma Date: Thu, 8 Aug 2024 21:46:43 +0800 Subject: [PATCH] feat: add --no-bump-peer-deps flag to prevent bumping peerDependencies --- src/__e2e__/bump.test.ts | 36 +++++++++++++++++++++++++++++ src/bump/bumpInPlace.ts | 2 +- src/bump/setDependentVersions.ts | 9 ++++++-- src/bump/setDependentsInBumpInfo.ts | 10 ++++++-- src/help.ts | 1 + src/options/getCliOptions.ts | 1 + src/options/getDefaultOptions.ts | 1 + src/types/BeachballOptions.ts | 6 +++++ 8 files changed, 61 insertions(+), 5 deletions(-) diff --git a/src/__e2e__/bump.test.ts b/src/__e2e__/bump.test.ts index 1f55d9f41..c6f5b4d82 100644 --- a/src/__e2e__/bump.test.ts +++ b/src/__e2e__/bump.test.ts @@ -155,6 +155,42 @@ describe('version bumping', () => { expect(changeFiles).toHaveLength(0); }); + it('does not bumps dependent packages with `peerDependencies` when `bumpPeerDeps=false`', async () => { + const monorepo: RepoFixture['folders'] = { + packages: { + 'pkg-1': { version: '1.0.0' }, + 'pkg-2': { version: '1.0.0', dependencies: { 'pkg-1': '1.0.0' } }, + 'pkg-3': { version: '1.0.0', devDependencies: { 'pkg-2': '1.0.0' } }, + 'pkg-4': { version: '1.0.0', peerDependencies: { 'pkg-3': '1.0.0' } }, + 'pkg-5': { version: '1.0.0', optionalDependencies: { 'pkg-4': '1.0.0' } }, + }, + }; + repositoryFactory = new RepositoryFactory({ folders: monorepo }); + const repo = repositoryFactory.cloneRepository(); + + generateChangeFiles(['pkg-1'], repo.rootPath); + + repo.push(); + + await bump({ path: repo.rootPath, bumpDeps: true, bumpPeerDeps: false } as BeachballOptions); + + const packageInfos = getPackageInfos(repo.rootPath); + + const pkg1NewVersion = '1.1.0'; + const dependentNewVersion = '1.0.1'; + expect(packageInfos['pkg-1'].version).toBe(pkg1NewVersion); + expect(packageInfos['pkg-2'].version).toBe(dependentNewVersion); + expect(packageInfos['pkg-3'].version).toBe(dependentNewVersion); + + expect(packageInfos['pkg-2'].dependencies!['pkg-1']).toBe(pkg1NewVersion); + expect(packageInfos['pkg-3'].devDependencies!['pkg-2']).toBe(dependentNewVersion); + expect(packageInfos['pkg-4'].peerDependencies!['pkg-3']).toBe('1.0.0'); + expect(packageInfos['pkg-5'].optionalDependencies!['pkg-4']).toBe('1.0.0'); + + const changeFiles = getChangeFiles(repo.rootPath); + expect(changeFiles).toHaveLength(0); + }); + it('bumps all grouped packages', async () => { const monorepo: RepoFixture['folders'] = { packages: { diff --git a/src/bump/bumpInPlace.ts b/src/bump/bumpInPlace.ts index 16ea6687b..7a29f0d52 100644 --- a/src/bump/bumpInPlace.ts +++ b/src/bump/bumpInPlace.ts @@ -17,7 +17,7 @@ export function bumpInPlace(bumpInfo: BumpInfo, options: BeachballOptions): void // pass 1: figure out all the change types for all the packages taking into account the bumpDeps option and version groups if (bumpDeps) { - setDependentsInBumpInfo(bumpInfo); + setDependentsInBumpInfo(bumpInfo, options); } setGroupsInBumpInfo(bumpInfo, options); diff --git a/src/bump/setDependentVersions.ts b/src/bump/setDependentVersions.ts index fe64cdc06..cdee0178f 100644 --- a/src/bump/setDependentVersions.ts +++ b/src/bump/setDependentVersions.ts @@ -5,7 +5,7 @@ import { bumpMinSemverRange } from './bumpMinSemverRange'; export function setDependentVersions( packageInfos: PackageInfos, scopedPackages: Set, - { verbose }: BeachballOptions + { verbose, bumpPeerDeps = true }: BeachballOptions ): { [dependent: string]: Set } { const dependentChangedBy: { [dependent: string]: Set } = {}; @@ -14,7 +14,12 @@ export function setDependentVersions( continue; } - for (const deps of [info.dependencies, info.devDependencies, info.peerDependencies, info.optionalDependencies]) { + for (const deps of [ + info.dependencies, + info.devDependencies, + bumpPeerDeps && info.peerDependencies, + info.optionalDependencies, + ]) { if (!deps) { continue; } diff --git a/src/bump/setDependentsInBumpInfo.ts b/src/bump/setDependentsInBumpInfo.ts index 996d59659..4e7dbf89f 100644 --- a/src/bump/setDependentsInBumpInfo.ts +++ b/src/bump/setDependentsInBumpInfo.ts @@ -1,11 +1,12 @@ import type { BumpInfo } from '../types/BumpInfo'; +import type { BeachballOptions } from '../types/BeachballOptions'; /** * Gets dependents for all packages * * Example: "BigApp" deps on "SomeUtil", "BigApp" would be the dependent */ -export function setDependentsInBumpInfo(bumpInfo: BumpInfo): void { +export function setDependentsInBumpInfo(bumpInfo: BumpInfo, { bumpPeerDeps = true }: BeachballOptions): void { const { packageInfos, scopedPackages } = bumpInfo; const dependents: BumpInfo['dependents'] = {}; @@ -14,7 +15,12 @@ export function setDependentsInBumpInfo(bumpInfo: BumpInfo): void { continue; } - for (const deps of [info.dependencies, info.devDependencies, info.peerDependencies, info.optionalDependencies]) { + for (const deps of [ + info.dependencies, + info.devDependencies, + bumpPeerDeps && info.peerDependencies, + info.optionalDependencies, + ]) { for (const dep of Object.keys(deps || {})) { if (packageInfos[dep]) { dependents[dep] ??= []; diff --git a/src/help.ts b/src/help.ts index adf77c757..963c92f17 100644 --- a/src/help.ts +++ b/src/help.ts @@ -33,6 +33,7 @@ Options: --no-push - skip pushing changes back to git remote origin --no-publish - skip publishing to the npm registry --no-bump - skip both bumping versions and pushing changes back to git remote origin when publishing; + --no-bump-peer-deps - skip bumping versions of newly published peer dependencies --no-commit - for the change command: stage change files only without autocommitting them --help, -?, -h - this very help message --yes, -y - skips the prompts for publish diff --git a/src/options/getCliOptions.ts b/src/options/getCliOptions.ts index dbd5330b9..bb988ff20 100644 --- a/src/options/getCliOptions.ts +++ b/src/options/getCliOptions.ts @@ -9,6 +9,7 @@ const booleanOptions = [ 'all', 'bump', 'bumpDeps', + 'bumpPeerDeps', 'commit', 'disallowDeletedChangeFiles', 'fetch', diff --git a/src/options/getDefaultOptions.ts b/src/options/getDefaultOptions.ts index 3c1861cce..5e60bda95 100644 --- a/src/options/getDefaultOptions.ts +++ b/src/options/getDefaultOptions.ts @@ -13,6 +13,7 @@ export function getDefaultOptions(): BeachballOptions { branch: 'origin/master', bump: true, bumpDeps: true, + bumpPeerDeps: true, canaryName: undefined, changehint: 'Run "beachball change" to create a change file', command: 'change', diff --git a/src/types/BeachballOptions.ts b/src/types/BeachballOptions.ts index 2827b4422..5316689c5 100644 --- a/src/types/BeachballOptions.ts +++ b/src/types/BeachballOptions.ts @@ -12,6 +12,7 @@ export interface CliOptions | 'access' | 'branch' | 'bumpDeps' + | 'bumpPeerDeps' | 'changehint' | 'depth' | 'disallowedChangeTypes' @@ -81,6 +82,11 @@ export interface RepoOptions { * @default true */ bumpDeps: boolean; + /** + * Bump dependent packages (peerDependencies) during publish (bump A if A depends on B as `peerDependencies`) + * @default true + */ + bumpPeerDeps?: boolean; /** Options for customizing change file prompt. */ changeFilePrompt?: ChangeFilePromptOptions; /**