// 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.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.TreeFileArtifact;
import com.google.devtools.build.lib.actions.ArtifactRoot.RootType;
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.analysis.actions.CustomCommandLine.VectorArg.SimpleVectorArg;
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.cmdline.RepositoryMapping;
import com.google.devtools.build.lib.cmdline.RepositoryName;
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.OnDemandString;
import com.google.devtools.build.lib.vfs.PathFragment;
import com.google.testing.junit.testparameterinjector.TestParameter;
import com.google.testing.junit.testparameterinjector.TestParameterInjector;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Consumer;
import net.starlark.java.eval.EvalException;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;

/** Tests for {@link CustomCommandLine}. */
@RunWith(TestParameterInjector.class)
public final class CustomCommandLineTest {
  private ArtifactRoot rootDir;
  private Artifact artifact1;
  private Artifact artifact2;

  @Before
  public void createArtifacts() throws Exception {
    Scratch scratch = new Scratch();
    rootDir = ArtifactRoot.asDerivedRoot(scratch.dir("/exec/root"), RootType.Output, "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 addScalar_addsSingleArgument() throws Exception {
    assertThat(builder().add("--arg").build().arguments()).containsExactly("--arg");
    assertThat(builder().addDynamicString("--arg").build().arguments()).containsExactly("--arg");
    assertThat(builder().addLabel(Label.parseCanonical("//a:b")).build().arguments())
        .containsExactly("//a:b");
    assertThat(builder().addPath(PathFragment.create("path")).build().arguments())
        .containsExactly("path");
    assertThat(builder().addExecPath(artifact1).build().arguments())
        .containsExactly("dir/file1.txt");
    assertThat(
            builder()
                .addLazyString(
                    new OnDemandString() {
                      @Override
                      public String toString() {
                        return "foo";
                      }
                    })
                .build()
                .arguments())
        .containsExactly("foo");
  }

  @Test
  public void addScalar_withConstantArg_addsStringPrependedByArg() throws Exception {
    assertThat(builder().add("--arg", "val").build().arguments())
        .containsExactly("--arg", "val")
        .inOrder();
    assertThat(builder().addLabel("--arg", Label.parseCanonical("//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 OnDemandString() {
                      @Override
                      public String toString() {
                        return "foo";
                      }
                    })
                .build()
                .arguments())
        .containsExactly("--arg", "foo")
        .inOrder();
  }

  @Test
  public void addFormatted_addsCorrectlyFormattedArgument() throws Exception {
    assertThat(builder().addFormatted("%s%s", "hello", "world").build().arguments())
        .containsExactly("helloworld");
  }

  @Test
  public void addPrefixed_addsPrefixForArguments() throws Exception {
    assertThat(builder().addPrefixed("prefix-", "foo").build().arguments())
        .containsExactly("prefix-foo");
    assertThat(
            builder()
                .addPrefixedLabel(
                    "prefix-", Label.parseCanonical("//a:b"), /* mainRepoMapping= */ null)
                .build()
                .arguments())
        .containsExactly("prefix-//a:b");
    assertThat(
            builder().addPrefixedPath("prefix-", PathFragment.create("path")).build().arguments())
        .containsExactly("prefix-path");
    assertThat(builder().addPrefixedExecPath("prefix-", artifact1).build().arguments())
        .containsExactly("prefix-dir/file1.txt");
  }

  @Test
  public void addPrefixedLabel_emitsExternalLabelInDisplayForm() throws Exception {
    assertThat(
            builder()
                .addPrefixedLabel(
                    "prefix-",
                    Label.parseCanonical("@@canonical_name//a:b"),
                    RepositoryMapping.create(
                        ImmutableMap.of(
                            "apparent_name", RepositoryName.createUnvalidated("canonical_name")),
                        RepositoryName.MAIN))
                .build()
                .arguments())
        .containsExactly("prefix-@apparent_name//a:b");
  }

  @Test
  public void addAll_addsAllArguments() 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();
  }

  @Test
  public void vectorAdds_withCompileTimeArg_addsAllValuesPrependedByArg() throws Exception {
    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();
  }

  private enum CustomCommandLineMode {
    REGULAR {
      @Override
      CustomCommandLine addAll(VectorArg<String> vectorArg) {
        return builder().addAll(vectorArg).build();
      }

      @Override
      CustomCommandLine addPaths(VectorArg<PathFragment> vectorArg) {
        return builder().addPaths(vectorArg).build();
      }

      @Override
      CustomCommandLine addExecPaths(VectorArg<Artifact> vectorArg) {
        return builder().addExecPaths(vectorArg).build();
      }

      @Override
      ImmutableList<String> expected(String... values) {
        return ImmutableList.copyOf(values);
      }
    },
    WITH_CONSTANT_ARG {
      @Override
      CustomCommandLine addAll(VectorArg<String> vectorArg) {
        return builder().addAll("--arg", vectorArg).build();
      }

      @Override
      CustomCommandLine addPaths(VectorArg<PathFragment> vectorArg) {
        return builder().addPaths("--arg", vectorArg).build();
      }

      @Override
      CustomCommandLine addExecPaths(VectorArg<Artifact> vectorArg) {
        return builder().addExecPaths("--arg", vectorArg).build();
      }

      @Override
      ImmutableList<String> expected(String... values) {
        return ImmutableList.<String>builderWithExpectedSize(values.length + 1)
            .add("--arg")
            .add(values)
            .build();
      }
    };

    abstract CustomCommandLine addAll(VectorArg<String> vectorArg);

    abstract CustomCommandLine addPaths(VectorArg<PathFragment> vectorArg);

    abstract CustomCommandLine addExecPaths(VectorArg<Artifact> vectorArg);

    abstract ImmutableList<String> expected(String... values);
  }

  private enum VectorArgMode {
    LIST {
      @Override
      <T> SimpleVectorArg<T> of(T... objects) {
        return VectorArg.of(list(objects));
      }

      @Override
      <T> SimpleVectorArg<T> each(VectorArg.Builder vectorArg, T... objects) {
        return vectorArg.each(list(objects));
      }
    },
    NESTED_SET {
      @Override
      <T> SimpleVectorArg<T> of(T... objects) {
        return VectorArg.of(nestedSet(objects));
      }

      @Override
      <T> SimpleVectorArg<T> each(VectorArg.Builder vectorArg, T... objects) {
        return vectorArg.each(nestedSet(objects));
      }
    };

    abstract <T> SimpleVectorArg<T> of(T... objects);

    abstract <T> SimpleVectorArg<T> each(VectorArg.Builder vectorArg, T... objects);
  }

  @Test
  public void addAllVector_addsAllArguments(
      @TestParameter CustomCommandLineMode customCommandLine,
      @TestParameter VectorArgMode vectorArg)
      throws Exception {
    assertThat(customCommandLine.addAll(vectorArg.of("1", "2")).arguments())
        .containsExactlyElementsIn(customCommandLine.expected("1", "2"))
        .inOrder();
    assertThat(
            customCommandLine
                .addAll(vectorArg.of(foo("1"), foo("2")).mapped(Foo::expandToStr))
                .arguments())
        .containsExactlyElementsIn(customCommandLine.expected("1", "2"))
        .inOrder();
  }

  @Test
  public void addJoinedVector_addsJoinedArguments(
      @TestParameter CustomCommandLineMode customCommandLine,
      @TestParameter VectorArgMode vectorArg)
      throws Exception {
    assertThat(
            customCommandLine
                .addAll(vectorArg.each(VectorArg.join(":"), "val1", "val2"))
                .arguments())
        .containsExactlyElementsIn(customCommandLine.expected("val1:val2"))
        .inOrder();
    assertThat(
            customCommandLine
                .addPaths(
                    vectorArg.each(
                        VectorArg.join(":"),
                        PathFragment.create("path1"),
                        PathFragment.create("path2")))
                .arguments())
        .containsExactlyElementsIn(customCommandLine.expected("path1:path2"))
        .inOrder();
    assertThat(
            customCommandLine
                .addExecPaths(vectorArg.each(VectorArg.join(":"), artifact1, artifact2))
                .arguments())
        .containsExactlyElementsIn(customCommandLine.expected("dir/file1.txt:dir/file2.txt"))
        .inOrder();
    assertThat(
            customCommandLine
                .addAll(
                    vectorArg
                        .each(VectorArg.join(":"), foo("1"), foo("2"))
                        .mapped(Foo::expandToStr))
                .arguments())
        .containsExactlyElementsIn(customCommandLine.expected("1:2"))
        .inOrder();
  }

  @Test
  public void addFormatEachVector_addsFormattedStrings(
      @TestParameter CustomCommandLineMode customCommandLine,
      @TestParameter VectorArgMode vectorArg)
      throws Exception {
    assertThat(
            customCommandLine
                .addAll(vectorArg.each(VectorArg.format("-D%s"), "val1", "val2"))
                .arguments())
        .containsExactlyElementsIn(customCommandLine.expected("-Dval1", "-Dval2"))
        .inOrder();
    assertThat(
            customCommandLine
                .addPaths(
                    vectorArg.each(
                        VectorArg.format("-D%s"),
                        PathFragment.create("path1"),
                        PathFragment.create("path2")))
                .arguments())
        .containsExactlyElementsIn(customCommandLine.expected("-Dpath1", "-Dpath2"))
        .inOrder();
    assertThat(
            customCommandLine
                .addExecPaths(vectorArg.each(VectorArg.format("-D%s"), artifact1, artifact2))
                .arguments())
        .containsExactlyElementsIn(customCommandLine.expected("-Ddir/file1.txt", "-Ddir/file2.txt"))
        .inOrder();
    assertThat(
            customCommandLine
                .addAll(
                    vectorArg
                        .each(VectorArg.format("-D%s"), foo("1"), foo("2"))
                        .mapped(Foo::expandToStr))
                .arguments())
        .containsExactlyElementsIn(customCommandLine.expected("-D1", "-D2"))
        .inOrder();
  }

  @Test
  public void addFormatEachJoinedVector_addsJoinedFormattedStrings(
      @TestParameter CustomCommandLineMode customCommandLine,
      @TestParameter VectorArgMode vectorArg)
      throws Exception {
    assertThat(
            customCommandLine
                .addAll(vectorArg.each(VectorArg.format("-D%s").join(":"), "val1", "val2"))
                .arguments())
        .containsExactlyElementsIn(customCommandLine.expected("-Dval1:-Dval2"))
        .inOrder();
    assertThat(
            customCommandLine
                .addPaths(
                    vectorArg.each(
                        VectorArg.format("-D%s").join(":"),
                        PathFragment.create("path1"),
                        PathFragment.create("path2")))
                .arguments())
        .containsExactlyElementsIn(customCommandLine.expected("-Dpath1:-Dpath2"))
        .inOrder();
    assertThat(
            customCommandLine
                .addExecPaths(
                    vectorArg.each(VectorArg.format("-D%s").join(":"), artifact1, artifact2))
                .arguments())
        .containsExactlyElementsIn(customCommandLine.expected("-Ddir/file1.txt:-Ddir/file2.txt"))
        .inOrder();
    assertThat(
            customCommandLine
                .addAll(
                    vectorArg
                        .each(VectorArg.format("-D%s").join(":"), foo("1"), foo("2"))
                        .mapped(Foo::expandToStr))
                .arguments())
        .containsExactlyElementsIn(customCommandLine.expected("-D1:-D2"))
        .inOrder();
  }

  @Test
  public void addBeforeEachVector_addsArgumentsEachPrependedWithArg(
      @TestParameter CustomCommandLineMode customCommandLine,
      @TestParameter VectorArgMode vectorArg)
      throws Exception {
    assertThat(
            customCommandLine
                .addAll(vectorArg.each(VectorArg.addBefore("-D"), "val1", "val2"))
                .arguments())
        .containsExactlyElementsIn(customCommandLine.expected("-D", "val1", "-D", "val2"))
        .inOrder();
    assertThat(
            customCommandLine
                .addPaths(
                    vectorArg.each(
                        VectorArg.addBefore("-D"),
                        PathFragment.create("path1"),
                        PathFragment.create("path2")))
                .arguments())
        .containsExactlyElementsIn(customCommandLine.expected("-D", "path1", "-D", "path2"))
        .inOrder();
    assertThat(
            customCommandLine
                .addExecPaths(vectorArg.each(VectorArg.addBefore("-D"), artifact1, artifact2))
                .arguments())
        .containsExactlyElementsIn(
            customCommandLine.expected("-D", "dir/file1.txt", "-D", "dir/file2.txt"))
        .inOrder();
    assertThat(
            customCommandLine
                .addAll(
                    vectorArg
                        .each(VectorArg.addBefore("-D"), foo("1"), foo("2"))
                        .mapped(Foo::expandToStr))
                .arguments())
        .containsExactlyElementsIn(customCommandLine.expected("-D", "1", "-D", "2"))
        .inOrder();
  }

  @Test
  public void addBeforeEachFormattedVector_addsFormattedStringsPrependedWithArg(
      @TestParameter VectorArgMode vectorArg) throws Exception {
    assertThat(
            builder()
                .addAll(vectorArg.each(VectorArg.addBefore("-D").format("D%s"), "val1", "val2"))
                .build()
                .arguments())
        .containsExactly("-D", "Dval1", "-D", "Dval2")
        .inOrder();
    assertThat(
            builder()
                .addPaths(
                    vectorArg.each(
                        VectorArg.addBefore("-D").format("D%s"),
                        PathFragment.create("path1"),
                        PathFragment.create("path2")))
                .build()
                .arguments())
        .containsExactly("-D", "Dpath1", "-D", "Dpath2")
        .inOrder();
    assertThat(
            builder()
                .addExecPaths(
                    vectorArg.each(VectorArg.addBefore("-D").format("D%s"), artifact1, artifact2))
                .build()
                .arguments())
        .containsExactly("-D", "Ddir/file1.txt", "-D", "Ddir/file2.txt")
        .inOrder();
    assertThat(
            builder()
                .addAll(
                    vectorArg
                        .each(VectorArg.addBefore("-D").format("D%s"), foo("1"), foo("2"))
                        .mapped(Foo::expandToStr))
                .build()
                .arguments())
        .containsExactly("-D", "D1", "-D", "D2")
        .inOrder();
  }

  @Test
  public void addCombinedArgs_addsAllArguments() throws Exception {
    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 addNulls_addsNothing() 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, /* mainRepoMapping= */ 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 evaluateTreeFileArtifacts_replacesTreeArtifactsWithChildrenExecPaths()
      throws Exception {
    SpecialArtifact treeArtifactOne = createTreeArtifact("myArtifact/treeArtifact1");
    SpecialArtifact treeArtifactTwo = createTreeArtifact("myArtifact/treeArtifact2");

    CustomCommandLine commandLineTemplate =
        builder()
            .addPlaceholderTreeArtifactExecPath("--argOne", treeArtifactOne)
            .addPlaceholderTreeArtifactExecPath("--argTwo", treeArtifactTwo)
            .build();

    TreeFileArtifact treeFileArtifactOne =
        TreeFileArtifact.createTreeOutput(treeArtifactOne, "children/child1");
    TreeFileArtifact treeFileArtifactTwo =
        TreeFileArtifact.createTreeOutput(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 addAllMappedTreeFileArtifacts_mapToRelativePath_addsTreeFileRelativePaths()
      throws Exception {
    SpecialArtifact treeArtifact = createTreeArtifact("myArtifact/treeArtifact");

    TreeFileArtifact treeFileArtifactOne =
        TreeFileArtifact.createTreeOutput(treeArtifact, "children/child1");
    TreeFileArtifact treeFileArtifactTwo =
        TreeFileArtifact.createTreeOutput(treeArtifact, "children/child2");

    CommandLineItem.MapFn<Artifact> expandParentRelativePath =
        (src, args) -> {
          try {
            args.accept(src.getTreeRelativePathString());
          } catch (EvalException e) {
            throw new IllegalStateException("Unexpected EvalException thown.", e);
          }
        };

    CustomCommandLine commandLineTemplate =
        builder()
            .addAll(
                VectorArg.SimpleVectorArg.of(
                        ImmutableList.of(treeFileArtifactOne, treeFileArtifactTwo))
                    .mapped(expandParentRelativePath))
            .build();

    assertThat(commandLineTemplate.arguments())
        .containsExactly("children/child1", "children/child2")
        .inOrder();
  }

  @Test
  public void arguments_unsubstitutedTreeArtifactPlaceholder_fails() {
    Artifact treeArtifactOne = createTreeArtifact("myArtifact/treeArtifact1");
    Artifact treeArtifactTwo = createTreeArtifact("myArtifact/treeArtifact2");

    CustomCommandLine commandLineTemplate =
        builder()
            .addPlaceholderTreeArtifactExecPath("--argOne", treeArtifactOne)
            .addPlaceholderTreeArtifactExecPath("--argTwo", treeArtifactTwo)
            .build();

    assertThrows(RuntimeException.class, commandLineTemplate::arguments);
  }

  @Test
  public void addToFingerPrint_computesUniqueKeyForDifferentCommandLines() throws Exception {
    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, /* artifactExpander= */ null, 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())));
      }
    }
  }

  private SpecialArtifact createTreeArtifact(String rootRelativePath) {
    return ActionsTestUtil.createTreeArtifactWithGeneratingAction(
        rootDir, rootDir.getExecPath().getRelative(rootRelativePath));
  }

  private static <T> ImmutableList<T> list(T... objects) {
    return ImmutableList.copyOf(objects);
  }

  private static <T> NestedSet<T> nestedSet(T... objects) {
    return NestedSetBuilder.create(Order.STABLE_ORDER, objects);
  }

  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);
    }
  }
}
