diff --git a/e2e/gradle/gradle/wrapper/gradle-wrapper.jar b/e2e/gradle/gradle/wrapper/gradle-wrapper.jar index d64cd4917707c..e6441136f3d4b 100644 Binary files a/e2e/gradle/gradle/wrapper/gradle-wrapper.jar and b/e2e/gradle/gradle/wrapper/gradle-wrapper.jar differ diff --git a/e2e/gradle/gradle/wrapper/gradle-wrapper.properties b/e2e/gradle/gradle/wrapper/gradle-wrapper.properties index 1af9e0930b89b..a0777a32ceeb7 100644 --- a/e2e/gradle/gradle/wrapper/gradle-wrapper.properties +++ b/e2e/gradle/gradle/wrapper/gradle-wrapper.properties @@ -1,7 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip -networkTimeout=10000 -validateDistributionUrl=true +distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +validateDistributionUrl=false zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/e2e/gradle/src/gradle.test.ts b/e2e/gradle/src/gradle.test.ts index a40fbf4fcbb74..7625873107813 100644 --- a/e2e/gradle/src/gradle.test.ts +++ b/e2e/gradle/src/gradle.test.ts @@ -53,7 +53,7 @@ describe('Gradle', () => { createFile( `app2/build.gradle`, `plugins { - id 'gradleProject.groovy-application-conventions' + id 'buildlogic.groovy-application-conventions' } dependencies { @@ -64,7 +64,7 @@ dependencies { createFile( `app2/build.gradle.kts`, `plugins { - id("gradleProject.kotlin-library-conventions") + id("buildlogic.kotlin-application-conventions") } dependencies { diff --git a/packages/gradle/migrations.json b/packages/gradle/migrations.json index f9d34cef28c2c..2f7d00abb471a 100644 --- a/packages/gradle/migrations.json +++ b/packages/gradle/migrations.json @@ -1,4 +1,11 @@ { - "generators": {}, + "generators": { + "add-project-report-all": { + "version": "19.3.0-beta.4", + "cli": "nx", + "description": "Add task projectReportAll to build.gradle file", + "factory": "./src/migrations/19-3-0/add-project-report-all" + } + }, "packageJsonUpdates": {} } diff --git a/packages/gradle/migrations.spec.ts b/packages/gradle/migrations.spec.ts new file mode 100644 index 0000000000000..3862b363a8af7 --- /dev/null +++ b/packages/gradle/migrations.spec.ts @@ -0,0 +1,8 @@ +import json = require('./migrations.json'); + +import { assertValidMigrationPaths } from '@nx/devkit/internal-testing-utils'; +import { MigrationsJson } from '@nx/devkit'; + +describe('gradle migrations', () => { + assertValidMigrationPaths(json as MigrationsJson, __dirname); +}); diff --git a/packages/gradle/src/generators/init/init.ts b/packages/gradle/src/generators/init/init.ts index 163521f1d065a..954ded4fb5063 100644 --- a/packages/gradle/src/generators/init/init.ts +++ b/packages/gradle/src/generators/init/init.ts @@ -2,6 +2,7 @@ import { addDependenciesToPackageJson, formatFiles, GeneratorCallback, + globAsync, logger, readNxJson, runTasksInSerial, @@ -12,6 +13,7 @@ import { execSync } from 'child_process'; import { nxVersion } from '../../utils/versions'; import { InitGeneratorSchema } from './schema'; import { hasGradlePlugin } from '../../utils/has-gradle-plugin'; +import { dirname, join, basename } from 'path'; export async function initGenerator(tree: Tree, options: InitGeneratorSchema) { const tasks: GeneratorCallback[] = []; @@ -36,10 +38,9 @@ Running 'gradle init':`); ) ); } - + await addBuildGradleFileNextToSettingsGradle(tree); addPlugin(tree); updateNxJsonConfiguration(tree); - addProjectReportToBuildGradle(tree); if (!options.skipFormat) { await formatFiles(tree); @@ -66,23 +67,44 @@ function addPlugin(tree: Tree) { } /** - * This function adds the project-report plugin to the build.gradle or build.gradle.kts file + * This function creates and populate build.gradle file next to the settings.gradle file. */ -function addProjectReportToBuildGradle(tree: Tree) { - let buildGradleFile: string; - if (tree.exists('settings.gradle.kts')) { - buildGradleFile = 'build.gradle.kts'; - } else if (tree.exists('settings.gradle')) { - buildGradleFile = 'build.gradle'; - } +export async function addBuildGradleFileNextToSettingsGradle(tree: Tree) { + const settingsGradleFiles = await globAsync(tree, ['**/settings.gradle*']); + settingsGradleFiles.forEach((settingsGradleFile) => { + addProjectReportToBuildGradle(settingsGradleFile, tree); + }); +} +/** + * - creates a build.gradle file next to the settings.gradle file if it does not exist. + * - adds the project-report plugin to the build.gradle file if it does not exist. + * - adds a task to generate project reports for all subprojects and included builds. + */ +function addProjectReportToBuildGradle(settingsGradleFile: string, tree: Tree) { + const filename = basename(settingsGradleFile); + let gradleFilePath; + if (filename === 'settings.gradle.kts') { + gradleFilePath = 'build.gradle.kts'; + } else if (filename === 'settings.gradle') { + gradleFilePath = 'build.gradle'; + } else { + logger.warn( + `Could not find 'settings.gradle' or 'settings.gradle.kts' file in your gradle workspace.` + ); + return; + } + gradleFilePath = join(dirname(settingsGradleFile), gradleFilePath); let buildGradleContent = ''; - if (tree.exists(buildGradleFile)) { - buildGradleContent = tree.read(buildGradleFile).toString(); + if (!tree.exists(gradleFilePath)) { + tree.write(gradleFilePath, buildGradleContent); // create a build.gradle file near settings.gradle file if it does not exist + } else { + buildGradleContent = tree.read(gradleFilePath).toString(); } + if (buildGradleContent.includes('allprojects')) { - if (!buildGradleContent.includes('"project-report')) { - logger.warn(`Please add the project-report plugin to your ${buildGradleFile}: + if (!buildGradleContent.includes('"project-report"')) { + logger.warn(`Please add the project-report plugin to your ${gradleFilePath}: allprojects { apply { plugin("project-report") @@ -95,7 +117,37 @@ allprojects { plugin("project-report") } }`; - tree.write(buildGradleFile, buildGradleContent); + } + + if (!buildGradleContent.includes(`tasks.register("projectReportAll")`)) { + if (gradleFilePath.endsWith('.kts')) { + buildGradleContent += `\n\rtasks.register("projectReportAll") { + // All project reports of subprojects + allprojects.forEach { + dependsOn(it.tasks.get("projectReport")) + } + + // All projectReportAll of included builds + gradle.includedBuilds.forEach { + dependsOn(it.task(":projectReportAll")) + } +}`; + } else { + buildGradleContent += `\n\rtasks.register("projectReportAll") { + // All project reports of subprojects + allprojects.forEach { + dependsOn(it.tasks.getAt("projectReport")) + } + + // All projectReportAll of included builds + gradle.includedBuilds.forEach { + dependsOn(it.task(":projectReportAll")) + } + }`; + } + } + if (buildGradleContent) { + tree.write(gradleFilePath, buildGradleContent); } } diff --git a/packages/gradle/src/migrations/19-3-0/add-project-report-all.spec.ts b/packages/gradle/src/migrations/19-3-0/add-project-report-all.spec.ts new file mode 100644 index 0000000000000..2aa06608dff4d --- /dev/null +++ b/packages/gradle/src/migrations/19-3-0/add-project-report-all.spec.ts @@ -0,0 +1,28 @@ +import { createTreeWithEmptyWorkspace } from '@nx/devkit/testing'; +import { Tree } from '@nx/devkit'; + +import update from './add-project-report-all'; + +describe('AddProjectReportAll', () => { + let tree: Tree; + + beforeAll(() => { + tree = createTreeWithEmptyWorkspace(); + }); + + it('should update build.gradle', async () => { + tree.write('settings.gradle', ''); + await update(tree); + const buildGradle = tree.read('build.gradle').toString(); + expect(buildGradle).toContain('project-report'); + expect(buildGradle).toContain('projectReportAll'); + }); + + it('should update build.gradle.kts', async () => { + tree.write('settings.gradle.kts', ''); + await update(tree); + const buildGradle = tree.read('build.gradle.kts').toString(); + expect(buildGradle).toContain('project-report'); + expect(buildGradle).toContain('projectReportAll'); + }); +}); diff --git a/packages/gradle/src/migrations/19-3-0/add-project-report-all.ts b/packages/gradle/src/migrations/19-3-0/add-project-report-all.ts new file mode 100644 index 0000000000000..0d9824e95e527 --- /dev/null +++ b/packages/gradle/src/migrations/19-3-0/add-project-report-all.ts @@ -0,0 +1,9 @@ +import { Tree } from '@nx/devkit'; +import { addBuildGradleFileNextToSettingsGradle } from '../../generators/init/init'; + +/** + * This migration adds task `projectReportAll` to build.gradle files + */ +export default async function update(tree: Tree) { + await addBuildGradleFileNextToSettingsGradle(tree); +} diff --git a/packages/gradle/src/plugin/dependencies.spec.ts b/packages/gradle/src/plugin/dependencies.spec.ts new file mode 100644 index 0000000000000..f1fff883a9693 --- /dev/null +++ b/packages/gradle/src/plugin/dependencies.spec.ts @@ -0,0 +1,72 @@ +import { join } from 'path'; +import { processGradleDependencies } from './dependencies'; + +jest.mock('@nx/devkit', () => ({ + ...jest.requireActual('@nx/devkit'), + validateDependency: jest.fn().mockReturnValue(true), +})); + +describe('processGradleDependencies', () => { + it('should process gradle dependencies with composite build', () => { + const depFilePath = join( + __dirname, + '..', + 'utils/__mocks__/gradle-composite-dependencies.txt' + ); + const dependencies = new Set([]); + processGradleDependencies( + depFilePath, + new Map([ + [':my-utils:number-utils', 'number-utils'], + [':my-utils:string-utils', 'string-utils'], + ]), + 'app', + 'app', + {} as any, + dependencies + ); + expect(Array.from(dependencies)).toEqual([ + { + source: 'app', + sourceFile: 'app', + target: 'number-utils', + type: 'static', + }, + { + source: 'app', + sourceFile: 'app', + target: 'string-utils', + type: 'static', + }, + ]); + }); + + it('should process gradle dependencies with regular build', () => { + const depFilePath = join( + __dirname, + '..', + 'utils/__mocks__/gradle-dependencies.txt' + ); + const dependencies = new Set([]); + processGradleDependencies( + depFilePath, + new Map([ + [':my-utils:number-utils', 'number-utils'], + [':my-utils:string-utils', 'string-utils'], + [':utilities', 'utilities'], + ]), + 'app', + 'app', + {} as any, + dependencies + ); + expect(Array.from(dependencies)).toEqual([ + { + source: 'app', + sourceFile: 'app', + target: 'utilities', + type: 'static', + }, + ]); + }); +}); diff --git a/packages/gradle/src/plugin/dependencies.ts b/packages/gradle/src/plugin/dependencies.ts index 66f0d6a3bf76c..b07163165eb5b 100644 --- a/packages/gradle/src/plugin/dependencies.ts +++ b/packages/gradle/src/plugin/dependencies.ts @@ -23,13 +23,13 @@ export const createDependencies: CreateDependencies = async ( return []; } - let dependencies: RawProjectGraphDependency[] = []; const gradleDependenciesStart = performance.mark('gradleDependencies:start'); const { gradleFileToGradleProjectMap, gradleProjectToProjectName, buildFileToDepsMap, } = getCurrentGradleReport(); + const dependencies: Set = new Set(); for (const gradleFile of gradleFiles) { const gradleProject = gradleFileToGradleProjectMap.get(gradleFile); @@ -37,19 +37,17 @@ export const createDependencies: CreateDependencies = async ( const depsFile = buildFileToDepsMap.get(gradleFile); if (projectName && depsFile) { - dependencies = dependencies.concat( - Array.from( - processGradleDependencies( - depsFile, - gradleProjectToProjectName, - projectName, - gradleFile, - context - ) - ) + processGradleDependencies( + depsFile, + gradleProjectToProjectName, + projectName, + gradleFile, + context, + dependencies ); } } + const gradleDependenciesEnd = performance.mark('gradleDependencies:end'); performance.measure( 'gradleDependencies', @@ -57,7 +55,7 @@ export const createDependencies: CreateDependencies = async ( gradleDependenciesEnd.name ); - return dependencies; + return Array.from(dependencies); }; const gradleConfigFileNames = new Set(['build.gradle', 'build.gradle.kts']); @@ -76,14 +74,14 @@ function findGradleFiles(fileMap: FileMap): string[] { return gradleFiles; } -function processGradleDependencies( +export function processGradleDependencies( depsFile: string, gradleProjectToProjectName: Map, sourceProjectName: string, gradleFile: string, - context: CreateDependenciesContext -): Set { - const dependencies: Set = new Set(); + context: CreateDependenciesContext, + dependencies: Set +): void { const lines = readFileSync(depsFile).toString().split(newLineSeparator); let inDeps = false; for (const line of lines) { @@ -101,24 +99,31 @@ function processGradleDependencies( continue; } const [indents, dep] = line.split('--- '); - if ((indents === '\\' || indents === '+') && dep.startsWith('project ')) { - const gradleProjectName = dep - .substring('project '.length) - .replace(/ \(n\)$/, '') - .trim(); + if (indents === '\\' || indents === '+') { + let gradleProjectName: string | undefined; + if (dep.startsWith('project ')) { + gradleProjectName = dep + .substring('project '.length) + .replace(/ \(n\)$/, '') + .trim(); + } else if (dep.includes('-> project')) { + const [_, projectName] = dep.split('-> project'); + gradleProjectName = projectName.trim(); + } const target = gradleProjectToProjectName.get( gradleProjectName ) as string; - const dependency: RawProjectGraphDependency = { - source: sourceProjectName, - target, - type: DependencyType.static, - sourceFile: gradleFile, - }; - validateDependency(dependency, context); - dependencies.add(dependency); + if (target) { + const dependency: RawProjectGraphDependency = { + source: sourceProjectName, + target, + type: DependencyType.static, + sourceFile: gradleFile, + }; + validateDependency(dependency, context); + dependencies.add(dependency); + } } } } - return dependencies; } diff --git a/packages/gradle/src/utils/__mocks__/gradle-composite-dependencies.txt b/packages/gradle/src/utils/__mocks__/gradle-composite-dependencies.txt new file mode 100644 index 0000000000000..afa14f41be81f --- /dev/null +++ b/packages/gradle/src/utils/__mocks__/gradle-composite-dependencies.txt @@ -0,0 +1,60 @@ + +------------------------------------------------------------ +Project ':my-app:app' +------------------------------------------------------------ + +annotationProcessor - Annotation processors and their dependencies for source set 'main'. +No dependencies + +compileClasspath - Compile classpath for source set 'main'. ++--- org.sample:number-utils:1.0 -> project :my-utils:number-utils +\--- org.sample:string-utils:1.0 -> project :my-utils:string-utils + +compileOnly - Compile-only dependencies for the 'main' feature. (n) +No dependencies + +default - Configuration for default artifacts. (n) +No dependencies + +implementation - Implementation dependencies for the 'main' feature. (n) ++--- org.sample:number-utils:1.0 (n) +\--- org.sample:string-utils:1.0 (n) + +mainSourceElements - List of source directories contained in the Main SourceSet. (n) +No dependencies + +runtimeClasspath - Runtime classpath of source set 'main'. ++--- org.sample:number-utils:1.0 -> project :my-utils:number-utils +\--- org.sample:string-utils:1.0 -> project :my-utils:string-utils + \--- org.apache.commons:commons-lang3:3.4 + +runtimeElements - Runtime elements for the 'main' feature. (n) +No dependencies + +runtimeOnly - Runtime-only dependencies for the 'main' feature. (n) +No dependencies + +testAnnotationProcessor - Annotation processors and their dependencies for source set 'test'. +No dependencies + +testCompileClasspath - Compile classpath for source set 'test'. ++--- org.sample:number-utils:1.0 -> project :my-utils:number-utils +\--- org.sample:string-utils:1.0 -> project :my-utils:string-utils + +testCompileOnly - Compile only dependencies for source set 'test'. (n) +No dependencies + +testImplementation - Implementation only dependencies for source set 'test'. (n) +No dependencies + +testRuntimeClasspath - Runtime classpath of source set 'test'. ++--- org.sample:number-utils:1.0 -> project :my-utils:number-utils +\--- org.sample:string-utils:1.0 -> project :my-utils:string-utils + \--- org.apache.commons:commons-lang3:3.4 + +testRuntimeOnly - Runtime only dependencies for source set 'test'. (n) +No dependencies + +(n) - A dependency or dependency configuration that cannot be resolved. + +A web-based, searchable dependency report is available by adding the --scan option. diff --git a/packages/gradle/src/utils/__mocks__/gradle-dependencies.txt b/packages/gradle/src/utils/__mocks__/gradle-dependencies.txt new file mode 100644 index 0000000000000..71a48578bba3b --- /dev/null +++ b/packages/gradle/src/utils/__mocks__/gradle-dependencies.txt @@ -0,0 +1,121 @@ + +------------------------------------------------------------ +Project ':app' +------------------------------------------------------------ + +annotationProcessor - Annotation processors and their dependencies for source set 'main'. +No dependencies + +compileClasspath - Compile classpath for source set 'main'. ++--- org.apache.commons:commons-text -> 1.11.0 +| \--- org.apache.commons:commons-lang3:3.13.0 ++--- project :utilities +| \--- project :list +\--- org.apache.commons:commons-text:1.11.0 (c) + +compileOnly - Compile-only dependencies for the 'main' feature. (n) +No dependencies + +default - Configuration for default artifacts. (n) +No dependencies + +implementation - Implementation dependencies for the 'main' feature. (n) ++--- org.apache.commons:commons-text (n) +\--- project utilities (n) + +mainSourceElements - List of source directories contained in the Main SourceSet. (n) +No dependencies + +runtimeClasspath - Runtime classpath of source set 'main'. ++--- org.apache.commons:commons-text -> 1.11.0 +| \--- org.apache.commons:commons-lang3:3.13.0 ++--- project :utilities +| +--- project :list +| | \--- org.apache.commons:commons-text:1.11.0 (c) +| \--- org.apache.commons:commons-text:1.11.0 (c) +\--- org.apache.commons:commons-text:1.11.0 (c) + +runtimeElements - Runtime elements for the 'main' feature. (n) +No dependencies + +runtimeOnly - Runtime-only dependencies for the 'main' feature. (n) +No dependencies + +testAnnotationProcessor - Annotation processors and their dependencies for source set 'test'. +No dependencies + +testCompileClasspath - Compile classpath for source set 'test'. ++--- org.apache.commons:commons-text -> 1.11.0 +| \--- org.apache.commons:commons-lang3:3.13.0 ++--- project :utilities +| \--- project :list ++--- org.apache.commons:commons-text:1.11.0 (c) +\--- org.junit.jupiter:junit-jupiter:5.10.1 + +--- org.junit:junit-bom:5.10.1 + | +--- org.junit.jupiter:junit-jupiter:5.10.1 (c) + | +--- org.junit.jupiter:junit-jupiter-api:5.10.1 (c) + | +--- org.junit.jupiter:junit-jupiter-params:5.10.1 (c) + | \--- org.junit.platform:junit-platform-commons:1.10.1 (c) + +--- org.junit.jupiter:junit-jupiter-api:5.10.1 + | +--- org.junit:junit-bom:5.10.1 (*) + | +--- org.opentest4j:opentest4j:1.3.0 + | +--- org.junit.platform:junit-platform-commons:1.10.1 + | | +--- org.junit:junit-bom:5.10.1 (*) + | | \--- org.apiguardian:apiguardian-api:1.1.2 + | \--- org.apiguardian:apiguardian-api:1.1.2 + \--- org.junit.jupiter:junit-jupiter-params:5.10.1 + +--- org.junit:junit-bom:5.10.1 (*) + +--- org.junit.jupiter:junit-jupiter-api:5.10.1 (*) + \--- org.apiguardian:apiguardian-api:1.1.2 + +testCompileOnly - Compile only dependencies for source set 'test'. (n) +No dependencies + +testImplementation - Implementation only dependencies for source set 'test'. (n) +\--- org.junit.jupiter:junit-jupiter:5.10.1 (n) + +testRuntimeClasspath - Runtime classpath of source set 'test'. ++--- org.apache.commons:commons-text -> 1.11.0 +| \--- org.apache.commons:commons-lang3:3.13.0 ++--- project :utilities +| +--- project :list +| | \--- org.apache.commons:commons-text:1.11.0 (c) +| \--- org.apache.commons:commons-text:1.11.0 (c) ++--- org.apache.commons:commons-text:1.11.0 (c) ++--- org.junit.jupiter:junit-jupiter:5.10.1 +| +--- org.junit:junit-bom:5.10.1 +| | +--- org.junit.jupiter:junit-jupiter:5.10.1 (c) +| | +--- org.junit.jupiter:junit-jupiter-api:5.10.1 (c) +| | +--- org.junit.jupiter:junit-jupiter-engine:5.10.1 (c) +| | +--- org.junit.jupiter:junit-jupiter-params:5.10.1 (c) +| | +--- org.junit.platform:junit-platform-launcher:1.10.1 (c) +| | +--- org.junit.platform:junit-platform-commons:1.10.1 (c) +| | \--- org.junit.platform:junit-platform-engine:1.10.1 (c) +| +--- org.junit.jupiter:junit-jupiter-api:5.10.1 +| | +--- org.junit:junit-bom:5.10.1 (*) +| | +--- org.opentest4j:opentest4j:1.3.0 +| | \--- org.junit.platform:junit-platform-commons:1.10.1 +| | \--- org.junit:junit-bom:5.10.1 (*) +| +--- org.junit.jupiter:junit-jupiter-params:5.10.1 +| | +--- org.junit:junit-bom:5.10.1 (*) +| | \--- org.junit.jupiter:junit-jupiter-api:5.10.1 (*) +| \--- org.junit.jupiter:junit-jupiter-engine:5.10.1 +| +--- org.junit:junit-bom:5.10.1 (*) +| +--- org.junit.platform:junit-platform-engine:1.10.1 +| | +--- org.junit:junit-bom:5.10.1 (*) +| | +--- org.opentest4j:opentest4j:1.3.0 +| | \--- org.junit.platform:junit-platform-commons:1.10.1 (*) +| \--- org.junit.jupiter:junit-jupiter-api:5.10.1 (*) +\--- org.junit.platform:junit-platform-launcher -> 1.10.1 + +--- org.junit:junit-bom:5.10.1 (*) + \--- org.junit.platform:junit-platform-engine:1.10.1 (*) + +testRuntimeOnly - Runtime only dependencies for source set 'test'. (n) +\--- org.junit.platform:junit-platform-launcher (n) + +(c) - A dependency constraint, not a dependency. The dependency affected by the constraint occurs elsewhere in the tree. +(*) - Indicates repeated occurrences of a transitive dependency subtree. Gradle expands transitive dependency subtrees only once per project; repeat occurrences only display the root of the subtree, followed by this annotation. + +(n) - A dependency or dependency configuration that cannot be resolved. + +A web-based, searchable dependency report is available by adding the --scan option. diff --git a/packages/gradle/src/utils/get-gradle-report.spec.ts b/packages/gradle/src/utils/get-gradle-report.spec.ts index 9e74b15cfe500..4a23efc768df6 100644 --- a/packages/gradle/src/utils/get-gradle-report.spec.ts +++ b/packages/gradle/src/utils/get-gradle-report.spec.ts @@ -1,6 +1,6 @@ import { readFileSync } from 'fs'; import { join } from 'path'; -import { processProjectReports, fileSeparator } from './get-gradle-report'; +import { processProjectReports } from './get-gradle-report'; describe('processProjectReports', () => { it('should process project reports', () => { diff --git a/packages/gradle/src/utils/get-gradle-report.ts b/packages/gradle/src/utils/get-gradle-report.ts index c868c67f93a4d..9047e036427c5 100644 --- a/packages/gradle/src/utils/get-gradle-report.ts +++ b/packages/gradle/src/utils/get-gradle-report.ts @@ -1,7 +1,7 @@ import { existsSync, readFileSync } from 'node:fs'; import { join, relative } from 'node:path'; -import { normalizePath, workspaceRoot } from '@nx/devkit'; +import { logger, normalizePath, workspaceRoot } from '@nx/devkit'; import { execGradleAsync } from './exec-gradle'; import { hashWithWorkspaceContext } from 'nx/src/utils/workspace-context'; @@ -49,13 +49,24 @@ export async function populateGradleReport( const gradleProjectReportStart = performance.mark( 'gradleProjectReport:start' ); - const projectReportLines = ( - await execGradleAsync(['projectReport'], { + let projectReportLines; + try { + projectReportLines = await execGradleAsync(['projectReportAll'], { cwd: workspaceRoot, - }) - ) + }); + } catch (e) { + logger.warn( + 'Could not generate gradle project report when running `projectReportAll`. Please run `nx generate @nx/gradle:init` and make sure `projectReportAll` task is included in your build.gradle or build.gradle.kts.' + ); + projectReportLines = await execGradleAsync(['projectReport'], { + cwd: workspaceRoot, + }); + } + projectReportLines = projectReportLines .toString() - .split(newLineSeparator); + .split(newLineSeparator) + .filter((line) => line.trim() !== ''); + const gradleProjectReportEnd = performance.mark('gradleProjectReport:end'); performance.measure( 'gradleProjectReport', @@ -72,10 +83,6 @@ export function processProjectReports( * Map of Gradle File path to Gradle Project Name */ const gradleFileToGradleProjectMap = new Map(); - /** - * Map of Gradle Project Name to Gradle File - */ - const gradleProjectToGradleFileMap = new Map(); const dependenciesMap = new Map(); /** * Map of Gradle Build File to tasks type map @@ -170,7 +177,6 @@ export function processProjectReports( gradleFileToOutputDirsMap.set(buildFile, outputDirMap); gradleFileToGradleProjectMap.set(buildFile, gradleProject); - gradleProjectToGradleFileMap.set(gradleProject, buildFile); gradleProjectToProjectName.set(gradleProject, projectName); } if (line.endsWith('taskReport')) { diff --git a/packages/nx/src/command-line/init/implementation/dot-nx/add-nx-scripts.ts b/packages/nx/src/command-line/init/implementation/dot-nx/add-nx-scripts.ts index 7e32895630539..425c2d9b26bec 100644 --- a/packages/nx/src/command-line/init/implementation/dot-nx/add-nx-scripts.ts +++ b/packages/nx/src/command-line/init/implementation/dot-nx/add-nx-scripts.ts @@ -84,12 +84,11 @@ export function writeMinimalNxJson(host: Tree, version: string) { export function updateGitIgnore(host: Tree) { let contents = host.read('.gitignore', 'utf-8') ?? ''; - if (!contents.includes('.nx/installation')) { - contents = [contents, '.nx/installation'].join('\n'); - } - if (!contents.includes('.nx/cache')) { - contents = [contents, '.nx/cache'].join('\n'); - } + ['.nx/installation', '.nx/cache', '.nx/workspace-data'].forEach((file) => { + if (!contents.includes(file)) { + contents = [contents, file].join('\n'); + } + }); host.write('.gitignore', contents); }