From d8e895d8e63676cde4b3c9fd06c376c53897e31d Mon Sep 17 00:00:00 2001 From: "minh.q.nguyen" Date: Thu, 17 Mar 2022 10:06:34 +0700 Subject: [PATCH] - refactor --- Dockerfile | 2 +- Dockerfile.graalvm | 9 -- pom.xml | 2 +- src/main/java/org/nqm/GisCommand.java | 61 +++++------ src/main/java/org/nqm/GitWrapper.java | 101 +++++++++--------- src/main/java/org/nqm/enums/GisAction.java | 24 +++++ src/main/java/org/nqm/enums/GisOption.java | 7 -- .../java/org/nqm/utils/ExceptionUtils.java | 12 +-- .../java/org/nqm/vertx/CommandVerticle.java | 90 ++++++++-------- src/main/java/org/nqm/vertx/GisVertx.java | 20 ++-- 10 files changed, 165 insertions(+), 163 deletions(-) delete mode 100644 Dockerfile.graalvm create mode 100644 src/main/java/org/nqm/enums/GisAction.java delete mode 100644 src/main/java/org/nqm/enums/GisOption.java diff --git a/Dockerfile b/Dockerfile index ac2f8b7..3a1d4d0 100644 --- a/Dockerfile +++ b/Dockerfile @@ -10,7 +10,7 @@ RUN ./mvnw verify clean --fail-never COPY . /app/gis RUN ./mvnw clean package -RUN native-image -cp target/gis-1.0.0.jar "org.nqm.GisCommand" \ +RUN native-image -cp target/gis-*.jar "org.nqm.GisCommand" \ --no-fallback \ --no-server \ --allow-incomplete-classpath \ diff --git a/Dockerfile.graalvm b/Dockerfile.graalvm deleted file mode 100644 index 66f7ba4..0000000 --- a/Dockerfile.graalvm +++ /dev/null @@ -1,9 +0,0 @@ -FROM ghcr.io/graalvm/native-image:ol8-java17 - -COPY . /home/app/gis -WORKDIR /home/app/gis - -RUN ./mvnw clean package -RUN native-image -cp target/gis-1.0.0.jar "org.nqm.GisCommand" -RUN mv org.nqm.giscommand gis -RUN chmod +x gis diff --git a/pom.xml b/pom.xml index 5498899..fc9c0f7 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ 4.0.0 org.nqm gis - 1.0.0 + 1.0.0-alpha ${packaging} diff --git a/src/main/java/org/nqm/GisCommand.java b/src/main/java/org/nqm/GisCommand.java index ef63165..6c08e10 100644 --- a/src/main/java/org/nqm/GisCommand.java +++ b/src/main/java/org/nqm/GisCommand.java @@ -4,51 +4,44 @@ import static org.nqm.GitWrapper.fetch; import static org.nqm.GitWrapper.pull; import static org.nqm.GitWrapper.status; -import org.nqm.enums.GisOption; +import org.nqm.enums.GisAction; import java.util.Optional; import picocli.CommandLine; import picocli.CommandLine.Command; +import picocli.CommandLine.Option; import picocli.CommandLine.Parameters; @Command( - name = "gis", - description = "Git extension which supports submodules", - mixinStandardHelpOptions = true, - version = "1.0.0") + name = "gis", + description = "Git extension which supports submodules", + mixinStandardHelpOptions = true, + version = "1.0.0-alpha") public class GisCommand implements Runnable { - @Parameters(index = "0", description = "Valid values: ${COMPLETION-CANDIDATES}") - GisOption option; + @Parameters(index = "0", description = "Valid values: ${COMPLETION-CANDIDATES}") + GisAction action; - @Parameters(index = "1", arity = "0..1") - String value; + @Parameters(index = "1", arity = "0..1") + Optional value; - public static void main(String[] args) { - // System.exit(new CommandLine(new GisCommand()).execute(args)); - new CommandLine(new GisCommand()).execute(args); - } + @Option(names = "-v", description = "verbose") + boolean isDebugEnabled; + + public static void main(String[] args) { + var cmd = new CommandLine(new GisCommand()); + // cmd.setCaseInsensitiveEnumValuesAllowed(true); + cmd.execute(args); + } - @Override - public void run() { - switch (option) { - case co: - Optional.ofNullable(value) - .ifPresentOrElse( - GitWrapper::checkOut, - () -> err.println("Please specified branch name!")); - break; - case st: - status(); - break; - case fe: - fetch(); - break; - case pu: - pull(); - break; - default: - status(); - } + @Override + public void run() { + switch (action) { + case co -> value.ifPresentOrElse(GitWrapper::checkOut, () -> err.println("Please specify branch!")); + case fe -> fetch(); + case pu -> pull(); + case st -> status(); + default -> status(); } + } } diff --git a/src/main/java/org/nqm/GitWrapper.java b/src/main/java/org/nqm/GitWrapper.java index c9a306c..57ef4b5 100644 --- a/src/main/java/org/nqm/GitWrapper.java +++ b/src/main/java/org/nqm/GitWrapper.java @@ -13,69 +13,70 @@ final class GitWrapper { - private static final String GIT = "/usr/bin/git %s"; + private static final String GIT = "/usr/bin/git %s"; - private static final String CURRENT_DIR = System.getProperty("user.dir"); + private static final String CURRENT_DIR = System.getProperty("user.dir"); - private GitWrapper() {} + private GitWrapper() {} - public static void status() { - run(path -> call(path, "status -sb --ignore-submodules"), err::println); - } + public static void status() { + run(path -> call(path, "status -sb --ignore-submodules"), err::println); + } - public static void fetch() { - run(path -> call(path, "fetch"), err::println); - } + public static void fetch() { + run(path -> call(path, "fetch"), err::println); + } - public static void pull() { - run(path -> call(path, "pull"), err::println); - } + public static void pull() { + run(path -> call(path, "pull"), err::println); + } - public static void checkOut(String branch) { - run(path -> call(path, "checkout %s".formatted(branch)), - () -> err.println("Could not checkout branch '%s'".formatted(branch))); - } + public static void checkOut(String branch) { + run(path -> call(path, "checkout %s".formatted(branch)), + () -> err.println("Could not checkout branch '%s'".formatted(branch))); + } - public static void checkOutNewBranch(String branch) { - run(path -> call(path, "checkout -b %s".formatted(branch)), err::println); - } + public static void checkOutNewBranch(String branch) { + run(path -> call(path, "checkout -b %s".formatted(branch)), err::println); + } - private static void run(Function consume, Runnable errHandling) { - var gitModulesFilePath = Path.of(".", ".gitmodules"); - if (!gitModulesFilePath.toFile().exists()) { - out.println("There is no git submodules under this directory!"); - return; - } - - var vertx = GisVertx.instance(); - vertx.fileSystem().readFile(gitModulesFilePath.toString()) - .map(GitWrapper::extractDirs) - .onComplete((AsyncResult> ar) -> { - if (ar.succeeded()) { - ar.result().forEach(dir -> vertx.executeBlocking((Promise p) -> p.complete(consume.apply(Path.of(CURRENT_DIR, dir))))); - vertx.executeBlocking((Promise p) -> p.complete(consume.apply(Path.of(CURRENT_DIR)))); - } - else { - err.println("failed to read file"); - System.exit(1); - } - }); + private static void run(Function consume, Runnable errHandling) { + var gitModulesFilePath = Path.of(".", ".gitmodules"); + if (!gitModulesFilePath.toFile().exists()) { + out.println("There is no git submodules under this directory!"); + return; } - private static Void call(Path path, String command) { - if (!path.toFile().exists()) { - return null; + var vertx = GisVertx.instance(); + vertx.fileSystem().readFile(gitModulesFilePath.toString()) + .map(GitWrapper::extractDirs) + .onComplete((AsyncResult> ar) -> { + if (ar.succeeded()) { + ar.result().forEach(dir -> vertx.executeBlocking( + (Promise p) -> p.complete(consume.apply(Path.of(CURRENT_DIR, dir))))); + vertx.executeBlocking((Promise p) -> p.complete(consume.apply(Path.of(CURRENT_DIR)))); } - GisVertx.instance().deployVerticle(new CommandVerticle(GIT, command, path)); - return null; - } + else { + err.println("failed to read file"); + System.exit(1); + } + }); + } - private static Stream extractDirs(Buffer buffer) { - return Stream.of(buffer.toString().split("\n")) - .map(String::trim) - .filter(s -> s.startsWith("path")) - .map(s -> s.replace("path = ", "")); + private static Void call(Path path, String command) { + if (!path.toFile().exists()) { + return null; } + GisVertx.instance().deployVerticle(new CommandVerticle(GIT, command, path)); + return null; + } + + private static Stream extractDirs(Buffer buffer) { + return Stream.of(buffer.toString().split("\n")) + .map(String::trim) + .filter(s -> s.startsWith("path")) + .map(s -> s.replace("path = ", "")); + } } diff --git a/src/main/java/org/nqm/enums/GisAction.java b/src/main/java/org/nqm/enums/GisAction.java new file mode 100644 index 0000000..e2c42d5 --- /dev/null +++ b/src/main/java/org/nqm/enums/GisAction.java @@ -0,0 +1,24 @@ +package org.nqm.enums; + +public enum GisAction { + + co("checkout"), st("status"), fe("fetch"), pu("pull"), push("push"); + + private String fullAction; + + GisAction(String fullAction) { + this.fullAction = fullAction; + } + + // public static GisAction map(String action) { + // return Stream.of(GisAction.values()) + // .filter(e -> e.getFullAction().equals(action)) + // .findFirst() + // .orElse(ST); + // } + + public String getFullAction() { + return fullAction; + } + +} diff --git a/src/main/java/org/nqm/enums/GisOption.java b/src/main/java/org/nqm/enums/GisOption.java deleted file mode 100644 index f9ecbcd..0000000 --- a/src/main/java/org/nqm/enums/GisOption.java +++ /dev/null @@ -1,7 +0,0 @@ -package org.nqm.enums; - -public enum GisOption { - - co, st, fe, pu; - -} diff --git a/src/main/java/org/nqm/utils/ExceptionUtils.java b/src/main/java/org/nqm/utils/ExceptionUtils.java index 8683353..6a86968 100644 --- a/src/main/java/org/nqm/utils/ExceptionUtils.java +++ b/src/main/java/org/nqm/utils/ExceptionUtils.java @@ -4,12 +4,12 @@ public class ExceptionUtils { - private ExceptionUtils() {} + private ExceptionUtils() {} - // Reason to use Supplier over new instance: https://stackoverflow.com/a/47264712/12381095 - public static void throwIf(boolean b, Supplier e) { - if (b) { - throw e.get(); - } + // Reason to use Supplier over new instance: https://stackoverflow.com/a/47264712/12381095 + public static void throwIf(boolean b, Supplier e) { + if (b) { + throw e.get(); } + } } diff --git a/src/main/java/org/nqm/vertx/CommandVerticle.java b/src/main/java/org/nqm/vertx/CommandVerticle.java index 9289f76..5735fb7 100644 --- a/src/main/java/org/nqm/vertx/CommandVerticle.java +++ b/src/main/java/org/nqm/vertx/CommandVerticle.java @@ -12,56 +12,56 @@ public class CommandVerticle extends AbstractVerticle { - private final String git; - private final String command; - private final Path path; + private final String git; + private final String command; + private final Path path; - public CommandVerticle(String git, String command, Path path) { - this.git = git; - this.command = command; - this.path = path; - } - - @Override - public void start() { - vertx.executeBlocking( - (Promise promise) -> { - try { - promise.complete(Runtime.getRuntime().exec(git.formatted(command), null, path.toFile())); - } - catch (IOException e) { - throw new RuntimeException(e); - } - }, - false, - res -> { - Optional.of(res.result()).ifPresent(this::safelyPrint); - // root should be considered the last dir - if (System.getProperty("user.dir").equals(path.toString())) { - System.exit(0); - } - }); - } + public CommandVerticle(String git, String command, Path path) { + this.git = git; + this.command = command; + this.path = path; + } - private void safelyPrint(Process pr) { - var line = ""; - var input = new BufferedReader(new InputStreamReader(pr.getInputStream())); - var sb = new StringBuilder("Entering '%s'".formatted(path.toString())).append('\n'); + @Override + public void start() { + vertx.executeBlocking( + (Promise promise) -> { try { - while (isNotBlank(line = input.readLine())) { - sb.append(line).append('\n'); - } - out.print(sb.toString()); - Optional.of(pr.waitFor()) - .ifPresent(exitCode -> throwIf(exitCode != 0, - () -> new RuntimeException("Process exits with code: '%s'".formatted(exitCode)))); + promise.complete(Runtime.getRuntime().exec(git.formatted(command), null, path.toFile())); } - catch (IOException | InterruptedException e) { - throw new RuntimeException(e); + catch (IOException e) { + throw new RuntimeException(e); } - } + }, + false, + res -> { + Optional.of(res.result()).ifPresent(this::safelyPrint); + // root should be considered the last dir + if (System.getProperty("user.dir").equals(path.toString())) { + System.exit(0); + } + }); + } - private static boolean isNotBlank(String s) { - return s != null && !s.isBlank(); + private void safelyPrint(Process pr) { + var line = ""; + var input = new BufferedReader(new InputStreamReader(pr.getInputStream())); + var sb = new StringBuilder("Entering '%s'".formatted(path.toString())).append('\n'); + try { + while (isNotBlank(line = input.readLine())) { + sb.append(line).append('\n'); + } + out.print(sb.toString()); + Optional.of(pr.waitFor()) + .ifPresent(exitCode -> throwIf(exitCode != 0, + () -> new RuntimeException("Process exits with code: '%s'".formatted(exitCode)))); + } + catch (IOException | InterruptedException e) { + throw new RuntimeException(e); } + } + + private static boolean isNotBlank(String s) { + return s != null && !s.isBlank(); + } } diff --git a/src/main/java/org/nqm/vertx/GisVertx.java b/src/main/java/org/nqm/vertx/GisVertx.java index ca5ba3e..b6b0244 100644 --- a/src/main/java/org/nqm/vertx/GisVertx.java +++ b/src/main/java/org/nqm/vertx/GisVertx.java @@ -5,16 +5,16 @@ public class GisVertx { - private static Vertx INSTANCE; + private static Vertx INSTANCE; - public static Vertx instance() { - if (INSTANCE == null) { - var options = new VertxOptions(); - options.setEventLoopPoolSize(1); - options.setWorkerPoolSize(1); - options.setInternalBlockingPoolSize(1); - INSTANCE = Vertx.vertx(options); - } - return INSTANCE; + public static Vertx instance() { + if (INSTANCE == null) { + var options = new VertxOptions(); + options.setEventLoopPoolSize(1); + options.setWorkerPoolSize(1); + options.setInternalBlockingPoolSize(1); + INSTANCE = Vertx.vertx(options); } + return INSTANCE; + } }