Updated `buck query` to accept aliases.
diff --git a/docs/command/query.soy b/docs/command/query.soy index 18beb0f..63cce8b 100644 --- a/docs/command/query.soy +++ b/docs/command/query.soy
@@ -16,12 +16,20 @@ This can be used to find a path from one dependency to another in the build graph. The format of the query is <code><em>source</em> -> <em>sink</em></code> as follows: -<pre>buck query "//apps/myapp:app -> //res/com/example/activity:res"</pre> +<pre>buck query '//apps/myapp:app -> //res/com/example/activity:res'</pre> It can also be used to find the set of transitive dependencies for a build rule by omitting the -sink in the query expression. +sink in the query expression: -<pre>buck query "//apps/myapp:app -> "</pre> +<pre>buck query '//apps/myapp:app -> '</pre> + +In addition to using fully-qualified build targets such as <code>//apps/myapp:app</code>, +you can also use aliases that you have declared in the <code>[alias]</code> section of +your {call buck.concept_buckconfig /} file in your query: + +<pre>buck query 'app -> //some/unexpected:dependency'</pre> + +<p> This can be useful in untangling your dependencies, or for general scripting against the build graph.
diff --git a/src/com/facebook/buck/cli/CommandLineBuildTargetNormalizer.java b/src/com/facebook/buck/cli/CommandLineBuildTargetNormalizer.java index 6b4e7d0..e6eaf0e 100644 --- a/src/com/facebook/buck/cli/CommandLineBuildTargetNormalizer.java +++ b/src/com/facebook/buck/cli/CommandLineBuildTargetNormalizer.java
@@ -76,6 +76,10 @@ }; } + public String normalize(String argument) { + return normalizer.apply(argument); + } + public List<String> normalizeAll(List<String> arguments) { // When transforming command-line arguments, first check to see whether it is an alias in the // BuckConfig. If so, return the value associated with the alias. Otherwise, try normalize().
diff --git a/src/com/facebook/buck/cli/DependencyQuery.java b/src/com/facebook/buck/cli/DependencyQuery.java index 1eb1103..49a62dd 100644 --- a/src/com/facebook/buck/cli/DependencyQuery.java +++ b/src/com/facebook/buck/cli/DependencyQuery.java
@@ -59,12 +59,9 @@ } private DependencyQuery(Optional<Integer> depth, String target, Optional<String> source) { - Preconditions.checkNotNull(depth); - Preconditions.checkNotNull(target); - Preconditions.checkNotNull(source); - this.depth = depth; - this.target = target; - this.source = source; + this.depth = Preconditions.checkNotNull(depth); + this.target = Preconditions.checkNotNull(target); + this.source = Preconditions.checkNotNull(source); } String getTarget() { @@ -98,7 +95,9 @@ * @return dependency query we constructed based on string. * @throws HumanReadableException on bad query strings. */ - static DependencyQuery parseQueryString(String queryString) throws HumanReadableException { + static DependencyQuery parseQueryString(String queryString, + CommandLineBuildTargetNormalizer commandLineBuildTargetNormalizer) + throws HumanReadableException { Matcher queryMatcher = ARROW_PATTERN.matcher(queryString); if (!queryMatcher.matches()) { throw new HumanReadableException(String.format("Invalid query string: %s.", queryString)); @@ -121,12 +120,10 @@ } String target = queryMatcher.group(1).trim(); - final String fullyQualifiedTarget = - CommandLineBuildTargetNormalizer.normalizeBuildTargetIdentifier(target); + final String fullyQualifiedTarget = commandLineBuildTargetNormalizer.normalize(target); String source = queryMatcher.group(3).trim(); - String fullyQualifiedSource = - CommandLineBuildTargetNormalizer.normalizeBuildTargetIdentifier(source); + String fullyQualifiedSource = commandLineBuildTargetNormalizer.normalize(source); if (source.isEmpty()) { return new DependencyQuery(depth, fullyQualifiedTarget);
diff --git a/src/com/facebook/buck/cli/QueryCommand.java b/src/com/facebook/buck/cli/QueryCommand.java index 94ed3b4..3e9d283 100644 --- a/src/com/facebook/buck/cli/QueryCommand.java +++ b/src/com/facebook/buck/cli/QueryCommand.java
@@ -84,7 +84,8 @@ return 1; } - DependencyQuery query = DependencyQuery.parseQueryString(options.getArguments().get(0)); + DependencyQuery query = DependencyQuery.parseQueryString(options.getArguments().get(0), + options.getCommandLineBuildTargetNormalizer()); PartialGraph graph; try {
diff --git a/test/com/facebook/buck/cli/DependencyQueryTest.java b/test/com/facebook/buck/cli/DependencyQueryTest.java new file mode 100644 index 0000000..70138c8 --- /dev/null +++ b/test/com/facebook/buck/cli/DependencyQueryTest.java
@@ -0,0 +1,47 @@ +/* + * Copyright 2013-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.cli; + +import static org.junit.Assert.assertEquals; + +import com.google.common.base.Optional; + +import org.easymock.EasyMock; +import org.junit.Test; + +public class DependencyQueryTest { + + @Test + public void testParseQueryStringResolvesBuildTargetAlias() { + BuckConfig buckConfig = EasyMock.createMock(BuckConfig.class); + EasyMock.expect(buckConfig.getBuildTargetForAlias("fb4a")) + .andReturn("//apps/fb4a:fb4a"); + EasyMock.expect(buckConfig.getBuildTargetForAlias("base")) + .andReturn("//java/com/facebook/base:base"); + EasyMock.replay(buckConfig); + + CommandLineBuildTargetNormalizer commandLineBuildTargetNormalizer = + new CommandLineBuildTargetNormalizer(buckConfig); + DependencyQuery query = DependencyQuery.parseQueryString("fb4a -> base", + commandLineBuildTargetNormalizer); + + assertEquals("//apps/fb4a:fb4a", query.getTarget()); + assertEquals(Optional.of("//java/com/facebook/base:base"), query.getSource()); + + EasyMock.verify(buckConfig); + } +}
diff --git a/test/com/facebook/buck/cli/QueryCommandTest.java b/test/com/facebook/buck/cli/QueryCommandTest.java index 8af2105..ab07277 100644 --- a/test/com/facebook/buck/cli/QueryCommandTest.java +++ b/test/com/facebook/buck/cli/QueryCommandTest.java
@@ -38,6 +38,8 @@ import com.google.common.collect.ImmutableSet; import com.google.common.collect.Lists; +import org.easymock.Capture; +import org.easymock.EasyMock; import org.junit.Before; import org.junit.Test; @@ -51,6 +53,9 @@ private PartialGraph testGraph; + private BuckConfig buckConfig; + private CommandLineBuildTargetNormalizer normalizer; + /** * Sets up the following dependency graph: * @@ -77,6 +82,18 @@ addRule(ruleResolver, "//:B", ImmutableList.of("//:D")); addRule(ruleResolver, "//:A", ImmutableList.of("//:B", "//:C")); testGraph = createGraphFromBuildRules(ruleResolver, ImmutableList.of("//:A")); + + buckConfig = EasyMock.createMock(BuckConfig.class); + EasyMock.expect(buckConfig.getBuildTargetForAlias(EasyMock.capture(new Capture<String>()))) + .andReturn(null) + .anyTimes(); + EasyMock.replay(buckConfig); + normalizer = new CommandLineBuildTargetNormalizer(buckConfig); + } + + @Before + public void tearDown() { + EasyMock.verify(buckConfig); } /** Test that the pattern we use to match query strings matches the right stuff. */ @@ -102,25 +119,25 @@ @Test public void testQueryParser() { DependencyQuery query; - query = DependencyQuery.parseQueryString("//:ased>> -4> //:>- "); + query = DependencyQuery.parseQueryString("//:ased>> -4> //:>- ", normalizer); assertEquals(4, query.getDepth().get().longValue()); assertEquals("//:ased>>", query.getTarget()); assertEquals("//:>-", query.getSource().get()); - query = DependencyQuery.parseQueryString("//:dd -*>"); + query = DependencyQuery.parseQueryString("//:dd -*>", normalizer); assertFalse(query.getDepth().isPresent()); assertEquals("//:dd", query.getTarget()); assertFalse(query.getSource().isPresent()); try { - query = DependencyQuery.parseQueryString("//:hello - > //:goodbye"); + query = DependencyQuery.parseQueryString("//:hello - > //:goodbye", normalizer); fail("Should not have parsed noncontinguous arrow"); } catch (HumanReadableException e) { assertEquals("Invalid query string: //:hello - > //:goodbye.", e.getMessage()); } try { - query = DependencyQuery.parseQueryString("-> //:goodbye"); + query = DependencyQuery.parseQueryString("-> //:goodbye", normalizer); fail("Query needs source"); } catch (HumanReadableException e) { assertEquals("Invalid query string: -> //:goodbye.", e.getMessage()); @@ -142,14 +159,14 @@ } private void testQuery(String queryString, String expectedOut) { - DependencyQuery query = DependencyQuery.parseQueryString(queryString); + DependencyQuery query = DependencyQuery.parseQueryString(queryString, normalizer); String output = queryCommand.executeQuery(testGraph, query); assertEqualsModuloLines(expectedOut, output); } private void testQueryError(String queryString, String expectedErr) { try { - DependencyQuery query = DependencyQuery.parseQueryString(queryString); + DependencyQuery query = DependencyQuery.parseQueryString(queryString, normalizer); queryCommand.executeQuery(testGraph, query); fail(String.format("Query: %s should have failed", queryString)); } catch (HumanReadableException e) {