Pass through information about package lookup failure into import lookup.
This fixes 'Misleading error message "file must have a corresponding package"' '#7094.
PiperOrigin-RevId: 235806611
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/ContainingPackageLookupFunction.java b/src/main/java/com/google/devtools/build/lib/skyframe/ContainingPackageLookupFunction.java
index f3ca988..0cdc9e8 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/ContainingPackageLookupFunction.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/ContainingPackageLookupFunction.java
@@ -14,6 +14,7 @@
package com.google.devtools.build.lib.skyframe;
import com.google.devtools.build.lib.cmdline.PackageIdentifier;
+import com.google.devtools.build.lib.skyframe.PackageLookupValue.ErrorReason;
import com.google.devtools.build.lib.skyframe.PackageLookupValue.IncorrectRepositoryReferencePackageLookupValue;
import com.google.devtools.build.lib.vfs.PathFragment;
import com.google.devtools.build.skyframe.SkyFunction;
@@ -49,6 +50,9 @@
return env.getValue(ContainingPackageLookupValue.key(correctPackageIdentifier));
}
+ if (ErrorReason.REPOSITORY_NOT_FOUND.equals(pkgLookupValue.getErrorReason())) {
+ return new ContainingPackageLookupValue.NoContainingPackage(pkgLookupValue.getErrorMsg());
+ }
PathFragment parentDir = dir.getPackageFragment().getParentDirectory();
if (parentDir == null) {
return ContainingPackageLookupValue.NONE;
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/ContainingPackageLookupValue.java b/src/main/java/com/google/devtools/build/lib/skyframe/ContainingPackageLookupValue.java
index 7ab319c..302d6db 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/ContainingPackageLookupValue.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/ContainingPackageLookupValue.java
@@ -26,6 +26,7 @@
import com.google.devtools.build.skyframe.SkyFunctionName;
import com.google.devtools.build.skyframe.SkyKey;
import com.google.devtools.build.skyframe.SkyValue;
+import javax.annotation.Nonnull;
/**
* A value that represents the result of looking for the existence of a package that owns a
@@ -45,6 +46,14 @@
/** If there is a containing package, returns its package root */
public abstract Root getContainingPackageRoot();
+ /**
+ * If there is not a containing package, returns a reason why (this is usually the reason the
+ * outer-most directory isn't a package).
+ */
+ public String getReasonForNoContainingPackage() {
+ throw new IllegalStateException();
+ }
+
public static Key key(PackageIdentifier id) {
Preconditions.checkArgument(!id.getPackageFragment().isAbsolute(), id);
Preconditions.checkArgument(!id.getRepository().isDefault(), id);
@@ -112,7 +121,15 @@
/** Value indicating there is no containing package. */
public static class NoContainingPackage extends ContainingPackageLookupValue {
- private NoContainingPackage() {}
+ private final String reason;
+
+ private NoContainingPackage() {
+ this.reason = null;
+ }
+
+ NoContainingPackage(@Nonnull String reason) {
+ this.reason = reason;
+ }
@Override
public boolean hasContainingPackage() {
@@ -133,6 +150,11 @@
public String toString() {
return getClass().getName();
}
+
+ @Override
+ public String getReasonForNoContainingPackage() {
+ return reason;
+ }
}
/** A successful lookup value. */
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/PackageLookupFunction.java b/src/main/java/com/google/devtools/build/lib/skyframe/PackageLookupFunction.java
index aed63e4..95fe4be 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/PackageLookupFunction.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/PackageLookupFunction.java
@@ -321,7 +321,7 @@
}
if (!repositoryValue.repositoryExists()) {
// TODO(ulfjack): Maybe propagate the error message from the repository delegator function?
- return PackageLookupValue.NO_SUCH_REPOSITORY_VALUE;
+ return new PackageLookupValue.NoRepositoryPackageLookupValue(id.getRepository().getName());
}
// This checks for the build file names in the correct precedence order.
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/PackageLookupValue.java b/src/main/java/com/google/devtools/build/lib/skyframe/PackageLookupValue.java
index f5c5f8c..7d24e17 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/PackageLookupValue.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/PackageLookupValue.java
@@ -51,10 +51,6 @@
public static final DeletedPackageLookupValue DELETED_PACKAGE_VALUE =
new DeletedPackageLookupValue();
- @AutoCodec
- public static final NoRepositoryPackageLookupValue NO_SUCH_REPOSITORY_VALUE =
- new NoRepositoryPackageLookupValue();
-
enum ErrorReason {
/** There is no BUILD file. */
NO_BUILD_FILE,
@@ -391,11 +387,15 @@
}
/**
- * Marker value for repository we could not find. This can happen when looking for a label that
- * specifies a non-existent repository.
+ * Value for repository we could not find. This can happen when looking for a label that specifies
+ * a non-existent repository.
*/
public static class NoRepositoryPackageLookupValue extends UnsuccessfulPackageLookupValue {
- private NoRepositoryPackageLookupValue() {}
+ private final String repositoryName;
+
+ NoRepositoryPackageLookupValue(String repositoryName) {
+ this.repositoryName = repositoryName;
+ }
@Override
ErrorReason getErrorReason() {
@@ -404,7 +404,7 @@
@Override
public String getErrorMsg() {
- return "The repository could not be resolved";
+ return String.format("The repository '%s' could not be resolved", repositoryName);
}
}
}
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/SkylarkImportLookupFunction.java b/src/main/java/com/google/devtools/build/lib/skyframe/SkylarkImportLookupFunction.java
index 0c3c081..179dc54 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/SkylarkImportLookupFunction.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/SkylarkImportLookupFunction.java
@@ -249,7 +249,8 @@
return null;
}
if (!containingPackageLookupValue.hasContainingPackage()) {
- throw SkylarkImportFailedException.noBuildFile(fileLabel.toPathFragment());
+ throw SkylarkImportFailedException.noBuildFile(
+ fileLabel, containingPackageLookupValue.getReasonForNoContainingPackage());
}
if (!containingPackageLookupValue.getContainingPackageName().equals(
fileLabel.getPackageIdentifier())) {
@@ -600,7 +601,11 @@
cause);
}
- static SkylarkImportFailedException noBuildFile(PathFragment file) {
+ static SkylarkImportFailedException noBuildFile(Label file, @Nullable String reason) {
+ if (reason != null) {
+ return new SkylarkImportFailedException(
+ String.format("Unable to find package for %s: %s.", file, reason));
+ }
return new SkylarkImportFailedException(
String.format("Every .bzl file must have a corresponding package, but '%s' "
+ "does not have one. Please create a BUILD file in the same or any parent directory."