paramValueMap) {
- if (args[i].length() < 2) {
- throw new IllegalArgumentException("You must provide an option name, e.g. -d");
- }
- char currentChar = Character.toLowerCase(args[i].charAt(1));
- if (currentChar == '-') {
- if (args[i].length() < 3) {
- throw new IllegalArgumentException("You must provide a flag name, e.g. --quiet");
- }
-
- F flag = getFlagByName(args[i].substring(2, args[i].length()));
-
- if (flag != null) {
- flags.add(flag);
- }
- } else if (currentChar == 'x') {
- String arg = args[i].substring(2);
- paramValueMap.putAll(parseArgToMap(arg));
- } else {
- if (args.length - 1 == i) {
- throw new IllegalArgumentException(
- String.format("A value must be provided after the option -%s", args[i])
- );
- }
-
- O option = getOptionByName(args[i].substring(1, args[i].length()));
-
- if (option != null) {
- options.put(option, args[i + 1]);
- }
-
- i++;
- }
- }
-
private F getFlagByName(String flagName) {
- F flagFound = flags.stream()
+ return flags.stream()
.filter(flag -> flag.getName().equals(flagName))
.findFirst()
- .orElse(null);
-
- if (flagFound == null && !this.ignoreUnmatchedArgs) {
- throw new NoSuchElementException(String.format("--%s is not a valid flag", flagName));
- }
-
- return flagFound;
+ .orElseThrow(
+ () -> new NoSuchElementException(String.format("--%s is not a valid flag", flagName))
+ );
}
private O getOptionByName(String optionName) {
- O option = options.stream()
+ return options.stream()
.filter(opt -> opt.getName().equals(optionName))
.findFirst()
- .orElse(null);
-
- if (option == null && !this.ignoreUnmatchedArgs) {
- throw new NoSuchElementException(String.format("-%s is not a valid option", optionName));
- }
-
- return option;
+ .orElseThrow(
+ () -> new NoSuchElementException(String.format("-%s is not a valid option", optionName))
+ );
}
/**
diff --git a/rskj-core/src/main/java/co/rsk/cli/CliToolRskContextAware.java b/rskj-core/src/main/java/co/rsk/cli/CliToolRskContextAware.java
index 5875b158f1d..e56b6841cfd 100644
--- a/rskj-core/src/main/java/co/rsk/cli/CliToolRskContextAware.java
+++ b/rskj-core/src/main/java/co/rsk/cli/CliToolRskContextAware.java
@@ -31,14 +31,12 @@
/**
* An abstract class for cli tools that need {@link RskContext}. Lifecycle of the {@link RskContext} instance
* is being managed by {@link CliToolRskContextAware}.
- *
+ *
* Also {@link CliToolRskContextAware} provides a logger instance for derived classes.
*/
public abstract class CliToolRskContextAware {
private static final Logger logger = LoggerFactory.getLogger("clitool");
- protected RskContext ctx;
- protected NodeStopper stopper;
protected static CliToolRskContextAware create(@Nonnull Class> cliToolClass) {
Objects.requireNonNull(cliToolClass, "cliToolClass should not be null");
@@ -59,27 +57,18 @@ public void execute(@Nonnull String[] args) {
execute(args, () -> new RskContext(args), System::exit);
}
- public void execute(@Nonnull String[] args, @Nonnull Factory contextFactory, @Nonnull NodeStopper nodeStopper) {
+ public void execute(@Nonnull String[] args, @Nonnull Factory contextFactory, @Nonnull NodeStopper stopper) {
Objects.requireNonNull(args, "args should not be null");
Objects.requireNonNull(contextFactory, "contextFactory should not be null");
- Objects.requireNonNull(nodeStopper, "stopper should not be null");
+ Objects.requireNonNull(stopper, "stopper should not be null");
String cliToolName = getClass().getSimpleName();
- // Ignore contextFactory if ctx was set previously
- // in order to allow compatibility between picocli
- // and old cli tool version
- if (this.ctx == null) {
- this.ctx = contextFactory.create();
- }
- // Ignore nodeStopper if stopper was set previously
- // in order to allow compatibility between picocli
- // and old cli tool version
- if (this.stopper == null) {
- this.stopper = nodeStopper;
- }
-
+ RskContext ctx = null;
+ // not using try-with-resources because System::exit (from stopper) prevents autocloseable closing
try {
+ ctx = contextFactory.create();
+
printInfo("{} started", cliToolName);
RskSystemProperties rskSystemProperties = ctx.getRskSystemProperties();
diff --git a/rskj-core/src/main/java/co/rsk/cli/PicoCliToolRskContextAware.java b/rskj-core/src/main/java/co/rsk/cli/PicoCliToolRskContextAware.java
deleted file mode 100644
index 9ff608d451e..00000000000
--- a/rskj-core/src/main/java/co/rsk/cli/PicoCliToolRskContextAware.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * This file is part of RskJ
- * Copyright (C) 2021 RSK Labs Ltd.
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program. If not, see .
- */
-package co.rsk.cli;
-
-import co.rsk.RskContext;
-import co.rsk.cli.exceptions.PicocliBadResultException;
-import picocli.CommandLine;
-
-import javax.annotation.Nonnull;
-import java.util.concurrent.Callable;
-
-public abstract class PicoCliToolRskContextAware extends CliToolRskContextAware implements Callable {
-
- @Override
- protected void onExecute(@Nonnull String[] args, @Nonnull RskContext ctx) {
- this.ctx = ctx;
-
- int result = new CommandLine(this).setUnmatchedArgumentsAllowed(true).execute(args);
-
- if (result != 0) {
- throw new PicocliBadResultException(result);
- }
- }
-}
diff --git a/rskj-core/src/main/java/co/rsk/cli/exceptions/PicocliBadResultException.java b/rskj-core/src/main/java/co/rsk/cli/exceptions/PicocliBadResultException.java
deleted file mode 100644
index d046f6d3237..00000000000
--- a/rskj-core/src/main/java/co/rsk/cli/exceptions/PicocliBadResultException.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * This file is part of RskJ
- * Copyright (C) 2017 RSK Labs Ltd.
- * (derived from ethereumJ library, Copyright (c) 2016 )
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program. If not, see .
- */
-
-package co.rsk.cli.exceptions;
-
-public class PicocliBadResultException extends RuntimeException {
- private final int errorCode;
-
- public PicocliBadResultException(int errorCode) {
- super(String.format("Command finished with code: %s", errorCode));
-
- this.errorCode = errorCode;
- }
-
- public int getErrorCode() {
- return errorCode;
- }
-}
diff --git a/rskj-core/src/main/java/co/rsk/cli/tools/ConnectBlocks.java b/rskj-core/src/main/java/co/rsk/cli/tools/ConnectBlocks.java
index 8d81bfbaade..f8e63763fac 100644
--- a/rskj-core/src/main/java/co/rsk/cli/tools/ConnectBlocks.java
+++ b/rskj-core/src/main/java/co/rsk/cli/tools/ConnectBlocks.java
@@ -17,7 +17,8 @@
*/
package co.rsk.cli.tools;
-import co.rsk.cli.PicoCliToolRskContextAware;
+import co.rsk.RskContext;
+import co.rsk.cli.CliToolRskContextAware;
import co.rsk.trie.TrieStore;
import org.bouncycastle.util.encoders.Hex;
import org.ethereum.core.Block;
@@ -25,8 +26,8 @@
import org.ethereum.core.Blockchain;
import org.ethereum.db.BlockStore;
import org.ethereum.db.ReceiptStore;
-import picocli.CommandLine;
+import javax.annotation.Nonnull;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
@@ -39,36 +40,31 @@
* Required cli args:
* - args[0] - file path
*/
-@CommandLine.Command(name = "connect-blocks", mixinStandardHelpOptions = true, version = "connect-blocks 1.0",
- description = "Connects blocks to a chain from external source file")
-public class ConnectBlocks extends PicoCliToolRskContextAware {
-
- @CommandLine.Option(names = {"-f", "--file"}, description = "Path to a file with blocks to connect", required = true)
- private String filePath;
+public class ConnectBlocks extends CliToolRskContextAware {
public static void main(String[] args) throws IOException {
create(MethodHandles.lookup().lookupClass()).execute(args);
}
@Override
- public Integer call() throws IOException {
+ protected void onExecute(@Nonnull String[] args, @Nonnull RskContext ctx) throws Exception {
BlockFactory blockFactory = ctx.getBlockFactory();
Blockchain blockchain = ctx.getBlockchain();
TrieStore trieStore = ctx.getTrieStore();
BlockStore blockStore = ctx.getBlockStore();
ReceiptStore receiptStore = ctx.getReceiptStore();
+ String filename = args[0];
+
long startTime = System.currentTimeMillis();
- try (BufferedReader reader = new BufferedReader(new FileReader(filePath))) {
+ try (BufferedReader reader = new BufferedReader(new FileReader(filename))) {
connectBlocks(blockFactory, blockchain, trieStore, blockStore, receiptStore, reader);
}
long endTime = System.currentTimeMillis();
printInfo("Duration: " + (endTime - startTime) + " millis");
-
- return 0;
}
private void connectBlocks(BlockFactory blockFactory, Blockchain blockchain, TrieStore trieStore, BlockStore blockStore, ReceiptStore receiptStore, BufferedReader reader) throws IOException {
diff --git a/rskj-core/src/main/java/co/rsk/cli/tools/DbMigrate.java b/rskj-core/src/main/java/co/rsk/cli/tools/DbMigrate.java
index 694ff0093e5..81b113cd37e 100644
--- a/rskj-core/src/main/java/co/rsk/cli/tools/DbMigrate.java
+++ b/rskj-core/src/main/java/co/rsk/cli/tools/DbMigrate.java
@@ -17,15 +17,16 @@
*/
package co.rsk.cli.tools;
-import co.rsk.cli.PicoCliToolRskContextAware;
+import co.rsk.RskContext;
+import co.rsk.cli.CliToolRskContextAware;
import org.ethereum.datasource.DataSourceKeyIterator;
import org.ethereum.datasource.DbKind;
import org.ethereum.datasource.KeyValueDataSource;
import org.ethereum.util.FileUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import picocli.CommandLine;
+import javax.annotation.Nonnull;
import java.io.File;
import java.io.IOException;
import java.lang.invoke.MethodHandles;
@@ -37,23 +38,18 @@
/**
* The entry point for db migration CLI tool
* This is an experimental/unsupported tool
- *
+ *
* Required cli args:
* - args[0] - database target where we are going to insert the information from the current selected database.
- *
+ *
* We do support the migrations between the following databases:
* - LevelDb (leveldb as argument)
* - RocksDb (rocksdb as argument)
*/
-@CommandLine.Command(name = "db-migrate", mixinStandardHelpOptions = true, version = "db-migrate 1.0",
- description = "Migrates between different databases such as leveldb and rocksdb.")
-public class DbMigrate extends PicoCliToolRskContextAware {
+public class DbMigrate extends CliToolRskContextAware {
private static final Logger logger = LoggerFactory.getLogger(DbMigrate.class);
private static final String NODE_ID_FILE = "nodeId.properties";
- @CommandLine.Option(names = {"-t", "--targetDb"}, description = "The target db to migrate to. Example: leveldb, rocksdb ...", required = true)
- private String targetdb;
-
private static class DbInformation {
private final KeyValueDataSource keyValueDataSource;
private final String indexPath;
@@ -95,19 +91,20 @@ public static void main(String[] args) {
create(MethodHandles.lookup().lookupClass()).execute(args);
}
+ @SuppressWarnings("unused")
public DbMigrate() {
}
@Override
- public Integer call() throws IOException {
+ protected void onExecute(@Nonnull String[] args, @Nonnull RskContext ctx) throws IOException {
logger.info("Starting db migration...");
- if (this.targetdb == null) {
+ if (args.length == 0) {
throw new IllegalArgumentException("Db to migrate not specified. Please specify in the first argument.");
}
DbKind sourceDbKind = ctx.getRskSystemProperties().databaseKind();
- DbKind targetDbKind = DbKind.ofName(this.targetdb);
+ DbKind targetDbKind = DbKind.ofName(args[0]);
if (sourceDbKind == targetDbKind) {
throw new IllegalArgumentException(String.format(
@@ -142,8 +139,6 @@ public Integer call() throws IOException {
FileUtil.recursiveDelete(sourceDbDir);
Files.move(Paths.get(targetDbDir), Paths.get(sourceDbDir));
-
- return 0;
}
private DbMigrationInformation buildDbMigrationInformation(
diff --git a/rskj-core/src/main/java/co/rsk/cli/tools/ExecuteBlocks.java b/rskj-core/src/main/java/co/rsk/cli/tools/ExecuteBlocks.java
index 2f80fafbed7..48b5c856995 100644
--- a/rskj-core/src/main/java/co/rsk/cli/tools/ExecuteBlocks.java
+++ b/rskj-core/src/main/java/co/rsk/cli/tools/ExecuteBlocks.java
@@ -17,7 +17,8 @@
*/
package co.rsk.cli.tools;
-import co.rsk.cli.PicoCliToolRskContextAware;
+import co.rsk.RskContext;
+import co.rsk.cli.CliToolRskContextAware;
import co.rsk.core.bc.BlockExecutor;
import co.rsk.core.bc.BlockResult;
import co.rsk.crypto.Keccak256;
@@ -25,9 +26,8 @@
import co.rsk.trie.TrieStore;
import org.ethereum.core.Block;
import org.ethereum.db.BlockStore;
-import picocli.CommandLine;
-import java.io.IOException;
+import javax.annotation.Nonnull;
import java.lang.invoke.MethodHandles;
import java.util.Arrays;
@@ -39,33 +39,27 @@
* - args[0] - from block number
* - args[1] - to block number
*/
-@CommandLine.Command(name = "execute-blocks", mixinStandardHelpOptions = true, version = "execute-blocks 1.0",
- description = "Executes blocks for a specified block range")
-public class ExecuteBlocks extends PicoCliToolRskContextAware {
- @CommandLine.Option(names = {"-fb", "--fromBlock"}, description = "From block number", required = true)
- private Long fromBlockNumber;
-
- @CommandLine.Option(names = {"-tb", "--toBlock"}, description = "To block number", required = true)
- private Long toBlockNumber;
+public class ExecuteBlocks extends CliToolRskContextAware {
public static void main(String[] args) {
create(MethodHandles.lookup().lookupClass()).execute(args);
}
@Override
- public Integer call() throws IOException {
+ protected void onExecute(@Nonnull String[] args, @Nonnull RskContext ctx) throws Exception {
BlockExecutor blockExecutor = ctx.getBlockExecutor();
BlockStore blockStore = ctx.getBlockStore();
TrieStore trieStore = ctx.getTrieStore();
StateRootHandler stateRootHandler = ctx.getStateRootHandler();
- executeBlocks(blockExecutor, blockStore, trieStore, stateRootHandler);
-
- return 0;
+ executeBlocks(args, blockExecutor, blockStore, trieStore, stateRootHandler);
}
- private void executeBlocks(BlockExecutor blockExecutor, BlockStore blockStore, TrieStore trieStore,
+ private void executeBlocks(String[] args, BlockExecutor blockExecutor, BlockStore blockStore, TrieStore trieStore,
StateRootHandler stateRootHandler) {
+ long fromBlockNumber = Long.parseLong(args[0]);
+ long toBlockNumber = Long.parseLong(args[1]);
+
for (long n = fromBlockNumber; n <= toBlockNumber; n++) {
Block block = blockStore.getChainBlockByNumber(n);
Block parent = blockStore.getBlockByHash(block.getParentHash().getBytes());
diff --git a/rskj-core/src/main/java/co/rsk/cli/tools/ExportBlocks.java b/rskj-core/src/main/java/co/rsk/cli/tools/ExportBlocks.java
index 193de67574b..aa57637a328 100644
--- a/rskj-core/src/main/java/co/rsk/cli/tools/ExportBlocks.java
+++ b/rskj-core/src/main/java/co/rsk/cli/tools/ExportBlocks.java
@@ -17,16 +17,16 @@
*/
package co.rsk.cli.tools;
-import co.rsk.cli.PicoCliToolRskContextAware;
+import co.rsk.RskContext;
+import co.rsk.cli.CliToolRskContextAware;
import co.rsk.core.BlockDifficulty;
import org.ethereum.core.Block;
import org.ethereum.db.BlockStore;
import org.ethereum.util.ByteUtil;
-import picocli.CommandLine;
+import javax.annotation.Nonnull;
import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
-import java.io.IOException;
import java.io.PrintStream;
import java.lang.invoke.MethodHandles;
@@ -39,34 +39,26 @@
* - args[1] - to block number
* - args[2] - file path
*/
-@CommandLine.Command(name = "export-blocks", mixinStandardHelpOptions = true, version = "export-blocks 1.0",
- description = "Exports blocks from a specific block range to a file")
-public class ExportBlocks extends PicoCliToolRskContextAware {
- @CommandLine.Option(names = {"-fb", "--fromBlock"}, description = "From block number", required = true)
- private Long fromBlockNumber;
-
- @CommandLine.Option(names = {"-tb", "--toBlock"}, description = "To block number", required = true)
- private Long toBlockNumber;
-
- @CommandLine.Option(names = {"-f", "--file"}, description = "Path to a file to export blocks to", required = true)
- private String filePath;
+public class ExportBlocks extends CliToolRskContextAware {
public static void main(String[] args) {
create(MethodHandles.lookup().lookupClass()).execute(args);
}
@Override
- public Integer call() throws IOException {
+ protected void onExecute(@Nonnull String[] args, @Nonnull RskContext ctx) throws Exception {
+ String filePath = args[2];
BlockStore blockStore = ctx.getBlockStore();
try (PrintStream writer = new PrintStream(new BufferedOutputStream(new FileOutputStream(filePath)))) {
- exportBlocks(blockStore, writer);
+ exportBlocks(args, blockStore, writer);
}
-
- return 0;
}
- private void exportBlocks(BlockStore blockStore, PrintStream writer) {
+ private void exportBlocks(String[] args, BlockStore blockStore, PrintStream writer) {
+ long fromBlockNumber = Long.parseLong(args[0]);
+ long toBlockNumber = Long.parseLong(args[1]);
+
for (long n = fromBlockNumber; n <= toBlockNumber; n++) {
Block block = blockStore.getChainBlockByNumber(n);
BlockDifficulty totalDifficulty = blockStore.getTotalDifficultyForHash(block.getHash().getBytes());
diff --git a/rskj-core/src/main/java/co/rsk/cli/tools/ExportState.java b/rskj-core/src/main/java/co/rsk/cli/tools/ExportState.java
index 7ad69f65fd2..c26ba19ea99 100644
--- a/rskj-core/src/main/java/co/rsk/cli/tools/ExportState.java
+++ b/rskj-core/src/main/java/co/rsk/cli/tools/ExportState.java
@@ -17,18 +17,18 @@
*/
package co.rsk.cli.tools;
-import co.rsk.cli.PicoCliToolRskContextAware;
+import co.rsk.RskContext;
+import co.rsk.cli.CliToolRskContextAware;
import co.rsk.trie.NodeReference;
import co.rsk.trie.Trie;
import co.rsk.trie.TrieStore;
import org.ethereum.core.Block;
import org.ethereum.db.BlockStore;
import org.ethereum.util.ByteUtil;
-import picocli.CommandLine;
+import javax.annotation.Nonnull;
import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
-import java.io.IOException;
import java.io.PrintStream;
import java.lang.invoke.MethodHandles;
import java.util.Optional;
@@ -41,32 +41,26 @@
* - args[0] - block number
* - args[1] - file path
*/
-@CommandLine.Command(name = "export-state", mixinStandardHelpOptions = true, version = "export-state 1.0",
- description = "Exports state at specific block number to a file")
-public class ExportState extends PicoCliToolRskContextAware {
- @CommandLine.Option(names = {"-b", "--block"}, description = "Block number", required = true)
- private Long blockNumber;
-
- @CommandLine.Option(names = {"-f", "--file"}, description = "Path to a file to export state to", required = true)
- private String filePath;
+public class ExportState extends CliToolRskContextAware {
public static void main(String[] args) {
create(MethodHandles.lookup().lookupClass()).execute(args);
}
@Override
- public Integer call() throws IOException {
+ protected void onExecute(@Nonnull String[] args, @Nonnull RskContext ctx) throws Exception {
+ String filePath = args[1];
BlockStore blockStore = ctx.getBlockStore();
TrieStore trieStore = ctx.getTrieStore();
try (PrintStream writer = new PrintStream(new BufferedOutputStream(new FileOutputStream(filePath)))) {
- exportState(blockStore, trieStore, writer);
+ exportState(args, blockStore, trieStore, writer);
}
-
- return 0;
}
- private void exportState(BlockStore blockStore, TrieStore trieStore, PrintStream writer) {
+ private void exportState(String[] args, BlockStore blockStore, TrieStore trieStore, PrintStream writer) {
+ long blockNumber = Long.parseLong(args[0]);
+
Block block = blockStore.getChainBlockByNumber(blockNumber);
Optional otrie = trieStore.retrieve(block.getStateRoot());
diff --git a/rskj-core/src/main/java/co/rsk/cli/tools/GenerateOpenRpcDoc.java b/rskj-core/src/main/java/co/rsk/cli/tools/GenerateOpenRpcDoc.java
index 361eead5059..95ca6ca306d 100644
--- a/rskj-core/src/main/java/co/rsk/cli/tools/GenerateOpenRpcDoc.java
+++ b/rskj-core/src/main/java/co/rsk/cli/tools/GenerateOpenRpcDoc.java
@@ -17,7 +17,6 @@
*/
package co.rsk.cli.tools;
-import co.rsk.cli.exceptions.PicocliBadResultException;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
import com.fasterxml.jackson.databind.JavaType;
@@ -26,10 +25,11 @@
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.type.MapType;
import com.fasterxml.jackson.databind.type.TypeFactory;
+import com.google.common.annotations.VisibleForTesting;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import picocli.CommandLine;
+import javax.annotation.Nonnull;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
@@ -38,7 +38,6 @@
import java.util.HashMap;
import java.util.List;
import java.util.Map;
-import java.util.concurrent.Callable;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@@ -58,9 +57,7 @@
* args[2]: destination file containing the final OpenRPC json doc
*
*/
-@CommandLine.Command(name = "gen-rpc-docs", mixinStandardHelpOptions = true, version = "gen-rpc-docs 1.0",
- description = "Generates OpenRPC json doc file by merging a static template with several json files under {workdir}/doc/rpc dir")
-public class GenerateOpenRpcDoc implements Callable {
+public class GenerateOpenRpcDoc {
public static final JavaType TEMPLATE_DOC_TYPE = TypeFactory.defaultInstance().constructType(TemplateDoc.class);
private static final JavaType OBJECT_TYPE = TypeFactory.defaultInstance().constructType(Object.class);
@@ -68,41 +65,19 @@ public class GenerateOpenRpcDoc implements Callable {
private static final Logger logger = LoggerFactory.getLogger(GenerateOpenRpcDoc.class);
- @CommandLine.Option(names = {"-v", "--version"}, description = "RSKj version, will be present on final doc", required = true)
- private String version;
-
- @CommandLine.Option(names = {"-d", "--dir"}, description = "work directory where the json template and individual json files are present", required = true)
- private String dir;
-
- @CommandLine.Option(names = {"-o", "--outputFile"}, description = "destination file containing the final OpenRPC json doc", required = true)
- private String outputFile;
-
protected static final ObjectMapper JSON_MAPPER = new ObjectMapper()
.enable(SerializationFeature.INDENT_OUTPUT)
.enable(MapperFeature.SORT_PROPERTIES_ALPHABETICALLY);
- public GenerateOpenRpcDoc() {
- }
-
- public GenerateOpenRpcDoc(String version, String dir, String outputFile) {
- this.version = version;
- this.dir = dir;
- this.outputFile = outputFile;
- }
-
public static void main(String[] args) {
- int result = new CommandLine(new GenerateOpenRpcDoc()).setUnmatchedArgumentsAllowed(true).execute(args);
-
- if (result != 0) {
- throw new PicocliBadResultException(result);
- }
+ new GenerateOpenRpcDoc().execute(args);
}
- @Override
- public Integer call() {
- String version = this.version;
- String workDirPath = this.dir;
- String destPath = this.outputFile;
+ @VisibleForTesting
+ void execute(@Nonnull String[] args) {
+ String version = args[0];
+ String workDirPath = args[1];
+ String destPath = args[2];
TemplateDoc templateDoc = loadTemplate(workDirPath);
templateDoc.info.version = version;
@@ -111,8 +86,6 @@ public Integer call() {
templateDoc.components.contentDescriptors.putAll(loadContentDescriptors(workDirPath));
writeToFile(destPath, templateDoc);
-
- return 0;
}
private TemplateDoc loadTemplate(String workDirPath) {
diff --git a/rskj-core/src/main/java/co/rsk/cli/tools/ImportBlocks.java b/rskj-core/src/main/java/co/rsk/cli/tools/ImportBlocks.java
index 1176aaa0ae1..3dc742d9519 100644
--- a/rskj-core/src/main/java/co/rsk/cli/tools/ImportBlocks.java
+++ b/rskj-core/src/main/java/co/rsk/cli/tools/ImportBlocks.java
@@ -17,14 +17,15 @@
*/
package co.rsk.cli.tools;
-import co.rsk.cli.PicoCliToolRskContextAware;
+import co.rsk.RskContext;
+import co.rsk.cli.CliToolRskContextAware;
import co.rsk.core.BlockDifficulty;
import org.bouncycastle.util.encoders.Hex;
import org.ethereum.core.Block;
import org.ethereum.core.BlockFactory;
import org.ethereum.db.BlockStore;
-import picocli.CommandLine;
+import javax.annotation.Nonnull;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
@@ -38,27 +39,22 @@
* Required cli args:
* - args[0] - file path
*/
-@CommandLine.Command(name = "import-blocks", mixinStandardHelpOptions = true, version = "import-blocks 1.0",
- description = "Imports blocks from a file")
-public class ImportBlocks extends PicoCliToolRskContextAware {
-
- @CommandLine.Option(names = {"-f", "--file"}, description = "Path to a file to import blocks from", required = true)
- private String filePath;
+public class ImportBlocks extends CliToolRskContextAware {
public static void main(String[] args) {
create(MethodHandles.lookup().lookupClass()).execute(args);
}
@Override
- public Integer call() throws IOException {
+ protected void onExecute(@Nonnull String[] args, @Nonnull RskContext ctx) throws Exception {
BlockFactory blockFactory = ctx.getBlockFactory();
BlockStore blockStore = ctx.getBlockStore();
- try (BufferedReader reader = new BufferedReader(new FileReader(filePath))) {
+ String filename = args[0];
+
+ try (BufferedReader reader = new BufferedReader(new FileReader(filename))) {
importBlocks(blockFactory, blockStore, reader);
}
-
- return 0;
}
private void importBlocks(BlockFactory blockFactory, BlockStore blockStore, BufferedReader reader) throws IOException {
diff --git a/rskj-core/src/main/java/co/rsk/cli/tools/ImportState.java b/rskj-core/src/main/java/co/rsk/cli/tools/ImportState.java
index b9a453ea864..bf283f89b9e 100644
--- a/rskj-core/src/main/java/co/rsk/cli/tools/ImportState.java
+++ b/rskj-core/src/main/java/co/rsk/cli/tools/ImportState.java
@@ -17,14 +17,15 @@
*/
package co.rsk.cli.tools;
-import co.rsk.cli.PicoCliToolRskContextAware;
+import co.rsk.RskContext;
+import co.rsk.cli.CliToolRskContextAware;
import co.rsk.config.RskSystemProperties;
import co.rsk.crypto.Keccak256;
import org.bouncycastle.util.encoders.Hex;
import org.ethereum.crypto.Keccak256Helper;
import org.ethereum.datasource.KeyValueDataSource;
-import picocli.CommandLine;
+import javax.annotation.Nonnull;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
@@ -38,31 +39,26 @@
* Required cli args:
* - args[0] - file path
*/
-@CommandLine.Command(name = "import-state", mixinStandardHelpOptions = true, version = "import-state 1.0",
- description = "Imports state from a file")
-public class ImportState extends PicoCliToolRskContextAware {
- @CommandLine.Option(names = {"-f", "--file"}, description = "Path to a file to import state from", required = true)
- private String filePath;
-
+public class ImportState extends CliToolRskContextAware {
public static void main(String[] args) {
create(MethodHandles.lookup().lookupClass()).execute(args);
}
@Override
- public Integer call() throws IOException {
+ protected void onExecute(@Nonnull String[] args, @Nonnull RskContext ctx) throws Exception {
RskSystemProperties rskSystemProperties = ctx.getRskSystemProperties();
String databaseDir = rskSystemProperties.databaseDir();
KeyValueDataSource trieDB = KeyValueDataSource.makeDataSource(Paths.get(databaseDir, "unitrie"), rskSystemProperties.databaseKind());
- try (BufferedReader reader = new BufferedReader(new FileReader(filePath))) {
+ String filename = args[0];
+
+ try (BufferedReader reader = new BufferedReader(new FileReader(filename))) {
importState(reader, trieDB);
}
trieDB.flush();
trieDB.close();
-
- return 0;
}
private void importState(BufferedReader reader, KeyValueDataSource trieDB) throws IOException {
diff --git a/rskj-core/src/main/java/co/rsk/cli/tools/IndexBlooms.java b/rskj-core/src/main/java/co/rsk/cli/tools/IndexBlooms.java
index 96868e5def4..85e916e592a 100644
--- a/rskj-core/src/main/java/co/rsk/cli/tools/IndexBlooms.java
+++ b/rskj-core/src/main/java/co/rsk/cli/tools/IndexBlooms.java
@@ -18,7 +18,6 @@
package co.rsk.cli.tools;
import co.rsk.RskContext;
-import co.rsk.cli.exceptions.PicocliBadResultException;
import co.rsk.logfilter.BlocksBloom;
import co.rsk.logfilter.BlocksBloomStore;
import org.ethereum.core.Block;
@@ -26,71 +25,43 @@
import org.ethereum.db.BlockStore;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import picocli.CommandLine;
import javax.annotation.Nonnull;
-import java.io.IOException;
-import java.util.concurrent.Callable;
/**
* The entry point for indexing block blooms
* This is an experimental/unsupported tool
*/
-@CommandLine.Command(name = "index-blooms", mixinStandardHelpOptions = true, version = "index-blooms 1.0",
- description = "Indexes blooms for a specific block range")
-public class IndexBlooms implements Callable {
-
- @CommandLine.Option(names = {"-fb", "--fromBlock"}, description = "From block number", required = true)
- private String fromBlockNumber;
-
- @CommandLine.Option(names = {"-tb", "--toBlock"}, description = "To block number", required = true)
- private String toBlockNumber;
+public class IndexBlooms {
private static final Logger logger = LoggerFactory.getLogger(IndexBlooms.class);
private static final String EARLIEST = "earliest";
private static final String LATEST = "latest";
- private final RskContext ctx;
-
- public IndexBlooms(RskContext ctx) {
- this.ctx = ctx;
- }
-
public static void main(String[] args) {
- try (RskContext ctx = new RskContext(args, true)) {
- int result = new CommandLine(new IndexBlooms(ctx)).setUnmatchedArgumentsAllowed(true).execute(args);
+ try (RskContext ctx = new RskContext(args)) {
+ BlockStore blockStore = ctx.getBlockStore();
+ BlocksBloomStore blocksBloomStore = ctx.getBlocksBloomStore();
- if (result != 0) {
- throw new PicocliBadResultException(result);
- }
+ execute(makeBlockRange(args, blockStore), blockStore, blocksBloomStore);
}
}
- @Override
- public Integer call() throws IOException {
- BlockStore blockStore = ctx.getBlockStore();
- BlocksBloomStore blocksBloomStore = ctx.getBlocksBloomStore();
-
- execute(makeBlockRange(this.fromBlockNumber, this.toBlockNumber, blockStore), blockStore, blocksBloomStore);
-
- return 0;
- }
-
/**
* Creates a block range by extract from/to values from {@code args}.
*/
@Nonnull
- static Range makeBlockRange(String fromBlock, String toBlock, @Nonnull BlockStore blockStore) {
- if (fromBlock == null || toBlock == null) {
+ static Range makeBlockRange(@Nonnull String[] args, @Nonnull BlockStore blockStore) {
+ if (args.length < 2) {
throw new IllegalArgumentException("Missing 'from' and/or 'to' block number(s)");
}
long minNumber = blockStore.getMinNumber();
long maxNumber = blockStore.getMaxNumber();
- long fromBlockNumber = EARLIEST.equals(fromBlock) ? minNumber : Long.parseLong(fromBlock);
- long toBlockNumber = LATEST.equals(toBlock) ? maxNumber : Long.parseLong(toBlock);
+ long fromBlockNumber = EARLIEST.equals(args[0]) ? minNumber : Long.parseLong(args[0]);
+ long toBlockNumber = LATEST.equals(args[1]) ? maxNumber : Long.parseLong(args[1]);
if (fromBlockNumber < 0 || fromBlockNumber > toBlockNumber) {
throw new IllegalArgumentException("Invalid 'from' and/or 'to' block number");
diff --git a/rskj-core/src/main/java/co/rsk/cli/tools/RewindBlocks.java b/rskj-core/src/main/java/co/rsk/cli/tools/RewindBlocks.java
index c3284266ffe..dcf9abbe4d5 100644
--- a/rskj-core/src/main/java/co/rsk/cli/tools/RewindBlocks.java
+++ b/rskj-core/src/main/java/co/rsk/cli/tools/RewindBlocks.java
@@ -17,16 +17,15 @@
*/
package co.rsk.cli.tools;
-import co.rsk.cli.PicoCliToolRskContextAware;
+import co.rsk.RskContext;
+import co.rsk.cli.CliToolRskContextAware;
import co.rsk.crypto.Keccak256;
import co.rsk.db.RepositoryLocator;
import com.google.common.annotations.VisibleForTesting;
import org.ethereum.core.Block;
import org.ethereum.db.BlockStore;
-import picocli.CommandLine;
import javax.annotation.Nonnull;
-import java.io.IOException;
import java.lang.invoke.MethodHandles;
import java.util.Objects;
import java.util.Optional;
@@ -43,22 +42,7 @@
* - "fmi" option can be used for finding minimum inconsistent block number and printing it to stdout. It'll print -1, if no such block is found;
* - "rbc" option does two things: it looks for minimum inconsistent block and, if there's such, rewinds blocks from top one till the found one inclusively.
*/
-@CommandLine.Command(name = "rewindblocks", mixinStandardHelpOptions = true, version = "rewindblocks 1.0",
- description = "The entry point for rewind blocks state CLI tool")
-public class RewindBlocks extends PicoCliToolRskContextAware {
- static class RewindOpts {
- @CommandLine.Option(names = {"-b", "--block"}, description = "block number to rewind blocks to")
- public Long blockNum;
-
- @CommandLine.Option(names = {"-fmi", "--findMinInconsistentBlock"}, description = "flag to find a min inconsistent block", defaultValue = "false")
- public Boolean findMinInconsistentBlock;
-
- @CommandLine.Option(names = {"-rbc", "--rewindToBestConsistentBlock"}, description = "flag to rewind to a best consistent block", defaultValue = "false")
- public Boolean rewindToBestConsistentBlock;
- }
-
- @CommandLine.ArgGroup(multiplicity = "1")
- private RewindOpts opts;
+public class RewindBlocks extends CliToolRskContextAware {
public static void main(String[] args) {
create(MethodHandles.lookup().lookupClass()).execute(args);
@@ -77,22 +61,23 @@ public RewindBlocks() { // used via reflection
}
@Override
- public Integer call() throws IOException {
+ protected void onExecute(@Nonnull String[] args, @Nonnull RskContext ctx) {
BlockStore blockStore = ctx.getBlockStore();
+ String blockNumOrOp = args[0];
- if (opts.findMinInconsistentBlock) {
+ if ("fmi".equals(blockNumOrOp)) {
RepositoryLocator repositoryLocator = ctx.getRepositoryLocator();
printMinInconsistentBlock(blockStore, repositoryLocator);
- } else if (opts.rewindToBestConsistentBlock) {
+ } else if ("rbc".equals(blockNumOrOp)) {
RepositoryLocator repositoryLocator = ctx.getRepositoryLocator();
rewindInconsistentBlocks(blockStore, repositoryLocator);
} else {
- rewindBlocks(opts.blockNum, blockStore);
- }
+ long blockNumber = Long.parseLong(blockNumOrOp);
- return 0;
+ rewindBlocks(blockNumber, blockStore);
+ }
}
private void printMinInconsistentBlock(@Nonnull BlockStore blockStore, @Nonnull RepositoryLocator repositoryLocator) {
diff --git a/rskj-core/src/main/java/co/rsk/cli/tools/ShowStateInfo.java b/rskj-core/src/main/java/co/rsk/cli/tools/ShowStateInfo.java
index 55ca487f8bc..19d924f2e5a 100644
--- a/rskj-core/src/main/java/co/rsk/cli/tools/ShowStateInfo.java
+++ b/rskj-core/src/main/java/co/rsk/cli/tools/ShowStateInfo.java
@@ -17,7 +17,8 @@
*/
package co.rsk.cli.tools;
-import co.rsk.cli.PicoCliToolRskContextAware;
+import co.rsk.RskContext;
+import co.rsk.cli.CliToolRskContextAware;
import co.rsk.trie.NodeReference;
import co.rsk.trie.Trie;
import co.rsk.trie.TrieStore;
@@ -25,10 +26,8 @@
import org.ethereum.core.Block;
import org.ethereum.db.BlockStore;
import org.ethereum.util.ByteUtil;
-import picocli.CommandLine;
import javax.annotation.Nonnull;
-import java.io.IOException;
import java.lang.invoke.MethodHandles;
import java.util.Objects;
import java.util.Optional;
@@ -40,12 +39,7 @@
* Required cli args:
* - args[0] - block number or "best"
*/
-@CommandLine.Command(name = "show-state-info", mixinStandardHelpOptions = true, version = "show-state-info 1.0",
- description = "Shows state information for a specific block number")
-public class ShowStateInfo extends PicoCliToolRskContextAware {
-
- @CommandLine.Option(names = {"-b", "--block"}, description = "block number or \"best\"", required = true)
- private String blockNum;
+public class ShowStateInfo extends CliToolRskContextAware {
public static void main(String[] args) {
create(MethodHandles.lookup().lookupClass()).execute(args);
@@ -64,25 +58,23 @@ public ShowStateInfo() { // used via reflection
}
@Override
- public Integer call() throws IOException {
+ protected void onExecute(@Nonnull String[] args, @Nonnull RskContext ctx) throws Exception {
BlockStore blockStore = ctx.getBlockStore();
TrieStore trieStore = ctx.getTrieStore();
- printStateInfo(blockStore, trieStore);
-
- return 0;
+ printStateInfo(args, blockStore, trieStore);
}
- private void printStateInfo(BlockStore blockStore, TrieStore trieStore) throws NumberFormatException {
+ private void printStateInfo(String[] args, BlockStore blockStore, TrieStore trieStore) {
StateInfo stateInfo = new StateInfo();
Block block;
- if ("best".equals(blockNum)) {
+ if ("best".equals(args[0])) {
block = blockStore.getBestBlock();
}
else {
- block = blockStore.getChainBlockByNumber(Long.parseLong(blockNum));
+ block = blockStore.getChainBlockByNumber(Long.parseLong(args[0]));
}
printer.println("Block number: " + block.getNumber());
diff --git a/rskj-core/src/main/java/co/rsk/cli/tools/StartBootstrap.java b/rskj-core/src/main/java/co/rsk/cli/tools/StartBootstrap.java
index b2d93b0ca29..2c31b6f7842 100644
--- a/rskj-core/src/main/java/co/rsk/cli/tools/StartBootstrap.java
+++ b/rskj-core/src/main/java/co/rsk/cli/tools/StartBootstrap.java
@@ -19,7 +19,6 @@
import co.rsk.NodeRunner;
import co.rsk.RskContext;
-import co.rsk.cli.exceptions.PicocliBadResultException;
import co.rsk.config.InternalService;
import co.rsk.config.RskSystemProperties;
import co.rsk.net.discovery.UDPServer;
@@ -27,13 +26,10 @@
import co.rsk.util.PreflightChecksUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import picocli.CommandLine;
import javax.annotation.Nonnull;
-import java.io.IOException;
import java.util.Collections;
import java.util.List;
-import java.util.concurrent.Callable;
/**
* Entry point of RSK bootstrap node.
@@ -43,38 +39,19 @@
*
* Note: this is an experimental tool
*/
-@CommandLine.Command(name = "start-bootstrap", mixinStandardHelpOptions = true, version = "start-bootstrap 1.0",
- description = "Starts a bootstrap node with one service, which only participates in the peer discovery protocol")
-public class StartBootstrap implements Callable {
+public class StartBootstrap {
private static final Logger logger = LoggerFactory.getLogger("bootstrap");
- private final RskContext ctx;
-
- public StartBootstrap(RskContext ctx) {
- this.ctx = ctx;
- }
-
public static void main(String[] args) {
setUpThread(Thread.currentThread());
- try (RskContext ctx = new BootstrapRskContext(args)) {
- int result = new CommandLine(new StartBootstrap(ctx)).setUnmatchedArgumentsAllowed(true).execute(args);
-
- if (result != 0) {
- throw new PicocliBadResultException(result);
- }
- }
- }
-
- @Override
- public Integer call() throws IOException {
+ RskContext ctx = new BootstrapRskContext(args);
PreflightChecksUtils preflightChecks = new PreflightChecksUtils(ctx);
Runtime runtime = Runtime.getRuntime();
NodeStopper nodeStopper = System::exit;
runBootstrapNode(ctx, preflightChecks, runtime, nodeStopper);
- return 0;
}
static void runBootstrapNode(@Nonnull RskContext ctx,
@@ -111,7 +88,7 @@ static void setUpThread(@Nonnull Thread thread) {
static class BootstrapRskContext extends RskContext {
BootstrapRskContext(String[] args) {
- super(args, true);
+ super(args);
}
@Override
diff --git a/rskj-core/src/test/java/co/rsk/cli/tools/CliToolsTest.java b/rskj-core/src/test/java/co/rsk/cli/tools/CliToolsTest.java
index 8dccbb72358..e9fc458a7b9 100644
--- a/rskj-core/src/test/java/co/rsk/cli/tools/CliToolsTest.java
+++ b/rskj-core/src/test/java/co/rsk/cli/tools/CliToolsTest.java
@@ -19,7 +19,6 @@
import co.rsk.NodeRunner;
import co.rsk.RskContext;
-import co.rsk.cli.PicoCliToolRskContextAware;
import co.rsk.config.RskSystemProperties;
import co.rsk.config.TestSystemProperties;
import co.rsk.core.BlockDifficulty;
@@ -59,8 +58,6 @@
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;
import org.mockito.ArgumentCaptor;
-import org.mockito.Mockito;
-import picocli.CommandLine;
import java.io.*;
import java.nio.charset.StandardCharsets;
@@ -92,7 +89,7 @@ void exportBlocks() throws IOException, DslProcessorException {
processor.processCommands(parser);
File blocksFile = tempDir.resolve( "blocks.txt").toFile();
- String[] args = new String[]{"--fromBlock", "0", "--toBlock", "2", "--file", blocksFile.getAbsolutePath()};
+ String[] args = new String[]{"0", "2", blocksFile.getAbsolutePath()};
RskContext rskContext = mock(RskContext.class);
RskSystemProperties rskSystemProperties = mock(RskSystemProperties.class);
@@ -130,7 +127,7 @@ void exportState() throws IOException, DslProcessorException {
processor.processCommands(parser);
File stateFile = tempDir.resolve("state.txt").toFile();
- String[] args = new String[]{"--block", "2", "--file", stateFile.getAbsolutePath()};
+ String[] args = new String[]{"2", stateFile.getAbsolutePath()};
RskContext rskContext = mock(RskContext.class);
RskSystemProperties rskSystemProperties = mock(RskSystemProperties.class);
@@ -170,7 +167,7 @@ void showStateInfo() throws FileNotFoundException, DslProcessorException {
WorldDslProcessor processor = new WorldDslProcessor(world);
processor.processCommands(parser);
- String[] args = new String[]{"--block", "best"};
+ String[] args = new String[]{"best"};
RskContext rskContext = mock(RskContext.class);
RskSystemProperties rskSystemProperties = mock(RskSystemProperties.class);
@@ -207,7 +204,7 @@ void executeBlocks() throws FileNotFoundException, DslProcessorException {
WorldDslProcessor processor = new WorldDslProcessor(world);
processor.processCommands(parser);
- String[] args = new String[]{"--fromBlock", "1", "--toBlock", "2"};
+ String[] args = new String[]{"1", "2"};
RskContext rskContext = mock(RskContext.class);
RskSystemProperties rskSystemProperties = mock(RskSystemProperties.class);
@@ -261,7 +258,7 @@ void connectBlocks() throws IOException, DslProcessorException {
writer.write(stringBuilder.toString());
}
- String[] args = new String[]{"--file", blocksFile.getAbsolutePath()};
+ String[] args = new String[]{blocksFile.getAbsolutePath()};
RskContext rskContext = mock(RskContext.class);
RskSystemProperties rskSystemProperties = mock(RskSystemProperties.class);
@@ -318,7 +315,7 @@ void importBlocks() throws IOException, DslProcessorException {
writer.write(stringBuilder.toString());
}
- String[] args = new String[]{"--file", blocksFile.getAbsolutePath()};
+ String[] args = new String[]{blocksFile.getAbsolutePath()};
RskContext rskContext = mock(RskContext.class);
RskSystemProperties rskSystemProperties = mock(RskSystemProperties.class);
@@ -354,7 +351,7 @@ void importState() throws IOException {
}
String databaseDir = tempDir.resolve( "db").toAbsolutePath().toString();
- String[] args = new String[]{"--file", stateFile.getAbsolutePath()};
+ String[] args = new String[]{stateFile.getAbsolutePath()};
RskContext rskContext = mock(RskContext.class);
RskSystemProperties rskSystemProperties = mock(RskSystemProperties.class);
@@ -419,7 +416,7 @@ void rewindBlocks() {
StringBuilder output = new StringBuilder();
RewindBlocks rewindBlocksCliTool = new RewindBlocks(output::append);
- rewindBlocksCliTool.execute(new String[]{"-fmi"}, () -> rskContext, stopper);
+ rewindBlocksCliTool.execute(new String[]{"fmi"}, () -> rskContext, stopper);
String data = output.toString();
Assertions.assertTrue(data.contains("No inconsistent block has been found"));
@@ -432,7 +429,7 @@ void rewindBlocks() {
output = new StringBuilder();
rewindBlocksCliTool = new RewindBlocks(output::append);
- rewindBlocksCliTool.execute(new String[]{"--block", String.valueOf(blockToRewind)}, () -> rskContext, stopper);
+ rewindBlocksCliTool.execute(new String[]{String.valueOf(blockToRewind)}, () -> rskContext, stopper);
bestBlock = indexedBlockStore.getBestBlock();
MatcherAssert.assertThat(bestBlock.getNumber(), is(blockToRewind));
@@ -446,7 +443,7 @@ void rewindBlocks() {
output = new StringBuilder();
rewindBlocksCliTool = new RewindBlocks(output::append);
- rewindBlocksCliTool.execute(new String[]{"--block", String.valueOf(blocksToGenerate + 1)}, () -> rskContext, stopper);
+ rewindBlocksCliTool.execute(new String[]{String.valueOf(blocksToGenerate + 1)}, () -> rskContext, stopper);
bestBlock = indexedBlockStore.getBestBlock();
MatcherAssert.assertThat(bestBlock.getNumber(), is(blockToRewind));
@@ -462,7 +459,7 @@ void rewindBlocks() {
output = new StringBuilder();
rewindBlocksCliTool = new RewindBlocks(output::append);
- rewindBlocksCliTool.execute(new String[]{"-fmi"}, () -> rskContext, stopper);
+ rewindBlocksCliTool.execute(new String[]{"fmi"}, () -> rskContext, stopper);
data = output.toString();
Assertions.assertTrue(data.contains("Min inconsistent block number: 0"));
@@ -473,7 +470,7 @@ void rewindBlocks() {
output = new StringBuilder();
rewindBlocksCliTool = new RewindBlocks(output::append);
- rewindBlocksCliTool.execute(new String[]{"-rbc"}, () -> rskContext, stopper);
+ rewindBlocksCliTool.execute(new String[]{"rbc"}, () -> rskContext, stopper);
data = output.toString();
Assertions.assertTrue(data.contains("Min inconsistent block number: 0"));
@@ -506,7 +503,7 @@ void dbMigrate() throws IOException {
NodeStopper stopper = mock(NodeStopper.class);
DbMigrate dbMigrateCliTool = new DbMigrate();
- dbMigrateCliTool.execute(new String[]{"-t", "rocksdb"}, () -> rskContext, stopper);
+ dbMigrateCliTool.execute(new String[]{"rocksdb"}, () -> rskContext, stopper);
String nodeIdPropsFileLine = null;
@@ -577,29 +574,29 @@ void makeBlockRange() {
doReturn(10L).when(blockStore).getMaxNumber();
try {
- IndexBlooms.makeBlockRange(null, null, blockStore);
+ IndexBlooms.makeBlockRange(new String[]{}, blockStore);
fail();
} catch (IllegalArgumentException ignored) { /* ignored */ }
try {
- IndexBlooms.makeBlockRange("0", null, blockStore);
+ IndexBlooms.makeBlockRange(new String[]{"0"}, blockStore);
fail();
} catch (IllegalArgumentException ignored) { /* ignored */ }
try {
- IndexBlooms.makeBlockRange("0", "abc", blockStore);
+ IndexBlooms.makeBlockRange(new String[]{"0", "abc"}, blockStore);
fail();
} catch (NumberFormatException ignored) { /* ignored */ }
try {
- IndexBlooms.makeBlockRange("-1", "1", blockStore);
+ IndexBlooms.makeBlockRange(new String[]{"-1", "1"}, blockStore);
fail();
} catch (IllegalArgumentException e) {
assertEquals("Invalid 'from' and/or 'to' block number", e.getMessage());
}
try {
- IndexBlooms.makeBlockRange("2", "1", blockStore);
+ IndexBlooms.makeBlockRange(new String[]{"2", "1"}, blockStore);
fail();
} catch (IllegalArgumentException e) {
assertEquals("Invalid 'from' and/or 'to' block number", e.getMessage());
@@ -608,20 +605,20 @@ void makeBlockRange() {
doReturn(2L).when(blockStore).getMinNumber();
try {
- IndexBlooms.makeBlockRange("1", "10", blockStore); // min block num is 10
+ IndexBlooms.makeBlockRange(new String[]{"1", "10"}, blockStore); // min block num is 10
fail();
} catch (IllegalArgumentException e) {
assertEquals("'from' block number is lesser than the min block number stored", e.getMessage());
}
try {
- IndexBlooms.makeBlockRange("5", "11", blockStore); // best block num is 10
+ IndexBlooms.makeBlockRange(new String[]{"5", "11"}, blockStore); // best block num is 10
fail();
} catch (IllegalArgumentException e) {
assertEquals("'to' block number is greater than the best block number", e.getMessage());
}
- IndexBlooms.Range range = IndexBlooms.makeBlockRange("5", "10", blockStore);
+ IndexBlooms.Range range = IndexBlooms.makeBlockRange(new String[]{"5", "10"}, blockStore);
assertEquals(5, range.fromBlockNumber);
assertEquals(10, range.toBlockNumber);
@@ -683,14 +680,12 @@ void generateOpenRpcDoc() throws IOException {
File workDir = new File(classLoader.getResource("doc/rpc").getFile());
File destFile = tempDir.resolve( "generated_openrpc.json").toFile();
- GenerateOpenRpcDoc generateOpenRpcDocCliTool = new GenerateOpenRpcDoc(
- version,
- workDir.getAbsolutePath(),
- destFile.getAbsolutePath()
- );
+ GenerateOpenRpcDoc generateOpenRpcDocCliTool = new GenerateOpenRpcDoc();
+
+ String[] args = new String[]{version, workDir.getAbsolutePath(), destFile.getAbsolutePath()};
try {
- generateOpenRpcDocCliTool.call();
+ generateOpenRpcDocCliTool.execute(args);
} catch (RuntimeException e) {
fail("should have not thrown " + e.getMessage());
}
@@ -706,32 +701,4 @@ void generateOpenRpcDoc() throws IOException {
assertEquals(expected, actual);
}
-
- @Test
- public void testErrorHandlingInPicocli() {
- RskContext rskContext = mock(RskContext.class);
- RskSystemProperties rskSystemProperties = mock(RskSystemProperties.class);
-
- doReturn(DbKind.LEVEL_DB).when(rskSystemProperties).databaseKind();
- doReturn(tempDir.getRoot().toFile().getPath()).when(rskSystemProperties).databaseDir();
- doReturn(true).when(rskSystemProperties).databaseReset();
- doReturn(rskSystemProperties).when(rskContext).getRskSystemProperties();
-
- NodeStopper stopper = mock(NodeStopper.class);
-
- @CommandLine.Command(name = "dummy-tool", mixinStandardHelpOptions = true, version = "1.0",
- description = "This is just a dummy tool")
- class DummyCliTool extends PicoCliToolRskContextAware {
- @Override
- public Integer call() {
- return -1;
- }
- }
-
- DummyCliTool dummyTool = new DummyCliTool();
-
- dummyTool.execute(new String[]{}, () -> rskContext, stopper);
-
- verify(stopper, times(1)).stop(Mockito.eq(1));
- }
}