Skip to content

Commit

Permalink
Move the default cquery output format to its own callback and standar…
Browse files Browse the repository at this point in the history
…dize cquery output callback logic

PiperOrigin-RevId: 190667120
  • Loading branch information
juliexxia authored and Copybara-Service committed Mar 27, 2018
1 parent 7a84f65 commit d350a89
Show file tree
Hide file tree
Showing 8 changed files with 207 additions and 88 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,22 +15,19 @@

import com.google.common.collect.ImmutableList;
import com.google.devtools.build.lib.analysis.BuildView.AnalysisResult;
import com.google.devtools.build.lib.analysis.ConfiguredTarget;
import com.google.devtools.build.lib.analysis.TargetAndConfiguration;
import com.google.devtools.build.lib.analysis.ViewCreationFailedException;
import com.google.devtools.build.lib.analysis.config.BuildConfiguration;
import com.google.devtools.build.lib.analysis.config.BuildConfigurationCollection;
import com.google.devtools.build.lib.events.Event;
import com.google.devtools.build.lib.query2.ConfiguredTargetQueryEnvironment;
import com.google.devtools.build.lib.query2.TransitionsOutputFormatterCallback;
import com.google.devtools.build.lib.query2.CqueryThreadsafeCallback;
import com.google.devtools.build.lib.query2.engine.QueryEnvironment.QueryFunction;
import com.google.devtools.build.lib.query2.engine.QueryEvalResult;
import com.google.devtools.build.lib.query2.engine.QueryException;
import com.google.devtools.build.lib.query2.engine.QueryExpression;
import com.google.devtools.build.lib.query2.engine.TargetLiteral;
import com.google.devtools.build.lib.query2.engine.ThreadSafeOutputFormatterCallback;
import com.google.devtools.build.lib.query2.output.CqueryOptions;
import com.google.devtools.build.lib.query2.output.CqueryOptions.Transitions;
import com.google.devtools.build.lib.runtime.CommandEnvironment;
import com.google.devtools.build.lib.skyframe.SkyframeExecutorWrappingWalkableGraph;
import com.google.devtools.build.skyframe.WalkableGraph;
Expand Down Expand Up @@ -130,38 +127,27 @@ private void doConfiguredTargetQuery(
env.getPackageManager().getPackagePath(),
() -> walkableGraph,
cqueryOptions.toSettings());
CqueryOptions.Transitions transitions = cqueryOptions.transitions;
ThreadSafeOutputFormatterCallback<ConfiguredTarget> callback =
!transitions.equals(Transitions.NONE)
? new TransitionsOutputFormatterCallback(
configuredTargetQueryEnvironment.getAccessor(),
transitions,
env.getReporter().getOutErr().getOutputStream(),
env.getSkyframeExecutor(),
hostConfiguration)
: new ThreadSafeOutputFormatterCallback<ConfiguredTarget>() {
@Override
public void processOutput(Iterable<ConfiguredTarget> partialResult) {
for (ConfiguredTarget configuredTarget : partialResult) {
BuildConfiguration config =
env.getSkyframeExecutor()
.getConfiguration(
env.getReporter(), configuredTarget.getConfigurationKey());
StringBuilder output =
new StringBuilder()
.append(
ConfiguredTargetQueryEnvironment.getCorrectLabel(configuredTarget))
.append(" (")
.append(config != null && config.isHostConfiguration() ? "HOST" : config)
.append(")");
env.getReporter().getOutErr().printOutLn(output.toString());
}
}
};
Iterable<CqueryThreadsafeCallback> callbacks =
ConfiguredTargetQueryEnvironment.getDefaultOutputFormatters(
configuredTargetQueryEnvironment.getAccessor(),
cqueryOptions,
env.getReporter().getOutErr().getOutputStream(),
env.getSkyframeExecutor(),
hostConfiguration);
CqueryThreadsafeCallback callback =
CqueryThreadsafeCallback.getCallback(cqueryOptions.outputFormat, callbacks);
if (callback == null) {
env.getReporter()
.handle(
Event.error(
String.format(
"Invalid output format '%s'. Valid values are: %s",
cqueryOptions.outputFormat,
CqueryThreadsafeCallback.callbackNames(callbacks))));
return;
}
QueryEvalResult result =
configuredTargetQueryEnvironment.evaluateQuery(
queryExpression,
callback);
configuredTargetQueryEnvironment.evaluateQuery(queryExpression, callback);
if (result.isEmpty()) {
env.getReporter().handle(Event.info("Empty query results"));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,20 @@

/** Options shared between blaze query and blaze cquery. */
public class CommonQueryOptions extends OptionsBase {

@Option(
name = "output",
defaultValue = "label",
category = "query",
documentationCategory = OptionDocumentationCategory.QUERY,
effectTags = {OptionEffectTag.TERMINAL_OUTPUT},
help =
"The format in which the query results should be printed. Allowed values for query are: "
+ "build, graph, label, label_kind, locations, maxrank, minrank, package, proto, xml."
+ "Currently you should never explicitly set this flag for cquery."
)
public String outputFormat;

@Option(
name = "universe_scope",
defaultValue = "",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@
import com.google.devtools.build.lib.query2.engine.QueryUtil.UniquifierImpl;
import com.google.devtools.build.lib.query2.engine.ThreadSafeOutputFormatterCallback;
import com.google.devtools.build.lib.query2.engine.Uniquifier;
import com.google.devtools.build.lib.query2.output.CqueryOptions;
import com.google.devtools.build.lib.query2.output.QueryOptions;
import com.google.devtools.build.lib.rules.AliasConfiguredTarget;
import com.google.devtools.build.lib.skyframe.BuildConfigurationValue;
Expand All @@ -60,13 +61,15 @@
import com.google.devtools.build.lib.skyframe.PackageValue;
import com.google.devtools.build.lib.skyframe.RecursivePackageProviderBackedTargetPatternResolver;
import com.google.devtools.build.lib.skyframe.SkyFunctions;
import com.google.devtools.build.lib.skyframe.SkyframeExecutor;
import com.google.devtools.build.lib.skyframe.TargetPatternValue;
import com.google.devtools.build.lib.skyframe.TargetPatternValue.TargetPatternKey;
import com.google.devtools.build.skyframe.SkyKey;
import com.google.devtools.build.skyframe.WalkableGraph;
import com.google.devtools.common.options.OptionsParser;
import com.google.devtools.common.options.OptionsParsingException;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
Expand Down Expand Up @@ -189,6 +192,20 @@ public static Label getCorrectLabel(ConfiguredTarget target) {
return target.getLabel();
}

public static ImmutableList<CqueryThreadsafeCallback> getDefaultOutputFormatters(
TargetAccessor<ConfiguredTarget> accessor,
CqueryOptions options,
OutputStream out,
SkyframeExecutor skyframeExecutor,
BuildConfiguration hostConfiguration) {
return new ImmutableList.Builder<CqueryThreadsafeCallback>()
.add(new LabelAndConfigurationOutputFormatterCallback(options, out))
.add(
new TransitionsOutputFormatterCallback(
accessor, options, out, skyframeExecutor, hostConfiguration))
.build();
}

// Check to make sure the settings requested are currently supported by this class
private void checkSettings(Set<Setting> settings) throws QueryException {
if (settings.contains(Setting.NO_NODEP_DEPS)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
// Copyright 2018 The Bazel Authors. All rights reserved.
//
// 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.google.devtools.build.lib.query2;

import static java.util.stream.Collectors.joining;

import com.google.common.annotations.VisibleForTesting;
import com.google.common.collect.Streams;
import com.google.devtools.build.lib.analysis.ConfiguredTarget;
import com.google.devtools.build.lib.query2.engine.ThreadSafeOutputFormatterCallback;
import com.google.devtools.build.lib.query2.output.CqueryOptions;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.List;

/**
* Parents class for cquery output callbacks. Handles names and outputting contents of result list
* that is populated by child classes.
*/
public abstract class CqueryThreadsafeCallback
extends ThreadSafeOutputFormatterCallback<ConfiguredTarget> {

protected final CqueryOptions options;
protected PrintStream printStream = null;

private final List<String> result = new ArrayList<>();

CqueryThreadsafeCallback(CqueryOptions options, OutputStream out) {
this.options = options;
if (out != null) {
this.printStream = new PrintStream(out);
}
}

public abstract String getName();

public static String callbackNames(Iterable<CqueryThreadsafeCallback> callbacks) {
return Streams.stream(callbacks).map(CqueryThreadsafeCallback::getName).collect(joining(", "));
}

public static CqueryThreadsafeCallback getCallback(
String type, Iterable<CqueryThreadsafeCallback> callbacks) {
for (CqueryThreadsafeCallback callback : callbacks) {
if (callback.getName().equals(type)) {
return callback;
}
}
return null;
}

public void addResult(String string) {
result.add(string);
}

@VisibleForTesting
public List<String> getResult() {
return result;
}

@Override
public void close(boolean failFast) throws InterruptedException, IOException {
if (!failFast && printStream != null) {
result.forEach(printStream::println);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
// Copyright 2018 The Bazel Authors. All rights reserved.
//
// 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.google.devtools.build.lib.query2;

import com.google.devtools.build.lib.analysis.ConfiguredTarget;
import com.google.devtools.build.lib.analysis.config.BuildConfiguration;
import com.google.devtools.build.lib.query2.output.CqueryOptions;
import java.io.OutputStream;

/**
* Default Output callback for cquery. Prints a label and configuration pair per
* result.
*/
public class LabelAndConfigurationOutputFormatterCallback extends CqueryThreadsafeCallback {

LabelAndConfigurationOutputFormatterCallback(CqueryOptions options, OutputStream out) {
super(options, out);
}

@Override
public String getName() {
return "label";
}

@Override
public void processOutput(Iterable<ConfiguredTarget> partialResult) {
for (ConfiguredTarget configuredTarget : partialResult) {
BuildConfiguration config = configuredTarget.getConfiguration();
StringBuilder output =
new StringBuilder()
.append(configuredTarget.getLabel())
.append(" (")
.append(config != null && config.isHostConfiguration() ? "HOST" : config)
.append(")");
addResult(output.toString());
}
}
}
Loading

0 comments on commit d350a89

Please sign in to comment.