001/* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, 013 * software distributed under the License is distributed on an 014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 015 * KIND, either express or implied. See the License for the 016 * specific language governing permissions and limitations 017 * under the License. 018 */ 019package org.apache.maven.scm.provider.git.jgit.command.checkin; 020 021import java.io.File; 022import java.io.FileWriter; 023import java.io.IOException; 024import java.io.PrintWriter; 025 026import org.apache.maven.scm.ScmException; 027import org.apache.maven.scm.ScmFileSet; 028import org.apache.maven.scm.command.add.AddScmResult; 029import org.apache.maven.scm.command.checkin.CheckInScmResult; 030import org.apache.maven.scm.provider.git.GitScmTestUtils; 031import org.apache.maven.scm.provider.git.command.checkin.GitCheckInCommandTckTest; 032import org.apache.maven.scm.provider.git.jgit.command.JGitUtils; 033import org.apache.maven.scm.repository.ScmRepository; 034import org.codehaus.plexus.util.IOUtil; 035import org.eclipse.jgit.api.Git; 036import org.eclipse.jgit.lib.AnyObjectId; 037import org.eclipse.jgit.lib.Config; 038import org.eclipse.jgit.lib.Constants; 039import org.eclipse.jgit.lib.Repository; 040import org.eclipse.jgit.lib.StoredConfig; 041import org.eclipse.jgit.revwalk.RevCommit; 042import org.eclipse.jgit.revwalk.RevWalk; 043import org.eclipse.jgit.storage.file.FileBasedConfig; 044import org.eclipse.jgit.util.FS; 045import org.eclipse.jgit.util.FileUtils; 046import org.eclipse.jgit.util.SystemReader; 047import org.junit.After; 048import org.junit.Before; 049import org.junit.Test; 050 051import static org.junit.Assert.assertEquals; 052import static org.junit.Assert.assertFalse; 053import static org.junit.Assert.assertNotNull; 054import static org.junit.Assert.assertTrue; 055 056/** 057 * @author Dominik Bartholdi (imod) 058 */ 059public class JGitCheckInCommandCommitterAuthorTckTest extends GitCheckInCommandTckTest { 060 061 @Before 062 @Override 063 public void setUp() throws Exception { 064 super.setUp(); 065 066 SystemReader.setInstance(new CustomSystemReader()); 067 } 068 069 @After 070 @Override 071 public void tearDown() throws Exception { 072 super.tearDown(); 073 074 // back to default 075 SystemReader.setInstance(null); 076 } 077 078 /** 079 * {@inheritDoc} 080 */ 081 public String getScmUrl() throws Exception { 082 return GitScmTestUtils.getScmUrl(getRepositoryRoot(), "jgit"); 083 } 084 085 @Override 086 protected void deleteDirectory(File directory) throws IOException { 087 if (directory.exists()) { 088 FileUtils.delete(directory, FileUtils.RECURSIVE | FileUtils.RETRY); 089 } 090 } 091 092 @Override 093 @Test 094 public void testCheckInCommandTest() throws Exception { 095 File fooJava = new File(getWorkingCopy(), "src/main/java/Foo.java"); 096 assertFalse("check Foo.java doesn't yet exist", fooJava.canRead()); 097 098 Git git = Git.open(getWorkingCopy()); 099 100 RevCommit head = getHeadCommit(git.getRepository()); 101 // Mark created the test repo... 102 assertEquals("Mark Struberg", head.getCommitterIdent().getName()); 103 JGitUtils.closeRepo(git); 104 105 createAndCommitFile(fooJava, null); 106 107 // change user in config 108 git = Git.open(getWorkingCopy()); 109 StoredConfig config = git.getRepository().getConfig(); 110 unsetConfig(config); 111 config.setString("user", null, "name", "Dominik"); 112 config.setString("user", null, "email", "domi@mycomp.com"); 113 config.save(); 114 115 // make a commit 116 createAndCommitFile(fooJava, null); 117 118 // check new commit is done with new user in config 119 head = getHeadCommit(git.getRepository()); 120 assertEquals("Dominik", head.getCommitterIdent().getName()); 121 assertEquals("Dominik", head.getAuthorIdent().getName()); 122 assertEquals("domi@mycomp.com", head.getAuthorIdent().getEmailAddress()); 123 assertEquals("domi@mycomp.com", head.getCommitterIdent().getEmailAddress()); 124 JGitUtils.closeRepo(git); 125 126 // change user in config 127 git = Git.open(getWorkingCopy()); 128 config = git.getRepository().getConfig(); 129 unsetConfig(config); 130 config.setString("user", null, "name", "dbartholdi"); 131 config.save(); 132 133 // make a change 134 createAndCommitFile(fooJava, null); 135 136 // check new commit is done with new user in config 137 head = getHeadCommit(git.getRepository()); 138 assertEquals("dbartholdi", head.getCommitterIdent().getName()); 139 assertFalse( 140 "no mail domain is configured, git system default should be used", 141 head.getCommitterIdent().getEmailAddress().contains("dbartholdi")); 142 JGitUtils.closeRepo(git); 143 144 // unset a user and maven user but set default mail domain 145 git = Git.open(getWorkingCopy()); 146 config = git.getRepository().getConfig(); 147 unsetConfig(config); 148 config.setString(JGitCheckInCommand.GIT_MAVEN_SECTION, null, JGitCheckInCommand.GIT_MAILDOMAIN, "comp.com"); 149 config.save(); 150 151 // make a change with an user on the commandline 152 createAndCommitFile(fooJava, "dude"); 153 154 // check new commit is done with new maven user in config 155 head = getHeadCommit(git.getRepository()); 156 assertEquals("dude", head.getCommitterIdent().getName()); 157 assertEquals("dude@comp.com", head.getCommitterIdent().getEmailAddress()); 158 assertEquals("dude", head.getAuthorIdent().getName()); 159 assertEquals("dude@comp.com", head.getAuthorIdent().getEmailAddress()); 160 JGitUtils.closeRepo(git); 161 162 // unset a user and maven user but set default mail domain 163 git = Git.open(getWorkingCopy()); 164 config = git.getRepository().getConfig(); 165 unsetConfig(config); 166 config.setString("user", null, "name", "dbartholdi"); 167 config.setBoolean(JGitCheckInCommand.GIT_MAVEN_SECTION, null, JGitCheckInCommand.GIT_FORCE, true); 168 config.setString(JGitCheckInCommand.GIT_MAVEN_SECTION, null, JGitCheckInCommand.GIT_MAILDOMAIN, "anycomp.com"); 169 config.save(); 170 171 // make a change with an user on the commandline 172 createAndCommitFile(fooJava, "dude"); 173 174 // check new commit is done with new maven user in config 175 head = getHeadCommit(git.getRepository()); 176 assertEquals("dude", head.getCommitterIdent().getName()); 177 assertEquals("dude@anycomp.com", head.getCommitterIdent().getEmailAddress()); 178 assertEquals("dude", head.getAuthorIdent().getName()); 179 assertEquals("dude@anycomp.com", head.getAuthorIdent().getEmailAddress()); 180 JGitUtils.closeRepo(git); 181 182 // unset a user and maven user but set default mail domain 183 git = Git.open(getWorkingCopy()); 184 config = git.getRepository().getConfig(); 185 unsetConfig(config); 186 config.setString(JGitCheckInCommand.GIT_MAVEN_SECTION, null, JGitCheckInCommand.GIT_MAILDOMAIN, "anycomp.com"); 187 config.save(); 188 189 // make a change with no username given 190 createAndCommitFile(fooJava, null); 191 192 // check new commit does not contain the configured email domain 193 head = getHeadCommit(git.getRepository()); 194 assertFalse(head.getCommitterIdent().getEmailAddress().contains("anycomp.com")); 195 assertFalse(head.getAuthorIdent().getEmailAddress().contains("anycomp.com")); 196 JGitUtils.closeRepo(git); 197 198 // unset a user and full maven section 199 git = Git.open(getWorkingCopy()); 200 config = git.getRepository().getConfig(); 201 unsetConfig(config); 202 config.save(); 203 204 // make a change with an user on the commandline 205 createAndCommitFile(fooJava, "dundy"); 206 207 // check new commit is done with new maven user in config 208 head = getHeadCommit(git.getRepository()); 209 assertEquals("dundy", head.getCommitterIdent().getName()); 210 assertEquals("dundy", head.getAuthorIdent().getName()); 211 assertTrue( 212 "the maven user (from parameter) name must be in the committer mail when nothing else is configured", 213 head.getCommitterIdent().getEmailAddress().contains("dundy")); 214 assertTrue( 215 "the user name (from parameter) must be in the author mail when nothing else is configured", 216 head.getAuthorIdent().getEmailAddress().contains("dundy")); 217 JGitUtils.closeRepo(git); 218 219 // unset all configs 220 git = Git.open(getWorkingCopy()); 221 config = git.getRepository().getConfig(); 222 unsetConfig(config); 223 config.save(); 224 225 // make a change with no user on the commandline 226 createAndCommitFile(fooJava, null); 227 228 // check new commit is has a committer/author with email set 229 head = getHeadCommit(git.getRepository()); 230 assertNotNull(head.getCommitterIdent().getName()); 231 assertNotNull(head.getAuthorIdent().getName()); 232 assertNotNull(head.getCommitterIdent().getEmailAddress()); 233 assertNotNull(head.getAuthorIdent().getEmailAddress()); 234 JGitUtils.closeRepo(git); 235 } 236 237 /** 238 * make sure the local .gitconfig is in a clean state 239 */ 240 private void unsetConfig(StoredConfig config) { 241 config.unsetSection("user", null); 242 config.unset("user", null, "name"); 243 // somehow unset does not always work on "user" 244 config.setString("user", null, "name", null); 245 config.setString("user", null, "email", null); 246 config.unsetSection(JGitCheckInCommand.GIT_MAVEN_SECTION, null); 247 } 248 249 private void createAndCommitFile(File file, String username) throws Exception, ScmException, IOException { 250 createFooJava(file); 251 252 ScmRepository scmRepository = getScmRepository(); 253 scmRepository.getProviderRepository().setUser(username); 254 AddScmResult addResult = getScmManager().add(scmRepository, new ScmFileSet(getWorkingCopy(), "**/*.java")); 255 256 assertResultIsSuccess(addResult); 257 258 CheckInScmResult result = getScmManager() 259 .checkIn(scmRepository, new ScmFileSet(getWorkingCopy(), "**/Foo.java"), "Commit message"); 260 261 assertResultIsSuccess(result); 262 } 263 264 private RevCommit getHeadCommit(Repository repository) throws Exception { 265 RevWalk rw = new RevWalk(repository); 266 AnyObjectId headId = repository.resolve(Constants.HEAD); 267 RevCommit head = rw.parseCommit(headId); 268 rw.close(); 269 return head; 270 } 271 272 private void createFooJava(File fooJava) throws Exception { 273 FileWriter output = new FileWriter(fooJava); 274 275 PrintWriter printer = new PrintWriter(output); 276 try { 277 printer.println("public class Foo"); 278 printer.println("{"); 279 280 printer.println(" public void foo()"); 281 printer.println(" {"); 282 printer.println(" //" + System.currentTimeMillis()); 283 printer.println(" int i = 10;"); 284 printer.println(" }"); 285 286 printer.println("}"); 287 } finally { 288 IOUtil.close(output); 289 IOUtil.close(printer); 290 } 291 } 292 293 /** 294 * SystemReader for testing to have full control some imported getters 295 * 296 * @author Robert Scholte 297 */ 298 class CustomSystemReader extends SystemReader { 299 300 private final SystemReader reader = SystemReader.getInstance(); 301 302 // Ensure environment properties from CI server don't get pulled in 303 public String getenv(String variable) { 304 return null; 305 } 306 307 @Override 308 public String getHostname() { 309 return reader.getHostname(); 310 } 311 312 @Override 313 public String getProperty(String key) { 314 return reader.getProperty(key); 315 } 316 317 @Override 318 public FileBasedConfig openSystemConfig(Config parent, FS fs) { 319 return reader.openSystemConfig(parent, fs); 320 } 321 322 @Override 323 public FileBasedConfig openUserConfig(Config parent, FS fs) { 324 return reader.openUserConfig(parent, fs); 325 } 326 327 @Override 328 public long getCurrentTime() { 329 return reader.getCurrentTime(); 330 } 331 332 @Override 333 public int getTimezone(long when) { 334 return reader.getTimezone(when); 335 } 336 337 @Override 338 public FileBasedConfig openJGitConfig(Config config, FS fs) { 339 return reader.openJGitConfig(config, fs); 340 } 341 } 342}