Search in sources :

Example 1 with PackageLookupValue

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;
}
Also used : SkyKey(com.google.devtools.build.skyframe.SkyKey) PackageLookupValue(com.google.devtools.build.lib.skyframe.PackageLookupValue) RootedPath(com.google.devtools.build.lib.vfs.RootedPath) Path(com.google.devtools.build.lib.vfs.Path) FileValue(com.google.devtools.build.lib.skyframe.FileValue) LabelSyntaxException(com.google.devtools.build.lib.cmdline.LabelSyntaxException) Label(com.google.devtools.build.lib.cmdline.Label) PathFragment(com.google.devtools.build.lib.vfs.PathFragment) EvalException(com.google.devtools.build.lib.syntax.EvalException) IOException(java.io.IOException) InconsistentFilesystemException(com.google.devtools.build.lib.skyframe.InconsistentFilesystemException) RootedPath(com.google.devtools.build.lib.vfs.RootedPath) FileSymlinkException(com.google.devtools.build.lib.skyframe.FileSymlinkException) RepositoryFunctionException(com.google.devtools.build.lib.rules.repository.RepositoryFunction.RepositoryFunctionException)

Example 2 with PackageLookupValue

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());
}
Also used : SkyKey(com.google.devtools.build.skyframe.SkyKey) PackageLookupValue(com.google.devtools.build.lib.skyframe.PackageLookupValue) RootedPath(com.google.devtools.build.lib.vfs.RootedPath) Path(com.google.devtools.build.lib.vfs.Path) LabelSyntaxException(com.google.devtools.build.lib.cmdline.LabelSyntaxException) EvalException(com.google.devtools.build.lib.syntax.EvalException)

Example 3 with PackageLookupValue

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;
}
Also used : SkyKey(com.google.devtools.build.skyframe.SkyKey) PackageLookupValue(com.google.devtools.build.lib.skyframe.PackageLookupValue) PathFragment(com.google.devtools.build.lib.vfs.PathFragment) SkyValue(com.google.devtools.build.skyframe.SkyValue) Map(java.util.Map) ImmutableMap(com.google.common.collect.ImmutableMap) HashMap(java.util.HashMap) LinkedHashSet(java.util.LinkedHashSet) CompactHashSet(com.google.devtools.build.lib.collect.CompactHashSet) HashSet(java.util.HashSet)

Example 4 with PackageLookupValue

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);
}
Also used : SkyKey(com.google.devtools.build.skyframe.SkyKey) PackageLookupValue(com.google.devtools.build.lib.skyframe.PackageLookupValue) BuildFileContainsErrorsException(com.google.devtools.build.lib.packages.BuildFileContainsErrorsException) WorkspaceFileValue(com.google.devtools.build.lib.skyframe.WorkspaceFileValue) Package(com.google.devtools.build.lib.packages.Package) Rule(com.google.devtools.build.lib.packages.Rule) RootedPath(com.google.devtools.build.lib.vfs.RootedPath) Nullable(javax.annotation.Nullable)

Aggregations

PackageLookupValue (com.google.devtools.build.lib.skyframe.PackageLookupValue)4 SkyKey (com.google.devtools.build.skyframe.SkyKey)4 RootedPath (com.google.devtools.build.lib.vfs.RootedPath)3 LabelSyntaxException (com.google.devtools.build.lib.cmdline.LabelSyntaxException)2 EvalException (com.google.devtools.build.lib.syntax.EvalException)2 Path (com.google.devtools.build.lib.vfs.Path)2 PathFragment (com.google.devtools.build.lib.vfs.PathFragment)2 ImmutableMap (com.google.common.collect.ImmutableMap)1 Label (com.google.devtools.build.lib.cmdline.Label)1 CompactHashSet (com.google.devtools.build.lib.collect.CompactHashSet)1 BuildFileContainsErrorsException (com.google.devtools.build.lib.packages.BuildFileContainsErrorsException)1 Package (com.google.devtools.build.lib.packages.Package)1 Rule (com.google.devtools.build.lib.packages.Rule)1 RepositoryFunctionException (com.google.devtools.build.lib.rules.repository.RepositoryFunction.RepositoryFunctionException)1 FileSymlinkException (com.google.devtools.build.lib.skyframe.FileSymlinkException)1 FileValue (com.google.devtools.build.lib.skyframe.FileValue)1 InconsistentFilesystemException (com.google.devtools.build.lib.skyframe.InconsistentFilesystemException)1 WorkspaceFileValue (com.google.devtools.build.lib.skyframe.WorkspaceFileValue)1 SkyValue (com.google.devtools.build.skyframe.SkyValue)1 IOException (java.io.IOException)1