use of com.google.devtools.build.lib.skyframe.PackageLookupValue in project bazel by bazelbuild.
the class NewRepositoryBuildFileHandler method getBuildFileValue.
private FileValue getBuildFileValue(Rule rule, Environment env) throws RepositoryFunctionException, InterruptedException {
WorkspaceAttributeMapper mapper = WorkspaceAttributeMapper.of(rule);
String buildFileAttribute;
try {
buildFileAttribute = mapper.get("build_file", Type.STRING);
} catch (EvalException e) {
throw new RepositoryFunctionException(e, Transience.PERSISTENT);
}
RootedPath rootedBuild;
if (LabelValidator.isAbsolute(buildFileAttribute)) {
try {
// Parse a label
Label label = Label.parseAbsolute(buildFileAttribute);
SkyKey pkgSkyKey = PackageLookupValue.key(label.getPackageIdentifier());
PackageLookupValue pkgLookupValue = (PackageLookupValue) env.getValue(pkgSkyKey);
if (pkgLookupValue == null) {
return null;
}
if (!pkgLookupValue.packageExists()) {
throw new RepositoryFunctionException(new EvalException(rule.getLocation(), "Unable to load package for " + buildFileAttribute + ": not found."), Transience.PERSISTENT);
}
// And now for the file
Path packageRoot = pkgLookupValue.getRoot();
rootedBuild = RootedPath.toRootedPath(packageRoot, label.toPathFragment());
} catch (LabelSyntaxException ex) {
throw new RepositoryFunctionException(new EvalException(rule.getLocation(), String.format("In %s the 'build_file' attribute does not specify a valid label: %s", rule, ex.getMessage())), Transience.PERSISTENT);
}
} else {
// TODO(dmarting): deprecate using a path for the build_file attribute.
PathFragment buildFile = new PathFragment(buildFileAttribute);
Path buildFileTarget = workspacePath.getRelative(buildFile);
if (!buildFileTarget.exists()) {
throw new RepositoryFunctionException(new EvalException(rule.getLocation(), String.format("In %s the 'build_file' attribute does not specify an existing file " + "(%s does not exist)", rule, buildFileTarget)), Transience.PERSISTENT);
}
if (buildFile.isAbsolute()) {
rootedBuild = RootedPath.toRootedPath(buildFileTarget.getParentDirectory(), new PathFragment(buildFileTarget.getBaseName()));
} else {
rootedBuild = RootedPath.toRootedPath(workspacePath, buildFile);
}
}
SkyKey buildFileKey = FileValue.key(rootedBuild);
FileValue buildFileValue;
try {
// Note that this dependency is, strictly speaking, not necessary: the symlink could simply
// point to this FileValue and the symlink chasing could be done while loading the package
// but this results in a nicer error message and it's correct as long as RepositoryFunctions
// don't write to things in the file system this FileValue depends on. In theory, the latter
// is possible if the file referenced by build_file is a symlink to somewhere under the
// external/ directory, but if you do that, you are really asking for trouble.
buildFileValue = (FileValue) env.getValueOrThrow(buildFileKey, IOException.class, FileSymlinkException.class, InconsistentFilesystemException.class);
if (buildFileValue == null) {
return null;
}
} catch (IOException | FileSymlinkException | InconsistentFilesystemException e) {
throw new RepositoryFunctionException(new IOException("Cannot lookup " + buildFileAttribute + ": " + e.getMessage()), Transience.TRANSIENT);
}
return buildFileValue;
}
use of com.google.devtools.build.lib.skyframe.PackageLookupValue in project bazel by bazelbuild.
the class SkylarkRepositoryContext method getRootedPathFromLabel.
private static RootedPath getRootedPathFromLabel(Label label, Environment env) throws InterruptedException, EvalException {
// Look for package.
if (label.getPackageIdentifier().getRepository().isDefault()) {
try {
label = Label.create(label.getPackageIdentifier().makeAbsolute(), label.getName());
} catch (LabelSyntaxException e) {
// Can't happen because the input label is valid
throw new AssertionError(e);
}
}
SkyKey pkgSkyKey = PackageLookupValue.key(label.getPackageIdentifier());
PackageLookupValue pkgLookupValue = (PackageLookupValue) env.getValue(pkgSkyKey);
if (pkgLookupValue == null) {
throw SkylarkRepositoryFunction.restart();
}
if (!pkgLookupValue.packageExists()) {
throw new EvalException(Location.BUILTIN, "Unable to load package for " + label + ": not found.");
}
// And now for the file
Path packageRoot = pkgLookupValue.getRoot();
return RootedPath.toRootedPath(packageRoot, label.toPathFragment());
}
use of com.google.devtools.build.lib.skyframe.PackageLookupValue in project bazel by bazelbuild.
the class SkyQueryEnvironment method getSkyKeysForFileFragments.
/**
* Returns FileValue keys for which there may be relevant (from the perspective of {@link
* #getRBuildFiles}) FileValues in the graph corresponding to the given {@code pathFragments},
* which are assumed to be file paths.
*
* <p>To do this, we emulate the {@link ContainingPackageLookupFunction} logic: for each given
* file path, we look for the nearest ancestor directory (starting with its parent directory), if
* any, that has a package. The {@link PackageLookupValue} for this package tells us the package
* root that we should use for the {@link RootedPath} for the {@link FileValue} key.
*
* <p>Note that there may not be nodes in the graph corresponding to the returned SkyKeys.
*/
Collection<SkyKey> getSkyKeysForFileFragments(Iterable<PathFragment> pathFragments) throws InterruptedException {
Set<SkyKey> result = new HashSet<>();
Multimap<PathFragment, PathFragment> currentToOriginal = ArrayListMultimap.create();
for (PathFragment pathFragment : pathFragments) {
currentToOriginal.put(pathFragment, pathFragment);
}
while (!currentToOriginal.isEmpty()) {
Multimap<SkyKey, PathFragment> packageLookupKeysToOriginal = ArrayListMultimap.create();
Multimap<SkyKey, PathFragment> packageLookupKeysToCurrent = ArrayListMultimap.create();
for (Entry<PathFragment, PathFragment> entry : currentToOriginal.entries()) {
PathFragment current = entry.getKey();
PathFragment original = entry.getValue();
for (SkyKey packageLookupKey : getPkgLookupKeysForFile(original, current)) {
packageLookupKeysToOriginal.put(packageLookupKey, original);
packageLookupKeysToCurrent.put(packageLookupKey, current);
}
}
Map<SkyKey, SkyValue> lookupValues = graph.getSuccessfulValues(packageLookupKeysToOriginal.keySet());
for (Map.Entry<SkyKey, SkyValue> entry : lookupValues.entrySet()) {
SkyKey packageLookupKey = entry.getKey();
PackageLookupValue packageLookupValue = (PackageLookupValue) entry.getValue();
if (packageLookupValue.packageExists()) {
Collection<PathFragment> originalFiles = packageLookupKeysToOriginal.get(packageLookupKey);
Preconditions.checkState(!originalFiles.isEmpty(), entry);
for (PathFragment fileName : originalFiles) {
result.add(FileValue.key(RootedPath.toRootedPath(packageLookupValue.getRoot(), fileName)));
}
for (PathFragment current : packageLookupKeysToCurrent.get(packageLookupKey)) {
currentToOriginal.removeAll(current);
}
}
}
Multimap<PathFragment, PathFragment> newCurrentToOriginal = ArrayListMultimap.create();
for (PathFragment pathFragment : currentToOriginal.keySet()) {
PathFragment parent = pathFragment.getParentDirectory();
if (parent != null) {
newCurrentToOriginal.putAll(parent, currentToOriginal.get(pathFragment));
}
}
currentToOriginal = newCurrentToOriginal;
}
return result;
}
use of com.google.devtools.build.lib.skyframe.PackageLookupValue in project bazel by bazelbuild.
the class RepositoryFunction method getRule.
/**
* Uses a remote repository name to fetch the corresponding Rule describing how to get it.
*
* <p>This should be the unique entry point for resolving a remote repository function.
*/
@Nullable
public static Rule getRule(String repository, Environment env) throws RepositoryFunctionException, InterruptedException {
SkyKey packageLookupKey = PackageLookupValue.key(Label.EXTERNAL_PACKAGE_IDENTIFIER);
PackageLookupValue packageLookupValue = (PackageLookupValue) env.getValue(packageLookupKey);
if (packageLookupValue == null) {
return null;
}
RootedPath workspacePath = packageLookupValue.getRootedPath(Label.EXTERNAL_PACKAGE_IDENTIFIER);
SkyKey workspaceKey = WorkspaceFileValue.key(workspacePath);
do {
WorkspaceFileValue value = (WorkspaceFileValue) env.getValue(workspaceKey);
if (value == null) {
return null;
}
Package externalPackage = value.getPackage();
if (externalPackage.containsErrors()) {
Event.replayEventsOn(env.getListener(), externalPackage.getEvents());
throw new RepositoryFunctionException(new BuildFileContainsErrorsException(Label.EXTERNAL_PACKAGE_IDENTIFIER, "Could not load //external package"), Transience.PERSISTENT);
}
Rule rule = externalPackage.getRule(repository);
if (rule != null) {
return rule;
}
workspaceKey = value.next();
} while (workspaceKey != null);
throw new RepositoryNotFoundException(repository);
}
Aggregations