Skip to content

Commit

Permalink
Using Argparse4j for Command Line Arguments Parsing
Browse files Browse the repository at this point in the history
  • Loading branch information
amengus87 committed May 27, 2024
1 parent fe4aa2e commit 5d51bb6
Show file tree
Hide file tree
Showing 6 changed files with 123 additions and 18 deletions.
1 change: 1 addition & 0 deletions backend/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ dependencies {
implementation 'org.dizitart:nitrite-mvstore-adapter'
implementation 'org.dizitart:nitrite-jackson-mapper'
implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.5.0'
implementation 'net.sourceforge.argparse4j:argparse4j:0.9.0'
developmentOnly("org.springframework.boot:spring-boot-devtools")
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
Expand Down
5 changes: 5 additions & 0 deletions backend/checkstyle.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@
<module name="Checker">
<property name="charset" value="UTF-8"/>
<module name="TreeWalker">
<module name="UnusedImports"/>
<module name="RedundantImport"/>
<module name="AvoidStarImport"/>
<module name="AvoidStaticImport"/>
<module name="IllegalImport"/>
<module name="CommentsIndentation"/>
<module name="PackageDeclaration"/>
<module name="AvoidStarImport"/>
Expand Down
30 changes: 15 additions & 15 deletions backend/src/main/java/ai/dragon/command/DatabaseExportCommand.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,33 +3,33 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;

import ai.dragon.enumeration.CommandLineExecutionResultType;
import ai.dragon.service.DatabaseService;
import ai.dragon.util.CommandLineRunnerWithArgumentsParser;
import net.sourceforge.argparse4j.inf.ArgumentParser;
import net.sourceforge.argparse4j.inf.Namespace;

@Component
public class DatabaseExportCommand implements ApplicationRunner {
public class DatabaseExportCommand extends CommandLineRunnerWithArgumentsParser {
private final Logger logger = LoggerFactory.getLogger(this.getClass());

@Autowired
private DatabaseService databaseService;

@Override
public void run(ApplicationArguments args) throws Exception {
if (args.containsOption("command") && args.containsOption("database-export")) {
logger.info("Database export command received");

if(!args.containsOption("output")) {
logger.error("Database export path not provided : --output=/tmp/dump.json");
System.exit(1);
}
public CommandLineExecutionResultType runCommand(String... args) throws Exception {
ArgumentParser parser = this.parserFor("database-export", "Dump the database to a file.");
parser.addArgument("--output")
.type(String.class)
.required(true)
.help("The output file path to export the database to.");

databaseService.exportDatabase(args.getOptionValues("output").get(0));
logger.info("Database export completed to : " + args.getOptionValues("output").get(0));
Namespace ns = parser.parseArgs(args);
databaseService.exportDatabase(ns.getString("output"));
logger.info("Database export completed to : " + ns.getString("output"));

System.exit(0);
}
return CommandLineExecutionResultType.EXECUTED;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package ai.dragon.enumeration;

public enum CommandLineExecutionResultType {
EXECUTED,
BYPASS,
ERROR
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
package ai.dragon.util;

import java.util.Arrays;
import java.util.Iterator;
import java.util.List;

import org.springframework.boot.CommandLineRunner;

import ai.dragon.enumeration.CommandLineExecutionResultType;
import net.sourceforge.argparse4j.ArgumentParsers;
import net.sourceforge.argparse4j.helper.HelpScreenException;
import net.sourceforge.argparse4j.inf.ArgumentParser;
import net.sourceforge.argparse4j.inf.ArgumentParserException;

public abstract class CommandLineRunnerWithArgumentsParser implements CommandLineRunner {
public abstract CommandLineExecutionResultType runCommand(String... args) throws Exception;

private String commandName;
private ArgumentParser parser;

public void run(String... args) throws Exception {
CommandLineExecutionResultType executionResult = null;

try {
executionResult = this.runCommand(args);
} catch (ArgumentParserException e) {
if (parser == null) {
throw e;
}

executionResult = this.handleError(parser, e, args);
}

switch (executionResult) {
case BYPASS:
return;
case ERROR:
System.exit(1);
case EXECUTED:
System.exit(0);
}
}

public CommandLineExecutionResultType handleError(ArgumentParser parser, ArgumentParserException parentException,
String... args) {
if (parentException instanceof HelpScreenException) {
return CommandLineExecutionResultType.EXECUTED;
}

String command = getCommandFromArgs(args);
if (commandName == null || !commandName.equals(command)) {
return CommandLineExecutionResultType.BYPASS;
}

parser.handleError(parentException);
return CommandLineExecutionResultType.ERROR;
}

public ArgumentParser parserFor(String command, String description) {
this.commandName = command;

parser = ArgumentParsers.newFor(command).build()
.defaultHelp(true)
.description("Dump the database to a file.");
parser.addArgument("--command")
.type(String.class)
.required(true)
.choices(command)
.help("Specify the command to launch");

return parser;
}

private String getCommandFromArgs(String... args) {
List<String> argsList = Arrays.asList(args);
Iterator<String> it = argsList.iterator();

while (it.hasNext()) {
String arg = it.next();
if (arg.startsWith("--command")) {
String[] argAndValue = arg.split("=");
if (argAndValue.length > 1) {
return argAndValue[1];
} else if (it.hasNext()) {
return it.next();
}
}
}

return null;
}
}
6 changes: 3 additions & 3 deletions docs/docs/commands/database-export.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,17 @@ This command should only be used when the backend server is offline. Running thi

### Using Gradle
```bash
gradle bootRun --args="--command --database-export --output=/path/to/dump.json"
gradle bootRun --args="--command=database-export --output=/path/to/dump.json"
```

### Using Java
```bash
java -jar backend.jar --command --database-export --output=/path/to/dump.json
java -jar backend.jar --command=database-export --output=/path/to/dump.json
```

### Using Docker
```bash
docker run -v /path/to/output:/output dragon --command --database-export --output=/output/dump.json
docker run -v /path/to/output:/output dragon --command=database-export --output=/output/dump.json
```

## Online Export
Expand Down

0 comments on commit 5d51bb6

Please sign in to comment.