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."