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
import static org.junit.Assert.fail; | import static org.junit.Assert.fail; | ||||
import java.io.File; | import java.io.File; | ||||
import java.io.FileNotFoundException; | |||||
import java.io.IOException; | import java.io.IOException; | ||||
import java.nio.file.Files; | import java.nio.file.Files; | ||||
import java.text.MessageFormat; | import java.text.MessageFormat; | ||||
import org.eclipse.jgit.api.MergeCommand.FastForwardMode; | import org.eclipse.jgit.api.MergeCommand.FastForwardMode; | ||||
import org.eclipse.jgit.errors.ConfigInvalidException; | import org.eclipse.jgit.errors.ConfigInvalidException; | ||||
import org.eclipse.jgit.internal.JGitText; | import org.eclipse.jgit.internal.JGitText; | ||||
import org.eclipse.jgit.junit.JGitTestUtil; | |||||
import org.eclipse.jgit.junit.MockSystemReader; | import org.eclipse.jgit.junit.MockSystemReader; | ||||
import org.eclipse.jgit.merge.MergeConfig; | import org.eclipse.jgit.merge.MergeConfig; | ||||
import org.eclipse.jgit.storage.file.FileBasedConfig; | import org.eclipse.jgit.storage.file.FileBasedConfig; | ||||
assertEquals("tr ue", parseEscapedValue("tr \\\r\n ue")); | 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) | private static void assertValueRoundTrip(String value) | ||||
throws ConfigInvalidException { | throws ConfigInvalidException { | ||||
assertValueRoundTrip(value, value); | assertValueRoundTrip(value, value); |
invalidChannel=Invalid channel {0} | invalidChannel=Invalid channel {0} | ||||
invalidCommitParentNumber=Invalid commit parent number | invalidCommitParentNumber=Invalid commit parent number | ||||
invalidDepth=Invalid depth: {0} | invalidDepth=Invalid depth: {0} | ||||
invalidEncoding=Invalid encoding from git config i18n.commitEncoding: {0} | |||||
invalidEncryption=Invalid encryption | invalidEncryption=Invalid encryption | ||||
invalidExpandWildcard=ExpandFromSource on a refspec that can have mismatched wildcards does not make sense. | invalidExpandWildcard=ExpandFromSource on a refspec that can have mismatched wildcards does not make sense. | ||||
invalidFilter=Invalid filter: {0} | invalidFilter=Invalid filter: {0} |
/***/ public String invalidChannel; | /***/ public String invalidChannel; | ||||
/***/ public String invalidCommitParentNumber; | /***/ public String invalidCommitParentNumber; | ||||
/***/ public String invalidDepth; | /***/ public String invalidDepth; | ||||
/***/ public String invalidEncoding; | |||||
/***/ public String invalidEncryption; | /***/ public String invalidEncryption; | ||||
/***/ public String invalidExpandWildcard; | /***/ public String invalidExpandWildcard; | ||||
/***/ public String invalidFilter; | /***/ public String invalidFilter; |
/* | |||||
* 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; | |||||
} | |||||
} |
*/ | */ | ||||
public static final String CONFIG_COMMIT_SECTION = "commit"; | 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 | * The "tag" section | ||||
* | * | ||||
*/ | */ | ||||
public static final String CONFIG_SECTION_I18N = "i18n"; | 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 | * The "logOutputEncoding" key | ||||
* | * |