|
50 | 50 | import com.google.devtools.build.lib.server.FailureDetails.FailureDetail;
|
51 | 51 | import com.google.devtools.build.lib.server.FailureDetails.StarlarkLoading;
|
52 | 52 | import com.google.devtools.build.lib.server.FailureDetails.StarlarkLoading.Code;
|
53 |
| -import com.google.devtools.build.lib.skyframe.PackageLookupValue.NoRepositoryPackageLookupValue; |
54 | 53 | import com.google.devtools.build.lib.skyframe.StarlarkBuiltinsFunction.BuiltinsFailedException;
|
55 | 54 | import com.google.devtools.build.lib.util.DetailedExitCode;
|
56 | 55 | import com.google.devtools.build.lib.util.Fingerprint;
|
|
64 | 63 | import com.google.devtools.build.skyframe.SkyKey;
|
65 | 64 | import com.google.devtools.build.skyframe.SkyValue;
|
66 | 65 | import com.google.devtools.build.skyframe.SkyframeLookupResult;
|
67 |
| -import java.util.ArrayList; |
68 | 66 | import java.util.HashMap;
|
69 | 67 | import java.util.HashSet;
|
70 | 68 | import java.util.LinkedHashSet;
|
@@ -646,103 +644,45 @@ private BzlCompileValue.Key validatePackageAndGetCompileKey(
|
646 | 644 | return key.getCompileKey(getBuiltinsRoot(builtinsBzlPath));
|
647 | 645 | }
|
648 | 646 |
|
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; |
703 | 663 | }
|
704 | 664 |
|
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; |
711 | 673 | } 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()); |
738 | 680 | } else {
|
739 |
| - throw BzlLoadFailedException.noBuildFile(label, /* reason= */ null); |
| 681 | + throw BzlLoadFailedException.labelCrossesPackageBoundary(label, packageLookup); |
740 | 682 | }
|
741 |
| - } else { |
742 |
| - throw BzlLoadFailedException.subpackageCrossesLabelPackageBoundary( |
743 |
| - label, candidateKey.argument(), candidateValue); |
744 | 683 | }
|
745 | 684 | }
|
| 685 | + return compileKey; |
746 | 686 | }
|
747 | 687 |
|
748 | 688 | private Root getBuiltinsRoot(String builtinsBzlPath) {
|
@@ -1643,21 +1583,17 @@ static BzlLoadFailedException noBuildFile(Label file, @Nullable String reason) {
|
1643 | 1583 | Code.PACKAGE_NOT_FOUND);
|
1644 | 1584 | }
|
1645 | 1585 |
|
1646 |
| - static BzlLoadFailedException labelSubpackageCrossesBoundary( |
| 1586 | + static BzlLoadFailedException labelCrossesPackageBoundary( |
1647 | 1587 | Label label, ContainingPackageLookupValue containingPackageLookupValue) {
|
1648 | 1588 | 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), |
1661 | 1597 | Code.LABEL_CROSSES_PACKAGE_BOUNDARY);
|
1662 | 1598 | }
|
1663 | 1599 |
|
|
0 commit comments