From c3245cd028977877aa9e485451b29c7736ebcae0 Mon Sep 17 00:00:00 2001 From: Fabian Meumertzheim Date: Sun, 8 Jan 2023 20:40:42 -0800 Subject: [PATCH] Add `SpellChecker` suggestions for common Bzlmod errors Closes #17121. PiperOrigin-RevId: 500606458 Change-Id: I3a4c3650e8f89401669f1d5e941073ed603673db --- .../devtools/build/lib/bazel/bzlmod/BUILD | 1 + .../bzlmod/SingleExtensionEvalFunction.java | 19 +++++++++++++++---- .../lib/bazel/bzlmod/TypeCheckedTag.java | 6 ++++-- 3 files changed, 20 insertions(+), 6 deletions(-) diff --git a/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/BUILD b/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/BUILD index 3c37edd9667c22..771b58e97ea21e 100644 --- a/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/BUILD +++ b/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/BUILD @@ -170,6 +170,7 @@ java_library( "//src/main/java/com/google/devtools/build/skyframe:skyframe-objects", "//src/main/java/net/starlark/java/annot", "//src/main/java/net/starlark/java/eval", + "//src/main/java/net/starlark/java/spelling", "//src/main/java/net/starlark/java/syntax", "//src/main/protobuf:failure_details_java_proto", "//third_party:auto_value", diff --git a/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/SingleExtensionEvalFunction.java b/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/SingleExtensionEvalFunction.java index 6eab1233834b9a..0418870181811b 100644 --- a/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/SingleExtensionEvalFunction.java +++ b/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/SingleExtensionEvalFunction.java @@ -16,7 +16,9 @@ package com.google.devtools.build.lib.bazel.bzlmod; import static com.google.common.collect.ImmutableBiMap.toImmutableBiMap; +import static com.google.common.collect.ImmutableSet.toImmutableSet; +import com.google.common.collect.ImmutableSet; import com.google.devtools.build.lib.analysis.BlazeDirectories; import com.google.devtools.build.lib.bazel.repository.downloader.DownloadManager; import com.google.devtools.build.lib.cmdline.BazelModuleContext; @@ -51,6 +53,7 @@ import net.starlark.java.eval.StarlarkList; import net.starlark.java.eval.StarlarkSemantics; import net.starlark.java.eval.StarlarkThread; +import net.starlark.java.spelling.SpellChecker; import net.starlark.java.syntax.Location; /** @@ -147,13 +150,19 @@ public SkyValue compute(SkyKey skyKey, Environment env) // Check that the .bzl file actually exports a module extension by our name. Object exported = bzlLoadValue.getModule().getGlobal(extensionId.getExtensionName()); if (!(exported instanceof ModuleExtension.InStarlark)) { + ImmutableSet exportedExtensions = + bzlLoadValue.getModule().getGlobals().entrySet().stream() + .filter(e -> e.getValue() instanceof ModuleExtension.InStarlark) + .map(Entry::getKey) + .collect(toImmutableSet()); throw new SingleExtensionEvalFunctionException( ExternalDepsException.withMessage( Code.BAD_MODULE, - "%s does not export a module extension called %s, yet its use is requested at %s", + "%s does not export a module extension called %s, yet its use is requested at %s%s", extensionId.getBzlFileLabel(), extensionId.getExtensionName(), - sampleUsageLocation), + sampleUsageLocation, + SpellChecker.didYouMean(extensionId.getExtensionName(), exportedExtensions)), Transience.PERSISTENT); } @@ -206,12 +215,14 @@ public SkyValue compute(SkyKey skyKey, Environment env) ExternalDepsException.withMessage( Code.BAD_MODULE, "module extension \"%s\" from \"%s\" does not generate repository \"%s\", yet it" - + " is imported as \"%s\" in the usage at %s", + + " is imported as \"%s\" in the usage at %s%s", extensionId.getExtensionName(), extensionId.getBzlFileLabel(), repoImport.getValue(), repoImport.getKey(), - usage.getLocation()), + usage.getLocation(), + SpellChecker.didYouMean( + repoImport.getValue(), threadContext.getGeneratedRepos().keySet())), Transience.PERSISTENT); } } diff --git a/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/TypeCheckedTag.java b/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/TypeCheckedTag.java index 855c8cb465a5b1..50c4b19e68525e 100644 --- a/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/TypeCheckedTag.java +++ b/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/TypeCheckedTag.java @@ -24,6 +24,7 @@ import net.starlark.java.annot.StarlarkBuiltin; import net.starlark.java.eval.EvalException; import net.starlark.java.eval.Structure; +import net.starlark.java.spelling.SpellChecker; /** * A {@link Tag} whose attribute values have been type-checked against the attribute schema define @@ -48,9 +49,10 @@ public static TypeCheckedTag create(TagClass tagClass, Tag tag, LabelConverter l if (attrIndex == null) { throw ExternalDepsException.withMessage( Code.BAD_MODULE, - "in tag at %s, unknown attribute %s provided", + "in tag at %s, unknown attribute %s provided%s", tag.getLocation(), - attrValue.getKey()); + attrValue.getKey(), + SpellChecker.didYouMean(attrValue.getKey(), tagClass.getAttributeIndices().keySet())); } Attribute attr = tagClass.getAttributes().get(attrIndex); Object nativeValue;