aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/main/java/com/google/devtools/build/lib/analysis/actions/CustomCommandLine.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/com/google/devtools/build/lib/analysis/actions/CustomCommandLine.java')
-rw-r--r--src/main/java/com/google/devtools/build/lib/analysis/actions/CustomCommandLine.java51
1 files changed, 51 insertions, 0 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/actions/CustomCommandLine.java b/src/main/java/com/google/devtools/build/lib/analysis/actions/CustomCommandLine.java
index d314388fe4..e6f9792637 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/actions/CustomCommandLine.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/actions/CustomCommandLine.java
@@ -15,6 +15,7 @@
package com.google.devtools.build.lib.analysis.actions;
import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Function;
import com.google.common.base.Joiner;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
@@ -28,6 +29,7 @@ import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable;
import com.google.devtools.build.lib.util.Preconditions;
import com.google.devtools.build.lib.vfs.PathFragment;
import java.util.ArrayList;
+import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -282,6 +284,34 @@ public final class CustomCommandLine extends CommandLine {
}
}
+ private static final class JoinValuesTransformed<T> extends ArgvFragment {
+
+ private final String delimiter;
+ private final Iterable<T> values;
+ private final Function<T, String> toString;
+
+ private JoinValuesTransformed(
+ String delimiter, Iterable<T> values, Function<T, String> toString) {
+ this.delimiter = delimiter;
+ this.values = CollectionUtils.makeImmutable(values);
+ this.toString = toString;
+ }
+
+ @Override
+ void eval(ImmutableList.Builder<String> builder) {
+ StringBuilder arg = new StringBuilder();
+ Iterator<T> parts = values.iterator();
+ if (parts.hasNext()) {
+ arg.append(toString.apply(parts.next()));
+ while (parts.hasNext()) {
+ arg.append(delimiter);
+ arg.append(toString.apply(parts.next()));
+ }
+ }
+ builder.add(arg.toString());
+ }
+ }
+
/**
* Arguments that intersperse strings between the items in a sequence. There are two forms of
* interspersing, and either may be used by this implementation:
@@ -480,6 +510,27 @@ public final class CustomCommandLine extends CommandLine {
}
return this;
}
+
+ /**
+ * Adds a list of values transformed by a function and delimited by a string.
+ *
+ * <p>Prefer this to transforming nested sets yourself as it is more memory-efficient. By using
+ * this class, expansion of the nested set is deferred until action execution instead of
+ * retained on the heap.
+ *
+ * @param arg The argument
+ * @param delimiter A delimiter string placed in between each transformed value
+ * @param values The values to expand into a list
+ * @param toString A function that transforms a value into a string
+ */
+ public <T> Builder addJoinValues(
+ String arg, String delimiter, Iterable<T> values, Function<T, String> toString) {
+ if (arg != null && arguments != null) {
+ arguments.add(arg);
+ arguments.add(new JoinValuesTransformed<T>(delimiter, values, toString));
+ }
+ return this;
+ }
public Builder addJoinExecPaths(String arg, String delimiter, Iterable<Artifact> artifacts) {
if (arg != null && artifacts != null) {