Search in sources :

Example 36 with SkyValue

use of com.google.devtools.build.skyframe.SkyValue in project bazel by bazelbuild.

the class AndroidSdkRepositoryFunction method getSubdirectoryListingValues.

/** Gets DirectoryListingValues for subdirectories of the directory or returns null. */
private static ImmutableMap<PathFragment, DirectoryListingValue> getSubdirectoryListingValues(final Path root, final PathFragment path, DirectoryListingValue directory, Environment env) throws RepositoryFunctionException, InterruptedException {
    Map<PathFragment, SkyKey> skyKeysForSubdirectoryLookups = Maps.transformEntries(Maps.uniqueIndex(directory.getDirents(), new Function<Dirent, PathFragment>() {

        @Override
        public PathFragment apply(Dirent input) {
            return path.getRelative(input.getName());
        }
    }), new EntryTransformer<PathFragment, Dirent, SkyKey>() {

        @Override
        public SkyKey transformEntry(PathFragment key, Dirent value) {
            return DirectoryListingValue.key(RootedPath.toRootedPath(root, root.getRelative(key)));
        }
    });
    Map<SkyKey, ValueOrException<InconsistentFilesystemException>> values = env.getValuesOrThrow(skyKeysForSubdirectoryLookups.values(), InconsistentFilesystemException.class);
    ImmutableMap.Builder<PathFragment, DirectoryListingValue> directoryListingValues = new ImmutableMap.Builder<>();
    for (PathFragment pathFragment : skyKeysForSubdirectoryLookups.keySet()) {
        try {
            SkyValue skyValue = values.get(skyKeysForSubdirectoryLookups.get(pathFragment)).get();
            if (skyValue == null) {
                return null;
            }
            directoryListingValues.put(pathFragment, (DirectoryListingValue) skyValue);
        } catch (InconsistentFilesystemException e) {
            throw new RepositoryFunctionException(new IOException(e), Transience.PERSISTENT);
        }
    }
    return directoryListingValues.build();
}
Also used : SkyKey(com.google.devtools.build.skyframe.SkyKey) PathFragment(com.google.devtools.build.lib.vfs.PathFragment) IOException(java.io.IOException) InconsistentFilesystemException(com.google.devtools.build.lib.skyframe.InconsistentFilesystemException) ValueOrException(com.google.devtools.build.skyframe.ValueOrException) ImmutableMap(com.google.common.collect.ImmutableMap) SkyValue(com.google.devtools.build.skyframe.SkyValue) RepositoryFunction(com.google.devtools.build.lib.rules.repository.RepositoryFunction) Function(com.google.common.base.Function) DirectoryListingValue(com.google.devtools.build.lib.skyframe.DirectoryListingValue) Dirent(com.google.devtools.build.lib.vfs.Dirent)

Example 37 with SkyValue

use of com.google.devtools.build.skyframe.SkyValue in project bazel by bazelbuild.

the class SkyframeExecutor method getDiff.

protected Differencer.Diff getDiff(TimestampGranularityMonitor tsgm, Iterable<PathFragment> modifiedSourceFiles, final Path pathEntry) throws InterruptedException {
    if (Iterables.isEmpty(modifiedSourceFiles)) {
        return new ImmutableDiff(ImmutableList.<SkyKey>of(), ImmutableMap.<SkyKey, SkyValue>of());
    }
    // TODO(bazel-team): change ModifiedFileSet to work with RootedPaths instead of PathFragments.
    Iterable<SkyKey> dirtyFileStateSkyKeys = Iterables.transform(modifiedSourceFiles, new Function<PathFragment, SkyKey>() {

        @Override
        public SkyKey apply(PathFragment pathFragment) {
            Preconditions.checkState(!pathFragment.isAbsolute(), "found absolute PathFragment: %s", pathFragment);
            return FileStateValue.key(RootedPath.toRootedPath(pathEntry, pathFragment));
        }
    });
    // We only need to invalidate directory values when a file has been created or deleted or
    // changes type, not when it has merely been modified. Unfortunately we do not have that
    // information here, so we compute it ourselves.
    // TODO(bazel-team): Fancy filesystems could provide it with a hypothetically modified
    // DiffAwareness interface.
    LOG.info("About to recompute filesystem nodes corresponding to files that are known to have " + "changed");
    FilesystemValueChecker fsvc = new FilesystemValueChecker(tsgm, null);
    Map<SkyKey, SkyValue> valuesMap = memoizingEvaluator.getValues();
    Differencer.DiffWithDelta diff = fsvc.getNewAndOldValues(valuesMap, dirtyFileStateSkyKeys, new FileDirtinessChecker());
    Set<SkyKey> valuesToInvalidate = new HashSet<>();
    Map<SkyKey, SkyValue> valuesToInject = new HashMap<>();
    for (Map.Entry<SkyKey, Delta> entry : diff.changedKeysWithNewAndOldValues().entrySet()) {
        SkyKey key = entry.getKey();
        Preconditions.checkState(key.functionName().equals(SkyFunctions.FILE_STATE), key);
        RootedPath rootedPath = (RootedPath) key.argument();
        Delta delta = entry.getValue();
        FileStateValue oldValue = (FileStateValue) delta.getOldValue();
        FileStateValue newValue = (FileStateValue) delta.getNewValue();
        if (newValue != null) {
            valuesToInject.put(key, newValue);
        } else {
            valuesToInvalidate.add(key);
        }
        SkyKey dirListingStateKey = parentDirectoryListingStateKey(rootedPath);
        // Invalidate the directory listing for the path's parent directory if the change was
        // relevant (e.g. path turned from a symlink into a directory) OR if we don't have enough
        // information to determine it was irrelevant.
        boolean changedType = false;
        if (newValue == null) {
            changedType = true;
        } else if (oldValue != null) {
            changedType = !oldValue.getType().equals(newValue.getType());
        } else {
            DirectoryListingStateValue oldDirListingStateValue = (DirectoryListingStateValue) valuesMap.get(dirListingStateKey);
            if (oldDirListingStateValue != null) {
                String baseName = rootedPath.getRelativePath().getBaseName();
                Dirent oldDirent = oldDirListingStateValue.getDirents().maybeGetDirent(baseName);
                changedType = (oldDirent == null) || !compatibleFileTypes(oldDirent.getType(), newValue.getType());
            } else {
                changedType = true;
            }
        }
        if (changedType) {
            valuesToInvalidate.add(dirListingStateKey);
        }
    }
    for (SkyKey key : diff.changedKeysWithoutNewValues()) {
        Preconditions.checkState(key.functionName().equals(SkyFunctions.FILE_STATE), key);
        RootedPath rootedPath = (RootedPath) key.argument();
        valuesToInvalidate.add(parentDirectoryListingStateKey(rootedPath));
    }
    return new ImmutableDiff(valuesToInvalidate, valuesToInject);
}
Also used : SkyKey(com.google.devtools.build.skyframe.SkyKey) ImmutableDiff(com.google.devtools.build.skyframe.ImmutableDiff) LinkedHashMap(java.util.LinkedHashMap) HashMap(java.util.HashMap) PathFragment(com.google.devtools.build.lib.vfs.PathFragment) Differencer(com.google.devtools.build.skyframe.Differencer) RootedPath(com.google.devtools.build.lib.vfs.RootedPath) SkyValue(com.google.devtools.build.skyframe.SkyValue) FileDirtinessChecker(com.google.devtools.build.lib.skyframe.DirtinessCheckerUtils.FileDirtinessChecker) Delta(com.google.devtools.build.skyframe.Differencer.DiffWithDelta.Delta) Dirent(com.google.devtools.build.lib.vfs.Dirent) Map(java.util.Map) LinkedHashMap(java.util.LinkedHashMap) ImmutableMap(com.google.common.collect.ImmutableMap) HashMap(java.util.HashMap) HashSet(java.util.HashSet)

Example 38 with SkyValue

use of com.google.devtools.build.skyframe.SkyValue in project bazel by bazelbuild.

the class SkyframeExecutor method getConfiguredTargetMap.

/**
   * Returns a map from {@link Dependency} inputs to the {@link ConfiguredTarget}s corresponding to
   * those dependencies.
   *
   * <p>For use for legacy support and tests calling through {@code BuildView} only.
   *
   * <p>If a requested configured target is in error, the corresponding value is omitted from the
   * returned list.
   */
@ThreadSafety.ThreadSafe
public ImmutableMultimap<Dependency, ConfiguredTarget> getConfiguredTargetMap(ExtendedEventHandler eventHandler, BuildConfiguration originalConfig, Iterable<Dependency> keys, boolean useOriginalConfig) {
    checkActive();
    Multimap<Dependency, BuildConfiguration> configs;
    if (originalConfig != null) {
        if (useOriginalConfig) {
            // This flag is used because of some unfortunate complexity in the configuration machinery:
            // Most callers of this method pass a <Label, Configuration> pair to directly create a
            // ConfiguredTarget from, but happen to use the Dependency data structure to pass that
            // info (even though the data has nothing to do with dependencies). If this configuration
            // includes a split transition, a dynamic configuration created from it will *not*
            // include that transition (because dynamic configurations don't embed transitions to
            // other configurations. In that case, we need to preserve the original configuration.
            // TODO(bazel-team); make this unnecessary once split transition logic is properly ported
            // out of configurations.
            configs = ArrayListMultimap.<Dependency, BuildConfiguration>create();
            configs.put(Iterables.getOnlyElement(keys), originalConfig);
        } else {
            configs = getConfigurations(eventHandler, originalConfig.getOptions(), keys);
        }
    } else {
        configs = ArrayListMultimap.<Dependency, BuildConfiguration>create();
        for (Dependency key : keys) {
            configs.put(key, null);
        }
    }
    final List<SkyKey> skyKeys = new ArrayList<>();
    for (Dependency key : keys) {
        if (!configs.containsKey(key)) {
            // it couldn't be loaded). Exclude it from the results.
            continue;
        }
        for (BuildConfiguration depConfig : configs.get(key)) {
            skyKeys.add(ConfiguredTargetValue.key(key.getLabel(), depConfig));
            for (AspectDescriptor aspectDescriptor : key.getAspects().getAllAspects()) {
                skyKeys.add(ActionLookupValue.key(AspectValue.createAspectKey(key.getLabel(), depConfig, aspectDescriptor, depConfig)));
            }
        }
    }
    EvaluationResult<SkyValue> result = evaluateSkyKeys(eventHandler, skyKeys);
    for (Map.Entry<SkyKey, ErrorInfo> entry : result.errorMap().entrySet()) {
        reportCycles(eventHandler, entry.getValue().getCycleInfo(), entry.getKey());
    }
    ImmutableMultimap.Builder<Dependency, ConfiguredTarget> cts = ImmutableMultimap.<Dependency, ConfiguredTarget>builder();
    DependentNodeLoop: for (Dependency key : keys) {
        if (!configs.containsKey(key)) {
            // it couldn't be loaded). Exclude it from the results.
            continue;
        }
        for (BuildConfiguration depConfig : configs.get(key)) {
            SkyKey configuredTargetKey = ConfiguredTargetValue.key(key.getLabel(), depConfig);
            if (result.get(configuredTargetKey) == null) {
                continue;
            }
            ConfiguredTarget configuredTarget = ((ConfiguredTargetValue) result.get(configuredTargetKey)).getConfiguredTarget();
            List<ConfiguredAspect> configuredAspects = new ArrayList<>();
            for (AspectDescriptor aspectDescriptor : key.getAspects().getAllAspects()) {
                SkyKey aspectKey = ActionLookupValue.key(AspectValue.createAspectKey(key.getLabel(), depConfig, aspectDescriptor, depConfig));
                if (result.get(aspectKey) == null) {
                    continue DependentNodeLoop;
                }
                configuredAspects.add(((AspectValue) result.get(aspectKey)).getConfiguredAspect());
            }
            try {
                cts.put(key, MergedConfiguredTarget.of(configuredTarget, configuredAspects));
            } catch (DuplicateException e) {
                throw new IllegalStateException(String.format("Error creating %s", configuredTarget.getTarget().getLabel()), e);
            }
        }
    }
    return cts.build();
}
Also used : SkyKey(com.google.devtools.build.skyframe.SkyKey) ErrorInfo(com.google.devtools.build.skyframe.ErrorInfo) ArrayList(java.util.ArrayList) ConfiguredTarget(com.google.devtools.build.lib.analysis.ConfiguredTarget) MergedConfiguredTarget(com.google.devtools.build.lib.analysis.MergedConfiguredTarget) Dependency(com.google.devtools.build.lib.analysis.Dependency) BuildConfiguration(com.google.devtools.build.lib.analysis.config.BuildConfiguration) SkyValue(com.google.devtools.build.skyframe.SkyValue) DuplicateException(com.google.devtools.build.lib.analysis.MergedConfiguredTarget.DuplicateException) AspectDescriptor(com.google.devtools.build.lib.packages.AspectDescriptor) ArrayList(java.util.ArrayList) List(java.util.List) ImmutableList(com.google.common.collect.ImmutableList) ImmutableMultimap(com.google.common.collect.ImmutableMultimap) Map(java.util.Map) LinkedHashMap(java.util.LinkedHashMap) ImmutableMap(com.google.common.collect.ImmutableMap) HashMap(java.util.HashMap)

Example 39 with SkyValue

use of com.google.devtools.build.skyframe.SkyValue in project bazel by bazelbuild.

the class SkylarkImportLookupFunction method computeInternal.

private SkyValue computeInternal(Label fileLabel, boolean inWorkspace, Environment env, @Nullable LinkedHashMap<Label, SkylarkImportLookupValue> alreadyVisited) throws InconsistentFilesystemException, SkylarkImportFailedException, InterruptedException {
    PathFragment filePath = fileLabel.toPathFragment();
    // Load the AST corresponding to this file.
    ASTFileLookupValue astLookupValue;
    try {
        SkyKey astLookupKey = ASTFileLookupValue.key(fileLabel);
        astLookupValue = (ASTFileLookupValue) env.getValueOrThrow(astLookupKey, ErrorReadingSkylarkExtensionException.class, InconsistentFilesystemException.class);
    } catch (ErrorReadingSkylarkExtensionException e) {
        throw SkylarkImportFailedException.errorReadingFile(filePath, e.getMessage());
    }
    if (astLookupValue == null) {
        return null;
    }
    if (!astLookupValue.lookupSuccessful()) {
        // Skylark import files have to exist.
        throw SkylarkImportFailedException.noFile(astLookupValue.getErrorMsg());
    }
    BuildFileAST ast = astLookupValue.getAST();
    if (ast.containsErrors()) {
        throw SkylarkImportFailedException.skylarkErrors(filePath);
    }
    // Process the load statements in the file.
    ImmutableList<SkylarkImport> imports = ast.getImports();
    Map<String, Extension> extensionsForImports = Maps.newHashMapWithExpectedSize(imports.size());
    ImmutableList.Builder<SkylarkFileDependency> fileDependencies = ImmutableList.builder();
    ImmutableMap<String, Label> labelsForImports;
    // Find the labels corresponding to the load statements.
    labelsForImports = findLabelsForLoadStatements(imports, fileLabel, env);
    if (labelsForImports == null) {
        return null;
    }
    // Look up and load the imports.
    ImmutableCollection<Label> importLabels = labelsForImports.values();
    List<SkyKey> importLookupKeys = Lists.newArrayListWithExpectedSize(importLabels.size());
    for (Label importLabel : importLabels) {
        importLookupKeys.add(SkylarkImportLookupValue.key(importLabel, inWorkspace));
    }
    Map<SkyKey, SkyValue> skylarkImportMap;
    boolean valuesMissing = false;
    if (alreadyVisited == null) {
        // Not inlining.
        skylarkImportMap = env.getValues(importLookupKeys);
        valuesMissing = env.valuesMissing();
    } else {
        // Inlining calls to SkylarkImportLookupFunction.
        if (alreadyVisited.containsKey(fileLabel)) {
            ImmutableList<Label> cycle = CycleUtils.splitIntoPathAndChain(Predicates.equalTo(fileLabel), alreadyVisited.keySet()).second;
            throw new SkylarkImportFailedException("Skylark import cycle: " + cycle);
        }
        alreadyVisited.put(fileLabel, null);
        skylarkImportMap = Maps.newHashMapWithExpectedSize(imports.size());
        for (SkyKey importLookupKey : importLookupKeys) {
            SkyValue skyValue = this.computeWithInlineCallsInternal(importLookupKey, env, alreadyVisited);
            if (skyValue == null) {
                Preconditions.checkState(env.valuesMissing(), "no skylark import value for %s", importLookupKey);
                // We continue making inline calls even if some requested values are missing, to maximize
                // the number of dependent (non-inlined) SkyFunctions that are requested, thus avoiding a
                // quadratic number of restarts.
                valuesMissing = true;
            } else {
                skylarkImportMap.put(importLookupKey, skyValue);
            }
        }
        // All imports traversed, this key can no longer be part of a cycle.
        Preconditions.checkState(alreadyVisited.remove(fileLabel) == null, fileLabel);
    }
    if (valuesMissing) {
        // This means some imports are unavailable.
        return null;
    }
    // Process the loaded imports.
    for (Entry<String, Label> importEntry : labelsForImports.entrySet()) {
        String importString = importEntry.getKey();
        Label importLabel = importEntry.getValue();
        SkyKey keyForLabel = SkylarkImportLookupValue.key(importLabel, inWorkspace);
        SkylarkImportLookupValue importLookupValue = (SkylarkImportLookupValue) skylarkImportMap.get(keyForLabel);
        extensionsForImports.put(importString, importLookupValue.getEnvironmentExtension());
        fileDependencies.add(importLookupValue.getDependency());
    }
    // Skylark UserDefinedFunction-s in that file will share this function definition Environment,
    // which will be frozen by the time it is returned by createExtension.
    Extension extension = createExtension(ast, fileLabel, extensionsForImports, env, inWorkspace);
    SkylarkImportLookupValue result = new SkylarkImportLookupValue(extension, new SkylarkFileDependency(fileLabel, fileDependencies.build()));
    if (alreadyVisited != null) {
        alreadyVisited.put(fileLabel, result);
    }
    return result;
}
Also used : SkyKey(com.google.devtools.build.skyframe.SkyKey) ImmutableList(com.google.common.collect.ImmutableList) PathFragment(com.google.devtools.build.lib.vfs.PathFragment) Label(com.google.devtools.build.lib.cmdline.Label) SkylarkImport(com.google.devtools.build.lib.syntax.SkylarkImport) Extension(com.google.devtools.build.lib.syntax.Environment.Extension) SkyValue(com.google.devtools.build.skyframe.SkyValue) BuildFileAST(com.google.devtools.build.lib.syntax.BuildFileAST)

Example 40 with SkyValue

use of com.google.devtools.build.skyframe.SkyValue in project bazel by bazelbuild.

the class TargetPatternPhaseFunction method determineTests.

/**
   * Interpret test target labels from the command-line arguments and return the corresponding set
   * of targets, handling the filter flags, and expanding test suites.
   *
   * @param targetPatterns the list of command-line target patterns specified by the user
   * @param testFilter the test filter
   */
private static ResolvedTargets<Target> determineTests(Environment env, List<String> targetPatterns, String offset, TestFilter testFilter) throws InterruptedException {
    List<SkyKey> patternSkyKeys = new ArrayList<>();
    for (TargetPatternSkyKeyOrException keyOrException : TargetPatternValue.keys(targetPatterns, FilteringPolicies.FILTER_TESTS, offset)) {
        try {
            patternSkyKeys.add(keyOrException.getSkyKey());
        } catch (TargetParsingException e) {
        // Skip.
        }
    }
    Map<SkyKey, ValueOrException<TargetParsingException>> resolvedPatterns = env.getValuesOrThrow(patternSkyKeys, TargetParsingException.class);
    if (env.valuesMissing()) {
        return null;
    }
    List<SkyKey> expandedSuiteKeys = new ArrayList<>();
    for (SkyKey key : patternSkyKeys) {
        TargetPatternValue value;
        try {
            value = (TargetPatternValue) resolvedPatterns.get(key).get();
        } catch (TargetParsingException e) {
            // Skip.
            continue;
        }
        expandedSuiteKeys.add(TestSuiteExpansionValue.key(value.getTargets().getTargets()));
    }
    Map<SkyKey, SkyValue> expandedSuites = env.getValues(expandedSuiteKeys);
    if (env.valuesMissing()) {
        return null;
    }
    ResolvedTargets.Builder<Target> testTargetsBuilder = ResolvedTargets.builder();
    for (SkyKey key : patternSkyKeys) {
        TargetPatternKey pattern = (TargetPatternKey) key.argument();
        TargetPatternValue value;
        try {
            value = (TargetPatternValue) resolvedPatterns.get(key).get();
        } catch (TargetParsingException e) {
            // This was already reported in getTargetsToBuild (maybe merge the two code paths?).
            continue;
        }
        TestSuiteExpansionValue expandedSuitesValue = (TestSuiteExpansionValue) expandedSuites.get(TestSuiteExpansionValue.key(value.getTargets().getTargets()));
        if (pattern.isNegative()) {
            ResolvedTargets<Target> negativeTargets = expandedSuitesValue.getTargets();
            testTargetsBuilder.filter(Predicates.not(Predicates.in(negativeTargets.getTargets())));
            testTargetsBuilder.mergeError(negativeTargets.hasError());
        } else {
            ResolvedTargets<Target> positiveTargets = expandedSuitesValue.getTargets();
            testTargetsBuilder.addAll(positiveTargets.getTargets());
            testTargetsBuilder.mergeError(positiveTargets.hasError());
        }
    }
    testTargetsBuilder.filter(testFilter);
    return testTargetsBuilder.build();
}
Also used : SkyKey(com.google.devtools.build.skyframe.SkyKey) TargetPatternKey(com.google.devtools.build.lib.skyframe.TargetPatternValue.TargetPatternKey) ArrayList(java.util.ArrayList) TargetPatternSkyKeyOrException(com.google.devtools.build.lib.skyframe.TargetPatternValue.TargetPatternSkyKeyOrException) ValueOrException(com.google.devtools.build.skyframe.ValueOrException) SkyValue(com.google.devtools.build.skyframe.SkyValue) Target(com.google.devtools.build.lib.packages.Target) TargetParsingException(com.google.devtools.build.lib.cmdline.TargetParsingException) ResolvedTargets(com.google.devtools.build.lib.cmdline.ResolvedTargets)

Aggregations

SkyValue (com.google.devtools.build.skyframe.SkyValue)66 SkyKey (com.google.devtools.build.skyframe.SkyKey)63 Map (java.util.Map)20 ImmutableMap (com.google.common.collect.ImmutableMap)18 RootedPath (com.google.devtools.build.lib.vfs.RootedPath)17 Test (org.junit.Test)16 Artifact (com.google.devtools.build.lib.actions.Artifact)15 PathFragment (com.google.devtools.build.lib.vfs.PathFragment)15 HashMap (java.util.HashMap)14 ImmutableList (com.google.common.collect.ImmutableList)10 SequentialBuildDriver (com.google.devtools.build.skyframe.SequentialBuildDriver)10 Path (com.google.devtools.build.lib.vfs.Path)9 ErrorInfo (com.google.devtools.build.skyframe.ErrorInfo)8 LinkedHashMap (java.util.LinkedHashMap)8 Label (com.google.devtools.build.lib.cmdline.Label)7 HashSet (java.util.HashSet)7 Target (com.google.devtools.build.lib.packages.Target)6 NoSuchPackageException (com.google.devtools.build.lib.packages.NoSuchPackageException)5 IOException (java.io.IOException)5 ImmutableSet (com.google.common.collect.ImmutableSet)4