diff --git a/codegen/src/main/java/org/web3j/codegen/TruffleJsonFunctionWrapperGenerator.java b/codegen/src/main/java/org/web3j/codegen/TruffleJsonFunctionWrapperGenerator.java index cf5c700a7..7ae3e2994 100644 --- a/codegen/src/main/java/org/web3j/codegen/TruffleJsonFunctionWrapperGenerator.java +++ b/codegen/src/main/java/org/web3j/codegen/TruffleJsonFunctionWrapperGenerator.java @@ -19,6 +19,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.concurrent.Callable; import java.util.stream.Collectors; import com.fasterxml.jackson.annotation.JsonAnyGetter; @@ -31,6 +32,7 @@ import com.fasterxml.jackson.annotation.JsonPropertyOrder; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; +import picocli.CommandLine; import org.web3j.abi.datatypes.Address; import org.web3j.protocol.ObjectMapperFactory; @@ -40,6 +42,15 @@ import static org.web3j.codegen.Console.exitError; import static org.web3j.utils.Collection.tail; +import static picocli.CommandLine.Command; +import static picocli.CommandLine.ExecutionException; +import static picocli.CommandLine.Help; +import static picocli.CommandLine.Help.Visibility.ALWAYS; +import static picocli.CommandLine.Option; +import static picocli.CommandLine.ParameterException; +import static picocli.CommandLine.Parameters; +import static picocli.CommandLine.ParseResult; +import static picocli.CommandLine.RunLast; /** * Java wrapper source code generator for Truffle JSON format. Truffle embeds the Solidity ABI @@ -50,66 +61,107 @@ @SuppressWarnings("deprecation") public class TruffleJsonFunctionWrapperGenerator extends FunctionWrapperGenerator { - private static final String USAGE = - "truffle generate " - + "[--javaTypes|--solidityTypes] " - + ".json " - + "-p|--package " - + "-o|--outputDir "; + public static final String COMMAND_TRUFFLE = "truffle"; + public static final String COMMAND_GENERATE = "generate"; + public static final String COMMAND_PREFIX = COMMAND_TRUFFLE + " " + COMMAND_GENERATE; - private String jsonFileLocation; + private final String jsonFileLocation; + private final boolean generateBothCallAndSend; public TruffleJsonFunctionWrapperGenerator( String jsonFileLocation, String destinationDirLocation, String basePackageName, - boolean useJavaNativeTypes) { + boolean useJavaNativeTypes, + boolean generateBothCallAndSend) { super(new File(destinationDirLocation), basePackageName, useJavaNativeTypes); this.jsonFileLocation = jsonFileLocation; + this.generateBothCallAndSend = generateBothCallAndSend; } - public static void run(String[] args) throws Exception { - if (args.length < 1 || !"generate".equals(args[0])) { - exitError(USAGE); - } else { - main(tail(args)); + public static void main(String[] args) { + if (args.length > 0 && args[0].equals(COMMAND_TRUFFLE)) { + args = tail(args); } - } - - public static void main(String[] args) throws Exception { - - String[] fullArgs; - if (args.length == 5) { - fullArgs = new String[args.length + 1]; - fullArgs[0] = JAVA_TYPES_ARG; - System.arraycopy(args, 0, fullArgs, 1, args.length); - } else { - fullArgs = args; + if (args.length > 0 && args[0].equals(COMMAND_GENERATE)) { + args = tail(args); } + CommandLine cmd = new CommandLine(new PicocliRunner()); + cmd.parseWithHandlers( + new RunLast().useOut(System.out).useAnsi(Help.Ansi.AUTO), + RethrowExceptionHandler.HANDLER, + args); + } - if (fullArgs.length != 6) { - exitError(USAGE); + @Command( + name = COMMAND_PREFIX, + mixinStandardHelpOptions = true, + version = "4.0", + sortOptions = false) + private static class PicocliRunner implements Callable { + + @Option( + names = {"-jt", JAVA_TYPES_ARG}, + description = "use native Java types.", + showDefaultValue = ALWAYS) + boolean useJavaNativeTypes; + + @Option( + names = {"-st", SOLIDITY_TYPES_ARG}, + description = "use solidity types.") + boolean useSolidityTypes; + + @Parameters(index = "0") + String jsonFileLocation; + + @Option( + names = {"-o", "--outputDir"}, + description = "destination base directory.", + required = true) + private String destinationDirLocation; + + @Option( + names = {"-B", "--generateBoth"}, + description = "generate both call and send functions.", + required = false) + private boolean generateBothCallAndSend; + + @Option( + names = {"-p", "--package"}, + description = "base package name.", + required = true) + private String basePackageName; + + @Override + public Void call() throws Exception { + useJavaNativeTypes = !(useSolidityTypes); + new TruffleJsonFunctionWrapperGenerator( + jsonFileLocation, + destinationDirLocation, + basePackageName, + useJavaNativeTypes, + generateBothCallAndSend) + .generate(); + return null; } + } - boolean useJavaNativeTypes = useJavaNativeTypes(fullArgs[0], USAGE); + public static class RethrowExceptionHandler + implements CommandLine.IExceptionHandler2> { - String jsonFileLocation = parsePositionalArg(fullArgs, 1); - String destinationDirLocation = parseParameterArgument(fullArgs, "-o", "--outputDir"); - String basePackageName = parseParameterArgument(fullArgs, "-p", "--package"); + public static final RethrowExceptionHandler HANDLER = new RethrowExceptionHandler(); - if (Strings.isEmpty(jsonFileLocation) - || Strings.isEmpty(destinationDirLocation) - || Strings.isEmpty(basePackageName)) { - exitError(USAGE); + @Override + public List handleParseException(ParameterException ex, String[] args) { + throw ex; } - new TruffleJsonFunctionWrapperGenerator( - jsonFileLocation, - destinationDirLocation, - basePackageName, - useJavaNativeTypes) - .generate(); + @Override + public List handleExecutionException( + ExecutionException ex, ParseResult parseResult) { + throw ex; + } } static Contract loadContractDefinition(File jsonFile) throws IOException { @@ -148,7 +200,8 @@ public void generate() throws IOException, ClassNotFoundException { } else { addresses = Collections.EMPTY_MAP; } - new SolidityFunctionWrapper(useJavaNativeTypes, Address.DEFAULT_LENGTH) + new SolidityFunctionWrapper( + useJavaNativeTypes, Address.DEFAULT_LENGTH, generateBothCallAndSend) .generateJavaFiles( contractName, c.getBytecode(), diff --git a/codegen/src/test/java/org/web3j/codegen/TruffleJsonFunctionWrapperGeneratorTest.java b/codegen/src/test/java/org/web3j/codegen/TruffleJsonFunctionWrapperGeneratorTest.java index 223e0d5d0..21a545eb9 100644 --- a/codegen/src/test/java/org/web3j/codegen/TruffleJsonFunctionWrapperGeneratorTest.java +++ b/codegen/src/test/java/org/web3j/codegen/TruffleJsonFunctionWrapperGeneratorTest.java @@ -14,7 +14,9 @@ import java.io.File; import java.net.URL; +import java.util.ArrayList; import java.util.Arrays; +import java.util.List; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -55,30 +57,41 @@ public void testContractGeneration() throws Exception { private void testCodeGenerationJvmTypes(String contractName, String inputFileName) throws Exception { - testCodeGeneration(contractName, inputFileName, PackageName, JAVA_TYPES_ARG); + testCodeGeneration(contractName, inputFileName, PackageName, JAVA_TYPES_ARG, false); + testCodeGeneration(contractName, inputFileName, PackageName, JAVA_TYPES_ARG, true); } @SuppressWarnings("SameParameterValue") private void testCodeGenerationSolidtyTypes(String contractName, String inputFileName) throws Exception { - testCodeGeneration(contractName, inputFileName, PackageName, SOLIDITY_TYPES_ARG); + testCodeGeneration(contractName, inputFileName, PackageName, SOLIDITY_TYPES_ARG, false); + testCodeGeneration(contractName, inputFileName, PackageName, SOLIDITY_TYPES_ARG, true); } private void testCodeGeneration( - String contractName, String inputFileName, String packageName, String types) + String contractName, + String inputFileName, + String packageName, + String types, + boolean generateBothCallAndSend) throws Exception { - TruffleJsonFunctionWrapperGenerator.main( - Arrays.asList( + List argList = + new ArrayList<>( + Arrays.asList( types, ContractJsonParseTest.jsonFileLocation( contractBaseDir, contractName, inputFileName), "-p", packageName, "-o", - tempDirPath) - .toArray(new String[0])); + tempDirPath)); + + if (generateBothCallAndSend) { + argList.add("-B"); + } + TruffleJsonFunctionWrapperGenerator.main(argList.toArray(new String[0])); GeneraterTestUtils.verifyGeneratedCode( tempDirPath