diff options
author | Thomas Wolf <thomas.wolf@paranor.ch> | 2022-01-15 22:51:06 +0100 |
---|---|---|
committer | Thomas Wolf <thomas.wolf@paranor.ch> | 2022-01-31 00:42:35 +0100 |
commit | 318a25f0e62553ee771962369462d54f0e8870c8 (patch) | |
tree | 00ebb1251ecf4d23e1b46147b09388ff9b1af38f /org.eclipse.jgit | |
parent | 2b01ac3389c11be88ec875048d6a2cc4ed6903f1 (diff) | |
download | jgit-318a25f0e62553ee771962369462d54f0e8870c8.tar.gz jgit-318a25f0e62553ee771962369462d54f0e8870c8.zip |
Provide git config commit.cleanup
Add an enumeration for the possible values, and a method to resolve the
"default" value. Give CommitConfig a static method to process a text
according to a given clean-up mode and comment character.
(The core.commentChar is not yet handled by JGit; it's hard-coded as #.)
Bug: 553065
Change-Id: If6e384522275f73b713fbc29ffcaa1753c239dea
Signed-off-by: Thomas Wolf <thomas.wolf@paranor.ch>
Diffstat (limited to 'org.eclipse.jgit')
-rw-r--r-- | org.eclipse.jgit/src/org/eclipse/jgit/lib/CommitConfig.java | 180 | ||||
-rw-r--r-- | org.eclipse.jgit/src/org/eclipse/jgit/lib/ConfigConstants.java | 7 |
2 files changed, 187 insertions, 0 deletions
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/CommitConfig.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/CommitConfig.java index 22e1f98181..55cc02683a 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/CommitConfig.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/CommitConfig.java @@ -18,11 +18,13 @@ import java.nio.charset.IllegalCharsetNameException; import java.nio.charset.StandardCharsets; import java.nio.charset.UnsupportedCharsetException; import java.text.MessageFormat; +import java.util.Locale; import org.eclipse.jgit.annotations.NonNull; import org.eclipse.jgit.annotations.Nullable; import org.eclipse.jgit.errors.ConfigInvalidException; import org.eclipse.jgit.internal.JGitText; +import org.eclipse.jgit.lib.Config.ConfigEnum; import org.eclipse.jgit.lib.Config.SectionParser; import org.eclipse.jgit.util.FS; import org.eclipse.jgit.util.IO; @@ -34,22 +36,76 @@ import org.eclipse.jgit.util.RawParseUtils; * @since 5.13 */ public class CommitConfig { + /** * Key for {@link Config#get(SectionParser)}. */ public static final Config.SectionParser<CommitConfig> KEY = CommitConfig::new; + private static final String CUT = " ------------------------ >8 ------------------------\n"; //$NON-NLS-1$ + + /** + * How to clean up commit messages when committing. + * + * @since 6.1 + */ + public enum CleanupMode implements ConfigEnum { + + /** + * {@link #WHITESPACE}, additionally remove comment lines. + */ + STRIP, + + /** + * Remove trailing whitespace and leading and trailing empty lines; + * collapse multiple empty lines to a single one. + */ + WHITESPACE, + + /** + * Make no changes. + */ + VERBATIM, + + /** + * Omit everything from the first "scissor" line on, then apply + * {@link #WHITESPACE}. + */ + SCISSORS, + + /** + * Use {@link #STRIP} for user-edited messages, otherwise + * {@link #WHITESPACE}, unless overridden by a git config setting other + * than DEFAULT. + */ + DEFAULT; + + @Override + public String toConfigValue() { + return name().toLowerCase(Locale.ROOT); + } + + @Override + public boolean matchConfigValue(String in) { + return toConfigValue().equals(in); + } + } + private final static Charset DEFAULT_COMMIT_MESSAGE_ENCODING = StandardCharsets.UTF_8; private String i18nCommitEncoding; private String commitTemplatePath; + private CleanupMode cleanupMode; + private CommitConfig(Config rc) { commitTemplatePath = rc.getString(ConfigConstants.CONFIG_COMMIT_SECTION, null, ConfigConstants.CONFIG_KEY_COMMIT_TEMPLATE); i18nCommitEncoding = rc.getString(ConfigConstants.CONFIG_SECTION_I18N, null, ConfigConstants.CONFIG_KEY_COMMIT_ENCODING); + cleanupMode = rc.getEnum(ConfigConstants.CONFIG_COMMIT_SECTION, null, + ConfigConstants.CONFIG_KEY_CLEANUP, CleanupMode.DEFAULT); } /** @@ -75,6 +131,48 @@ public class CommitConfig { } /** + * Retrieves the {@link CleanupMode} as given by git config + * {@code commit.cleanup}. + * + * @return the {@link CleanupMode}; {@link CleanupMode#DEFAULT} if the git + * config is not set + * @since 6.1 + */ + @NonNull + public CleanupMode getCleanupMode() { + return cleanupMode; + } + + /** + * Computes a non-default {@link CleanupMode} from the given mode and the + * git config. + * + * @param mode + * {@link CleanupMode} to resolve + * @param defaultStrip + * if {@code true} return {@link CleanupMode#STRIP} if the git + * config is also "default", otherwise return + * {@link CleanupMode#WHITESPACE} + * @return the {@code mode}, if it is not {@link CleanupMode#DEFAULT}, + * otherwise the resolved mode, which is never + * {@link CleanupMode#DEFAULT} + * @since 6.1 + */ + @NonNull + public CleanupMode resolve(@NonNull CleanupMode mode, + boolean defaultStrip) { + if (CleanupMode.DEFAULT == mode) { + CleanupMode defaultMode = getCleanupMode(); + if (CleanupMode.DEFAULT == defaultMode) { + return defaultStrip ? CleanupMode.STRIP + : CleanupMode.WHITESPACE; + } + return defaultMode; + } + return mode; + } + + /** * Get the content to the commit template as defined in * {@code commit.template}. If no {@code i18n.commitEncoding} is specified, * UTF-8 fallback is used. @@ -135,4 +233,86 @@ public class CommitConfig { return commitMessageEncoding; } + + /** + * Processes a text according to the given {@link CleanupMode}. + * + * @param text + * text to process + * @param mode + * {@link CleanupMode} to use + * @param commentChar + * comment character (normally {@code #}) to use if {@code mode} + * is {@link CleanupMode#STRIP} or {@link CleanupMode#SCISSORS} + * @return the processed text + * @throws IllegalArgumentException + * if {@code mode} is {@link CleanupMode#DEFAULT} (use + * {@link #resolve(CleanupMode, boolean)} first) + * @since 6.1 + */ + public static String cleanText(@NonNull String text, + @NonNull CleanupMode mode, char commentChar) { + String toProcess = text; + boolean strip = false; + switch (mode) { + case VERBATIM: + return text; + case SCISSORS: + String cut = commentChar + CUT; + if (text.startsWith(cut)) { + return ""; //$NON-NLS-1$ + } + int cutPos = text.indexOf('\n' + cut); + if (cutPos >= 0) { + toProcess = text.substring(0, cutPos + 1); + } + break; + case STRIP: + strip = true; + break; + case WHITESPACE: + break; + case DEFAULT: + default: + // Internal error; no translation + throw new IllegalArgumentException("Invalid clean-up mode " + mode); //$NON-NLS-1$ + } + // WHITESPACE + StringBuilder result = new StringBuilder(); + boolean lastWasEmpty = true; + for (String line : toProcess.split("\n")) { //$NON-NLS-1$ + line = line.stripTrailing(); + if (line.isEmpty()) { + if (!lastWasEmpty) { + result.append('\n'); + lastWasEmpty = true; + } + } else if (!strip || !isComment(line, commentChar)) { + lastWasEmpty = false; + result.append(line).append('\n'); + } + } + int bufferSize = result.length(); + if (lastWasEmpty && bufferSize > 0) { + bufferSize--; + result.setLength(bufferSize); + } + if (bufferSize > 0 && !toProcess.endsWith("\n")) { //$NON-NLS-1$ + if (result.charAt(bufferSize - 1) == '\n') { + result.setLength(bufferSize - 1); + } + } + return result.toString(); + } + + private static boolean isComment(String text, char commentChar) { + int len = text.length(); + for (int i = 0; i < len; i++) { + char ch = text.charAt(i); + if (!Character.isWhitespace(ch)) { + return ch == commentChar; + } + } + return false; + } }
\ No newline at end of file diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/ConfigConstants.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/ConfigConstants.java index 4b21e4be4e..af2b4ccdd1 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/ConfigConstants.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/ConfigConstants.java @@ -182,6 +182,13 @@ public final class ConfigConstants { public static final String CONFIG_TAG_SECTION = "tag"; /** + * The "cleanup" key + * + * @since 6.1 + */ + public static final String CONFIG_KEY_CLEANUP = "cleanup"; + + /** * The "gpgSign" key * * @since 5.2 |