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 index 4aed4471..3d41783e 100644 --- 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 @@ -18,6 +18,7 @@ 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; @@ -116,7 +117,8 @@ public BuildValidationData fetchBuildValidationData(String buildScanId) { buildOutcomeFrom(attributes), remoteBuildCacheUrlFrom(buildCachePerformance), summarizeTaskExecutions(buildCachePerformance), - toDuration(buildCachePerformance.getEffectiveTaskExecutionTime()) + toDuration(buildCachePerformance.getEffectiveTaskExecutionTime()), + BigDecimal.valueOf(buildCachePerformance.getSerializationFactor()) ); } if (build.getBuildToolType().equalsIgnoreCase("maven")) { @@ -134,7 +136,8 @@ public BuildValidationData fetchBuildValidationData(String buildScanId) { buildOutcomeFrom(attributes), remoteBuildCacheUrlFrom(buildCachePerformance), summarizeTaskExecutions(buildCachePerformance), - toDuration(buildCachePerformance.getEffectiveProjectExecutionTime()) + toDuration(buildCachePerformance.getEffectiveProjectExecutionTime()), + BigDecimal.valueOf(buildCachePerformance.getSerializationFactor()) ); } throw new UnknownBuildAgentException(baseUrl, buildScanId, build.getBuildToolType()); diff --git a/components/fetch-build-scan-data-cmdline-tool/src/main/java/com/gradle/enterprise/cli/FetchBuildValidationDataCommand.java b/components/fetch-build-scan-data-cmdline-tool/src/main/java/com/gradle/enterprise/cli/FetchBuildValidationDataCommand.java index f1818dde..2ca3e4df 100644 --- a/components/fetch-build-scan-data-cmdline-tool/src/main/java/com/gradle/enterprise/cli/FetchBuildValidationDataCommand.java +++ b/components/fetch-build-scan-data-cmdline-tool/src/main/java/com/gradle/enterprise/cli/FetchBuildValidationDataCommand.java @@ -11,6 +11,7 @@ import picocli.CommandLine.Parameters; import java.io.IOException; +import java.math.BigDecimal; import java.net.MalformedURLException; import java.net.URL; import java.nio.file.Path; @@ -107,7 +108,8 @@ private BuildValidationData fetchBuildScanData(int index, URL buildScanUrl, Cust "", null, Collections.emptyMap(), - Duration.ZERO); + Duration.ZERO, + BigDecimal.ZERO); } } diff --git a/components/fetch-build-scan-data-cmdline-tool/src/main/java/com/gradle/enterprise/cli/Fields.java b/components/fetch-build-scan-data-cmdline-tool/src/main/java/com/gradle/enterprise/cli/Fields.java index 3f8ce5f3..6aad492c 100644 --- a/components/fetch-build-scan-data-cmdline-tool/src/main/java/com/gradle/enterprise/cli/Fields.java +++ b/components/fetch-build-scan-data-cmdline-tool/src/main/java/com/gradle/enterprise/cli/Fields.java @@ -3,6 +3,7 @@ import com.gradle.enterprise.model.BuildValidationData; import com.gradle.enterprise.model.TaskExecutionSummary; +import java.math.BigDecimal; import java.time.Duration; import java.util.Arrays; import java.util.Locale; @@ -31,6 +32,7 @@ public enum Fields { 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")), EFFECTIVE_TASK_EXECUTION_DURATION("Effective task execution duration", d -> String.valueOf(d.getEffectiveTaskExecutionDuration().toMillis())), + SERIALIZATION_FACTOR("Serialization factor", d -> formatBigDecimal(d.getSerializationFactor())), ; public final String label; @@ -91,4 +93,11 @@ private static String formatDuration(Duration duration) { return s.toString().trim(); } + + private static String formatBigDecimal(BigDecimal value) { + if (value.compareTo(BigDecimal.ZERO) == 0) { + return ""; + } + return value.toPlainString(); + } } diff --git a/components/fetch-build-scan-data-cmdline-tool/src/main/java/com/gradle/enterprise/model/BuildValidationData.java b/components/fetch-build-scan-data-cmdline-tool/src/main/java/com/gradle/enterprise/model/BuildValidationData.java index ebcd51a9..7c5e3cf3 100644 --- a/components/fetch-build-scan-data-cmdline-tool/src/main/java/com/gradle/enterprise/model/BuildValidationData.java +++ b/components/fetch-build-scan-data-cmdline-tool/src/main/java/com/gradle/enterprise/model/BuildValidationData.java @@ -1,5 +1,6 @@ package com.gradle.enterprise.model; +import java.math.BigDecimal; import java.net.MalformedURLException; import java.net.URL; import java.time.Duration; @@ -22,6 +23,7 @@ public class BuildValidationData { private final URL remoteBuildCacheUrl; private final Map tasksByAvoidanceOutcome; private final Duration effectiveTaskExecutionDuration; + private final BigDecimal serializationFactor; public BuildValidationData( String rootProjectName, @@ -34,7 +36,8 @@ public BuildValidationData( String buildOutcome, URL remoteBuildCacheUrl, Map tasksByAvoidanceOutcome, - Duration effectiveTaskExecutionDuration) { + Duration effectiveTaskExecutionDuration, + BigDecimal serializationFactor) { this.rootProjectName = rootProjectName; this.buildScanId = buildScanId; this.gradleEnterpriseServerUrl = gradleEnterpriseServerUrl; @@ -46,6 +49,7 @@ public BuildValidationData( this.remoteBuildCacheUrl = remoteBuildCacheUrl; this.tasksByAvoidanceOutcome = tasksByAvoidanceOutcome; this.effectiveTaskExecutionDuration = effectiveTaskExecutionDuration; + this.serializationFactor = serializationFactor; } public String getRootProjectName() { @@ -142,4 +146,8 @@ public Map getTasksByAvoidanceOutcome() { public Duration getEffectiveTaskExecutionDuration() { return effectiveTaskExecutionDuration; } + + public BigDecimal getSerializationFactor() { + return serializationFactor; + } } diff --git a/components/scripts/gradle/01-validate-incremental-building.sh b/components/scripts/gradle/01-validate-incremental-building.sh index a0938574..14dd436a 100755 --- a/components/scripts/gradle/01-validate-incremental-building.sh +++ b/components/scripts/gradle/01-validate-incremental-building.sh @@ -171,6 +171,8 @@ print_performance_characteristics() { print_performance_characteristics_header print_realized_build_time_savings + + print_serialization_factor } print_quick_links() { diff --git a/components/scripts/lib/build-scan-parse.sh b/components/scripts/lib/build-scan-parse.sh index 10b63cd2..887fbcee 100644 --- a/components/scripts/lib/build-scan-parse.sh +++ b/components/scripts/lib/build-scan-parse.sh @@ -27,6 +27,7 @@ executed_not_cacheable_duration=() # Build duration metrics effective_task_execution_duration=() +serialization_factors=() parse_build_scan_csv() { # This isn't the most robust way to read a CSV, @@ -45,7 +46,7 @@ parse_build_scan_csv() { idx=0 # shellcheck disable=SC2034 # not all scripts use all of the fetched data - while IFS=, read -r field_1 field_2 field_3 field_4 field_5 field_6 field_7 field_8 field_9 field_10 field_11 field_12 field_13 field_14 field_15 field_16 field_17 field_18 field_19 field_20; do + while IFS=, read -r field_1 field_2 field_3 field_4 field_5 field_6 field_7 field_8 field_9 field_10 field_11 field_12 field_13 field_14 field_15 field_16 field_17 field_18 field_19 field_20 field_21; do if [[ "$header_row_read" == "false" ]]; then header_row_read=true continue; @@ -76,11 +77,15 @@ parse_build_scan_csv() { executed_not_cacheable_num_tasks[idx]="${field_18}" executed_not_cacheable_duration[idx]="${field_19}" - # Conditional because build-scan-support-tool does not yet support this field + # Conditional because build-scan-support-tool does not yet support these fields if [[ -n "$field_20" ]]; then effective_task_execution_duration[idx]="${field_20}" fi + if [[ -n "$field_21" ]]; then + serialization_factors[idx]="${field_21}" + fi + ((idx++)) done <<< "${build_scan_csv}" } diff --git a/components/scripts/lib/info.sh b/components/scripts/lib/info.sh index 9dc6695b..f461d6a2 100644 --- a/components/scripts/lib/info.sh +++ b/components/scripts/lib/info.sh @@ -142,6 +142,8 @@ print_performance_characteristics() { print_build_caching_leverage_metrics + print_serialization_factor + print_executed_cacheable_tasks_warning } @@ -204,6 +206,14 @@ print_build_caching_leverage_metrics() { summary_row "Executed non-cacheable ${BUILD_TOOL_TASK}s:" "${value}" } +print_serialization_factor() { + # Do not print serialization factor at all if this value does not exist + # This can happen since build-scan-support-tool does not yet support this field + if [[ -n "${serialization_factors[0]}" ]]; then + summary_row "Serialization factor:" "$(to_two_decimal_places "${serialization_factors[0]}")x" + fi +} + print_executed_cacheable_tasks_warning() { if (( executed_cacheable_num_tasks[1] > 0)); then print_bl @@ -279,3 +289,9 @@ format_duration() { printf "%d.%03ds" "${seconds}" "${millis}" } + +# Rounds the argument to two decimal places +# See: https://unix.stackexchange.com/a/167059 +to_two_decimal_places() { + LC_ALL=C printf "%.2f" "$1" +} diff --git a/release/changes.md b/release/changes.md index cb3b71f7..fd2dd6bc 100644 --- a/release/changes.md +++ b/release/changes.md @@ -1,2 +1,3 @@ - [NEW] Include realized build time savings in all experiment summaries +- [NEW] Include serialization factor in all experiment summaries - [NEW] Support `-x` command line option for Gradle experiment 1