View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.maven.scm.provider.git.jgit.command.checkin;
20  
21  import java.io.File;
22  import java.io.FileWriter;
23  import java.io.IOException;
24  import java.io.PrintWriter;
25  
26  import org.apache.maven.scm.ScmException;
27  import org.apache.maven.scm.ScmFileSet;
28  import org.apache.maven.scm.command.add.AddScmResult;
29  import org.apache.maven.scm.command.checkin.CheckInScmResult;
30  import org.apache.maven.scm.provider.git.GitScmTestUtils;
31  import org.apache.maven.scm.provider.git.command.checkin.GitCheckInCommandTckTest;
32  import org.apache.maven.scm.provider.git.jgit.command.JGitUtils;
33  import org.apache.maven.scm.repository.ScmRepository;
34  import org.codehaus.plexus.util.IOUtil;
35  import org.eclipse.jgit.api.Git;
36  import org.eclipse.jgit.lib.AnyObjectId;
37  import org.eclipse.jgit.lib.Config;
38  import org.eclipse.jgit.lib.Constants;
39  import org.eclipse.jgit.lib.Repository;
40  import org.eclipse.jgit.lib.StoredConfig;
41  import org.eclipse.jgit.revwalk.RevCommit;
42  import org.eclipse.jgit.revwalk.RevWalk;
43  import org.eclipse.jgit.storage.file.FileBasedConfig;
44  import org.eclipse.jgit.util.FS;
45  import org.eclipse.jgit.util.FileUtils;
46  import org.eclipse.jgit.util.SystemReader;
47  import org.junit.After;
48  import org.junit.Before;
49  import org.junit.Test;
50  
51  import static org.junit.Assert.assertEquals;
52  import static org.junit.Assert.assertFalse;
53  import static org.junit.Assert.assertNotNull;
54  import static org.junit.Assert.assertTrue;
55  
56  /**
57   * @author Dominik Bartholdi (imod)
58   */
59  public class JGitCheckInCommandCommitterAuthorTckTest extends GitCheckInCommandTckTest {
60  
61      @Before
62      @Override
63      public void setUp() throws Exception {
64          super.setUp();
65  
66          SystemReader.setInstance(new CustomSystemReader());
67      }
68  
69      @After
70      @Override
71      public void tearDown() throws Exception {
72          super.tearDown();
73  
74          // back to default
75          SystemReader.setInstance(null);
76      }
77  
78      /**
79       * {@inheritDoc}
80       */
81      public String getScmUrl() throws Exception {
82          return GitScmTestUtils.getScmUrl(getRepositoryRoot(), "jgit");
83      }
84  
85      @Override
86      protected void deleteDirectory(File directory) throws IOException {
87          if (directory.exists()) {
88              FileUtils.delete(directory, FileUtils.RECURSIVE | FileUtils.RETRY);
89          }
90      }
91  
92      @Override
93      @Test
94      public void testCheckInCommandTest() throws Exception {
95          File fooJava = new File(getWorkingCopy(), "src/main/java/Foo.java");
96          assertFalse("check Foo.java doesn't yet exist", fooJava.canRead());
97  
98          Git git = Git.open(getWorkingCopy());
99  
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 }