| // 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 com.google.devtools.build.lib.testutil.MoreAsserts.assertThrows; |
| import static org.junit.Assert.fail; |
| |
| import com.google.common.base.Joiner; |
| import com.google.common.collect.ImmutableList; |
| import com.google.common.collect.ImmutableMap; |
| 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.actions.util.ActionsTestUtil; |
| import com.google.devtools.build.lib.analysis.actions.CustomCommandLine; |
| 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.Fingerprint; |
| import com.google.devtools.build.lib.util.LazyString; |
| import com.google.devtools.build.lib.vfs.PathFragment; |
| import java.util.Arrays; |
| import java.util.HashMap; |
| import java.util.Map; |
| import java.util.function.Consumer; |
| 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 ArtifactRoot rootDir; |
| private Artifact artifact1; |
| private Artifact artifact2; |
| |
| @Before |
| public void createArtifacts() throws Exception { |
| scratch = new Scratch(); |
| rootDir = ArtifactRoot.asDerivedRoot(scratch.dir("/exec/root"), scratch.dir("/exec/root/dir")); |
| artifact1 = ActionsTestUtil.createArtifact(rootDir, scratch.file("/exec/root/dir/file1.txt")); |
| artifact2 = ActionsTestUtil.createArtifact(rootDir, scratch.file("/exec/root/dir/file2.txt")); |
| } |
| |
| @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", ImmutableMap.of())).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", ImmutableMap.of())) |
| .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", ImmutableMap.of())) |
| .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::expandToStr)) |
| .build() |
| .arguments()) |
| .containsExactly("1", "2") |
| .inOrder(); |
| assertThat( |
| builder() |
| .addAll(VectorArg.of(nestedSet(foo("1"), foo("2"))).mapped(Foo::expandToStr)) |
| .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::expandToStr)) |
| .build() |
| .arguments()) |
| .containsExactly("--arg", "1", "2") |
| .inOrder(); |
| assertThat( |
| builder() |
| .addAll( |
| "--arg", VectorArg.of(nestedSet(foo("1"), foo("2"))).mapped(Foo::expandToStr)) |
| .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::expandToStr)) |
| .build() |
| .arguments()) |
| .containsExactly("1:2") |
| .inOrder(); |
| assertThat( |
| builder() |
| .addAll( |
| VectorArg.join(":") |
| .each(nestedSet(foo("1"), foo("2"))) |
| .mapped(Foo::expandToStr)) |
| .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::expandToStr)) |
| .build() |
| .arguments()) |
| .containsExactly("--arg", "1:2") |
| .inOrder(); |
| assertThat( |
| builder() |
| .addAll( |
| "--arg", |
| VectorArg.join(":") |
| .each(nestedSet(foo("1"), foo("2"))) |
| .mapped(Foo::expandToStr)) |
| .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::expandToStr)) |
| .build() |
| .arguments()) |
| .containsExactly("-D1", "-D2") |
| .inOrder(); |
| assertThat( |
| builder() |
| .addAll( |
| VectorArg.format("-D%s") |
| .each(nestedSet(foo("1"), foo("2"))) |
| .mapped(Foo::expandToStr)) |
| .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::expandToStr)) |
| .build() |
| .arguments()) |
| .containsExactly("--arg", "-D1", "-D2") |
| .inOrder(); |
| assertThat( |
| builder() |
| .addAll( |
| "--arg", |
| VectorArg.format("-D%s") |
| .each(nestedSet(foo("1"), foo("2"))) |
| .mapped(Foo::expandToStr)) |
| .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::expandToStr)) |
| .build() |
| .arguments()) |
| .containsExactly("-D1:-D2") |
| .inOrder(); |
| assertThat( |
| builder() |
| .addAll( |
| VectorArg.format("-D%s") |
| .join(":") |
| .each(nestedSet(foo("1"), foo("2"))) |
| .mapped(Foo::expandToStr)) |
| .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::expandToStr)) |
| .build() |
| .arguments()) |
| .containsExactly("--arg", "-D1:-D2") |
| .inOrder(); |
| assertThat( |
| builder() |
| .addAll( |
| "--arg", |
| VectorArg.format("-D%s") |
| .join(":") |
| .each(nestedSet(foo("1"), foo("2"))) |
| .mapped(Foo::expandToStr)) |
| .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::expandToStr)) |
| .build() |
| .arguments()) |
| .containsExactly("-D", "1", "-D", "2") |
| .inOrder(); |
| assertThat( |
| builder() |
| .addAll( |
| VectorArg.addBefore("-D") |
| .each(nestedSet(foo("1"), foo("2"))) |
| .mapped(Foo::expandToStr)) |
| .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::expandToStr)) |
| .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::expandToStr)) |
| .build() |
| .arguments()) |
| .containsExactly("-D", "D1", "-D", "D2") |
| .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<String>) null) |
| .addAll(ImmutableList.of()) |
| .addPaths((ImmutableList<PathFragment>) null) |
| .addPaths(ImmutableList.of()) |
| .addExecPaths((ImmutableList<Artifact>) null) |
| .addExecPaths(ImmutableList.of()) |
| .addAll((NestedSet<String>) null) |
| .addAll(NestedSetBuilder.emptySet(Order.STABLE_ORDER)) |
| .addPaths((NestedSet<PathFragment>) null) |
| .addPaths(NestedSetBuilder.emptySet(Order.STABLE_ORDER)) |
| .addExecPaths((NestedSet<Artifact>) null) |
| .addExecPaths(NestedSetBuilder.emptySet(Order.STABLE_ORDER)) |
| .addAll(VectorArg.of((NestedSet<String>) null)) |
| .addAll(VectorArg.of(NestedSetBuilder.<String>emptySet(Order.STABLE_ORDER))) |
| .addAll("foo", (ImmutableList<String>) null) |
| .addAll("foo", ImmutableList.of()) |
| .addPaths("foo", (ImmutableList<PathFragment>) null) |
| .addPaths("foo", ImmutableList.of()) |
| .addExecPaths("foo", (ImmutableList<Artifact>) null) |
| .addExecPaths("foo", ImmutableList.of()) |
| .addAll("foo", (NestedSet<String>) null) |
| .addAll("foo", NestedSetBuilder.emptySet(Order.STABLE_ORDER)) |
| .addPaths("foo", (NestedSet<PathFragment>) null) |
| .addPaths("foo", NestedSetBuilder.emptySet(Order.STABLE_ORDER)) |
| .addExecPaths("foo", (NestedSet<Artifact>) null) |
| .addExecPaths("foo", NestedSetBuilder.emptySet(Order.STABLE_ORDER)) |
| .addAll("foo", VectorArg.of((NestedSet<String>) null)) |
| .addAll("foo", VectorArg.of(NestedSetBuilder.<String>emptySet(Order.STABLE_ORDER))) |
| .addPlaceholderTreeArtifactExecPath("foo", null) |
| .build(); |
| assertThat(cl.arguments()).isEmpty(); |
| } |
| |
| @Test |
| public void testTreeFileArtifactExecPathArgs() { |
| SpecialArtifact treeArtifactOne = createTreeArtifact("myArtifact/treeArtifact1"); |
| SpecialArtifact treeArtifactTwo = createTreeArtifact("myArtifact/treeArtifact2"); |
| |
| CustomCommandLine commandLineTemplate = |
| builder() |
| .addPlaceholderTreeArtifactExecPath("--argOne", treeArtifactOne) |
| .addPlaceholderTreeArtifactExecPath("--argTwo", treeArtifactTwo) |
| .build(); |
| |
| TreeFileArtifact treeFileArtifactOne = |
| ActionsTestUtil.createTreeFileArtifactWithNoGeneratingAction( |
| treeArtifactOne, "children/child1"); |
| TreeFileArtifact treeFileArtifactTwo = |
| ActionsTestUtil.createTreeFileArtifactWithNoGeneratingAction( |
| treeArtifactTwo, "children/child2"); |
| |
| CustomCommandLine commandLine = commandLineTemplate.evaluateTreeFileArtifacts( |
| ImmutableList.of(treeFileArtifactOne, treeFileArtifactTwo)); |
| |
| assertThat(commandLine.arguments()) |
| .containsExactly( |
| "--argOne", |
| "dir/myArtifact/treeArtifact1/children/child1", |
| "--argTwo", |
| "dir/myArtifact/treeArtifact2/children/child2") |
| .inOrder(); |
| } |
| |
| @Test |
| public void testKeyComputation() { |
| NestedSet<String> values = NestedSetBuilder.<String>stableOrder().add("a").add("b").build(); |
| ImmutableList<CustomCommandLine> commandLines = |
| ImmutableList.<CustomCommandLine>builder() |
| .add(builder().add("arg").build()) |
| .add(builder().addFormatted("--foo=%s", "arg").build()) |
| .add(builder().addPrefixed("--foo=%s", "arg").build()) |
| .add(builder().addAll(values).build()) |
| .add(builder().addAll(VectorArg.addBefore("--foo=%s").each(values)).build()) |
| .add(builder().addAll(VectorArg.join("--foo=%s").each(values)).build()) |
| .add(builder().addAll(VectorArg.format("--foo=%s").each(values)).build()) |
| .add( |
| builder() |
| .addAll(VectorArg.of(values).mapped((s, args) -> args.accept(s + "_mapped"))) |
| .build()) |
| .build(); |
| |
| // Ensure all these command lines have distinct keys |
| ActionKeyContext actionKeyContext = new ActionKeyContext(); |
| Map<String, CustomCommandLine> digests = new HashMap<>(); |
| for (CustomCommandLine commandLine : commandLines) { |
| Fingerprint fingerprint = new Fingerprint(); |
| commandLine.addToFingerprint(actionKeyContext, fingerprint); |
| String digest = fingerprint.hexDigestAndReset(); |
| CustomCommandLine previous = digests.putIfAbsent(digest, commandLine); |
| if (previous != null) { |
| fail( |
| String.format( |
| "Found two command lines with identical digest %s: '%s' and '%s'", |
| digest, |
| Joiner.on(' ').join(previous.arguments()), |
| Joiner.on(' ').join(commandLine.arguments()))); |
| } |
| } |
| } |
| |
| @Test |
| public void testTreeFileArtifactArgThrowWithoutSubstitution() { |
| Artifact treeArtifactOne = createTreeArtifact("myArtifact/treeArtifact1"); |
| Artifact treeArtifactTwo = createTreeArtifact("myArtifact/treeArtifact2"); |
| |
| CustomCommandLine commandLineTemplate = |
| builder() |
| .addPlaceholderTreeArtifactExecPath("--argOne", treeArtifactOne) |
| .addPlaceholderTreeArtifactExecPath("--argTwo", treeArtifactTwo) |
| .build(); |
| |
| assertThrows(NullPointerException.class, () -> commandLineTemplate.arguments()); |
| } |
| |
| private SpecialArtifact createTreeArtifact(String rootRelativePath) { |
| PathFragment relpath = PathFragment.create(rootRelativePath); |
| return new SpecialArtifact( |
| rootDir, |
| rootDir.getExecPath().getRelative(relpath), |
| ActionsTestUtil.NULL_ACTION_LOOKUP_DATA.getActionLookupKey(), |
| SpecialArtifactType.TREE); |
| } |
| |
| private static <T> ImmutableList<T> list(T... objects) { |
| return ImmutableList.<T>builder().addAll(Arrays.asList(objects)).build(); |
| } |
| |
| private static <T> NestedSet<T> nestedSet(T... objects) { |
| return NestedSetBuilder.<T>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 void expandToStr(Foo foo, Consumer<String> args) { |
| args.accept(foo.str); |
| } |
| } |
| } |