// Copyright 2015 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.actions; import static com.google.common.truth.Truth.assertThat; import static com.google.devtools.build.lib.analysis.actions.CustomCommandLine.builder; import static org.junit.Assert.fail; import com.google.common.collect.ImmutableList; import com.google.devtools.build.lib.actions.Artifact.SpecialArtifact; import com.google.devtools.build.lib.actions.Artifact.SpecialArtifactType; import com.google.devtools.build.lib.actions.Artifact.TreeFileArtifact; import com.google.devtools.build.lib.analysis.actions.CustomCommandLine; import com.google.devtools.build.lib.analysis.actions.CustomCommandLine.CustomMultiArgv; import com.google.devtools.build.lib.analysis.actions.CustomCommandLine.VectorArg; import com.google.devtools.build.lib.cmdline.Label; import com.google.devtools.build.lib.collect.nestedset.NestedSet; import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder; import com.google.devtools.build.lib.collect.nestedset.Order; import com.google.devtools.build.lib.testutil.Scratch; import com.google.devtools.build.lib.util.LazyString; import com.google.devtools.build.lib.vfs.PathFragment; import java.util.Arrays; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; /** * Tests for CustomCommandLine. */ @RunWith(JUnit4.class) public class CustomCommandLineTest { private Scratch scratch; private Root rootDir; private Artifact artifact1; private Artifact artifact2; @Before public void createArtifacts() throws Exception { scratch = new Scratch(); rootDir = Root.asDerivedRoot(scratch.dir("/exec/root")); artifact1 = new Artifact(scratch.file("/exec/root/dir/file1.txt"), rootDir); artifact2 = new Artifact(scratch.file("/exec/root/dir/file2.txt"), rootDir); } @Test public void testScalarAdds() throws Exception { assertThat(builder().add("--arg").build().arguments()).containsExactly("--arg").inOrder(); assertThat(builder().addDynamicString("--arg").build().arguments()) .containsExactly("--arg") .inOrder(); assertThat(builder().addLabel(Label.parseAbsolute("//a:b")).build().arguments()) .containsExactly("//a:b") .inOrder(); assertThat(builder().addPath(PathFragment.create("path")).build().arguments()) .containsExactly("path") .inOrder(); assertThat(builder().addExecPath(artifact1).build().arguments()) .containsExactly("dir/file1.txt") .inOrder(); assertThat( builder() .addLazyString( new LazyString() { @Override public String toString() { return "foo"; } }) .build() .arguments()) .containsExactly("foo") .inOrder(); assertThat(builder().add("--arg", "val").build().arguments()) .containsExactly("--arg", "val") .inOrder(); assertThat(builder().addLabel("--arg", Label.parseAbsolute("//a:b")).build().arguments()) .containsExactly("--arg", "//a:b") .inOrder(); assertThat(builder().addPath("--arg", PathFragment.create("path")).build().arguments()) .containsExactly("--arg", "path") .inOrder(); assertThat(builder().addExecPath("--arg", artifact1).build().arguments()) .containsExactly("--arg", "dir/file1.txt") .inOrder(); assertThat( builder() .addLazyString( "--arg", new LazyString() { @Override public String toString() { return "foo"; } }) .build() .arguments()) .containsExactly("--arg", "foo") .inOrder(); } @Test public void testAddFormatted() throws Exception { assertThat(builder().addFormatted("%s%s", "hello", "world").build().arguments()) .containsExactly("helloworld") .inOrder(); } @Test public void testAddPrefixed() throws Exception { assertThat(builder().addPrefixed("prefix-", "foo").build().arguments()) .containsExactly("prefix-foo") .inOrder(); assertThat( builder().addPrefixedLabel("prefix-", Label.parseAbsolute("//a:b")).build().arguments()) .containsExactly("prefix-//a:b") .inOrder(); assertThat( builder().addPrefixedPath("prefix-", PathFragment.create("path")).build().arguments()) .containsExactly("prefix-path") .inOrder(); assertThat(builder().addPrefixedExecPath("prefix-", artifact1).build().arguments()) .containsExactly("prefix-dir/file1.txt") .inOrder(); } @Test public void testVectorAdds() throws Exception { assertThat(builder().addAll(list("val1", "val2")).build().arguments()) .containsExactly("val1", "val2") .inOrder(); assertThat(builder().addAll(nestedSet("val1", "val2")).build().arguments()) .containsExactly("val1", "val2") .inOrder(); assertThat( builder() .addPaths(list(PathFragment.create("path1"), PathFragment.create("path2"))) .build() .arguments()) .containsExactly("path1", "path2") .inOrder(); assertThat( builder() .addPaths(nestedSet(PathFragment.create("path1"), PathFragment.create("path2"))) .build() .arguments()) .containsExactly("path1", "path2") .inOrder(); assertThat(builder().addExecPaths(list(artifact1, artifact2)).build().arguments()) .containsExactly("dir/file1.txt", "dir/file2.txt") .inOrder(); assertThat(builder().addExecPaths(nestedSet(artifact1, artifact2)).build().arguments()) .containsExactly("dir/file1.txt", "dir/file2.txt") .inOrder(); assertThat( builder() .addAll(VectorArg.of(list(foo("1"), foo("2"))).mapped(Foo::str)) .build() .arguments()) .containsExactly("1", "2") .inOrder(); assertThat( builder() .addAll(VectorArg.of(nestedSet(foo("1"), foo("2"))).mapped(Foo::str)) .build() .arguments()) .containsExactly("1", "2") .inOrder(); assertThat(builder().addAll("--arg", list("val1", "val2")).build().arguments()) .containsExactly("--arg", "val1", "val2") .inOrder(); assertThat(builder().addAll("--arg", nestedSet("val1", "val2")).build().arguments()) .containsExactly("--arg", "val1", "val2") .inOrder(); assertThat( builder() .addPaths("--arg", list(PathFragment.create("path1"), PathFragment.create("path2"))) .build() .arguments()) .containsExactly("--arg", "path1", "path2") .inOrder(); assertThat( builder() .addPaths( "--arg", nestedSet(PathFragment.create("path1"), PathFragment.create("path2"))) .build() .arguments()) .containsExactly("--arg", "path1", "path2") .inOrder(); assertThat(builder().addExecPaths("--arg", list(artifact1, artifact2)).build().arguments()) .containsExactly("--arg", "dir/file1.txt", "dir/file2.txt") .inOrder(); assertThat(builder().addExecPaths("--arg", nestedSet(artifact1, artifact2)).build().arguments()) .containsExactly("--arg", "dir/file1.txt", "dir/file2.txt") .inOrder(); assertThat( builder() .addAll("--arg", VectorArg.of(list(foo("1"), foo("2"))).mapped(Foo::str)) .build() .arguments()) .containsExactly("--arg", "1", "2") .inOrder(); assertThat( builder() .addAll("--arg", VectorArg.of(nestedSet(foo("1"), foo("2"))).mapped(Foo::str)) .build() .arguments()) .containsExactly("--arg", "1", "2") .inOrder(); } @Test public void testAddJoined() throws Exception { assertThat(builder().addAll(VectorArg.join(":").each(list("val1", "val2"))).build().arguments()) .containsExactly("val1:val2") .inOrder(); assertThat( builder() .addAll(VectorArg.join(":").each(nestedSet("val1", "val2"))) .build() .arguments()) .containsExactly("val1:val2") .inOrder(); assertThat( builder() .addPaths( VectorArg.join(":") .each(list(PathFragment.create("path1"), PathFragment.create("path2")))) .build() .arguments()) .containsExactly("path1:path2") .inOrder(); assertThat( builder() .addPaths( VectorArg.join(":") .each( nestedSet(PathFragment.create("path1"), PathFragment.create("path2")))) .build() .arguments()) .containsExactly("path1:path2") .inOrder(); assertThat( builder() .addExecPaths(VectorArg.join(":").each(list(artifact1, artifact2))) .build() .arguments()) .containsExactly("dir/file1.txt:dir/file2.txt") .inOrder(); assertThat( builder() .addExecPaths(VectorArg.join(":").each(nestedSet(artifact1, artifact2))) .build() .arguments()) .containsExactly("dir/file1.txt:dir/file2.txt") .inOrder(); assertThat( builder() .addAll(VectorArg.join(":").each(list(foo("1"), foo("2"))).mapped(Foo::str)) .build() .arguments()) .containsExactly("1:2") .inOrder(); assertThat( builder() .addAll(VectorArg.join(":").each(nestedSet(foo("1"), foo("2"))).mapped(Foo::str)) .build() .arguments()) .containsExactly("1:2") .inOrder(); assertThat( builder() .addAll("--arg", VectorArg.join(":").each(list("val1", "val2"))) .build() .arguments()) .containsExactly("--arg", "val1:val2") .inOrder(); assertThat( builder() .addAll("--arg", VectorArg.join(":").each(nestedSet("val1", "val2"))) .build() .arguments()) .containsExactly("--arg", "val1:val2") .inOrder(); assertThat( builder() .addPaths( "--arg", VectorArg.join(":") .each(list(PathFragment.create("path1"), PathFragment.create("path2")))) .build() .arguments()) .containsExactly("--arg", "path1:path2") .inOrder(); assertThat( builder() .addPaths( "--arg", VectorArg.join(":") .each( nestedSet(PathFragment.create("path1"), PathFragment.create("path2")))) .build() .arguments()) .containsExactly("--arg", "path1:path2") .inOrder(); assertThat( builder() .addExecPaths("--arg", VectorArg.join(":").each(list(artifact1, artifact2))) .build() .arguments()) .containsExactly("--arg", "dir/file1.txt:dir/file2.txt") .inOrder(); assertThat( builder() .addExecPaths("--arg", VectorArg.join(":").each(nestedSet(artifact1, artifact2))) .build() .arguments()) .containsExactly("--arg", "dir/file1.txt:dir/file2.txt") .inOrder(); assertThat( builder() .addAll( "--arg", VectorArg.join(":").each(list(foo("1"), foo("2"))).mapped(Foo::str)) .build() .arguments()) .containsExactly("--arg", "1:2") .inOrder(); assertThat( builder() .addAll( "--arg", VectorArg.join(":").each(nestedSet(foo("1"), foo("2"))).mapped(Foo::str)) .build() .arguments()) .containsExactly("--arg", "1:2") .inOrder(); } @Test public void testAddFormatEach() throws Exception { assertThat( builder() .addAll(VectorArg.format("-D%s").each(list("val1", "val2"))) .build() .arguments()) .containsExactly("-Dval1", "-Dval2") .inOrder(); assertThat( builder() .addAll(VectorArg.format("-D%s").each(nestedSet("val1", "val2"))) .build() .arguments()) .containsExactly("-Dval1", "-Dval2") .inOrder(); assertThat( builder() .addPaths( VectorArg.format("-D%s") .each(list(PathFragment.create("path1"), PathFragment.create("path2")))) .build() .arguments()) .containsExactly("-Dpath1", "-Dpath2") .inOrder(); assertThat( builder() .addPaths( VectorArg.format("-D%s") .each( nestedSet(PathFragment.create("path1"), PathFragment.create("path2")))) .build() .arguments()) .containsExactly("-Dpath1", "-Dpath2") .inOrder(); assertThat( builder() .addExecPaths(VectorArg.format("-D%s").each(list(artifact1, artifact2))) .build() .arguments()) .containsExactly("-Ddir/file1.txt", "-Ddir/file2.txt") .inOrder(); assertThat( builder() .addExecPaths(VectorArg.format("-D%s").each(nestedSet(artifact1, artifact2))) .build() .arguments()) .containsExactly("-Ddir/file1.txt", "-Ddir/file2.txt") .inOrder(); assertThat( builder() .addAll(VectorArg.format("-D%s").each(list(foo("1"), foo("2"))).mapped(Foo::str)) .build() .arguments()) .containsExactly("-D1", "-D2") .inOrder(); assertThat( builder() .addAll( VectorArg.format("-D%s").each(nestedSet(foo("1"), foo("2"))).mapped(Foo::str)) .build() .arguments()) .containsExactly("-D1", "-D2") .inOrder(); assertThat( builder() .addAll("--arg", VectorArg.format("-D%s").each(list("val1", "val2"))) .build() .arguments()) .containsExactly("--arg", "-Dval1", "-Dval2") .inOrder(); assertThat( builder() .addAll("--arg", VectorArg.format("-D%s").each(nestedSet("val1", "val2"))) .build() .arguments()) .containsExactly("--arg", "-Dval1", "-Dval2") .inOrder(); assertThat( builder() .addPaths( "--arg", VectorArg.format("-D%s") .each(list(PathFragment.create("path1"), PathFragment.create("path2")))) .build() .arguments()) .containsExactly("--arg", "-Dpath1", "-Dpath2") .inOrder(); assertThat( builder() .addPaths( "--arg", VectorArg.format("-D%s") .each( nestedSet(PathFragment.create("path1"), PathFragment.create("path2")))) .build() .arguments()) .containsExactly("--arg", "-Dpath1", "-Dpath2") .inOrder(); assertThat( builder() .addExecPaths("--arg", VectorArg.format("-D%s").each(list(artifact1, artifact2))) .build() .arguments()) .containsExactly("--arg", "-Ddir/file1.txt", "-Ddir/file2.txt") .inOrder(); assertThat( builder() .addExecPaths( "--arg", VectorArg.format("-D%s").each(nestedSet(artifact1, artifact2))) .build() .arguments()) .containsExactly("--arg", "-Ddir/file1.txt", "-Ddir/file2.txt") .inOrder(); assertThat( builder() .addAll( "--arg", VectorArg.format("-D%s").each(list(foo("1"), foo("2"))).mapped(Foo::str)) .build() .arguments()) .containsExactly("--arg", "-D1", "-D2") .inOrder(); assertThat( builder() .addAll( "--arg", VectorArg.format("-D%s").each(nestedSet(foo("1"), foo("2"))).mapped(Foo::str)) .build() .arguments()) .containsExactly("--arg", "-D1", "-D2") .inOrder(); } @Test public void testAddFormatEachJoined() throws Exception { assertThat( builder() .addAll(VectorArg.format("-D%s").join(":").each(list("val1", "val2"))) .build() .arguments()) .containsExactly("-Dval1:-Dval2") .inOrder(); assertThat( builder() .addAll(VectorArg.format("-D%s").join(":").each(nestedSet("val1", "val2"))) .build() .arguments()) .containsExactly("-Dval1:-Dval2") .inOrder(); assertThat( builder() .addPaths( VectorArg.format("-D%s") .join(":") .each(list(PathFragment.create("path1"), PathFragment.create("path2")))) .build() .arguments()) .containsExactly("-Dpath1:-Dpath2") .inOrder(); assertThat( builder() .addPaths( VectorArg.format("-D%s") .join(":") .each( nestedSet(PathFragment.create("path1"), PathFragment.create("path2")))) .build() .arguments()) .containsExactly("-Dpath1:-Dpath2") .inOrder(); assertThat( builder() .addExecPaths(VectorArg.format("-D%s").join(":").each(list(artifact1, artifact2))) .build() .arguments()) .containsExactly("-Ddir/file1.txt:-Ddir/file2.txt") .inOrder(); assertThat( builder() .addExecPaths( VectorArg.format("-D%s").join(":").each(nestedSet(artifact1, artifact2))) .build() .arguments()) .containsExactly("-Ddir/file1.txt:-Ddir/file2.txt") .inOrder(); assertThat( builder() .addAll( VectorArg.format("-D%s") .join(":") .each(list(foo("1"), foo("2"))) .mapped(Foo::str)) .build() .arguments()) .containsExactly("-D1:-D2") .inOrder(); assertThat( builder() .addAll( VectorArg.format("-D%s") .join(":") .each(nestedSet(foo("1"), foo("2"))) .mapped(Foo::str)) .build() .arguments()) .containsExactly("-D1:-D2") .inOrder(); assertThat( builder() .addAll("--arg", VectorArg.format("-D%s").join(":").each(list("val1", "val2"))) .build() .arguments()) .containsExactly("--arg", "-Dval1:-Dval2") .inOrder(); assertThat( builder() .addAll("--arg", VectorArg.format("-D%s").join(":").each(nestedSet("val1", "val2"))) .build() .arguments()) .containsExactly("--arg", "-Dval1:-Dval2") .inOrder(); assertThat( builder() .addPaths( "--arg", VectorArg.format("-D%s") .join(":") .each(list(PathFragment.create("path1"), PathFragment.create("path2")))) .build() .arguments()) .containsExactly("--arg", "-Dpath1:-Dpath2") .inOrder(); assertThat( builder() .addPaths( "--arg", VectorArg.format("-D%s") .join(":") .each( nestedSet(PathFragment.create("path1"), PathFragment.create("path2")))) .build() .arguments()) .containsExactly("--arg", "-Dpath1:-Dpath2") .inOrder(); assertThat( builder() .addExecPaths( "--arg", VectorArg.format("-D%s").join(":").each(list(artifact1, artifact2))) .build() .arguments()) .containsExactly("--arg", "-Ddir/file1.txt:-Ddir/file2.txt") .inOrder(); assertThat( builder() .addExecPaths( "--arg", VectorArg.format("-D%s").join(":").each(nestedSet(artifact1, artifact2))) .build() .arguments()) .containsExactly("--arg", "-Ddir/file1.txt:-Ddir/file2.txt") .inOrder(); assertThat( builder() .addAll( "--arg", VectorArg.format("-D%s") .join(":") .each(list(foo("1"), foo("2"))) .mapped(Foo::str)) .build() .arguments()) .containsExactly("--arg", "-D1:-D2") .inOrder(); assertThat( builder() .addAll( "--arg", VectorArg.format("-D%s") .join(":") .each(nestedSet(foo("1"), foo("2"))) .mapped(Foo::str)) .build() .arguments()) .containsExactly("--arg", "-D1:-D2") .inOrder(); } @Test public void testAddBeforeEach() throws Exception { assertThat( builder() .addAll(VectorArg.addBefore("-D").each(list("val1", "val2"))) .build() .arguments()) .containsExactly("-D", "val1", "-D", "val2") .inOrder(); assertThat( builder() .addAll(VectorArg.addBefore("-D").each(nestedSet("val1", "val2"))) .build() .arguments()) .containsExactly("-D", "val1", "-D", "val2") .inOrder(); assertThat( builder() .addPaths( VectorArg.addBefore("-D") .each(list(PathFragment.create("path1"), PathFragment.create("path2")))) .build() .arguments()) .containsExactly("-D", "path1", "-D", "path2") .inOrder(); assertThat( builder() .addPaths( VectorArg.addBefore("-D") .each( nestedSet(PathFragment.create("path1"), PathFragment.create("path2")))) .build() .arguments()) .containsExactly("-D", "path1", "-D", "path2") .inOrder(); assertThat( builder() .addExecPaths(VectorArg.addBefore("-D").each(list(artifact1, artifact2))) .build() .arguments()) .containsExactly("-D", "dir/file1.txt", "-D", "dir/file2.txt") .inOrder(); assertThat( builder() .addExecPaths(VectorArg.addBefore("-D").each(nestedSet(artifact1, artifact2))) .build() .arguments()) .containsExactly("-D", "dir/file1.txt", "-D", "dir/file2.txt") .inOrder(); assertThat( builder() .addAll(VectorArg.addBefore("-D").each(list(foo("1"), foo("2"))).mapped(Foo::str)) .build() .arguments()) .containsExactly("-D", "1", "-D", "2") .inOrder(); assertThat( builder() .addAll( VectorArg.addBefore("-D").each(nestedSet(foo("1"), foo("2"))).mapped(Foo::str)) .build() .arguments()) .containsExactly("-D", "1", "-D", "2") .inOrder(); } @Test public void testAddBeforeEachFormatted() throws Exception { assertThat( builder() .addAll(VectorArg.addBefore("-D").format("D%s").each(list("val1", "val2"))) .build() .arguments()) .containsExactly("-D", "Dval1", "-D", "Dval2") .inOrder(); assertThat( builder() .addAll(VectorArg.addBefore("-D").format("D%s").each(nestedSet("val1", "val2"))) .build() .arguments()) .containsExactly("-D", "Dval1", "-D", "Dval2") .inOrder(); assertThat( builder() .addPaths( VectorArg.addBefore("-D") .format("D%s") .each(list(PathFragment.create("path1"), PathFragment.create("path2")))) .build() .arguments()) .containsExactly("-D", "Dpath1", "-D", "Dpath2") .inOrder(); assertThat( builder() .addPaths( VectorArg.addBefore("-D") .format("D%s") .each( nestedSet(PathFragment.create("path1"), PathFragment.create("path2")))) .build() .arguments()) .containsExactly("-D", "Dpath1", "-D", "Dpath2") .inOrder(); assertThat( builder() .addExecPaths( VectorArg.addBefore("-D").format("D%s").each(list(artifact1, artifact2))) .build() .arguments()) .containsExactly("-D", "Ddir/file1.txt", "-D", "Ddir/file2.txt") .inOrder(); assertThat( builder() .addExecPaths( VectorArg.addBefore("-D").format("D%s").each(nestedSet(artifact1, artifact2))) .build() .arguments()) .containsExactly("-D", "Ddir/file1.txt", "-D", "Ddir/file2.txt") .inOrder(); assertThat( builder() .addAll( VectorArg.addBefore("-D") .format("D%s") .each(list(foo("1"), foo("2"))) .mapped(Foo::str)) .build() .arguments()) .containsExactly("-D", "D1", "-D", "D2") .inOrder(); assertThat( builder() .addAll( VectorArg.addBefore("-D") .format("D%s") .each(nestedSet(foo("1"), foo("2"))) .mapped(Foo::str)) .build() .arguments()) .containsExactly("-D", "D1", "-D", "D2") .inOrder(); } @Test public void testCustomMultiArgs() { CustomCommandLine cl = builder() .addCustomMultiArgv( new CustomMultiArgv() { @Override public ImmutableList argv() { return ImmutableList.of("--arg1", "--arg2"); } }) .build(); assertThat(cl.arguments()).containsExactly("--arg1", "--arg2").inOrder(); } @Test public void testCombinedArgs() { CustomCommandLine cl = builder() .add("--arg") .addAll("--args", ImmutableList.of("abc")) .addExecPaths("--path1", ImmutableList.of(artifact1)) .addExecPath("--path2", artifact2) .build(); assertThat(cl.arguments()) .containsExactly( "--arg", "--args", "abc", "--path1", "dir/file1.txt", "--path2", "dir/file2.txt") .inOrder(); } @Test public void testAddNulls() throws Exception { Artifact treeArtifact = createTreeArtifact("myTreeArtifact"); assertThat(treeArtifact).isNotNull(); CustomCommandLine cl = builder() .addDynamicString(null) .addLabel(null) .addPath(null) .addExecPath(null) .addLazyString(null) .add("foo", null) .addLabel("foo", null) .addPath("foo", null) .addExecPath("foo", null) .addLazyString("foo", null) .addPrefixed("prefix", null) .addPrefixedLabel("prefix", null) .addPrefixedPath("prefix", null) .addPrefixedExecPath("prefix", null) .addAll((ImmutableList) null) .addAll(ImmutableList.of()) .addPaths((ImmutableList) null) .addPaths(ImmutableList.of()) .addExecPaths((ImmutableList) null) .addExecPaths(ImmutableList.of()) .addAll((NestedSet) null) .addAll(NestedSetBuilder.emptySet(Order.STABLE_ORDER)) .addPaths((NestedSet) null) .addPaths(NestedSetBuilder.emptySet(Order.STABLE_ORDER)) .addExecPaths((NestedSet) null) .addExecPaths(NestedSetBuilder.emptySet(Order.STABLE_ORDER)) .addAll(VectorArg.of((NestedSet) null)) .addAll(VectorArg.of(NestedSetBuilder.emptySet(Order.STABLE_ORDER))) .addAll("foo", (ImmutableList) null) .addAll("foo", ImmutableList.of()) .addPaths("foo", (ImmutableList) null) .addPaths("foo", ImmutableList.of()) .addExecPaths("foo", (ImmutableList) null) .addExecPaths("foo", ImmutableList.of()) .addAll("foo", (NestedSet) null) .addAll("foo", NestedSetBuilder.emptySet(Order.STABLE_ORDER)) .addPaths("foo", (NestedSet) null) .addPaths("foo", NestedSetBuilder.emptySet(Order.STABLE_ORDER)) .addExecPaths("foo", (NestedSet) null) .addExecPaths("foo", NestedSetBuilder.emptySet(Order.STABLE_ORDER)) .addAll("foo", VectorArg.of((NestedSet) null)) .addAll("foo", VectorArg.of(NestedSetBuilder.emptySet(Order.STABLE_ORDER))) .addCustomMultiArgv(null) .addPlaceholderTreeArtifactExecPath("foo", null) .build(); assertThat(cl.arguments()).isEmpty(); } @Test public void testTreeFileArtifactExecPathArgs() { Artifact treeArtifactOne = createTreeArtifact("myArtifact/treeArtifact1"); Artifact treeArtifactTwo = createTreeArtifact("myArtifact/treeArtifact2"); CustomCommandLine commandLineTemplate = builder() .addPlaceholderTreeArtifactExecPath("--argOne", treeArtifactOne) .addPlaceholderTreeArtifactExecPath("--argTwo", treeArtifactTwo) .build(); TreeFileArtifact treeFileArtifactOne = createTreeFileArtifact( treeArtifactOne, "children/child1"); TreeFileArtifact treeFileArtifactTwo = createTreeFileArtifact( treeArtifactTwo, "children/child2"); CustomCommandLine commandLine = commandLineTemplate.evaluateTreeFileArtifacts( ImmutableList.of(treeFileArtifactOne, treeFileArtifactTwo)); assertThat(commandLine.arguments()) .containsExactly( "--argOne", "myArtifact/treeArtifact1/children/child1", "--argTwo", "myArtifact/treeArtifact2/children/child2") .inOrder(); } @Test public void testTreeFileArtifactArgThrowWithoutSubstitution() { Artifact treeArtifactOne = createTreeArtifact("myArtifact/treeArtifact1"); Artifact treeArtifactTwo = createTreeArtifact("myArtifact/treeArtifact2"); CustomCommandLine commandLineTemplate = builder() .addPlaceholderTreeArtifactExecPath("--argOne", treeArtifactOne) .addPlaceholderTreeArtifactExecPath("--argTwo", treeArtifactTwo) .build(); try { commandLineTemplate.arguments(); fail("No substitution map provided, expected NullPointerException"); } catch (NullPointerException e) { // expected } } private Artifact createTreeArtifact(String rootRelativePath) { PathFragment relpath = PathFragment.create(rootRelativePath); return new SpecialArtifact( rootDir.getPath().getRelative(relpath), rootDir, rootDir.getExecPath().getRelative(relpath), ArtifactOwner.NULL_OWNER, SpecialArtifactType.TREE); } private TreeFileArtifact createTreeFileArtifact( Artifact inputTreeArtifact, String parentRelativePath) { return ActionInputHelper.treeFileArtifact( inputTreeArtifact, PathFragment.create(parentRelativePath)); } private static ImmutableList list(T... objects) { return ImmutableList.builder().addAll(Arrays.asList(objects)).build(); } private static NestedSet nestedSet(T... objects) { return NestedSetBuilder.stableOrder().addAll(Arrays.asList(objects)).build(); } private static Foo foo(String str) { return new Foo(str); } private static class Foo { private final String str; Foo(String str) { this.str = str; } static String str(Foo foo) { return foo.str; } } }