com.facebook.buck.rules.keys.DefaultDependencyFileRuleKeyBuilderFactory.java Source code

Java tutorial

Introduction

Here is the source code for com.facebook.buck.rules.keys.DefaultDependencyFileRuleKeyBuilderFactory.java

Source

/*
 * Copyright 2015-present Facebook, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may
 * not use this file except in compliance with the License. You may obtain
 * a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations
 * under the License.
 */

package com.facebook.buck.rules.keys;

import com.facebook.buck.model.Pair;
import com.facebook.buck.rules.BuildRule;
import com.facebook.buck.rules.RuleKey;
import com.facebook.buck.rules.RuleKeyBuilderFactory;
import com.facebook.buck.rules.SourcePath;
import com.facebook.buck.rules.SourcePathResolver;
import com.facebook.buck.util.cache.FileHashCache;
import com.google.common.collect.ImmutableCollection;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMultimap;
import com.google.common.collect.ImmutableSet;

import java.io.IOException;
import java.nio.file.NoSuchFileException;
import java.nio.file.Path;

/**
 * A variant of {@link InputBasedRuleKeyBuilderFactory} which ignores inputs when calculating the
 * {@link RuleKey}, allowing them to specified explicitly.
 */
public class DefaultDependencyFileRuleKeyBuilderFactory extends InputBasedRuleKeyBuilderFactory
        implements DependencyFileRuleKeyBuilderFactory {

    private final SourcePathResolver pathResolver;

    public DefaultDependencyFileRuleKeyBuilderFactory(FileHashCache fileHashCache, SourcePathResolver pathResolver,
            RuleKeyBuilderFactory ruleKeyBuilderFactory) {
        super(fileHashCache, pathResolver, ruleKeyBuilderFactory, InputHandling.IGNORE);
        this.pathResolver = pathResolver;
    }

    @Override
    public RuleKey build(BuildRule rule, ImmutableList<Path> inputs) throws IOException {

        // Create a builder which records all `SourcePath`s which are possibly used by the rule.
        Builder builder = newInstance(rule);

        // Use a multi-map to gather up all the `SourcePath`s that have relative paths that are
        // referenced in the input list, as it's possible for multiple `SourcePath`s to have the
        // same relative path (but come from different cells).
        ImmutableSet<Path> inputSet = ImmutableSet.copyOf(inputs);
        ImmutableMultimap.Builder<Path, SourcePath> relativePathToSourcePathsBuilder = ImmutableMultimap.builder();
        for (SourcePath input : builder.getInputsSoFar()) {
            Path relativePath = pathResolver.getRelativePath(input);
            if (inputSet.contains(relativePath)) {
                relativePathToSourcePathsBuilder.put(relativePath, input);
            }
        }
        final ImmutableMultimap<Path, SourcePath> relativePathToSourcePaths = relativePathToSourcePathsBuilder
                .build();

        // Now add the actual given inputs to the rule key using all possible `SourcePath`s they map to.
        // It's important that we do this by walking the `inputs` list, so that we maintain the original
        // ordering the duplicate handling.
        for (Path input : inputs) {
            ImmutableCollection<SourcePath> sourcePaths = relativePathToSourcePaths.get(input);

            // If we don't find actual inputs in the rule that correspond to this input, this likely means
            // that the rule changed to no longer use the input.  In this case, we need to throw a
            // `NoSuchFileException` error so that the build engine handles this as a signal that the dep
            // file rule key can't be used.
            if (sourcePaths.isEmpty()) {
                throw new NoSuchFileException(
                        String.format("%s: could not find any inputs matching the relative path `%s`",
                                rule.getBuildTarget(), input));
            }

            // Add each `SourcePath` using `builder.setPath()`.  We can't use `builder.setSourcePath()`
            // here since the special `RuleKeyBuilder` sub-class that dep-file rule keys use intentionally
            // override `builder.setSourcePath()` to be a noop (and just record the inputs).
            for (SourcePath sourcePath : sourcePaths) {
                builder.setPath(pathResolver.getAbsolutePath(sourcePath), pathResolver.getRelativePath(sourcePath));
            }
        }

        return builder.build();
    }

    @Override
    public Pair<RuleKey, ImmutableSet<SourcePath>> buildManifestKey(BuildRule rule) {
        Builder builder = newInstance(rule);
        builder.setReflectively("buck.key_type", "manifest");
        ImmutableSet<SourcePath> inputs = builder.getInputsSoFar();
        return new Pair<>(builder.build(), inputs);
    }

}