From a9b1fe82ed0717b3871751dd6edb82fb12f3c968 Mon Sep 17 00:00:00 2001 From: Jack Hsu Date: Tue, 27 Feb 2024 16:14:59 -0500 Subject: [PATCH] feat(core): provide a hint when project.json has empty targets --- .../__snapshots__/application.spec.ts.snap | 1 + .../utils/project-configuration.spec.ts | 77 ++++++++++++++++++- .../generators/utils/project-configuration.ts | 25 +++++- .../utils/project-configuration-utils.ts | 3 + 4 files changed, 102 insertions(+), 4 deletions(-) diff --git a/packages/nuxt/src/generators/application/__snapshots__/application.spec.ts.snap b/packages/nuxt/src/generators/application/__snapshots__/application.spec.ts.snap index 9d170b344c436..b1880793f872c 100644 --- a/packages/nuxt/src/generators/application/__snapshots__/application.spec.ts.snap +++ b/packages/nuxt/src/generators/application/__snapshots__/application.spec.ts.snap @@ -62,6 +62,7 @@ exports[`app generated files content - as-provided general application should co "$schema": "../node_modules/nx/schemas/project-schema.json", "projectType": "application", "sourceRoot": "my-app/src", + "// targets": "to see all targets run: nx show project my-app --web", "targets": {} } " diff --git a/packages/nx/src/generators/utils/project-configuration.spec.ts b/packages/nx/src/generators/utils/project-configuration.spec.ts index 90e2908904dc6..4b663db33f2b2 100644 --- a/packages/nx/src/generators/utils/project-configuration.spec.ts +++ b/packages/nx/src/generators/utils/project-configuration.spec.ts @@ -21,7 +21,6 @@ const projectConfiguration: ProjectConfiguration = { name: 'test', root: 'libs/test', sourceRoot: 'libs/test/src', - targets: {}, }; describe('project configuration', () => { @@ -32,7 +31,12 @@ describe('project configuration', () => { }); it('should create project.json file when adding a project if standalone is true', () => { - addProjectConfiguration(tree, 'test', projectConfiguration); + addProjectConfiguration(tree, 'test', { + ...projectConfiguration, + targets: { + test: {}, + }, + }); expect(readProjectConfiguration(tree, 'test')).toMatchInlineSnapshot(` { @@ -40,12 +44,79 @@ describe('project configuration', () => { "name": "test", "root": "libs/test", "sourceRoot": "libs/test/src", - "targets": {}, + "targets": { + "test": {}, + }, } `); expect(tree.exists('libs/test/project.json')).toBeTruthy(); }); + it('should add a comment to show project details when targets are missing', () => { + addProjectConfiguration(tree, 'test', { + ...projectConfiguration, + targets: {}, + }); + + expect(readProjectConfiguration(tree, 'test')).toMatchInlineSnapshot(` + { + "$schema": "../../node_modules/nx/schemas/project-schema.json", + "name": "test", + "root": "libs/test", + "sourceRoot": "libs/test/src", + "targets": {}, + } + `); + + expect(tree.read('libs/test/project.json', 'utf-8')).toMatchInlineSnapshot(` + "{ + "name": "test", + "$schema": "../../node_modules/nx/schemas/project-schema.json", + "sourceRoot": "libs/test/src", + "// targets": "to see all targets run: nx show project test --web", + "targets": {} + } + " + `); + + // Adding a target removes the "// targets" comment. + updateProjectConfiguration(tree, 'test', { + ...projectConfiguration, + targets: { + test: {}, + }, + }); + + expect(tree.read('libs/test/project.json', 'utf-8')).toMatchInlineSnapshot(` + "{ + "name": "test", + "$schema": "../../node_modules/nx/schemas/project-schema.json", + "sourceRoot": "libs/test/src", + "targets": { + "test": {} + } + } + " + `); + + // Emptying out targets add "// targets" comment back. + updateProjectConfiguration(tree, 'test', { + ...projectConfiguration, + targets: {}, + }); + + expect(tree.read('libs/test/project.json', 'utf-8')).toMatchInlineSnapshot(` + "{ + "name": "test", + "$schema": "../../node_modules/nx/schemas/project-schema.json", + "sourceRoot": "libs/test/src", + "// targets": "to see all targets run: nx show project test --web", + "targets": {} + } + " + `); + }); + it('should update project.json file when updating a project', () => { addProjectConfiguration(tree, 'test', projectConfiguration); const expectedProjectConfig = { diff --git a/packages/nx/src/generators/utils/project-configuration.ts b/packages/nx/src/generators/utils/project-configuration.ts index 7c595eb0fa72c..8a702193b22d5 100644 --- a/packages/nx/src/generators/utils/project-configuration.ts +++ b/packages/nx/src/generators/utils/project-configuration.ts @@ -64,6 +64,9 @@ export function addProjectConfiguration( } delete (projectConfiguration as any).$schema; + + handleEmptyTargets(projectName, projectConfiguration); + writeJson(tree, projectConfigFile, { name: projectName, $schema: getRelativeProjectJsonSchemaPath(tree, projectConfiguration), @@ -94,6 +97,7 @@ export function updateProjectConfiguration( `Cannot update Project ${projectName} at ${projectConfiguration.root}. It either doesn't exist yet, or may not use project.json for configuration. Use \`addProjectConfiguration()\` instead if you want to create a new project.` ); } + handleEmptyTargets(projectName, projectConfiguration); writeJson(tree, projectConfigFile, { name: projectConfiguration.name ?? projectName, $schema: getRelativeProjectJsonSchemaPath(tree, projectConfiguration), @@ -192,7 +196,7 @@ function readAndCombineAllProjectConfigurations(tree: Tree): { '**/project.json', 'project.json', ...getGlobPatternsFromPackageManagerWorkspaces(tree.root, (p) => - readJson(tree, p) + readJson(tree, p, { expectComments: true }) ), ]; const projectGlobPatterns = configurationGlobs([ @@ -328,3 +332,22 @@ function toNewFormat(w: any): ProjectsConfigurations { } return w; } + +function handleEmptyTargets( + projectName: string, + projectConfiguration: ProjectConfiguration +): void { + if ( + projectConfiguration.targets && + !Object.keys(projectConfiguration.targets).length + ) { + // Re-order `targets` to appear after the `// target` comment. + delete projectConfiguration.targets; + projectConfiguration[ + '// targets' + ] = `to see all targets run: nx show project ${projectName} --web`; + projectConfiguration.targets = {}; + } else { + delete projectConfiguration['// targets']; + } +} diff --git a/packages/nx/src/project-graph/utils/project-configuration-utils.ts b/packages/nx/src/project-graph/utils/project-configuration-utils.ts index d4562f265e32e..2de13e24e296d 100644 --- a/packages/nx/src/project-graph/utils/project-configuration-utils.ts +++ b/packages/nx/src/project-graph/utils/project-configuration-utils.ts @@ -303,6 +303,9 @@ export function readProjectConfigurationsFromRootMap( const errors: Map = new Map(); for (const [root, configuration] of projectRootMap.entries()) { + // We're setting `// targets` as a comment `targets` is empty due to Project Crystal. + // Strip it before returning configuration for usage. + if (configuration['// targets']) delete configuration['// targets']; if (!configuration.name) { try { const { name } = readJsonFile(join(root, 'package.json'));