From 81f2b5ec7d1407e6e54113f921aefd40f1b2b013 Mon Sep 17 00:00:00 2001 From: jaybell Date: Thu, 23 Nov 2023 09:03:17 -0800 Subject: [PATCH 1/6] feat(nx): add the ability to filter truly affected by target(s) --- libs/core/src/types.ts | 1 + libs/nx/src/cli.spec.ts | 48 +++++++++++++++++++++++++++++++++++++++-- libs/nx/src/cli.ts | 20 ++++++++++++++++- libs/nx/src/nx.ts | 1 + tsconfig.base.json | 2 +- 5 files changed, 68 insertions(+), 4 deletions(-) diff --git a/libs/core/src/types.ts b/libs/core/src/types.ts index f88cdb4..76daa8e 100644 --- a/libs/core/src/types.ts +++ b/libs/core/src/types.ts @@ -3,6 +3,7 @@ export interface TrueAffectedProject { sourceRoot: string; tsConfig?: string; implicitDependencies?: string[]; + targets: string[]; } export interface TrueAffected { diff --git a/libs/nx/src/cli.spec.ts b/libs/nx/src/cli.spec.ts index 1db5aa5..5c41092 100644 --- a/libs/nx/src/cli.spec.ts +++ b/libs/nx/src/cli.spec.ts @@ -125,6 +125,7 @@ describe('cli', () => { json: false, restArgs: [], tsConfigFilePath: 'tsconfig.base.json', + target: [], }); expect(getNxTrueAffectedProjectsSpy).toBeCalledWith(process.cwd()); @@ -150,6 +151,7 @@ describe('cli', () => { json: false, restArgs: [], tsConfigFilePath: 'tsconfig.base.json', + target: [], }); expect(logSpy).toHaveBeenCalledWith('No affected projects'); @@ -167,6 +169,7 @@ describe('cli', () => { json: false, restArgs: [], tsConfigFilePath: 'tsconfig.base.json', + target: [], }); expect(logSpy).toHaveBeenCalledWith('Affected projects:\n - proj1'); @@ -186,6 +189,7 @@ describe('cli', () => { json: true, restArgs: [], tsConfigFilePath: 'tsconfig.base.json', + target: [], }); expect(consoleSpy).toHaveBeenCalledWith('["proj1"]'); @@ -206,6 +210,7 @@ describe('cli', () => { json: false, restArgs: [], tsConfigFilePath: 'tsconfig.base.json', + target: [], }); const expectedCommand = `npx nx run-many --target=build --projects=proj1 `; @@ -219,13 +224,50 @@ describe('cli', () => { ); }); + describe('`target` option', () => { + beforeEach(() => { + trafSpy.mockResolvedValueOnce(['proj1']); + + getNxTrueAffectedProjectsSpy.mockResolvedValueOnce([ + { + name: 'proj1', + sourceRoot: 'mock', + tsConfig: 'mock', + targets: ['build'], + }, + { + name: 'proj2', + sourceRoot: 'mock', + tsConfig: 'mock', + targets: ['test'], + }, + ]); + }); + + it('should only return projects with a build target', async () => { + await cli.affectedAction({ + action: 'log', + all: false, + base: 'origin/main', + cwd: process.cwd(), + includeFiles: [], + json: false, + restArgs: [], + tsConfigFilePath: 'tsconfig.base.json', + target: ['build'], + }); + + expect(logSpy).toHaveBeenCalledWith('Affected projects:\n - proj1'); + }); + }); + describe('`all` option', () => { beforeEach(() => { trafSpy.mockResolvedValueOnce(['proj1']); getNxTrueAffectedProjectsSpy.mockResolvedValueOnce([ - { name: 'proj1', sourceRoot: 'mock', tsConfig: 'mock' }, - { name: 'proj2', sourceRoot: 'mock', tsConfig: 'mock' }, + { name: 'proj1', sourceRoot: 'mock', tsConfig: 'mock', targets: [] }, + { name: 'proj2', sourceRoot: 'mock', tsConfig: 'mock', targets: [] }, ]); }); @@ -239,6 +281,7 @@ describe('cli', () => { json: false, restArgs: [], tsConfigFilePath: 'tsconfig.base.json', + target: [], }); expect(logSpy).toHaveBeenCalledWith('Affected projects:\n - proj1'); @@ -254,6 +297,7 @@ describe('cli', () => { json: false, restArgs: [], tsConfigFilePath: 'tsconfig.base.json', + target: [], }); expect(logSpy).toHaveBeenCalledWith( diff --git a/libs/nx/src/cli.ts b/libs/nx/src/cli.ts index c394213..08f34a8 100644 --- a/libs/nx/src/cli.ts +++ b/libs/nx/src/cli.ts @@ -23,8 +23,15 @@ export const affectedAction = async ({ restArgs, tsConfigFilePath, includeFiles, + target, }: AffectedOptions) => { - const projects = await getNxTrueAffectedProjects(cwd); + let projects = await getNxTrueAffectedProjects(cwd); + + if (target.length) { + projects = projects.filter((project) => + project.targets.some((projectTarget) => target.includes(projectTarget)) + ); + } const affected = all ? projects.map((p) => p.name) @@ -80,6 +87,7 @@ interface AffectedOptions { json: boolean; includeFiles: string[]; restArgs: string[]; + target: string[]; } const affectedCommand: CommandModule = { @@ -119,6 +127,14 @@ const affectedCommand: CommandModule = { return array.flatMap((v) => v.split(',')); }, }, + target: { + desc: 'Comma separate list of targets to filter affected projects by', + type: 'array', + coerce: (array: string[]) => { + return array.flatMap((v) => v.split(',')).map((v) => v.trim()); + }, + alias: ['t', 'targets'], + }, }, handler: async ({ cwd, @@ -128,6 +144,7 @@ const affectedCommand: CommandModule = { base, json, includeFiles, + target, // eslint-disable-next-line @typescript-eslint/no-unused-vars $0, // eslint-disable-next-line @typescript-eslint/no-unused-vars @@ -142,6 +159,7 @@ const affectedCommand: CommandModule = { base, json, includeFiles, + target, restArgs: Object.entries(rest).map( /* istanbul ignore next */ ([key, value]) => `--${key}=${value}` diff --git a/libs/nx/src/nx.ts b/libs/nx/src/nx.ts index 6cffad3..94095b7 100644 --- a/libs/nx/src/nx.ts +++ b/libs/nx/src/nx.ts @@ -124,6 +124,7 @@ export async function getNxTrueAffectedProjects( sourceRoot: project.sourceRoot, implicitDependencies: project.implicitDependencies ?? [], tsConfig, + targets: Object.keys(project.targets ?? {}), }; }); } diff --git a/tsconfig.base.json b/tsconfig.base.json index 023f0f4..7b786af 100644 --- a/tsconfig.base.json +++ b/tsconfig.base.json @@ -17,7 +17,7 @@ "paths": { "@traf/core": ["libs/core/src/index.ts"], "@traf/nx": ["libs/nx/src/cli.ts"], - "@traf/turbo": ["libs/turbo/src/cli.ts"], + "@traf/turbo": ["libs/turbo/src/cli.ts"] } }, "exclude": ["node_modules", "tmp"] From 63f71bd360729875675175e0cd9db8ae61f8679f Mon Sep 17 00:00:00 2001 From: jaybell Date: Thu, 23 Nov 2023 09:04:44 -0800 Subject: [PATCH 2/6] chore(nx): remove aliases --- libs/nx/src/cli.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/libs/nx/src/cli.ts b/libs/nx/src/cli.ts index 08f34a8..ac4011d 100644 --- a/libs/nx/src/cli.ts +++ b/libs/nx/src/cli.ts @@ -133,7 +133,6 @@ const affectedCommand: CommandModule = { coerce: (array: string[]) => { return array.flatMap((v) => v.split(',')).map((v) => v.trim()); }, - alias: ['t', 'targets'], }, }, handler: async ({ From a4fa2c25191802cbbeda6681fcfe28f67bdcdc05 Mon Sep 17 00:00:00 2001 From: jaybell Date: Thu, 23 Nov 2023 09:10:03 -0800 Subject: [PATCH 3/6] fix(turbo): make targets optional so we do not need to return them yet --- libs/core/src/types.ts | 2 +- libs/nx/src/cli.ts | 7 +++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/libs/core/src/types.ts b/libs/core/src/types.ts index 76daa8e..fd9c938 100644 --- a/libs/core/src/types.ts +++ b/libs/core/src/types.ts @@ -3,7 +3,7 @@ export interface TrueAffectedProject { sourceRoot: string; tsConfig?: string; implicitDependencies?: string[]; - targets: string[]; + targets?: string[]; } export interface TrueAffected { diff --git a/libs/nx/src/cli.ts b/libs/nx/src/cli.ts index ac4011d..4df7d16 100644 --- a/libs/nx/src/cli.ts +++ b/libs/nx/src/cli.ts @@ -28,8 +28,11 @@ export const affectedAction = async ({ let projects = await getNxTrueAffectedProjects(cwd); if (target.length) { - projects = projects.filter((project) => - project.targets.some((projectTarget) => target.includes(projectTarget)) + projects = projects.filter( + (project) => + !!project.targets?.some((projectTarget) => + target.includes(projectTarget) + ) ); } From 221b1863b42cfe152540b4c4355aff93a40d9866 Mon Sep 17 00:00:00 2001 From: jaybell Date: Thu, 23 Nov 2023 09:23:39 -0800 Subject: [PATCH 4/6] fix(nx): add a default empty array for --target --- libs/nx/src/cli.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/libs/nx/src/cli.ts b/libs/nx/src/cli.ts index 4df7d16..039ce9e 100644 --- a/libs/nx/src/cli.ts +++ b/libs/nx/src/cli.ts @@ -133,6 +133,7 @@ const affectedCommand: CommandModule = { target: { desc: 'Comma separate list of targets to filter affected projects by', type: 'array', + default: [], coerce: (array: string[]) => { return array.flatMap((v) => v.split(',')).map((v) => v.trim()); }, From 3ca20177eba6380092a4ef8f0ca58922769f2669 Mon Sep 17 00:00:00 2001 From: jaybell Date: Thu, 23 Nov 2023 09:41:50 -0800 Subject: [PATCH 5/6] test:(nx): add target empty array to tests --- libs/nx/src/cli.spec.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libs/nx/src/cli.spec.ts b/libs/nx/src/cli.spec.ts index 5c41092..4ecba20 100644 --- a/libs/nx/src/cli.spec.ts +++ b/libs/nx/src/cli.spec.ts @@ -71,6 +71,7 @@ describe('cli', () => { json: false, restArgs: [], tsConfigFilePath: 'tsconfig.base.json', + target: [], }); }); @@ -93,6 +94,7 @@ describe('cli', () => { json: false, restArgs: [], tsConfigFilePath: 'tsconfig.json', + target: [], }); }); }); From 239304222eb11ddd96ce1c4364f9df4b9befb710 Mon Sep 17 00:00:00 2001 From: jaybell Date: Thu, 23 Nov 2023 10:00:22 -0800 Subject: [PATCH 6/6] docs(nx): update Nx docs to show target option --- libs/nx/README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libs/nx/README.md b/libs/nx/README.md index 67515db..47726b6 100644 --- a/libs/nx/README.md +++ b/libs/nx/README.md @@ -17,7 +17,7 @@ npx @traf/nx@latest affected [options] ### **Options** | Option | Description | Default | -| -------------------- | ------------------------------------------------------------------------------------ | -------------------- | +|----------------------|--------------------------------------------------------------------------------------| -------------------- | | `--cwd` | The current working directory | `process.cwd()` | | `--all` | Outputs all available projects regardless of changes | `false` | | `--base` | The base branch to compare against | `origin/main` | @@ -25,3 +25,4 @@ npx @traf/nx@latest affected [options] | `--action` | The action to perform. Can be any command | `log` | | `--json` | Output the result as JSON | `false` | | `--includeFiles` | Comma separated list of glob patterns to include (relative to projects' source root) | | +| `--target` | Comma separated list of targets to filter affected projects by | |