Browse Source

Support commit.template config property

Adds functionality to read the git commit.template property. The
template content is read either via a default encoding or, if present,
via encoding specified by i18n.commitEncoding property.

Bug: 446355

Change-Id: I0c45db98e324ddff26a7e0262835f259d6528a86
Signed-off-by: Julian Ruppel <julian.ruppel@sap.com>
changes/21/179821/3
Julian Ruppel 3 years ago
parent
commit
7b60a5ddaf

+ 95
- 0
org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/ConfigTest.java View File

@@ -34,6 +34,7 @@ import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.nio.file.Files;
import java.text.MessageFormat;
@@ -50,6 +51,7 @@ import java.util.function.Consumer;
import org.eclipse.jgit.api.MergeCommand.FastForwardMode;
import org.eclipse.jgit.errors.ConfigInvalidException;
import org.eclipse.jgit.internal.JGitText;
import org.eclipse.jgit.junit.JGitTestUtil;
import org.eclipse.jgit.junit.MockSystemReader;
import org.eclipse.jgit.merge.MergeConfig;
import org.eclipse.jgit.storage.file.FileBasedConfig;
@@ -1463,6 +1465,99 @@ public class ConfigTest {
assertEquals("tr ue", parseEscapedValue("tr \\\r\n ue"));
}

@Test
public void testCommitTemplateConfig()
throws ConfigInvalidException, IOException {
// no values defined nowhere
Config config = new Config(null);
assertNull(config.get(CommitConfig.KEY).getCommitTemplatePath());
assertNull(config.get(CommitConfig.KEY).getCommitTemplateContent());
File tempFile = tmp.newFile("testCommitTemplate-");
String templateContent = "content of the template";
JGitTestUtil.write(tempFile, templateContent);
// values are defined in the configuration
String expectedTemplatePath = tempFile.getPath();
config = parse("[commit]\n\ttemplate = " + expectedTemplatePath + "\n");
String templatePath = config.get(CommitConfig.KEY)
.getCommitTemplatePath();
String commitEncoding = config.get(CommitConfig.KEY)
.getCommitEncoding();
assertEquals(expectedTemplatePath, templatePath);
assertEquals(templateContent,
config.get(CommitConfig.KEY).getCommitTemplateContent());
assertNull("no commitEncoding has been set so it must be null",
commitEncoding);
}

@Test
public void testCommitTemplateEncoding()
throws ConfigInvalidException, IOException {
Config config = new Config(null);
File tempFile = tmp.newFile("testCommitTemplate-");
String templateContent = "content of the template";
JGitTestUtil.write(tempFile, templateContent);
String expectedTemplatePath = tempFile.getPath();
config = parse("[i18n]\n\tcommitEncoding = utf-8\n"
+ "[commit]\n\ttemplate = " + expectedTemplatePath + "\n");
assertEquals(templateContent,
config.get(CommitConfig.KEY).getCommitTemplateContent());
String commitEncoding = config.get(CommitConfig.KEY)
.getCommitEncoding();
assertEquals("commitEncoding has been set to utf-8 it must be utf-8",
"utf-8", commitEncoding);
}

@Test
public void testCommitTemplatePathInHomeDirecory()
throws ConfigInvalidException, IOException {
Config config = new Config(null);
File tempFile = tmp.newFile("testCommitTemplate-");
String templateContent = "content of the template";
JGitTestUtil.write(tempFile, templateContent);
// proper evaluation of the ~/ directory
String homeDir = System.getProperty("user.home");
File tempFileInHomeDirectory = File.createTempFile("fileInHomeFolder",
".tmp", new File(homeDir));
tempFileInHomeDirectory.deleteOnExit();
JGitTestUtil.write(tempFileInHomeDirectory, templateContent);
String expectedTemplatePath = tempFileInHomeDirectory.getPath()
.replace(homeDir, "~");
config = parse("[commit]\n\ttemplate = " + expectedTemplatePath + "\n");
String templatePath = config.get(CommitConfig.KEY)
.getCommitTemplatePath();
assertEquals(expectedTemplatePath, templatePath);
assertEquals(templateContent,
config.get(CommitConfig.KEY).getCommitTemplateContent());
}

@Test(expected = ConfigInvalidException.class)
public void testCommitTemplateWithInvalidEncoding()
throws ConfigInvalidException, IOException {
Config config = new Config(null);
File tempFile = tmp.newFile("testCommitTemplate-");
String templateContent = "content of the template";
JGitTestUtil.write(tempFile, templateContent);
config = parse("[i18n]\n\tcommitEncoding = invalidEcoding\n"
+ "[commit]\n\ttemplate = " + tempFile.getPath() + "\n");
config.get(CommitConfig.KEY).getCommitTemplateContent();
}

@Test(expected = FileNotFoundException.class)
public void testCommitTemplateWithInvalidPath()
throws ConfigInvalidException, IOException {
Config config = new Config(null);
File tempFile = tmp.newFile("testCommitTemplate-");
String templateContent = "content of the template";
JGitTestUtil.write(tempFile, templateContent);
// commit message encoding
String expectedTemplatePath = "nonExistingTemplate";
config = parse("[commit]\n\ttemplate = " + expectedTemplatePath + "\n");
String templatePath = config.get(CommitConfig.KEY)
.getCommitTemplatePath();
assertEquals(expectedTemplatePath, templatePath);
config.get(CommitConfig.KEY).getCommitTemplateContent();
}

private static void assertValueRoundTrip(String value)
throws ConfigInvalidException {
assertValueRoundTrip(value, value);

+ 1
- 0
org.eclipse.jgit/resources/org/eclipse/jgit/internal/JGitText.properties View File

@@ -365,6 +365,7 @@ invalidBooleanValue=Invalid boolean value: {0}.{1}={2}
invalidChannel=Invalid channel {0}
invalidCommitParentNumber=Invalid commit parent number
invalidDepth=Invalid depth: {0}
invalidEncoding=Invalid encoding from git config i18n.commitEncoding: {0}
invalidEncryption=Invalid encryption
invalidExpandWildcard=ExpandFromSource on a refspec that can have mismatched wildcards does not make sense.
invalidFilter=Invalid filter: {0}

+ 1
- 0
org.eclipse.jgit/src/org/eclipse/jgit/internal/JGitText.java View File

@@ -393,6 +393,7 @@ public class JGitText extends TranslationBundle {
/***/ public String invalidChannel;
/***/ public String invalidCommitParentNumber;
/***/ public String invalidDepth;
/***/ public String invalidEncoding;
/***/ public String invalidEncryption;
/***/ public String invalidExpandWildcard;
/***/ public String invalidFilter;

+ 125
- 0
org.eclipse.jgit/src/org/eclipse/jgit/lib/CommitConfig.java View File

@@ -0,0 +1,125 @@
/*
* Copyright (c) 2020 Julian Ruppel <julian.ruppel@sap.com>
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Distribution License v. 1.0 which is available at
* https://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: BSD-3-Clause
*/

package org.eclipse.jgit.lib;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.charset.IllegalCharsetNameException;
import java.nio.charset.StandardCharsets;
import java.nio.charset.UnsupportedCharsetException;
import java.text.MessageFormat;
import org.eclipse.jgit.annotations.Nullable;
import org.eclipse.jgit.errors.ConfigInvalidException;
import org.eclipse.jgit.internal.JGitText;
import org.eclipse.jgit.lib.Config.SectionParser;
import org.eclipse.jgit.util.FS;
import org.eclipse.jgit.util.IO;
import org.eclipse.jgit.util.RawParseUtils;

/**
* The standard "commit" configuration parameters.
*
* @since 5.12
*/
public class CommitConfig {
/**
* Key for {@link Config#get(SectionParser)}.
*/
public static final Config.SectionParser<CommitConfig> KEY = CommitConfig::new;

private final static Charset DEFAULT_COMMIT_MESSAGE_ENCODING = StandardCharsets.UTF_8;

private String i18nCommitEncoding;

private String commitTemplatePath;

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);
}

/**
* Get the path to the commit template as defined in the git
* {@code commit.template} property.
*
* @return the path to commit template or {@code null} if not present.
*/
@Nullable
public String getCommitTemplatePath() {
return commitTemplatePath;
}

/**
* Get the encoding of the commit as defined in the git
* {@code i18n.commitEncoding} property.
*
* @return the encoding or {@code null} if not present.
*/
@Nullable
public String getCommitEncoding() {
return i18nCommitEncoding;
}

/**
* 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.
*
* @return content of the commit template or {@code null} if not present.
* @throws IOException
* if the template file can not be read
* @throws FileNotFoundException
* if the template file does not exists
* @throws ConfigInvalidException
* if a {@code commitEncoding} is specified and is invalid
*/
@Nullable
public String getCommitTemplateContent()
throws FileNotFoundException, IOException, ConfigInvalidException {

if (commitTemplatePath != null) {
Charset commitMessageEncoding = getEncoding();

File commitTemplateFile;
if (commitTemplatePath.startsWith("~/")) { //$NON-NLS-1$
commitTemplateFile = FS.DETECTED.resolve(FS.DETECTED.userHome(),
commitTemplatePath.substring(2));
} else {
commitTemplateFile = FS.DETECTED.resolve(null,
commitTemplatePath);
}
return RawParseUtils.decode(commitMessageEncoding,
IO.readFully(commitTemplateFile));
}
return null;
}

private Charset getEncoding() throws ConfigInvalidException {
Charset commitMessageEncoding = DEFAULT_COMMIT_MESSAGE_ENCODING;

if (i18nCommitEncoding != null) {
try {
commitMessageEncoding = Charset.forName(i18nCommitEncoding);
} catch (IllegalCharsetNameException
| UnsupportedCharsetException e) {
throw new ConfigInvalidException(
MessageFormat.format(JGitText.get().invalidEncoding,
i18nCommitEncoding),
e);
}
}
return commitMessageEncoding;
}
}

+ 14
- 0
org.eclipse.jgit/src/org/eclipse/jgit/lib/ConfigConstants.java View File

@@ -124,6 +124,13 @@ public final class ConfigConstants {
*/
public static final String CONFIG_COMMIT_SECTION = "commit";

/**
* The "template" key
*
* @since 5.12
*/
public static final String CONFIG_KEY_COMMIT_TEMPLATE = "template";

/**
* The "tag" section
*
@@ -517,6 +524,13 @@ public final class ConfigConstants {
*/
public static final String CONFIG_SECTION_I18N = "i18n";

/**
* The "commitEncoding" key
*
* @since 5.12
*/
public static final String CONFIG_KEY_COMMIT_ENCODING = "commitEncoding";

/**
* The "logOutputEncoding" key
*

Loading…
Cancel
Save