Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(gradle): track childProjects in properties report #27488

Merged
merged 1 commit into from
Aug 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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,
};
}