diff --git a/tools/generators/dependency-mismatch/index.spec.ts b/tools/generators/dependency-mismatch/index.spec.ts index f85c7cbf57f27..e6f642d39accd 100644 --- a/tools/generators/dependency-mismatch/index.spec.ts +++ b/tools/generators/dependency-mismatch/index.spec.ts @@ -33,7 +33,7 @@ describe('dependency-mismatch generator', () => { }); await generator(appTree); - const packageJson: PackageJson = await readTargetPackageJson(); + const packageJson: PackageJson = readTargetPackageJson(); expect(packageJson.dependencies).toMatchInlineSnapshot(` Object { "@proj/react-theme": "^9.0.1", @@ -41,7 +41,7 @@ describe('dependency-mismatch generator', () => { `); }); - it('should also fix dev dependencies', async () => { + it('should fix dev dependencies', async () => { const { readPackageJson: readTargetPackageJson } = setupDummyPackage(appTree, { name: 'public-docsite-v9', version: '9.0.0', @@ -61,7 +61,7 @@ describe('dependency-mismatch generator', () => { }); await generator(appTree); - const packageJson: PackageJson = await readTargetPackageJson(); + const packageJson: PackageJson = readTargetPackageJson(); expect(packageJson.devDependencies).toMatchInlineSnapshot(` Object { "@proj/react-theme": "^9.0.1", @@ -69,7 +69,7 @@ describe('dependency-mismatch generator', () => { `); }); - it('should also fix peer dependencies', async () => { + it('should fix peer dependencies', async () => { const { readPackageJson: readTargetPackageJson } = setupDummyPackage(appTree, { name: 'public-docsite-v9', version: '9.0.0', @@ -89,7 +89,7 @@ describe('dependency-mismatch generator', () => { }); await generator(appTree); - const packageJson: PackageJson = await readTargetPackageJson(); + const packageJson: PackageJson = readTargetPackageJson(); expect(packageJson.peerDependencies).toMatchInlineSnapshot(` Object { "@proj/react-theme": "^9.0.1", @@ -125,7 +125,7 @@ describe('dependency-mismatch generator', () => { }); await generator(appTree); - const packageJson: PackageJson = await readTargetPackageJson(); + const packageJson: PackageJson = readTargetPackageJson(); expect(packageJson.dependencies).toMatchInlineSnapshot(` Object { "@proj/react-select": "^9.0.0-beta.2", @@ -134,7 +134,7 @@ describe('dependency-mismatch generator', () => { `); }); - it('should run non-converged package', async () => { + it('should run on v8 packages', async () => { const { readPackageJson: readTargetPackageJson } = setupDummyPackage(appTree, { name: 'react', version: '8.0.0', @@ -154,7 +154,7 @@ describe('dependency-mismatch generator', () => { }); await generator(appTree); - const packageJson: PackageJson = await readTargetPackageJson(); + const packageJson: PackageJson = readTargetPackageJson(); expect(packageJson.dependencies).toMatchInlineSnapshot(` Object { "@proj/react-portal-compat-context": "^9.0.1", @@ -162,28 +162,7 @@ describe('dependency-mismatch generator', () => { `); }); - it('should ignore 3rd party packages/dependencies', async () => { - const { readPackageJson: readTargetPackageJson } = setupDummyPackage(appTree, { - name: 'react', - version: '8.0.0', - dependencies: { - [`@${workspaceNpmScope}/tslib`]: '^2.1.1', - }, - devDependencies: {}, - peerDependencies: {}, - }); - - await generator(appTree); - - const packageJson: PackageJson = await readTargetPackageJson(); - expect(packageJson.dependencies).toMatchInlineSnapshot(` - Object { - "@proj/tslib": "^2.1.1", - } - `); - }); - - it('generator should not run on northstar packages', async () => { + it('should run on v0(northstar) packages changing only v9 deps', async () => { const { readPackageJson: readTargetPackageJson } = setupDummyPackage( appTree, { @@ -191,6 +170,7 @@ describe('dependency-mismatch generator', () => { version: '0.66.0', dependencies: { [`@${workspaceNpmScope}/dom-utilities`]: '^1.1.1', + [`@${workspaceNpmScope}/react-portal-compat-context`]: '^9.0.0', }, devDependencies: {}, peerDependencies: {}, @@ -205,6 +185,17 @@ describe('dependency-mismatch generator', () => { devDependencies: {}, peerDependencies: {}, }); + setupDummyPackage( + appTree, + { + name: 'react-portal-compat-context', + version: '9.0.1', + dependencies: {}, + devDependencies: {}, + peerDependencies: {}, + }, + ['vNext'], + ); await generator(appTree); @@ -212,6 +203,28 @@ describe('dependency-mismatch generator', () => { expect(packageJson.dependencies).toMatchInlineSnapshot(` Object { "@proj/dom-utilities": "^1.1.1", + "@proj/react-portal-compat-context": "^9.0.1", + } + `); + }); + + it('should ignore 3rd party packages/dependencies', async () => { + const { readPackageJson: readTargetPackageJson } = setupDummyPackage(appTree, { + name: 'react', + version: '8.0.0', + dependencies: { + [`@${workspaceNpmScope}/tslib`]: '^2.1.1', + }, + devDependencies: {}, + peerDependencies: {}, + }); + + await generator(appTree); + + const packageJson: PackageJson = readTargetPackageJson(); + expect(packageJson.dependencies).toMatchInlineSnapshot(` + Object { + "@proj/tslib": "^2.1.1", } `); }); diff --git a/tools/generators/dependency-mismatch/index.ts b/tools/generators/dependency-mismatch/index.ts index 599f097ec3096..00d76fa5f6473 100644 --- a/tools/generators/dependency-mismatch/index.ts +++ b/tools/generators/dependency-mismatch/index.ts @@ -2,31 +2,32 @@ import * as semver from 'semver'; import { Tree, formatFiles, updateJson, readJson, readProjectConfiguration } from '@nrwl/devkit'; import { getProjectConfig, getProjects, isPackageVersionPrerelease } from '../../utils'; -import { PackageJson } from '../../types'; +import type { PackageJson } from '../../types'; export default async function (tree: Tree) { const projects = getProjects(tree); projects.forEach((_project, projectName) => { const config = getProjectConfig(tree, { packageName: projectName }); - - const { tags = [] } = readProjectConfiguration(tree, projectName); - // Ignore northstar packages - if (tags.includes('react-northstar')) { - return; - } + const scope = getProjectScope(config); updateJson(tree, config.paths.packageJson, (packageJson: PackageJson) => { if (packageJson.dependencies) { - packageJson.dependencies = getUpdatedDependencies(tree, packageJson.dependencies); + packageJson.dependencies = getUpdatedDependencies(tree, { dependencies: packageJson.dependencies, scope }); } if (packageJson.devDependencies) { - packageJson.devDependencies = getUpdatedDependencies(tree, packageJson.devDependencies); + packageJson.devDependencies = getUpdatedDependencies(tree, { + dependencies: packageJson.devDependencies, + scope, + }); } if (packageJson.peerDependencies) { - packageJson.peerDependencies = getUpdatedDependencies(tree, packageJson.peerDependencies); + packageJson.peerDependencies = getUpdatedDependencies(tree, { + dependencies: packageJson.peerDependencies, + scope, + }); } return packageJson; @@ -46,7 +47,11 @@ function isProjectInWorkspace(tree: Tree, projectName: string) { } } -function getUpdatedDependencies(tree: Tree, dependencies: Record) { +function getUpdatedDependencies( + tree: Tree, + options: { dependencies: Record; scope: ReturnType }, +) { + const { dependencies, scope } = options; return Object.entries(dependencies).reduce((acc, [dependencyName, versionRange]) => { if (versionRange === '*') { return acc; @@ -62,9 +67,15 @@ function getUpdatedDependencies(tree: Tree, dependencies: Record return acc; } - const shouldHaveCaret = !isPackageVersionPrerelease(minVersion.raw) || versionRange[0] === '^'; - const depPackageConfig = getProjectConfig(tree, { packageName: dependencyName }); + const depScope = getProjectScope(depPackageConfig); + + const isNorthstarUnsupportedDepBump = scope.isReactNorthstarPackage && !depScope.isReactComponentsPackage; + if (isNorthstarUnsupportedDepBump) { + return acc; + } + + const shouldHaveCaret = !isPackageVersionPrerelease(minVersion.raw) || versionRange[0] === '^'; acc[dependencyName] = `${shouldHaveCaret ? '^' : ''}${ readJson(tree, depPackageConfig.paths.packageJson).version @@ -73,3 +84,11 @@ function getUpdatedDependencies(tree: Tree, dependencies: Record return acc; }, dependencies); } + +function getProjectScope(project: ReturnType) { + const tags = project.projectConfig.tags ?? []; + const isReactPackage = tags.includes('v8'); + const isReactNorthstarPackage = tags.includes('react-northstar'); + const isReactComponentsPackage = tags.includes('vNext'); + return { isReactPackage, isReactNorthstarPackage, isReactComponentsPackage }; +} diff --git a/tools/utils.ts b/tools/utils.ts index 0890300ba7b74..ea2a26524072f 100644 --- a/tools/utils.ts +++ b/tools/utils.ts @@ -197,7 +197,7 @@ export function isPackageVersionConverged(versionString: string) { export function isPackageVersionPrerelease(versionString: string) { const version = semver.parse(versionString); - return version?.prerelease?.length && version?.prerelease?.length > 0; + return Boolean(version?.prerelease?.length && version?.prerelease?.length > 0); } export function isPackageConverged(tree: Tree, project: ProjectConfiguration) {