// 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.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.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.Arrays;
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 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")
        .inOrder();
    assertThat(
            builder()
                .addLazyString(
                    new OnDemandString() {
                      @Override
                      public String toString() {
                        return "foo";
                      }
                    })
                .build()
                .arguments())
        .containsExactly("foo")
        .inOrder();
  }

  @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")
        .inOrder();
  }

  @Test
  public void addPrefixed_addsPrefixForArguments() throws Exception {
    assertThat(builder().addPrefixed("prefix-", "foo").build().arguments())
        .containsExactly("prefix-foo")
        .inOrder();
    assertThat(
            builder()
                .addPrefixedLabel("prefix-", Label.parseCanonical("//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 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)
            .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(NullPointerException.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.<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);
    }
  }
}
