com.facebook.buck.rules.macros.QueryMacroExpander.java Source code

Java tutorial

Introduction

Here is the source code for com.facebook.buck.rules.macros.QueryMacroExpander.java

Source

/*
 * Copyright 2016-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.macros;

import com.facebook.buck.model.BuildTarget;
import com.facebook.buck.model.MacroException;
import com.facebook.buck.query.QueryBuildTarget;
import com.facebook.buck.query.QueryException;
import com.facebook.buck.query.QueryExpression;
import com.facebook.buck.query.QueryTarget;
import com.facebook.buck.rules.BuildRuleResolver;
import com.facebook.buck.rules.CellPathResolver;
import com.facebook.buck.rules.TargetGraph;
import com.facebook.buck.rules.query.GraphEnhancementQueryEnvironment;
import com.google.common.base.CharMatcher;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.common.util.concurrent.ListeningExecutorService;
import com.google.common.util.concurrent.MoreExecutors;

import java.util.HashSet;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * Abstract base class for the query_targets and query_outputs macros
 */
public abstract class QueryMacroExpander implements MacroExpander {

    private ListeningExecutorService executorService;
    private Optional<TargetGraph> targetGraph;

    public QueryMacroExpander(Optional<TargetGraph> targetGraph) {
        this.targetGraph = targetGraph;
        this.executorService = MoreExecutors.newDirectExecutorService();
    }

    private Stream<BuildTarget> extractTargets(BuildTarget target, CellPathResolver cellNames,
            Optional<BuildRuleResolver> resolver, ImmutableList<String> input) throws MacroException {
        if (input.isEmpty()) {
            throw new MacroException("One quoted query expression is expected with optional flags");
        }
        String queryExpression = CharMatcher.anyOf("\"'").trimFrom(input.get(0));
        final GraphEnhancementQueryEnvironment env = new GraphEnhancementQueryEnvironment(resolver, targetGraph,
                cellNames, target, ImmutableSet.of());
        try {
            QueryExpression parsedExp = QueryExpression.parse(queryExpression, env);
            HashSet<String> targetLiterals = new HashSet<>();
            parsedExp.collectTargetPatterns(targetLiterals);
            return targetLiterals.stream().flatMap(pattern -> {
                try {
                    return env.getTargetsMatchingPattern(pattern, executorService).stream();
                } catch (Exception e) {
                    throw new RuntimeException(new MacroException("Error parsing target expression", e));
                }
            }).map(queryTarget -> {
                Preconditions.checkState(queryTarget instanceof QueryBuildTarget);
                return ((QueryBuildTarget) queryTarget).getBuildTarget();
            });
        } catch (QueryException e) {
            throw new MacroException("Error parsing query from macro", e);
        }
    }

    protected Stream<QueryTarget> resolveQuery(BuildTarget target, CellPathResolver cellNames,
            final BuildRuleResolver resolver, String queryExpression) throws MacroException {
        GraphEnhancementQueryEnvironment env = new GraphEnhancementQueryEnvironment(Optional.of(resolver),
                targetGraph, cellNames, target, ImmutableSet.of());
        try {
            QueryExpression parsedExp = QueryExpression.parse(queryExpression, env);
            Set<QueryTarget> queryTargets = parsedExp.eval(env, executorService);
            return queryTargets.stream();
        } catch (QueryException e) {
            throw new MacroException("Error parsing/executing query from macro", e);
        } catch (InterruptedException e) {
            throw new MacroException("Error executing query", e);
        }
    }

    @Override
    public ImmutableList<BuildTarget> extractParseTimeDeps(BuildTarget target, CellPathResolver cellNames,
            ImmutableList<String> input) throws MacroException {
        return ImmutableList
                .copyOf(extractTargets(target, cellNames, Optional.empty(), input).collect(Collectors.toList()));
    }

}