Accept Nested TOML Array for Default Value Decoding (#920)

* Handle nested TOML array to resolve TOML array decoding bug in certain plugin configs.
* Fix for picocli unable to determine if plugin options are multivalue.

Signed-off-by: Steven J Schroeder <steven.schroeder@consensys.net>
pull/1043/head
Steven Schroeder 5 years ago committed by GitHub
parent 9c37887df4
commit 3ad217730c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 29
      besu/src/main/java/org/hyperledger/besu/cli/util/TomlConfigFileDefaultProvider.java
  2. 9
      besu/src/test/java/org/hyperledger/besu/cli/TomlConfigFileDefaultProviderTest.java

@ -20,11 +20,13 @@ import java.io.File;
import java.io.IOException;
import java.math.BigInteger;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
import org.apache.tuweni.toml.Toml;
import org.apache.tuweni.toml.TomlArray;
import org.apache.tuweni.toml.TomlParseError;
import org.apache.tuweni.toml.TomlParseResult;
import picocli.CommandLine;
@ -55,11 +57,16 @@ public class TomlConfigFileDefaultProvider implements IDefaultValueProvider {
}
private String getConfigurationValue(final OptionSpec optionSpec) {
// NOTE: This temporary fix is necessary to make certain options be treated as a multi-value.
// This can be done automatically by picocli if the object implements Collection.
final boolean isArray =
getKeyName(optionSpec).map(keyName -> result.isArray(keyName)).orElse(false);
final String defaultValue;
// Convert config values to the right string representation for default string value
if (optionSpec.type().equals(Boolean.class)) {
defaultValue = getBooleanEntryAsString(optionSpec);
} else if (optionSpec.isMultiValue()) {
} else if (optionSpec.isMultiValue() || isArray) {
defaultValue = getListEntryAsString(optionSpec);
} else if (optionSpec.type().equals(Integer.class)) {
defaultValue = getIntegerEntryAsString(optionSpec);
@ -93,12 +100,22 @@ public class TomlConfigFileDefaultProvider implements IDefaultValueProvider {
// returns the string representation of the array value of the config line in CLI format
// corresponding to the option in toml file
// or null if not present in the config
return getKeyName(spec)
.map(result::getArray)
return decodeTomlArray(
getKeyName(spec).map(result::getArray).map(tomlArray -> tomlArray.toList()).orElse(null));
}
private String decodeTomlArray(final List<Object> tomlArrayElements) {
if (tomlArrayElements == null) return null;
return tomlArrayElements.stream()
.map(
tomlArray ->
tomlArray.toList().stream().map(Object::toString).collect(Collectors.joining(",")))
.orElse(null);
tomlObject -> {
if (tomlObject instanceof TomlArray) {
return "[".concat(decodeTomlArray(((TomlArray) tomlObject).toList())).concat("]");
} else {
return tomlObject.toString();
}
})
.collect(Collectors.joining(","));
}
private String getBooleanEntryAsString(final OptionSpec spec) {

@ -101,6 +101,7 @@ public class TomlConfigFileDefaultProviderTest {
validOptionsMap.put("--an-int-value-option", null);
validOptionsMap.put("--a-wei-value-option", null);
validOptionsMap.put("--a-string-value-option", null);
validOptionsMap.put("--a-nested-multi-value-option", null);
when(mockCommandSpec.optionsMap()).thenReturn(validOptionsMap);
@ -119,6 +120,9 @@ public class TomlConfigFileDefaultProviderTest {
fileWriter.write("a-wei-value-option=1");
fileWriter.newLine();
fileWriter.write("a-string-value-option='my value'");
fileWriter.newLine();
fileWriter.write(
"a-nested-multi-value-option=[ [\"value1\", \"value2\"], [\"value3\", \"value4\"] ]");
fileWriter.flush();
final TomlConfigFileDefaultProvider providerUnderTest =
@ -153,6 +157,11 @@ public class TomlConfigFileDefaultProviderTest {
providerUnderTest.defaultValue(
OptionSpec.builder("a-string-value-option").type(String.class).build()))
.isEqualTo("my value");
assertThat(
providerUnderTest.defaultValue(
OptionSpec.builder("a-nested-multi-value-option").type(Collection.class).build()))
.isEqualTo("[value1,value2],[value3,value4]");
}
}

Loading…
Cancel
Save