Skip to content

Commit

Permalink
Optionally output source files with cquery --output=files
Browse files Browse the repository at this point in the history
RELNOTES: `cquery --output=files` can be configured to additionally
output source files with the new `--files:include_source_files` flag.
  • Loading branch information
fmeum committed Oct 28, 2022
1 parent 55f4f48 commit ddf37f3
Show file tree
Hide file tree
Showing 5 changed files with 73 additions and 8 deletions.
3 changes: 2 additions & 1 deletion site/en/query/cquery.md
Expand Up @@ -368,7 +368,8 @@ by the query similar to the list printed at the end of a `bazel build`
invocation. The output contains only the files advertised in the requested
output groups as determined by the
[`--output_groups`](/reference/command-line-reference#flag--output_groups) flag
and never contains source files.
and does not contain source files unless `--files:include_source_files` is
specified.

Note: The output of `bazel cquery --output=files //pkg:foo` contains the output
files of `//pkg:foo` in *all* configurations that occur in the build (also see
Expand Down
Expand Up @@ -107,4 +107,12 @@ public enum Transitions {
+ " error to specify both --starlark:expr and --starlark:file. See help for"
+ " --output=starlark for additional detail.")
public String file;

@Option(
name = "files:include_source_files",
defaultValue = "false",
documentationCategory = OptionDocumentationCategory.QUERY,
effectTags = {OptionEffectTag.TERMINAL_OUTPUT},
help = "If true, source files are included in the output of cquery with --output=files.")
public boolean includeSourceFiles;
}
Expand Up @@ -17,6 +17,7 @@
import com.google.devtools.build.lib.analysis.ConfiguredTarget;
import com.google.devtools.build.lib.analysis.TopLevelArtifactContext;
import com.google.devtools.build.lib.analysis.TopLevelArtifactHelper;
import com.google.devtools.build.lib.analysis.configuredtargets.InputFileConfiguredTarget;
import com.google.devtools.build.lib.events.ExtendedEventHandler;
import com.google.devtools.build.lib.query2.engine.QueryEnvironment.TargetAccessor;
import com.google.devtools.build.lib.skyframe.SkyframeExecutor;
Expand Down Expand Up @@ -53,14 +54,16 @@ public void processOutput(Iterable<KeyedConfiguredTarget> partialResult)
throws IOException, InterruptedException {
for (KeyedConfiguredTarget keyedTarget : partialResult) {
ConfiguredTarget target = keyedTarget.getConfiguredTarget();
if (!TopLevelArtifactHelper.shouldConsiderForDisplay(target)) {
if (!TopLevelArtifactHelper.shouldConsiderForDisplay(target) && !(options.includeSourceFiles
&& target instanceof InputFileConfiguredTarget)) {
continue;
}
TopLevelArtifactHelper.getAllArtifactsToBuild(target, topLevelArtifactContext)
.getImportantArtifacts()
.toList()
.stream()
.filter(TopLevelArtifactHelper::shouldDisplay)
.filter(artifact -> TopLevelArtifactHelper.shouldDisplay(artifact) || (
artifact.isSourceArtifact() && options.includeSourceFiles))
.map(Artifact::getExecPathString)
.forEach(this::addResult);
}
Expand Down
Expand Up @@ -33,6 +33,7 @@
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import org.junit.Before;
import org.junit.Test;

Expand Down Expand Up @@ -71,7 +72,7 @@ public final void defineSimpleRule() throws Exception {
" runfiles = ctx.runfiles([runfile]),",
" ),",
" OutputGroupInfo(",
" foobar = [output_group_only],",
" foobar = [output_group_only, ctx.file.explicit_source_dep],",
" ),",
" ]",
"r = rule(",
Expand Down Expand Up @@ -105,14 +106,16 @@ public final void setUpCqueryOptions() {
this.reporter = new Reporter(new EventBus(), events::add);
}

private List<String> getOutput(String queryExpression, List<String> outputGroups)
private List<String> getOutput(String queryExpression, List<String> outputGroups,
boolean includeSourceFiles)
throws Exception {
QueryExpression expression = QueryParser.parse(queryExpression, getDefaultFunctions());
Set<String> targetPatternSet = new LinkedHashSet<>();
expression.collectTargetPatterns(targetPatternSet);
PostAnalysisQueryEnvironment<KeyedConfiguredTarget> env =
((ConfiguredTargetQueryHelper) helper).getPostAnalysisQueryEnvironment(targetPatternSet);

options.includeSourceFiles = includeSourceFiles;
ByteArrayOutputStream output = new ByteArrayOutputStream();
FilesOutputFormatterCallback callback =
new FilesOutputFormatterCallback(
Expand All @@ -133,24 +136,54 @@ private List<String> getOutput(String queryExpression, List<String> outputGroups

@Test
public void basicQuery_defaultOutputGroup() throws Exception {
List<String> output = getOutput("//pkg:all", ImmutableList.of());
List<String> output = getOutput("//pkg:all", ImmutableList.of(), false);
assertContainsExactlyWithBinDirPrefix(
output, "pkg/main_default_file", "pkg/other_default_file");
}

@Test
public void basicQuery_defaultOutputGroup_includeSourceFiles() throws Exception {
List<String> output = getOutput("//pkg:all", ImmutableList.of(), true);
var sourceAndGeneratedFiles = output.stream()
.collect(Collectors.<String>partitioningBy(path -> path.startsWith("bazel-out/")));
assertThat(sourceAndGeneratedFiles.get(false)).containsExactly("pkg/BUILD", "defs/rules.bzl");
assertContainsExactlyWithBinDirPrefix(sourceAndGeneratedFiles.get(true),
"pkg/main_default_file", "pkg/other_default_file");
}

@Test
public void basicQuery_defaultAndCustomOutputGroup() throws Exception {
List<String> output = getOutput("//pkg:main", ImmutableList.of("+foobar"));
List<String> output = getOutput("//pkg:main", ImmutableList.of("+foobar"), false);
assertContainsExactlyWithBinDirPrefix(
output, "pkg/main_default_file", "pkg/main_output_group_only");
}

@Test
public void basicQuery_defaultAndCustomOutputGroup_includeSourceFiles() throws Exception {
List<String> output = getOutput("//pkg:main", ImmutableList.of("+foobar"), true);
var sourceAndGeneratedFiles = output.stream()
.collect(Collectors.<String>partitioningBy(path -> path.startsWith("bazel-out/")));
assertThat(sourceAndGeneratedFiles.get(false)).containsExactly("pkg/BUILD", "defs/rules.bzl");
assertContainsExactlyWithBinDirPrefix(
sourceAndGeneratedFiles.get(true), "pkg/main_default_file", "pkg/main_output_group_only");
}

@Test
public void basicQuery_customOutputGroupOnly() throws Exception {
List<String> output = getOutput("//pkg:other", ImmutableList.of("foobar"));
List<String> output = getOutput("//pkg:other", ImmutableList.of("foobar"), false);
assertContainsExactlyWithBinDirPrefix(output, "pkg/other_output_group_only");
}

@Test
public void basicQuery_customOutputGroupOnly_includeSourceFiles() throws Exception {
List<String> output = getOutput("//pkg:other", ImmutableList.of("foobar"), true);
var sourceAndGeneratedFiles = output.stream()
.collect(Collectors.<String>partitioningBy(path -> path.startsWith("bazel-out/")));
assertThat(sourceAndGeneratedFiles.get(false)).containsExactly("pkg/BUILD");
assertContainsExactlyWithBinDirPrefix(sourceAndGeneratedFiles.get(true),
"pkg/other_output_group_only");
}

private void assertContainsExactlyWithBinDirPrefix(
List<String> output, String... binDirRelativePaths) {
if (binDirRelativePaths.length == 0) {
Expand Down
20 changes: 20 additions & 0 deletions src/test/shell/integration/configured_query_test.sh
Expand Up @@ -1430,4 +1430,24 @@ EOF
expect_not_log "QueryException"
}

function test_files_include_source_files() {
local -r pkg=$FUNCNAME
mkdir -p $pkg
cat > $pkg/BUILD <<'EOF'
filegroup(name="files", srcs=["BUILD"])
alias(name="alias", actual="single_file")
EOF
touch $pkg/single_file

bazel cquery --output=files //$pkg:all \
> output 2>"$TEST_log" || fail "Unexpected failure"
assert_not_contains "$pkg/BUILD" output
assert_not_contains "$pkg/single_file" output

bazel cquery --output=files --files:include_source_files //$pkg:all \
> output 2>"$TEST_log" || fail "Unexpected failure"
assert_contains "$pkg/BUILD" output
assert_contains "$pkg/single_file" output
}

run_suite "${PRODUCT_NAME} configured query tests"

0 comments on commit ddf37f3

Please sign in to comment.