From 0d6ac670b9e893ecd296c44e7d4d276e53014091 Mon Sep 17 00:00:00 2001 From: Florian Guitton Date: Fri, 31 Mar 2023 00:36:33 +0100 Subject: [PATCH 1/3] feat(core): add support for tags selection in affected and run-many commands --- docs/generated/cli/run-many.md | 8 +- .../angular/generators/application.json | 4 +- .../packages/angular/generators/host.json | 2 +- .../packages/angular/generators/library.json | 5 +- .../packages/angular/generators/remote.json | 2 +- .../packages/expo/generators/application.json | 2 +- .../packages/expo/generators/library.json | 2 +- .../express/generators/application.json | 2 +- .../packages/js/generators/library.json | 5 +- .../packages/nest/generators/application.json | 2 +- .../packages/nest/generators/library.json | 2 +- .../packages/next/generators/application.json | 2 +- .../packages/next/generators/library.json | 2 +- .../packages/node/generators/application.json | 2 +- .../packages/node/generators/library.json | 2 +- .../packages/nx-plugin/generators/plugin.json | 2 +- .../packages/nx/documents/run-many.md | 8 +- .../react-native/generators/application.json | 2 +- .../react-native/generators/library.json | 2 +- .../react/generators/application.json | 4 +- .../packages/react/generators/host.json | 2 +- .../packages/react/generators/library.json | 2 +- .../packages/react/generators/remote.json | 2 +- .../packages/web/generators/application.json | 4 +- .../workspace/generators/library.json | 5 +- .../recipes/generators/generator-options.md | 2 +- e2e/nx-run/src/affected-graph.test.ts | 12 +- e2e/nx-run/src/run.test.ts | 42 +++++- packages/angular/docs/application-examples.md | 2 +- .../src/generators/application/schema.json | 2 +- .../angular/src/generators/host/schema.json | 2 +- .../src/generators/library/schema.json | 2 +- .../angular/src/generators/remote/schema.json | 2 +- .../src/generators/application/schema.json | 2 +- .../expo/src/generators/library/schema.json | 2 +- .../src/generators/application/schema.json | 2 +- .../js/src/generators/library/schema.json | 2 +- .../src/generators/application/schema.json | 2 +- .../nest/src/generators/library/schema.json | 2 +- .../src/generators/application/schema.json | 2 +- .../next/src/generators/library/schema.json | 2 +- .../src/generators/application/schema.json | 2 +- .../node/src/generators/library/schema.json | 2 +- .../__fileName__/schema.json__tmpl__ | 2 +- .../src/generators/plugin/schema.json | 2 +- packages/nx/src/command-line/affected.ts | 8 +- packages/nx/src/command-line/examples.ts | 7 +- packages/nx/src/command-line/nx-commands.ts | 1 - packages/nx/src/command-line/run-many.spec.ts | 74 ++++++++++ packages/nx/src/command-line/run-many.ts | 9 +- .../build-nodes/workspace-projects.spec.ts | 88 ++++++++---- .../build-nodes/workspace-projects.ts | 30 ++-- .../nx/src/utils/assert-workspace-validity.ts | 26 ++-- packages/nx/src/utils/command-line-utils.ts | 4 + .../src/utils/find-matching-projects.spec.ts | 128 ++++++++++++++++-- .../nx/src/utils/find-matching-projects.ts | 92 ++++++++++--- .../src/generators/application/schema.json | 2 +- .../src/generators/library/schema.json | 2 +- packages/react/docs/application-examples.md | 2 +- .../src/generators/application/schema.json | 2 +- .../react/src/generators/host/schema.json | 2 +- .../react/src/generators/library/schema.json | 2 +- .../react/src/generators/remote/schema.json | 2 +- packages/web/docs/application-examples.md | 2 +- .../src/generators/application/schema.json | 2 +- .../src/generators/library/schema.json | 2 +- 66 files changed, 495 insertions(+), 159 deletions(-) diff --git a/docs/generated/cli/run-many.md b/docs/generated/cli/run-many.md index 623e65370a8d9..b9e5a21bf53e8 100644 --- a/docs/generated/cli/run-many.md +++ b/docs/generated/cli/run-many.md @@ -44,7 +44,13 @@ Test proj1 and proj2 in sequence: Test all projects ending with `*-app` except `excluded-app`. Note: your shell may require you to escape the `*` like this: `\*`: ```shell - nx run-many --target=test --projects=*-app --exclude excluded-app + nx run-many --target=test --projects=*-app --exclude=excluded-app +``` + +Test all projects with tags starting with `api-*`. Note: your shell may require you to escape the `*` like this: `\*`: + +```shell + nx run-many --target=test --projects=tag:api-* ``` Run lint, test, and build targets for all projects. Requires Nx v15.4+: diff --git a/docs/generated/packages/angular/generators/application.json b/docs/generated/packages/angular/generators/application.json index 549762f8b30d0..1ad2ebc015d2d 100644 --- a/docs/generated/packages/angular/generators/application.json +++ b/docs/generated/packages/angular/generators/application.json @@ -108,7 +108,7 @@ }, "tags": { "type": "string", - "description": "Add tags to the application (used for linting)." + "description": "Add tags to the application." }, "linter": { "description": "The tool to use for running lint checks.", @@ -165,7 +165,7 @@ }, "additionalProperties": false, "required": ["name"], - "examplesFile": "## Examples\n\n{% tabs %}\n{% tab label=\"Simple Application\" %}\n\nCreate an application named `my-app`:\n\n```bash\nnx g @nrwl/angular:application my-app\n```\n\n{% /tab %}\n\n{% tab label=\"Specify directory and style extension\" %}\n\nCreate an application named `my-app` in the `my-dir` directory and use `scss` for styles:\n\n```bash\nnx g @nrwl/angular:app my-app --directory=my-dir --style=scss\n```\n\n{% /tab %}\n\n{% tab label=\"Single File Components application\" %}\n\nCreate an application with Single File Components (inline styles and inline templates):\n\n```bash\nnx g @nrwl/angular:app my-app --inlineStyle --inlineTemplate\n```\n\n{% /tab %}\n\n{% tab label=\"Standalone Components application\" %}\n\nCreate an application that is setup to use standalone components:\n\n```bash\nnx g @nrwl/angular:app my-app --standalone\n```\n\n{% /tab %}\n\n{% tab label=\"Set custom prefix and tags\" %}\n\nSet the prefix to apply to generated selectors and add tags to the application (used for linting).\n\n```bash\nnx g @nrwl/angular:app my-app --prefix=admin --tags=scope:admin,type:ui\n```\n\n{% /tab %}\n{% /tabs %}\n", + "examplesFile": "## Examples\n\n{% tabs %}\n{% tab label=\"Simple Application\" %}\n\nCreate an application named `my-app`:\n\n```bash\nnx g @nrwl/angular:application my-app\n```\n\n{% /tab %}\n\n{% tab label=\"Specify directory and style extension\" %}\n\nCreate an application named `my-app` in the `my-dir` directory and use `scss` for styles:\n\n```bash\nnx g @nrwl/angular:app my-app --directory=my-dir --style=scss\n```\n\n{% /tab %}\n\n{% tab label=\"Single File Components application\" %}\n\nCreate an application with Single File Components (inline styles and inline templates):\n\n```bash\nnx g @nrwl/angular:app my-app --inlineStyle --inlineTemplate\n```\n\n{% /tab %}\n\n{% tab label=\"Standalone Components application\" %}\n\nCreate an application that is setup to use standalone components:\n\n```bash\nnx g @nrwl/angular:app my-app --standalone\n```\n\n{% /tab %}\n\n{% tab label=\"Set custom prefix and tags\" %}\n\nSet the prefix to apply to generated selectors and add tags to the application.\n\n```bash\nnx g @nrwl/angular:app my-app --prefix=admin --tags=scope:admin,type:ui\n```\n\n{% /tab %}\n{% /tabs %}\n", "presets": [] }, "aliases": ["app"], diff --git a/docs/generated/packages/angular/generators/host.json b/docs/generated/packages/angular/generators/host.json index 856524fd58520..fea78bec5d4cc 100644 --- a/docs/generated/packages/angular/generators/host.json +++ b/docs/generated/packages/angular/generators/host.json @@ -115,7 +115,7 @@ }, "tags": { "type": "string", - "description": "Add tags to the application (used for linting)." + "description": "Add tags to the application." }, "linter": { "description": "The tool to use for running lint checks.", diff --git a/docs/generated/packages/angular/generators/library.json b/docs/generated/packages/angular/generators/library.json index adde6fab5bb11..9fe90f1405177 100644 --- a/docs/generated/packages/angular/generators/library.json +++ b/docs/generated/packages/angular/generators/library.json @@ -89,10 +89,7 @@ "description": "Path to the parent route configuration using `loadChildren` or `children`, depending on what `lazy` is set to.", "x-priority": "important" }, - "tags": { - "type": "string", - "description": "Add tags to the library (used for linting)." - }, + "tags": { "type": "string", "description": "Add tags to the library." }, "unitTestRunner": { "type": "string", "enum": ["jest", "none"], diff --git a/docs/generated/packages/angular/generators/remote.json b/docs/generated/packages/angular/generators/remote.json index 793a89111aa0d..938a3bdd0065f 100644 --- a/docs/generated/packages/angular/generators/remote.json +++ b/docs/generated/packages/angular/generators/remote.json @@ -109,7 +109,7 @@ }, "tags": { "type": "string", - "description": "Add tags to the application (used for linting)." + "description": "Add tags to the application." }, "linter": { "description": "The tool to use for running lint checks.", diff --git a/docs/generated/packages/expo/generators/application.json b/docs/generated/packages/expo/generators/application.json index 94ae26f44b2c8..6feee1d1bbfd5 100644 --- a/docs/generated/packages/expo/generators/application.json +++ b/docs/generated/packages/expo/generators/application.json @@ -53,7 +53,7 @@ }, "tags": { "type": "string", - "description": "Add tags to the application (used for linting)", + "description": "Add tags to the application", "alias": "t" }, "js": { diff --git a/docs/generated/packages/expo/generators/library.json b/docs/generated/packages/expo/generators/library.json index b3976b6ae037b..0110484fdaa35 100644 --- a/docs/generated/packages/expo/generators/library.json +++ b/docs/generated/packages/expo/generators/library.json @@ -40,7 +40,7 @@ }, "tags": { "type": "string", - "description": "Add tags to the library (used for linting).", + "description": "Add tags to the library.", "alias": "t" }, "skipFormat": { diff --git a/docs/generated/packages/express/generators/application.json b/docs/generated/packages/express/generators/application.json index 10336208f37f7..9df851b3fc3c9 100644 --- a/docs/generated/packages/express/generators/application.json +++ b/docs/generated/packages/express/generators/application.json @@ -44,7 +44,7 @@ }, "tags": { "type": "string", - "description": "Add tags to the application (used for linting)." + "description": "Add tags to the application." }, "frontendProject": { "type": "string", diff --git a/docs/generated/packages/js/generators/library.json b/docs/generated/packages/js/generators/library.json index 78223d2c7aaa2..65098f4d9d4a3 100644 --- a/docs/generated/packages/js/generators/library.json +++ b/docs/generated/packages/js/generators/library.json @@ -33,10 +33,7 @@ "description": "Test runner to use for unit tests.", "x-prompt": "Which unit test runner would you like to use?" }, - "tags": { - "type": "string", - "description": "Add tags to the library (used for linting)." - }, + "tags": { "type": "string", "description": "Add tags to the library." }, "skipFormat": { "description": "Skip formatting files.", "type": "boolean", diff --git a/docs/generated/packages/nest/generators/application.json b/docs/generated/packages/nest/generators/application.json index 6350158831da0..16f4ca48bda72 100644 --- a/docs/generated/packages/nest/generators/application.json +++ b/docs/generated/packages/nest/generators/application.json @@ -50,7 +50,7 @@ "default": "jest" }, "tags": { - "description": "Add tags to the application (used for linting).", + "description": "Add tags to the application.", "type": "string" }, "frontendProject": { diff --git a/docs/generated/packages/nest/generators/library.json b/docs/generated/packages/nest/generators/library.json index 2fe5b804d4fa7..21d0b742fdcf7 100644 --- a/docs/generated/packages/nest/generators/library.json +++ b/docs/generated/packages/nest/generators/library.json @@ -39,7 +39,7 @@ "default": "jest" }, "tags": { - "description": "Add tags to the library (used for linting).", + "description": "Add tags to the library.", "type": "string", "alias": "t" }, diff --git a/docs/generated/packages/next/generators/application.json b/docs/generated/packages/next/generators/application.json index 5ad1db11b4e52..6f5ac0fd401bc 100644 --- a/docs/generated/packages/next/generators/application.json +++ b/docs/generated/packages/next/generators/application.json @@ -90,7 +90,7 @@ }, "tags": { "type": "string", - "description": "Add tags to the application (used for linting).", + "description": "Add tags to the application.", "alias": "t" }, "js": { diff --git a/docs/generated/packages/next/generators/library.json b/docs/generated/packages/next/generators/library.json index f06dff5a6173c..70665455c6298 100644 --- a/docs/generated/packages/next/generators/library.json +++ b/docs/generated/packages/next/generators/library.json @@ -75,7 +75,7 @@ }, "tags": { "type": "string", - "description": "Add tags to the library (used for linting).", + "description": "Add tags to the library.", "alias": "t" }, "skipFormat": { diff --git a/docs/generated/packages/node/generators/application.json b/docs/generated/packages/node/generators/application.json index a2bbe09416a60..7bac364144beb 100644 --- a/docs/generated/packages/node/generators/application.json +++ b/docs/generated/packages/node/generators/application.json @@ -47,7 +47,7 @@ }, "tags": { "type": "string", - "description": "Add tags to the application (used for linting)." + "description": "Add tags to the application." }, "frontendProject": { "type": "string", diff --git a/docs/generated/packages/node/generators/library.json b/docs/generated/packages/node/generators/library.json index 47c5f4a86eab8..1fb4a0a0645d6 100644 --- a/docs/generated/packages/node/generators/library.json +++ b/docs/generated/packages/node/generators/library.json @@ -45,7 +45,7 @@ }, "tags": { "type": "string", - "description": "Add tags to the library (used for linting).", + "description": "Add tags to the library.", "alias": "t" }, "skipFormat": { diff --git a/docs/generated/packages/nx-plugin/generators/plugin.json b/docs/generated/packages/nx-plugin/generators/plugin.json index e6df079e46662..aeca396c68232 100644 --- a/docs/generated/packages/nx-plugin/generators/plugin.json +++ b/docs/generated/packages/nx-plugin/generators/plugin.json @@ -45,7 +45,7 @@ }, "tags": { "type": "string", - "description": "Add tags to the library (used for linting).", + "description": "Add tags to the library.", "alias": "t" }, "skipFormat": { diff --git a/docs/generated/packages/nx/documents/run-many.md b/docs/generated/packages/nx/documents/run-many.md index 623e65370a8d9..b9e5a21bf53e8 100644 --- a/docs/generated/packages/nx/documents/run-many.md +++ b/docs/generated/packages/nx/documents/run-many.md @@ -44,7 +44,13 @@ Test proj1 and proj2 in sequence: Test all projects ending with `*-app` except `excluded-app`. Note: your shell may require you to escape the `*` like this: `\*`: ```shell - nx run-many --target=test --projects=*-app --exclude excluded-app + nx run-many --target=test --projects=*-app --exclude=excluded-app +``` + +Test all projects with tags starting with `api-*`. Note: your shell may require you to escape the `*` like this: `\*`: + +```shell + nx run-many --target=test --projects=tag:api-* ``` Run lint, test, and build targets for all projects. Requires Nx v15.4+: diff --git a/docs/generated/packages/react-native/generators/application.json b/docs/generated/packages/react-native/generators/application.json index 318198dc3ca72..4c874aabe76eb 100644 --- a/docs/generated/packages/react-native/generators/application.json +++ b/docs/generated/packages/react-native/generators/application.json @@ -53,7 +53,7 @@ }, "tags": { "type": "string", - "description": "Add tags to the application (used for linting).", + "description": "Add tags to the application.", "alias": "t" }, "js": { diff --git a/docs/generated/packages/react-native/generators/library.json b/docs/generated/packages/react-native/generators/library.json index 906eb413a0a93..48462d25f9919 100644 --- a/docs/generated/packages/react-native/generators/library.json +++ b/docs/generated/packages/react-native/generators/library.json @@ -42,7 +42,7 @@ }, "tags": { "type": "string", - "description": "Add tags to the library (used for linting).", + "description": "Add tags to the library.", "alias": "t" }, "skipFormat": { diff --git a/docs/generated/packages/react/generators/application.json b/docs/generated/packages/react/generators/application.json index c9813e4946715..32ef2b620837d 100644 --- a/docs/generated/packages/react/generators/application.json +++ b/docs/generated/packages/react/generators/application.json @@ -118,7 +118,7 @@ }, "tags": { "type": "string", - "description": "Add tags to the application (used for linting).", + "description": "Add tags to the application.", "alias": "t" }, "pascalCaseFiles": { @@ -192,7 +192,7 @@ } }, "required": [], - "examplesFile": "## Examples\n\n{% tabs %}\n{% tab label=\"Simple Application\" %}\n\nCreate an application named `my-app`:\n\n```bash\nnx g @nrwl/react:application my-app\n```\n\n{% /tab %}\n\n{% tab label=\"Application using Vite as bundler\" %}\n\nCreate an application named `my-app`:\n\n```bash\nnx g @nrwl/react:app my-app --bundler=vite\n```\n\n{% /tab %}\n\n{% tab label=\"Specify directory and style extension\" %}\n\nCreate an application named `my-app` in the `my-dir` directory and use `scss` for styles:\n\n```bash\nnx g @nrwl/react:app my-app --directory=my-dir --style=scss\n```\n\n{% /tab %}\n\n{% tab label=\"Add tags\" %}\n\nAdd tags to the application (used for linting).\n\n```bash\nnx g @nrwl/react:app my-app --tags=scope:admin,type:ui\n```\n\n{% /tab %}\n{% /tabs %}\n", + "examplesFile": "## Examples\n\n{% tabs %}\n{% tab label=\"Simple Application\" %}\n\nCreate an application named `my-app`:\n\n```bash\nnx g @nrwl/react:application my-app\n```\n\n{% /tab %}\n\n{% tab label=\"Application using Vite as bundler\" %}\n\nCreate an application named `my-app`:\n\n```bash\nnx g @nrwl/react:app my-app --bundler=vite\n```\n\n{% /tab %}\n\n{% tab label=\"Specify directory and style extension\" %}\n\nCreate an application named `my-app` in the `my-dir` directory and use `scss` for styles:\n\n```bash\nnx g @nrwl/react:app my-app --directory=my-dir --style=scss\n```\n\n{% /tab %}\n\n{% tab label=\"Add tags\" %}\n\nAdd tags to the application.\n\n```bash\nnx g @nrwl/react:app my-app --tags=scope:admin,type:ui\n```\n\n{% /tab %}\n{% /tabs %}\n", "presets": [] }, "aliases": ["app"], diff --git a/docs/generated/packages/react/generators/host.json b/docs/generated/packages/react/generators/host.json index 802c15f41a8a7..d6f0ccbca9a65 100644 --- a/docs/generated/packages/react/generators/host.json +++ b/docs/generated/packages/react/generators/host.json @@ -93,7 +93,7 @@ }, "tags": { "type": "string", - "description": "Add tags to the application (used for linting).", + "description": "Add tags to the application.", "alias": "t" }, "pascalCaseFiles": { diff --git a/docs/generated/packages/react/generators/library.json b/docs/generated/packages/react/generators/library.json index 35b01e811a9ca..ad53b9ec60a7e 100644 --- a/docs/generated/packages/react/generators/library.json +++ b/docs/generated/packages/react/generators/library.json @@ -90,7 +90,7 @@ }, "tags": { "type": "string", - "description": "Add tags to the library (used for linting).", + "description": "Add tags to the library.", "alias": "t" }, "skipFormat": { diff --git a/docs/generated/packages/react/generators/remote.json b/docs/generated/packages/react/generators/remote.json index bcc76f7936198..556113f67742a 100644 --- a/docs/generated/packages/react/generators/remote.json +++ b/docs/generated/packages/react/generators/remote.json @@ -98,7 +98,7 @@ }, "tags": { "type": "string", - "description": "Add tags to the application (used for linting).", + "description": "Add tags to the application.", "alias": "t" }, "pascalCaseFiles": { diff --git a/docs/generated/packages/web/generators/application.json b/docs/generated/packages/web/generators/application.json index 5b2bc487bbd4e..da283b31614bc 100644 --- a/docs/generated/packages/web/generators/application.json +++ b/docs/generated/packages/web/generators/application.json @@ -89,7 +89,7 @@ }, "tags": { "type": "string", - "description": "Add tags to the application (used for linting)" + "description": "Add tags to the application" }, "setParserOptionsProject": { "type": "boolean", @@ -104,7 +104,7 @@ } }, "required": ["name"], - "examplesFile": "## Examples\n\n{% tabs %}\n{% tab label=\"Simple Application\" %}\n\nCreate an application named `my-app`:\n\n```bash\nnx g @nrwl/web:application my-app\n```\n\n{% /tab %}\n\n{% tab label=\"Application using Vite as bundler\" %}\n\nCreate an application named `my-app`:\n\n```bash\nnx g @nrwl/web:app my-app --bundler=vite\n```\n\n{% /tab %}\n\n{% tab label=\"Specify directory\" %}\n\nCreate an application named `my-app` in the `my-dir` directory:\n\n```bash\nnx g @nrwl/web:app my-app --directory=my-dir\n```\n\n{% /tab %}\n\n{% tab label=\"Add tags\" %}\n\nAdd tags to the application (used for linting).\n\n```bash\nnx g @nrwl/web:app my-app --tags=scope:admin,type:ui\n```\n\n{% /tab %}\n{% /tabs %}\n", + "examplesFile": "## Examples\n\n{% tabs %}\n{% tab label=\"Simple Application\" %}\n\nCreate an application named `my-app`:\n\n```bash\nnx g @nrwl/web:application my-app\n```\n\n{% /tab %}\n\n{% tab label=\"Application using Vite as bundler\" %}\n\nCreate an application named `my-app`:\n\n```bash\nnx g @nrwl/web:app my-app --bundler=vite\n```\n\n{% /tab %}\n\n{% tab label=\"Specify directory\" %}\n\nCreate an application named `my-app` in the `my-dir` directory:\n\n```bash\nnx g @nrwl/web:app my-app --directory=my-dir\n```\n\n{% /tab %}\n\n{% tab label=\"Add tags\" %}\n\nAdd tags to the application.\n\n```bash\nnx g @nrwl/web:app my-app --tags=scope:admin,type:ui\n```\n\n{% /tab %}\n{% /tabs %}\n", "presets": [] }, "aliases": ["app"], diff --git a/docs/generated/packages/workspace/generators/library.json b/docs/generated/packages/workspace/generators/library.json index abfc5317dab3c..b40c89b26a4e7 100644 --- a/docs/generated/packages/workspace/generators/library.json +++ b/docs/generated/packages/workspace/generators/library.json @@ -39,10 +39,7 @@ "description": "Test runner to use for unit tests.", "default": "jest" }, - "tags": { - "type": "string", - "description": "Add tags to the library (used for linting)." - }, + "tags": { "type": "string", "description": "Add tags to the library." }, "skipFormat": { "description": "Skip formatting files.", "type": "boolean", diff --git a/docs/shared/recipes/generators/generator-options.md b/docs/shared/recipes/generators/generator-options.md index 09d0df483a5c3..29c6ba95a6f9c 100644 --- a/docs/shared/recipes/generators/generator-options.md +++ b/docs/shared/recipes/generators/generator-options.md @@ -533,7 +533,7 @@ The alias of this property. Example: { "tags": { "type": "string", - "description": "Add tags to the project (used for linting)", + "description": "Add tags to the project", "alias": "t" }, "directory": { diff --git a/e2e/nx-run/src/affected-graph.test.ts b/e2e/nx-run/src/affected-graph.test.ts index bb123ad6140a7..a48383d34d2b4 100644 --- a/e2e/nx-run/src/affected-graph.test.ts +++ b/e2e/nx-run/src/affected-graph.test.ts @@ -38,7 +38,7 @@ describe('Nx Affected and Graph Tests', () => { runCLI(`generate @nrwl/js:lib ${mylib}`); runCLI(`generate @nrwl/js:lib ${mylib2}`); runCLI( - `generate @nrwl/js:lib ${mypublishablelib} --publishable --importPath=@${proj}/${mypublishablelib}` + `generate @nrwl/js:lib ${mypublishablelib} --publishable --importPath=@${proj}/${mypublishablelib} --tags=ui` ); updateFile( @@ -135,11 +135,19 @@ describe('Nx Affected and Graph Tests', () => { expect(build).toContain('Successfully ran target build'); const buildExcluded = runCLI( - `affected:build --files="libs/${mylib}/src/index.ts" --exclude ${myapp}` + `affected:build --files="libs/${mylib}/src/index.ts" --exclude=${myapp}` ); expect(buildExcluded).toContain(`Running target build for 2 projects:`); expect(buildExcluded).toContain(`- ${mypublishablelib}`); + const buildExcludedByTag = runCLI( + `affected:build --files="libs/${mylib}/src/index.ts" --exclude=tag:ui` + ); + expect(buildExcludedByTag).toContain( + `Running target build for 2 projects:` + ); + expect(buildExcludedByTag).not.toContain(`- ${mypublishablelib}`); + // test updateFile( `apps/${myapp}/src/app/app.element.spec.ts`, diff --git a/e2e/nx-run/src/run.test.ts b/e2e/nx-run/src/run.test.ts index d069c83c1cd14..ffb46fd4eaca2 100644 --- a/e2e/nx-run/src/run.test.ts +++ b/e2e/nx-run/src/run.test.ts @@ -440,9 +440,13 @@ describe('Nx Running Tests', () => { runCLI(`generate @nrwl/web:app ${appA}`); runCLI(`generate @nrwl/js:lib ${libA} --bundler=tsc --defaults`); - runCLI(`generate @nrwl/js:lib ${libB} --bundler=tsc --defaults`); - runCLI(`generate @nrwl/js:lib ${libC} --bundler=tsc --defaults`); - runCLI(`generate @nrwl/node:lib ${libD} --defaults`); + runCLI( + `generate @nrwl/js:lib ${libB} --bundler=tsc --defaults --tags=ui-a` + ); + runCLI( + `generate @nrwl/js:lib ${libC} --bundler=tsc --defaults --tags=ui-b,shared` + ); + runCLI(`generate @nrwl/node:lib ${libD} --defaults --tags=api`); // libA depends on libC updateFile( @@ -462,6 +466,7 @@ describe('Nx Running Tests', () => { `run-many --target=build --projects="${libC},${libB}"` ); expect(buildParallel).toContain(`Running target build for 2 projects:`); + expect(buildParallel).not.toContain(`- ${appA}`); expect(buildParallel).not.toContain(`- ${libA}`); expect(buildParallel).toContain(`- ${libB}`); expect(buildParallel).toContain(`- ${libC}`); @@ -480,6 +485,36 @@ describe('Nx Running Tests', () => { expect(buildAllParallel).not.toContain(`- ${libD}`); expect(buildAllParallel).toContain('Successfully ran target build'); + // testing run many by tags + const buildByTagParallel = runCLI( + `run-many --target=build --projects="tag:ui*"` + ); + expect(buildByTagParallel).toContain( + `Running target build for 2 projects:` + ); + expect(buildByTagParallel).not.toContain(`- ${appA}`); + expect(buildByTagParallel).not.toContain(`- ${libA}`); + expect(buildByTagParallel).toContain(`- ${libB}`); + expect(buildByTagParallel).toContain(`- ${libC}`); + expect(buildByTagParallel).not.toContain(`- ${libD}`); + expect(buildByTagParallel).toContain('Successfully ran target build'); + + // testing run many with exclude + const buildWithExcludeParallel = runCLI( + `run-many --target=build --exclude="${libD},tag:ui*"` + ); + expect(buildWithExcludeParallel).toContain( + `Running target build for 2 projects and 1 task they depend on:` + ); + expect(buildWithExcludeParallel).toContain(`- ${appA}`); + expect(buildWithExcludeParallel).toContain(`- ${libA}`); + expect(buildWithExcludeParallel).not.toContain(`- ${libB}`); + expect(buildWithExcludeParallel).toContain(`${libC}`); // should still include libC as dependency despite exclude + expect(buildWithExcludeParallel).not.toContain(`- ${libD}`); + expect(buildWithExcludeParallel).toContain( + 'Successfully ran target build' + ); + // testing run many when project depends on other projects const buildWithDeps = runCLI( `run-many --target=build --projects="${libA}"` @@ -487,6 +522,7 @@ describe('Nx Running Tests', () => { expect(buildWithDeps).toContain( `Running target build for project ${libA} and 1 task it depends on:` ); + expect(buildWithDeps).not.toContain(`- ${appA}`); expect(buildWithDeps).toContain(`- ${libA}`); expect(buildWithDeps).toContain(`${libC}`); // build should include libC as dependency expect(buildWithDeps).not.toContain(`- ${libB}`); diff --git a/packages/angular/docs/application-examples.md b/packages/angular/docs/application-examples.md index 3ff5015e2524c..986f330135c1e 100644 --- a/packages/angular/docs/application-examples.md +++ b/packages/angular/docs/application-examples.md @@ -43,7 +43,7 @@ nx g @nrwl/angular:app my-app --standalone {% tab label="Set custom prefix and tags" %} -Set the prefix to apply to generated selectors and add tags to the application (used for linting). +Set the prefix to apply to generated selectors and add tags to the application. ```bash nx g @nrwl/angular:app my-app --prefix=admin --tags=scope:admin,type:ui diff --git a/packages/angular/src/generators/application/schema.json b/packages/angular/src/generators/application/schema.json index 223eac46a397f..6bbe5805e2d7a 100644 --- a/packages/angular/src/generators/application/schema.json +++ b/packages/angular/src/generators/application/schema.json @@ -111,7 +111,7 @@ }, "tags": { "type": "string", - "description": "Add tags to the application (used for linting)." + "description": "Add tags to the application." }, "linter": { "description": "The tool to use for running lint checks.", diff --git a/packages/angular/src/generators/host/schema.json b/packages/angular/src/generators/host/schema.json index f24b551c3cf50..eed0dc327c43d 100644 --- a/packages/angular/src/generators/host/schema.json +++ b/packages/angular/src/generators/host/schema.json @@ -118,7 +118,7 @@ }, "tags": { "type": "string", - "description": "Add tags to the application (used for linting)." + "description": "Add tags to the application." }, "linter": { "description": "The tool to use for running lint checks.", diff --git a/packages/angular/src/generators/library/schema.json b/packages/angular/src/generators/library/schema.json index 8463a226f44dd..ec4061b7d0b87 100644 --- a/packages/angular/src/generators/library/schema.json +++ b/packages/angular/src/generators/library/schema.json @@ -91,7 +91,7 @@ }, "tags": { "type": "string", - "description": "Add tags to the library (used for linting)." + "description": "Add tags to the library." }, "unitTestRunner": { "type": "string", diff --git a/packages/angular/src/generators/remote/schema.json b/packages/angular/src/generators/remote/schema.json index 22601e3b5fec8..0bf5aca3bc763 100644 --- a/packages/angular/src/generators/remote/schema.json +++ b/packages/angular/src/generators/remote/schema.json @@ -112,7 +112,7 @@ }, "tags": { "type": "string", - "description": "Add tags to the application (used for linting)." + "description": "Add tags to the application." }, "linter": { "description": "The tool to use for running lint checks.", diff --git a/packages/expo/src/generators/application/schema.json b/packages/expo/src/generators/application/schema.json index c507bcc6afa17..d277dbd4c1017 100644 --- a/packages/expo/src/generators/application/schema.json +++ b/packages/expo/src/generators/application/schema.json @@ -53,7 +53,7 @@ }, "tags": { "type": "string", - "description": "Add tags to the application (used for linting)", + "description": "Add tags to the application", "alias": "t" }, "js": { diff --git a/packages/expo/src/generators/library/schema.json b/packages/expo/src/generators/library/schema.json index 0961290da0706..9a4a172731246 100644 --- a/packages/expo/src/generators/library/schema.json +++ b/packages/expo/src/generators/library/schema.json @@ -40,7 +40,7 @@ }, "tags": { "type": "string", - "description": "Add tags to the library (used for linting).", + "description": "Add tags to the library.", "alias": "t" }, "skipFormat": { diff --git a/packages/express/src/generators/application/schema.json b/packages/express/src/generators/application/schema.json index db3c743ce5f18..41af3129db5b7 100644 --- a/packages/express/src/generators/application/schema.json +++ b/packages/express/src/generators/application/schema.json @@ -44,7 +44,7 @@ }, "tags": { "type": "string", - "description": "Add tags to the application (used for linting)." + "description": "Add tags to the application." }, "frontendProject": { "type": "string", diff --git a/packages/js/src/generators/library/schema.json b/packages/js/src/generators/library/schema.json index b0f26af936477..ef26ad601ff9a 100644 --- a/packages/js/src/generators/library/schema.json +++ b/packages/js/src/generators/library/schema.json @@ -35,7 +35,7 @@ }, "tags": { "type": "string", - "description": "Add tags to the library (used for linting)." + "description": "Add tags to the library." }, "skipFormat": { "description": "Skip formatting files.", diff --git a/packages/nest/src/generators/application/schema.json b/packages/nest/src/generators/application/schema.json index 3acc26f63f81d..e567e436e5ac8 100644 --- a/packages/nest/src/generators/application/schema.json +++ b/packages/nest/src/generators/application/schema.json @@ -50,7 +50,7 @@ "default": "jest" }, "tags": { - "description": "Add tags to the application (used for linting).", + "description": "Add tags to the application.", "type": "string" }, "frontendProject": { diff --git a/packages/nest/src/generators/library/schema.json b/packages/nest/src/generators/library/schema.json index df3e8967e2e9c..674410042b7b7 100644 --- a/packages/nest/src/generators/library/schema.json +++ b/packages/nest/src/generators/library/schema.json @@ -39,7 +39,7 @@ "default": "jest" }, "tags": { - "description": "Add tags to the library (used for linting).", + "description": "Add tags to the library.", "type": "string", "alias": "t" }, diff --git a/packages/next/src/generators/application/schema.json b/packages/next/src/generators/application/schema.json index 93ac82b521bb7..e24cdc97c81c6 100644 --- a/packages/next/src/generators/application/schema.json +++ b/packages/next/src/generators/application/schema.json @@ -90,7 +90,7 @@ }, "tags": { "type": "string", - "description": "Add tags to the application (used for linting).", + "description": "Add tags to the application.", "alias": "t" }, "js": { diff --git a/packages/next/src/generators/library/schema.json b/packages/next/src/generators/library/schema.json index f5b1c95c6cb20..71e235b48a988 100644 --- a/packages/next/src/generators/library/schema.json +++ b/packages/next/src/generators/library/schema.json @@ -78,7 +78,7 @@ }, "tags": { "type": "string", - "description": "Add tags to the library (used for linting).", + "description": "Add tags to the library.", "alias": "t" }, "skipFormat": { diff --git a/packages/node/src/generators/application/schema.json b/packages/node/src/generators/application/schema.json index 92b9f48010926..10e127e286402 100644 --- a/packages/node/src/generators/application/schema.json +++ b/packages/node/src/generators/application/schema.json @@ -47,7 +47,7 @@ }, "tags": { "type": "string", - "description": "Add tags to the application (used for linting)." + "description": "Add tags to the application." }, "frontendProject": { "type": "string", diff --git a/packages/node/src/generators/library/schema.json b/packages/node/src/generators/library/schema.json index c66e679f4d005..dae1c202bc67d 100644 --- a/packages/node/src/generators/library/schema.json +++ b/packages/node/src/generators/library/schema.json @@ -45,7 +45,7 @@ }, "tags": { "type": "string", - "description": "Add tags to the library (used for linting).", + "description": "Add tags to the library.", "alias": "t" }, "skipFormat": { diff --git a/packages/nx-plugin/src/generators/generator/files/generator/__fileName__/schema.json__tmpl__ b/packages/nx-plugin/src/generators/generator/files/generator/__fileName__/schema.json__tmpl__ index 7ded707fbde36..b1cd73cb841ea 100644 --- a/packages/nx-plugin/src/generators/generator/files/generator/__fileName__/schema.json__tmpl__ +++ b/packages/nx-plugin/src/generators/generator/files/generator/__fileName__/schema.json__tmpl__ @@ -16,7 +16,7 @@ }, "tags": { "type": "string", - "description": "Add tags to the project (used for linting)", + "description": "Add tags to the project", "alias": "t" }, "directory": { diff --git a/packages/nx-plugin/src/generators/plugin/schema.json b/packages/nx-plugin/src/generators/plugin/schema.json index e3fa9902bc4bb..a9e8692d9b18c 100644 --- a/packages/nx-plugin/src/generators/plugin/schema.json +++ b/packages/nx-plugin/src/generators/plugin/schema.json @@ -45,7 +45,7 @@ }, "tags": { "type": "string", - "description": "Add tags to the library (used for linting).", + "description": "Add tags to the library.", "alias": "t" }, "skipFormat": { diff --git a/packages/nx/src/command-line/affected.ts b/packages/nx/src/command-line/affected.ts index c493d7f97a3b7..e4102a0a05485 100644 --- a/packages/nx/src/command-line/affected.ts +++ b/packages/nx/src/command-line/affected.ts @@ -17,6 +17,7 @@ import { filterAffected } from '../project-graph/affected/affected-project-graph import { TargetDependencyConfig } from '../config/workspace-json-project-json'; import { readNxJson } from '../config/configuration'; import { workspaceConfigurationCheck } from '../utils/workspace-configuration-check'; +import { findMatchingProjects } from '../utils/find-matching-projects'; export async function affected( command: 'apps' | 'libs' | 'graph' | 'print-affected' | 'affected', @@ -168,13 +169,16 @@ async function projectsToRun( ); if (nxArgs.exclude) { - const excludedProjects = new Set(nxArgs.exclude); + const excludedProjects = new Set( + findMatchingProjects(nxArgs.exclude, affectedGraph.nodes) + ); + return Object.entries(affectedGraph.nodes) .filter(([projectName]) => !excludedProjects.has(projectName)) .map(([, project]) => project); } - return Object.values(affectedGraph.nodes) as ProjectGraphProjectNode[]; + return Object.values(affectedGraph.nodes); } function allProjectsWithTarget( diff --git a/packages/nx/src/command-line/examples.ts b/packages/nx/src/command-line/examples.ts index 76a4226f3a25f..9cf5538abb250 100644 --- a/packages/nx/src/command-line/examples.ts +++ b/packages/nx/src/command-line/examples.ts @@ -305,10 +305,15 @@ export const examples: Record = { description: 'Test proj1 and proj2 in sequence', }, { - command: 'run-many --target=test --projects=*-app --exclude excluded-app', + command: 'run-many --target=test --projects=*-app --exclude=excluded-app', description: 'Test all projects ending with `*-app` except `excluded-app`. Note: your shell may require you to escape the `*` like this: `\\*`', }, + { + command: 'run-many --target=test --projects=tag:api-*', + description: + 'Test all projects with tags starting with `api-*`. Note: your shell may require you to escape the `*` like this: `\\*`', + }, { command: 'run-many --targets=lint,test,build --all', description: diff --git a/packages/nx/src/command-line/nx-commands.ts b/packages/nx/src/command-line/nx-commands.ts index b996b1e18b4dc..4c2f3b6a32c3d 100644 --- a/packages/nx/src/command-line/nx-commands.ts +++ b/packages/nx/src/command-line/nx-commands.ts @@ -481,7 +481,6 @@ function withExcludeOption(yargs: yargs.Argv): yargs.Argv { describe: 'Exclude certain projects from being processed', type: 'string', coerce: parseCSV, - default: '', }); } diff --git a/packages/nx/src/command-line/run-many.spec.ts b/packages/nx/src/command-line/run-many.spec.ts index dcca4bfa7c6fd..7abc2013e1020 100644 --- a/packages/nx/src/command-line/run-many.spec.ts +++ b/packages/nx/src/command-line/run-many.spec.ts @@ -13,6 +13,7 @@ describe('run-many', () => { type: 'lib', data: { root: 'proj1', + tags: ['api', 'theme1'], targets: { build: {}, test: {}, @@ -24,6 +25,7 @@ describe('run-many', () => { type: 'lib', data: { root: 'proj2', + tags: ['ui', 'theme2'], targets: { test: {}, }, @@ -71,6 +73,50 @@ describe('run-many', () => { expect(projects).toContain('proj2'); }); + it('should filter projects by tag', () => { + const projects = projectsToRun( + { + targets: ['test'], + projects: ['tag:api'], + }, + projectGraph + ).map(({ name }) => name); + expect(projects).toContain('proj1'); + expect(projects).not.toContain('proj2'); + }); + + it('should filter projects by tag pattern', () => { + const projects = projectsToRun( + { + targets: ['test'], + projects: ['tag:theme*'], + }, + projectGraph + ).map(({ name }) => name); + expect(projects).toContain('proj1'); + expect(projects).toContain('proj2'); + }); + + it('should filter projects by name and tag', () => { + let projects = projectsToRun( + { + targets: ['test'], + projects: ['proj1', 'tag:ui'], + }, + projectGraph + ).map(({ name }) => name); + expect(projects).toContain('proj1'); + expect(projects).toContain('proj2'); + projects = projectsToRun( + { + targets: ['test'], + projects: ['proj1', 'tag:a*'], + }, + projectGraph + ).map(({ name }) => name); + expect(projects).toContain('proj1'); + }); + it('should exclude projects', () => { const projects = projectsToRun( { @@ -99,6 +145,34 @@ describe('run-many', () => { expect(projects).not.toContain('proj2'); }); + it('should exclude projects by tag', () => { + const projects = projectsToRun( + { + all: true, + targets: ['test'], + projects: [], + exclude: ['tag:ui'], + }, + projectGraph + ).map(({ name }) => name); + expect(projects).toContain('proj1'); + expect(projects).not.toContain('proj2'); + }); + + it('should exclude projects with a tag pattern', () => { + const projects = projectsToRun( + { + all: true, + targets: ['test'], + projects: [], + exclude: ['tag:theme*'], + }, + projectGraph + ).map(({ name }) => name); + expect(projects).not.toContain('proj1'); + expect(projects).not.toContain('proj2'); + }); + describe('perf testing', () => { beforeEach(() => { for (let i = 0; i < 1000000; i++) { diff --git a/packages/nx/src/command-line/run-many.ts b/packages/nx/src/command-line/run-many.ts index c0a3379ff0ebd..62afb4c5916a0 100644 --- a/packages/nx/src/command-line/run-many.ts +++ b/packages/nx/src/command-line/run-many.ts @@ -83,11 +83,9 @@ export function projectsToRun( selectedProjects.set(projectName, projectGraph.nodes[projectName]); } } else { - const allProjectNames = Object.keys(projectGraph.nodes); const matchingProjects = findMatchingProjects( nxArgs.projects, - allProjectNames, - new Set(allProjectNames) + projectGraph.nodes ); for (const project of matchingProjects) { if (!validProjects.has(project)) { @@ -108,9 +106,8 @@ export function projectsToRun( } const excludedProjects = findMatchingProjects( - nxArgs.exclude ?? [], - Array.from(selectedProjects.keys()), - new Set(selectedProjects.keys()) + nxArgs.exclude, + selectedProjects ); for (const excludedProject of excludedProjects) { diff --git a/packages/nx/src/project-graph/build-nodes/workspace-projects.spec.ts b/packages/nx/src/project-graph/build-nodes/workspace-projects.spec.ts index a01c9f0003ff4..1e8a6d469b772 100644 --- a/packages/nx/src/project-graph/build-nodes/workspace-projects.spec.ts +++ b/packages/nx/src/project-graph/build-nodes/workspace-projects.spec.ts @@ -1,45 +1,83 @@ +import { ProjectGraphProjectNode } from 'nx/src/config/project-graph'; import { normalizeImplicitDependencies } from './workspace-projects'; describe('workspace-projects', () => { - let projectsSet: Set; - - beforeEach(() => { - projectsSet = new Set(['test-project', 'a', 'b', 'c']); - }); + let projectGraph: Record = { + 'test-project': { + name: 'test-project', + type: 'lib', + data: { + root: 'lib/test-project', + files: [], + tags: ['api', 'theme1'], + }, + }, + a: { + name: 'a', + type: 'lib', + data: { + root: 'lib/a', + files: [], + tags: ['api', 'theme2'], + }, + }, + b: { + name: 'b', + type: 'lib', + data: { + root: 'lib/b', + files: [], + tags: ['ui'], + }, + }, + c: { + name: 'c', + type: 'lib', + data: { + root: 'lib/c', + files: [], + tags: ['api'], + }, + }, + }; describe('normalizeImplicitDependencies', () => { it('should expand "*" implicit dependencies', () => { expect( - normalizeImplicitDependencies( - 'test-project', - ['*'], - Array.from(projectsSet), - projectsSet - ) + normalizeImplicitDependencies('test-project', ['*'], projectGraph) ).toEqual(['a', 'b', 'c']); }); it('should return [] for null implicit dependencies', () => { expect( - normalizeImplicitDependencies( - 'test-project', - null, - Array.from(projectsSet), - projectsSet - ) + normalizeImplicitDependencies('test-project', null, projectGraph) ).toEqual([]); }); it('should expand glob based implicit dependencies', () => { - projectsSet.add('b-1'); - projectsSet.add('b-2'); + const projectGraphMod: typeof projectGraph = { + ...projectGraph, + 'b-1': { + name: 'b-1', + type: 'lib', + data: { + root: 'lib/b-1', + files: [], + tags: [], + }, + }, + 'b-2': { + name: 'b-2', + type: 'lib', + data: { + root: 'lib/b-2', + files: [], + tags: [], + }, + }, + }; expect( - normalizeImplicitDependencies( - 'test-project', - ['b*'], - Array.from(projectsSet), - projectsSet - ) + normalizeImplicitDependencies('test-project', ['b*'], projectGraphMod) ).toEqual(['b', 'b-1', 'b-2']); }); }); diff --git a/packages/nx/src/project-graph/build-nodes/workspace-projects.ts b/packages/nx/src/project-graph/build-nodes/workspace-projects.ts index 8a9ebf219b780..595a94aa6a060 100644 --- a/packages/nx/src/project-graph/build-nodes/workspace-projects.ts +++ b/packages/nx/src/project-graph/build-nodes/workspace-projects.ts @@ -5,7 +5,10 @@ import { loadNxPlugins, mergePluginTargetsWithNxTargets, } from '../../utils/nx-plugin'; -import { ProjectGraphProcessorContext } from '../../config/project-graph'; +import { + ProjectGraphProcessorContext, + ProjectGraphProjectNode, +} from '../../config/project-graph'; import { mergeNpmScriptsWithTargets } from '../../utils/project-graph-utils'; import { ProjectGraphBuilder } from '../project-graph-builder'; import { PackageJson } from '../../utils/package-json'; @@ -26,7 +29,18 @@ export async function buildWorkspaceProjectNodes( ) { const toAdd = []; const projects = Object.keys(ctx.workspace.projects); - const projectsSet = new Set(projects); + const projectsGraph = projects.reduce((graph, project) => { + const projectConfiguration = ctx.workspace.projects[project]; + graph[project] = { + name: project, + type: projectConfiguration.projectType === 'library' ? 'lib' : 'app', // missing fallback to `e2e` + data: { + ...projectConfiguration, + files: [], // missing files + }, + }; + return graph; + }, {} as Record); for (const key of projects) { const p = ctx.workspace.projects[key]; @@ -59,8 +73,7 @@ export async function buildWorkspaceProjectNodes( p.implicitDependencies = normalizeImplicitDependencies( key, p.implicitDependencies, - projects, - projectsSet + projectsGraph ); p.targets = mergePluginTargetsWithNxTargets( @@ -157,17 +170,12 @@ function normalizeProjectTargets( export function normalizeImplicitDependencies( source: string, implicitDependencies: ProjectConfiguration['implicitDependencies'], - projectNames: string[], - projectsSet: Set + projects: Record ) { if (!implicitDependencies?.length) { return implicitDependencies ?? []; } - const matches = findMatchingProjects( - implicitDependencies, - projectNames, - projectsSet - ); + const matches = findMatchingProjects(implicitDependencies, projects); return ( matches .filter((x) => x !== source) diff --git a/packages/nx/src/utils/assert-workspace-validity.ts b/packages/nx/src/utils/assert-workspace-validity.ts index 1bfff266d0219..7c5c947690cb5 100644 --- a/packages/nx/src/utils/assert-workspace-validity.ts +++ b/packages/nx/src/utils/assert-workspace-validity.ts @@ -1,14 +1,26 @@ import { ProjectsConfigurations } from '../config/workspace-json-project-json'; import { NxJsonConfiguration } from '../config/nx-json'; import { findMatchingProjects } from './find-matching-projects'; -import { output } from './output'; +import {output} from './output'; +import { ProjectGraphProjectNode } from '../config/project-graph'; export function assertWorkspaceValidity( - projectsConfigurations, + projectsConfigurations: ProjectsConfigurations, nxJson: NxJsonConfiguration ) { const projectNames = Object.keys(projectsConfigurations.projects); - const projectNameSet = new Set(projectNames); + const projectsGraph = projectNames.reduce((graph, project) => { + const projectConfiguration = projectsConfigurations.projects[project]; + graph[project] = { + name: project, + type: projectConfiguration.projectType === 'library' ? 'lib' : 'app', // missing fallback to `e2e` + data: { + ...projectConfiguration, + files: [], // missing files + }, + }; + return graph; + }, {} as Record); const projects = { ...projectsConfigurations.projects, @@ -39,8 +51,7 @@ export function assertWorkspaceValidity( projectName, project.implicitDependencies, projects, - projectNames, - projectNameSet + projectsGraph ); return map; }, invalidImplicitDependencies); @@ -66,8 +77,7 @@ function detectAndSetInvalidProjectGlobValues( sourceName: string, desiredImplicitDeps: string[], projectConfigurations: ProjectsConfigurations['projects'], - projectNames: string[], - projectNameSet: Set + projects: Record ) { const invalidProjectsOrGlobs = desiredImplicitDeps.filter((implicit) => { const projectName = implicit.startsWith('!') @@ -76,7 +86,7 @@ function detectAndSetInvalidProjectGlobValues( return !( projectConfigurations[projectName] || - findMatchingProjects([implicit], projectNames, projectNameSet).length + findMatchingProjects([implicit], projects).length ); }); diff --git a/packages/nx/src/utils/command-line-utils.ts b/packages/nx/src/utils/command-line-utils.ts index 9d3a946bceb31..b7dce0df0374f 100644 --- a/packages/nx/src/utils/command-line-utils.ts +++ b/packages/nx/src/utils/command-line-utils.ts @@ -173,6 +173,10 @@ export function splitArgsIntoNxArgsAndOverrides( } } + if (typeof args.exclude === 'string') { + nxArgs.exclude = args.exclude.split(','); + } + if (!nxArgs.skipNxCache) { nxArgs.skipNxCache = process.env.NX_SKIP_NX_CACHE === 'true'; } diff --git a/packages/nx/src/utils/find-matching-projects.spec.ts b/packages/nx/src/utils/find-matching-projects.spec.ts index e9092bac9801d..2794d091a06a8 100644 --- a/packages/nx/src/utils/find-matching-projects.spec.ts +++ b/packages/nx/src/utils/find-matching-projects.spec.ts @@ -1,30 +1,130 @@ import { findMatchingProjects } from './find-matching-projects'; +import { type ProjectGraphProjectNode } from '../config/project-graph'; describe('findMatchingProjects', () => { - let projectsSet: Set; + let projectGraph: Record = { + 'test-project': { + name: 'test-project', + type: 'lib', + data: { + root: 'lib/test-project', + files: [], + tags: ['api', 'theme1'], + }, + }, + a: { + name: 'a', + type: 'lib', + data: { + root: 'lib/a', + files: [], + tags: ['api', 'theme2'], + }, + }, + b: { + name: 'b', + type: 'lib', + data: { + root: 'lib/b', + files: [], + tags: ['ui'], + }, + }, + c: { + name: 'c', + type: 'lib', + data: { + root: 'lib/c', + files: [], + tags: ['api'], + }, + }, + }; - beforeEach(() => { - projectsSet = new Set(['test-project', 'a', 'b', 'c']); + it('should expand "*"', () => { + expect(findMatchingProjects(['*'], projectGraph)).toEqual([ + 'test-project', + 'a', + 'b', + 'c', + ]); }); - it('should expand "*"', () => { - expect( - findMatchingProjects(['*'], Array.from(projectsSet), projectsSet) - ).toEqual(['test-project', 'a', 'b', 'c']); + it('should support negation "!"', () => { + expect(findMatchingProjects(['*', '!a'], projectGraph)).toEqual([ + 'test-project', + 'b', + 'c', + ]); + expect(findMatchingProjects(['!*', 'a'], projectGraph)).toEqual([]); }); it('should expand generic glob patterns', () => { - projectsSet.add('b-1'); - projectsSet.add('b-2'); + const projectGraphMod: typeof projectGraph = { + ...projectGraph, + 'b-1': { + name: 'b-1', + type: 'lib', + data: { + root: 'lib/b-1', + files: [], + tags: [], + }, + }, + 'b-2': { + name: 'b-2', + type: 'lib', + data: { + root: 'lib/b-2', + files: [], + tags: [], + }, + }, + }; - expect( - findMatchingProjects(['b*'], Array.from(projectsSet), projectsSet) - ).toEqual(['b', 'b-1', 'b-2']); + expect(findMatchingProjects(['b*'], projectGraphMod)).toEqual([ + 'b', + 'b-1', + 'b-2', + ]); }); it('should support projectNames', () => { + expect(findMatchingProjects(['a', 'b'], projectGraph)).toEqual(['a', 'b']); + }); + + it('should expand "*" for tags', () => { + expect(findMatchingProjects(['tags:*'], projectGraph)).toEqual([ + 'test-project', + 'a', + 'b', + 'c', + ]); + }); + + it('should support negation "!" for tags', () => { + expect(findMatchingProjects(['*', 'tag:!api'], projectGraph)).toEqual([ + 'b', + ]); + expect(findMatchingProjects(['*', '!tag:api'], projectGraph)).toEqual([ + 'b', + ]); + }); + + it('should expand generic glob patterns for tags', () => { + expect(findMatchingProjects(['tag:theme*'], projectGraph)).toEqual([ + 'test-project', + 'a', + ]); + }); + + it('should support mixed projectNames and tags', () => { + expect(findMatchingProjects(['a', 'tag:ui'], projectGraph)).toEqual([ + 'a', + 'b', + ]); expect( - findMatchingProjects(['a', 'b'], Array.from(projectsSet), projectsSet) - ).toEqual(['a', 'b']); + findMatchingProjects(['tag:api', '!tag:theme2'], projectGraph) + ).toEqual(['test-project', 'c']); }); }); diff --git a/packages/nx/src/utils/find-matching-projects.ts b/packages/nx/src/utils/find-matching-projects.ts index 7162874e58e67..846e8607bf92a 100644 --- a/packages/nx/src/utils/find-matching-projects.ts +++ b/packages/nx/src/utils/find-matching-projects.ts @@ -1,4 +1,5 @@ import minimatch = require('minimatch'); +import { type ProjectGraphProjectNode } from '../config/project-graph'; const globCharacters = ['*', '|', '{', '}', '(', ')']; @@ -6,41 +7,90 @@ const globCharacters = ['*', '|', '{', '}', '(', ')']; * Find matching project names given a list of potential project names or globs. * * @param patterns A list of project names or globs to match against. - * @param projectNames An array containing the list of project names. - * @param projectNamesSet A set containing the list of project names. + * @param projects A map of {@link ProjectGraphProjectNode} by project name. * @returns */ export function findMatchingProjects( - patterns: string[], - projectNames: string[], - projectNamesSet: Set + patterns: string[] = [], + projects: + | Record + | Map ): string[] { + const projectObject = + projects instanceof Map ? Object.fromEntries(projects) : projects; + const projectNames = Object.keys(projectObject); + const patternObjects = patterns.map((pattern) => { + let isExclude = false; + if (pattern.startsWith('!')) { + isExclude = true; + pattern = pattern.substring(1); + } + let [value, type] = pattern.split(':').reverse(); + if (value.startsWith('!')) { + isExclude ||= true; + value = value.substring(1); + } + return { + not: isExclude, + type: type, + value, + }; + }); + const selectedProjects: Set = new Set(); const excludedProjects: Set = new Set(); - for (const nameOrGlob of patterns) { - if (projectNamesSet.has(nameOrGlob)) { - selectedProjects.add(nameOrGlob); - continue; + for (const patternObject of patternObjects) { + if (patternObject.value === '*') { + projectNames.every((projectName) => + (patternObject.not ? excludedProjects : selectedProjects).add( + projectName + ) + ); + if (patternObjects.length === 1) continue; } - if (!globCharacters.some((c) => nameOrGlob.includes(c))) { + if (patternObject.type === 'tag') { + for (const projectName of projectNames) { + const tags = projectObject[projectName].data.tags || []; + + if (tags.includes(patternObject.value)) { + (patternObject.not ? excludedProjects : selectedProjects).add( + projectName + ); + continue; + } + + if (!globCharacters.some((c) => patternObject.value.includes(c))) { + continue; + } + + if (minimatch.match(tags, patternObject.value).length) + (patternObject.not ? excludedProjects : selectedProjects).add( + projectName + ); + } continue; } - const exclude = nameOrGlob.startsWith('!'); - const pattern = exclude ? nameOrGlob.substring(1) : nameOrGlob; + if (projectNames.includes(patternObject.value)) { + (patternObject.not ? excludedProjects : selectedProjects).add( + patternObject.value + ); + continue; + } - const matchedProjectNames = - pattern === '*' ? projectNames : minimatch.match(projectNames, pattern); + if (!globCharacters.some((c) => patternObject.value.includes(c))) { + continue; + } - matchedProjectNames.forEach((matchedProjectName) => { - if (exclude) { - excludedProjects.add(matchedProjectName); - } else { - selectedProjects.add(matchedProjectName); - } - }); + const matchedProjectNames = minimatch.match( + projectNames, + patternObject.value + ); + matchedProjectNames.every((projectName) => + (patternObject.not ? excludedProjects : selectedProjects).add(projectName) + ); } for (const project of excludedProjects) { diff --git a/packages/react-native/src/generators/application/schema.json b/packages/react-native/src/generators/application/schema.json index 1ef969aa555a0..a6870108b959f 100644 --- a/packages/react-native/src/generators/application/schema.json +++ b/packages/react-native/src/generators/application/schema.json @@ -53,7 +53,7 @@ }, "tags": { "type": "string", - "description": "Add tags to the application (used for linting).", + "description": "Add tags to the application.", "alias": "t" }, "js": { diff --git a/packages/react-native/src/generators/library/schema.json b/packages/react-native/src/generators/library/schema.json index bd727f6e4af8a..98a23742cf46e 100644 --- a/packages/react-native/src/generators/library/schema.json +++ b/packages/react-native/src/generators/library/schema.json @@ -42,7 +42,7 @@ }, "tags": { "type": "string", - "description": "Add tags to the library (used for linting).", + "description": "Add tags to the library.", "alias": "t" }, "skipFormat": { diff --git a/packages/react/docs/application-examples.md b/packages/react/docs/application-examples.md index b3314804eadd6..fa6503e91bd03 100644 --- a/packages/react/docs/application-examples.md +++ b/packages/react/docs/application-examples.md @@ -33,7 +33,7 @@ nx g @nrwl/react:app my-app --directory=my-dir --style=scss {% tab label="Add tags" %} -Add tags to the application (used for linting). +Add tags to the application. ```bash nx g @nrwl/react:app my-app --tags=scope:admin,type:ui diff --git a/packages/react/src/generators/application/schema.json b/packages/react/src/generators/application/schema.json index 6073454d01979..9ddc4cb52d2df 100644 --- a/packages/react/src/generators/application/schema.json +++ b/packages/react/src/generators/application/schema.json @@ -124,7 +124,7 @@ }, "tags": { "type": "string", - "description": "Add tags to the application (used for linting).", + "description": "Add tags to the application.", "alias": "t" }, "pascalCaseFiles": { diff --git a/packages/react/src/generators/host/schema.json b/packages/react/src/generators/host/schema.json index ba6adf0f57317..922e94bedccdf 100644 --- a/packages/react/src/generators/host/schema.json +++ b/packages/react/src/generators/host/schema.json @@ -99,7 +99,7 @@ }, "tags": { "type": "string", - "description": "Add tags to the application (used for linting).", + "description": "Add tags to the application.", "alias": "t" }, "pascalCaseFiles": { diff --git a/packages/react/src/generators/library/schema.json b/packages/react/src/generators/library/schema.json index fa7e3a82c2e45..4d05dc67ae27d 100644 --- a/packages/react/src/generators/library/schema.json +++ b/packages/react/src/generators/library/schema.json @@ -93,7 +93,7 @@ }, "tags": { "type": "string", - "description": "Add tags to the library (used for linting).", + "description": "Add tags to the library.", "alias": "t" }, "skipFormat": { diff --git a/packages/react/src/generators/remote/schema.json b/packages/react/src/generators/remote/schema.json index e1c1f678e0f64..704078acabbfa 100644 --- a/packages/react/src/generators/remote/schema.json +++ b/packages/react/src/generators/remote/schema.json @@ -104,7 +104,7 @@ }, "tags": { "type": "string", - "description": "Add tags to the application (used for linting).", + "description": "Add tags to the application.", "alias": "t" }, "pascalCaseFiles": { diff --git a/packages/web/docs/application-examples.md b/packages/web/docs/application-examples.md index abc396b3a1ad5..a572c469a93dd 100644 --- a/packages/web/docs/application-examples.md +++ b/packages/web/docs/application-examples.md @@ -33,7 +33,7 @@ nx g @nrwl/web:app my-app --directory=my-dir {% tab label="Add tags" %} -Add tags to the application (used for linting). +Add tags to the application. ```bash nx g @nrwl/web:app my-app --tags=scope:admin,type:ui diff --git a/packages/web/src/generators/application/schema.json b/packages/web/src/generators/application/schema.json index 56bd2ac79336c..ffbf8935d837d 100644 --- a/packages/web/src/generators/application/schema.json +++ b/packages/web/src/generators/application/schema.json @@ -92,7 +92,7 @@ }, "tags": { "type": "string", - "description": "Add tags to the application (used for linting)" + "description": "Add tags to the application" }, "setParserOptionsProject": { "type": "boolean", diff --git a/packages/workspace/src/generators/library/schema.json b/packages/workspace/src/generators/library/schema.json index 36fece6dee888..d433e65834b38 100644 --- a/packages/workspace/src/generators/library/schema.json +++ b/packages/workspace/src/generators/library/schema.json @@ -41,7 +41,7 @@ }, "tags": { "type": "string", - "description": "Add tags to the library (used for linting)." + "description": "Add tags to the library." }, "skipFormat": { "description": "Skip formatting files.", From f86eaf1a8025b8ea6ae820b53044fbc3d02cf8ab Mon Sep 17 00:00:00 2001 From: AgentEnder Date: Wed, 5 Apr 2023 13:43:06 -0400 Subject: [PATCH 2/3] chore(misc): revert changed to tag documentation --- docs/generated/packages/angular/generators/application.json | 2 +- docs/generated/packages/angular/generators/host.json | 2 +- docs/generated/packages/angular/generators/library.json | 5 ++++- docs/generated/packages/angular/generators/remote.json | 2 +- docs/generated/packages/expo/generators/application.json | 2 +- docs/generated/packages/expo/generators/library.json | 2 +- docs/generated/packages/express/generators/application.json | 2 +- docs/generated/packages/js/generators/library.json | 5 ++++- docs/generated/packages/nest/generators/application.json | 2 +- docs/generated/packages/nest/generators/library.json | 2 +- docs/generated/packages/next/generators/application.json | 2 +- docs/generated/packages/next/generators/library.json | 2 +- docs/generated/packages/node/generators/application.json | 2 +- docs/generated/packages/node/generators/library.json | 2 +- docs/generated/packages/nx-plugin/generators/plugin.json | 2 +- .../packages/react-native/generators/application.json | 2 +- docs/generated/packages/react-native/generators/library.json | 2 +- docs/generated/packages/react/generators/application.json | 2 +- docs/generated/packages/react/generators/host.json | 2 +- docs/generated/packages/react/generators/library.json | 2 +- docs/generated/packages/react/generators/remote.json | 2 +- docs/generated/packages/web/generators/application.json | 2 +- docs/generated/packages/workspace/generators/library.json | 5 ++++- packages/angular/docs/application-examples.md | 2 +- packages/angular/src/generators/application/schema.json | 2 +- packages/angular/src/generators/host/schema.json | 2 +- packages/angular/src/generators/library/schema.json | 2 +- packages/angular/src/generators/remote/schema.json | 2 +- packages/expo/src/generators/application/schema.json | 2 +- packages/expo/src/generators/library/schema.json | 2 +- packages/express/src/generators/application/schema.json | 2 +- packages/js/src/generators/library/schema.json | 2 +- packages/nest/src/generators/application/schema.json | 2 +- packages/nest/src/generators/library/schema.json | 2 +- packages/next/src/generators/application/schema.json | 2 +- packages/next/src/generators/library/schema.json | 2 +- packages/node/src/generators/application/schema.json | 2 +- packages/node/src/generators/library/schema.json | 2 +- .../files/generator/__fileName__/schema.json__tmpl__ | 2 +- packages/nx-plugin/src/generators/plugin/schema.json | 2 +- packages/react-native/src/generators/application/schema.json | 2 +- packages/react-native/src/generators/library/schema.json | 2 +- packages/react/docs/application-examples.md | 2 +- packages/react/src/generators/application/schema.json | 2 +- packages/react/src/generators/host/schema.json | 2 +- packages/react/src/generators/library/schema.json | 2 +- packages/react/src/generators/remote/schema.json | 2 +- packages/web/docs/application-examples.md | 2 +- packages/web/src/generators/application/schema.json | 2 +- packages/workspace/src/generators/library/schema.json | 2 +- 50 files changed, 59 insertions(+), 50 deletions(-) diff --git a/docs/generated/packages/angular/generators/application.json b/docs/generated/packages/angular/generators/application.json index 1ad2ebc015d2d..ddc27ec116055 100644 --- a/docs/generated/packages/angular/generators/application.json +++ b/docs/generated/packages/angular/generators/application.json @@ -108,7 +108,7 @@ }, "tags": { "type": "string", - "description": "Add tags to the application." + "description": "Add tags to the application (used for linting)." }, "linter": { "description": "The tool to use for running lint checks.", diff --git a/docs/generated/packages/angular/generators/host.json b/docs/generated/packages/angular/generators/host.json index fea78bec5d4cc..856524fd58520 100644 --- a/docs/generated/packages/angular/generators/host.json +++ b/docs/generated/packages/angular/generators/host.json @@ -115,7 +115,7 @@ }, "tags": { "type": "string", - "description": "Add tags to the application." + "description": "Add tags to the application (used for linting)." }, "linter": { "description": "The tool to use for running lint checks.", diff --git a/docs/generated/packages/angular/generators/library.json b/docs/generated/packages/angular/generators/library.json index 9fe90f1405177..adde6fab5bb11 100644 --- a/docs/generated/packages/angular/generators/library.json +++ b/docs/generated/packages/angular/generators/library.json @@ -89,7 +89,10 @@ "description": "Path to the parent route configuration using `loadChildren` or `children`, depending on what `lazy` is set to.", "x-priority": "important" }, - "tags": { "type": "string", "description": "Add tags to the library." }, + "tags": { + "type": "string", + "description": "Add tags to the library (used for linting)." + }, "unitTestRunner": { "type": "string", "enum": ["jest", "none"], diff --git a/docs/generated/packages/angular/generators/remote.json b/docs/generated/packages/angular/generators/remote.json index 938a3bdd0065f..793a89111aa0d 100644 --- a/docs/generated/packages/angular/generators/remote.json +++ b/docs/generated/packages/angular/generators/remote.json @@ -109,7 +109,7 @@ }, "tags": { "type": "string", - "description": "Add tags to the application." + "description": "Add tags to the application (used for linting)." }, "linter": { "description": "The tool to use for running lint checks.", diff --git a/docs/generated/packages/expo/generators/application.json b/docs/generated/packages/expo/generators/application.json index 6feee1d1bbfd5..94ae26f44b2c8 100644 --- a/docs/generated/packages/expo/generators/application.json +++ b/docs/generated/packages/expo/generators/application.json @@ -53,7 +53,7 @@ }, "tags": { "type": "string", - "description": "Add tags to the application", + "description": "Add tags to the application (used for linting)", "alias": "t" }, "js": { diff --git a/docs/generated/packages/expo/generators/library.json b/docs/generated/packages/expo/generators/library.json index 0110484fdaa35..b3976b6ae037b 100644 --- a/docs/generated/packages/expo/generators/library.json +++ b/docs/generated/packages/expo/generators/library.json @@ -40,7 +40,7 @@ }, "tags": { "type": "string", - "description": "Add tags to the library.", + "description": "Add tags to the library (used for linting).", "alias": "t" }, "skipFormat": { diff --git a/docs/generated/packages/express/generators/application.json b/docs/generated/packages/express/generators/application.json index 9df851b3fc3c9..10336208f37f7 100644 --- a/docs/generated/packages/express/generators/application.json +++ b/docs/generated/packages/express/generators/application.json @@ -44,7 +44,7 @@ }, "tags": { "type": "string", - "description": "Add tags to the application." + "description": "Add tags to the application (used for linting)." }, "frontendProject": { "type": "string", diff --git a/docs/generated/packages/js/generators/library.json b/docs/generated/packages/js/generators/library.json index 65098f4d9d4a3..78223d2c7aaa2 100644 --- a/docs/generated/packages/js/generators/library.json +++ b/docs/generated/packages/js/generators/library.json @@ -33,7 +33,10 @@ "description": "Test runner to use for unit tests.", "x-prompt": "Which unit test runner would you like to use?" }, - "tags": { "type": "string", "description": "Add tags to the library." }, + "tags": { + "type": "string", + "description": "Add tags to the library (used for linting)." + }, "skipFormat": { "description": "Skip formatting files.", "type": "boolean", diff --git a/docs/generated/packages/nest/generators/application.json b/docs/generated/packages/nest/generators/application.json index 16f4ca48bda72..6350158831da0 100644 --- a/docs/generated/packages/nest/generators/application.json +++ b/docs/generated/packages/nest/generators/application.json @@ -50,7 +50,7 @@ "default": "jest" }, "tags": { - "description": "Add tags to the application.", + "description": "Add tags to the application (used for linting).", "type": "string" }, "frontendProject": { diff --git a/docs/generated/packages/nest/generators/library.json b/docs/generated/packages/nest/generators/library.json index 21d0b742fdcf7..2fe5b804d4fa7 100644 --- a/docs/generated/packages/nest/generators/library.json +++ b/docs/generated/packages/nest/generators/library.json @@ -39,7 +39,7 @@ "default": "jest" }, "tags": { - "description": "Add tags to the library.", + "description": "Add tags to the library (used for linting).", "type": "string", "alias": "t" }, diff --git a/docs/generated/packages/next/generators/application.json b/docs/generated/packages/next/generators/application.json index 6f5ac0fd401bc..5ad1db11b4e52 100644 --- a/docs/generated/packages/next/generators/application.json +++ b/docs/generated/packages/next/generators/application.json @@ -90,7 +90,7 @@ }, "tags": { "type": "string", - "description": "Add tags to the application.", + "description": "Add tags to the application (used for linting).", "alias": "t" }, "js": { diff --git a/docs/generated/packages/next/generators/library.json b/docs/generated/packages/next/generators/library.json index 70665455c6298..f06dff5a6173c 100644 --- a/docs/generated/packages/next/generators/library.json +++ b/docs/generated/packages/next/generators/library.json @@ -75,7 +75,7 @@ }, "tags": { "type": "string", - "description": "Add tags to the library.", + "description": "Add tags to the library (used for linting).", "alias": "t" }, "skipFormat": { diff --git a/docs/generated/packages/node/generators/application.json b/docs/generated/packages/node/generators/application.json index 7bac364144beb..a2bbe09416a60 100644 --- a/docs/generated/packages/node/generators/application.json +++ b/docs/generated/packages/node/generators/application.json @@ -47,7 +47,7 @@ }, "tags": { "type": "string", - "description": "Add tags to the application." + "description": "Add tags to the application (used for linting)." }, "frontendProject": { "type": "string", diff --git a/docs/generated/packages/node/generators/library.json b/docs/generated/packages/node/generators/library.json index 1fb4a0a0645d6..47c5f4a86eab8 100644 --- a/docs/generated/packages/node/generators/library.json +++ b/docs/generated/packages/node/generators/library.json @@ -45,7 +45,7 @@ }, "tags": { "type": "string", - "description": "Add tags to the library.", + "description": "Add tags to the library (used for linting).", "alias": "t" }, "skipFormat": { diff --git a/docs/generated/packages/nx-plugin/generators/plugin.json b/docs/generated/packages/nx-plugin/generators/plugin.json index aeca396c68232..e6df079e46662 100644 --- a/docs/generated/packages/nx-plugin/generators/plugin.json +++ b/docs/generated/packages/nx-plugin/generators/plugin.json @@ -45,7 +45,7 @@ }, "tags": { "type": "string", - "description": "Add tags to the library.", + "description": "Add tags to the library (used for linting).", "alias": "t" }, "skipFormat": { diff --git a/docs/generated/packages/react-native/generators/application.json b/docs/generated/packages/react-native/generators/application.json index 4c874aabe76eb..318198dc3ca72 100644 --- a/docs/generated/packages/react-native/generators/application.json +++ b/docs/generated/packages/react-native/generators/application.json @@ -53,7 +53,7 @@ }, "tags": { "type": "string", - "description": "Add tags to the application.", + "description": "Add tags to the application (used for linting).", "alias": "t" }, "js": { diff --git a/docs/generated/packages/react-native/generators/library.json b/docs/generated/packages/react-native/generators/library.json index 48462d25f9919..906eb413a0a93 100644 --- a/docs/generated/packages/react-native/generators/library.json +++ b/docs/generated/packages/react-native/generators/library.json @@ -42,7 +42,7 @@ }, "tags": { "type": "string", - "description": "Add tags to the library.", + "description": "Add tags to the library (used for linting).", "alias": "t" }, "skipFormat": { diff --git a/docs/generated/packages/react/generators/application.json b/docs/generated/packages/react/generators/application.json index 32ef2b620837d..e58345ab6d24c 100644 --- a/docs/generated/packages/react/generators/application.json +++ b/docs/generated/packages/react/generators/application.json @@ -118,7 +118,7 @@ }, "tags": { "type": "string", - "description": "Add tags to the application.", + "description": "Add tags to the application (used for linting).", "alias": "t" }, "pascalCaseFiles": { diff --git a/docs/generated/packages/react/generators/host.json b/docs/generated/packages/react/generators/host.json index d6f0ccbca9a65..802c15f41a8a7 100644 --- a/docs/generated/packages/react/generators/host.json +++ b/docs/generated/packages/react/generators/host.json @@ -93,7 +93,7 @@ }, "tags": { "type": "string", - "description": "Add tags to the application.", + "description": "Add tags to the application (used for linting).", "alias": "t" }, "pascalCaseFiles": { diff --git a/docs/generated/packages/react/generators/library.json b/docs/generated/packages/react/generators/library.json index ad53b9ec60a7e..35b01e811a9ca 100644 --- a/docs/generated/packages/react/generators/library.json +++ b/docs/generated/packages/react/generators/library.json @@ -90,7 +90,7 @@ }, "tags": { "type": "string", - "description": "Add tags to the library.", + "description": "Add tags to the library (used for linting).", "alias": "t" }, "skipFormat": { diff --git a/docs/generated/packages/react/generators/remote.json b/docs/generated/packages/react/generators/remote.json index 556113f67742a..bcc76f7936198 100644 --- a/docs/generated/packages/react/generators/remote.json +++ b/docs/generated/packages/react/generators/remote.json @@ -98,7 +98,7 @@ }, "tags": { "type": "string", - "description": "Add tags to the application.", + "description": "Add tags to the application (used for linting).", "alias": "t" }, "pascalCaseFiles": { diff --git a/docs/generated/packages/web/generators/application.json b/docs/generated/packages/web/generators/application.json index da283b31614bc..490f73fe8e317 100644 --- a/docs/generated/packages/web/generators/application.json +++ b/docs/generated/packages/web/generators/application.json @@ -89,7 +89,7 @@ }, "tags": { "type": "string", - "description": "Add tags to the application" + "description": "Add tags to the application (used for linting)" }, "setParserOptionsProject": { "type": "boolean", diff --git a/docs/generated/packages/workspace/generators/library.json b/docs/generated/packages/workspace/generators/library.json index b40c89b26a4e7..abfc5317dab3c 100644 --- a/docs/generated/packages/workspace/generators/library.json +++ b/docs/generated/packages/workspace/generators/library.json @@ -39,7 +39,10 @@ "description": "Test runner to use for unit tests.", "default": "jest" }, - "tags": { "type": "string", "description": "Add tags to the library." }, + "tags": { + "type": "string", + "description": "Add tags to the library (used for linting)." + }, "skipFormat": { "description": "Skip formatting files.", "type": "boolean", diff --git a/packages/angular/docs/application-examples.md b/packages/angular/docs/application-examples.md index 986f330135c1e..3ff5015e2524c 100644 --- a/packages/angular/docs/application-examples.md +++ b/packages/angular/docs/application-examples.md @@ -43,7 +43,7 @@ nx g @nrwl/angular:app my-app --standalone {% tab label="Set custom prefix and tags" %} -Set the prefix to apply to generated selectors and add tags to the application. +Set the prefix to apply to generated selectors and add tags to the application (used for linting). ```bash nx g @nrwl/angular:app my-app --prefix=admin --tags=scope:admin,type:ui diff --git a/packages/angular/src/generators/application/schema.json b/packages/angular/src/generators/application/schema.json index 6bbe5805e2d7a..223eac46a397f 100644 --- a/packages/angular/src/generators/application/schema.json +++ b/packages/angular/src/generators/application/schema.json @@ -111,7 +111,7 @@ }, "tags": { "type": "string", - "description": "Add tags to the application." + "description": "Add tags to the application (used for linting)." }, "linter": { "description": "The tool to use for running lint checks.", diff --git a/packages/angular/src/generators/host/schema.json b/packages/angular/src/generators/host/schema.json index eed0dc327c43d..f24b551c3cf50 100644 --- a/packages/angular/src/generators/host/schema.json +++ b/packages/angular/src/generators/host/schema.json @@ -118,7 +118,7 @@ }, "tags": { "type": "string", - "description": "Add tags to the application." + "description": "Add tags to the application (used for linting)." }, "linter": { "description": "The tool to use for running lint checks.", diff --git a/packages/angular/src/generators/library/schema.json b/packages/angular/src/generators/library/schema.json index ec4061b7d0b87..8463a226f44dd 100644 --- a/packages/angular/src/generators/library/schema.json +++ b/packages/angular/src/generators/library/schema.json @@ -91,7 +91,7 @@ }, "tags": { "type": "string", - "description": "Add tags to the library." + "description": "Add tags to the library (used for linting)." }, "unitTestRunner": { "type": "string", diff --git a/packages/angular/src/generators/remote/schema.json b/packages/angular/src/generators/remote/schema.json index 0bf5aca3bc763..22601e3b5fec8 100644 --- a/packages/angular/src/generators/remote/schema.json +++ b/packages/angular/src/generators/remote/schema.json @@ -112,7 +112,7 @@ }, "tags": { "type": "string", - "description": "Add tags to the application." + "description": "Add tags to the application (used for linting)." }, "linter": { "description": "The tool to use for running lint checks.", diff --git a/packages/expo/src/generators/application/schema.json b/packages/expo/src/generators/application/schema.json index d277dbd4c1017..c507bcc6afa17 100644 --- a/packages/expo/src/generators/application/schema.json +++ b/packages/expo/src/generators/application/schema.json @@ -53,7 +53,7 @@ }, "tags": { "type": "string", - "description": "Add tags to the application", + "description": "Add tags to the application (used for linting)", "alias": "t" }, "js": { diff --git a/packages/expo/src/generators/library/schema.json b/packages/expo/src/generators/library/schema.json index 9a4a172731246..0961290da0706 100644 --- a/packages/expo/src/generators/library/schema.json +++ b/packages/expo/src/generators/library/schema.json @@ -40,7 +40,7 @@ }, "tags": { "type": "string", - "description": "Add tags to the library.", + "description": "Add tags to the library (used for linting).", "alias": "t" }, "skipFormat": { diff --git a/packages/express/src/generators/application/schema.json b/packages/express/src/generators/application/schema.json index 41af3129db5b7..db3c743ce5f18 100644 --- a/packages/express/src/generators/application/schema.json +++ b/packages/express/src/generators/application/schema.json @@ -44,7 +44,7 @@ }, "tags": { "type": "string", - "description": "Add tags to the application." + "description": "Add tags to the application (used for linting)." }, "frontendProject": { "type": "string", diff --git a/packages/js/src/generators/library/schema.json b/packages/js/src/generators/library/schema.json index ef26ad601ff9a..b0f26af936477 100644 --- a/packages/js/src/generators/library/schema.json +++ b/packages/js/src/generators/library/schema.json @@ -35,7 +35,7 @@ }, "tags": { "type": "string", - "description": "Add tags to the library." + "description": "Add tags to the library (used for linting)." }, "skipFormat": { "description": "Skip formatting files.", diff --git a/packages/nest/src/generators/application/schema.json b/packages/nest/src/generators/application/schema.json index e567e436e5ac8..3acc26f63f81d 100644 --- a/packages/nest/src/generators/application/schema.json +++ b/packages/nest/src/generators/application/schema.json @@ -50,7 +50,7 @@ "default": "jest" }, "tags": { - "description": "Add tags to the application.", + "description": "Add tags to the application (used for linting).", "type": "string" }, "frontendProject": { diff --git a/packages/nest/src/generators/library/schema.json b/packages/nest/src/generators/library/schema.json index 674410042b7b7..df3e8967e2e9c 100644 --- a/packages/nest/src/generators/library/schema.json +++ b/packages/nest/src/generators/library/schema.json @@ -39,7 +39,7 @@ "default": "jest" }, "tags": { - "description": "Add tags to the library.", + "description": "Add tags to the library (used for linting).", "type": "string", "alias": "t" }, diff --git a/packages/next/src/generators/application/schema.json b/packages/next/src/generators/application/schema.json index e24cdc97c81c6..93ac82b521bb7 100644 --- a/packages/next/src/generators/application/schema.json +++ b/packages/next/src/generators/application/schema.json @@ -90,7 +90,7 @@ }, "tags": { "type": "string", - "description": "Add tags to the application.", + "description": "Add tags to the application (used for linting).", "alias": "t" }, "js": { diff --git a/packages/next/src/generators/library/schema.json b/packages/next/src/generators/library/schema.json index 71e235b48a988..f5b1c95c6cb20 100644 --- a/packages/next/src/generators/library/schema.json +++ b/packages/next/src/generators/library/schema.json @@ -78,7 +78,7 @@ }, "tags": { "type": "string", - "description": "Add tags to the library.", + "description": "Add tags to the library (used for linting).", "alias": "t" }, "skipFormat": { diff --git a/packages/node/src/generators/application/schema.json b/packages/node/src/generators/application/schema.json index 10e127e286402..92b9f48010926 100644 --- a/packages/node/src/generators/application/schema.json +++ b/packages/node/src/generators/application/schema.json @@ -47,7 +47,7 @@ }, "tags": { "type": "string", - "description": "Add tags to the application." + "description": "Add tags to the application (used for linting)." }, "frontendProject": { "type": "string", diff --git a/packages/node/src/generators/library/schema.json b/packages/node/src/generators/library/schema.json index dae1c202bc67d..c66e679f4d005 100644 --- a/packages/node/src/generators/library/schema.json +++ b/packages/node/src/generators/library/schema.json @@ -45,7 +45,7 @@ }, "tags": { "type": "string", - "description": "Add tags to the library.", + "description": "Add tags to the library (used for linting).", "alias": "t" }, "skipFormat": { diff --git a/packages/nx-plugin/src/generators/generator/files/generator/__fileName__/schema.json__tmpl__ b/packages/nx-plugin/src/generators/generator/files/generator/__fileName__/schema.json__tmpl__ index b1cd73cb841ea..7ded707fbde36 100644 --- a/packages/nx-plugin/src/generators/generator/files/generator/__fileName__/schema.json__tmpl__ +++ b/packages/nx-plugin/src/generators/generator/files/generator/__fileName__/schema.json__tmpl__ @@ -16,7 +16,7 @@ }, "tags": { "type": "string", - "description": "Add tags to the project", + "description": "Add tags to the project (used for linting)", "alias": "t" }, "directory": { diff --git a/packages/nx-plugin/src/generators/plugin/schema.json b/packages/nx-plugin/src/generators/plugin/schema.json index a9e8692d9b18c..e3fa9902bc4bb 100644 --- a/packages/nx-plugin/src/generators/plugin/schema.json +++ b/packages/nx-plugin/src/generators/plugin/schema.json @@ -45,7 +45,7 @@ }, "tags": { "type": "string", - "description": "Add tags to the library.", + "description": "Add tags to the library (used for linting).", "alias": "t" }, "skipFormat": { diff --git a/packages/react-native/src/generators/application/schema.json b/packages/react-native/src/generators/application/schema.json index a6870108b959f..1ef969aa555a0 100644 --- a/packages/react-native/src/generators/application/schema.json +++ b/packages/react-native/src/generators/application/schema.json @@ -53,7 +53,7 @@ }, "tags": { "type": "string", - "description": "Add tags to the application.", + "description": "Add tags to the application (used for linting).", "alias": "t" }, "js": { diff --git a/packages/react-native/src/generators/library/schema.json b/packages/react-native/src/generators/library/schema.json index 98a23742cf46e..bd727f6e4af8a 100644 --- a/packages/react-native/src/generators/library/schema.json +++ b/packages/react-native/src/generators/library/schema.json @@ -42,7 +42,7 @@ }, "tags": { "type": "string", - "description": "Add tags to the library.", + "description": "Add tags to the library (used for linting).", "alias": "t" }, "skipFormat": { diff --git a/packages/react/docs/application-examples.md b/packages/react/docs/application-examples.md index fa6503e91bd03..b3314804eadd6 100644 --- a/packages/react/docs/application-examples.md +++ b/packages/react/docs/application-examples.md @@ -33,7 +33,7 @@ nx g @nrwl/react:app my-app --directory=my-dir --style=scss {% tab label="Add tags" %} -Add tags to the application. +Add tags to the application (used for linting). ```bash nx g @nrwl/react:app my-app --tags=scope:admin,type:ui diff --git a/packages/react/src/generators/application/schema.json b/packages/react/src/generators/application/schema.json index 9ddc4cb52d2df..6073454d01979 100644 --- a/packages/react/src/generators/application/schema.json +++ b/packages/react/src/generators/application/schema.json @@ -124,7 +124,7 @@ }, "tags": { "type": "string", - "description": "Add tags to the application.", + "description": "Add tags to the application (used for linting).", "alias": "t" }, "pascalCaseFiles": { diff --git a/packages/react/src/generators/host/schema.json b/packages/react/src/generators/host/schema.json index 922e94bedccdf..ba6adf0f57317 100644 --- a/packages/react/src/generators/host/schema.json +++ b/packages/react/src/generators/host/schema.json @@ -99,7 +99,7 @@ }, "tags": { "type": "string", - "description": "Add tags to the application.", + "description": "Add tags to the application (used for linting).", "alias": "t" }, "pascalCaseFiles": { diff --git a/packages/react/src/generators/library/schema.json b/packages/react/src/generators/library/schema.json index 4d05dc67ae27d..fa7e3a82c2e45 100644 --- a/packages/react/src/generators/library/schema.json +++ b/packages/react/src/generators/library/schema.json @@ -93,7 +93,7 @@ }, "tags": { "type": "string", - "description": "Add tags to the library.", + "description": "Add tags to the library (used for linting).", "alias": "t" }, "skipFormat": { diff --git a/packages/react/src/generators/remote/schema.json b/packages/react/src/generators/remote/schema.json index 704078acabbfa..e1c1f678e0f64 100644 --- a/packages/react/src/generators/remote/schema.json +++ b/packages/react/src/generators/remote/schema.json @@ -104,7 +104,7 @@ }, "tags": { "type": "string", - "description": "Add tags to the application.", + "description": "Add tags to the application (used for linting).", "alias": "t" }, "pascalCaseFiles": { diff --git a/packages/web/docs/application-examples.md b/packages/web/docs/application-examples.md index a572c469a93dd..abc396b3a1ad5 100644 --- a/packages/web/docs/application-examples.md +++ b/packages/web/docs/application-examples.md @@ -33,7 +33,7 @@ nx g @nrwl/web:app my-app --directory=my-dir {% tab label="Add tags" %} -Add tags to the application. +Add tags to the application (used for linting). ```bash nx g @nrwl/web:app my-app --tags=scope:admin,type:ui diff --git a/packages/web/src/generators/application/schema.json b/packages/web/src/generators/application/schema.json index ffbf8935d837d..56bd2ac79336c 100644 --- a/packages/web/src/generators/application/schema.json +++ b/packages/web/src/generators/application/schema.json @@ -92,7 +92,7 @@ }, "tags": { "type": "string", - "description": "Add tags to the application" + "description": "Add tags to the application (used for linting)" }, "setParserOptionsProject": { "type": "boolean", diff --git a/packages/workspace/src/generators/library/schema.json b/packages/workspace/src/generators/library/schema.json index d433e65834b38..36fece6dee888 100644 --- a/packages/workspace/src/generators/library/schema.json +++ b/packages/workspace/src/generators/library/schema.json @@ -41,7 +41,7 @@ }, "tags": { "type": "string", - "description": "Add tags to the library." + "description": "Add tags to the library (used for linting)." }, "skipFormat": { "description": "Skip formatting files.", From d2ffdb6ca361841c6117eed0df2cd7d59b0d3bca Mon Sep 17 00:00:00 2001 From: AgentEnder Date: Wed, 5 Apr 2023 14:30:52 -0400 Subject: [PATCH 3/3] chore(misc): apply review feedback to clean up findMatchingProjects --- docs/generated/cli/run-many.md | 2 +- .../angular/generators/application.json | 2 +- .../packages/nx/documents/run-many.md | 2 +- .../react/generators/application.json | 2 +- .../packages/web/generators/application.json | 2 +- .../recipes/generators/generator-options.md | 2 +- packages/nx/src/command-line/examples.ts | 2 +- .../implicit-project-dependencies.ts | 4 +- .../implict-project-dependencies.spec.ts | 16 +- .../build-nodes/workspace-projects.ts | 16 +- .../nx/src/utils/assert-workspace-validity.ts | 6 +- .../src/utils/find-matching-projects.spec.ts | 7 +- .../nx/src/utils/find-matching-projects.ts | 169 ++++++++++++------ 13 files changed, 147 insertions(+), 85 deletions(-) diff --git a/docs/generated/cli/run-many.md b/docs/generated/cli/run-many.md index b9e5a21bf53e8..91620395d8bac 100644 --- a/docs/generated/cli/run-many.md +++ b/docs/generated/cli/run-many.md @@ -47,7 +47,7 @@ Test all projects ending with `*-app` except `excluded-app`. Note: your shell ma nx run-many --target=test --projects=*-app --exclude=excluded-app ``` -Test all projects with tags starting with `api-*`. Note: your shell may require you to escape the `*` like this: `\*`: +Test all projects with tags starting with `api-`. Note: your shell may require you to escape the `*` like this: `\*`: ```shell nx run-many --target=test --projects=tag:api-* diff --git a/docs/generated/packages/angular/generators/application.json b/docs/generated/packages/angular/generators/application.json index ddc27ec116055..549762f8b30d0 100644 --- a/docs/generated/packages/angular/generators/application.json +++ b/docs/generated/packages/angular/generators/application.json @@ -165,7 +165,7 @@ }, "additionalProperties": false, "required": ["name"], - "examplesFile": "## Examples\n\n{% tabs %}\n{% tab label=\"Simple Application\" %}\n\nCreate an application named `my-app`:\n\n```bash\nnx g @nrwl/angular:application my-app\n```\n\n{% /tab %}\n\n{% tab label=\"Specify directory and style extension\" %}\n\nCreate an application named `my-app` in the `my-dir` directory and use `scss` for styles:\n\n```bash\nnx g @nrwl/angular:app my-app --directory=my-dir --style=scss\n```\n\n{% /tab %}\n\n{% tab label=\"Single File Components application\" %}\n\nCreate an application with Single File Components (inline styles and inline templates):\n\n```bash\nnx g @nrwl/angular:app my-app --inlineStyle --inlineTemplate\n```\n\n{% /tab %}\n\n{% tab label=\"Standalone Components application\" %}\n\nCreate an application that is setup to use standalone components:\n\n```bash\nnx g @nrwl/angular:app my-app --standalone\n```\n\n{% /tab %}\n\n{% tab label=\"Set custom prefix and tags\" %}\n\nSet the prefix to apply to generated selectors and add tags to the application.\n\n```bash\nnx g @nrwl/angular:app my-app --prefix=admin --tags=scope:admin,type:ui\n```\n\n{% /tab %}\n{% /tabs %}\n", + "examplesFile": "## Examples\n\n{% tabs %}\n{% tab label=\"Simple Application\" %}\n\nCreate an application named `my-app`:\n\n```bash\nnx g @nrwl/angular:application my-app\n```\n\n{% /tab %}\n\n{% tab label=\"Specify directory and style extension\" %}\n\nCreate an application named `my-app` in the `my-dir` directory and use `scss` for styles:\n\n```bash\nnx g @nrwl/angular:app my-app --directory=my-dir --style=scss\n```\n\n{% /tab %}\n\n{% tab label=\"Single File Components application\" %}\n\nCreate an application with Single File Components (inline styles and inline templates):\n\n```bash\nnx g @nrwl/angular:app my-app --inlineStyle --inlineTemplate\n```\n\n{% /tab %}\n\n{% tab label=\"Standalone Components application\" %}\n\nCreate an application that is setup to use standalone components:\n\n```bash\nnx g @nrwl/angular:app my-app --standalone\n```\n\n{% /tab %}\n\n{% tab label=\"Set custom prefix and tags\" %}\n\nSet the prefix to apply to generated selectors and add tags to the application (used for linting).\n\n```bash\nnx g @nrwl/angular:app my-app --prefix=admin --tags=scope:admin,type:ui\n```\n\n{% /tab %}\n{% /tabs %}\n", "presets": [] }, "aliases": ["app"], diff --git a/docs/generated/packages/nx/documents/run-many.md b/docs/generated/packages/nx/documents/run-many.md index b9e5a21bf53e8..91620395d8bac 100644 --- a/docs/generated/packages/nx/documents/run-many.md +++ b/docs/generated/packages/nx/documents/run-many.md @@ -47,7 +47,7 @@ Test all projects ending with `*-app` except `excluded-app`. Note: your shell ma nx run-many --target=test --projects=*-app --exclude=excluded-app ``` -Test all projects with tags starting with `api-*`. Note: your shell may require you to escape the `*` like this: `\*`: +Test all projects with tags starting with `api-`. Note: your shell may require you to escape the `*` like this: `\*`: ```shell nx run-many --target=test --projects=tag:api-* diff --git a/docs/generated/packages/react/generators/application.json b/docs/generated/packages/react/generators/application.json index e58345ab6d24c..c9813e4946715 100644 --- a/docs/generated/packages/react/generators/application.json +++ b/docs/generated/packages/react/generators/application.json @@ -192,7 +192,7 @@ } }, "required": [], - "examplesFile": "## Examples\n\n{% tabs %}\n{% tab label=\"Simple Application\" %}\n\nCreate an application named `my-app`:\n\n```bash\nnx g @nrwl/react:application my-app\n```\n\n{% /tab %}\n\n{% tab label=\"Application using Vite as bundler\" %}\n\nCreate an application named `my-app`:\n\n```bash\nnx g @nrwl/react:app my-app --bundler=vite\n```\n\n{% /tab %}\n\n{% tab label=\"Specify directory and style extension\" %}\n\nCreate an application named `my-app` in the `my-dir` directory and use `scss` for styles:\n\n```bash\nnx g @nrwl/react:app my-app --directory=my-dir --style=scss\n```\n\n{% /tab %}\n\n{% tab label=\"Add tags\" %}\n\nAdd tags to the application.\n\n```bash\nnx g @nrwl/react:app my-app --tags=scope:admin,type:ui\n```\n\n{% /tab %}\n{% /tabs %}\n", + "examplesFile": "## Examples\n\n{% tabs %}\n{% tab label=\"Simple Application\" %}\n\nCreate an application named `my-app`:\n\n```bash\nnx g @nrwl/react:application my-app\n```\n\n{% /tab %}\n\n{% tab label=\"Application using Vite as bundler\" %}\n\nCreate an application named `my-app`:\n\n```bash\nnx g @nrwl/react:app my-app --bundler=vite\n```\n\n{% /tab %}\n\n{% tab label=\"Specify directory and style extension\" %}\n\nCreate an application named `my-app` in the `my-dir` directory and use `scss` for styles:\n\n```bash\nnx g @nrwl/react:app my-app --directory=my-dir --style=scss\n```\n\n{% /tab %}\n\n{% tab label=\"Add tags\" %}\n\nAdd tags to the application (used for linting).\n\n```bash\nnx g @nrwl/react:app my-app --tags=scope:admin,type:ui\n```\n\n{% /tab %}\n{% /tabs %}\n", "presets": [] }, "aliases": ["app"], diff --git a/docs/generated/packages/web/generators/application.json b/docs/generated/packages/web/generators/application.json index 490f73fe8e317..5b2bc487bbd4e 100644 --- a/docs/generated/packages/web/generators/application.json +++ b/docs/generated/packages/web/generators/application.json @@ -104,7 +104,7 @@ } }, "required": ["name"], - "examplesFile": "## Examples\n\n{% tabs %}\n{% tab label=\"Simple Application\" %}\n\nCreate an application named `my-app`:\n\n```bash\nnx g @nrwl/web:application my-app\n```\n\n{% /tab %}\n\n{% tab label=\"Application using Vite as bundler\" %}\n\nCreate an application named `my-app`:\n\n```bash\nnx g @nrwl/web:app my-app --bundler=vite\n```\n\n{% /tab %}\n\n{% tab label=\"Specify directory\" %}\n\nCreate an application named `my-app` in the `my-dir` directory:\n\n```bash\nnx g @nrwl/web:app my-app --directory=my-dir\n```\n\n{% /tab %}\n\n{% tab label=\"Add tags\" %}\n\nAdd tags to the application.\n\n```bash\nnx g @nrwl/web:app my-app --tags=scope:admin,type:ui\n```\n\n{% /tab %}\n{% /tabs %}\n", + "examplesFile": "## Examples\n\n{% tabs %}\n{% tab label=\"Simple Application\" %}\n\nCreate an application named `my-app`:\n\n```bash\nnx g @nrwl/web:application my-app\n```\n\n{% /tab %}\n\n{% tab label=\"Application using Vite as bundler\" %}\n\nCreate an application named `my-app`:\n\n```bash\nnx g @nrwl/web:app my-app --bundler=vite\n```\n\n{% /tab %}\n\n{% tab label=\"Specify directory\" %}\n\nCreate an application named `my-app` in the `my-dir` directory:\n\n```bash\nnx g @nrwl/web:app my-app --directory=my-dir\n```\n\n{% /tab %}\n\n{% tab label=\"Add tags\" %}\n\nAdd tags to the application (used for linting).\n\n```bash\nnx g @nrwl/web:app my-app --tags=scope:admin,type:ui\n```\n\n{% /tab %}\n{% /tabs %}\n", "presets": [] }, "aliases": ["app"], diff --git a/docs/shared/recipes/generators/generator-options.md b/docs/shared/recipes/generators/generator-options.md index 29c6ba95a6f9c..09d0df483a5c3 100644 --- a/docs/shared/recipes/generators/generator-options.md +++ b/docs/shared/recipes/generators/generator-options.md @@ -533,7 +533,7 @@ The alias of this property. Example: { "tags": { "type": "string", - "description": "Add tags to the project", + "description": "Add tags to the project (used for linting)", "alias": "t" }, "directory": { diff --git a/packages/nx/src/command-line/examples.ts b/packages/nx/src/command-line/examples.ts index 9cf5538abb250..68977fc89d460 100644 --- a/packages/nx/src/command-line/examples.ts +++ b/packages/nx/src/command-line/examples.ts @@ -312,7 +312,7 @@ export const examples: Record = { { command: 'run-many --target=test --projects=tag:api-*', description: - 'Test all projects with tags starting with `api-*`. Note: your shell may require you to escape the `*` like this: `\\*`', + 'Test all projects with tags starting with `api-`. Note: your shell may require you to escape the `*` like this: `\\*`', }, { command: 'run-many --targets=lint,test,build --all', diff --git a/packages/nx/src/project-graph/build-dependencies/implicit-project-dependencies.ts b/packages/nx/src/project-graph/build-dependencies/implicit-project-dependencies.ts index 97e6409d725e5..371189c68f4e0 100644 --- a/packages/nx/src/project-graph/build-dependencies/implicit-project-dependencies.ts +++ b/packages/nx/src/project-graph/build-dependencies/implicit-project-dependencies.ts @@ -5,8 +5,8 @@ export function buildImplicitProjectDependencies( ctx: ProjectGraphProcessorContext, builder: ProjectGraphBuilder ) { - Object.keys(ctx.workspace.projects).forEach((source) => { - const p = ctx.workspace.projects[source]; + Object.keys(ctx.projectsConfigurations.projects).forEach((source) => { + const p = ctx.projectsConfigurations.projects[source]; if (p.implicitDependencies && p.implicitDependencies.length > 0) { p.implicitDependencies.forEach((target) => { if (target.startsWith('!')) { diff --git a/packages/nx/src/project-graph/build-dependencies/implict-project-dependencies.spec.ts b/packages/nx/src/project-graph/build-dependencies/implict-project-dependencies.spec.ts index a63f2a9aa8cfa..c93cb5166a85e 100644 --- a/packages/nx/src/project-graph/build-dependencies/implict-project-dependencies.spec.ts +++ b/packages/nx/src/project-graph/build-dependencies/implict-project-dependencies.spec.ts @@ -8,8 +8,6 @@ jest.mock('nx/src/utils/workspace-root', () => ({ })); describe('explicit project dependencies', () => { - let ctx: ProjectGraphProcessorContext; - it(`should add implicit deps`, () => { const builder = new ProjectGraphBuilder(); builder.addNode({ @@ -25,12 +23,13 @@ describe('explicit project dependencies', () => { { filesToProcess: {}, fileMap: {}, - workspace: { + projectsConfigurations: { + version: 2, projects: { - proj1: { implicitDependencies: ['proj2'] }, + proj1: { root: '', implicitDependencies: ['proj2'] }, }, }, - } as any, + } as Partial as ProjectGraphProcessorContext, builder ); @@ -59,12 +58,13 @@ describe('explicit project dependencies', () => { { filesToProcess: {}, fileMap: {}, - workspace: { + projectsConfigurations: { + version: 2, projects: { - proj1: { implicitDependencies: ['!proj2'] }, + proj1: { root: '', implicitDependencies: ['!proj2'] }, }, }, - } as any, + } as Partial as ProjectGraphProcessorContext, builder ); diff --git a/packages/nx/src/project-graph/build-nodes/workspace-projects.ts b/packages/nx/src/project-graph/build-nodes/workspace-projects.ts index 595a94aa6a060..20aea0afa65f5 100644 --- a/packages/nx/src/project-graph/build-nodes/workspace-projects.ts +++ b/packages/nx/src/project-graph/build-nodes/workspace-projects.ts @@ -28,9 +28,11 @@ export async function buildWorkspaceProjectNodes( nxJson: NxJsonConfiguration ) { const toAdd = []; - const projects = Object.keys(ctx.workspace.projects); - const projectsGraph = projects.reduce((graph, project) => { - const projectConfiguration = ctx.workspace.projects[project]; + const projects = Object.keys(ctx.projectsConfigurations.projects); + + // Used for expanding implicit dependencies (e.g. `@proj/*` or `tag:foo`) + const partialProjectGraphNodes = projects.reduce((graph, project) => { + const projectConfiguration = ctx.projectsConfigurations.projects[project]; graph[project] = { name: project, type: projectConfiguration.projectType === 'library' ? 'lib' : 'app', // missing fallback to `e2e` @@ -43,7 +45,7 @@ export async function buildWorkspaceProjectNodes( }, {} as Record); for (const key of projects) { - const p = ctx.workspace.projects[key]; + const p = ctx.projectsConfigurations.projects[key]; const projectRoot = join(workspaceRoot, p.root); if (existsSync(join(projectRoot, 'package.json'))) { @@ -73,13 +75,13 @@ export async function buildWorkspaceProjectNodes( p.implicitDependencies = normalizeImplicitDependencies( key, p.implicitDependencies, - projectsGraph + partialProjectGraphNodes ); p.targets = mergePluginTargetsWithNxTargets( p.root, p.targets, - await loadNxPlugins(ctx.workspace.plugins) + await loadNxPlugins(ctx.nxJsonConfiguration.plugins) ); p.targets = normalizeProjectTargets(p, nxJson.targetDefaults, key); @@ -91,7 +93,7 @@ export async function buildWorkspaceProjectNodes( ? 'e2e' : 'app' : 'lib'; - const tags = ctx.workspace.projects?.[key]?.tags || []; + const tags = ctx.projectsConfigurations.projects?.[key]?.tags || []; toAdd.push({ name: key, diff --git a/packages/nx/src/utils/assert-workspace-validity.ts b/packages/nx/src/utils/assert-workspace-validity.ts index 7c5c947690cb5..cb57461a015ea 100644 --- a/packages/nx/src/utils/assert-workspace-validity.ts +++ b/packages/nx/src/utils/assert-workspace-validity.ts @@ -1,7 +1,7 @@ import { ProjectsConfigurations } from '../config/workspace-json-project-json'; import { NxJsonConfiguration } from '../config/nx-json'; import { findMatchingProjects } from './find-matching-projects'; -import {output} from './output'; +import { output } from './output'; import { ProjectGraphProjectNode } from '../config/project-graph'; export function assertWorkspaceValidity( @@ -9,7 +9,7 @@ export function assertWorkspaceValidity( nxJson: NxJsonConfiguration ) { const projectNames = Object.keys(projectsConfigurations.projects); - const projectsGraph = projectNames.reduce((graph, project) => { + const projectGraphNodes = projectNames.reduce((graph, project) => { const projectConfiguration = projectsConfigurations.projects[project]; graph[project] = { name: project, @@ -51,7 +51,7 @@ export function assertWorkspaceValidity( projectName, project.implicitDependencies, projects, - projectsGraph + projectGraphNodes ); return map; }, invalidImplicitDependencies); diff --git a/packages/nx/src/utils/find-matching-projects.spec.ts b/packages/nx/src/utils/find-matching-projects.spec.ts index 2794d091a06a8..ebfeb7af2c878 100644 --- a/packages/nx/src/utils/find-matching-projects.spec.ts +++ b/packages/nx/src/utils/find-matching-projects.spec.ts @@ -1,5 +1,5 @@ import { findMatchingProjects } from './find-matching-projects'; -import { type ProjectGraphProjectNode } from '../config/project-graph'; +import type { ProjectGraphProjectNode } from '../config/project-graph'; describe('findMatchingProjects', () => { let projectGraph: Record = { @@ -94,7 +94,7 @@ describe('findMatchingProjects', () => { }); it('should expand "*" for tags', () => { - expect(findMatchingProjects(['tags:*'], projectGraph)).toEqual([ + expect(findMatchingProjects(['tag:*'], projectGraph)).toEqual([ 'test-project', 'a', 'b', @@ -103,9 +103,6 @@ describe('findMatchingProjects', () => { }); it('should support negation "!" for tags', () => { - expect(findMatchingProjects(['*', 'tag:!api'], projectGraph)).toEqual([ - 'b', - ]); expect(findMatchingProjects(['*', '!tag:api'], projectGraph)).toEqual([ 'b', ]); diff --git a/packages/nx/src/utils/find-matching-projects.ts b/packages/nx/src/utils/find-matching-projects.ts index 846e8607bf92a..686762fb24aa4 100644 --- a/packages/nx/src/utils/find-matching-projects.ts +++ b/packages/nx/src/utils/find-matching-projects.ts @@ -1,8 +1,23 @@ import minimatch = require('minimatch'); -import { type ProjectGraphProjectNode } from '../config/project-graph'; +import type { ProjectGraphProjectNode } from '../config/project-graph'; const globCharacters = ['*', '|', '{', '}', '(', ')']; +const validPatternTypes = [ + 'name', // Pattern is based on the project's name + 'tag', // Pattern is based on the project's tags +] as const; +type ProjectPatternType = typeof validPatternTypes[number]; + +interface ProjectPattern { + // If true, the pattern is an exclude pattern + exclude: boolean; + // The type of pattern to match against + type: ProjectPatternType; + // The pattern to match against + value: string; +} + /** * Find matching project names given a list of potential project names or globs. * @@ -16,81 +31,72 @@ export function findMatchingProjects( | Record | Map ): string[] { - const projectObject = - projects instanceof Map ? Object.fromEntries(projects) : projects; - const projectNames = Object.keys(projectObject); - const patternObjects = patterns.map((pattern) => { - let isExclude = false; - if (pattern.startsWith('!')) { - isExclude = true; - pattern = pattern.substring(1); - } - let [value, type] = pattern.split(':').reverse(); - if (value.startsWith('!')) { - isExclude ||= true; - value = value.substring(1); - } - return { - not: isExclude, - type: type, - value, - }; - }); + const projectNames = keys(projects); + + const patternObjects: ProjectPattern[] = patterns.map((p) => + parseStringPattern(p, projects) + ); const selectedProjects: Set = new Set(); const excludedProjects: Set = new Set(); - for (const patternObject of patternObjects) { - if (patternObject.value === '*') { - projectNames.every((projectName) => - (patternObject.not ? excludedProjects : selectedProjects).add( - projectName - ) - ); - if (patternObjects.length === 1) continue; + for (const pattern of patternObjects) { + // Handle wildcard with short-circuit, as its a common case with potentially + // large project sets and we can avoid the more expensive glob matching. + if (pattern.value === '*') { + for (const projectName of projectNames) { + if (pattern.exclude) { + excludedProjects.add(projectName); + } else { + selectedProjects.add(projectName); + } + } + continue; } - if (patternObject.type === 'tag') { + if (pattern.type === 'tag') { for (const projectName of projectNames) { - const tags = projectObject[projectName].data.tags || []; + const tags = + getItemInMapOrRecord(projects, projectName).data.tags || []; - if (tags.includes(patternObject.value)) { - (patternObject.not ? excludedProjects : selectedProjects).add( + if (tags.includes(pattern.value)) { + (pattern.exclude ? excludedProjects : selectedProjects).add( projectName ); continue; } - if (!globCharacters.some((c) => patternObject.value.includes(c))) { + if (!globCharacters.some((c) => pattern.value.includes(c))) { continue; } - if (minimatch.match(tags, patternObject.value).length) - (patternObject.not ? excludedProjects : selectedProjects).add( + if (minimatch.match(tags, pattern.value).length) + (pattern.exclude ? excludedProjects : selectedProjects).add( projectName ); } continue; - } + } else if (pattern.type === 'name') { + if (hasKey(projects, pattern.value)) { + (pattern.exclude ? excludedProjects : selectedProjects).add( + pattern.value + ); + continue; + } - if (projectNames.includes(patternObject.value)) { - (patternObject.not ? excludedProjects : selectedProjects).add( - patternObject.value - ); - continue; - } + if (!globCharacters.some((c) => pattern.value.includes(c))) { + continue; + } - if (!globCharacters.some((c) => patternObject.value.includes(c))) { - continue; + const matchedProjectNames = minimatch.match(projectNames, pattern.value); + for (const projectName of matchedProjectNames) { + if (pattern.exclude) { + excludedProjects.add(projectName); + } else { + selectedProjects.add(projectName); + } + } } - - const matchedProjectNames = minimatch.match( - projectNames, - patternObject.value - ); - matchedProjectNames.every((projectName) => - (patternObject.not ? excludedProjects : selectedProjects).add(projectName) - ); } for (const project of excludedProjects) { @@ -99,3 +105,60 @@ export function findMatchingProjects( return Array.from(selectedProjects); } + +function keys( + object: Record | Map +): string[] { + return object instanceof Map ? [...object.keys()] : Object.keys(object); +} + +function hasKey( + object: Record | Map, + key: string +) { + return object instanceof Map ? object.has(key) : key in object; +} + +function getItemInMapOrRecord( + object: Record | Map, + key: string +): T { + return object instanceof Map ? object.get(key) : object[key]; +} + +function parseStringPattern( + pattern: string, + projects: + | Map + | Record +): ProjectPattern { + let type: ProjectPatternType; + let value: string; + const isExclude = pattern.startsWith('!'); + + // Support for things like: `!{type}:value` + if (isExclude) { + pattern = pattern.substring(1); + } + + const indexOfFirstPotentialSeparator = pattern.indexOf(':'); + if (indexOfFirstPotentialSeparator === -1 || hasKey(projects, pattern)) { + type = 'name'; + value = pattern; + } else { + const potentialType = pattern.substring(0, indexOfFirstPotentialSeparator); + if (isValidPatternType(potentialType)) { + type = potentialType; + value = pattern.substring(indexOfFirstPotentialSeparator + 1); + } else { + type = 'name'; + value = pattern; + } + } + + return { type, value, exclude: isExclude }; +} + +function isValidPatternType(type: string): type is ProjectPatternType { + return validPatternTypes.includes(type as ProjectPatternType); +}