diff --git a/Gradle.md b/Gradle.md index a61377b8..271e87aa 100644 --- a/Gradle.md +++ b/Gradle.md @@ -159,22 +159,6 @@ Develocity server at develocity.example.io. ./02-validate-local-build-caching-same-location.sh -i -e -s https://develocity.example.io ``` -## Running the experiments without publishing Build Scan data - -The scripts that run all builds locally can be configured to not publish any Build Scan data and instead extract the required data -right during the build to surface the state of work avoidance by passing the `-x` or `--disable-build-scan-publishing` command -line argument. - -The use of this option requires at least Java 17 to analyze the build data. The JVM version to analyze the build data is -[configurable](#specifying-the-jvm-used-to-analyze-the-build-data). You can still run the builds of the experiments with a JVM -version lower than Java 17. - -The use of this configuration option also requires a license file from Gradle Inc. to be present in the root directory of the scripts. - -```bash -./02-validate-local-build-caching-same-location.sh -i -x -``` - ## Specifying the JVM used to analyze the build data The scripts use a Java-based utility to fetch and analyze the captured build data. diff --git a/LICENSE b/LICENSE index f49a4e16..261eeb9e 100644 --- a/LICENSE +++ b/LICENSE @@ -198,4 +198,4 @@ distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and - limitations under the License. \ No newline at end of file + limitations under the License. diff --git a/Maven.md b/Maven.md index 45dbe36e..d47829db 100644 --- a/Maven.md +++ b/Maven.md @@ -157,22 +157,6 @@ Develocity server at develocity.example.io. ./01-validate-local-build-caching-same-location.sh -i -e -s https://develocity.example.io ``` -## Running the experiments without publishing Build Scan data - -The scripts that run all builds locally can be configured to not publish any Build Scan data and instead extract the required data -right during the build to surface the state of work avoidance by passing the `-x` or `--disable-build-scan-publishing` command -line argument. - -The use of this option requires at least Java 17 to analyze the build data. The JVM version to analyze the build data is -[configurable](#specifying-the-jvm-used-to-analyze-the-build-data). You can still run the builds of the experiments with a JVM -version lower than Java 17. - -The use of this configuration option also requires a license file from Gradle Inc. to be present in the root directory of the scripts. - -```bash -./01-validate-local-build-caching-same-location.sh -i -x -``` - ## Specifying the JVM used to analyze the build data The scripts use a Java-based utility to fetch and analyze the captured build data. diff --git a/NOTICE b/NOTICE new file mode 100644 index 00000000..29d3b1e0 --- /dev/null +++ b/NOTICE @@ -0,0 +1,230 @@ +The following copyright statements and licenses apply to various third party open +source software packages (or portions thereof) that are distributed with +this content in the folder titled "lib/third-party". + +TABLE OF CONTENTS +================= + +The following is a listing of the open source components detailed in this +document. This list is provided for your convenience; please read further if +you wish to review the copyright notice(s) and the full text of the license +associated with each component. + + +**SECTION 1: Apache License, V2.0** + * Google Guava + * `com.google.guava:guava` + * Google Gson + * `com.google.code.gson:gson` + * Gradle Develocity Plugin/Extension Adapters + * `com.gradle:develocity-maven-extension-adapters` + * Gradle Common Custom User Data Maven Extension + * `com.gradle:common-custom-user-data-maven-extension` + * Gson on Fire + * `io.gsonfire:gson-fire` + * Picocli + * `info.picocli:picocli` + * Square OkHttp + * `com.squareup.okhttp3:okhttp` + * `com.squareup.okhttp3:logging-interceptor` + * `com.squareup.okhttp3:okhttp-tls` + * Swagger Core - Annotations + * `io.swagger:swagger-annotations` + +**SECTION 2: Common Development and Distribution License (CDDL) v1.0 and GNU General Public License (GPL) v2 with Classpath Exception** + * JAX-RS + * `javax.ws.rs:javax.ws.rs-api` + * `javax.ws.rs:jsr311-api` + * Javax Annotations + * `javax.annotation:javax.annotation-api` + +**SECTION 3: New BSD License** + * Findbugs JSR 305 + * `com.google.code.findbugs:jsr305` + +**SECTION 4: Gradle License** + * Build Scan Summary + * `com.gradle:build-scan-summary` + +SECTION 1: Apache License, V2.0 +================================ + +Google Guava +------------ +Copyright 2024 Google, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +Google Gson +------------ +Copyright 2024 Google, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +Gradle Develocity Plugin/Extension Adapters +------------------------------------------- +Copyright 2024 Gradle, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +Gradle Common Custom User Data Maven Extension +---------------------------------------------- +Copyright 2024 Gradle, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +Gson on Fire +------------- +Copyright 2015 Julio Viera + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +Picocli +------- +Copyright 2023 Remko Popma + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License + +Square OkHttp +------------- +Copyright 2019 Square, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +Swagger Core - Annotations +--------------------------- +Copyright 2023 SmartBear Software + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +SECTION 2: Common Development and Distribution License (CDDL) v1.0 and +GNU General Public License (GPL) v2 with Classpath Exception +==================================================================================================================================== + +JAX-RS +------ +Copyright 2009 Oracle, Inc. + +Licensed under the Common Development and Distribution License (CDDL) v1.0 and GNU General Public License (GPL) v2 with Classpath Exception +See https://javaee.github.io/jsr311/LICENSE + +Javax Annotation +---------------- +Copyright 2007 Oracle, Inc. + +Licensed under the Common Development and Distribution License (CDDL) v1.0 and GNU General Public License (GPL) v2 with Classpath Exception +See https://github.com/javaee/javax.annotation/blob/master/LICENSE + +SECTION 3: New BSD License +======================================================= + +Findbugs JSR 305 +---------------- +Copyright 2005 the University of Maryland + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the +following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +SECTION 4: Gradle License +======================================================= + +Build Scan Summary +------------------ +Copyright 2024 Gradle, Inc. + +Subject to and licensed pursuant to the Gradle, Inc. Terms of Use, available at https://gradle.com/legal/terms-of-use/ (the "Gradle License"). +You may not use this library except in compliance with the Gradle License. diff --git a/build.gradle.kts b/build.gradle.kts index 58c5ce0b..36bc8811 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -29,28 +29,45 @@ repositories { includeModule("argbash", "argbash") } } + exclusiveContent { + forRepository { + maven("https://repo.gradle.org/artifactory/solutions") + } + filter { + includeModule("com.gradle", "build-scan-summary") + } + } mavenCentral() + } val isDevelopmentRelease = !hasProperty("finalRelease") val releaseVersion = releaseVersion() val releaseNotes = releaseNotes() val distributionVersion = distributionVersion() +val buildScanSummaryVersion = "1.0-2024.1" allprojects { version = releaseVersion.get() } val argbash by configurations.creating -val commonComponents by configurations.creating +val develocityComponents by configurations.creating { + attributes.attribute( + TargetJvmEnvironment.TARGET_JVM_ENVIRONMENT_ATTRIBUTE, + objects.named(TargetJvmEnvironment.STANDARD_JVM) + ) +} val mavenComponents by configurations.creating +val thirdPartyMavenComponents by configurations.creating +val develocityMavenComponents by configurations.creating dependencies { argbash("argbash:argbash:2.10.0@zip") - commonComponents(project(path = ":fetch-build-scan-data-cmdline-tool", configuration = "shadow")) + develocityComponents("com.gradle:build-scan-summary:$buildScanSummaryVersion") + develocityMavenComponents("com.gradle:gradle-enterprise-maven-extension:1.18.4") mavenComponents(project(path = ":configure-gradle-enterprise-maven-extension", configuration = "shadow")) - mavenComponents("com.gradle:gradle-enterprise-maven-extension:1.18.4") - mavenComponents("com.gradle:common-custom-user-data-maven-extension:1.13") + thirdPartyMavenComponents("com.gradle:common-custom-user-data-maven-extension:1.13") } shellcheck { @@ -58,7 +75,19 @@ shellcheck { shellcheckVersion = "v0.10.0" } -val unpackArgbash by tasks.registering(Copy::class) { +val copyDevelocityComponents by tasks.registering(Sync::class) { + from(develocityComponents) + into(project.layout.buildDirectory.dir("components/develocity")) + include("build-scan-summary-$buildScanSummaryVersion.jar") +} + +val copyThirdPartyComponents by tasks.registering(Sync::class) { + from(develocityComponents) + into(project.layout.buildDirectory.dir("components/third-party")) + exclude("build-scan-summary-$buildScanSummaryVersion.jar") +} + +val unpackArgbash by tasks.registering(Sync::class) { group = "argbash" description = "Unpacks Argbash." from(zipTree(argbash.singleFile)) { @@ -88,76 +117,110 @@ val generateBashCliParsers by tasks.registering(ApplyArgbash::class) { }) } -val copyGradleScripts by tasks.registering(Copy::class) { +val copyGradleScripts by tasks.registering(Sync::class) { group = "build" description = "Copies the Gradle source and the generated scripts to the output directory." // local variable required for configuration cache compatibility // https://docs.gradle.org/current/userguide/configuration_cache.html#config_cache:not_yet_implemented:accessing_top_level_at_execution val releaseVersion = releaseVersion + val buildScanSummaryVersion = buildScanSummaryVersion + inputs.property("project.version", releaseVersion) + inputs.property("summary.version", buildScanSummaryVersion) - from(layout.projectDirectory.file("LICENSE")) + from(layout.projectDirectory.dir("components/licenses/gradle")) + from(layout.projectDirectory.file("NOTICE")) from(layout.projectDirectory.dir("release").file("version.txt")) rename("version.txt", "VERSION") from(layout.projectDirectory.dir("components/scripts/gradle")) { exclude("gradle-init-scripts") filter { line: String -> line.replace("", releaseVersion.get()) } + filter { line: String -> line.replace("", buildScanSummaryVersion) } } from(layout.projectDirectory.dir("components/scripts/gradle")) { include("gradle-init-scripts/**") - into("lib/") + into("lib/scripts/") } from(layout.projectDirectory.dir("components/scripts")) { include("README.md") include("mapping.example") include("network.settings") - include("lib/**") - exclude("lib/cli-parsers") filter { line: String -> line.replace("", releaseVersion.get()) } + filter { line: String -> line.replace("", buildScanSummaryVersion) } + } + from(layout.projectDirectory.dir("components/scripts/lib")) { + include("**") + exclude("cli-parsers") + filter { line: String -> line.replace("", releaseVersion.get()) } + filter { line: String -> line.replace("", buildScanSummaryVersion) } + into("lib/scripts/") } from(generateBashCliParsers.map { it.outputDir.file("lib/cli-parsers/gradle") }) { - into("lib/") + into("lib/scripts/") } - from(commonComponents) { - into("lib/build-scan-clients/") + from(copyDevelocityComponents) { + into("lib/develocity/") + } + from(copyThirdPartyComponents) { + into("lib/third-party/") } into(layout.buildDirectory.dir("scripts/gradle")) } -val copyMavenScripts by tasks.registering(Copy::class) { +val copyMavenScripts by tasks.registering(Sync::class) { group = "build" description = "Copies the Maven source and the generated scripts to the output directory." // local variable required for configuration cache compatibility // https://docs.gradle.org/current/userguide/configuration_cache.html#config_cache:not_yet_implemented:accessing_top_level_at_execution val releaseVersion = releaseVersion + val buildScanSummaryVersion = buildScanSummaryVersion + inputs.property("project.version", releaseVersion) + inputs.property("summary.version", buildScanSummaryVersion) - from(layout.projectDirectory.file("LICENSE")) + from(layout.projectDirectory.dir("components/licenses/maven")) + from(layout.projectDirectory.file("NOTICE")) from(layout.projectDirectory.dir("release").file("version.txt")) rename("version.txt", "VERSION") from(layout.projectDirectory.dir("components/scripts/maven")) { filter { line: String -> line.replace("", releaseVersion.get()) } + filter { line: String -> line.replace("", buildScanSummaryVersion) } } from(layout.projectDirectory.dir("components/scripts/")) { include("README.md") include("mapping.example") include("network.settings") - include("lib/**") - exclude("lib/cli-parsers") filter { line: String -> line.replace("", releaseVersion.get()) } + filter { line: String -> line.replace("", buildScanSummaryVersion) } + } + from(layout.projectDirectory.dir("components/scripts/lib")) { + include("**") + exclude("cli-parsers") + filter { line: String -> line.replace("", releaseVersion.get()) } + filter { line: String -> line.replace("", buildScanSummaryVersion) } + into("lib/scripts/") } from(generateBashCliParsers.map { it.outputDir.file("lib/cli-parsers/maven") }) { - into("lib/") + into("lib/scripts/") + } + from(copyDevelocityComponents) { + into("lib/develocity/") + } + from(develocityMavenComponents) { + into("lib/develocity/") } - from(commonComponents) { - into("lib/build-scan-clients/") + from(copyThirdPartyComponents) { + into("lib/third-party/") + } + from(thirdPartyMavenComponents) { + into("lib/third-party/") } from(mavenComponents) { - into("lib/maven-libs/") + into("lib/scripts/maven-libs/") } into(layout.buildDirectory.dir("scripts/maven")) } @@ -206,8 +269,8 @@ val shellcheckGradleScripts by tasks.registering(Shellcheck::class) { description = "Perform quality checks on Gradle build validation scripts using Shellcheck." sourceFiles = copyGradleScripts.get().outputs.files.asFileTree.matching { include("**/*.sh") - // scripts in lib/ are checked when Shellcheck checks the top-level scripts because the top-level scripts include (source) the scripts in lib/ - exclude("lib/") + // scripts in lib/scripts/ are checked when Shellcheck checks the top-level scripts because the top-level scripts include (source) the scripts in lib/ + exclude("lib/scripts/") } // scripts in lib/ are still inputs to this task (we want shellcheck to run if they change) even though we don't include them explicitly in sourceFiles inputs.files(copyGradleScripts.get().outputs.files.asFileTree.matching { @@ -227,8 +290,8 @@ val shellcheckMavenScripts by tasks.registering(Shellcheck::class) { description = "Perform quality checks on Maven build validation scripts using Shellcheck." sourceFiles = copyMavenScripts.get().outputs.files.asFileTree.matching { include("**/*.sh") - // scripts in lib/ are checked when Shellcheck checks the top-level scripts because the top-level scripts include (source) the scripts in lib/ - exclude("lib/") + // scripts in lib/scripts/ are checked when Shellcheck checks the top-level scripts because the top-level scripts include (source) the scripts in lib/ + exclude("lib/scripts/") } // scripts in lib/ are still inputs to this task (we want shellcheck to run if they change) even though we don't include them explicitly in sourceFiles inputs.files(copyMavenScripts.get().outputs.files.asFileTree.matching { @@ -300,4 +363,4 @@ fun releaseVersion(): Provider { fun releaseNotes(): Provider { val releaseNotesFile = layout.projectDirectory.file("release/changes.md") return providers.fileContents(releaseNotesFile).asText.map { it.trim() } -} \ No newline at end of file +} diff --git a/components/fetch-build-scan-data-cmdline-tool/.openapi-generator-ignore b/components/fetch-build-scan-data-cmdline-tool/.openapi-generator-ignore deleted file mode 100644 index d70ed322..00000000 --- a/components/fetch-build-scan-data-cmdline-tool/.openapi-generator-ignore +++ /dev/null @@ -1,7 +0,0 @@ -build/generated/gradle_enterprise_api/* -build/generated/gradle_enterprise_api/.github/* -build/generated/gradle_enterprise_api/api/* -build/generated/gradle_enterprise_api/docs/* -build/generated/gradle_enterprise_api/gradle/**/* -build/generated/gradle_enterprise_api/src/main/AndroidManifest.xml -build/generated/gradle_enterprise_api/src/test/**/* diff --git a/components/fetch-build-scan-data-cmdline-tool/build.gradle.kts b/components/fetch-build-scan-data-cmdline-tool/build.gradle.kts deleted file mode 100644 index 7c0d92e0..00000000 --- a/components/fetch-build-scan-data-cmdline-tool/build.gradle.kts +++ /dev/null @@ -1,79 +0,0 @@ -@file:Suppress("UnstableApiUsage") - -plugins { - id("application") - id("java") - id("jvm-test-suite") - id("com.github.johnrengelman.shadow") version "8.1.1" - id("org.openapi.generator") version "6.5.0" -} - -description = "Application to fetch build scan data using the Gradle Enterprise Export API" - -repositories { - mavenCentral() -} - -dependencies { - implementation(platform("com.squareup.okhttp3:okhttp-bom:4.12.0")) - implementation("com.squareup.okhttp3:okhttp") - implementation("com.squareup.okhttp3:okhttp-tls") - implementation("com.squareup.okhttp3:logging-interceptor") - - implementation("io.swagger:swagger-annotations:1.6.14") - implementation("io.gsonfire:gson-fire:1.9.0") - implementation("javax.ws.rs:jsr311-api:1.1.1") - implementation("javax.ws.rs:javax.ws.rs-api:2.1.1") - - implementation("com.google.guava:guava:33.2.1-jre") - implementation("info.picocli:picocli:4.7.4") - annotationProcessor("info.picocli:picocli-codegen:4.7.4") -} - -java { - toolchain { - languageVersion.set(JavaLanguageVersion.of(8)) - vendor.set(JvmVendorSpec.AZUL) - } -} - -val test by testing.suites.getting(JvmTestSuite::class) { - useJUnitJupiter() -} - -openApiGenerate { - generatorName.set("java") - inputSpec.set("$projectDir/src/main/openapi/openapi.yaml") - outputDir.set("$buildDir/generated/gradle_enterprise_api") - ignoreFileOverride.set("$projectDir/.openapi-generator-ignore") - modelPackage.set("com.gradle.enterprise.api.model") - apiPackage.set("com.gradle.enterprise.api") - invokerPackage.set("com.gradle.enterprise.api.client") - // see https://github.com/OpenAPITools/openapi-generator/blob/master/docs/generators/java.md for a description of each configuration option - configOptions.set(mapOf( - "library" to "okhttp-gson", - "dateLibrary" to "java8", - "hideGenerationTimestamp" to "true", - "openApiNullable" to "false", - "useBeanValidation" to "false", - "disallowAdditionalPropertiesIfNotPresent" to "false", - "sourceFolder" to "" // makes IDEs like IntelliJ more reliably interpret the class packages. - )) -} - -sourceSets { - main { - java { - srcDir(tasks.openApiGenerate) - } - } -} - -tasks.withType(JavaCompile::class).configureEach { - options.compilerArgs.add("-Aproject=${project.group}/${project.name}") - options.encoding = "UTF-8" -} - -application { - mainClass.set("com.gradle.enterprise.Main") -} diff --git a/components/fetch-build-scan-data-cmdline-tool/src/main/java/com/gradle/enterprise/Main.java b/components/fetch-build-scan-data-cmdline-tool/src/main/java/com/gradle/enterprise/Main.java deleted file mode 100644 index b58b226b..00000000 --- a/components/fetch-build-scan-data-cmdline-tool/src/main/java/com/gradle/enterprise/Main.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.gradle.enterprise; - -import com.gradle.enterprise.cli.FetchBuildScanDataCommand; -import com.gradle.enterprise.cli.PrintExceptionHandler; -import picocli.CommandLine; -import picocli.CommandLine.Help.ColorScheme; - -public class Main { - public static void main(String[] args) { - ColorScheme colorScheme = CommandLine.Help.defaultColorScheme(CommandLine.Help.Ansi.AUTO); - CommandLine cmdLine = new CommandLine(new FetchBuildScanDataCommand(colorScheme)) - .setExecutionExceptionHandler(new PrintExceptionHandler()) - .setColorScheme(colorScheme); - - System.exit(cmdLine.execute(args)); - } -} 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 deleted file mode 100644 index 2ca8eff0..00000000 --- a/components/fetch-build-scan-data-cmdline-tool/src/main/java/com/gradle/enterprise/api/client/AuthenticationConfigurator.java +++ /dev/null @@ -1,122 +0,0 @@ -package com.gradle.enterprise.api.client; - -import com.google.common.base.Strings; -import com.gradle.enterprise.cli.ConsoleLogger; - -import java.io.BufferedReader; -import java.io.IOException; -import java.net.URL; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.Optional; -import java.util.Properties; - -public class AuthenticationConfigurator { - public static final class EnvVars { - public static final String ACCESS_KEY = "GRADLE_ENTERPRISE_ACCESS_KEY"; - public static final String USERNAME = "GRADLE_ENTERPRISE_USERNAME"; - public static final String PASSWORD = "GRADLE_ENTERPRISE_PASSWORD"; - public static final String GRADLE_USER_HOME = "GRADLE_USER_HOME"; - } - - private static final String MALFORMED_ENVIRONMENT_VARIABLE_ERROR = "Environment variable " + EnvVars.ACCESS_KEY - + " is malformed (expected format: 'server-host=access-key' or 'server-host1=access-key1;server-host2=access-key2')"; - - public static void configureAuth(URL url, ApiClient client, ConsoleLogger logger) { - String username = System.getenv(EnvVars.USERNAME); - String password = System.getenv(EnvVars.PASSWORD); - - if (!Strings.isNullOrEmpty(username) && !Strings.isNullOrEmpty(password)) { - client.setUsername(username); - client.setPassword(password); - logger.debug("Using basic authentication."); - } else { - Optional accessKey = lookupAccessKey(url, logger); - accessKey.ifPresent(key -> { - client.setBearerToken(key); - logger.debug("Using access key authentication."); - }); - - if (!accessKey.isPresent()) { - logger.debug("Using anonymous authentication."); - } - } - } - - private static Optional lookupAccessKey(URL url, ConsoleLogger logger) { - try { - Properties accessKeysByHost = new Properties(); - accessKeysByHost.putAll(loadMavenHomeAccessKeys()); - accessKeysByHost.putAll(loadGradleHomeAccessKeys()); - accessKeysByHost.putAll(loadFromEnvVar()); - - return Optional.ofNullable(accessKeysByHost.getProperty(url.getHost())); - } catch (IOException e) { - 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(); - } - } - - private static Properties loadGradleHomeAccessKeys() throws IOException { - Path accessKeysFile = getGradleUserHomeDirectory().resolve("enterprise/keys.properties"); - return loadAccessKeysFromFile(accessKeysFile); - } - - private static Path getGradleUserHomeDirectory() { - if (Strings.isNullOrEmpty(System.getenv(EnvVars.GRADLE_USER_HOME))) { - return Paths.get(System.getProperty("user.home"), ".gradle"); - } - return Paths.get(System.getenv(EnvVars.GRADLE_USER_HOME)); - } - - private static Properties loadMavenHomeAccessKeys() throws IOException { - Path accessKeysFile = getMavenStorageDirectory().resolve("keys.properties"); - return loadAccessKeysFromFile(accessKeysFile); - } - - private static Path getMavenStorageDirectory() { - String defaultLocation = System.getProperty("user.home") + "/.m2/.gradle-enterprise"; - return Paths.get(System.getProperty("gradle.enterprise.storage.directory", defaultLocation)); - } - - private static Properties loadAccessKeysFromFile(Path accessKeysFile) throws IOException { - Properties accessKeysByHost = new Properties(); - if (Files.isRegularFile(accessKeysFile)) { - try (BufferedReader in = Files.newBufferedReader(accessKeysFile)) { - accessKeysByHost.load(in); - } - } - return accessKeysByHost; - } - - private static Properties loadFromEnvVar() { - Properties accessKeys = new Properties(); - String value = System.getenv(EnvVars.ACCESS_KEY); - - if(Strings.isNullOrEmpty(value)) { - return accessKeys; - } - - String[] entries = value.split(";"); - for(String entry: entries) { - if(entry == null) throw new RuntimeException(MALFORMED_ENVIRONMENT_VARIABLE_ERROR); - - String[] parts = entry.split("=", 2); - if (parts.length < 2) throw new RuntimeException(MALFORMED_ENVIRONMENT_VARIABLE_ERROR); - - String joinedServers = parts[0].trim(); - String accessKey = parts[1].trim(); - - if(joinedServers.isEmpty() || Strings.isNullOrEmpty(accessKey)) throw new RuntimeException(MALFORMED_ENVIRONMENT_VARIABLE_ERROR); - for(String server: joinedServers.split(",")) { - server = server.trim(); - if (server.isEmpty()) throw new RuntimeException(MALFORMED_ENVIRONMENT_VARIABLE_ERROR); - accessKeys.put(server, accessKey); - } - } - - return accessKeys; - } -} diff --git a/components/fetch-build-scan-data-cmdline-tool/src/main/java/com/gradle/enterprise/api/client/FailedRequestException.java b/components/fetch-build-scan-data-cmdline-tool/src/main/java/com/gradle/enterprise/api/client/FailedRequestException.java deleted file mode 100644 index bdee3e3c..00000000 --- a/components/fetch-build-scan-data-cmdline-tool/src/main/java/com/gradle/enterprise/api/client/FailedRequestException.java +++ /dev/null @@ -1,39 +0,0 @@ -package com.gradle.enterprise.api.client; - -import java.net.URL; -import java.util.Optional; - -public class FailedRequestException extends RuntimeException { - - private final int httpStatusCode; - - private final String responseBody; - - public FailedRequestException(URL buildScanUrl, ApiException e) { - super(buildMessage(buildScanUrl, e.getCode()), e); - this.httpStatusCode = e.getCode(); - this.responseBody = e.getResponseBody(); - } - - public int httpStatusCode() { - return httpStatusCode; - } - - public Optional getResponseBody() { - return Optional.ofNullable(responseBody); - } - - private static String buildMessage(URL buildScanUrl, int code) { - switch (code) { - case 404: - return String.format("Build scan %s was not found.%nVerify the build scan exists and you have been " + - "granted the permission 'Access build data via the API'.", buildScanUrl); - case 401: - return String.format("Failed to authenticate while attempting to fetch build scan %s", buildScanUrl); - case 0: - return String.format("Unable to connect to server to fetch build scan %s", buildScanUrl); - default: - return String.format("Encountered an unexpected response while fetching build scan %s", buildScanUrl); - } - } -} diff --git a/components/fetch-build-scan-data-cmdline-tool/src/main/java/com/gradle/enterprise/api/client/GradleEnterpriseApiClient.java b/components/fetch-build-scan-data-cmdline-tool/src/main/java/com/gradle/enterprise/api/client/GradleEnterpriseApiClient.java deleted file mode 100644 index 4924808f..00000000 --- a/components/fetch-build-scan-data-cmdline-tool/src/main/java/com/gradle/enterprise/api/client/GradleEnterpriseApiClient.java +++ /dev/null @@ -1,340 +0,0 @@ -package com.gradle.enterprise.api.client; - -import com.gradle.enterprise.api.GradleEnterpriseApi; -import com.gradle.enterprise.api.model.Build; -import com.gradle.enterprise.api.model.BuildAttributesValue; -import com.gradle.enterprise.api.model.BuildQuery; -import com.gradle.enterprise.api.model.GradleAttributes; -import com.gradle.enterprise.api.model.GradleBuildCachePerformance; -import com.gradle.enterprise.api.model.GradleBuildCachePerformanceTaskExecutionEntry; -import com.gradle.enterprise.api.model.MavenAttributes; -import com.gradle.enterprise.api.model.MavenBuildCachePerformance; -import com.gradle.enterprise.api.model.MavenBuildCachePerformanceGoalExecutionEntry; -import com.gradle.enterprise.cli.ConsoleLogger; -import com.gradle.enterprise.model.BuildScanData; -import com.gradle.enterprise.model.CustomValueNames; -import com.gradle.enterprise.model.NumberedBuildScan; -import com.gradle.enterprise.model.TaskExecutionSummary; -import okhttp3.Credentials; -import okhttp3.OkHttpClient; -import okhttp3.tls.HandshakeCertificates; -import org.jetbrains.annotations.NotNull; - -import java.math.BigDecimal; -import java.net.MalformedURLException; -import java.net.URL; -import java.time.Duration; -import java.time.format.DateTimeParseException; -import java.util.AbstractMap; -import java.util.Arrays; -import java.util.List; -import java.util.Locale; -import java.util.Map; -import java.util.stream.Collectors; - -import static com.gradle.enterprise.api.model.GradleBuildCachePerformanceTaskExecutionEntry.AvoidanceOutcomeEnum.EXECUTED_CACHEABLE; -import static com.gradle.enterprise.api.model.GradleBuildCachePerformanceTaskExecutionEntry.AvoidanceOutcomeEnum.EXECUTED_NOT_CACHEABLE; -import static com.gradle.enterprise.api.model.GradleBuildCachePerformanceTaskExecutionEntry.NonCacheabilityCategoryEnum.DISABLED_TO_ENSURE_CORRECTNESS; -import static com.gradle.enterprise.api.model.GradleBuildCachePerformanceTaskExecutionEntry.NonCacheabilityCategoryEnum.OVERLAPPING_OUTPUTS; - -public class GradleEnterpriseApiClient { - - private static final Integer DEFAULT_AVAILABILITY_WAIT_TIMEOUT_SECS = 10; - - private final URL baseUrl; - private final GradleEnterpriseApi apiClient; - - private final CustomValueNames customValueNames; - - private final ConsoleLogger logger; - - public GradleEnterpriseApiClient(URL baseUrl, CustomValueNames customValueNames, ConsoleLogger logger) { - this.baseUrl = baseUrl; - this.customValueNames = customValueNames; - this.logger = logger; - - ApiClient client = new ApiClient(); - client.setHttpClient(configureHttpClient(client.getHttpClient())); - client.setBasePath(baseUrl.toString()); - AuthenticationConfigurator.configureAuth(baseUrl, client, logger); - - this.apiClient = new GradleEnterpriseApi(client); - } - - private OkHttpClient configureHttpClient(OkHttpClient httpClient) { - OkHttpClient.Builder httpClientBuilder = httpClient.newBuilder(); - - configureSsl(httpClientBuilder); - configureProxyAuthentication(httpClientBuilder); - configureTimeouts(httpClientBuilder); - - return httpClientBuilder.build(); - } - - private void configureSsl(OkHttpClient.Builder httpClientBuilder) { - HandshakeCertificates.Builder trustedCertsBuilder = new HandshakeCertificates.Builder() - .addPlatformTrustedCertificates(); - - if (allowUntrustedServer()) { - trustedCertsBuilder.addInsecureHost(baseUrl.getHost()); - httpClientBuilder.hostnameVerifier((hostname, session) -> baseUrl.getHost().equals(hostname)); - } - - HandshakeCertificates trustedCerts = trustedCertsBuilder.build(); - httpClientBuilder.sslSocketFactory(trustedCerts.sslSocketFactory(), trustedCerts.trustManager()); - } - - private void configureProxyAuthentication(OkHttpClient.Builder httpClientBuilder) { - httpClientBuilder - .proxyAuthenticator((route, response) -> { - if (response.code() == 407) { - String scheme = response.request().url().scheme().toLowerCase(Locale.ROOT); - String proxyUser = System.getProperty(scheme + ".proxyUser"); - String proxyPassword = System.getProperty(scheme + ".proxyPassword"); - if (proxyUser != null && proxyPassword != null) { - return response.request().newBuilder() - .header("Proxy-Authorization", Credentials.basic(proxyUser, proxyPassword)) - .build(); - } - } - return null; - }); - } - - private boolean allowUntrustedServer() { - return Boolean.parseBoolean(System.getProperty("ssl.allowUntrustedServer")); - } - - private void configureTimeouts(OkHttpClient.Builder httpClientBuilder) { - Duration connectTimeout = parseTimeout("connect.timeout"); - if (connectTimeout != null) { - httpClientBuilder.connectTimeout(connectTimeout); - } - Duration readTimeout = parseTimeout("read.timeout"); - if (readTimeout != null) { - httpClientBuilder.readTimeout(readTimeout); - } - } - - private Duration parseTimeout(String key) { - String value = System.getProperty(key); - try { - return value == null ? null : Duration.parse(value); - } catch (DateTimeParseException e) { - throw new IllegalArgumentException("The value of " + key + " (\"" + value + "\") is not a valid duration.", e); - } - } - - public BuildScanData fetchBuildScanData(NumberedBuildScan buildScan) { - int runNum = buildScan.runNum(); - String buildScanId = buildScan.buildScanId(); - try { - BuildQuery buildQuery = new BuildQuery().availabilityWaitTimeoutSecs(DEFAULT_AVAILABILITY_WAIT_TIMEOUT_SECS); - Build build = apiClient.getBuild(buildScanId, buildQuery); - - if (build.getBuildToolType().equalsIgnoreCase("gradle")) { - GradleAttributes attributes = apiClient.getGradleAttributes(buildScanId, null); - GradleBuildCachePerformance buildCachePerformance = apiClient.getGradleBuildCachePerformance(buildScanId, null); - - return new BuildScanData( - runNum, - attributes.getRootProjectName(), - buildScanId, - baseUrl, - findCustomValue(customValueNames.getGitRepositoryKey(), attributes.getValues()), - findCustomValue(customValueNames.getGitBranchKey(), attributes.getValues()), - findCustomValue(customValueNames.getGitCommitIdKey(), attributes.getValues()), - attributes.getRequestedTasks(), - buildOutcomeFrom(attributes), - remoteBuildCacheUrlFrom(buildCachePerformance), - summarizeTaskExecutions(buildCachePerformance), - buildTimeFrom(buildCachePerformance), - serializationFactorFrom(buildCachePerformance) - ); - } - if (build.getBuildToolType().equalsIgnoreCase("maven")) { - MavenAttributes attributes = apiClient.getMavenAttributes(buildScanId, null); - MavenBuildCachePerformance buildCachePerformance = apiClient.getMavenBuildCachePerformance(buildScanId, null); - - return new BuildScanData( - runNum, - attributes.getTopLevelProjectName(), - buildScanId, - baseUrl, - findCustomValue(customValueNames.getGitRepositoryKey(), attributes.getValues()), - findCustomValue(customValueNames.getGitBranchKey(), attributes.getValues()), - findCustomValue(customValueNames.getGitCommitIdKey(), attributes.getValues()), - attributes.getRequestedGoals(), - buildOutcomeFrom(attributes), - remoteBuildCacheUrlFrom(buildCachePerformance), - summarizeTaskExecutions(buildCachePerformance), - buildTimeFrom(buildCachePerformance), - serializationFactorFrom(buildCachePerformance) - ); - } - throw new RuntimeException(String.format("Build scan %s was generated by an unknown build agent: %s.", buildScan.url(), build.getBuildToolType())); - } catch (ApiException e) { - throw new FailedRequestException(buildScan.url(), e); - } - } - - private String findCustomValue(String key, List values) { - return values.stream() - .filter(v -> v.getName().equals(key)) - .map(v -> { - if (v.getValue() == null) { - return ""; - } - return v.getValue(); - }) - .findFirst() - .orElse(""); - } - - private String buildOutcomeFrom(GradleAttributes attributes) { - if(!attributes.getHasFailed()) { - return "SUCCESS"; - } - return "FAILED"; - } - - private String buildOutcomeFrom(MavenAttributes attributes) { - if(!attributes.getHasFailed()) { - return "SUCCESS"; - } - return "FAILED"; - } - - private URL remoteBuildCacheUrlFrom(GradleBuildCachePerformance buildCachePerformance) { - if (buildCachePerformance.getBuildCaches() == null || - buildCachePerformance.getBuildCaches().getRemote().getUrl() == null) { - return null; - } - - try { - return new URL(buildCachePerformance.getBuildCaches().getRemote().getUrl()); - } catch (MalformedURLException e) { - // Don't do anything on purpose. - return null; - } - } - - private URL remoteBuildCacheUrlFrom(MavenBuildCachePerformance buildCachePerformance) { - if (buildCachePerformance.getBuildCaches() == null || - buildCachePerformance.getBuildCaches().getRemote() == null || - buildCachePerformance.getBuildCaches().getRemote().getUrl() == null) { - return null; - } - - try { - return new URL(buildCachePerformance.getBuildCaches().getRemote().getUrl()); - } catch (MalformedURLException e) { - // Don't do anything on purpose. - return null; - } - } - - @NotNull - private Map summarizeTaskExecutions(GradleBuildCachePerformance buildCachePerformance) { - Map> tasksByOutcome = buildCachePerformance.getTaskExecution().stream() - .collect(Collectors.groupingBy(this::avoidanceOutcome)); - - Map summariesByOutcome = tasksByOutcome.entrySet() - .stream() - .map(GradleEnterpriseApiClient::summarizeForGradle) - .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); - - Arrays.stream(GradleBuildCachePerformanceTaskExecutionEntry.AvoidanceOutcomeEnum.values()) - .forEach(outcome -> summariesByOutcome.putIfAbsent(outcome.toString(), TaskExecutionSummary.ZERO)); - - return toTotalAvoidedFromCache(summariesByOutcome); - } - - private String avoidanceOutcome(GradleBuildCachePerformanceTaskExecutionEntry task) { - GradleBuildCachePerformanceTaskExecutionEntry.AvoidanceOutcomeEnum avoidanceOutcome = task.getAvoidanceOutcome(); - GradleBuildCachePerformanceTaskExecutionEntry.NonCacheabilityCategoryEnum nonCacheabilityCategory = task.getNonCacheabilityCategory(); - if (avoidanceOutcome == EXECUTED_NOT_CACHEABLE && (nonCacheabilityCategory == OVERLAPPING_OUTPUTS || nonCacheabilityCategory == DISABLED_TO_ENSURE_CORRECTNESS)) { - return EXECUTED_CACHEABLE.toString(); - } - return avoidanceOutcome.toString(); - } - - @NotNull - private Map summarizeTaskExecutions(MavenBuildCachePerformance buildCachePerformance) { - Map> tasksByOutcome = buildCachePerformance.getGoalExecution().stream() - .collect(Collectors.groupingBy( - t -> t.getAvoidanceOutcome().toString() - )); - - Map summariesByOutcome = tasksByOutcome.entrySet() - .stream() - .map(GradleEnterpriseApiClient::summarizeForMaven) - .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); - - Arrays.stream(MavenBuildCachePerformanceGoalExecutionEntry.AvoidanceOutcomeEnum.values()) - .forEach(outcome -> summariesByOutcome.putIfAbsent(outcome.toString(), TaskExecutionSummary.ZERO)); - - return toTotalAvoidedFromCache(summariesByOutcome); - } - - private static Map.Entry summarizeForGradle(Map.Entry> entry) { - return new AbstractMap.SimpleEntry<>(entry.getKey(), summarizeForGradle(entry.getValue())); - } - - private static TaskExecutionSummary summarizeForGradle(List tasks) { - return tasks.stream() - .reduce(TaskExecutionSummary.ZERO, (summary, task) -> - new TaskExecutionSummary( - summary.totalTasks() + 1, - summary.totalDuration().plus(toDuration(task.getDuration())), - summary.totalAvoidanceSavings().plus(toDuration(task.getAvoidanceSavings()))), - TaskExecutionSummary::plus - ); - } - - private static Map.Entry summarizeForMaven(Map.Entry> entry) { - return new AbstractMap.SimpleEntry<>(entry.getKey(), summarizeForMaven(entry.getValue())); - } - - private static TaskExecutionSummary summarizeForMaven(List tasks) { - return tasks.stream() - .reduce(TaskExecutionSummary.ZERO, (summary, task) -> - new TaskExecutionSummary( - summary.totalTasks() + 1, - summary.totalDuration().plus(toDuration(task.getDuration())), - summary.totalAvoidanceSavings().plus(toDuration(task.getAvoidanceSavings()))), - TaskExecutionSummary::plus - ); - } - - private static Duration toDuration(Long millis) { - if (millis == null) { - return Duration.ZERO; - } - return Duration.ofMillis(millis); - } - - private static Map toTotalAvoidedFromCache(Map summariesByOutcome) { - TaskExecutionSummary fromLocalCache = summariesByOutcome.getOrDefault("avoided_from_local_cache", TaskExecutionSummary.ZERO); - TaskExecutionSummary fromRemoteCache = summariesByOutcome.getOrDefault("avoided_from_remote_cache", TaskExecutionSummary.ZERO); - - summariesByOutcome.put("avoided_from_cache", fromLocalCache.plus(fromRemoteCache)); - return summariesByOutcome; - } - - private static Duration buildTimeFrom(GradleBuildCachePerformance buildCachePerformance) { - return toDuration(buildCachePerformance.getBuildTime()); - } - - private static Duration buildTimeFrom(MavenBuildCachePerformance buildCachePerformance) { - return toDuration(buildCachePerformance.getBuildTime()); - } - - private static BigDecimal serializationFactorFrom(GradleBuildCachePerformance buildCachePerformance) { - return BigDecimal.valueOf(buildCachePerformance.getSerializationFactor()); - } - - private static BigDecimal serializationFactorFrom(MavenBuildCachePerformance buildCachePerformance) { - return BigDecimal.valueOf(buildCachePerformance.getSerializationFactor()); - } -} diff --git a/components/fetch-build-scan-data-cmdline-tool/src/main/java/com/gradle/enterprise/cli/BuildInsightsPrinter.java b/components/fetch-build-scan-data-cmdline-tool/src/main/java/com/gradle/enterprise/cli/BuildInsightsPrinter.java deleted file mode 100644 index 4dfc9bee..00000000 --- a/components/fetch-build-scan-data-cmdline-tool/src/main/java/com/gradle/enterprise/cli/BuildInsightsPrinter.java +++ /dev/null @@ -1,54 +0,0 @@ -package com.gradle.enterprise.cli; - -import com.gradle.enterprise.model.BuildScanData; -import com.gradle.enterprise.model.BuildTimeMetrics; - -import java.util.List; -import java.util.stream.Stream; - -import static java.util.stream.Collectors.joining; - -final class BuildInsightsPrinter { - - static void printInsights(List buildScanData) { - printBuildScanDataHeader(); - printBuildScanData(buildScanData); - - if (buildScanData.size() == 2) { - printBuildTimeMetricsHeader(); - printBuildTimeMetrics(buildScanData); - } - } - - private static void printBuildScanDataHeader() { - printRow(BuildScanDataFields.ordered().map(f -> f.label)); - } - - private static void printBuildScanData(List buildScanData) { - buildScanData.forEach(BuildInsightsPrinter::printBuildScanData); - } - - private static void printBuildScanData(BuildScanData buildScanData) { - printRow(BuildScanDataFields.ordered().map(f -> f.value.apply(buildScanData))); - } - - private static void printBuildTimeMetricsHeader() { - printRow(BuildTimeMetricsFields.ordered().map(f -> f.label)); - } - - private static void printBuildTimeMetrics(List buildScanData) { - final BuildTimeMetrics buildTimeData = BuildTimeMetrics.from(buildScanData.get(0), buildScanData.get(1)); - if (buildTimeData == null) { - printRow(BuildTimeMetricsFields.ordered().map(f -> "")); - } else { - printRow(BuildTimeMetricsFields.ordered().map(f -> f.value.apply(buildTimeData))); - } - } - - private static void printRow(Stream values) { - System.out.println(values.collect(joining(","))); - } - - private BuildInsightsPrinter() { - } -} diff --git a/components/fetch-build-scan-data-cmdline-tool/src/main/java/com/gradle/enterprise/cli/BuildScanDataFields.java b/components/fetch-build-scan-data-cmdline-tool/src/main/java/com/gradle/enterprise/cli/BuildScanDataFields.java deleted file mode 100644 index 883e8270..00000000 --- a/components/fetch-build-scan-data-cmdline-tool/src/main/java/com/gradle/enterprise/cli/BuildScanDataFields.java +++ /dev/null @@ -1,84 +0,0 @@ -package com.gradle.enterprise.cli; - -import com.gradle.enterprise.model.BuildScanData; -import com.gradle.enterprise.model.TaskExecutionSummary; - -import java.math.BigDecimal; -import java.math.RoundingMode; -import java.time.Duration; -import java.util.Arrays; -import java.util.function.Function; -import java.util.stream.Stream; - -import static com.gradle.enterprise.cli.DurationFormat.format; - -public enum BuildScanDataFields { - // The order the enums are defined controls the order the fields are printed in the CSV - RUN_NUM("Run Num", d -> toStringSafely(d.runNum())), - ROOT_PROJECT_NAME("Root Project Name", BuildScanData::getRootProjectName), - GE_SERVER("Gradle Enterprise Server", d -> toStringSafely(d.getGradleEnterpriseServerUrl())), - BUILD_SCAN("Build Scan", d -> toStringSafely(d.getBuildScanUrl())), - BUILD_SCAN_ID("Build Scan ID", BuildScanData::getBuildScanId), - GIT_URL("Git URL", BuildScanData::getGitUrl), - GIT_BRANCH("Git Branch", BuildScanData::getGitBranch), - GIT_COMMIT_ID("Git Commit ID", BuildScanData::getGitCommitId), - REQUESTED_TASKS("Requested Tasks", d -> String.join(" ", d.getRequestedTasks())), - BUILD_OUTCOME("Build Outcome", BuildScanData::getBuildOutcome), - REMOTE_BUILD_CACHE_URL("Remote Build Cache URL", d -> toStringSafely(d.getRemoteBuildCacheUrl())), - REMOTE_BUILD_CACHE_SHARD("Remote Build Cache Shard", BuildScanData::getRemoteBuildCacheShard), - AVOIDED_UP_TO_DATE("Avoided Up To Date", d -> totalTasks(d, "avoided_up_to_date")), - AVOIDED_UP_TO_DATE_AVOIDANCE_SAVINGS("Avoided up-to-date avoidance savings", d -> totalAvoidanceSavings(d, "avoided_up_to_date")), - AVOIDED_FROM_CACHE("Avoided from cache", d -> totalTasks(d, "avoided_from_cache")), - AVOIDED_FROM_CACHE_AVOIDANCE_SAVINGS("Avoided from cache avoidance savings", d -> totalAvoidanceSavings(d, "avoided_from_cache")), - EXECUTED_CACHEABLE("Executed cacheable", d -> totalTasks(d, "executed_cacheable")), - EXECUTED_CACHEABLE_DURATION("Executed cacheable duration", d -> totalDuration(d, "executed_cacheable")), - EXECUTED_NOT_CACHEABLE("Executed not cacheable", d -> totalTasks(d, "executed_not_cacheable")), - EXECUTED_NOT_CACHEABLE_DURATION("Executed not cacheable duration", d -> totalDuration(d, "executed_not_cacheable")), - SERIALIZATION_FACTOR("Serialization factor", d -> formatSerializationFactor(d.getSerializationFactor())), - ; - - private static final String NO_VALUE = ""; - - public final String label; - public final Function value; - - BuildScanDataFields(String label, Function value) { - this.label = label; - this.value = value; - } - - public static Stream ordered() { - return Arrays.stream(BuildScanDataFields.values()); - } - - private static String toStringSafely(Object object) { - return object == null ? NO_VALUE : object.toString(); - } - - private static String totalTasks(BuildScanData data, String avoidanceOutcome) { - return summaryTotal(data, avoidanceOutcome, t -> String.valueOf(t.totalTasks())); - } - - private static String totalAvoidanceSavings(BuildScanData data, String avoidanceOutcome) { - return summaryTotal(data, avoidanceOutcome, t -> formatDuration(t.totalAvoidanceSavings())); - } - - private static String totalDuration(BuildScanData data, String avoidanceOutcome) { - return summaryTotal(data, avoidanceOutcome, t -> formatDuration(t.totalDuration())); - } - - private static String summaryTotal(BuildScanData data, String avoidanceOutcome, Function toString) { - if (data.getTasksByAvoidanceOutcome().containsKey(avoidanceOutcome)) { - return toString.apply(data.getTasksByAvoidanceOutcome().get(avoidanceOutcome)); - } - return NO_VALUE; - } - - private static String formatDuration(Duration duration) { - return duration == null ? NO_VALUE : format(duration); - } - - private static String formatSerializationFactor(BigDecimal serializationFactor) { - return serializationFactor == null ? NO_VALUE : serializationFactor.setScale(2, RoundingMode.HALF_UP).doubleValue() + "x"; - } -} diff --git a/components/fetch-build-scan-data-cmdline-tool/src/main/java/com/gradle/enterprise/cli/BuildTimeMetricsFields.java b/components/fetch-build-scan-data-cmdline-tool/src/main/java/com/gradle/enterprise/cli/BuildTimeMetricsFields.java deleted file mode 100644 index 53a9171e..00000000 --- a/components/fetch-build-scan-data-cmdline-tool/src/main/java/com/gradle/enterprise/cli/BuildTimeMetricsFields.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.gradle.enterprise.cli; - -import com.gradle.enterprise.model.BuildTimeMetrics; - -import java.util.Arrays; -import java.util.function.Function; -import java.util.stream.Stream; - -import static com.gradle.enterprise.cli.DurationFormat.format; - -public enum BuildTimeMetricsFields { - // The order the enums are defined controls the order the fields are printed in the CSV - INITIAL_BUILD_TIME("Initial Build Time", d -> format(d.initialBuildTime)), - INSTANT_SAVINGS("Instant Savings", d -> format(d.instantSavings)), - INSTANT_SAVINGS_BUILD_TIME("Instant Savings Build Time", d -> format(d.instantSavingsBuildTime)), - PENDING_SAVINGS("Pending Savings", d -> format(d.pendingSavings)), - PENDING_SAVINGS_BUILD_TIME("Pending Savings Build Time", d -> format(d.pendingSavingsBuildTime)), - ; - - public final String label; - public final Function value; - - BuildTimeMetricsFields(String label, Function value) { - this.label = label; - this.value = value; - } - - public static Stream ordered() { - return Arrays.stream(BuildTimeMetricsFields.values()); - } -} diff --git a/components/fetch-build-scan-data-cmdline-tool/src/main/java/com/gradle/enterprise/cli/ConsoleLogger.java b/components/fetch-build-scan-data-cmdline-tool/src/main/java/com/gradle/enterprise/cli/ConsoleLogger.java deleted file mode 100644 index 1b340bf6..00000000 --- a/components/fetch-build-scan-data-cmdline-tool/src/main/java/com/gradle/enterprise/cli/ConsoleLogger.java +++ /dev/null @@ -1,61 +0,0 @@ -package com.gradle.enterprise.cli; - -import picocli.CommandLine; - -import java.io.PrintStream; - -public class ConsoleLogger { - - private final PrintStream out; - private final CommandLine.Help.ColorScheme colorScheme; - private final boolean debugEnabled; - - private boolean lastStatementIncludedNewline = true; - - public ConsoleLogger(PrintStream out, CommandLine.Help.ColorScheme colorScheme, boolean debugEnabled) { - this.out = out; - this.colorScheme = colorScheme; - this.debugEnabled = debugEnabled; - } - - public void info(String message, Object... args) { - info(String.format(message, args)); - } - - public void info(String message) { - out.println(message); - lastStatementIncludedNewline = true; - } - - public void debug(String message) { - if (debugEnabled) { - out.println(colorScheme.text("@|faint " + message + "|@")); - lastStatementIncludedNewline = true; - } - } - - public void debug(Throwable t) { - debug(colorScheme.stackTraceText(t).plainString()); - } - - public void error(String message, Object... args) { - error(String.format(message, args)); - } - - public void error(String message) { - if (!lastStatementIncludedNewline) { - out.println(); - } - out.println(colorScheme.errorText(message)); - lastStatementIncludedNewline = true; - } - - public void error(Throwable t) { - error(colorScheme.stackTraceText(t).plainString()); - } - - public boolean isDebugEnabled() { - return debugEnabled; - } - -} diff --git a/components/fetch-build-scan-data-cmdline-tool/src/main/java/com/gradle/enterprise/cli/DurationFormat.java b/components/fetch-build-scan-data-cmdline-tool/src/main/java/com/gradle/enterprise/cli/DurationFormat.java deleted file mode 100644 index a369a989..00000000 --- a/components/fetch-build-scan-data-cmdline-tool/src/main/java/com/gradle/enterprise/cli/DurationFormat.java +++ /dev/null @@ -1,29 +0,0 @@ -package com.gradle.enterprise.cli; - -import java.time.Duration; -import java.util.Locale; - -final class DurationFormat { - - static String format(Duration duration) { - long hours = duration.abs().toHours(); - long minutes = duration.abs().toMinutes() % 60; - double seconds = (duration.abs().toMillis() % 60_000) / 1000d; - - StringBuilder s = new StringBuilder(); - if (duration.isNegative()) { - s.append('-'); - } - if (hours != 0) { - s.append(hours).append("h "); - } - if (minutes != 0) { - s.append(minutes).append("m "); - } - s.append(String.format(Locale.ROOT, "%.3fs", seconds)); - return s.toString().trim(); - } - - private DurationFormat() { - } -} diff --git a/components/fetch-build-scan-data-cmdline-tool/src/main/java/com/gradle/enterprise/cli/FetchBuildScanDataCommand.java b/components/fetch-build-scan-data-cmdline-tool/src/main/java/com/gradle/enterprise/cli/FetchBuildScanDataCommand.java deleted file mode 100644 index 444641e4..00000000 --- a/components/fetch-build-scan-data-cmdline-tool/src/main/java/com/gradle/enterprise/cli/FetchBuildScanDataCommand.java +++ /dev/null @@ -1,185 +0,0 @@ -package com.gradle.enterprise.cli; - -import com.gradle.enterprise.api.client.FailedRequestException; -import com.gradle.enterprise.api.client.GradleEnterpriseApiClient; -import com.gradle.enterprise.model.BuildScanData; -import com.gradle.enterprise.model.CustomValueNames; -import com.gradle.enterprise.model.NumberedBuildScan; -import com.gradle.enterprise.network.NetworkSettingsConfigurator; -import org.jetbrains.annotations.NotNull; -import picocli.CommandLine; -import picocli.CommandLine.Command; -import picocli.CommandLine.Option; -import picocli.CommandLine.Parameters; - -import java.nio.file.Path; -import java.util.Collections; -import java.util.List; -import java.util.Optional; -import java.util.concurrent.Callable; -import java.util.stream.Collectors; - -@Command( - name = "fetch-build-scan-data-cmdline-tool", - mixinStandardHelpOptions = true, - description = "Fetches data relevant to build validation from the given build scans." -) -public class FetchBuildScanDataCommand implements Callable { - - private final CommandLine.Help.ColorScheme colorScheme; - private ConsoleLogger logger; - - public FetchBuildScanDataCommand(CommandLine.Help.ColorScheme colorScheme) { - this.colorScheme = colorScheme; - } - - public static class ExitCode { - public static final int OK = 0; - } - - @Parameters(paramLabel = "BUILD_SCAN", description = "The build scans to fetch. Each build scan URL is preceded by the run num that produced the build scan.", arity = "1..*") - private List runNumsAndBuildScanUrls; - - @Option(names = {"--mapping-file"}, description = "Specifies a mapping file that configures the names used to fetch important custom values.") - private Optional customValuesMappingFile; - - @Option(names = {"--network-settings-file"}, description = "Specifies a file that configures HTTP(S) Proxy and SSL settings.") - private Optional networkSettingsFile; - - @Option(names = {"--debug"}, description = "Prints additional debugging information while running.") - private boolean debug; - - @Option(names = {"--brief-logging"}, description = "Only log a short message about fetching build scan data and when it completes.") - private boolean briefLogging; - - @Override - public Integer call() { - // Use System.err for logging since we're going to write out the CSV to System.out - logger = new ConsoleLogger(System.err, colorScheme, debug); - logger.debug("Using JVM at " + System.getProperty("java.home")); - - networkSettingsFile.ifPresent(settingsFile -> NetworkSettingsConfigurator.configureNetworkSettings(settingsFile, logger)); - - List buildScans = NumberedBuildScan.parse(runNumsAndBuildScanUrls); - CustomValueNames customValueKeys = customValuesMappingFile - .map(CustomValueNames::loadFromFile) - .orElse(CustomValueNames.DEFAULT); - - logStartFetchingAllBuildScanData(); - List buildScanData = fetchBuildScanData(buildScans, customValueKeys); - - logFinishedFetchingAllBuildScanData(); - logFetchResults(buildScanData, customValueKeys); - - BuildInsightsPrinter.printInsights(buildScanData); - - return ExitCode.OK; - } - - @NotNull - private List fetchBuildScanData(List buildScans, CustomValueNames customValueKeys) { - return buildScans.stream() - .parallel() - .map(buildScan -> fetchBuildScanData(buildScan, customValueKeys)) - .collect(Collectors.toList()); - } - - private BuildScanData fetchBuildScanData(NumberedBuildScan buildScan, CustomValueNames customValueNames) { - logStartFetchingBuildScanData(buildScan); - try { - GradleEnterpriseApiClient apiClient = new GradleEnterpriseApiClient(buildScan.baseUrl(), customValueNames, logger); - BuildScanData data = apiClient.fetchBuildScanData(buildScan); - - logFinishedFetchingBuildScanData(buildScan); - return data; - } catch (RuntimeException e) { - logException(e); - return new BuildScanData( - buildScan.runNum(), - "", - buildScan.buildScanId(), - buildScan.baseUrl(), - "", - "", - "", - Collections.emptyList(), - "", - null, - Collections.emptyMap(), - null, - null); - } - } - - private void logException(RuntimeException e) { - if (logger.isDebugEnabled()) { - logger.error(e); - if (e instanceof FailedRequestException) { - printFailedRequest((FailedRequestException) e); - } - } else { - logger.error("ERROR: " + e.getMessage()); - } - } - - private void printFailedRequest(FailedRequestException e) { - logger.error("Response status code: " + e.httpStatusCode()); - e.getResponseBody().ifPresent(responseBody -> { - logger.error("Response body:"); - logger.error(responseBody); - logger.error("--------------------------"); - }); - } - - private void logStartFetchingAllBuildScanData() { - if (briefLogging) { - logger.info("Fetching Build Scan data for all builds"); - } - } - - private void logFinishedFetchingAllBuildScanData() { - if (briefLogging) { - logger.info("Finished fetching Build Scan data for all builds"); - } - } - - private void logStartFetchingBuildScanData(NumberedBuildScan buildScan) { - if (!briefLogging) { - logger.info("Fetching Build Scan data for %s build", toOrdinal(buildScan.runNum())); - } - } - - private void logFinishedFetchingBuildScanData(NumberedBuildScan buildScan) { - if (!briefLogging) { - logger.info("Finished fetching Build Scan data for %s build", toOrdinal(buildScan.runNum())); - } - } - - private void logFetchResults(List buildScanData, CustomValueNames customValueKeys) { - if (!briefLogging) { - buildScanData.forEach(validationData -> { - logger.info(""); - - logFetchResultFor(validationData.runNum(), "Git repository", customValueKeys.getGitRepositoryKey(), validationData.isGitUrlFound()); - logFetchResultFor(validationData.runNum(), "Git branch", customValueKeys.getGitBranchKey(), validationData.isGitBranchFound()); - logFetchResultFor(validationData.runNum(), "Git commit id", customValueKeys.getGitCommitIdKey(), validationData.isGitCommitIdFound()); - }); - } - } - - private void logFetchResultFor(int runNum, String property, String customValueKey, boolean found) { - logger.info( - "%s %s from custom value with name '%s' for %s build", - found ? "Found": "Did not find", property, customValueKey, toOrdinal(runNum) - ); - } - - private static String toOrdinal(int i) { - switch(i + 1) { - case 1: return "first"; - case 2: return "second"; - case 3: return "third"; - default: return (i + 1) + "th"; - } - } -} diff --git a/components/fetch-build-scan-data-cmdline-tool/src/main/java/com/gradle/enterprise/cli/PrintExceptionHandler.java b/components/fetch-build-scan-data-cmdline-tool/src/main/java/com/gradle/enterprise/cli/PrintExceptionHandler.java deleted file mode 100644 index 324c92a7..00000000 --- a/components/fetch-build-scan-data-cmdline-tool/src/main/java/com/gradle/enterprise/cli/PrintExceptionHandler.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.gradle.enterprise.cli; - -import picocli.CommandLine; - -public class PrintExceptionHandler implements CommandLine.IExecutionExceptionHandler { - - @Override - public int handleExecutionException(Exception e, CommandLine cmd, CommandLine.ParseResult parseResult) throws Exception { - if (parseResult.hasMatchedOption("debug")) { - cmd.getErr().println(cmd.getColorScheme().errorText(cmd.getColorScheme().stackTraceText(e).toString())); - } else { - cmd.getErr().println(cmd.getColorScheme().errorText("ERROR: " + e.getMessage())); - } - - int returnCode = cmd.getCommandSpec().exitCodeOnExecutionException(); - if (cmd.getExitCodeExceptionMapper() != null) { - returnCode = cmd.getExitCodeExceptionMapper().getExitCode(e); - } - return returnCode; - } -} diff --git a/components/fetch-build-scan-data-cmdline-tool/src/main/java/com/gradle/enterprise/model/BuildScanData.java b/components/fetch-build-scan-data-cmdline-tool/src/main/java/com/gradle/enterprise/model/BuildScanData.java deleted file mode 100644 index ead416dd..00000000 --- a/components/fetch-build-scan-data-cmdline-tool/src/main/java/com/gradle/enterprise/model/BuildScanData.java +++ /dev/null @@ -1,149 +0,0 @@ -package com.gradle.enterprise.model; - -import java.math.BigDecimal; -import java.net.MalformedURLException; -import java.net.URL; -import java.time.Duration; -import java.util.List; -import java.util.Map; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -public class BuildScanData { - private static final Pattern REMOTE_BUILD_CACHE_SHARD_PATTERN = Pattern.compile(".*/cache/(.+)$"); - - private final int runNum; - private final String rootProjectName; - private final String buildScanId; - private final URL gradleEnterpriseServerUrl; - private final String gitUrl; - private final String gitBranch; - private final String gitCommitId; - private final List requestedTasks; - private final String buildOutcome; - private final URL remoteBuildCacheUrl; - private final Map tasksByAvoidanceOutcome; - private final Duration buildTime; - private final BigDecimal serializationFactor; - - public BuildScanData( - int runNum, - String rootProjectName, - String buildScanId, - URL gradleEnterpriseServerUrl, - String gitUrl, - String gitBranch, - String gitCommitId, - List requestedTasks, - String buildOutcome, - URL remoteBuildCacheUrl, - Map tasksByAvoidanceOutcome, - Duration buildTime, - BigDecimal serializationFactor) { - this.runNum = runNum; - this.rootProjectName = rootProjectName; - this.buildScanId = buildScanId; - this.gradleEnterpriseServerUrl = gradleEnterpriseServerUrl; - this.gitUrl = gitUrl; - this.gitBranch = gitBranch; - this.gitCommitId = gitCommitId; - this.requestedTasks = requestedTasks; - this.buildOutcome = buildOutcome; - this.remoteBuildCacheUrl = remoteBuildCacheUrl; - this.tasksByAvoidanceOutcome = tasksByAvoidanceOutcome; - this.buildTime = buildTime; - this.serializationFactor = serializationFactor; - } - - public int runNum() { - return runNum; - } - - public String getRootProjectName() { - return rootProjectName; - } - - public String getBuildScanId() { - return buildScanId; - } - - public URL getBuildScanUrl() { - try { - return new URL(gradleEnterpriseServerUrl, "/s/" + buildScanId); - } catch (MalformedURLException e) { - throw new RuntimeException(e.getMessage(), e); - } - } - - public URL getGradleEnterpriseServerUrl() { - return gradleEnterpriseServerUrl; - } - - public String getGitUrl() { - return gitUrl; - } - - public boolean isGitUrlFound() { - return isFound(gitUrl); - } - - public String getGitBranch() { - return gitBranch; - } - - public boolean isGitBranchFound() { - return isFound(gitBranch); - } - - public String getGitCommitId() { - return gitCommitId; - } - - public boolean isGitCommitIdFound() { - return isFound(gitCommitId); - } - - public List getRequestedTasks() { - return requestedTasks; - } - - public String getBuildOutcome() { - return buildOutcome; - } - - public URL getRemoteBuildCacheUrl() { - return remoteBuildCacheUrl; - } - - public String getRemoteBuildCacheShard() { - if (remoteBuildCacheUrl == null) { - return ""; - } - Matcher matcher = REMOTE_BUILD_CACHE_SHARD_PATTERN.matcher(remoteBuildCacheUrl.getPath()); - if (matcher.matches()) { - return matcher.group(1); - } - return ""; - } - - private static boolean isFound(String value) { - return !value.isEmpty(); - } - - public Map getTasksByAvoidanceOutcome() { - return tasksByAvoidanceOutcome; - } - - public TaskExecutionSummary getExecutedCacheableSummary() { - return tasksByAvoidanceOutcome.get("executed_cacheable"); - } - - public Duration getBuildTime() { - return buildTime; - } - - public BigDecimal getSerializationFactor() { - return serializationFactor; - } - -} diff --git a/components/fetch-build-scan-data-cmdline-tool/src/main/java/com/gradle/enterprise/model/BuildTimeMetrics.java b/components/fetch-build-scan-data-cmdline-tool/src/main/java/com/gradle/enterprise/model/BuildTimeMetrics.java deleted file mode 100644 index 4c50040e..00000000 --- a/components/fetch-build-scan-data-cmdline-tool/src/main/java/com/gradle/enterprise/model/BuildTimeMetrics.java +++ /dev/null @@ -1,47 +0,0 @@ -package com.gradle.enterprise.model; - -import java.time.Duration; - -public class BuildTimeMetrics { - - public final Duration initialBuildTime; - public final Duration instantSavings; - public final Duration instantSavingsBuildTime; - public final Duration pendingSavings; - public final Duration pendingSavingsBuildTime; - - private BuildTimeMetrics( - Duration initialBuildTime, - Duration instantSavings, - Duration instantSavingsBuildTime, - Duration pendingSavings, - Duration pendingSavingsBuildTime) { - this.initialBuildTime = initialBuildTime; - this.instantSavings = instantSavings; - this.instantSavingsBuildTime = instantSavingsBuildTime; - this.pendingSavings = pendingSavings; - this.pendingSavingsBuildTime = pendingSavingsBuildTime; - } - - public static BuildTimeMetrics from(BuildScanData firstBuild, BuildScanData secondBuild) { - if (firstBuild.getBuildTime() == null || - secondBuild.getBuildTime() == null || - secondBuild.getExecutedCacheableSummary() == null || - secondBuild.getSerializationFactor() == null) { - return null; - } - - final Duration instantSavings = firstBuild.getBuildTime().minus(secondBuild.getBuildTime()); - final Duration pendingSavings = - Duration.ofMillis((long) (secondBuild.getExecutedCacheableSummary().totalDuration().toMillis() - / secondBuild.getSerializationFactor().doubleValue())); - final Duration pendingSavingsBuildTime = secondBuild.getBuildTime().minus(pendingSavings); - - return new BuildTimeMetrics( - firstBuild.getBuildTime(), - instantSavings, - secondBuild.getBuildTime(), - pendingSavings, - pendingSavingsBuildTime); - } -} diff --git a/components/fetch-build-scan-data-cmdline-tool/src/main/java/com/gradle/enterprise/model/CustomValueNames.java b/components/fetch-build-scan-data-cmdline-tool/src/main/java/com/gradle/enterprise/model/CustomValueNames.java deleted file mode 100644 index dadd194d..00000000 --- a/components/fetch-build-scan-data-cmdline-tool/src/main/java/com/gradle/enterprise/model/CustomValueNames.java +++ /dev/null @@ -1,57 +0,0 @@ -package com.gradle.enterprise.model; - -import java.io.BufferedReader; -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.Properties; - -public class CustomValueNames { - - public static final CustomValueNames DEFAULT = new CustomValueNames( - "Git repository", "Git branch", "Git commit id" - ); - - public static CustomValueNames loadFromFile(Path customValuesMappingFile) { - try { - if (Files.isRegularFile(customValuesMappingFile)) { - try (BufferedReader in = Files.newBufferedReader(customValuesMappingFile)) { - Properties mappingProps = new Properties(); - mappingProps.load(in); - return new CustomValueNames( - mappingProps.getProperty("git.repository", DEFAULT.getGitRepositoryKey()), - mappingProps.getProperty("git.branch", DEFAULT.getGitBranchKey()), - mappingProps.getProperty("git.commitId", DEFAULT.getGitCommitIdKey()) - ); - } - } else { - return CustomValueNames.DEFAULT; - } - } catch (IOException e) { - throw new RuntimeException("Could not load custom value mapping file: " + customValuesMappingFile, e); - } - } - - private final String gitRepositoryKey; - private final String gitBranchKey; - private final String gitCommitIdKey; - - public CustomValueNames(String gitRepositoryKey, String gitBranchKey, String gitCommitIdKey) { - this.gitRepositoryKey = gitRepositoryKey; - this.gitBranchKey = gitBranchKey; - this.gitCommitIdKey = gitCommitIdKey; - } - - public String getGitRepositoryKey() { - return gitRepositoryKey; - } - - public String getGitBranchKey() { - return gitBranchKey; - } - - public String getGitCommitIdKey() { - return gitCommitIdKey; - } - -} diff --git a/components/fetch-build-scan-data-cmdline-tool/src/main/java/com/gradle/enterprise/model/NumberedBuildScan.java b/components/fetch-build-scan-data-cmdline-tool/src/main/java/com/gradle/enterprise/model/NumberedBuildScan.java deleted file mode 100644 index 74b4ac7a..00000000 --- a/components/fetch-build-scan-data-cmdline-tool/src/main/java/com/gradle/enterprise/model/NumberedBuildScan.java +++ /dev/null @@ -1,81 +0,0 @@ -package com.gradle.enterprise.model; - -import java.net.MalformedURLException; -import java.net.URL; -import java.util.List; -import java.util.stream.Collectors; - -import static java.lang.Integer.parseInt; - -public class NumberedBuildScan { - private final int runNum; - private final URL baseUrl; - private final String buildScanId; - - private NumberedBuildScan(int runNum, URL baseUrl, String buildScanId) { - this.runNum = runNum; - this.baseUrl = baseUrl; - this.buildScanId = buildScanId; - } - - public static List parse(List runNumsAndBuildScanUrls) { - return runNumsAndBuildScanUrls.stream().map(NumberedBuildScan::parse).collect(Collectors.toList()); - } - - public static NumberedBuildScan parse(String runNumAndBuildScanUrl) { - String[] parts = runNumAndBuildScanUrl.split(","); - if (parts.length != 2) { - throw new IllegalArgumentException("Invalid numbered Build Scan URL: " + runNumAndBuildScanUrl); - } - - String runNum = parts[0]; - URL buildScanUrl = toURL(parts[1]); - - return new NumberedBuildScan( - parseInt(runNum), - extractBaseUrl(buildScanUrl), - extractBuildScanId(buildScanUrl) - ); - } - - public int runNum() { - return runNum; - } - - public URL baseUrl() { - return baseUrl; - } - - public String buildScanId() { - return buildScanId; - } - - public URL url() { - try { - return new URL(baseUrl, "/s/" + buildScanId); - } catch (MalformedURLException e) { - throw new RuntimeException(e.getMessage(), e); - } - } - - private static URL extractBaseUrl(URL buildScanUrl) { - String port = (buildScanUrl.getPort() != -1) ? ":" + buildScanUrl.getPort() : ""; - return toURL(buildScanUrl.getProtocol() + "://" + buildScanUrl.getHost() + port); - } - - private static String extractBuildScanId(URL buildScanUrl) { - String[] pathSegments = buildScanUrl.getPath().split("/"); - if (pathSegments.length <= 2 || !pathSegments[1].equals("s")) { - throw new IllegalArgumentException("Invalid Build Scan URL: " + buildScanUrl); - } - return pathSegments[2]; - } - - private static URL toURL(String url) { - try { - return new URL(url); - } catch (MalformedURLException e) { - throw new IllegalArgumentException("Invalid Build Scan URL: " + url, e); - } - } -} diff --git a/components/fetch-build-scan-data-cmdline-tool/src/main/java/com/gradle/enterprise/model/TaskExecutionSummary.java b/components/fetch-build-scan-data-cmdline-tool/src/main/java/com/gradle/enterprise/model/TaskExecutionSummary.java deleted file mode 100644 index 7756487a..00000000 --- a/components/fetch-build-scan-data-cmdline-tool/src/main/java/com/gradle/enterprise/model/TaskExecutionSummary.java +++ /dev/null @@ -1,38 +0,0 @@ -package com.gradle.enterprise.model; - -import java.time.Duration; - -public class TaskExecutionSummary { - - public static final TaskExecutionSummary ZERO = new TaskExecutionSummary(0, Duration.ZERO, Duration.ZERO); - - private final Integer totalTasks; - private final Duration totalDuration; - private final Duration totalAvoidanceSavings; - - public TaskExecutionSummary(Integer totalTasks, Duration totalDuration, Duration totalAvoidanceSavings) { - this.totalTasks = totalTasks; - this.totalDuration = totalDuration; - this.totalAvoidanceSavings = totalAvoidanceSavings; - } - - public Integer totalTasks() { - return totalTasks; - } - - public Duration totalDuration() { - return totalDuration; - } - - public Duration totalAvoidanceSavings() { - return totalAvoidanceSavings; - } - - public TaskExecutionSummary plus(TaskExecutionSummary other) { - return new TaskExecutionSummary( - totalTasks + other.totalTasks, - totalDuration.plus(other.totalDuration), - totalAvoidanceSavings.plus(other.totalAvoidanceSavings) - ); - } -} diff --git a/components/fetch-build-scan-data-cmdline-tool/src/main/java/com/gradle/enterprise/network/NetworkSettingsConfigurator.java b/components/fetch-build-scan-data-cmdline-tool/src/main/java/com/gradle/enterprise/network/NetworkSettingsConfigurator.java deleted file mode 100644 index 5a33cca9..00000000 --- a/components/fetch-build-scan-data-cmdline-tool/src/main/java/com/gradle/enterprise/network/NetworkSettingsConfigurator.java +++ /dev/null @@ -1,57 +0,0 @@ -package com.gradle.enterprise.network; - -import com.gradle.enterprise.cli.ConsoleLogger; - -import java.io.BufferedReader; -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.Properties; - -public class NetworkSettingsConfigurator { - - public static void configureNetworkSettings(Path networkSettingsFile, ConsoleLogger logger) { - try { - configureBasedOnProperties(networkSettingsFile, logger); - } catch (IOException e) { - throw new RuntimeException(String.format("Failed to load network settings from %s.", networkSettingsFile.toAbsolutePath()), e); - } - } - - private static void configureBasedOnProperties(Path networkSettingsFile, ConsoleLogger logger) throws IOException { - if (Files.isRegularFile(networkSettingsFile)) { - logger.debug("Loading network settings from " + networkSettingsFile.toAbsolutePath()); - Properties proxyProps = loadProperties(networkSettingsFile); - proxyProps.stringPropertyNames().stream() - .filter(NetworkSettingsConfigurator::isNetworkProperty) - .forEach(key -> System.setProperty(key, proxyProps.getProperty(key))); - } - } - - private static boolean isNetworkProperty(String key) { - return isSslProperty(key) || isProxyProperty(key) || isConnectionProperty(key); - } - private static boolean isSslProperty(String key) { - return key.startsWith("javax.net.ssl") - || key.equals("ssl.allowUntrustedServer"); - } - - private static boolean isProxyProperty(String key) { - return key.startsWith("http.proxy") - || key.startsWith("https.proxy") - || key.startsWith("socksProxy") - || key.endsWith(".nonProxyHosts"); - } - - private static boolean isConnectionProperty(String key) { - return key.startsWith("connect") || key.startsWith("read"); - } - - private static Properties loadProperties(Path propertiesFile) throws IOException { - Properties properties = new Properties(); - try (BufferedReader in = Files.newBufferedReader(propertiesFile)) { - properties.load(in); - return properties; - } - } -} diff --git a/components/fetch-build-scan-data-cmdline-tool/src/main/openapi/openapi.yaml b/components/fetch-build-scan-data-cmdline-tool/src/main/openapi/openapi.yaml deleted file mode 100644 index cb4405d7..00000000 --- a/components/fetch-build-scan-data-cmdline-tool/src/main/openapi/openapi.yaml +++ /dev/null @@ -1,2059 +0,0 @@ -openapi: 3.0.3 -info: - title: Gradle Enterprise API - description: > - The Gradle Enterprise API allows programmatic interaction with various - aspects of Gradle Enterprise, from configuration to inspecting build data. - version: "2022.2.4" - license: - name: Gradle Enterprise License - url: https://gradle.com/legal/gradle-enterprise-software-agreement - termsOfService: https://gradle.com/legal/terms-of-service - contact: - name: Gradle - url: https://gradle.com - x-logo: - url: https://assets.gradle.com/logo/gradle-enterprise-dark-green-primary.svg - altText: Gradle Enterprise -servers: - - url: https://ge.mycompany.com - description: Your Gradle Enterprise instance. -security: - - GradleEnterpriseAccessKey: [] -paths: - /api/builds: - description: > - Returns a list of builds with basic attributes of a Build Scan. The - returned list is capped by the `maxBuilds` and `maxWaitSecs` query - parameters. This - - endpoint supports pagination by using the `sinceBuild` query parameter, - and the last returned build from a previous call to this endpoint, one can - get - - the next batch of builds. - parameters: - - in: query - name: BuildsQuery - explode: true - schema: - title: BuildsQuery - type: object - properties: - since: - type: integer - format: int64 - minimum: 0 - x-nullable: true - description: > - The time in milliseconds from the Epoch as of when the Build - Scan has been received. A value of `0` will process all builds. - If not provided, the time - - in milliseconds when the request is received by the Gradle - Enterprise instance will be used. This parameter has no effect - if `sinceBuild` is used. - sinceBuild: - type: string - x-nullable: true - description: > - A Build Scan ID allowing to retrieve builds for which Gradle - Enterprise completed receiving and processing after the given - Build Scan ID (excluding it). - - This parameter has precedence over any value set for the `since` - parameter. A valid Build Scan ID must be provided, that is, a - Build Scan ID that exists - - in the Gradle Enterprise instance. A Build Scan ID for a deleted - build is valid. - maxBuilds: - type: integer - minimum: 0 - maximum: 1000 - x-nullable: true - description: > - The maximum number of builds returned by the query. The query - returns when that number is reached or when `maxWaitSecs` is - reached. - - If not provided, the default value is `100`. - maxWaitSecs: - type: integer - minimum: 1 - maximum: 20 - x-nullable: true - description: > - The maximum number of seconds to wait for builds before - returning. If this time is reached before `maxBuilds` is - reached, the query returns with the - - already processed builds. Note that this time is respected with - best effort. A query will return soon after this time has passed - but there is no - - guarantee that it exactly returns before this time has passed. - If not provided, the default value is `3`. - get: - operationId: GetBuilds - summary: Get a list of builds with basic attributes of a Build Scan. - description: The contained attributes are build tool agnostic. - tags: - - Builds - - GradleEnterprise - responses: - '200': - description: A list of builds with basic attributes of a Build Scan. - content: - application/json: - schema: - $ref: '#/components/schemas/Builds' - example: - - id: 9r4d13f0r3v3r - availableAt: 1635400481000 - buildToolType: gradle - buildToolVersion: '7.2' - buildAgentVersion: 3.7.1 - - id: ji7vz3ey5qdvk - availableAt: 1635400482000 - buildToolType: maven - buildToolVersion: 3.8.4 - buildAgentVersion: '1.13' - - id: cvpd4j7ug7j4q - availableAt: 1635400483000 - buildToolType: bazel - buildToolVersion: 6.0.0 - buildAgentVersion: '1.0' - '400': - $ref: '#/components/responses/BadRequestError' - '404': - $ref: '#/components/responses/NotFoundError' - '500': - $ref: '#/components/responses/UnexpectedError' - '503': - $ref: '#/components/responses/NotReadyError' - /api/builds/{id}: - parameters: - - in: path - name: id - schema: - type: string - required: true - description: The Build Scan ID. - - in: query - name: BuildQuery - explode: true - schema: - $ref: '#/components/schemas/BuildQuery' - get: - operationId: GetBuild - summary: Get the common attributes of a Build Scan. - description: The contained attributes are build tool agnostic. - tags: - - Builds - - GradleEnterprise - responses: - '200': - description: The common attributes of a Build Scan. - content: - application/json: - schema: - $ref: '#/components/schemas/Build' - example: - id: 9r4d13f0r3v3r - availableAt: 1635400481000 - buildToolType: gradle - buildToolVersion: '7.2' - buildAgentVersion: 3.7.1 - '400': - $ref: '#/components/responses/BadRequestError' - '404': - $ref: '#/components/responses/NotFoundError' - '500': - $ref: '#/components/responses/UnexpectedError' - '503': - $ref: '#/components/responses/NotReadyError' - /api/builds/{id}/gradle-attributes: - parameters: - - in: path - name: id - schema: - type: string - required: true - description: The Build Scan ID. - - in: query - name: BuildQuery - explode: true - schema: - $ref: '#/components/schemas/BuildQuery' - get: - operationId: GetGradleAttributes - summary: Get the attributes of a Gradle Build Scan. - description: >- - This model is Gradle specific and cannot be requested for another build - tool. - tags: - - Builds - - GradleEnterprise - responses: - '200': - description: The attributes of a Gradle Build Scan. - content: - application/json: - schema: - $ref: '#/components/schemas/GradleAttributes' - example: - id: 9r4d13f0r3v3r - buildStartTime: 1637316480 - buildDuration: 5000 - gradleVersion: '7.3' - pluginVersion: 3.7.2 - rootProjectName: example-project - requestedTasks: - - clean - - build - hasFailed: false - tags: - - CI - - feature-branch - values: - - name: branch - value: feature/one - - name: commitId - value: c874006021712affa4e7bd82d2ec4cd06beaa4f5 - links: - - label: CI job - url: https://ci.com/job1 - - label: GIT commit - url: https://git.com/c874006021712affa4e7bd82d2ec4cd06beaa4f5 - gradleEnterpriseSettings: - backgroundPublicationEnabled: true - buildOutputCapturingEnabled: true - taskInputsFileCapturingEnabled: true - testOutputCapturingEnabled: true - buildOptions: - buildCacheEnabled: true - configurationCacheEnabled: true - configurationOnDemandEnabled: true - continuousBuildEnabled: true - continueOnFailureEnabled: true - daemonEnabled: true - dryRunEnabled: true - fileSystemWatchingEnabled: true - maxNumberOfGradleWorkers: 4 - offlineModeEnabled: true - parallelProjectExecutionEnabled: true - refreshDependenciesEnabled: true - rerunTasksEnabled: true - environment: - username: gradle - operatingSystem: macOS 12.2.1 (x86_64) - numberOfCpuCores: 16 - jreVersion: AdoptOpenJDK OpenJDK Runtime Environment 11.0.11+9 - jvmVersion: AdoptOpenJDK OpenJDK 64-Bit Server VM 11.0.11+9 (mixed mode) - jvmMaxMemoryHeapSize: 16777216 - jvmCharset: UTF-8 - jvmLocale: English (United States) - publicHostname: agent.gradle.com - localHostname: gradle - localIpAddresses: - - 192.168.1.126 - - 192.168.1.128 - '400': - $ref: '#/components/responses/BadRequestError' - '404': - $ref: '#/components/responses/NotFoundError' - '500': - $ref: '#/components/responses/UnexpectedError' - '503': - $ref: '#/components/responses/NotReadyError' - /api/builds/{id}/maven-attributes: - parameters: - - in: path - name: id - schema: - type: string - required: true - description: The Build Scan ID. - - in: query - name: BuildQuery - explode: true - schema: - $ref: '#/components/schemas/BuildQuery' - get: - operationId: GetMavenAttributes - summary: Get the attributes of a Maven Build Scan. - description: >- - This model is Maven specific and cannot be requested for another build - tool. - tags: - - Builds - - GradleEnterprise - responses: - '200': - description: The attributes of a Maven Build Scan. - content: - application/json: - schema: - $ref: '#/components/schemas/MavenAttributes' - example: - id: 9r4d13f0r3v3r - buildStartTime: 1637316480 - buildDuration: 11000 - mavenVersion: 3.8.4 - extensionVersion: 1.11.1 - topLevelProjectName: example-project - requestedGoals: - - clean - - verify - hasFailed: false - tags: - - CI - - feature-branch - values: - - name: branch - value: feature/one - - name: commitId - value: c874006021712affa4e7bd82d2ec4cd06beaa4f5 - links: - - label: CI job - url: https://ci.com/job1 - - label: GIT commit - url: https://git.com/c874006021712affa4e7bd82d2ec4cd06beaa4f5 - gradleEnterpriseSettings: - backgroundPublicationEnabled: true - buildOutputCapturingEnabled: true - goalInputsFileCapturingEnabled: true - testOutputCapturingEnabled: true - buildOptions: - batchModeEnabled: true - debugEnabled: true - errorsEnabled: true - failAtEndEnabled: true - failFastEnabled: true - failNeverEnabled: true - laxChecksumsEnabled: true - maxNumberOfThreads: 4 - nonRecursiveEnabled: true - noSnapshotsUpdatesEnabled: true - offlineModeEnabled: true - quietEnabled: true - rerunGoals: false - strictChecksumsEnabled: true - updateSnapshotsEnabled: true - environment: - username: maven - operatingSystem: macOS 12.2.1 (x86_64) - numberOfCpuCores: 16 - jreVersion: AdoptOpenJDK OpenJDK Runtime Environment 11.0.11+9 - jvmVersion: AdoptOpenJDK OpenJDK 64-Bit Server VM 11.0.11+9 (mixed mode) - jvmMaxMemoryHeapSize: 16777216 - jvmCharset: UTF-8 - jvmLocale: English (United States) - publicHostname: agent.gradle.com - localHostname: maven - localIpAddresses: - - 192.168.1.126 - - 192.168.1.128 - '400': - $ref: '#/components/responses/BadRequestError' - '404': - $ref: '#/components/responses/NotFoundError' - '500': - $ref: '#/components/responses/UnexpectedError' - '503': - $ref: '#/components/responses/NotReadyError' - /api/builds/{id}/gradle-build-cache-performance: - parameters: - - in: path - name: id - schema: - type: string - required: true - description: The Build Scan ID. - - in: query - name: BuildQuery - explode: true - schema: - $ref: '#/components/schemas/BuildQuery' - get: - operationId: GetGradleBuildCachePerformance - summary: Get the build cache performance of a Gradle Build Scan. - description: >- - This model is Gradle specific and cannot be requested for another build - tool. - tags: - - Builds - - GradleEnterprise - responses: - '200': - description: The build cache performance of a Gradle Build Scan. - content: - application/json: - schema: - $ref: '#/components/schemas/GradleBuildCachePerformance' - example: - id: 9r4d13f0r3v3r - buildTime: 5000 - effectiveTaskExecutionTime: 5000 - serialTaskExecutionTime: 10000 - serializationFactor: 2 - taskExecution: - - taskPath: ':task' - taskType: org.gradle.api.tasks.Task - avoidanceOutcome: avoided_from_local_cache - duration: 5000 - fingerprintingDuration: 5 - avoidanceSavings: 6000 - - taskPath: ':task2' - taskType: org.gradle.api.tasks.Task - avoidanceOutcome: avoided_from_remote_cache - duration: 3000 - fingerprintingDuration: 3 - avoidanceSavings: 4000 - - taskPath: ':task3' - avoidanceOutcome: executed_not_cacheable - duration: 2000 - fingerprintingDuration: 6 - nonCacheabilityCategory: cache-if_condition_not_matched - nonCacheabilityReason: '''Task outputs cacheable'' not satisfied' - taskFingerprintingSummary: - count: 1 - serialDuration: 8 - avoidanceSavingsSummary: - total: 10000 - ratio: 0.55556 - upToDate: 0 - localBuildCache: 6000 - remoteBuildCache: 4000 - buildCaches: - local: - isEnabled: true - isPushEnabled: true - isDisabledDueToError: false - remote: - isEnabled: true - isPushEnabled: true - isDisabledDueToError: false - overhead: - uploading: 100 - downloading: 200 - packing: 50 - unpacking: 25 - '400': - $ref: '#/components/responses/BadRequestError' - '404': - $ref: '#/components/responses/NotFoundError' - '500': - $ref: '#/components/responses/UnexpectedError' - '503': - $ref: '#/components/responses/NotReadyError' - /api/builds/{id}/maven-build-cache-performance: - parameters: - - in: path - name: id - schema: - type: string - required: true - description: The Build Scan ID. - - in: query - name: BuildQuery - explode: true - schema: - $ref: '#/components/schemas/BuildQuery' - get: - operationId: GetMavenBuildCachePerformance - summary: Get the build cache performance of a Maven Build Scan. - description: >- - This model is Maven specific and cannot be requested for another build - tool. - tags: - - Builds - - GradleEnterprise - responses: - '200': - description: The build cache performance of a Maven Build Scan. - content: - application/json: - schema: - $ref: '#/components/schemas/MavenBuildCachePerformance' - example: - id: 9r4d13f0r3v3r - buildTime: 5000 - effectiveProjectExecutionTime: 5000 - serialProjectExecutionTime: 10000 - serializationFactor: 2 - goalExecution: - - goalName: clean:clean - goalExecutionId: default-clean - goalProjectName: myproject - avoidanceOutcome: executed_not_cacheable - duration: 2000 - nonCacheabilityCategory: build_cache_disabled_by_user - nonCacheabilityReason: >- - Neither the local or remote build cache were enabled in - the configuration of the build. - - goalName: compiler:compile - mojoType: org.apache.maven.plugin.jar.JarMojo - goalExecutionId: default-compile - goalProjectName: myproject - avoidanceOutcome: avoided_from_local_cache - duration: 5000 - fingerprintingDuration: 5 - avoidanceSavings: 6000 - - goalName: compiler:compile - mojoType: org.apache.maven.plugin.jar.JarMojo - goalExecutionId: default-compile - goalProjectName: myproject2 - avoidanceOutcome: avoided_from_remote_cache - duration: 3000 - fingerprintingDuration: 3 - avoidanceSavings: 4000 - goalFingerprintingSummary: - count: 1 - serialDuration: 8 - avoidanceSavingsSummary: - total: 10000 - ratio: 0.55556 - localBuildCache: 6000 - remoteBuildCache: 4000 - buildCaches: - local: - isEnabled: true - isDisabledDueToError: false - remote: - isEnabled: true - isPushEnabled: true - isDisabledDueToError: false - overhead: - uploading: 100 - downloading: 200 - packing: 50 - unpacking: 25 - '400': - $ref: '#/components/responses/BadRequestError' - '404': - $ref: '#/components/responses/NotFoundError' - '500': - $ref: '#/components/responses/UnexpectedError' - '503': - $ref: '#/components/responses/NotReadyError' - /api/build-cache/nodes/{name}: - parameters: - - in: path - name: name - schema: - type: string - required: true - description: >- - The name of the Build Cache Node. To select the Built-in Build Cache - Node, use `Built-in` as name. - get: - operationId: GetBuildCacheNode - summary: View the configuration of a Build Cache Node. - description: >- - View the enablement status and replication configuration of a Build - Cache Node. - tags: - - BuildCache - - GradleEnterprise - responses: - '200': - description: The configuration of a Build Cache Node. - content: - application/json: - schema: - $ref: '#/components/schemas/NodeConfiguration' - example: - enabled: false - replication: - source: parent-node-1 - preemptive: true - '404': - $ref: '#/components/responses/NotFoundError' - '500': - $ref: '#/components/responses/UnexpectedError' - put: - operationId: CreateOrUpdateBuildCacheNode - summary: Create or update a Build Cache Node. - description: > - Create a new Build Cache Node in Gradle Enterprise or update the - configuration of an existing one. - - The Built-in Build Cache Node cannot be named as the target of this - operation. - tags: - - BuildCache - - GradleEnterprise - requestBody: - required: true - content: - application/json: - schema: - $ref: '#/components/schemas/NodeConfiguration' - example: - enabled: false - replication: - source: parent-node-1 - preemptive: true - responses: - '200': - description: >- - The name referenced an existing Build Cache Node and that Build - Cache Node’s configuration was updated successfully. - '201': - description: >- - A new Build Cache Node was created with the configuration specified - in the request. - '400': - $ref: '#/components/responses/BadRequestError' - '404': - $ref: '#/components/responses/NotFoundError' - /api/build-cache/nodes/{name}/secret: - parameters: - - in: path - name: name - schema: - type: string - required: true - description: The name of the Build Cache Node. - post: - operationId: RegenerateSecretOfBuildCacheNode - summary: Regenerate the secret of a Build Cache Node. - description: > - Regenerates the secret associated with the named Build Cache Node. The - old secret expires immediately, causing the Build Cache Node to - - disconnect from Gradle Enterprise. The Built-in Build Cache Node cannot - be named as the target of this operation. - tags: - - BuildCache - - GradleEnterprise - responses: - '200': - description: >- - The name referenced an existing Build Cache Node and that Build - Cache Node's secret was regenerated. - content: - application/json: - schema: - $ref: '#/components/schemas/KeySecretPair' - example: - key: cvzxztkqkqxzc3vcruabpcr264 - secret: e5ag76yp6abcc5jbxusboca313 - '404': - $ref: '#/components/responses/NotFoundError' - '500': - $ref: '#/components/responses/UnexpectedError' - /api/build-cache/nodes/{name}/purge: - parameters: - - in: path - name: name - schema: - type: string - required: true - description: >- - The name of the Build Cache Node. To select the Built-in Build Cache - Node, use `Built-in` as name. - post: - operationId: InitiatePurgeOfBuildCacheNode - summary: Deletes all entries from a Build Cache Node. - description: > - Triggers the deletion of all entries stored at the named Build Cache - Node. - tags: - - BuildCache - - GradleEnterprise - responses: - '202': - description: Purging the Build Cache Node was successfully initiated. - '404': - $ref: '#/components/responses/NotFoundError' - '500': - $ref: '#/components/responses/UnexpectedError' - '503': - $ref: '#/components/responses/NodeNotSignedInError' -components: - securitySchemes: - GradleEnterpriseAccessKey: - type: http - in: header - scheme: bearer - bearerFormat: Bearer <> - description: > - All requests require a Gradle Enterprise access key as a bearer token. - - Given an access key of - `l3an7wk3j4ze5v4mi7rvgjf2p7g44nvlswg4cpvdonjs7rzd4kmq`, the required - header is `Authorization: Bearer - l3an7wk3j4ze5v4mi7rvgjf2p7g44nvlswg4cpvdonjs7rzd4kmq`. - - - Please consult the [Gradle Enterprise API User - Manual](https://docs.gradle.com/api-manual#access_control) for guidance - on how to provision access keys and check user permissions. - responses: - BadRequestError: - description: The request cannot be fulfilled due to a problem. - content: - application/problem+json: - schema: - $ref: '#/components/schemas/ApiProblem' - examples: - BuildDeletedProblemResponse: - $ref: '#/components/examples/BuildDeletedApiProblemExample' - NonApplicableModelProblemResponse: - $ref: '#/components/examples/NonApplicableModelApiProblemExample' - RequestValidationApiProblemResponse: - $ref: '#/components/examples/RequestValidationApiProblemExample' - NotFoundError: - description: >- - The referenced resource either does not exist or the permissions to know - about it are missing. - content: - application/problem+json: - schema: - $ref: '#/components/schemas/ApiProblem' - examples: - NotFoundResponse: - $ref: '#/components/examples/NotFoundApiProblemExample' - UnexpectedError: - description: The server encountered an unexpected error. - content: - application/problem+json: - schema: - $ref: '#/components/schemas/ApiProblem' - examples: - UnexpectedErrorResponse: - $ref: '#/components/examples/UnexpectedErrorApiProblemExample' - NotReadyError: - description: The server is not ready to handle the request. - content: - application/problem+json: - schema: - $ref: '#/components/schemas/ApiProblem' - examples: - IngestionNotCompletedResponse: - $ref: '#/components/examples/IngestionNotCompletedApiProblemExample' - NodeNotSignedInError: - description: The node was not signed in with Gradle Enterprise. - content: - application/problem+json: - schema: - $ref: '#/components/schemas/ApiProblem' - examples: - NodeNotSignedInResponse: - $ref: '#/components/examples/NodeNotSignedInProblemExample' - schemas: - ApiProblem: - type: object - description: > - Response detailing why a request was rejected. - - Adheres to the [RFC-7807](https://datatracker.ietf.org/doc/html/rfc7807) - standard (colloquially known as "Problem JSON") for the response format. - required: - - type - - title - - status - properties: - status: - type: integer - description: HTTP status code of the problem response. - type: - type: string - description: A URN (Uniform Resource Name) identifying the type of the problem. - title: - type: string - description: The underlying reason for the problem. - detail: - type: string - description: >- - A longer and comprehensive description of the problem. May be `null` - if not available. - x-nullable: true - Build: - type: object - description: A build with basic attributes of a Build Scan. - required: - - id - - availableAt - - buildToolType - - buildToolVersion - - buildAgentVersion - properties: - id: - type: string - description: The Build Scan ID. - availableAt: - type: integer - format: int64 - description: >- - The time in milliseconds from the Epoch as of when the Build Scan - has been received. - buildToolType: - type: string - description: The build tool type used to caputre the Build Scan. - buildToolVersion: - type: string - description: The build tool version used. - buildAgentVersion: - type: string - description: The build agent version used. - Builds: - type: array - items: - $ref: '#/components/schemas/Build' - description: List of builds with basic attributes of a Build Scan. - BuildQuery: - type: object - properties: - availabilityWaitTimeoutSecs: - type: integer - minimum: 0 - description: >- - The time in seconds the server should wait for ingestion before - returning a wait timeout response. - BuildAttributesValue: - type: object - description: A Build Scan value. - required: - - name - properties: - name: - type: string - description: The name of the Build Scan value. - value: - type: string - description: >- - The value of the Build Scan value. May be `null` if the Build Scan - value is not set. - BuildAttributesLink: - type: object - description: A Build Scan link. - required: - - label - - url - properties: - label: - type: string - description: The label of the Build Scan link. - url: - type: string - description: The url of the Build Scan link. - GradleGradleEnterpriseSettings: - type: object - description: Settings for Gradle Enterprise. - properties: - backgroundPublicationEnabled: - type: boolean - description: >- - Whether background Build Scan publication was enabled for the build. - May be `null` if Gradle version is < `5.0` or Gradle Enterprise - Gradle plugin version is < `3.4`. See - https://docs.gradle.com/enterprise/gradle-plugin/#configuring_background_uploading. - x-nullable: true - buildOutputCapturingEnabled: - type: boolean - description: >- - Whether build logging output capturing was enabled for the build. - May be `null` if Gradle version is < `5.0` or Gradle Enterprise - Gradle plugin version is < `3.7`. See - https://docs.gradle.com/enterprise/gradle-plugin/#capturing_build_and_test_outputs. - x-nullable: true - taskInputsFileCapturingEnabled: - type: boolean - description: >- - Whether task input file snapshots capturing was enabled for the - build. May be `null` if Gradle version is < `5.0` or Gradle - Enterprise Gradle plugin version is < `2.1`. See - https://docs.gradle.com/enterprise/gradle-plugin/#capturing_task_input_files. - x-nullable: true - testOutputCapturingEnabled: - type: boolean - description: >- - Whether test logging output capturing was enabled for the build. May - be `null` if Gradle version is < `5.0` or Gradle Enterprise Gradle - plugin version is < `3.7`. See - https://docs.gradle.com/enterprise/gradle-plugin/#capturing_build_and_test_outputs. - x-nullable: true - GradleBuildOptions: - type: object - description: Gradle build options for this build. - required: - - configurationOnDemandEnabled - - continuousBuildEnabled - - continueOnFailureEnabled - - daemonEnabled - - dryRunEnabled - - maxNumberOfGradleWorkers - - offlineModeEnabled - - parallelProjectExecutionEnabled - - refreshDependenciesEnabled - - rerunTasksEnabled - properties: - buildCacheEnabled: - type: boolean - description: >- - Whether the build cache was enabled for the build. May be `null` if - Gradle version is < `3.1` or Gradle Enterprise Gradle plugin version - is < `1.3`. See - https://docs.gradle.org/current/javadoc/org/gradle/StartParameter.html#isBuildCacheEnabled--. - x-nullable: true - configurationCacheEnabled: - type: boolean - description: >- - Whether the configuration cache was enabled for the build. May be - `null` if Gradle version is < `6.6` or Gradle Enterprise Gradle - plugin version is < `3.4`. See - https://docs.gradle.org/current/userguide/configuration_cache.html. - x-nullable: true - configurationOnDemandEnabled: - type: boolean - description: >- - Whether configuration on demand mode was enabled for the build. See - https://docs.gradle.org/current/userguide/multi_project_configuration_and_execution.html#sec:configuration_on_demand. - continuousBuildEnabled: - type: boolean - description: >- - Whether continuous build mode was running for the build. See - https://docs.gradle.org/current/userguide/command_line_interface.html#sec:continuous_build. - continueOnFailureEnabled: - type: boolean - description: >- - Whether continue on failure mode was set for the build. See - https://docs.gradle.org/current/userguide/command_line_interface.html#sec:continue_build_on_failure. - daemonEnabled: - type: boolean - description: >- - Whether the build was run with the Gradle Daemon. See - https://docs.gradle.org/current/userguide/gradle_daemon.html. - dryRunEnabled: - type: boolean - description: >- - Whether the dry run flag was set for the build. See - https://docs.gradle.org/current/userguide/command_line_interface.html#sec:command_line_execution_options. - fileSystemWatchingEnabled: - type: boolean - description: >- - Whether file system watching was enabled for the build. May be - `null` if Gradle version is < `6.6` or Gradle Enterprise Gradle - plugin version is < `3.4`. See - https://docs.gradle.org/current/userguide/gradle_daemon.html#sec:daemon_watch_fs. - x-nullable: true - maxNumberOfGradleWorkers: - type: integer - description: >- - The maximum number of build workers used to run the build. See - https://docs.gradle.org/current/userguide/command_line_interface.html#sec:command_line_performance. - offlineModeEnabled: - type: boolean - description: >- - Whether the offline mode was set for the build. See - https://docs.gradle.org/current/userguide/dynamic_versions.html#sec:offline-mode. - parallelProjectExecutionEnabled: - type: boolean - description: >- - Whether parallel project execution was enabled for the build. See - https://docs.gradle.org/current/userguide/multi_project_configuration_and_execution.html#sec:parallel_execution. - refreshDependenciesEnabled: - type: boolean - description: >- - Whether the build was set to refresh all dependencies in the - dependency cache. See - https://docs.gradle.org/current/userguide/dynamic_versions.html#sec:refreshing-dependencies. - rerunTasksEnabled: - type: boolean - description: >- - Whether the build was forced to run all the tasks, ignoring any - up-to-date checks. - https://docs.gradle.org/current/userguide/command_line_interface.html#sec:rerun_tasks. - BuildAttributesEnvironment: - type: object - description: The environment where the build has been executed. - required: - - operatingSystem - - numberOfCpuCores - - jreVersion - - jvmVersion - - jvmMaxMemoryHeapSize - - jvmLocale - properties: - username: - type: string - description: >- - Operating system username of the build user. May be `null` if no - username was captured. - x-nullable: true - operatingSystem: - type: string - description: Operating system of the build machine. - numberOfCpuCores: - type: integer - description: Number of cores available to the build JVM. - jreVersion: - type: string - description: Version of the Java runtime that executed the build. - jvmVersion: - type: string - description: Version of the Java Virtual Machine that executed the build. - jvmMaxMemoryHeapSize: - type: integer - format: int64 - description: Maximum heap memory available to the build JVM in bytes. - jvmCharset: - type: string - description: >- - The default charset of the JVM that executed the build. May be - `null` if capturing was not possible. - x-nullable: true - jvmLocale: - type: string - description: The locale of the JVM that executed the build. - publicHostname: - type: string - description: >- - The hostname of the build machine, as seen on the network. May be - `null` if capturing was not possible. - x-nullable: true - localHostname: - type: string - description: >- - The hostname of the build machine, as specified by itself. May be - `null` if capturing was not possible. - x-nullable: true - localIpAddresses: - type: array - items: - type: string - description: >- - The local IP addresses of the build machine. May be `null` if - capturing was not possible. - x-nullable: true - GradleAttributes: - type: object - description: The attributes of a Gradle Build Scan. - required: - - id - - buildStartTime - - buildDuration - - gradleVersion - - pluginVersion - - requestedTasks - - hasFailed - - tags - - values - - links - - gradleEnterpriseSettings - - buildOptions - - environment - properties: - id: - type: string - description: The Build Scan ID. - buildStartTime: - type: integer - format: int64 - description: The time when the build started, as milliseconds since Epoch. - buildDuration: - type: integer - format: int64 - description: The duration of the build, as milliseconds since Epoch. - gradleVersion: - type: string - description: The Gradle version used. - pluginVersion: - type: string - description: The Gradle Enterprise Gradle plugin version used. - rootProjectName: - type: string - description: >- - The root project name. May be `null` in case of very early build - failure. - x-nullable: true - requestedTasks: - type: array - items: - type: string - description: The list of requested tasks. - hasFailed: - type: boolean - description: True when the build failed, false otherwise. - tags: - type: array - items: - type: string - description: The list of Build Scan tags. - values: - type: array - items: - $ref: '#/components/schemas/BuildAttributesValue' - description: The list of Build Scan values. - links: - type: array - items: - $ref: '#/components/schemas/BuildAttributesLink' - description: The list of Build Scan links. - gradleEnterpriseSettings: - $ref: '#/components/schemas/GradleGradleEnterpriseSettings' - buildOptions: - $ref: '#/components/schemas/GradleBuildOptions' - environment: - $ref: '#/components/schemas/BuildAttributesEnvironment' - MavenGradleEnterpriseSettings: - type: object - description: Settings for Gradle Enterprise. - properties: - backgroundPublicationEnabled: - type: boolean - description: >- - Whether background Build Scan publication was enabled for the build. - May be `null` if Gradle Enterprise Maven extension version is < - `1.6`. See - https://docs.gradle.com/enterprise/maven-extension/#configuring_background_uploading. - x-nullable: true - buildOutputCapturingEnabled: - type: boolean - description: >- - Whether to capture build logging output for the build. May be `null` - if Gradle Enterprise Maven extension version is < `1.11`. See - https://docs.gradle.com/enterprise/maven-extension/#capturing_build_and_test_outputs. - x-nullable: true - goalInputsFileCapturingEnabled: - type: boolean - description: >- - Whether to capture goal input file snapshots for the build. May be - `null` if Gradle Enterprise Maven extension version is < `1.1`. See - https://docs.gradle.com/enterprise/maven-extension/#capturing_goal_input_files. - x-nullable: true - testOutputCapturingEnabled: - type: boolean - description: >- - Whether to capture test logging output for the build. May be `null` - if Gradle Enterprise Maven extension version is < `1.11`. See - https://docs.gradle.com/enterprise/maven-extension/#capturing_build_and_test_outputs. - x-nullable: true - MavenBuildOptions: - type: object - description: Maven build options for this build. - required: - - errorsEnabled - - maxNumberOfThreads - - nonRecursiveEnabled - - noSnapshotsUpdatesEnabled - - offlineModeEnabled - - updateSnapshotsEnabled - properties: - batchModeEnabled: - type: boolean - description: >- - Whether the build was configured to run in non-interactive (batch) - mode. May be `null` if capturing was not possible. See - https://maven.apache.org/ref/current/maven-embedder/cli.html#batch-mode. - x-nullable: true - debugEnabled: - type: boolean - description: >- - Whether the build was configured to produce execution debug output. - May be `null` if capturing was not possible. See - https://maven.apache.org/ref/current/maven-embedder/cli.html#debug. - x-nullable: true - errorsEnabled: - type: boolean - description: >- - Whether the build was configured to produce execution error - messages. See - https://maven.apache.org/ref/current/maven-embedder/cli.html#errors. - failAtEndEnabled: - type: boolean - description: >- - Whether the build was configured to only fail at the end. May be - `null` if capturing was not possible. See - https://maven.apache.org/ref/current/maven-embedder/cli.html#fail-at-end. - x-nullable: true - failFastEnabled: - type: boolean - description: >- - Whether the build was configured to fail at the first error. May be - `null` if capturing was not possible. See - https://maven.apache.org/ref/current/maven-embedder/cli.html#fail-fast. - x-nullable: true - failNeverEnabled: - type: boolean - description: >- - Whether the build was configured to never fail, regardless of errors - produced. May be `null` if capturing was not possible. See - https://maven.apache.org/ref/current/maven-embedder/cli.html#fail-never. - x-nullable: true - laxChecksumsEnabled: - type: boolean - description: >- - Whether the build was configured to only warn if checksums don't - match. May be `null` if capturing was not possible. See - https://maven.apache.org/ref/current/maven-embedder/cli.html#lax-checksums. - x-nullable: true - maxNumberOfThreads: - type: integer - description: >- - Maximum number of threads used when executing the build. See - https://cwiki.apache.org/confluence/display/MAVEN/Parallel+builds+in+Maven+3. - nonRecursiveEnabled: - type: boolean - description: >- - Whether the build was configured to not recurse into sub-projects. - See - https://maven.apache.org/ref/current/maven-embedder/cli.html#non-recursive. - rerunGoals: - type: boolean - description: >- - Whether the build was configured to rerun goals without checking the - build cache. May be `null` if Gradle Enterprise Maven extension - version is < `1.13`. See - https://docs.gradle.com/enterprise/maven-extension/#rerunning_goals. - x-nullable: true - noSnapshotsUpdatesEnabled: - type: boolean - description: >- - Whether the build was configured to suppress snapshot updates. See - https://maven.apache.org/ref/current/maven-embedder/cli.html#no-snapshot-updates. - offlineModeEnabled: - type: boolean - description: >- - Whether the build was configured to run offline. See - https://maven.apache.org/ref/current/maven-embedder/cli.html#offline. - quietEnabled: - type: boolean - description: >- - Whether the build was configured to run in quiet mode. May be `null` - if capturing was not possible. See - https://maven.apache.org/ref/current/maven-embedder/cli.html#quiet. - x-nullable: true - strictChecksumsEnabled: - type: boolean - description: >- - Whether the build was configured to fail if checksums don't match. - May be `null` if capturing was not possible. See - https://maven.apache.org/ref/current/maven-embedder/cli.html#strict-checksums. - x-nullable: true - updateSnapshotsEnabled: - type: boolean - description: >- - Whether the build was configured to force a check for missing - releases and updated snapshots on remote repositories. See - https://maven.apache.org/ref/current/maven-embedder/cli.html#update-snapshots. - MavenAttributes: - type: object - description: The attributes of a Maven Build Scan. - required: - - id - - buildStartTime - - buildDuration - - mavenVersion - - extensionVersion - - requestedGoals - - hasFailed - - tags - - values - - links - - gradleEnterpriseSettings - - buildOptions - - environment - properties: - id: - type: string - description: The Build Scan ID. - buildStartTime: - type: integer - format: int64 - description: The time when the build started, as milliseconds since Epoch. - buildDuration: - type: integer - format: int64 - description: The duration of the build, as milliseconds since Epoch. - mavenVersion: - type: string - description: The Maven version used. - extensionVersion: - type: string - description: The Gradle Enterprise Maven extension version used. - topLevelProjectName: - type: string - description: >- - The top level project name. May be `null` in case of very early - build failure. - x-nullable: true - requestedGoals: - type: array - items: - type: string - description: The list of requested goals. - hasFailed: - type: boolean - description: True when the build failed, false otherwise. - tags: - type: array - items: - type: string - description: The list of Build Scan tags. - values: - type: array - items: - $ref: '#/components/schemas/BuildAttributesValue' - description: The list of Build Scan values. - links: - type: array - items: - $ref: '#/components/schemas/BuildAttributesLink' - description: The list of Build Scan links. - gradleEnterpriseSettings: - $ref: '#/components/schemas/MavenGradleEnterpriseSettings' - buildOptions: - $ref: '#/components/schemas/MavenBuildOptions' - environment: - $ref: '#/components/schemas/BuildAttributesEnvironment' - GradleBuildCachePerformanceTaskExecutionEntry: - type: object - required: - - taskPath - - avoidanceOutcome - - duration - properties: - taskPath: - type: string - description: The full task path. - taskType: - type: string - description: The fully qualified class name of the task. - avoidanceOutcome: - type: string - enum: - - avoided_up_to_date - - avoided_from_local_cache - - avoided_from_remote_cache - - executed_cacheable - - executed_not_cacheable - - executed_unknown_cacheability - - lifecycle - - no-source - - skipped - description: | - The avoidance outcome of this task with respect to performance: - * `avoided_up_to_date` - Task whose execution was avoided due to build incrementalism - * `avoided_from_local_cache` - Task whose execution was avoided due to reusing a local build cache entry - * `avoided_from_remote_cache` - Task whose execution was avoided due to reusing a remote build cache entry - * `executed_cacheable` - Task which was executed but was cacheable - * `executed_not_cacheable` - Task which was executed but was not cacheable - * `executed_unknown_cacheability` - Task which was executed and whose cacheability could not be determined - * `lifecycle` - Lifecycle task - * `no-source` - No-source task - * `skipped` - Skipped task - duration: - type: integer - format: int64 - description: The task duration in milliseconds. - fingerprintingDuration: - type: integer - format: int64 - description: >- - The task fingerprinting duration in milliseconds. This duration is - part of the complete task execution duration. May be `null` if the - task was not fingerprinted, or the information was not available. - x-nullable: true - avoidanceSavings: - type: integer - format: int64 - description: >- - The task avoidance savings in milliseconds, which can be negative. - Negative values indicate that it took more time to reuse outputs - than it did to create them originally. May be `null` if the - information was not available. - x-nullable: true - nonCacheabilityCategory: - type: string - enum: - - build_cache_not_enabled - - cache-if_condition_not_matched - - disabled_to_ensure_correctness - - do-not-cache-if_condition_matched - - multiple_outputs_declared - - no_outputs_declared - - non_cacheable_inputs - - non_cacheable_task_action - - non_cacheable_task_implementation - - non_cacheable_tree_output - - overlapping_outputs - - task_has_no_actions - - task_output_caching_not_enabled - - unknown - description: > - The category of the non-cacheability reason: - * `build_cache_not_enabled` - Caching has not been enabled for the build - * `cache-if_condition_not_matched` - Caching was disabled for the task via `org.gradle.api.tasks.TaskOutputs#cacheIf` - * `disabled_to_ensure_correctness` - The task failed validation. Available since Gradle 7.0 - * `do-not-cache-if_condition_matched` - Caching was disabled for the task via `org.gradle.api.tasks.TaskOutputs#doNotCacheIf` - * `multiple_outputs_declared` - The task declared multiple outputs - * `no_outputs_declared` - The task had no outputs declared - * `non_cacheable_inputs` - One of the task inputs was not cacheable, either because some type used as an input to the task was loaded via a custom classloader, or a Java lambda was used as an input. Available since Gradle 5.0 and before Gradle 7.5 - * `non_cacheable_task_action` - One of the task actions was not cacheable, either because it was loaded via a custom classloader, or a Java lambda was used to implement it. Available since Gradle 5.0 and before Gradle 7.5 - * `non_cacheable_task_implementation` - The task implementation was not cacheable, either because it was loaded via a custom classloader, or a Java lambda was used to implement it. Available since Gradle 5.0 and before Gradle 7.5 - * `non_cacheable_tree_output` - The task had a `org.gradle.api.file.FileTree` or a `org.gradle.api.internal.file.collections.DirectoryFileTree` as an output. Available since Gradle 5.0 - * `overlapping_outputs` - The tasks outputs overlapped with another task. As Gradle cannot safely determine which task each output file belongs to, it disabled caching - * `task_has_no_actions` - The task did not declare any actions - * `task_output_caching_not_enabled` - Caching has not been enabled for the task - * `unknown` - Reason for disabled caching was not known - - May be `null` when the task was cacheable or if the information was - not available. - x-nullable: true - nonCacheabilityReason: - type: string - description: >- - The human-readable reason for a non-cacheable task. May be `null` - when the task was cacheable or if the information was not available. - x-nullable: true - GradleBuildCachePerformanceTaskExecution: - type: array - description: A list of executed tasks with performance related information. - items: - $ref: '#/components/schemas/GradleBuildCachePerformanceTaskExecutionEntry' - GradleBuildCachePerformanceTaskFingerprintingSummary: - type: object - description: >- - A summary of task fingerprinting. Fingerprinted tasks are part of the - `taskExecution.avoidedTasks` or `taskExecution.executedTasks`, or - `taskExecution.noSourceTasks` buckets. May be `null` if Gradle version - is < `5.0` or Gradle Enterprise Gradle plugin version is < `2.1`. - x-nullable: true - required: - - count - - serialDuration - properties: - count: - type: integer - description: Count of fingerprinted tasks. - serialDuration: - type: integer - format: int64 - description: >- - Sum of all fingerprinting times of fingerprinted tasks in - milliseconds. - GradleBuildCachePerformanceAvoidanceSavingsSummary: - type: object - description: A breakdown of avoidance savings. - required: - - total - - ratio - - upToDate - - localBuildCache - - remoteBuildCache - properties: - total: - type: integer - format: int64 - description: >- - The estimated reduction in serial execution time of the tasks due to - their outputs being reused in milliseconds. - ratio: - type: number - format: double - description: >- - The ratio of the total avoidance savings against the potential - serial execution time (which is the actual serial execution time - plus the total avoidance savings). Quantifies the effect of - avoidance savings in this build. The bigger the ratio is, the more - time was saved when running the build. - upToDate: - type: integer - format: int64 - description: >- - The estimated reduction in serial execution time of the tasks due to - build incrementalism in milliseconds. - localBuildCache: - type: integer - format: int64 - description: >- - The estimated reduction in serial execution time of the tasks due to - their outputs being reused from the local build cache in - milliseconds. - remoteBuildCache: - type: integer - format: int64 - description: >- - The estimated reduction in serial execution time of the tasks due to - their outputs being reused from the remote build cache in - milliseconds. - GradleBuildCachePerformanceBuildCacheLocalInfo: - type: object - description: Information about the local build cache used in the build. - required: - - isEnabled - properties: - isEnabled: - type: boolean - description: Whether the local build cache was enabled. - isPushEnabled: - type: boolean - description: >- - Whether pushing to the local build cache was enabled. May be `null` - if the local build cache is disabled. - x-nullable: true - isDisabledDueToError: - type: boolean - description: >- - Whether the local cache was disabled due to an error occuring in - loading or storing local build cache entries. - x-nullable: true - directory: - type: string - description: >- - Location of the local build cache. Can be relative or absolute - depending on its value. May be `null` if the local build cache is - disabled. - x-nullable: true - GradleBuildCachePerformanceBuildCacheRemoteInfo: - type: object - description: Information about the remote build cache used in the build. - required: - - isEnabled - properties: - isEnabled: - type: boolean - description: Whether the remote build cache was enabled. - isPushEnabled: - type: boolean - description: >- - Whether pushing to the remote build cache was enabled. May be `null` - if the remote build cache is disabled. - x-nullable: true - isDisabledDueToError: - type: boolean - description: >- - Wether the remote build cache was disabled during the build due to - an error occuring in loading or storing remote build cache entries. - x-nullable: true - url: - type: string - description: >- - URL of the remote build cache. May be `null` if the remote build - cache is disabled. - x-nullable: true - GradleBuildCachePerformanceBuildCacheOverhead: - type: object - description: Information about the build cache overhead in this build. - required: - - uploading - - downloading - - packing - - unpacking - properties: - uploading: - type: integer - format: int64 - description: Overhead of upload operations in milliseconds. - downloading: - type: integer - format: int64 - description: Overhead of download operations in milliseconds. - packing: - type: integer - format: int64 - description: Overhead of pack operations in milliseconds. - unpacking: - type: integer - format: int64 - description: Overhead of unpack operations in milliseconds. - GradleBuildCachePerformanceBuildCaches: - type: object - description: >- - Information about the local and remote build caches used in the build. - May be `null` if the build cache is globally disabled. - x-nullable: true - required: - - local - - remote - - overhead - properties: - local: - $ref: '#/components/schemas/GradleBuildCachePerformanceBuildCacheLocalInfo' - remote: - $ref: '#/components/schemas/GradleBuildCachePerformanceBuildCacheRemoteInfo' - overhead: - $ref: '#/components/schemas/GradleBuildCachePerformanceBuildCacheOverhead' - GradleBuildCachePerformance: - type: object - description: The build cache performance of a Gradle Build Scan. - required: - - id - - buildTime - - effectiveTaskExecutionTime - - serialTaskExecutionTime - - serializationFactor - - taskExecution - - avoidanceSavingsSummary - properties: - id: - type: string - description: The Build Scan ID. - buildTime: - type: integer - format: int64 - description: Wall clock duration of the build in milliseconds. - effectiveTaskExecutionTime: - type: integer - format: int64 - description: >- - Wall clock time spent executing tasks in milliseconds. It is the - time spent between the start of the first task in the execution - phase and the end of the last task of the execution phase, removing - any interval where no task is being executed. - serialTaskExecutionTime: - type: integer - format: int64 - description: >- - Wall clock time of all task executions in milliseconds. It is the - sum of all individual task durations. - serializationFactor: - type: number - format: double - description: >- - The ratio of `serialTaskExecutionTime` over the - `effectiveTaskExecutionTime`. Quantifies the effect of task - parallelization. A value equal to `1` means that no parallelization - occurred. A value greater than `1` means that tasks were executed - faster due to parallelization. - taskExecution: - $ref: '#/components/schemas/GradleBuildCachePerformanceTaskExecution' - taskFingerprintingSummary: - $ref: >- - #/components/schemas/GradleBuildCachePerformanceTaskFingerprintingSummary - avoidanceSavingsSummary: - $ref: >- - #/components/schemas/GradleBuildCachePerformanceAvoidanceSavingsSummary - buildCaches: - $ref: '#/components/schemas/GradleBuildCachePerformanceBuildCaches' - MavenBuildCachePerformanceGoalExecutionEntry: - type: object - required: - - goalName - - mojoType - - goalExecutionId - - goalProjectName - - avoidanceOutcome - - duration - properties: - goalName: - type: string - description: The goal name. - mojoType: - type: string - description: >- - The fully qualified class name of the Mojo that provides the - implementation of this goal. - goalExecutionId: - type: string - description: The goal execution ID. - goalProjectName: - type: string - description: The goal project name. - avoidanceOutcome: - type: string - enum: - - avoided_from_local_cache - - avoided_from_remote_cache - - executed_cacheable - - executed_not_cacheable - - executed_unknown_cacheability - - skipped - description: | - The avoidance outcome of this task with respect to performance: - * `avoided_from_local_cache` - Goal whose execution was avoided due to reusing a local build cache entry - * `avoided_from_remote_cache` - Goal whose execution was avoided due to reusing a remote build cache entry - * `executed_cacheable` - Goal which was executed but was cacheable - * `executed_not_cacheable` - Goal which was executed but was not cacheable - * `executed_unknown_cacheability` - Goal which was executed and whose cacheability could not be determined - * `skipped` - Skipped goal - duration: - type: integer - format: int64 - description: The goal duration in milliseconds. - fingerprintingDuration: - type: integer - format: int64 - description: >- - The goal fingerprinting duration in milliseconds. This duration is - part of the complete task execution duration. May be `null` if the - goal was not fingerprinted. - x-nullable: true - avoidanceSavings: - type: integer - format: int64 - description: >- - The goal avoidance savings in milliseconds, which can be negative. - Negative values indicate that it took more time to reuse outputs - than it did to create them originally. May be `null` if the - information was not available. - x-nullable: true - nonCacheabilityCategory: - type: string - enum: - - build_cache_disabled_by_user - - goal_execution_marked_non_cacheable - - goal_not_supported - - no_gradle_enterprise_server_configured - - non_clean_build - - not_entitled - - offline_build - - unknown - - unknown_entitlements - description: > - The category of the non-cacheability reason: - * `build_cache_disabled_by_user` - The build cache was disabled by the user - * `goal_execution_marked_non_cacheable` - The goal execution was marked as non-cacheable - * `goal_not_supported` - The goal did not support build caching - * `no_gradle_enterprise_server_configured` - No Gradle Enterprise server was configured - * `non_clean_build` - The `clean` lifecycle was not executed - * `not_entitled` - The Gradle Enterprise license entitlements did not allow Maven build caching - * `offline_build` - The build was run in offline mode - * `unknown` - Reason for disabled caching was not known - * `unknown_entitlements` - The Gradle Enterprise license entitlements could not be checked - - May be `null` when the goal execution was cacheable or if the - information was not available. - x-nullable: true - nonCacheabilityReason: - type: string - description: >- - The human-readable reason for a non-cacheable goal execution. May be - `null` when the goal execution was cacheable or if the information - was not available. - x-nullable: true - MavenBuildCachePerformanceGoalExecution: - type: array - description: A list of executed goals with performance related information. - items: - $ref: '#/components/schemas/MavenBuildCachePerformanceGoalExecutionEntry' - MavenBuildCachePerformanceGoalFingerprintingSummary: - type: object - description: >- - A summary of goal fingerprinting. Fingerprinted goals are part of the - `goalExecution.avoidedGoals` or `goalExecution.executedGoals` buckets. - required: - - count - - serialDuration - properties: - count: - type: integer - description: Count of fingerprinted goals. - serialDuration: - type: integer - format: int64 - description: >- - Sum of all fingerprinting times of fingerprinted goals in - milliseconds. - MavenBuildCachePerformanceAvoidanceSavingsSummary: - type: object - description: A breakdown of avoidance savings. - required: - - total - - ratio - - localBuildCache - - remoteBuildCache - properties: - total: - type: integer - format: int64 - description: >- - The estimated reduction in serial execution time of the goals due to - their outputs being reused in milliseconds. - ratio: - type: number - format: double - description: >- - The ratio of the total avoidance savings against the potential - serial execution time (which is the actual serial execution time - plus the total avoidance savings). Quantifies the effect of - avoidance savings in this build. The bigger the ratio is, the more - time was saved when running the build. - localBuildCache: - type: integer - format: int64 - description: >- - The estimated reduction in serial execution time of the goals due to - their outputs being reused from the local build cache in - milliseconds. - remoteBuildCache: - type: integer - format: int64 - description: >- - The estimated reduction in serial execution time of the goals due to - their outputs being reused from the remote build cache in - milliseconds. - MavenBuildCachePerformanceBuildCacheLocalInfo: - type: object - description: >- - Information about the local build cache used in the build, if it was - configured in the build. May be `null` if the local build cache is not - configured. - x-nullable: true - required: - - isEnabled - properties: - isEnabled: - type: boolean - description: Whether the local build cache was enabled. - isPushEnabled: - type: boolean - description: >- - Whether pushing to the local build cache was enabled. May be `null` - if the local build cache is disabled. - x-nullable: true - isDisabledDueToError: - type: boolean - description: >- - Whether the local cache was disabled due to an error occuring in - loading or storing local build cache entries. - x-nullable: true - directory: - type: string - description: >- - Location of the local build cache. Can be relative or absolute - depending on its value. May be `null` if the local build cache is - disabled. - x-nullable: true - MavenBuildCachePerformanceBuildCacheRemoteInfo: - type: object - description: >- - Information about the remote build cache used in the build, if it was - configured in the build. May be `null` if the remote build cache is not - configured. - x-nullable: true - required: - - isEnabled - properties: - isEnabled: - type: boolean - description: Whether the remote build cache was enabled. - isPushEnabled: - type: boolean - description: >- - Whether pushing to the remote build cache was enabled. May be `null` - if the remote build cache is disabled. - x-nullable: true - isDisabledDueToError: - type: boolean - description: >- - Whether the remote build cache was disabled during the build due to - an error occuring in loading or storing remote build cache entries. - x-nullable: true - url: - type: string - description: >- - URL of the remote build cache. May be `null` if the remote build - cache is disabled. - x-nullable: true - MavenBuildCachePerformanceBuildCacheOverhead: - type: object - description: Information about the build cache overhead in this build. - required: - - uploading - - downloading - - packing - - unpacking - properties: - uploading: - type: integer - format: int64 - description: Overhead of upload operations in milliseconds. - downloading: - type: integer - format: int64 - description: Overhead of download operations in milliseconds. - packing: - type: integer - format: int64 - description: Overhead of pack operations in milliseconds. - unpacking: - type: integer - format: int64 - description: Overhead of unpack operations in milliseconds. - MavenBuildCachePerformanceBuildCaches: - type: object - description: >- - Information about the local and remote build caches used in the build, - if it was configured in the build. May be `null` if the build cache - configuration could not be captured (e.g. very early build failure). - x-nullable: true - required: - - overhead - properties: - local: - $ref: '#/components/schemas/MavenBuildCachePerformanceBuildCacheLocalInfo' - remote: - $ref: '#/components/schemas/MavenBuildCachePerformanceBuildCacheRemoteInfo' - overhead: - $ref: '#/components/schemas/MavenBuildCachePerformanceBuildCacheOverhead' - MavenBuildCachePerformance: - type: object - description: The build cache performance of a Maven Build Scan. - required: - - id - - buildTime - - effectiveProjectExecutionTime - - serialProjectExecutionTime - - serializationFactor - - goalExecution - - goalFingerprintingSummary - - avoidanceSavingsSummary - properties: - id: - type: string - description: The Build Scan ID. - buildTime: - type: integer - format: int64 - description: Wall clock duration of the build in milliseconds. - effectiveProjectExecutionTime: - type: integer - format: int64 - description: >- - Wall clock time spent executing projects in milliseconds. It is the - time spent between the start of the first project execution and the - end of the last project execution, removing any interval where no - project is being executed. - serialProjectExecutionTime: - type: integer - format: int64 - description: >- - Wall clock time of all project executions in milliseconds. It is the - sum of all individual project durations. - serializationFactor: - type: number - format: double - description: >- - The ratio of `serialProjectExecutionTime` over the - `effectiveProjectExecutionTime`. Quantifies the effect of project - parallelization. A value equal to `1` means that no parallelization - occurred. A value greater than `1` means that projects were executed - faster due to parallelization. - goalExecution: - $ref: '#/components/schemas/MavenBuildCachePerformanceGoalExecution' - goalFingerprintingSummary: - $ref: >- - #/components/schemas/MavenBuildCachePerformanceGoalFingerprintingSummary - avoidanceSavingsSummary: - $ref: >- - #/components/schemas/MavenBuildCachePerformanceAvoidanceSavingsSummary - buildCaches: - $ref: '#/components/schemas/MavenBuildCachePerformanceBuildCaches' - ReplicationConfiguration: - description: >- - Cached data replication configuration description. May be `null` if - replication is not configured. - type: object - x-nullable: true - required: - - source - - preemptive - properties: - source: - type: string - description: The name of the Build Cache Node which is the source of data. - preemptive: - type: boolean - description: Indicates if preemptive replication is enabled from the source. - NodeConfiguration: - description: A Build Cache Node configuration description. - type: object - required: - - enabled - properties: - enabled: - type: boolean - description: Indicates if the Build Cache Node is enabled. - replication: - $ref: '#/components/schemas/ReplicationConfiguration' - KeySecretPair: - description: A Build Cache Node key and secret pair. - type: object - required: - - key - - secret - properties: - key: - type: string - description: A unique identifier for the Build Cache Node in Gradle Enterprise. - secret: - type: string - description: The secret associated with the Build Cache Node. - examples: - BuildDeletedApiProblemExample: - value: - type: urn:gradle:enterprise:api:problems:build-deleted - title: Build deleted. - detail: | - Build 9r4d13f0r3v3r has been deleted and is no longer available. - status: 400 - NonApplicableModelApiProblemExample: - value: - type: urn:gradle:enterprise:api:problems:build-model-not-applicable - title: Build model is not applicable. - detail: > - Build model BuildCachePerformance is not available for build - 9r4d13f0r3v3r because the build agent version is not supported. - status: 400 - RequestValidationApiProblemExample: - value: - type: urn:gradle:enterprise:api:problems:validation - title: Request validation failed. - detail: > - Numeric instance is lower than the required minimum (minimum: 1, - found: 0) (Additional info: Query parameter: maxWaitSecs). - status: 400 - NotFoundApiProblemExample: - value: - type: urn:gradle:enterprise:api:problems:not-found - title: >- - The requested resource is not found or the permissions to know about - it are missing. - status: 404 - UnexpectedErrorApiProblemExample: - value: - type: urn:gradle:enterprise:api:problems:unexpected-error - title: Encountered an internal server error. - detail: | - The ingestion of build 9r4d13f0r3v3r failed. - status: 500 - IngestionNotCompletedApiProblemExample: - value: - type: urn:gradle:enterprise:api:problems:build-processing-incomplete - title: Build processing is incomplete. - detail: > - The data of build 9r4d13f0r3v3r is not yet available for viewing. - Please try again later. - status: 503 - NodeNotSignedInProblemExample: - value: - type: urn:gradle:enterprise:api:problems:node-not-signed-in - title: >- - Node with name not-signed-in-node1 must be signed-in before this - operation can be performed. - status: 503 -tags: - - name: Builds - description: > - Endpoints related to retrieving details of a Build Scan of the Gradle - Enterprise instance. - - To access these endpoints the user requires the `Access build data via the - API` permission. - - name: BuildCache - x-displayName: Build Cache - description: > - Endpoints related to configuring the Build Cache nodes of the Gradle - Enterprise instance. - - To access these endpoints the user requires the `Configure build caches` - permission. - - name: GradleEnterprise - x-traitTag: true - description: All endpoints of the Gradle Enterprise API. diff --git a/components/fetch-build-scan-data-cmdline-tool/src/test/java/com/gradle/enterprise/cli/DurationFormatTests.java b/components/fetch-build-scan-data-cmdline-tool/src/test/java/com/gradle/enterprise/cli/DurationFormatTests.java deleted file mode 100644 index ecdb6766..00000000 --- a/components/fetch-build-scan-data-cmdline-tool/src/test/java/com/gradle/enterprise/cli/DurationFormatTests.java +++ /dev/null @@ -1,38 +0,0 @@ -package com.gradle.enterprise.cli; - -import org.junit.jupiter.api.Test; - -import java.time.Duration; - -import static org.junit.jupiter.api.Assertions.assertAll; -import static org.junit.jupiter.api.Assertions.assertEquals; - -public class DurationFormatTests { - - @Test - void durationsAreFormattedCorrectly() { - assertAll( - () -> assertDurationFormatting( "0.009s", 9L), - () -> assertDurationFormatting( "0.099s", 99L), - () -> assertDurationFormatting( "0.999s", 999L), - () -> assertDurationFormatting( "9.999s", 9999L), - () -> assertDurationFormatting( "1m 39.999s", 99999L), - () -> assertDurationFormatting( "16m 39.999s", 999999L), - () -> assertDurationFormatting( "2h 46m 39.999s", 9999999L), - () -> assertDurationFormatting( "27h 46m 39.999s", 99999999L), - - () -> assertDurationFormatting( "-0.009s", -9L), - () -> assertDurationFormatting( "-0.099s", -99L), - () -> assertDurationFormatting( "-0.999s", -999L), - () -> assertDurationFormatting( "-9.999s", -9999L), - () -> assertDurationFormatting( "-1m 39.999s", -99999L), - () -> assertDurationFormatting( "-16m 39.999s", -999999L), - () -> assertDurationFormatting( "-2h 46m 39.999s", -9999999L), - () -> assertDurationFormatting("-27h 46m 39.999s", -99999999L) - ); - } - - private static void assertDurationFormatting(String expected, Long millis) { - assertEquals(expected, DurationFormat.format(Duration.ofMillis(millis))); - } -} diff --git a/components/fetch-build-scan-data-cmdline-tool/src/test/java/com/gradle/enterprise/model/NumberedBuildScanTests.java b/components/fetch-build-scan-data-cmdline-tool/src/test/java/com/gradle/enterprise/model/NumberedBuildScanTests.java deleted file mode 100644 index fb5404d0..00000000 --- a/components/fetch-build-scan-data-cmdline-tool/src/test/java/com/gradle/enterprise/model/NumberedBuildScanTests.java +++ /dev/null @@ -1,42 +0,0 @@ -package com.gradle.enterprise.model; - -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.ValueSource; - -import java.net.URL; - -import static org.junit.jupiter.api.Assertions.assertAll; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertThrows; - -class NumberedBuildScanTests { - - @ParameterizedTest - @ValueSource(strings = { - "https://ge.example.com/s/7slcdesxr2xnw", - "https://ge.example.com/s/7slcdesxr2xnw/", - "https://ge.example.com/s/7slcdesxr2xnw/timeline", - "https://ge.example.com/s/7slcdesxr2xnw/console-log?page=1", - "https://ge.example.com/s/7slcdesxr2xnw/projects#:foo-service" - }) - void validBuildScanUrlsAreCorrectlyParsed(String buildScanUrl) { - final NumberedBuildScan numberedBuildScan = NumberedBuildScan.parse("0," + buildScanUrl); - assertAll( - () -> assertEquals(new URL("https://ge.example.com"), numberedBuildScan.baseUrl()), - () -> assertEquals("7slcdesxr2xnw", numberedBuildScan.buildScanId()) - ); - } - - @ParameterizedTest - @ValueSource(strings = { - "https://ge.example.com", - "https://ge.example.com/", - "https://ge.example.com/s", - "https://ge.example.com/s/", - "https://ge.example.com/S/", - "https://ge.example.com/S/7slcdesxr2xnw", - }) - void invalidBuildScanUrlsThrowException(String buildScanUrl) { - assertThrows(IllegalArgumentException.class, () -> NumberedBuildScan.parse("0," + buildScanUrl)); - } -} diff --git a/components/licenses/gradle/LICENSE b/components/licenses/gradle/LICENSE new file mode 100644 index 00000000..fe32f647 --- /dev/null +++ b/components/licenses/gradle/LICENSE @@ -0,0 +1,11 @@ +Copyright 2024 Gradle, Inc. + +The files titled 01-validate-incremental-building.sh, 02-validate-local-build-caching-same-location.sh, 03-validate-local-build-caching-different-locations.sh, 04-validate-remote-build-caching-ci-ci.sh, 05-validate-remote-build-caching-ci-local.sh and all files in the folder titled "lib/scripts" are licensed under the Apache License, Version 2.0 (the "Apache License"); you may not use these files except in compliance with the Apache License. You may obtain a copy of the Apache License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + +All files located in the folder titled "lib/develocity" are subject to and licensed pursuant to the Gradle, Inc. Terms of Use, available at https://gradle.com/legal/terms-of-use/ (the "Gradle License"). You may not use these files except in compliance with the Gradle License. + +This content includes certain third party libraries as set forth in the folder titled "lib/third-party". For copyright and license information for these third party libraries, please see the file titled "NOTICE". diff --git a/components/licenses/maven/LICENSE b/components/licenses/maven/LICENSE new file mode 100644 index 00000000..f6b15efa --- /dev/null +++ b/components/licenses/maven/LICENSE @@ -0,0 +1,11 @@ +Copyright 2024 Gradle, Inc. + +The files titled 01-validate-local-build-caching-same-location.sh, 02-validate-local-build-caching-different-locations.sh, 03-validate-remote-build-caching-ci-ci.sh, 04-validate-remote-build-caching-ci-local.sh and all files in the folder titled "lib/scripts" are licensed under the Apache License, Version 2.0 (the "Apache License"); you may not use these files except in compliance with the Apache License. You may obtain a copy of the Apache License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + +All files located in the folder titled "lib/develocity" are subject to and licensed pursuant to the Gradle, Inc. Terms of Use, available at https://gradle.com/legal/terms-of-use/ (the "Gradle License"). You may not use these files except in compliance with the Gradle License. + +This content includes certain third party libraries as set forth in the folder titled "lib/third-party". For copyright and license information for these third party libraries, please see the file titled "NOTICE". diff --git a/components/scripts/gradle/01-validate-incremental-building.sh b/components/scripts/gradle/01-validate-incremental-building.sh index f8622510..bf759933 100755 --- a/components/scripts/gradle/01-validate-incremental-building.sh +++ b/components/scripts/gradle/01-validate-incremental-building.sh @@ -10,6 +10,7 @@ readonly EXP_NO="01" readonly EXP_SCAN_TAG=exp1-gradle readonly BUILD_TOOL="Gradle" readonly SCRIPT_VERSION="" +readonly SUMMARY_VERSION="" readonly SHOW_RUN_ID=true # Needed to bootstrap the script @@ -18,13 +19,13 @@ readonly SCRIPT_NAME # shellcheck disable=SC2164 # it is highly unlikely cd will fail here because we're cding to the location of this script SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")"; cd -P "$(dirname "$(readlink "${BASH_SOURCE[0]}" || echo .)")"; pwd)" readonly SCRIPT_DIR -readonly LIB_DIR="${SCRIPT_DIR}/lib" +readonly LIB_DIR="${SCRIPT_DIR}/lib/scripts" readonly INIT_SCRIPTS_DIR="${LIB_DIR}/gradle-init-scripts" # Include and parse the command line arguments -# shellcheck source=lib/01-cli-parser.sh +# shellcheck source=lib/scripts/01-cli-parser.sh source "${LIB_DIR}/${EXP_NO}-cli-parser.sh" || { echo -e "\033[00;31m\033[1mERROR: Couldn't find '${LIB_DIR}/${EXP_NO}-cli-parser.sh'\033[0m"; exit 100; } -# shellcheck source=lib/libs.sh +# shellcheck source=lib/scripts/libs.sh source "${LIB_DIR}/libs.sh" || { echo -e "\033[00;31m\033[1mERROR: Couldn't find '${LIB_DIR}/libs.sh'\033[0m"; exit 100; } # These will be set by the config functions (see lib/config.sh) @@ -39,10 +40,6 @@ ge_server='' interactive_mode='' main() { - if [[ "$build_scan_publishing_mode" == "off" ]]; then - verify_offline_mode_required_files_exist - fi - if [ "${interactive_mode}" == "on" ]; then wizard_execute else @@ -74,16 +71,11 @@ execute() { wizard_execute() { print_introduction - if [[ "${build_scan_publishing_mode}" == "on" ]]; then - print_bl - explain_prerequisites_ccud_gradle_plugin "I." + print_bl + explain_prerequisites_ccud_gradle_plugin "I." - print_bl - explain_prerequisites_api_access "II." - else - print_bl - explain_prerequisites_ccud_gradle_plugin - fi + print_bl + explain_prerequisites_api_access "II." print_bl explain_collect_git_details @@ -144,19 +136,11 @@ execute_build() { } print_gradle_command() { - if [[ "${build_scan_publishing_mode}" == "on" ]]; then info "./gradlew --no-build-cache -Dscan.tag.${EXP_SCAN_TAG} -Dscan.value.runId=${RUN_ID} $*$(print_extra_args)" - else - info "./gradlew --no-build-cache -Dscan.dump -Dscan.tag.${EXP_SCAN_TAG} -Dscan.value.runId=${RUN_ID} $*$(print_extra_args)" - fi } fetch_build_cache_metrics() { - if [ "$build_scan_publishing_mode" == "on" ]; then - process_build_scan_data_online - else - find_and_read_build_scan_dumps - fi + process_build_scan_data_online } # Overrides summary.sh#print_performance_characteristics @@ -274,8 +258,7 @@ EOF explain_measure_build_results() { local text - if [[ "${build_scan_publishing_mode}" == "on" ]]; then - IFS='' read -r -d '' text < to measure the build results.${RESTORE} EOF - else - IFS='' read -r -d '' text < to measure the build results.${RESTORE} -EOF - fi print_interactive_text "${text}" wait_for_enter } explain_and_print_summary() { local text - if [[ "${build_scan_publishing_mode}" == "on" ]]; then - IFS='' read -r -d '' text < to measure the build results.${RESTORE} EOF - else - IFS='' read -r -d '' text < to measure the build results.${RESTORE} -EOF - fi print_interactive_text "${text}" wait_for_enter } explain_and_print_summary() { local text - if [[ "${build_scan_publishing_mode}" == "on" ]]; then - IFS='' read -r -d '' text < to measure the build results.${RESTORE} EOF - else - IFS='' read -r -d '' text < to measure the build results.${RESTORE} -EOF - fi print_interactive_text "${text}" wait_for_enter } explain_and_print_summary() { local text - - if [[ "${build_scan_publishing_mode}" == "on" ]]; then - IFS='' read -r -d '' text </dev/null 2>&1; then diff --git a/components/scripts/lib/libs.sh b/components/scripts/lib/libs.sh index 313fdb04..f1ce4e2d 100644 --- a/components/scripts/lib/libs.sh +++ b/components/scripts/lib/libs.sh @@ -12,53 +12,50 @@ failed_to_load_lib() { exit "${_UNEXPECTED_ERROR}" } -# shellcheck source=lib/logging.sh +# shellcheck source=lib/scripts/logging.sh source "${LIB_DIR}/logging.sh" || failed_to_load_lib logging.sh -# shellcheck source=lib/build-scan-offline.sh -source "${LIB_DIR}/build-scan-offline.sh" || failed_to_load_lib build-scan-offline.sh - -# shellcheck source=lib/build-scan-parse.sh +# shellcheck source=lib/scripts/build-scan-parse.sh source "${LIB_DIR}/build-scan-parse.sh" || failed_to_load_lib build-scan-parse.sh -# shellcheck source=lib/build-scan-online.sh +# shellcheck source=lib/scripts/build-scan-online.sh source "${LIB_DIR}/build-scan-online.sh" || failed_to_load_lib build-scan-online.sh -# shellcheck source=lib/color.sh +# shellcheck source=lib/scripts/color.sh source "${LIB_DIR}/color.sh" || failed_to_load_lib color.sh -# shellcheck source=lib/config.sh +# shellcheck source=lib/scripts/config.sh source "${LIB_DIR}/config.sh" || failed_to_load_lib config.sh -# shellcheck source=lib/exit-code.sh +# shellcheck source=lib/scripts/exit-code.sh source "${LIB_DIR}/exit-code.sh" || failed_to_load_lib exit-code.sh -# shellcheck source=lib/git.sh +# shellcheck source=lib/scripts/git.sh source "${LIB_DIR}/git.sh" || failed_to_load_lib git.sh -# shellcheck source=lib/gradle.sh +# shellcheck source=lib/scripts/gradle.sh source "${LIB_DIR}/gradle.sh" || failed_to_load_lib gradle.sh -# shellcheck source=lib/help.sh +# shellcheck source=lib/scripts/help.sh source "${LIB_DIR}/help.sh" || failed_to_load_lib help.sh -# shellcheck source=lib/summary.sh +# shellcheck source=lib/scripts/summary.sh source "${LIB_DIR}/summary.sh" || failed_to_load_lib summary.sh -# shellcheck source=lib/init.sh +# shellcheck source=lib/scripts/init.sh source "${LIB_DIR}/init.sh" || failed_to_load_lib init.sh -# shellcheck source=lib/java.sh +# shellcheck source=lib/scripts/java.sh source "${LIB_DIR}/java.sh" || failed_to_load_lib java.sh -# shellcheck source=lib/maven.sh +# shellcheck source=lib/scripts/maven.sh source "${LIB_DIR}/maven.sh" || failed_to_load_lib maven.sh -# shellcheck source=lib/paths.sh +# shellcheck source=lib/scripts/paths.sh source "${LIB_DIR}/paths.sh" || failed_to_load_lib paths.sh -# shellcheck source=lib/project.sh +# shellcheck source=lib/scripts/project.sh source "${LIB_DIR}/project.sh" || failed_to_load_lib project.sh -# shellcheck source=lib/interactive-mode.sh +# shellcheck source=lib/scripts/interactive-mode.sh source "${LIB_DIR}/interactive-mode.sh" || failed_to_load_lib interactive-mode.sh diff --git a/components/scripts/lib/maven.sh b/components/scripts/lib/maven.sh index 975eb373..8a5e3cea 100644 --- a/components/scripts/lib/maven.sh +++ b/components/scripts/lib/maven.sh @@ -1,6 +1,17 @@ #!/usr/bin/env bash -readonly CONFIGURE_GRADLE_ENTERPRISE_JAR="${LIB_DIR}/maven-libs/configure-gradle-enterprise-maven-extension-${SCRIPT_VERSION}-all.jar" +find_versioned_jar() { + local dir_to_search base_name + dir_to_search="$1" + base_name="$2" + + find "${dir_to_search}" -name "${base_name}*" -type f -print -quit +} + +CONFIGURE_GRADLE_ENTERPRISE_JAR="${LIB_DIR}/maven-libs/configure-gradle-enterprise-maven-extension-${SCRIPT_VERSION}-all.jar" +GRADLE_ENTERPRISE_MAVEN_EXTENSION_JAR="$(find_versioned_jar "${SCRIPT_DIR}/lib/develocity" "gradle-enterprise-maven-extension")" +COMMON_CUSTOM_USER_DATA_MAVEN_EXTENSION_JAR="$(find_versioned_jar "${SCRIPT_DIR}/lib/third-party" "common-custom-user-data-maven-extension")" +readonly CONFIGURE_GRADLE_ENTERPRISE_JAR GRADLE_ENTERPRISE_MAVEN_EXTENSION_JAR COMMON_CUSTOM_USER_DATA_MAVEN_EXTENSION_JAR find_maven_executable() { if [ -f "./mvnw" ]; then @@ -31,19 +42,7 @@ invoke_maven() { extension_classpath="${CONFIGURE_GRADLE_ENTERPRISE_JAR}" if [ "$enable_ge" == "on" ]; then - # Reset the extension classpath and add all of the jars in the lib/maven dir - # The lib/maven dir includes: - # - the Gradle Enterprise Maven extension - # - the Common Custom User Data Maven extension - # - the configure-gradle-enterprise Maven extension - extension_classpath="" - for jar in "${LIB_DIR}"/maven-libs/*; do - if [ "${extension_classpath}" == "" ]; then - extension_classpath="${jar}" - else - extension_classpath="${extension_classpath}:${jar}" - fi - done + extension_classpath="${extension_classpath}:${GRADLE_ENTERPRISE_MAVEN_EXTENSION_JAR}:${COMMON_CUSTOM_USER_DATA_MAVEN_EXTENSION_JAR}" fi if [ -n "${ge_server}" ]; then @@ -51,11 +50,6 @@ invoke_maven() { args+=("-Dgradle.enterprise.allowUntrustedServer=false") fi - if [[ "${build_scan_publishing_mode}" == "off" ]]; then - args+=("-Dcom.gradle.enterprise.build-validation.omitServerUrlValidation=true") - args+=("-Dscan.dump") - fi - args+=( -Dmaven.ext.class.path="${extension_classpath}" -Dcom.gradle.enterprise.build-validation.expDir="${EXP_DIR}" @@ -92,7 +86,7 @@ invoke_maven() { die "ERROR: Experiment aborted due to a non-recoverable failure: $(cat "${EXP_DIR}/errors.txt")" fi - if [[ "${build_scan_publishing_mode}" == "on" ]] && is_build_scan_metadata_missing "$run_num"; then + if is_build_scan_metadata_missing "$run_num"; then print_bl die "ERROR: Experiment aborted due to a non-recoverable failure: No Build Scan was published" fi diff --git a/components/scripts/lib/summary.sh b/components/scripts/lib/summary.sh index 513cf373..fec3cc6f 100644 --- a/components/scripts/lib/summary.sh +++ b/components/scripts/lib/summary.sh @@ -102,10 +102,8 @@ print_summary() { print_performance_characteristics - if [[ "${build_scan_publishing_mode}" == "on" ]]; then - print_bl - print_quick_links - fi + print_bl + print_quick_links } detect_warnings_from_build_scans() { @@ -364,16 +362,12 @@ warn_if_nonzero() { print_build_scans() { for (( i=0; i<2; i++ )); do - if [[ "${build_scan_publishing_mode}" == "on" ]]; then - if [ -z "${build_outcomes[i]}" ]; then - summary_row "Build scan ${ORDINALS[i]} build:" "${WARN_COLOR}${build_scan_urls[i]:+${build_scan_urls[i]} }BUILD SCAN DATA FETCH FAILED${RESTORE}" - elif [[ "${build_outcomes[i]}" == "FAILED" ]]; then - summary_row "Build scan ${ORDINALS[i]} build:" "${WARN_COLOR}${build_scan_urls[i]:+${build_scan_urls[i]} }FAILED${RESTORE}" - else - summary_row "Build scan ${ORDINALS[i]} build:" "${build_scan_urls[i]}" - fi + if [ -z "${build_outcomes[i]}" ]; then + summary_row "Build scan ${ORDINALS[i]} build:" "${WARN_COLOR}${build_scan_urls[i]:+${build_scan_urls[i]} }BUILD SCAN DATA FETCH FAILED${RESTORE}" + elif [[ "${build_outcomes[i]}" == "FAILED" ]]; then + summary_row "Build scan ${ORDINALS[i]} build:" "${WARN_COLOR}${build_scan_urls[i]:+${build_scan_urls[i]} }FAILED${RESTORE}" else - summary_row "Build scan ${ORDINALS[i]} build:" "" + summary_row "Build scan ${ORDINALS[i]} build:" "${build_scan_urls[i]}" fi done } diff --git a/components/scripts/maven/01-validate-local-build-caching-same-location.sh b/components/scripts/maven/01-validate-local-build-caching-same-location.sh index 65d2fda5..02e32fff 100755 --- a/components/scripts/maven/01-validate-local-build-caching-same-location.sh +++ b/components/scripts/maven/01-validate-local-build-caching-same-location.sh @@ -10,6 +10,7 @@ readonly EXP_NO="01" readonly EXP_SCAN_TAG=exp1-maven readonly BUILD_TOOL="Maven" readonly SCRIPT_VERSION="" +readonly SUMMARY_VERSION="" readonly SHOW_RUN_ID=true # Needed to bootstrap the script @@ -18,12 +19,12 @@ readonly SCRIPT_NAME # shellcheck disable=SC2164 # it is highly unlikely cd will fail here because we're cding to the location of this script SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")"; cd -P "$(dirname "$(readlink "${BASH_SOURCE[0]}" || echo .)")"; pwd)" readonly SCRIPT_DIR -readonly LIB_DIR="${SCRIPT_DIR}/lib" +readonly LIB_DIR="${SCRIPT_DIR}/lib/scripts" # Include and parse the command line arguments -# shellcheck source=lib/01-cli-parser.sh +# shellcheck source=lib/scripts/01-cli-parser.sh source "${LIB_DIR}/${EXP_NO}-cli-parser.sh" || { echo -e "\033[00;31m\033[1mERROR: Couldn't find '${LIB_DIR}/${EXP_NO}-cli-parser.sh'\033[0m"; exit 100; } -# shellcheck source=lib/libs.sh +# shellcheck source=lib/scripts/libs.sh source "${LIB_DIR}/libs.sh" || { echo -e "\033[00;31m\033[1mERROR: Couldn't find '${LIB_DIR}/libs.sh'\033[0m"; exit 100; } # These will be set by the config functions (see lib/config.sh) @@ -38,10 +39,6 @@ ge_server='' interactive_mode='' main() { - if [[ "$build_scan_publishing_mode" == "off" ]]; then - verify_offline_mode_required_files_exist - fi - if [ "${interactive_mode}" == "on" ]; then wizard_execute else @@ -74,16 +71,11 @@ execute() { wizard_execute() { print_introduction - if [[ "${build_scan_publishing_mode}" == "on" ]]; then - print_bl - explain_prerequisites_ccud_maven_extension "I." + print_bl + explain_prerequisites_ccud_maven_extension "I." - print_bl - explain_prerequisites_api_access "II." - else - print_bl - explain_prerequisites_ccud_maven_extension - fi + print_bl + explain_prerequisites_api_access "II." print_bl explain_collect_git_details @@ -150,19 +142,11 @@ execute_build() { } print_maven_command() { - if [[ "${build_scan_publishing_mode}" == "on" ]]; then - info "./mvnw -Dscan -Dscan.tag.${EXP_SCAN_TAG} -Dscan.value.runId=${RUN_ID} clean ${tasks}$(print_extra_args)" - else - info "./mvnw -Dscan.dump -Dscan.tag.${EXP_SCAN_TAG} -Dscan.value.runId=${RUN_ID} clean ${tasks}$(print_extra_args)" - fi + info "./mvnw -Dscan -Dscan.tag.${EXP_SCAN_TAG} -Dscan.value.runId=${RUN_ID} clean ${tasks}$(print_extra_args)" } fetch_build_cache_metrics() { - if [ "$build_scan_publishing_mode" == "on" ]; then - process_build_scan_data_online - else - find_and_read_build_scan_dumps - fi + process_build_scan_data_online } print_introduction() { @@ -253,8 +237,7 @@ EOF explain_measure_build_results() { local text - if [[ "${build_scan_publishing_mode}" == "on" ]]; then - IFS='' read -r -d '' text < to measure the build results.${RESTORE} EOF - else - IFS='' read -r -d '' text < to measure the build results.${RESTORE} -EOF - fi print_interactive_text "${text}" wait_for_enter } explain_and_print_summary() { local text - if [[ "${build_scan_publishing_mode}" == "on" ]]; then - IFS='' read -r -d '' text < to measure the build results.${RESTORE} EOF - else - IFS='' read -r -d '' text < to measure the build results.${RESTORE} -EOF - fi print_interactive_text "${text}" wait_for_enter } explain_and_print_summary() { local text - if [[ "${build_scan_publishing_mode}" == "on" ]]; then - IFS='' read -r -d '' text <