From 9e73661900b28a0db950a807fc9203499d6530d1 Mon Sep 17 00:00:00 2001 From: Florian Heck <florian.heck@hotmail.de> Date: Tue, 18 Oct 2016 17:40:43 +0200 Subject: [PATCH] added status bean and method for parsing status --- .../fim/seibt/gitwrapper/repo/Repository.java | 14 ++++ .../fim/seibt/gitwrapper/repo/Status.java | 67 +++++++++++++++++++ 2 files changed, 81 insertions(+) create mode 100644 src/de/uni_passau/fim/seibt/gitwrapper/repo/Status.java diff --git a/src/de/uni_passau/fim/seibt/gitwrapper/repo/Repository.java b/src/de/uni_passau/fim/seibt/gitwrapper/repo/Repository.java index 0f8bbd9..1f66e8d 100644 --- a/src/de/uni_passau/fim/seibt/gitwrapper/repo/Repository.java +++ b/src/de/uni_passau/fim/seibt/gitwrapper/repo/Repository.java @@ -452,6 +452,20 @@ public class Repository { return Optional.of(conflicts); } + public Optional<Status> getStatus() { + Optional<ExecRes> output = git.exec(dir, "status", "-z"); + Function<ExecRes, Status> toStatus = execRes -> { + if (git.failed(execRes)) { + LOG.warning(() -> String.format("Failed to get status information for repo %s", this)); + return null; + } + + return Status.parseStatus(this, execRes.stdOut+"\0"); + }; + + return output.map(toStatus); + } + /** * Returns the {@link GitWrapper} used by this {@link Repository}. * diff --git a/src/de/uni_passau/fim/seibt/gitwrapper/repo/Status.java b/src/de/uni_passau/fim/seibt/gitwrapper/repo/Status.java new file mode 100644 index 0000000..8cb4112 --- /dev/null +++ b/src/de/uni_passau/fim/seibt/gitwrapper/repo/Status.java @@ -0,0 +1,67 @@ +package de.uni_passau.fim.seibt.gitwrapper.repo; + +import java.io.File; +import java.util.*; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class Status { + private static final Pattern STATUS_ENTRY = Pattern.compile("(.?.) (?:.*? )?(.*?)\0"); + + public final String head; + public final Map<File, String> changed; + public final Map<File, String> unmerged; + + private Status(String head, Map<File, String> changed, Map<File, String> unmerged) { + this.head = head; + this.changed = Collections.unmodifiableMap(changed); + this.unmerged = Collections.unmodifiableMap(unmerged); + } + + public boolean isClean() { + return changed.isEmpty() && unmerged.isEmpty(); + } + + public boolean hasConflicts() { + return !unmerged.isEmpty(); + } + + @Override + public String toString() { + String out = ""; + if (isClean()) { + out = "Clean working directory on commit " + head + "\n"; + } else { + if (!unmerged.isEmpty()) { + out = "Unmerged files:"; + out += unmerged.keySet().stream().map(File::getPath).reduce("", (list, file) -> String.join("\n", list, file)); + out += "\n"; + } + if (!changed.isEmpty()) { + out += "Changed files:"; + out += changed.keySet().stream().map(File::getPath).reduce("", (list, file) -> String.join("\n", list, file)); + out += "\n"; + } + } + + return out; + } + + static Status parseStatus(Repository repo, String gitOutput) { + Map<File, String> changed = new HashMap<>(); + Map<File, String> unmerged = new HashMap<>(); + Matcher matcher = STATUS_ENTRY.matcher(gitOutput); + while (matcher.find()) { + // used new path, if file was moved + File file = new File(matcher.group(2)); + String code = matcher.group(1).toUpperCase(); + if (code.contains("U")) { + unmerged.put(file, code); + } else { + changed.put(file, code); + } + } + + return new Status(repo.getCurrentHEAD().get().getId(), changed, unmerged); + } +} -- GitLab