diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml
index 4487e21..03fee46 100644
--- a/.github/workflows/maven.yml
+++ b/.github/workflows/maven.yml
@@ -8,11 +8,7 @@
name: Java CI with Maven
-on:
- push:
- branches: [ "master" ]
- pull_request:
- branches: [ "master" ]
+on: [push, pull_request]
jobs:
build:
@@ -38,8 +34,7 @@ jobs:
native-image-job-reports: 'true'
- name: Build executable file
run: |
- native-image -march=compatibility -cp target/gis-*.jar "org.nqm.Gis" --no-fallback --initialize-at-run-time=io.netty.handler.ssl.BouncyCastleAlpnSslUtils
- mv org.nqm.gis gis
+ docker build -f Containerfile -t gis . || return 1; docker create --name dkgis_ gis:latest; docker cp dkgis_:/app/gis/gis .; docker rm -f dkgis_
./gis --version
du -sh gis
- name: Upload artifact
diff --git a/pom.xml b/pom.xml
index 5f653fb..885eda4 100644
--- a/pom.xml
+++ b/pom.xml
@@ -24,6 +24,7 @@
3.3.0
0.8.12
9.0.1
+ 6.10.0.202406032230-r
@@ -32,6 +33,23 @@
picocli
${picocli.version}
+
+ org.eclipse.jgit
+ org.eclipse.jgit
+ ${jgit.version}
+
+
+
+
+ org.slf4j
+ slf4j-api
+ ${slf4j.version}
+
+
+ org.slf4j
+ slf4j-simple
+ ${slf4j.version}
+
@@ -64,18 +82,6 @@
${testcontainers.version}
test
-
- org.slf4j
- slf4j-api
- ${slf4j.version}
- test
-
-
- org.slf4j
- slf4j-simple
- ${slf4j.version}
- test
-
@@ -180,6 +186,26 @@
+
+ default-check
+
+ check
+
+
+
+
+ BUNDLE
+
+
+ COMPLEXITY
+ COVEREDRATIO
+ 0.90
+
+
+
+
+
+
diff --git a/src/main/java/org/nqm/Gis.java b/src/main/java/org/nqm/Gis.java
index d1555ba..6083ee3 100644
--- a/src/main/java/org/nqm/Gis.java
+++ b/src/main/java/org/nqm/Gis.java
@@ -1,7 +1,7 @@
package org.nqm;
+import org.nqm.command.GisCommand;
import org.nqm.command.GisVersion;
-import org.nqm.command.GitCommand;
import org.nqm.config.GisLog;
import org.nqm.utils.GisProcessUtils;
import picocli.CommandLine;
@@ -16,7 +16,7 @@
description = "Git extension wrapper which supports submodules",
mixinStandardHelpOptions = true,
versionProvider = GisVersion.class)
-public class Gis extends GitCommand {
+public class Gis extends GisCommand {
private static final IExecutionExceptionHandler GLOBAL_EXCEPTION_HANLER = new IExecutionExceptionHandler() {
@Override
@@ -38,9 +38,14 @@ public static void setDryRun(boolean dryRun) {
}
public static void main(String... args) {
+ // try {
+ // System.out.println(GitStatusCommand.status(Path.of("/home/minh/projects/test/small-git-root-module/small-git-domain/.git"), false));
+ // } catch (NoWorkTreeException | IOException | GitAPIException e) {
+ // e.printStackTrace();
+ // }
+
var gis = new CommandLine(new Gis());
gis.setExecutionExceptionHandler(GLOBAL_EXCEPTION_HANLER);
-
gis.execute(args.length == 0
? new String[] {GIT_STATUS, "--one-line"}
: args);
diff --git a/src/main/java/org/nqm/command/CommandVerticle.java b/src/main/java/org/nqm/command/CommandVerticle.java
index 38aa62d..429ade0 100644
--- a/src/main/java/org/nqm/command/CommandVerticle.java
+++ b/src/main/java/org/nqm/command/CommandVerticle.java
@@ -1,6 +1,6 @@
package org.nqm.command;
-import static org.nqm.command.GitCommand.HOOKS_OPTION;
+import static org.nqm.command.GisCommand.HOOKS_OPTION;
import static org.nqm.utils.GisStringUtils.isNotBlank;
import static org.nqm.utils.StdOutUtils.gitStatus;
import static org.nqm.utils.StdOutUtils.gitStatusOneLine;
@@ -95,7 +95,7 @@ private static void safelyPrint(
var sb = new StringBuilder(infof("%s", "" + path.getFileName()));
var isOneLineOpt = Stream.of(gisOptions).anyMatch("--gis-one-line"::equals);
while (isNotBlank(line = input.readLine())) {
- if (commandWithArgs[1].equals(GitCommand.GIT_STATUS)) {
+ if (commandWithArgs[1].equals(GisCommand.GIT_STATUS)) {
sb.append(isOneLineOpt ? gitStatusOneLine(line) : gitStatus(line));
} else {
sb.append("%n %s".formatted(line));
diff --git a/src/main/java/org/nqm/command/GitCommand.java b/src/main/java/org/nqm/command/GisCommand.java
similarity index 93%
rename from src/main/java/org/nqm/command/GitCommand.java
rename to src/main/java/org/nqm/command/GisCommand.java
index 24c54b1..187ae67 100644
--- a/src/main/java/org/nqm/command/GitCommand.java
+++ b/src/main/java/org/nqm/command/GisCommand.java
@@ -1,6 +1,7 @@
package org.nqm.command;
import static org.nqm.command.Wrapper.forEachModuleDo;
+import static org.nqm.command.Wrapper.forEachModuleStatus;
import static org.nqm.command.Wrapper.forEachModuleWith;
import static org.nqm.config.GisConfig.currentDir;
import java.io.BufferedReader;
@@ -15,9 +16,13 @@
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.Optional;
+import java.util.TreeSet;
+import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.function.Predicate;
import java.util.regex.Pattern;
+import java.util.stream.Collectors;
import java.util.stream.Stream;
+import org.eclipse.jgit.api.errors.GitAPIException;
import org.nqm.GisException;
import org.nqm.config.GisConfig;
import org.nqm.config.GisLog;
@@ -28,7 +33,7 @@
import picocli.CommandLine.Option;
import picocli.CommandLine.Parameters;
-public class GitCommand {
+public class GisCommand {
private static final String CHECKOUT = "checkout";
private static final String FETCHED_AT = "(fetched at: %s)";
@@ -47,12 +52,18 @@ void pull() throws IOException {
}
@Command(name = GIT_STATUS, aliases = "st", description = "Show the working trees status")
- void status(@Option(names = "--one-line") boolean oneLineOpt) throws IOException {
- if (oneLineOpt) {
- forEachModuleDo(GIT_STATUS, "-sb", "--ignore-submodules", "--porcelain=v2", "--gis-one-line");
- } else {
- forEachModuleDo(GIT_STATUS, "-sb", "--ignore-submodules", "--porcelain=v2");
- }
+ void status(@Option(names = "--one-line") boolean oneLiner) throws IOException {
+ var result = new ConcurrentLinkedQueue();
+ forEachModuleStatus(f -> {
+ try {
+ result.add(GitStatusCommand.status(f, oneLiner));
+ } catch (IOException | GitAPIException e) {
+ GisLog.debug(e);
+ }
+ });
+ StdOutUtils.println(String.join(
+ GisStringUtils.NEWLINE,
+ result.stream().collect(Collectors.toCollection(TreeSet::new))));
if (Files.exists(TMP_FILE)) {
var lastFetched = Files.readString(TMP_FILE);
if (GisStringUtils.isNotBlank(lastFetched)) {
@@ -235,7 +246,7 @@ void generateCompletion(
try (var out = new FileOutputStream(file.toFile())) {
while ((line = buffer.readLine()) != null) {
out.write(line.getBytes());
- out.write("%n".formatted().getBytes());
+ out.write(GisStringUtils.NEWLINE.getBytes());
}
}
return;
diff --git a/src/main/java/org/nqm/command/GitStatusCommand.java b/src/main/java/org/nqm/command/GitStatusCommand.java
new file mode 100644
index 0000000..640ed63
--- /dev/null
+++ b/src/main/java/org/nqm/command/GitStatusCommand.java
@@ -0,0 +1,138 @@
+package org.nqm.command;
+
+import static org.nqm.model.FileStatus.ADDED;
+import static org.nqm.model.FileStatus.CHANGED;
+import static org.nqm.model.FileStatus.CONFLICT;
+import static org.nqm.model.FileStatus.MISSING;
+import static org.nqm.model.FileStatus.MODIFIED;
+import static org.nqm.model.FileStatus.REMOVED;
+import static org.nqm.model.FileStatus.UNTRACKED;
+import static org.nqm.model.FileStatus.UNTRACKED_DIRS;
+import static org.nqm.utils.GisStringUtils.getDirectoryName;
+import static org.nqm.utils.StdOutUtils.CL_GREEN;
+import static org.nqm.utils.StdOutUtils.CL_RED;
+import static org.nqm.utils.StdOutUtils.coloringBranch;
+import static org.nqm.utils.StdOutUtils.coloringWord;
+import static org.nqm.utils.StdOutUtils.infof;
+import java.io.IOException;
+import java.nio.file.Path;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.function.Consumer;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+import org.eclipse.jgit.api.Git;
+import org.eclipse.jgit.api.Status;
+import org.eclipse.jgit.api.errors.GitAPIException;
+import org.eclipse.jgit.lib.BranchConfig;
+import org.eclipse.jgit.lib.BranchTrackingStatus;
+import org.eclipse.jgit.lib.Repository;
+import org.eclipse.jgit.storage.file.FileRepositoryBuilder;
+import org.eclipse.jgit.submodule.SubmoduleWalk.IgnoreSubmoduleMode;
+import org.nqm.model.FileStatus;
+import org.nqm.utils.GisStringUtils;
+import org.nqm.utils.StdOutUtils;
+
+public class GitStatusCommand {
+
+ private static Repository openRepo(Path f) throws IOException {
+ var repo = new FileRepositoryBuilder().readEnvironment();
+ if (f != null) {
+ repo.findGitDir(f.toFile());
+ } else {
+ repo.findGitDir();
+ }
+ return repo.build();
+ }
+
+ private static String aheadBehind(Repository repo) throws IOException {
+ var trackingStatus = BranchTrackingStatus.of(repo, repo.getBranch());
+ int ahead = trackingStatus.getAheadCount();
+ int behind = trackingStatus.getBehindCount();
+ return StdOutUtils.buildAheadBehind(ahead, behind);
+ }
+
+ private static String statusOneLiner(Repository repo, Status status, String localBranch)
+ throws IOException {
+ // TODO: add styling modified and changed files
+ // TODO: add styling for upstream?
+ var result = new StringBuilder(" ")
+ .append(coloringBranch(localBranch))
+ .append(aheadBehind(repo));
+
+ var updatedFiles = Stream.of(status.getModified().stream(),
+ status.getChanged().stream(),
+ status.getAdded().stream(),
+ status.getMissing().stream(),
+ status.getRemoved().stream(),
+ status.getUntracked().stream(),
+ status.getConflicting().stream(),
+ status.getUntrackedFolders().stream())
+ .reduce(Stream::concat)
+ .orElseGet(Stream::empty)
+ .distinct()
+ .collect(Collectors.joining(" "));
+ if (GisStringUtils.isNotBlank(updatedFiles)) {
+ result.append(" ").append(updatedFiles);
+ }
+ return result.toString();
+ }
+
+ private static String statusFull(Repository repo, Status status, String localBranch) throws IOException {
+ var trackingBranch = new BranchConfig(repo.getConfig(), localBranch)
+ .getTrackingBranch()
+ .replace("refs/remotes/", "");
+ var result = new StringBuilder()
+ .append(GisStringUtils.NEWLINE)
+ .append(" ## ")
+ .append(coloringWord(localBranch, CL_GREEN))
+ .append("...")
+ .append(coloringWord(trackingBranch, CL_RED))
+ .append(" ")
+ .append(aheadBehind(repo));
+
+ var statusByFiles = new HashMap>();
+
+ Function> computeStatus = s -> f -> {
+ var value = statusByFiles.computeIfAbsent(f, v -> new ArrayList());
+ value.add(s);
+ statusByFiles.put(f, value);
+ };
+
+ // TODO how do we know of file rename status
+ status.getModified().stream().forEach(computeStatus.apply(MODIFIED));
+ status.getChanged().stream().forEach(computeStatus.apply(CHANGED));
+ status.getAdded().stream().forEach(computeStatus.apply(ADDED));
+ status.getMissing().stream().forEach(computeStatus.apply(MISSING));
+ status.getRemoved().stream().forEach(computeStatus.apply(REMOVED));
+ status.getUntracked().stream().forEach(computeStatus.apply(UNTRACKED));
+ status.getConflicting().stream().forEach(computeStatus.apply(CONFLICT));
+ status.getUntrackedFolders().stream().forEach(computeStatus.apply(UNTRACKED_DIRS));
+
+ statusByFiles.forEach((k, v) -> result.append(GisStringUtils.NEWLINE)
+ .append(" ")
+ .append(FileStatus.toPrint(k, v)));
+ return result.toString();
+ }
+
+ public static String status(Path f, boolean oneLiner) throws IOException, GitAPIException {
+ var repo = openRepo(f.resolve(".git"));
+ Status status;
+ try (var git = new Git(repo)) {
+ status = git.status()
+ .setIgnoreSubmodules(IgnoreSubmoduleMode.ALL)
+ .call();
+ }
+ if (status == null) {
+ return "";
+ }
+ var result = new StringBuilder(infof(getDirectoryName(repo.getWorkTree().toPath())));
+ var localBranch = repo.getBranch();
+ result.append(oneLiner
+ ? statusOneLiner(repo, status, localBranch)
+ : statusFull(repo, status, localBranch));
+ return result.toString();
+ }
+}
diff --git a/src/main/java/org/nqm/command/Wrapper.java b/src/main/java/org/nqm/command/Wrapper.java
index 004689a..32ae5e9 100644
--- a/src/main/java/org/nqm/command/Wrapper.java
+++ b/src/main/java/org/nqm/command/Wrapper.java
@@ -9,10 +9,11 @@
import java.util.Optional;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executors;
+import java.util.function.Consumer;
import java.util.function.Predicate;
import java.util.stream.Stream;
-import org.nqm.config.GisLog;
import org.nqm.GisException;
+import org.nqm.config.GisLog;
import org.nqm.utils.StdOutUtils;
public final class Wrapper {
@@ -69,4 +70,26 @@ public static void forEachModuleWith(Predicate pred, String... args) throw
public static void forEachModuleDo(String... args) throws IOException {
forEachModuleWith(p -> true, args);
}
+
+ public static void forEachModuleStatus(Consumer gitStatus) throws IOException {
+ var gitModulesFilePath = getFileMarker();
+ var currentDir = currentDir();
+ try (var exe = Executors.newVirtualThreadPerTaskExecutor()) {
+ Optional.of(Path.of(currentDir))
+ .ifPresent(root -> exe.submit(() -> gitStatus.accept(root)));
+ Files.readAllLines(gitModulesFilePath.toPath()).stream()
+ .map(String::trim)
+ .filter(s -> s.startsWith("path"))
+ .map(s -> s.replace("path = ", ""))
+ .map(dir -> Path.of(currentDir, dir))
+ .filter(dir -> {
+ if (dir.toFile().exists()) {
+ return true;
+ }
+ StdOutUtils.errln("directory '%s' does not exist, will be ignored!".formatted("" + dir));
+ return false;
+ })
+ .forEach(dir -> exe.submit(() -> gitStatus.accept(dir)));
+ }
+ }
}
diff --git a/src/main/java/org/nqm/config/GisConfig.java b/src/main/java/org/nqm/config/GisConfig.java
index bb0575b..9141980 100644
--- a/src/main/java/org/nqm/config/GisConfig.java
+++ b/src/main/java/org/nqm/config/GisConfig.java
@@ -47,7 +47,6 @@ public static String[] getDefaultBranches() {
public static String[] getFeatureBranchPrefixes() {
return Optional.of(props)
.map(props -> props.getProperty(FEATURE_BRANCH_PREFIXES_KEY))
- .map(String::toLowerCase)
.map(splitValue)
.orElse(FEATURE_BRANCH_PREFIX_VALS);
}
diff --git a/src/main/java/org/nqm/model/FileStatus.java b/src/main/java/org/nqm/model/FileStatus.java
new file mode 100644
index 0000000..41932ff
--- /dev/null
+++ b/src/main/java/org/nqm/model/FileStatus.java
@@ -0,0 +1,58 @@
+package org.nqm.model;
+
+import static org.nqm.utils.StdOutUtils.CL_GREEN;
+import static org.nqm.utils.StdOutUtils.CL_RED;
+import static org.nqm.utils.StdOutUtils.coloringWord;
+import java.util.List;
+
+public enum FileStatus {
+
+ // @formatter:off
+ MODIFIED(1, "M"),
+ CHANGED(0, "M"),
+ ADDED(0, "A"),
+ MISSING(1, "D"),
+ REMOVED(0, "D"),
+ UNTRACKED(1, "?"),
+ CONFLICT(1, "U"),
+ UNTRACKED_DIRS(1, "?");
+ // @formatter:on
+
+ /**
+ * The level base on staging, 0 means staged, 1 means unstagged
+ */
+ private int level;
+
+ private String symbol;
+
+ FileStatus(int level, String symbol) {
+ this.level = level;
+ this.symbol = symbol;
+ }
+
+ public static String toPrint(String file, List statuses) {
+ if (statuses == null || statuses.isEmpty()) {
+ return "";
+ }
+ var size = statuses.size();
+ var result = "%s%s %s";
+ if (size > 1) {
+ statuses.sort((a, b) -> a.level - b.level);
+ var staged = statuses.getFirst();
+ var unstaged = statuses.getLast();
+ result = result.formatted(
+ coloringWord(staged.symbol, CL_GREEN),
+ coloringWord(unstaged.symbol, CL_RED),
+ file);
+ } else {
+ var st = statuses.getFirst();
+ int level = st.level;
+ if (level == 0) {
+ result = result.formatted(coloringWord(st.symbol, CL_GREEN), ".", file);
+ } else {
+ result = result.formatted(".", coloringWord(st.symbol, CL_RED), file);
+ }
+ }
+ return result;
+ }
+}
diff --git a/src/main/java/org/nqm/utils/GisStringUtils.java b/src/main/java/org/nqm/utils/GisStringUtils.java
index 358bf56..8cb1ff4 100644
--- a/src/main/java/org/nqm/utils/GisStringUtils.java
+++ b/src/main/java/org/nqm/utils/GisStringUtils.java
@@ -2,11 +2,14 @@
import java.io.ByteArrayInputStream;
import java.io.InputStreamReader;
+import java.nio.file.Path;
public class GisStringUtils {
private GisStringUtils() {}
+ public static final String NEWLINE = "%n".formatted();
+
public static boolean isNotBlank(String s) {
return s != null && !s.isBlank();
}
@@ -18,4 +21,8 @@ public static boolean isBlank(String s) {
public static InputStreamReader toInputStreamReader(String s) {
return new InputStreamReader(new ByteArrayInputStream(s.getBytes()));
}
+
+ public static String getDirectoryName(Path p) {
+ return "" + p.subpath(p.getNameCount() - 1, p.getNameCount());
+ }
}
diff --git a/src/main/java/org/nqm/utils/StdOutUtils.java b/src/main/java/org/nqm/utils/StdOutUtils.java
index 37aeab7..0232a6c 100644
--- a/src/main/java/org/nqm/utils/StdOutUtils.java
+++ b/src/main/java/org/nqm/utils/StdOutUtils.java
@@ -59,11 +59,15 @@ public static void debugln(String msg) {
out.println(" " + CL_YELLOW + "[DEBUG] " + msg + CL_RESET);
}
- public static String infof(String msgFormat, String word) {
+ public static String infof(String msgFormat, String word) { // TODO: remove this
return msgFormat.formatted(CL_CYAN + word + CL_RESET);
}
- private static String coloringBranch(String branch) {
+ public static String infof(String word) {
+ return "%s".formatted(CL_CYAN + word + CL_RESET);
+ }
+
+ public static String coloringBranch(String branch) {
if (Stream.of(GisConfig.getDefaultBranches()).anyMatch(branch::equals)) {
return coloringWord(branch, CL_RED);
}
@@ -75,7 +79,7 @@ private static String coloringBranch(String branch) {
return coloringWord(branch, CL_GREEN);
}
- private static String coloringWord(String word, String color) {
+ public static String coloringWord(String word, String color) {
return color + word + CL_RESET;
}
@@ -96,6 +100,26 @@ private static String buildStaging(char[] chars) {
+ " ";
}
+ public static String buildAheadBehind(int a, int b) {
+ if (a == 0 && b == 0) {
+ return "";
+ }
+ var ahead = Optional.of(a)
+ .filter(x -> x > 0)
+ .map(x -> "" + x)
+ .map(s -> "ahead " + coloringWord(s, CL_GREEN))
+ .orElse("");
+ var behind = Optional.of(b)
+ .filter(x -> x > 0)
+ .map(x -> "" + x)
+ .map(s -> "behind " + coloringWord(s, CL_RED))
+ .orElse("");
+ return "[%s]".formatted(Stream.of(ahead, behind)
+ .filter(not(String::isBlank))
+ .collect(Collectors.joining(", ")));
+ }
+
+ @Deprecated(since = "2.0.0")
private static String buildAheadBehind(String[] splitS) {
var ahead = Optional.of(splitS[2])
.map(s -> s.replace("+", ""))
diff --git a/src/test/java/org/nqm/command/GitCommandIntTest.java b/src/test/java/org/nqm/command/GitCommandIntTest.java
index 4829452..366f8b2 100644
--- a/src/test/java/org/nqm/command/GitCommandIntTest.java
+++ b/src/test/java/org/nqm/command/GitCommandIntTest.java
@@ -17,15 +17,16 @@
import org.nqm.helper.GisConfigMock;
import org.nqm.helper.GisProcessUtilsMock;
import org.nqm.helper.GitBaseTest;
+import org.nqm.utils.GisStringUtils;
class GitCommandIntTest extends GitBaseTest {
- private GitCommand gis;
+ private GisCommand gis;
@Override
protected void additionalSetup() {
GisConfigMock.mockCurrentDirectory("" + tempPath);
- gis = new GitCommand();
+ gis = new GisCommand();
}
@Override
@@ -137,7 +138,7 @@ void listBranches_withoutModuleNames_OK() throws IOException {
gis.listBranches(true, false);
// then:
- assertThat(outCaptor.toString().split("%n".formatted())).containsExactlyInAnyOrder(
+ assertThat(outCaptor.toString().split(GisStringUtils.NEWLINE)).containsExactlyInAnyOrder(
"bb1", "master", "bb1", "master", "bb1", "master");
}
@@ -162,7 +163,7 @@ void listBranchesWithRemote_withoutModuleNames_OK() throws IOException {
gis.listBranches(true, true);
// then:
- assertThat(outCaptor.toString().split("%n".formatted()))
+ assertThat(outCaptor.toString().split(GisStringUtils.NEWLINE))
.containsExactlyInAnyOrder(
"bb1",
"bb2",
@@ -193,7 +194,7 @@ void listFilesChanged_OK() throws IOException {
gis.files();
// then:
- assertThat(outCaptor.toString().split("%n".formatted())).containsExactlyInAnyOrder(
+ assertThat(outCaptor.toString().split(GisStringUtils.NEWLINE)).containsExactlyInAnyOrder(
"otq_1_a/filescramble1",
"otq_3_c/filescramble1",
"otq_2_b/filescramble1");
diff --git a/src/test/java/org/nqm/command/GitCommandTest.java b/src/test/java/org/nqm/command/GitCommandTest.java
index bd57783..03b8822 100644
--- a/src/test/java/org/nqm/command/GitCommandTest.java
+++ b/src/test/java/org/nqm/command/GitCommandTest.java
@@ -5,7 +5,7 @@
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
-import static org.nqm.command.GitCommand.GIS_AUTOCOMPLETE_FILE;
+import static org.nqm.command.GisCommand.GIS_AUTOCOMPLETE_FILE;
import static org.nqm.config.GisConfig.GIT_HOME_DIR;
import java.io.ByteArrayInputStream;
import java.io.IOException;
@@ -27,7 +27,7 @@
@ExtendWith(MockitoExtension.class)
class GitCommandTest extends StdBaseTest {
- private GitCommand gis;
+ private GisCommand gis;
@TempDir
private Path tempPath;
@@ -47,7 +47,7 @@ void ignoreMarkerFile() throws IOException {
@Override
protected void additionalSetup() throws IOException {
- gis = new GitCommand();
+ gis = new GisCommand();
ignoreMarkerFile();
try {
@@ -431,7 +431,7 @@ void generateCompletionToFile_withFileAlreadyExist_shouldOverwrite() throws IOEx
@Test
void confirmYesPattern_false() throws Exception {
// given:
- var pattern = GitCommand.CONFIRM_YES;
+ var pattern = GisCommand.CONFIRM_YES;
// then:
assertThat(pattern.matcher("Yey").matches()).isFalse();
@@ -447,7 +447,7 @@ void confirmYesPattern_false() throws Exception {
@Test
void confirmYesPattern_true() throws Exception {
// given:
- var pattern = GitCommand.CONFIRM_YES;
+ var pattern = GisCommand.CONFIRM_YES;
// then:
assertThat(pattern.matcher("YES").matches()).isTrue();
diff --git a/src/test/java/org/nqm/command/GitCommandWithoutDependMarkerFileTest.java b/src/test/java/org/nqm/command/GitCommandWithoutDependMarkerFileTest.java
index 4f1e756..9e6c9e8 100644
--- a/src/test/java/org/nqm/command/GitCommandWithoutDependMarkerFileTest.java
+++ b/src/test/java/org/nqm/command/GitCommandWithoutDependMarkerFileTest.java
@@ -10,7 +10,7 @@ class GitCommandWithoutDependMarkerFileTest extends StdBaseTest {
@Test
void pull_withoutAnyMarkerFiles_NOK() {
// given:
- var gis = new GitCommand();
+ var gis = new GisCommand();
// when then:
Assertions.assertThatThrownBy(() -> gis.pull())
diff --git a/src/test/java/org/nqm/helper/GisConfigMock.java b/src/test/java/org/nqm/helper/GisConfigMock.java
index c2b43a0..aa0aaf3 100644
--- a/src/test/java/org/nqm/helper/GisConfigMock.java
+++ b/src/test/java/org/nqm/helper/GisConfigMock.java
@@ -19,10 +19,18 @@ public static void mockBranchesColorDefault() {
if (mock == null || mock.isClosed()) {
mock = Mockito.mockStatic(GisConfig.class);
}
- mock.when(GisConfig::getDefaultBranches).thenReturn(new String[] {"master"});
+ mock.when(GisConfig::getDefaultBranches).thenReturn(new String[] {"master", "main", "develop"});
mock.when(GisConfig::getFeatureBranchPrefixes).thenReturn(new String[] {"feature/"});
}
+ public static void mockBranchesColorDefault(String[] defaultBranches, String[] prefixes) {
+ if (mock == null || mock.isClosed()) {
+ mock = Mockito.mockStatic(GisConfig.class);
+ }
+ mock.when(GisConfig::getDefaultBranches).thenReturn(defaultBranches);
+ mock.when(GisConfig::getFeatureBranchPrefixes).thenReturn(prefixes);
+ }
+
public static void close() {
if (mock != null && !mock.isClosed()) {
mock.close();
diff --git a/src/test/java/org/nqm/helper/StdBaseTest.java b/src/test/java/org/nqm/helper/StdBaseTest.java
index 988686f..fcf14e9 100644
--- a/src/test/java/org/nqm/helper/StdBaseTest.java
+++ b/src/test/java/org/nqm/helper/StdBaseTest.java
@@ -19,6 +19,7 @@
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.nqm.config.GisLog;
+import org.nqm.utils.GisStringUtils;
import org.nqm.utils.StdOutUtils;
public abstract class StdBaseTest {
@@ -56,7 +57,7 @@ protected void resetOutputStreamTest() {
}
protected static Function> stripColors =
- str -> Stream.of(str.split("%n".formatted()))
+ str -> Stream.of(str.split(GisStringUtils.NEWLINE))
.map(s -> s.replace(CL_RESET, ""))
.map(s -> s.replace(CL_BLACK, ""))
.map(s -> s.replace(CL_RED, ""))
diff --git a/src/test/java/org/nqm/utils/GisProcessUtilsTest.java b/src/test/java/org/nqm/utils/GisProcessUtilsTest.java
index 192b9f8..198ae89 100644
--- a/src/test/java/org/nqm/utils/GisProcessUtilsTest.java
+++ b/src/test/java/org/nqm/utils/GisProcessUtilsTest.java
@@ -19,7 +19,7 @@ void run_OK() throws IOException, InterruptedException {
// then:
assertThat(result.exitCode()).isZero();
- assertThat(result.output()).isEqualTo("" + tempPath + "%n".formatted());
+ assertThat(result.output()).isEqualTo("" + tempPath + GisStringUtils.NEWLINE);
}
@Test
@@ -38,7 +38,7 @@ void quickRun_OK() throws IOException {
// then:
assertThat(result.exitCode()).isZero();
- assertThat(result.output()).isEqualTo("" + tempPath + "%n".formatted());
+ assertThat(result.output()).isEqualTo("" + tempPath + GisStringUtils.NEWLINE);
}
@Test
diff --git a/src/test/java/org/nqm/utils/StdOutUtilsTest.java b/src/test/java/org/nqm/utils/StdOutUtilsTest.java
index 4083140..ad20bbb 100644
--- a/src/test/java/org/nqm/utils/StdOutUtilsTest.java
+++ b/src/test/java/org/nqm/utils/StdOutUtilsTest.java
@@ -7,10 +7,21 @@
import static org.nqm.utils.StdOutUtils.CL_RESET;
import static org.nqm.utils.StdOutUtils.CL_YELLOW;
import org.junit.jupiter.api.Test;
+import org.nqm.helper.GisConfigMock;
import org.nqm.helper.StdBaseTest;
class StdOutUtilsTest extends StdBaseTest {
+ @Override
+ protected void additionalSetup() {
+ GisConfigMock.mockBranchesColorDefault();
+ }
+
+ @Override
+ protected void additionalTeardown() {
+ GisConfigMock.close();
+ }
+
@Test
void debugln_OK() {
StdOutUtils.debugln("debugln_7_b");
@@ -125,6 +136,30 @@ void gitStatusOneLine_OK() {
.isEqualTo(" StdOutUtilsTest.java");
}
+ @Test
+ void gitStatusOneLine_withConfigBranchPrefixes_shouldCompareCaseSensitive() {
+ // given:
+ GisConfigMock.mockBranchesColorDefault(new String[]{"Master", "MAIN"}, new String[]{"FEA-ture"});
+
+ // then:
+ assertThat(StdOutUtils.gitStatusOneLine("# branch.head Master"))
+ .isEqualTo(" %s".formatted(coloringWord("Master", CL_RED)));
+ assertThat(StdOutUtils.gitStatusOneLine("# branch.head masTer"))
+ .isEqualTo(" %s".formatted(coloringWord("masTer", CL_GREEN)));
+
+ assertThat(StdOutUtils.gitStatusOneLine("# branch.head MAIN"))
+ .isEqualTo(" %s".formatted(coloringWord("MAIN", CL_RED)));
+ assertThat(StdOutUtils.gitStatusOneLine("# branch.head main"))
+ .isEqualTo(" %s".formatted(coloringWord("main", CL_GREEN)));
+
+ assertThat(StdOutUtils.gitStatusOneLine("# branch.head FEA-ture/destroy-d-b"))
+ .isEqualTo(" %s".formatted(coloringWord("FEA-ture/destroy-d-b", CL_YELLOW)));
+ assertThat(StdOutUtils.gitStatusOneLine("# branch.head Fea-ture/destroy-d-b"))
+ .isEqualTo(" %s".formatted(coloringWord("Fea-ture/destroy-d-b", CL_GREEN)));
+ assertThat(StdOutUtils.gitStatusOneLine("# branch.head fea-ture/destroy-d-b"))
+ .isEqualTo(" %s".formatted(coloringWord("fea-ture/destroy-d-b", CL_GREEN)));
+ }
+
@Test
void print_OK() {
// when: