diff --git a/components/configure-gradle-enterprise-maven-extension/src/main/java/com/gradle/ConfigureGradleEnterprise.java b/components/configure-gradle-enterprise-maven-extension/src/main/java/com/gradle/ConfigureGradleEnterprise.java index 81807f76..2f48cba1 100644 --- a/components/configure-gradle-enterprise-maven-extension/src/main/java/com/gradle/ConfigureGradleEnterprise.java +++ b/components/configure-gradle-enterprise-maven-extension/src/main/java/com/gradle/ConfigureGradleEnterprise.java @@ -23,10 +23,12 @@ public class ConfigureGradleEnterprise implements GradleEnterpriseListener { private static final String EXPERIMENT_DIR = System.getProperty("com.gradle.enterprise.build-validation.expDir"); + private final RootProjectExtractor rootProjectExtractor; private final Logger logger; @Inject - public ConfigureGradleEnterprise(Logger logger) { + public ConfigureGradleEnterprise(RootProjectExtractor rootProjectExtractor, Logger logger) { + this.rootProjectExtractor = rootProjectExtractor; this.logger = logger; } @@ -46,11 +48,13 @@ public void configure(GradleEnterpriseApi api, MavenSession session) { buildScan.setAllowUntrustedServer(Boolean.parseBoolean(geAllowUntrustedServer)); } - registerBuildScanActions(buildScan); + String rootProjectName = rootProjectExtractor.extractRootProject(session).getName(); + + registerBuildScanActions(buildScan, rootProjectName); configureBuildScanPublishing(buildScan); } - private static void registerBuildScanActions(BuildScanApi buildScan) { + private static void registerBuildScanActions(BuildScanApi buildScan, String rootProjectName) { buildScan.buildFinished(buildResult -> { // communicate via error file that no GE server is set boolean omitServerUrlValidation = parseBoolean(System.getProperty("com.gradle.enterprise.build-validation.omitServerUrlValidation")); @@ -81,7 +85,7 @@ private static void registerBuildScanActions(BuildScanApi buildScan) { String baseUrl = String.format("%s://%s%s", buildScanUri.getScheme(), buildScanUri.getHost(), port); File scanFile = new File(EXPERIMENT_DIR, "build-scans.csv"); - append(scanFile, String.format("%s,%s,%s,%s\n", runNum, baseUrl, buildScanUri, buildScanId)); + append(scanFile, String.format("%s,%s,%s,%s,%s\n", runNum, rootProjectName, baseUrl, buildScanUri, buildScanId)); }); } diff --git a/components/configure-gradle-enterprise-maven-extension/src/main/java/com/gradle/RootProjectExtractor.java b/components/configure-gradle-enterprise-maven-extension/src/main/java/com/gradle/RootProjectExtractor.java new file mode 100644 index 00000000..e22a5df2 --- /dev/null +++ b/components/configure-gradle-enterprise-maven-extension/src/main/java/com/gradle/RootProjectExtractor.java @@ -0,0 +1,66 @@ +package com.gradle; + +import org.apache.maven.execution.MavenExecutionRequest; +import org.apache.maven.execution.MavenSession; +import org.apache.maven.model.building.ModelProcessor; +import org.apache.maven.project.MavenProject; +import org.apache.maven.project.ProjectBuilder; +import org.apache.maven.project.ProjectBuildingException; +import org.codehaus.plexus.logging.Logger; + +import javax.inject.Inject; +import java.io.File; +import java.util.*; + +import static java.util.Collections.emptyList; + +public class RootProjectExtractor { + + private final ProjectBuilder projectBuilder; + private final ModelProcessor modelProcessor; + private final Logger logger; + + @Inject + public RootProjectExtractor(ProjectBuilder projectBuilder, ModelProcessor modelProcessor, Logger logger) { + this.projectBuilder = projectBuilder; + this.modelProcessor = modelProcessor; + this.logger = logger; + } + + public MavenProject extractRootProject(MavenSession session) { + List allProjects = discoverAllProjects(session.getAllProjects()); + File workspaceDirectory = getWorkspaceDirectory(session); + + if (workspaceDirectory.equals(allProjects.get(0).getBasedir())) { + return allProjects.get(0); + } + + File workspaceDirectoryPom = modelProcessor.locatePom(workspaceDirectory); + if (workspaceDirectoryPom.exists()) { + try { + return projectBuilder.build(workspaceDirectoryPom, session.getProjectBuildingRequest()).getProject(); + } catch (ProjectBuildingException e) { + logger.error("Error locating the top level project", e); + } + } + + // return the first project if the top level project was not identified successfully + return allProjects.get(0); + } + + private File getWorkspaceDirectory(MavenSession session) { + MavenExecutionRequest request = session.getRequest(); + try { + return request.getMultiModuleProjectDirectory(); + } catch (NoSuchMethodError ignored) { + return new File(session.getExecutionRootDirectory()); + } + } + + private List discoverAllProjects(Collection sessionProjects) { + Set allProjects = new LinkedHashSet<>(sessionProjects); + sessionProjects.stream().flatMap(p -> Optional.ofNullable(p.getCollectedProjects()).orElse(emptyList()).stream()).forEach(allProjects::add); + return new ArrayList(allProjects); + } + +} diff --git a/components/fetch-build-scan-data-cmdline-tool/src/main/java/com/gradle/enterprise/api/client/AuthenticationConfigurator.java b/components/fetch-build-scan-data-cmdline-tool/src/main/java/com/gradle/enterprise/api/client/AuthenticationConfigurator.java index d66a9d9a..2ca8eff0 100644 --- a/components/fetch-build-scan-data-cmdline-tool/src/main/java/com/gradle/enterprise/api/client/AuthenticationConfigurator.java +++ b/components/fetch-build-scan-data-cmdline-tool/src/main/java/com/gradle/enterprise/api/client/AuthenticationConfigurator.java @@ -53,7 +53,7 @@ private static Optional lookupAccessKey(URL url, ConsoleLogger logger) { return Optional.ofNullable(accessKeysByHost.getProperty(url.getHost())); } catch (IOException e) { - logger.debug("Error whole trying to read access keys: " + e.getMessage() + ". Will try fetching build scan data without authentication."); + logger.debug("Error while trying to read access keys: " + e.getMessage() + ". Will try fetching build scan data without authentication."); logger.debug(e); return Optional.empty(); } diff --git a/components/scripts/gradle/gradle-init-scripts/configure-gradle-enterprise.gradle b/components/scripts/gradle/gradle-init-scripts/configure-gradle-enterprise.gradle index 6a868a60..57a990ac 100644 --- a/components/scripts/gradle/gradle-init-scripts/configure-gradle-enterprise.gradle +++ b/components/scripts/gradle/gradle-init-scripts/configure-gradle-enterprise.gradle @@ -94,7 +94,7 @@ if (ccudPluginVersion && isNotAtLeast(ccudPluginVersion, '1.7')) { } // register build scan listeners to capture build scan URL/id and to track publishing errors -def registerBuildScanActions = { def buildScan -> +def registerBuildScanActions = { def buildScan, def rootProjectName -> buildScan.buildScanPublished { publishedBuildScan -> // defer reading the `runNum` system property until execution time since it does not affect // the configuration of the build, and given its value changes between consecutive build invocations @@ -111,7 +111,7 @@ def registerBuildScanActions = { def buildScan -> def baseUrl = "${buildScanUri.scheme}://${buildScanUri.host}${port}" def scanFile = new File(expDir, 'build-scans.csv') - scanFile.append("${runNum},${baseUrl},${buildScanUri},${buildScanId}\n") + scanFile.append("${runNum},${rootProjectName},${baseUrl},${buildScanUri},${buildScanId}\n") } buildScan.onError { error -> @@ -212,7 +212,7 @@ if (GradleVersion.current() < GradleVersion.version('6.0')) { "or use `--gradle-enterprise-server` when running the build validation script.") } - registerBuildScanActions(buildScan) + registerBuildScanActions(buildScan, rootProject.name) configureBuildScanPublishing(buildScan) addBuildScanCustomData(buildScan) } @@ -261,7 +261,7 @@ if (GradleVersion.current() < GradleVersion.version('6.0')) { "or use `--gradle-enterprise-server` when running the build validation script.") } - registerBuildScanActions(ext.buildScan) + registerBuildScanActions(ext.buildScan, settings.rootProject.name) configureBuildScanPublishing(ext.buildScan) addBuildScanCustomData(ext.buildScan) } diff --git a/components/scripts/lib/build-scan-online.sh b/components/scripts/lib/build-scan-online.sh index 12652e69..c6ca6b06 100644 --- a/components/scripts/lib/build-scan-online.sh +++ b/components/scripts/lib/build-scan-online.sh @@ -24,10 +24,14 @@ read_build_scan_metadata() { debug "" fi - while IFS=, read -r run_num field_1 field_2 field_3; do - base_urls[$run_num]="$field_1" - build_scan_urls[$run_num]="$field_2" - build_scan_ids[$run_num]="$field_3" + local run_num project_name base_url build_scan_url build_scan_id + + # shellcheck disable=SC2034 + while IFS=, read -r run_num project_name base_url build_scan_url build_scan_id; do + project_names[$run_num]="${project_name}" + base_urls[$run_num]="${base_url}" + build_scan_urls[$run_num]="${build_scan_url}" + build_scan_ids[$run_num]="${build_scan_id}" done <<< "${build_scan_metadata}" fi } diff --git a/components/scripts/lib/build-scan-parse.sh b/components/scripts/lib/build-scan-parse.sh index 3642e0f7..5b2442e5 100644 --- a/components/scripts/lib/build-scan-parse.sh +++ b/components/scripts/lib/build-scan-parse.sh @@ -80,7 +80,17 @@ parse_build_scan_row() { while IFS=, read -r run_num field_1 field_2 field_3 field_4 field_5 field_6 field_7 field_8 field_9 field_10 field_11 field_12 field_13 field_14 field_15 field_16 field_17 field_18 field_19 field_20 field_21; do debug "Build Scan $field_4 is for build $run_num" - project_names[run_num]="${field_1}" + # The project_name should be overridden by Build Scan data if it is + # available. This is so that the project names displayed in the summary are + # consistent with what is shown in the Build Scan. + + if [ -n "${field_1}" ]; then + project_names[run_num]="${field_1}" + fi + + # If the following fields are already valued, then they should not be + # overridden by Build Scan data. For locally executed builds, this data is + # determined by the scripts as a result of execution. if [ -z "${base_urls[run_num]}" ]; then base_urls[run_num]="${field_2}" @@ -90,7 +100,9 @@ parse_build_scan_row() { build_scan_urls[run_num]="${field_3}" fi - build_scan_ids[run_num]="${field_4}" + if [ -z "${build_scan_ids[run_num]}" ]; then + build_scan_ids[run_num]="${field_4}" + fi if [ -z "${git_repos[run_num]}" ]; then git_repos[run_num]="${field_5}" @@ -112,6 +124,9 @@ parse_build_scan_row() { build_outcomes[run_num]="${field_9}" fi + # The below fields are always set by Build Scan data regardless of their + # previous value and are always safe to override. + remote_build_cache_urls[run_num]="${field_10}" remote_build_cache_shards[run_num]="${field_11}"