From 64ae5ad18ed6f3e38f8190d9cf148cc70f2560b6 Mon Sep 17 00:00:00 2001 From: Jordan Mele Date: Mon, 29 Sep 2025 09:08:28 +0000 Subject: [PATCH 1/2] Quote labels in missing toolchains debug advice --- .../lib/skyframe/toolchains/ToolchainResolutionFunction.java | 2 ++ .../skyframe/toolchains/ToolchainResolutionFunctionTest.java | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/toolchains/ToolchainResolutionFunction.java b/src/main/java/com/google/devtools/build/lib/skyframe/toolchains/ToolchainResolutionFunction.java index df1d1ebfb1d803..0e020b80b67202 100644 --- a/src/main/java/com/google/devtools/build/lib/skyframe/toolchains/ToolchainResolutionFunction.java +++ b/src/main/java/com/google/devtools/build/lib/skyframe/toolchains/ToolchainResolutionFunction.java @@ -50,6 +50,7 @@ import java.util.Optional; import java.util.SequencedSet; import java.util.Set; +import java.util.regex.Pattern; import javax.annotation.Nullable; /** @@ -396,6 +397,7 @@ private static String getMessage( missingToolchainTypes.stream() .map(ToolchainTypeInfo::typeLabel) .map(Label::toString) + .map(Pattern::quote) .collect(toImmutableList()); ImmutableList missingToolchainRows = missingToolchainTypes.stream() diff --git a/src/test/java/com/google/devtools/build/lib/skyframe/toolchains/ToolchainResolutionFunctionTest.java b/src/test/java/com/google/devtools/build/lib/skyframe/toolchains/ToolchainResolutionFunctionTest.java index e1a6bf79e6f642..bc5c36d61648d3 100644 --- a/src/test/java/com/google/devtools/build/lib/skyframe/toolchains/ToolchainResolutionFunctionTest.java +++ b/src/test/java/com/google/devtools/build/lib/skyframe/toolchains/ToolchainResolutionFunctionTest.java @@ -391,7 +391,7 @@ public void resolve_mandatory_missing() throws Exception { """ No matching toolchains found for types: //toolchain:test_toolchain -To debug, rerun with --toolchain_resolution_debug='//toolchain:test_toolchain' +To debug, rerun with --toolchain_resolution_debug='\\Q//toolchain:test_toolchain\\E' For more information on platforms or toolchains see https://bazel.build/concepts/platforms-intro.\ """); } From 4cf7f09821e389a85d0edd17a276f42570ee8e99 Mon Sep 17 00:00:00 2001 From: Jordan Mele Date: Thu, 2 Oct 2025 11:35:45 +0000 Subject: [PATCH 2/2] Quote only if necessary, add test case --- .../ToolchainResolutionFunction.java | 15 +++++++++- .../build/lib/skyframe/toolchains/BUILD | 2 ++ .../ToolchainResolutionFunctionTest.java | 30 +++++++++++++++++-- 3 files changed, 44 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/toolchains/ToolchainResolutionFunction.java b/src/main/java/com/google/devtools/build/lib/skyframe/toolchains/ToolchainResolutionFunction.java index 0e020b80b67202..b0f1e618115177 100644 --- a/src/main/java/com/google/devtools/build/lib/skyframe/toolchains/ToolchainResolutionFunction.java +++ b/src/main/java/com/google/devtools/build/lib/skyframe/toolchains/ToolchainResolutionFunction.java @@ -393,11 +393,24 @@ protected Code getDetailedCode() { private static String getMessage( PlatformInfo targetPlatformInfo, SequencedSet missingToolchainTypes) { + // All characters with special meaning anywhere in a regex (':' for example is only special within brackets). + List regexSpecialChars = "+.|([{^$?\\*".codePoints() + .mapToObj(c -> (char) c) + .toList(); ImmutableList labelStrings = missingToolchainTypes.stream() .map(ToolchainTypeInfo::typeLabel) .map(Label::toString) - .map(Pattern::quote) + .map(label -> { + // Regex-quote if label contains special characters. + for (char c : regexSpecialChars) { + if (label.indexOf(c) >= 0) { + return Pattern.quote(label); + } + } + + return label; + }) .collect(toImmutableList()); ImmutableList missingToolchainRows = missingToolchainTypes.stream() diff --git a/src/test/java/com/google/devtools/build/lib/skyframe/toolchains/BUILD b/src/test/java/com/google/devtools/build/lib/skyframe/toolchains/BUILD index a4386fb222c4ff..91367dbff46603 100644 --- a/src/test/java/com/google/devtools/build/lib/skyframe/toolchains/BUILD +++ b/src/test/java/com/google/devtools/build/lib/skyframe/toolchains/BUILD @@ -139,11 +139,13 @@ java_test( "//src/main/java/com/google/devtools/build/lib/analysis:platform_options", "//src/main/java/com/google/devtools/build/lib/analysis/config:build_options", "//src/main/java/com/google/devtools/build/lib/analysis/config:toolchain_type_requirement", + "//src/main/java/com/google/devtools/build/lib/analysis/platform", "//src/main/java/com/google/devtools/build/lib/cmdline", "//src/main/java/com/google/devtools/build/lib/skyframe/config", "//src/main/java/com/google/devtools/build/lib/skyframe/toolchains:constraint_value_lookup_util", "//src/main/java/com/google/devtools/build/lib/skyframe/toolchains:platform_lookup_util", "//src/main/java/com/google/devtools/build/lib/skyframe/toolchains:toolchain_context_key", + "//src/main/java/com/google/devtools/build/lib/skyframe/toolchains:toolchain_resolution_function", "//src/main/java/com/google/devtools/build/lib/skyframe/toolchains:toolchain_type_lookup_util", "//src/main/java/com/google/devtools/build/lib/skyframe/toolchains:unloaded_toolchain_context", "//src/main/java/com/google/devtools/build/skyframe", diff --git a/src/test/java/com/google/devtools/build/lib/skyframe/toolchains/ToolchainResolutionFunctionTest.java b/src/test/java/com/google/devtools/build/lib/skyframe/toolchains/ToolchainResolutionFunctionTest.java index bc5c36d61648d3..cd1dfb3feaabc7 100644 --- a/src/test/java/com/google/devtools/build/lib/skyframe/toolchains/ToolchainResolutionFunctionTest.java +++ b/src/test/java/com/google/devtools/build/lib/skyframe/toolchains/ToolchainResolutionFunctionTest.java @@ -18,9 +18,11 @@ import static com.google.devtools.build.skyframe.EvaluationResultSubjectFactory.assertThatEvaluationResult; import com.google.common.collect.ImmutableList; -import com.google.devtools.build.lib.analysis.PlatformOptions; import com.google.devtools.build.lib.analysis.config.BuildOptions; import com.google.devtools.build.lib.analysis.config.ToolchainTypeRequirement; +import com.google.devtools.build.lib.analysis.platform.PlatformInfo; +import com.google.devtools.build.lib.analysis.platform.ToolchainTypeInfo; +import com.google.devtools.build.lib.analysis.PlatformOptions; import com.google.devtools.build.lib.cmdline.Label; import com.google.devtools.build.lib.rules.platform.ToolchainTestCase; import com.google.devtools.build.lib.skyframe.config.BuildConfigurationKey; @@ -30,6 +32,7 @@ import com.google.devtools.build.lib.skyframe.util.SkyframeExecutorTestUtils; import com.google.devtools.build.skyframe.EvaluationResult; import com.google.devtools.build.skyframe.SkyKey; +import java.util.LinkedHashSet; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; @@ -391,11 +394,34 @@ public void resolve_mandatory_missing() throws Exception { """ No matching toolchains found for types: //toolchain:test_toolchain -To debug, rerun with --toolchain_resolution_debug='\\Q//toolchain:test_toolchain\\E' +To debug, rerun with --toolchain_resolution_debug='//toolchain:test_toolchain' For more information on platforms or toolchains see https://bazel.build/concepts/platforms-intro.\ """); } + @Test + public void unresolved_toolchain_message_regex_quotes() throws Exception { + PlatformInfo platformInfo = PlatformInfo.builder() + .setLabel(Label.parseCanonicalUnchecked("//platforms:test_platform")) + .build(); + ToolchainTypeInfo toolchainTypeInfo = ToolchainTypeInfo.create( + Label.parseCanonicalUnchecked("@@repo+//toolchain:test_toolchain")); + LinkedHashSet missingToolchainTypes = new LinkedHashSet<>(); + missingToolchainTypes.add(toolchainTypeInfo); + + var exception = new ToolchainResolutionFunction.UnresolvedToolchainsException(platformInfo, missingToolchainTypes); + + assertThat(exception) + .hasMessageThat() + .isEqualTo( +""" +No matching toolchains found for types: + @@repo+//toolchain:test_toolchain +To debug, rerun with --toolchain_resolution_debug='\\Q@@repo+//toolchain:test_toolchain\\E' +""" + ); + } + @Test public void resolve_mandatory_missing_customPlatformMessage() throws Exception { scratch.appendFile(