Skip to content

Commit

Permalink
- refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
minh.q.nguyen committed Mar 17, 2022
1 parent f405124 commit d8e895d
Show file tree
Hide file tree
Showing 10 changed files with 165 additions and 163 deletions.
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -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 \
Expand Down
9 changes: 0 additions & 9 deletions Dockerfile.graalvm

This file was deleted.

2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>org.nqm</groupId>
<artifactId>gis</artifactId>
<version>1.0.0</version>
<version>1.0.0-alpha</version>
<packaging>${packaging}</packaging>

<properties>
Expand Down
61 changes: 27 additions & 34 deletions src/main/java/org/nqm/GisCommand.java
Original file line number Diff line number Diff line change
Expand Up @@ -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<String> 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();
}
}

}
101 changes: 51 additions & 50 deletions src/main/java/org/nqm/GitWrapper.java
Original file line number Diff line number Diff line change
Expand Up @@ -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<Path, Void> 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<Stream<String>> ar) -> {
if (ar.succeeded()) {
ar.result().forEach(dir -> vertx.executeBlocking((Promise<Void> p) -> p.complete(consume.apply(Path.of(CURRENT_DIR, dir)))));
vertx.executeBlocking((Promise<Void> p) -> p.complete(consume.apply(Path.of(CURRENT_DIR))));
}
else {
err.println("failed to read file");
System.exit(1);
}
});
private static void run(Function<Path, Void> 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<Stream<String>> ar) -> {
if (ar.succeeded()) {
ar.result().forEach(dir -> vertx.executeBlocking(
(Promise<Void> p) -> p.complete(consume.apply(Path.of(CURRENT_DIR, dir)))));
vertx.executeBlocking((Promise<Void> 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<String> 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<String> extractDirs(Buffer buffer) {
return Stream.of(buffer.toString().split("\n"))
.map(String::trim)
.filter(s -> s.startsWith("path"))
.map(s -> s.replace("path = ", ""));
}

}
24 changes: 24 additions & 0 deletions src/main/java/org/nqm/enums/GisAction.java
Original file line number Diff line number Diff line change
@@ -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;
}

}
7 changes: 0 additions & 7 deletions src/main/java/org/nqm/enums/GisOption.java

This file was deleted.

12 changes: 6 additions & 6 deletions src/main/java/org/nqm/utils/ExceptionUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -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<? extends RuntimeException> 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<? extends RuntimeException> e) {
if (b) {
throw e.get();
}
}
}
90 changes: 45 additions & 45 deletions src/main/java/org/nqm/vertx/CommandVerticle.java
Original file line number Diff line number Diff line change
Expand Up @@ -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<Process> 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<Process> 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();
}
}
Loading

0 comments on commit d8e895d

Please sign in to comment.