Skip to content

Commit 4344a03

Browse files
haxorzcopybara-github
authored andcommitted
Automated rollback of commit 00a4fef.
*** Reason for rollback *** b/285381501 *** Original change description *** Use `PackageLookupValue` to do package lookup and subpackage boundary cross check in `BzlLoadFunction`. This is a similar change as c3a838b in which we switch from using `ContainingPackageLookupValue` to `PackageLookupValue` for `PackageFunction`. PiperOrigin-RevId: 537190556 Change-Id: Id6368b98cd80575f728ee91e730a727ac164459b
1 parent d47ee4d commit 4344a03

File tree

5 files changed

+101
-142
lines changed

5 files changed

+101
-142
lines changed

src/main/java/com/google/devtools/build/lib/skyframe/BzlLoadFunction.java

Lines changed: 41 additions & 105 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,6 @@
5050
import com.google.devtools.build.lib.server.FailureDetails.FailureDetail;
5151
import com.google.devtools.build.lib.server.FailureDetails.StarlarkLoading;
5252
import com.google.devtools.build.lib.server.FailureDetails.StarlarkLoading.Code;
53-
import com.google.devtools.build.lib.skyframe.PackageLookupValue.NoRepositoryPackageLookupValue;
5453
import com.google.devtools.build.lib.skyframe.StarlarkBuiltinsFunction.BuiltinsFailedException;
5554
import com.google.devtools.build.lib.util.DetailedExitCode;
5655
import com.google.devtools.build.lib.util.Fingerprint;
@@ -64,7 +63,6 @@
6463
import com.google.devtools.build.skyframe.SkyKey;
6564
import com.google.devtools.build.skyframe.SkyValue;
6665
import com.google.devtools.build.skyframe.SkyframeLookupResult;
67-
import java.util.ArrayList;
6866
import java.util.HashMap;
6967
import java.util.HashSet;
7068
import java.util.LinkedHashSet;
@@ -646,103 +644,45 @@ private BzlCompileValue.Key validatePackageAndGetCompileKey(
646644
return key.getCompileKey(getBuiltinsRoot(builtinsBzlPath));
647645
}
648646

649-
// The block below derives all (sub)directories that could possibly contain (sub)packages and
650-
// add them to a list of PackageLookup keys. These (sub)directories include the label path, and
651-
// all subdirectories from label path to the bzl file. For example,
652-
// 1. If the label is //a/b/c:d.bzl, allPackageLookupKeys only contains //a/b/c. There is no
653-
// subdirectory under label path.
654-
// 2. If the label name contains '/', for example, //a/b/c:d/e/f.bzl, allPackageLookupKeys
655-
// contain //a/b/c, //a/b/c/d and //a/b/c/d/e.
656-
List<PackageLookupValue.Key> allPackageLookupKeys = new ArrayList<>();
657-
allPackageLookupKeys.add(PackageLookupValue.key(label.getPackageIdentifier()));
658-
RepositoryName labelRepository = label.getRepository();
659-
PathFragment subpkgPath = label.getPackageFragment();
660-
PathFragment labelAsRelativePath = PathFragment.create(label.getName()).getParentDirectory();
661-
for (String segment : labelAsRelativePath.segments()) {
662-
subpkgPath = subpkgPath.getRelative(segment);
663-
PackageLookupValue.Key currentPackageLookupKey =
664-
PackageLookupValue.key(PackageIdentifier.create(labelRepository, subpkgPath));
665-
allPackageLookupKeys.add(currentPackageLookupKey);
666-
}
667-
668-
SkyframeLookupResult packageLookupResults = env.getValuesAndExceptions(allPackageLookupKeys);
669-
670-
// We intentionally choose not to check `env.valuesMissing()` here. It is possible that all
671-
// PackageLookupValues are already not null but `env.valuesMissing()` is still true from a prior
672-
// request. Returning `null` in this case causes unnecessary Skyframe restarts.
673-
674-
PackageLookupValue.Key candidateKey = null;
675-
PackageLookupValue candidateValue = null;
676-
for (PackageLookupValue.Key packageLookupKey : allPackageLookupKeys) {
677-
// Iterate in order of the directory structure so that the candidate{Key,Value} will end up as
678-
// the deepest package, in other words the "containing package".
679-
PackageLookupValue packageLookupValue;
680-
try {
681-
packageLookupValue =
682-
(PackageLookupValue)
683-
packageLookupResults.getOrThrow(
684-
packageLookupKey,
685-
BuildFileNotFoundException.class,
686-
InconsistentFilesystemException.class);
687-
} catch (BuildFileNotFoundException | InconsistentFilesystemException e) {
688-
throw BzlLoadFailedException.errorFindingContainingPackage(label.toPathFragment(), e);
689-
}
690-
691-
if (packageLookupValue == null) {
692-
return null;
693-
}
694-
695-
if (packageLookupValue instanceof NoRepositoryPackageLookupValue) {
696-
throw BzlLoadFailedException.noBuildFile(label, packageLookupValue.getErrorMsg());
697-
}
698-
699-
if (packageLookupValue.packageExists()) {
700-
candidateKey = packageLookupKey;
701-
candidateValue = packageLookupValue;
702-
}
647+
// Do package lookup.
648+
PathFragment dir = Label.getContainingDirectory(label);
649+
PackageIdentifier dirId = PackageIdentifier.create(label.getRepository(), dir);
650+
ContainingPackageLookupValue packageLookup;
651+
try {
652+
packageLookup =
653+
(ContainingPackageLookupValue)
654+
env.getValueOrThrow(
655+
ContainingPackageLookupValue.key(dirId),
656+
BuildFileNotFoundException.class,
657+
InconsistentFilesystemException.class);
658+
} catch (BuildFileNotFoundException | InconsistentFilesystemException e) {
659+
throw BzlLoadFailedException.errorFindingContainingPackage(label.toPathFragment(), e);
660+
}
661+
if (packageLookup == null) {
662+
return null;
703663
}
704664

705-
if (candidateKey != null && candidateKey.argument().equals(label.getPackageIdentifier())) {
706-
if (candidateValue.packageExists()) {
707-
return key.getCompileKey(candidateValue.getRoot());
708-
} else {
709-
throw BzlLoadFailedException.noBuildFile(label, candidateValue.getErrorMsg());
710-
}
665+
// Resolve to compile key or error.
666+
BzlCompileValue.Key compileKey;
667+
boolean packageOk =
668+
packageLookup.hasContainingPackage()
669+
&& packageLookup.getContainingPackageName().equals(label.getPackageIdentifier());
670+
if (key.isBuildPrelude() && !packageOk) {
671+
// Ignore the prelude, its package doesn't exist.
672+
compileKey = BzlCompileValue.EMPTY_PRELUDE_KEY;
711673
} else {
712-
if (key.isBuildPrelude()) {
713-
return BzlCompileValue.EMPTY_PRELUDE_KEY;
714-
}
715-
if (candidateKey == null) {
716-
// If we cannot find any subpackage below label's package directory, it is still possible
717-
// that the label's package is a subpackage itself. This case should be rare, so we choose
718-
// to still handle it using ContainingPackageLookup node.
719-
ContainingPackageLookupValue containingPackageLookup;
720-
try {
721-
containingPackageLookup =
722-
(ContainingPackageLookupValue)
723-
env.getValueOrThrow(
724-
ContainingPackageLookupValue.key(label.getPackageIdentifier()),
725-
BuildFileNotFoundException.class,
726-
InconsistentFilesystemException.class);
727-
} catch (BuildFileNotFoundException | InconsistentFilesystemException e) {
728-
throw BzlLoadFailedException.errorFindingContainingPackage(label.toPathFragment(), e);
729-
}
730-
731-
if (containingPackageLookup == null) {
732-
return null;
733-
}
734-
735-
if (containingPackageLookup.hasContainingPackage()) {
736-
throw BzlLoadFailedException.labelSubpackageCrossesBoundary(
737-
label, containingPackageLookup);
674+
if (packageOk) {
675+
compileKey = key.getCompileKey(packageLookup.getContainingPackageRoot());
676+
} else {
677+
if (!packageLookup.hasContainingPackage()) {
678+
throw BzlLoadFailedException.noBuildFile(
679+
label, packageLookup.getReasonForNoContainingPackage());
738680
} else {
739-
throw BzlLoadFailedException.noBuildFile(label, /* reason= */ null);
681+
throw BzlLoadFailedException.labelCrossesPackageBoundary(label, packageLookup);
740682
}
741-
} else {
742-
throw BzlLoadFailedException.subpackageCrossesLabelPackageBoundary(
743-
label, candidateKey.argument(), candidateValue);
744683
}
745684
}
685+
return compileKey;
746686
}
747687

748688
private Root getBuiltinsRoot(String builtinsBzlPath) {
@@ -1643,21 +1583,17 @@ static BzlLoadFailedException noBuildFile(Label file, @Nullable String reason) {
16431583
Code.PACKAGE_NOT_FOUND);
16441584
}
16451585

1646-
static BzlLoadFailedException labelSubpackageCrossesBoundary(
1586+
static BzlLoadFailedException labelCrossesPackageBoundary(
16471587
Label label, ContainingPackageLookupValue containingPackageLookupValue) {
16481588
return new BzlLoadFailedException(
1649-
ContainingPackageLookupValue.getErrorMessageForLabelSubpackageCrossesBoundary(
1650-
containingPackageLookupValue, label),
1651-
Code.LABEL_CROSSES_PACKAGE_BOUNDARY);
1652-
}
1653-
1654-
static BzlLoadFailedException subpackageCrossesLabelPackageBoundary(
1655-
Label label,
1656-
PackageIdentifier subpackageIdentifier,
1657-
PackageLookupValue packageLookupValue) {
1658-
return new BzlLoadFailedException(
1659-
PackageLookupValue.getErrorMessageForSubpackageCrossesLabelPackageBoundary(
1660-
packageLookupValue.getRoot(), label, subpackageIdentifier, packageLookupValue),
1589+
ContainingPackageLookupValue.getErrorMessageForLabelCrossingPackageBoundary(
1590+
// We don't actually know the proper Root to pass in here (since we don't e.g. know
1591+
// the root of the bzl/BUILD file that is trying to load 'label'). Therefore we just
1592+
// pass in the Root of the containing package in order to still get a useful error
1593+
// message for the user.
1594+
containingPackageLookupValue.getContainingPackageRoot(),
1595+
label,
1596+
containingPackageLookupValue),
16611597
Code.LABEL_CROSSES_PACKAGE_BOUNDARY);
16621598
}
16631599

src/main/java/com/google/devtools/build/lib/skyframe/ContainingPackageLookupValue.java

Lines changed: 41 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -59,27 +59,48 @@ public static Key key(PackageIdentifier id) {
5959
return Key.create(id);
6060
}
6161

62-
/**
63-
* Creates the error message for the input {@linkplain Label label} if label itself is a
64-
* subpackage crosses boundary when an outer package exists.
65-
*/
66-
static String getErrorMessageForLabelSubpackageCrossesBoundary(
67-
ContainingPackageLookupValue containingPkgLookupValue, Label label) {
62+
static String getErrorMessageForLabelCrossingPackageBoundary(
63+
Root pkgRoot,
64+
Label label,
65+
ContainingPackageLookupValue containingPkgLookupValue) {
6866
PackageIdentifier containingPkg = containingPkgLookupValue.getContainingPackageName();
69-
Preconditions.checkState(
70-
label.getPackageIdentifier().getSourceRoot().startsWith(containingPkg.getSourceRoot()),
71-
"Label's path should start with outer package's path.");
72-
73-
String message =
74-
String.format(
75-
"Label '%s' is invalid because '%s' is not a package", label, label.getPackageName());
76-
PathFragment labelNameInContainingPackage =
77-
label.toPathFragment().relativeTo(containingPkg.getPackageFragment());
78-
message += "; perhaps you meant to put the colon here: '";
79-
if (containingPkg.getRepository().isMain()) {
80-
message += "//";
81-
}
82-
message += containingPkg + ":" + labelNameInContainingPackage + "'?";
67+
boolean crossesPackageBoundaryBelow =
68+
containingPkg.getSourceRoot().startsWith(label.getPackageIdentifier().getSourceRoot());
69+
PathFragment labelNameFragment = PathFragment.create(label.getName());
70+
String message;
71+
if (crossesPackageBoundaryBelow) {
72+
message =
73+
String.format("Label '%s' is invalid because '%s' is a subpackage", label, containingPkg);
74+
} else {
75+
message =
76+
String.format(
77+
"Label '%s' is invalid because '%s' is not a package", label, label.getPackageName());
78+
}
79+
80+
Root containingRoot = containingPkgLookupValue.getContainingPackageRoot();
81+
if (pkgRoot.equals(containingRoot)) {
82+
PathFragment containingPkgFragment = containingPkg.getPackageFragment();
83+
PathFragment labelNameInContainingPackage =
84+
crossesPackageBoundaryBelow
85+
? labelNameFragment.subFragment(
86+
containingPkgFragment.segmentCount()
87+
- label.getPackageFragment().segmentCount(),
88+
labelNameFragment.segmentCount())
89+
: label.toPathFragment().relativeTo(containingPkgFragment);
90+
message += "; perhaps you meant to put the colon here: '";
91+
if (containingPkg.getRepository().isMain()) {
92+
message += "//";
93+
}
94+
message += containingPkg + ":" + labelNameInContainingPackage + "'?";
95+
} else {
96+
message +=
97+
"; have you deleted "
98+
+ containingPkg
99+
+ "/BUILD? "
100+
+ "If so, use the --deleted_packages="
101+
+ containingPkg
102+
+ " option";
103+
}
83104
return message;
84105
}
85106

src/main/java/com/google/devtools/build/lib/skyframe/PackageFunction.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -881,7 +881,7 @@ private static boolean maybeAddEventAboutLabelCrossingSubpackage(
881881
return true;
882882
}
883883
String errMsg =
884-
PackageLookupValue.getErrorMessageForSubpackageCrossesLabelPackageBoundary(
884+
PackageLookupValue.getErrorMessageForLabelCrossingPackageBoundary(
885885
pkgRoot, target.getLabel(), subpackageIdentifier, packageLookupValue);
886886
if (errMsg != null) {
887887
Event error =

src/main/java/com/google/devtools/build/lib/skyframe/PackageLookupValue.java

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -401,13 +401,13 @@ public String getErrorMsg() {
401401
}
402402

403403
/**
404-
* Creates the error message for the input {@linkplain Label label} if it contains a subpackage
405-
* crossing boundary.
404+
* Creates the error message for the input {@linkplain Label label} has a subpackage crossing
405+
* boundary.
406406
*
407407
* <p>Returns {@code null} if no subpackage is discovered or the subpackage is marked as DELETED.
408408
*/
409409
@Nullable
410-
static String getErrorMessageForSubpackageCrossesLabelPackageBoundary(
410+
static String getErrorMessageForLabelCrossingPackageBoundary(
411411
Root pkgRoot,
412412
Label label,
413413
PackageIdentifier subpackageIdentifier,
@@ -422,19 +422,19 @@ static String getErrorMessageForSubpackageCrossesLabelPackageBoundary(
422422
if (pkgRoot.equals(subPackageRoot)) {
423423
PathFragment labelRootPathFragment = label.getPackageIdentifier().getSourceRoot();
424424
PathFragment subpackagePathFragment = subpackageIdentifier.getSourceRoot();
425-
Preconditions.checkState(
426-
subpackagePathFragment.startsWith(labelRootPathFragment),
427-
"Subpackage should start with label's package path when they share the same package"
428-
+ " root");
429-
PathFragment labelNameInSubpackage =
430-
PathFragment.create(label.getName())
431-
.subFragment(
432-
subpackagePathFragment.segmentCount() - labelRootPathFragment.segmentCount());
433-
message += "; perhaps you meant to put the" + " colon here: '";
434-
if (subpackageIdentifier.getRepository().isMain()) {
435-
message += "//";
425+
if (subpackagePathFragment.startsWith(labelRootPathFragment)) {
426+
PathFragment labelNameInSubpackage =
427+
PathFragment.create(label.getName())
428+
.subFragment(
429+
subpackagePathFragment.segmentCount() - labelRootPathFragment.segmentCount());
430+
message += "; perhaps you meant to put the" + " colon here: '";
431+
if (subpackageIdentifier.getRepository().isMain()) {
432+
message += "//";
433+
}
434+
message += subpackageIdentifier + ":" + labelNameInSubpackage + "'?";
435+
} else {
436+
// TODO: Is this a valid case? How do we handle this case?
436437
}
437-
message += subpackageIdentifier + ":" + labelNameInSubpackage + "'?";
438438
} else {
439439
message +=
440440
"; have you deleted "

src/test/java/com/google/devtools/build/lib/skyframe/PackageFunctionTest.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1679,7 +1679,9 @@ public void testPreludeCanAccessBzlDialectFeatures() throws Exception {
16791679

16801680
@Test
16811681
public void testPreludeNeedNotBePresent() throws Exception {
1682-
scratch.file("pkg/BUILD", "print('FOO')");
1682+
scratch.file(
1683+
"pkg/BUILD", //
1684+
"print('FOO')");
16831685

16841686
getConfiguredTarget("//pkg:BUILD");
16851687
assertContainsEvent("FOO");

0 commit comments

Comments
 (0)