feat(gradle): support composite build (#25990)

<!-- Please make sure you have read the submission guidelines before
posting an PR -->
<!--
https://github.com/nrwl/nx/blob/master/CONTRIBUTING.md#-submitting-a-pr
-->

<!-- Please make sure that your commit message follows our format -->
<!-- Example: `fix(nx): must begin with lowercase` -->

## Current Behavior
<!-- This is the behavior we have today -->

## Expected Behavior
![Workspace Project Graph
(2)](https://github.com/nrwl/nx/assets/16211801/9776a642-16c6-45ee-a253-cfc4b86a12a8)



## Related Issue(s)
<!-- Please link the issue being fixed so it gets closed when this is
merged. -->

Fixes #
This commit is contained in:
Emily Xiong 2024-06-24 13:05:32 -07:00 committed by GitHub
parent 3b2c42a8a5
commit 0e7e4690f2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
15 changed files with 450 additions and 70 deletions

Binary file not shown.

View File

@ -1,7 +1,6 @@
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip
networkTimeout=10000 validateDistributionUrl=false
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists

View File

@ -53,7 +53,7 @@ describe('Gradle', () => {
createFile( createFile(
`app2/build.gradle`, `app2/build.gradle`,
`plugins { `plugins {
id 'gradleProject.groovy-application-conventions' id 'buildlogic.groovy-application-conventions'
} }
dependencies { dependencies {
@ -64,7 +64,7 @@ dependencies {
createFile( createFile(
`app2/build.gradle.kts`, `app2/build.gradle.kts`,
`plugins { `plugins {
id("gradleProject.kotlin-library-conventions") id("buildlogic.kotlin-application-conventions")
} }
dependencies { dependencies {

View File

@ -1,4 +1,11 @@
{ {
"generators": {}, "generators": {
"add-project-report-all": {
"version": "19.4.0-beta.1",
"cli": "nx",
"description": "Add task projectReportAll to build.gradle file",
"factory": "./src/migrations/19-4-0/add-project-report-all"
}
},
"packageJsonUpdates": {} "packageJsonUpdates": {}
} }

View File

@ -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);
});

View File

@ -2,6 +2,7 @@ import {
addDependenciesToPackageJson, addDependenciesToPackageJson,
formatFiles, formatFiles,
GeneratorCallback, GeneratorCallback,
globAsync,
logger, logger,
readNxJson, readNxJson,
runTasksInSerial, runTasksInSerial,
@ -12,6 +13,7 @@ import { execSync } from 'child_process';
import { nxVersion } from '../../utils/versions'; import { nxVersion } from '../../utils/versions';
import { InitGeneratorSchema } from './schema'; import { InitGeneratorSchema } from './schema';
import { hasGradlePlugin } from '../../utils/has-gradle-plugin'; import { hasGradlePlugin } from '../../utils/has-gradle-plugin';
import { dirname, join, basename } from 'path';
export async function initGenerator(tree: Tree, options: InitGeneratorSchema) { export async function initGenerator(tree: Tree, options: InitGeneratorSchema) {
const tasks: GeneratorCallback[] = []; const tasks: GeneratorCallback[] = [];
@ -36,10 +38,9 @@ Running 'gradle init':`);
) )
); );
} }
await addBuildGradleFileNextToSettingsGradle(tree);
addPlugin(tree); addPlugin(tree);
updateNxJsonConfiguration(tree); updateNxJsonConfiguration(tree);
addProjectReportToBuildGradle(tree);
if (!options.skipFormat) { if (!options.skipFormat) {
await formatFiles(tree); await formatFiles(tree);
@ -66,23 +67,39 @@ 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) { export async function addBuildGradleFileNextToSettingsGradle(tree: Tree) {
let buildGradleFile: string; const settingsGradleFiles = await globAsync(tree, [
if (tree.exists('settings.gradle.kts')) { '**/settings.gradle?(.kts)',
buildGradleFile = 'build.gradle.kts'; ]);
} else if (tree.exists('settings.gradle')) { settingsGradleFiles.forEach((settingsGradleFile) => {
buildGradleFile = 'build.gradle'; 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 = 'build.gradle';
if (filename.endsWith('.kts')) {
gradleFilePath = 'build.gradle.kts';
}
gradleFilePath = join(dirname(settingsGradleFile), gradleFilePath);
let buildGradleContent = '';
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();
} }
let buildGradleContent = '';
if (tree.exists(buildGradleFile)) {
buildGradleContent = tree.read(buildGradleFile).toString();
}
if (buildGradleContent.includes('allprojects')) { if (buildGradleContent.includes('allprojects')) {
if (!buildGradleContent.includes('"project-report')) { if (!buildGradleContent.includes('"project-report"')) {
logger.warn(`Please add the project-report plugin to your ${buildGradleFile}: logger.warn(`Please add the project-report plugin to your ${gradleFilePath}:
allprojects { allprojects {
apply { apply {
plugin("project-report") plugin("project-report")
@ -95,7 +112,37 @@ allprojects {
plugin("project-report") 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);
} }
} }

View File

@ -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');
});
});

View File

@ -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);
}

View File

@ -0,0 +1,72 @@
import { join } from 'path';
import { processGradleDependencies } from './dependencies';
jest.mock('@nx/devkit', () => ({
...jest.requireActual<any>('@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',
},
]);
});
});

View File

@ -23,13 +23,13 @@ export const createDependencies: CreateDependencies = async (
return []; return [];
} }
let dependencies: RawProjectGraphDependency[] = [];
const gradleDependenciesStart = performance.mark('gradleDependencies:start'); const gradleDependenciesStart = performance.mark('gradleDependencies:start');
const { const {
gradleFileToGradleProjectMap, gradleFileToGradleProjectMap,
gradleProjectToProjectName, gradleProjectToProjectName,
buildFileToDepsMap, buildFileToDepsMap,
} = getCurrentGradleReport(); } = getCurrentGradleReport();
const dependencies: Set<RawProjectGraphDependency> = new Set();
for (const gradleFile of gradleFiles) { for (const gradleFile of gradleFiles) {
const gradleProject = gradleFileToGradleProjectMap.get(gradleFile); const gradleProject = gradleFileToGradleProjectMap.get(gradleFile);
@ -37,19 +37,17 @@ export const createDependencies: CreateDependencies = async (
const depsFile = buildFileToDepsMap.get(gradleFile); const depsFile = buildFileToDepsMap.get(gradleFile);
if (projectName && depsFile) { if (projectName && depsFile) {
dependencies = dependencies.concat( processGradleDependencies(
Array.from( depsFile,
processGradleDependencies( gradleProjectToProjectName,
depsFile, projectName,
gradleProjectToProjectName, gradleFile,
projectName, context,
gradleFile, dependencies
context
)
)
); );
} }
} }
const gradleDependenciesEnd = performance.mark('gradleDependencies:end'); const gradleDependenciesEnd = performance.mark('gradleDependencies:end');
performance.measure( performance.measure(
'gradleDependencies', 'gradleDependencies',
@ -57,7 +55,7 @@ export const createDependencies: CreateDependencies = async (
gradleDependenciesEnd.name gradleDependenciesEnd.name
); );
return dependencies; return Array.from(dependencies);
}; };
const gradleConfigFileNames = new Set(['build.gradle', 'build.gradle.kts']); const gradleConfigFileNames = new Set(['build.gradle', 'build.gradle.kts']);
@ -76,14 +74,14 @@ function findGradleFiles(fileMap: FileMap): string[] {
return gradleFiles; return gradleFiles;
} }
function processGradleDependencies( export function processGradleDependencies(
depsFile: string, depsFile: string,
gradleProjectToProjectName: Map<string, string>, gradleProjectToProjectName: Map<string, string>,
sourceProjectName: string, sourceProjectName: string,
gradleFile: string, gradleFile: string,
context: CreateDependenciesContext context: CreateDependenciesContext,
): Set<RawProjectGraphDependency> { dependencies: Set<RawProjectGraphDependency>
const dependencies: Set<RawProjectGraphDependency> = new Set(); ): void {
const lines = readFileSync(depsFile).toString().split(newLineSeparator); const lines = readFileSync(depsFile).toString().split(newLineSeparator);
let inDeps = false; let inDeps = false;
for (const line of lines) { for (const line of lines) {
@ -101,24 +99,31 @@ function processGradleDependencies(
continue; continue;
} }
const [indents, dep] = line.split('--- '); const [indents, dep] = line.split('--- ');
if ((indents === '\\' || indents === '+') && dep.startsWith('project ')) { if (indents === '\\' || indents === '+') {
const gradleProjectName = dep let gradleProjectName: string | undefined;
.substring('project '.length) if (dep.startsWith('project ')) {
.replace(/ \(n\)$/, '') gradleProjectName = dep
.trim(); .substring('project '.length)
.replace(/ \(n\)$/, '')
.trim();
} else if (dep.includes('-> project')) {
const [_, projectName] = dep.split('-> project');
gradleProjectName = projectName.trim();
}
const target = gradleProjectToProjectName.get( const target = gradleProjectToProjectName.get(
gradleProjectName gradleProjectName
) as string; ) as string;
const dependency: RawProjectGraphDependency = { if (target) {
source: sourceProjectName, const dependency: RawProjectGraphDependency = {
target, source: sourceProjectName,
type: DependencyType.static, target,
sourceFile: gradleFile, type: DependencyType.static,
}; sourceFile: gradleFile,
validateDependency(dependency, context); };
dependencies.add(dependency); validateDependency(dependency, context);
dependencies.add(dependency);
}
} }
} }
} }
return dependencies;
} }

View File

@ -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.

View File

@ -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.

View File

@ -1,6 +1,6 @@
import { readFileSync } from 'fs'; import { readFileSync } from 'fs';
import { join } from 'path'; import { join } from 'path';
import { processProjectReports, fileSeparator } from './get-gradle-report'; import { processProjectReports } from './get-gradle-report';
describe('processProjectReports', () => { describe('processProjectReports', () => {
it('should process project reports', () => { it('should process project reports', () => {

View File

@ -1,7 +1,12 @@
import { existsSync, readFileSync } from 'node:fs'; import { existsSync, readFileSync } from 'node:fs';
import { join, relative } from 'node:path'; import { join, relative } from 'node:path';
import { normalizePath, workspaceRoot } from '@nx/devkit'; import {
AggregateCreateNodesError,
logger,
normalizePath,
workspaceRoot,
} from '@nx/devkit';
import { execGradleAsync } from './exec-gradle'; import { execGradleAsync } from './exec-gradle';
import { hashWithWorkspaceContext } from 'nx/src/utils/workspace-context'; import { hashWithWorkspaceContext } from 'nx/src/utils/workspace-context';
@ -49,13 +54,38 @@ export async function populateGradleReport(
const gradleProjectReportStart = performance.mark( const gradleProjectReportStart = performance.mark(
'gradleProjectReport:start' 'gradleProjectReport:start'
); );
const projectReportLines = ( let projectReportLines;
await execGradleAsync(['projectReport'], { try {
projectReportLines = await execGradleAsync(['projectReportAll'], {
cwd: workspaceRoot, cwd: workspaceRoot,
}) });
) } catch (e) {
try {
projectReportLines = await execGradleAsync(['projectReport'], {
cwd: workspaceRoot,
});
logger.warn(
'Could not run `projectReportAll` task. Ran `projectReport` instead. Please run `nx generate @nx/gradle:init` to generate the necessary tasks.'
);
} catch (e) {
throw new AggregateCreateNodesError(
[
[
null,
new Error(
'Could not run `projectReportAll` or `projectReport` task. Please run `nx generate @nx/gradle:init` to generate the necessary tasks.'
),
],
],
[]
);
}
}
projectReportLines = projectReportLines
.toString() .toString()
.split(newLineSeparator); .split(newLineSeparator)
.filter((line) => line.trim() !== '');
const gradleProjectReportEnd = performance.mark('gradleProjectReport:end'); const gradleProjectReportEnd = performance.mark('gradleProjectReport:end');
performance.measure( performance.measure(
'gradleProjectReport', 'gradleProjectReport',
@ -72,10 +102,6 @@ export function processProjectReports(
* Map of Gradle File path to Gradle Project Name * Map of Gradle File path to Gradle Project Name
*/ */
const gradleFileToGradleProjectMap = new Map<string, string>(); const gradleFileToGradleProjectMap = new Map<string, string>();
/**
* Map of Gradle Project Name to Gradle File
*/
const gradleProjectToGradleFileMap = new Map<string, string>();
const dependenciesMap = new Map<string, string>(); const dependenciesMap = new Map<string, string>();
/** /**
* Map of Gradle Build File to tasks type map * Map of Gradle Build File to tasks type map
@ -170,7 +196,6 @@ export function processProjectReports(
gradleFileToOutputDirsMap.set(buildFile, outputDirMap); gradleFileToOutputDirsMap.set(buildFile, outputDirMap);
gradleFileToGradleProjectMap.set(buildFile, gradleProject); gradleFileToGradleProjectMap.set(buildFile, gradleProject);
gradleProjectToGradleFileMap.set(gradleProject, buildFile);
gradleProjectToProjectName.set(gradleProject, projectName); gradleProjectToProjectName.set(gradleProject, projectName);
} }
if (line.endsWith('taskReport')) { if (line.endsWith('taskReport')) {

View File

@ -84,12 +84,11 @@ export function writeMinimalNxJson(host: Tree, version: string) {
export function updateGitIgnore(host: Tree) { export function updateGitIgnore(host: Tree) {
let contents = host.read('.gitignore', 'utf-8') ?? ''; let contents = host.read('.gitignore', 'utf-8') ?? '';
if (!contents.includes('.nx/installation')) { ['.nx/installation', '.nx/cache', '.nx/workspace-data'].forEach((file) => {
contents = [contents, '.nx/installation'].join('\n'); if (!contents.includes(file)) {
} contents = [contents, file].join('\n');
if (!contents.includes('.nx/cache')) { }
contents = [contents, '.nx/cache'].join('\n'); });
}
host.write('.gitignore', contents); host.write('.gitignore', contents);
} }