Skip to content

Commit

Permalink
fix(gradle): track childProjects in properties report (#27488)
Browse files Browse the repository at this point in the history
<!-- 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` -->

<!-- If this is a particularly complex change or feature addition, you
can request a dedicated Nx release for this pull request branch. Mention
someone from the Nx team or the `@nrwl/nx-pipelines-reviewers` and they
will confirm if the PR warrants its own release for testing purposes,
and generate it for you if appropriate. -->

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

## Expected Behavior
<!-- This is the behavior we should expect with the changes in this PR
-->

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

Fixes #27160

(cherry picked from commit 7c45589)
  • Loading branch information
xiongemi authored and FrozenPandaz committed Aug 21, 2024
1 parent e17b775 commit cfdf9a0
Show file tree
Hide file tree
Showing 5 changed files with 150 additions and 0 deletions.
13 changes: 13 additions & 0 deletions packages/gradle/src/plugin/dependencies.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ export const createDependencies: CreateDependencies = async (
gradleFileToGradleProjectMap,
gradleProjectToProjectName,
buildFileToDepsMap,
gradleProjectToChildProjects,
} = getCurrentGradleReport();
const dependencies: Set<RawProjectGraphDependency> = new Set();

Expand All @@ -47,6 +48,18 @@ export const createDependencies: CreateDependencies = async (
dependencies
);
}
gradleProjectToChildProjects.get(gradleProject)?.forEach((childProject) => {
if (childProject) {
const dependency: RawProjectGraphDependency = {
source: projectName as string,
target: childProject,
type: DependencyType.static,
sourceFile: gradleFile,
};
validateDependency(dependency, context);
dependencies.add(dependency);
}
});
}

const gradleDependenciesEnd = performance.mark('gradleDependencies:end');
Expand Down
3 changes: 3 additions & 0 deletions packages/gradle/src/plugin/nodes.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ describe('@nx/gradle/plugin', () => {
['proj', new Map([['test', 'Verification']])],
]),
gradleProjectToProjectName: new Map<string, string>([['proj', 'proj']]),
gradleProjectToChildProjects: new Map<string, string[]>(),
};
cwd = process.cwd();
process.chdir(tempFs.tempDir);
Expand Down Expand Up @@ -135,6 +136,7 @@ describe('@nx/gradle/plugin', () => {
['proj', new Map([['test', 'Verification']])],
]),
gradleProjectToProjectName: new Map<string, string>([['proj', 'proj']]),
gradleProjectToChildProjects: new Map<string, string[]>(),
};
await tempFs.createFiles({
'nested/nested/proj/build.gradle': ``,
Expand Down Expand Up @@ -216,6 +218,7 @@ describe('@nx/gradle/plugin', () => {
['proj', new Map([['test', 'Test']])],
]),
gradleProjectToProjectName: new Map<string, string>([['proj', 'proj']]),
gradleProjectToChildProjects: new Map<string, string[]>(),
};
await tempFs.createFiles({
'nested/nested/proj/build.gradle': ``,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@

------------------------------------------------------------
Root project 'My Application'
------------------------------------------------------------

allprojects: [root project 'My Application', project ':app', project ':mylibrary']
android.nonTransitiveRClass: true
android.useAndroidX: true
ant: org.gradle.api.internal.project.DefaultAntBuilder@ee42530
antBuilderFactory: org.gradle.api.internal.project.DefaultAntBuilderFactory@5a5e3c76
artifacts: org.gradle.api.internal.artifacts.dsl.DefaultArtifactHandler_Decorated@3793af5a
asDynamicObject: DynamicObject for root project 'My Application'
baseClassLoaderScope: org.gradle.api.internal.initialization.DefaultClassLoaderScope@4dc8adab
buildDir: /Users/emily/code/tmp/nx-android/build
buildFile: /Users/emily/code/tmp/nx-android/build.gradle
buildPath: :
buildScriptSource: org.gradle.groovy.scripts.TextResourceScriptSource@622acc87
buildTreePath: :
buildscript: org.gradle.api.internal.initialization.DefaultScriptHandler_Decorated@493cf138
childProjects: {app=project ':app', mylibrary=project ':mylibrary'}
childProjectsUnchecked: {app=project ':app', mylibrary=project ':mylibrary'}
class: class org.gradle.api.internal.project.DefaultProject_Decorated
classLoaderScope: org.gradle.api.internal.initialization.DefaultClassLoaderScope@72a593e2
components: SoftwareComponent container
configurationActions: org.gradle.configuration.project.DefaultProjectConfigurationActionContainer@63ff7e3a
configurationTargetIdentifier: org.gradle.configuration.ConfigurationTargetIdentifier$1@6b52321b
configurations: configuration container
convention: org.gradle.internal.extensibility.DefaultConvention@5f289502
conventionMapping: org.gradle.internal.extensibility.ConventionAwareHelper@71b30aee
crossProjectModelAccess: org.gradle.api.internal.project.DefaultCrossProjectModelAccess@69a5b44c
defaultTasks: []
deferredProjectConfiguration: org.gradle.api.internal.project.DeferredProjectConfiguration@131d8189
dependencies: org.gradle.api.internal.artifacts.dsl.dependencies.DefaultDependencyHandler_Decorated@806966d
dependencyFactory: org.gradle.api.internal.artifacts.DefaultDependencyFactory@618b09f9
dependencyLocking: org.gradle.internal.locking.DefaultDependencyLockingHandler_Decorated@2548d650
dependencyMetaDataProvider: org.gradle.internal.service.scopes.ProjectScopeServices$ProjectBackedModuleMetaDataProvider@5a261ab9
dependencyReport: task ':dependencyReport'
depth: 0
description: null
detachedState: false
displayName: root project 'My Application'
ext: org.gradle.internal.extensibility.DefaultExtraPropertiesExtension@66af4a6e
extensions: org.gradle.internal.extensibility.DefaultConvention@5f289502
fileOperations: org.gradle.api.internal.file.DefaultFileOperations@5f525383
fileResolver: org.gradle.api.internal.file.BaseDirFileResolver@3c4be46f
gradle: build 'My Application'
group:
htmlDependencyReport: task ':htmlDependencyReport'
identityPath: :
inheritedScope: org.gradle.internal.extensibility.ExtensibleDynamicObject$InheritedDynamicObject@5652c28d
internalStatus: property(java.lang.Object, fixed(class java.lang.String, release))
kotlin.code.style: official
kotlin.plugin.loaded.in.projects.1.9.0: :app
layout: org.gradle.api.internal.file.DefaultProjectLayout@750a8619
libs: extension 'libs'
listenerBuildOperationDecorator: org.gradle.configuration.internal.DefaultListenerBuildOperationDecorator@4233a086
logger: org.gradle.internal.logging.slf4j.OutputEventListenerBackedLogger@27ef32e
logging: org.gradle.internal.logging.services.DefaultLoggingManager@5a33f0dd
model: root project 'My Application'
modelIdentityDisplayName: null
modelRegistry: org.gradle.model.internal.registry.DefaultModelRegistry@7b289fcc
name: My Application
normalization: org.gradle.normalization.internal.DefaultInputNormalizationHandler_Decorated@244027bf
objects: org.gradle.api.internal.model.DefaultObjectFactory@5152579a
org.gradle.jvmargs: -Xmx2048m -Dfile.encoding=UTF-8
owner: root project 'My Application'
parent: null
parentIdentifier: null
path: :
pluginContext: false
pluginManager: org.gradle.api.internal.plugins.DefaultPluginManager_Decorated@14a2f075
plugins: [org.gradle.api.plugins.HelpTasksPlugin$Inject@611c939a, org.gradle.buildinit.plugins.BuildInitPlugin$Inject@2cd76269, org.gradle.buildinit.plugins.WrapperPlugin$Inject@2009557, org.gradle.api.plugins.ReportingBasePlugin$Inject@75934caa, org.gradle.api.plugins.ProjectReportsPlugin$Inject@bc7a22e]
processOperations: org.gradle.process.internal.DefaultExecActionFactory$DecoratingExecActionFactory@2bcbdbd2
project: root project 'My Application'
projectConfigurator: org.gradle.api.internal.project.BuildOperationCrossProjectConfigurator@e136ccb
projectDir: /Users/emily/code/tmp/nx-android
projectEvaluationBroadcaster: ProjectEvaluationListener broadcast
projectEvaluator: org.gradle.configuration.project.LifecycleProjectEvaluator@4d3e0414
projectPath: :
projectReport: task ':projectReport'
projectReportAll: task ':projectReportAll'
projectReportDir: /Users/emily/code/tmp/nx-android/build/reports/project
projectReportDirName: project
projects: [root project 'My Application']
properties: {...}
propertyReport: task ':propertyReport'
providers: org.gradle.api.internal.provider.DefaultProviderFactory_Decorated@4e1c649e
publicType: org.gradle.api.plugins.ProjectReportsPluginConvention
reporting: extension 'reporting'
repositories: repository container
resources: org.gradle.api.internal.resources.DefaultResourceHandler@3bfc23c4
rootDir: /Users/emily/code/tmp/nx-android
rootProject: root project 'My Application'
rootScript: false
script: false
scriptHandlerFactory: org.gradle.api.internal.initialization.DefaultScriptHandlerFactory@2e1c6544
scriptPluginFactory: org.gradle.configuration.ScriptPluginFactorySelector@133fca37
serviceRegistryFactory: org.gradle.internal.service.scopes.BuildScopeServiceRegistryFactory@3e2a745a
services: Project services
standardOutputCapture: org.gradle.internal.logging.services.DefaultLoggingManager@5a33f0dd
state: project state 'EXECUTED'
status: release
subprojects: [project ':app', project ':mylibrary']
taskDependencyFactory: org.gradle.api.internal.tasks.DefaultTaskDependencyFactory@64128258
taskReport: task ':taskReport'
taskThatOwnsThisObject: null
tasks: task set
version: unspecified
versionCatalogs: extension 'versionCatalogs'
12 changes: 12 additions & 0 deletions packages/gradle/src/utils/get-gradle-report.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,16 @@ describe('processProjectReports', () => {
Object.keys(Object.fromEntries(report.gradleProjectToTasksTypeMap))
).toEqual(['', ':app', ':list', ':utilities']);
});

it('should process properties report with child projects', () => {
const report = processProjectReports([
'> Task :propertyReport',
`See the report at: file://${__dirname}/__mocks__/gradle-properties-report-child-projects.txt`,
]);
expect(report.gradleProjectToProjectName.get('')).toEqual('My Application');
expect(report.gradleProjectToChildProjects.get('')).toEqual([
'app',
'mylibrary',
]);
});
});
13 changes: 13 additions & 0 deletions packages/gradle/src/utils/get-gradle-report.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ export interface GradleReport {
gradleFileToOutputDirsMap: Map<string, Map<string, string>>;
gradleProjectToTasksTypeMap: Map<string, Map<string, string>>;
gradleProjectToProjectName: Map<string, string>;
gradleProjectToChildProjects: Map<string, string[]>;
}

let gradleReportCache: GradleReport;
Expand Down Expand Up @@ -133,6 +134,10 @@ export function processProjectReports(
* e.g. {build.gradle.kts: { projectReportDir: '' testReportDir: '' }}
*/
const gradleFileToOutputDirsMap = new Map<string, Map<string, string>>();
/**
* Map of Gradle Project to its child projects
*/
const gradleProjectToChildProjects = new Map<string, string[]>();

let index = 0;
while (index < projectReportLines.length) {
Expand Down Expand Up @@ -182,6 +187,13 @@ export function processProjectReports(
if (line.startsWith('buildDir: ')) {
absBuildDirPath = line.substring('buildDir: '.length);
}
if (line.startsWith('childProjects: ')) {
const childProjects = line.substring('childProjects: {'.length); // remove curly braces {} around childProjects
gradleProjectToChildProjects.set(
gradleProject,
childProjects.split(',').map((c) => c.trim().split('=')[0]) // e.g. get project name from text like "app=project ':app', mylibrary=project ':mylibrary'"
);
}
if (line.includes('Dir: ')) {
const [dirName, dirPath] = line.split(': ');
const taskName = dirName.replace('Dir', '');
Expand Down Expand Up @@ -260,5 +272,6 @@ export function processProjectReports(
gradleFileToOutputDirsMap,
gradleProjectToTasksTypeMap,
gradleProjectToProjectName,
gradleProjectToChildProjects,
};
}

0 comments on commit cfdf9a0

Please sign in to comment.