-
Notifications
You must be signed in to change notification settings - Fork 2.9k
chore(nx-generator): Replace internal dev dependency versions with *
#19799
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
Merged
Merged
Changes from all commits
Commits
Show all changes
9 commits
Select commit
Hold shift + click to select a range
edb589c
chore(nx-generator): Replace internal dev dependency versions with `*`
ling1726 6f8a298
improve logs
ling1726 2e933d8
improve logging
ling1726 d3beca9
update version group
ling1726 b92ef3b
increase readability
ling1726 7ab484c
Merge remote-tracking branch 'origin/master' into chore/start-dev-deps
ling1726 3f87685
run on all packages for limited deps
ling1726 930eb45
make configurabl;e
ling1726 5958d4b
remove test-utilites
ling1726 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,39 @@ | ||
| # star-dev-deps | ||
|
|
||
| For all packages in the monorepo, replace certain dev dependencies on other internal packages in the monorepo with the `*` | ||
| version. | ||
|
|
||
| The dependencies to be updated can be configured in `config.ts` | ||
|
|
||
| <!-- toc --> | ||
|
|
||
| - [NOTES](#notes) | ||
| - [Usage](#usage) | ||
| - [Examples](#examples) | ||
|
|
||
| <!-- tocstop --> | ||
|
|
||
| ## NOTES | ||
|
|
||
| - Only affects dev dependencies that are also published from the monorepo | ||
| - Does not affect third party dependencies | ||
| - Will run for every package in the monorepo | ||
| - Only updates dependencies listed in `config.ts` | ||
|
|
||
| ## Usage | ||
|
|
||
| ```sh | ||
| yarn nx workspace-generator star-dev-deps | ||
| ``` | ||
|
|
||
| Show what will be generated without writing to disk: | ||
|
|
||
| ```sh | ||
| yarn nx workspace-generator star-dev-deps --dry-run | ||
| ``` | ||
|
|
||
| ### Examples | ||
|
|
||
| ```sh | ||
| yarn nx workspace-generator star-dev-deps | ||
| ``` |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| export const dependenciesToUpdate = ['@fluentui/eslint-plugin', '@fluentui/react-conformance']; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,160 @@ | ||
| import { createTreeWithEmptyWorkspace } from '@nrwl/devkit/testing'; | ||
| import { | ||
| Tree, | ||
| readProjectConfiguration, | ||
| addProjectConfiguration, | ||
| serializeJson, | ||
| readWorkspaceConfiguration, | ||
| readJson, | ||
| } from '@nrwl/devkit'; | ||
|
|
||
| import generator from './index'; | ||
| import { StarDevDepsGeneratorSchema } from './schema'; | ||
|
|
||
| describe('star-dev-deps generator', () => { | ||
| let tree: Tree; | ||
| const options: StarDevDepsGeneratorSchema = { name: 'test' }; | ||
|
|
||
| beforeEach(() => { | ||
| tree = createTreeWithEmptyWorkspace(); | ||
| setupDummyPackage(tree, { | ||
| packageName: '@proj/eslint-plugin', | ||
| version: '1.0.0', | ||
| }); | ||
| }); | ||
|
|
||
| it('should change internal package devdeps to * version', async () => { | ||
| const devPkgName = '@proj/eslint-plugin'; | ||
|
|
||
| setupDummyPackage(tree, { | ||
| packageName: '@proj/react-button', | ||
| devDependencies: { [devPkgName]: '1.0.0' }, | ||
| }); | ||
|
|
||
| await generator(tree); | ||
| const pkgJson = readJson(tree, 'packages/react-button/package.json'); | ||
| expect(pkgJson.devDependencies[devPkgName]).toBe('*'); | ||
| }); | ||
|
|
||
| it('should run for all packages in the monorepo', async () => { | ||
| const devPkgName = '@proj/eslint-plugin'; | ||
|
|
||
| setupDummyPackage(tree, { | ||
| packageName: '@proj/react-button', | ||
| devDependencies: { [devPkgName]: '1.0.0' }, | ||
| }); | ||
|
|
||
| setupDummyPackage(tree, { | ||
| packageName: '@proj/react-avatar', | ||
| devDependencies: { [devPkgName]: '1.0.0' }, | ||
| }); | ||
|
|
||
| setupDummyPackage(tree, { | ||
| packageName: '@proj/react-menu', | ||
| devDependencies: { [devPkgName]: '1.0.0' }, | ||
| }); | ||
|
|
||
| await generator(tree); | ||
|
|
||
| ['react-button', 'react-avatar', 'react-menu'].forEach(name => { | ||
| const path = `packages/${name}/package.json`; | ||
| const pkgJson = readJson(tree, path); | ||
| expect(pkgJson.devDependencies[devPkgName]).toBe('*'); | ||
| }); | ||
| }); | ||
|
|
||
| it('should also modify non-v9 packages', async () => { | ||
| const devPkgName = '@proj/eslint-plugin'; | ||
|
|
||
| setupDummyPackage(tree, { | ||
| packageName: '@proj/react-button', | ||
| version: '1.0.0', | ||
| devDependencies: { [devPkgName]: '1.0.0' }, | ||
| }); | ||
|
|
||
| await generator(tree); | ||
| const pkgJson = readJson(tree, 'packages/react-button/package.json'); | ||
| expect(pkgJson.devDependencies[devPkgName]).toBe('*'); | ||
| }); | ||
|
|
||
| it('should only modify dev dependencies', async () => { | ||
| const devPkgName = '@proj/eslint-plugin'; | ||
| const expectedVersion = '1.0.0'; | ||
|
|
||
| setupDummyPackage(tree, { | ||
| packageName: '@proj/react-button', | ||
| version: '9.0.0', | ||
| dependencies: { [devPkgName]: expectedVersion }, | ||
| }); | ||
|
|
||
| await generator(tree); | ||
| const pkgJson = readJson(tree, 'packages/react-button/package.json'); | ||
| expect(pkgJson.dependencies[devPkgName]).toBe(expectedVersion); | ||
| }); | ||
|
|
||
| it('should not modify external dev dependencies', async () => { | ||
| const devPkgName = 'jest'; | ||
| const expectedVersion = '1.0.0'; | ||
|
|
||
| setupDummyPackage(tree, { | ||
| packageName: '@proj/react-button', | ||
| version: '9.0.0', | ||
| dependencies: { [devPkgName]: expectedVersion }, | ||
| }); | ||
|
|
||
| await generator(tree); | ||
| const pkgJson = readJson(tree, 'packages/react-button/package.json'); | ||
| expect(pkgJson.dependencies[devPkgName]).toBe(expectedVersion); | ||
| }); | ||
| }); | ||
|
|
||
| function setupDummyPackage( | ||
| tree: Tree, | ||
| options: Partial<{ | ||
| packageName: string; | ||
| version: string; | ||
| devDependencies: Record<string, string>; | ||
| dependencies: Record<string, string>; | ||
| projectConfiguration: Partial<ReturnType<typeof readProjectConfiguration>>; | ||
| }>, | ||
| ) { | ||
| const workspaceConfig = readWorkspaceConfiguration(tree); | ||
| const defaults = { | ||
| version: '9.0.0-alpha.40', | ||
| dependencies: { | ||
| [`@${workspaceConfig.npmScope}/react-make-styles`]: '^9.0.0-alpha.38', | ||
| [`@${workspaceConfig.npmScope}/react-theme`]: '^9.0.0-alpha.13', | ||
| [`@${workspaceConfig.npmScope}/react-utilities`]: '^9.0.0-alpha.25', | ||
| tslib: '^2.1.0', | ||
| someThirdPartyDep: '^11.1.2', | ||
| }, | ||
| }; | ||
|
|
||
| const normalizedOptions = { ...defaults, ...options }; | ||
| const pkgName = options.packageName || ''; | ||
| const normalizedPkgName = pkgName.replace(`@${workspaceConfig.npmScope}/`, ''); | ||
| const paths = { | ||
| root: `packages/${normalizedPkgName}`, | ||
| }; | ||
|
|
||
| const templates = { | ||
| packageJson: { | ||
| name: pkgName, | ||
| version: normalizedOptions.version, | ||
| dependencies: normalizedOptions.dependencies, | ||
| devDependencies: normalizedOptions.devDependencies, | ||
| }, | ||
| }; | ||
|
|
||
| tree.write(`${paths.root}/package.json`, serializeJson(templates.packageJson)); | ||
|
|
||
| addProjectConfiguration(tree, pkgName, { | ||
| root: paths.root, | ||
| projectType: 'library', | ||
| targets: {}, | ||
| tags: ['platform:web'], | ||
| ...options.projectConfiguration, | ||
| }); | ||
|
|
||
| return tree; | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,67 @@ | ||
| import { Tree, updateJson, getProjects, formatFiles, readWorkspaceConfiguration, readJson } from '@nrwl/devkit'; | ||
| import { getProjectConfig, printUserLogs, UserLog } from '../../utils'; | ||
| import { PackageJson } from '../../types'; | ||
| import { dependenciesToUpdate } from './config'; | ||
|
|
||
| export default async function (host: Tree) { | ||
| const userLog: UserLog = []; | ||
|
|
||
| runMigration(host, userLog); | ||
|
|
||
| formatFiles(host); | ||
|
|
||
| return () => { | ||
| printUserLogs(userLog); | ||
| }; | ||
| } | ||
|
|
||
| function runMigrationOnProject(host: Tree, packageName: string, userLog: UserLog) { | ||
| const projectConfig = getProjectConfig(host, { packageName }); | ||
| const packageJsonPath = projectConfig.paths.packageJson; | ||
|
|
||
| updateJson(host, packageJsonPath, (packageJson: PackageJson) => { | ||
| if (packageJson.devDependencies) { | ||
| Object.keys(packageJson.devDependencies).forEach(dependency => { | ||
| if ( | ||
| isPackageInMonorepo(dependency, host) && | ||
| packageJson.devDependencies && | ||
| dependenciesToUpdate.includes(dependency) | ||
| ) { | ||
| userLog.push({ | ||
| type: 'info', | ||
| message: `Updating dev dependency ${dependency} in ${packageName}`, | ||
| }); | ||
| packageJson.devDependencies[dependency] = '*'; | ||
| } | ||
| }); | ||
| } | ||
|
|
||
| return packageJson; | ||
| }); | ||
| } | ||
|
|
||
| function runMigration(host: Tree, userLog: UserLog) { | ||
| const projects = getProjects(host); | ||
|
|
||
| projects.forEach((project, projectName) => { | ||
| runMigrationOnProject(host, projectName, userLog); | ||
| }); | ||
| } | ||
|
|
||
| /** | ||
| * @returns whether the packageName is internally in the monorepo | ||
| */ | ||
| function isPackageInMonorepo(packageName: string, host: Tree) { | ||
| let config: ReturnType<typeof getProjectConfig>; | ||
| try { | ||
| config = getProjectConfig(host, { packageName }); | ||
| } catch (err) { | ||
| if (!(err as Error).message.startsWith('Cannot find configuration for')) { | ||
| throw err; | ||
| } | ||
|
|
||
| return false; | ||
| } | ||
|
|
||
| return true; | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,8 @@ | ||
| { | ||
| "$schema": "http://json-schema.org/schema", | ||
| "cli": "nx", | ||
| "id": "star-dev-deps", | ||
| "type": "object", | ||
| "properties": {}, | ||
| "required": [] | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| export interface StarDevDepsGeneratorSchema {} |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.