From e260d147d1f1583678ec21a0c01462552aa79f80 Mon Sep 17 00:00:00 2001 From: Eric Haag Date: Wed, 12 Apr 2023 12:26:10 -0500 Subject: [PATCH 1/6] Fix typo --- .../enterprise/api/client/AuthenticationConfigurator.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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(); } From bb3b160400645e0f107c377646a44b6b318e4f8b Mon Sep 17 00:00:00 2001 From: Eric Haag Date: Wed, 12 Apr 2023 12:50:19 -0500 Subject: [PATCH 2/6] Include rootProjectName in build-scans.csv for Gradle --- .../configure-gradle-enterprise.gradle | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) 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) } From 16326f098aad51ea3af7b3b352d5bb7399b07daa Mon Sep 17 00:00:00 2001 From: Eric Haag Date: Wed, 12 Apr 2023 12:59:04 -0500 Subject: [PATCH 3/6] Include rootProjectName in build-scans.csv for Maven --- .../com/gradle/ConfigureGradleEnterprise.java | 12 ++- .../java/com/gradle/RootProjectExtractor.java | 73 +++++++++++++++++++ 2 files changed, 81 insertions(+), 4 deletions(-) create mode 100644 components/configure-gradle-enterprise-maven-extension/src/main/java/com/gradle/RootProjectExtractor.java 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..c93864e2 --- /dev/null +++ b/components/configure-gradle-enterprise-maven-extension/src/main/java/com/gradle/RootProjectExtractor.java @@ -0,0 +1,73 @@ +package com.gradle; + +import org.apache.maven.execution.ExecutionEvent; +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(ExecutionEvent event) { + return extractRootProject(event.getSession()); + } + + 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("Exception locating the top level project", e); + } + } + + // We didn't successfully identify the root project, so just return the first project. + 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()); + } + } + + /** + * Older Maven versions under-reported the list of discovered projects. + * This method discovers all their submodules. For newer Maven versions it is a no-op. + */ + 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); + } +} From e79fbbe24a90f82b10f469d3e07726fda9c9a2d7 Mon Sep 17 00:00:00 2001 From: Eric Haag Date: Wed, 12 Apr 2023 20:04:52 -0500 Subject: [PATCH 4/6] Set project name from build-scans.csv in scripts --- components/scripts/lib/build-scan-online.sh | 12 ++++++++---- components/scripts/lib/build-scan-parse.sh | 18 +++++++++++++++--- 2 files changed, 23 insertions(+), 7 deletions(-) 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..5cb49470 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,8 +100,6 @@ parse_build_scan_row() { build_scan_urls[run_num]="${field_3}" fi - build_scan_ids[run_num]="${field_4}" - if [ -z "${git_repos[run_num]}" ]; then git_repos[run_num]="${field_5}" fi @@ -112,6 +120,10 @@ 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. + + build_scan_ids[run_num]="${field_4}" remote_build_cache_urls[run_num]="${field_10}" remote_build_cache_shards[run_num]="${field_11}" From 95a8aeb42367bdfd35b372eeafe8d9a6bb60b42a Mon Sep 17 00:00:00 2001 From: Etienne Studer Date: Thu, 13 Apr 2023 14:32:00 +0200 Subject: [PATCH 5/6] Polish a bit --- .../java/com/gradle/RootProjectExtractor.java | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) 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 index c93864e2..e22a5df2 100644 --- 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 @@ -1,6 +1,5 @@ package com.gradle; -import org.apache.maven.execution.ExecutionEvent; import org.apache.maven.execution.MavenExecutionRequest; import org.apache.maven.execution.MavenSession; import org.apache.maven.model.building.ModelProcessor; @@ -16,6 +15,7 @@ import static java.util.Collections.emptyList; public class RootProjectExtractor { + private final ProjectBuilder projectBuilder; private final ModelProcessor modelProcessor; private final Logger logger; @@ -27,10 +27,6 @@ public RootProjectExtractor(ProjectBuilder projectBuilder, ModelProcessor modelP this.logger = logger; } - public MavenProject extractRootProject(ExecutionEvent event) { - return extractRootProject(event.getSession()); - } - public MavenProject extractRootProject(MavenSession session) { List allProjects = discoverAllProjects(session.getAllProjects()); File workspaceDirectory = getWorkspaceDirectory(session); @@ -44,11 +40,11 @@ public MavenProject extractRootProject(MavenSession session) { try { return projectBuilder.build(workspaceDirectoryPom, session.getProjectBuildingRequest()).getProject(); } catch (ProjectBuildingException e) { - logger.error("Exception locating the top level project", e); + logger.error("Error locating the top level project", e); } } - // We didn't successfully identify the root project, so just return the first project. + // return the first project if the top level project was not identified successfully return allProjects.get(0); } @@ -61,13 +57,10 @@ private File getWorkspaceDirectory(MavenSession session) { } } - /** - * Older Maven versions under-reported the list of discovered projects. - * This method discovers all their submodules. For newer Maven versions it is a no-op. - */ 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); } + } From 07116d09c5db8f626beb22010ee4dbbf6aeddde6 Mon Sep 17 00:00:00 2001 From: Eric Haag Date: Thu, 13 Apr 2023 12:55:38 -0500 Subject: [PATCH 6/6] Use same override logic for Build Scan IDs as Build Scan URLs --- components/scripts/lib/build-scan-parse.sh | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/components/scripts/lib/build-scan-parse.sh b/components/scripts/lib/build-scan-parse.sh index 5cb49470..5b2442e5 100644 --- a/components/scripts/lib/build-scan-parse.sh +++ b/components/scripts/lib/build-scan-parse.sh @@ -100,6 +100,10 @@ parse_build_scan_row() { build_scan_urls[run_num]="${field_3}" fi + 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}" fi @@ -123,7 +127,6 @@ parse_build_scan_row() { # The below fields are always set by Build Scan data regardless of their # previous value and are always safe to override. - build_scan_ids[run_num]="${field_4}" remote_build_cache_urls[run_num]="${field_10}" remote_build_cache_shards[run_num]="${field_11}"