/*
* Copyright 2014-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 static com.facebook.buck.rules.TestCellBuilder.createCellRoots;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.fail;
import com.facebook.buck.io.ProjectFilesystem;
import com.facebook.buck.jvm.java.JavaBinaryRuleBuilder;
import com.facebook.buck.jvm.java.JavaLibraryBuilder;
import com.facebook.buck.model.BuildTarget;
import com.facebook.buck.model.BuildTargetFactory;
import com.facebook.buck.model.MacroException;
import com.facebook.buck.parser.NoSuchBuildTargetException;
import com.facebook.buck.rules.BuildRule;
import com.facebook.buck.rules.BuildRuleResolver;
import com.facebook.buck.rules.DefaultTargetNodeToBuildRuleTransformer;
import com.facebook.buck.rules.SourcePathResolver;
import com.facebook.buck.rules.SourcePathRuleFinder;
import com.facebook.buck.rules.TargetGraph;
import com.facebook.buck.rules.TargetNode;
import com.facebook.buck.shell.GenruleBuilder;
import com.facebook.buck.testutil.FakeProjectFilesystem;
import com.facebook.buck.testutil.TargetGraphFactory;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSortedSet;
import java.nio.file.Path;
import java.nio.file.Paths;
import org.hamcrest.Matchers;
import org.junit.Test;
public class LocationMacroExpanderTest {
private BuildRule createSampleJavaBinaryRule(BuildRuleResolver ruleResolver)
throws NoSuchBuildTargetException {
// Create a java_binary that depends on a java_library so it is possible to create a
// java_binary rule with a classpath entry and a main class.
BuildRule javaLibrary =
JavaLibraryBuilder.createBuilder(
BuildTargetFactory.newInstance("//java/com/facebook/util:util"))
.addSrc(Paths.get("java/com/facebook/util/ManifestGenerator.java"))
.build(ruleResolver);
BuildTarget buildTarget =
BuildTargetFactory.newInstance("//java/com/facebook/util:ManifestGenerator");
return new JavaBinaryRuleBuilder(buildTarget)
.setDeps(ImmutableSortedSet.of(javaLibrary.getBuildTarget()))
.setMainClass("com.facebook.util.ManifestGenerator")
.build(ruleResolver);
}
@Test
public void testShouldWarnUsersWhenThereIsNoOutputForARuleButLocationRequested()
throws NoSuchBuildTargetException {
BuildRuleResolver resolver =
new BuildRuleResolver(TargetGraph.EMPTY, new DefaultTargetNodeToBuildRuleTransformer());
JavaLibraryBuilder.createBuilder(BuildTargetFactory.newInstance("//cheese:java"))
.build(resolver);
BuildTarget target = BuildTargetFactory.newInstance("//cheese:cake");
ProjectFilesystem filesystem = new FakeProjectFilesystem();
MacroHandler macroHandler =
new MacroHandler(ImmutableMap.of("location", new LocationMacroExpander()));
try {
macroHandler.expand(
target, createCellRoots(filesystem), resolver, "$(location //cheese:java)");
fail("Location was null. Expected HumanReadableException with helpful message.");
} catch (MacroException e) {
assertEquals(
"expanding $(location //cheese:java): //cheese:java used"
+ " in location macro does not produce output",
e.getMessage());
}
}
@Test
public void replaceLocationOfFullyQualifiedBuildTarget() throws Exception {
ProjectFilesystem filesystem = new FakeProjectFilesystem();
BuildRuleResolver ruleResolver =
new BuildRuleResolver(TargetGraph.EMPTY, new DefaultTargetNodeToBuildRuleTransformer());
SourcePathResolver pathResolver =
new SourcePathResolver(new SourcePathRuleFinder(ruleResolver));
BuildRule javaBinary = createSampleJavaBinaryRule(ruleResolver);
Path absolutePath = pathResolver.getAbsolutePath(javaBinary.getSourcePathToOutput());
String originalCmd =
String.format(
"$(location :%s) $(location %s) $OUT",
javaBinary.getBuildTarget().getShortNameAndFlavorPostfix(),
javaBinary.getBuildTarget().getFullyQualifiedName());
// Interpolate the build target in the genrule cmd string.
MacroHandler macroHandler =
new MacroHandler(ImmutableMap.of("location", new LocationMacroExpander()));
String transformedString =
macroHandler.expand(
javaBinary.getBuildTarget(), createCellRoots(filesystem), ruleResolver, originalCmd);
// Verify that the correct cmd was created.
String expectedCmd = String.format("%s %s $OUT", absolutePath, absolutePath);
assertEquals(expectedCmd, transformedString);
}
@Test
public void extractRuleKeyAppendable() throws Exception {
BuildTarget target = BuildTargetFactory.newInstance("//:rule");
String input = "//some/other:rule";
TargetNode<?, ?> node =
GenruleBuilder.newGenruleBuilder(BuildTargetFactory.newInstance(input))
.setOut("out")
.build();
BuildRuleResolver resolver =
new BuildRuleResolver(
TargetGraphFactory.newInstance(node), new DefaultTargetNodeToBuildRuleTransformer());
BuildRule rule = resolver.requireRule(node.getBuildTarget());
LocationMacroExpander macroExpander = new LocationMacroExpander();
assertThat(
macroExpander.extractRuleKeyAppendables(
target,
createCellRoots(new FakeProjectFilesystem()),
resolver,
ImmutableList.of(input)),
Matchers.equalTo(rule.getSourcePathToOutput()));
}
}