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