Repository: maven-scm
Updated Branches:
  refs/heads/master abea2d9c8 -> 037ba69bc


SCM-765 fix JGit provider to use the correct commiter/author when committing 
changes


Project: http://git-wip-us.apache.org/repos/asf/maven-scm/repo
Commit: http://git-wip-us.apache.org/repos/asf/maven-scm/commit/6a4ccf50
Tree: http://git-wip-us.apache.org/repos/asf/maven-scm/tree/6a4ccf50
Diff: http://git-wip-us.apache.org/repos/asf/maven-scm/diff/6a4ccf50

Branch: refs/heads/master
Commit: 6a4ccf507b73d92d33ee050dac8e2d977f7fb245
Parents: 692b76a
Author: imod <[email protected]>
Authored: Fri Jul 18 00:45:07 2014 +0200
Committer: imod <[email protected]>
Committed: Fri Jul 18 00:45:07 2014 +0200

----------------------------------------------------------------------
 .../command/checkin/JGitCheckInCommand.java     | 155 +++++++++++-
 ...GitCheckInCommandCommitterAuthorTckTest.java | 246 +++++++++++++++++++
 2 files changed, 400 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/maven-scm/blob/6a4ccf50/maven-scm-providers/maven-scm-providers-git/maven-scm-provider-jgit/src/main/java/org/apache/maven/scm/provider/git/jgit/command/checkin/JGitCheckInCommand.java
----------------------------------------------------------------------
diff --git 
a/maven-scm-providers/maven-scm-providers-git/maven-scm-provider-jgit/src/main/java/org/apache/maven/scm/provider/git/jgit/command/checkin/JGitCheckInCommand.java
 
b/maven-scm-providers/maven-scm-providers-git/maven-scm-provider-jgit/src/main/java/org/apache/maven/scm/provider/git/jgit/command/checkin/JGitCheckInCommand.java
index 98c0f98..7e91cf0 100644
--- 
a/maven-scm-providers/maven-scm-providers-git/maven-scm-provider-jgit/src/main/java/org/apache/maven/scm/provider/git/jgit/command/checkin/JGitCheckInCommand.java
+++ 
b/maven-scm-providers/maven-scm-providers-git/maven-scm-provider-jgit/src/main/java/org/apache/maven/scm/provider/git/jgit/command/checkin/JGitCheckInCommand.java
@@ -33,15 +33,37 @@ import org.codehaus.plexus.util.StringUtils;
 import org.eclipse.jgit.api.AddCommand;
 import org.eclipse.jgit.api.Git;
 import org.eclipse.jgit.lib.Constants;
+import org.eclipse.jgit.lib.UserConfig;
 import org.eclipse.jgit.revwalk.RevCommit;
 import org.eclipse.jgit.transport.RefSpec;
 
 import java.io.File;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
 import java.util.Collections;
 import java.util.List;
 import java.util.Set;
 
 /**
+ * This provider uses the following strategy to discover the committer and 
author name/mail for a commit:
+ * <ol>
+ *   <li>"maven-scm" section in .gitconfig</li>
+ *   <li>"user" section in .gitconfig</li>
+ *   <li>"username" passed to maven execution</li>
+ *   <li>default git config (system user and hostname for email)</li>
+ * </ol>
+ * 
+ * the "maven-scm" config can be configured like this:
+ * 
+ * the user to be used:<br>
+ * <code>git config --global maven-scm.name "dude"</code>
+ * <br>
+ * <code>git config --global maven-scm.email "[email protected]"</code>
+ * <br>
+ * the default email domain to be used (will be used to create an email from 
the username passed to maven):<br>
+ * <code>git config --global maven-scm.maildomain "mycomp.com"</code>
+ * <br>
+ * 
  * @author <a href="mailto:[email protected]";>Mark Struberg</a>
  * @author Dominik Bartholdi (imod)
  * @since 1.9
@@ -50,6 +72,15 @@ public class JGitCheckInCommand
     extends AbstractCheckInCommand
     implements GitCommand
 {
+       
+       protected static final String GIT_MAVEN_SECTION = "maven-scm";
+       
+       protected static final String GIT_USERNAME = "name";
+       
+       protected static final String GIT_EMAIL = "email";
+       
+       protected static final String GIT_MAILDOMAIN = "maildomain";
+       
     /**
      * {@inheritDoc}
      */
@@ -96,7 +127,10 @@ public class JGitCheckInCommand
             List<ScmFile> checkedInFiles = Collections.emptyList();
             if ( doCommit )
             {
-                RevCommit commitRev = git.commit().setMessage( message 
).call();
+               UserInfo author = getAuthor(repo, git);
+               UserInfo committer = getCommitter(repo, git);
+               
+                RevCommit commitRev = git.commit().setMessage( message 
).setAuthor(author.name, author.email).setCommitter(committer.name, 
committer.email).call();
                 getLogger().info( "commit done: " + 
commitRev.getShortMessage() );
                 checkedInFiles = JGitUtils.getFilesInCommit( 
git.getRepository(), commitRev );
                 if ( getLogger().isDebugEnabled() )
@@ -132,4 +166,123 @@ public class JGitCheckInCommand
         }
     }
 
+    private static final class UserInfo 
+    {
+       final String name;
+       final String email;
+       
+       public UserInfo(String name, String email) 
+       {
+                       this.name = name;
+                       this.email = email;
+               }
+    }
+    
+    private UserInfo getCommitter( ScmProviderRepository repo, Git git ) 
+    {
+       // mvn scm git config
+       String committerName = git.getRepository().getConfig().getString( 
GIT_MAVEN_SECTION, null, GIT_USERNAME );
+       
+       // git config
+       UserConfig user = git.getRepository().getConfig().get(UserConfig.KEY);
+       if ( StringUtils.isBlank( committerName ) && 
!user.isCommitterNameImplicit() )
+       {
+               committerName = user.getCommitterName();
+       }
+       
+       // mvn parameter
+       if ( StringUtils.isBlank( committerName ) )
+       {
+               committerName = repo.getUser();
+       }
+       
+       // git default
+       if ( StringUtils.isBlank( committerName ) )
+       {
+               committerName = user.getCommitterName();
+       }
+       
+
+       // maven scm git config
+       String committerMail = git.getRepository().getConfig().getString( 
GIT_MAVEN_SECTION, null, GIT_EMAIL );
+       
+       // git config
+       if ( StringUtils.isBlank( committerMail ) && 
!user.isCommitterEmailImplicit() )
+       {
+               committerMail = user.getCommitterEmail();
+       }
+       
+       if ( StringUtils.isBlank( committerMail ) )
+       {
+               String defaultDomain = 
git.getRepository().getConfig().getString( GIT_MAVEN_SECTION, null, 
GIT_MAILDOMAIN );
+               defaultDomain = StringUtils.isNotBlank( defaultDomain ) ? 
defaultDomain : getHostname();
+
+               // mvn parameter (constructed with username) or git default
+               committerMail = StringUtils.isNotBlank( repo.getUser() ) ? 
repo.getUser() + "@" + defaultDomain : user.getCommitterEmail();
+       }
+       
+       return new UserInfo( committerName, committerMail );
+    }
+    
+    private UserInfo getAuthor( ScmProviderRepository repo, Git git ) 
+    {
+               // mvn scm config
+       String authorName = git.getRepository().getConfig().getString( 
GIT_MAVEN_SECTION, null, GIT_USERNAME );
+       
+       // git config
+       UserConfig user = git.getRepository().getConfig().get(UserConfig.KEY);
+       if ( StringUtils.isBlank( authorName ) && !user.isAuthorNameImplicit() )
+       {
+               authorName = user.getAuthorName();
+       }
+       
+       // mvn parameter
+       if ( StringUtils.isBlank( authorName ) )
+       {
+               authorName = repo.getUser();
+       }
+       
+       // git default
+       if ( StringUtils.isBlank( authorName ) )
+       {
+               authorName = user.getAuthorName();
+       }
+       
+       // maven scm git config
+       String authorMail = git.getRepository().getConfig().getString( 
GIT_MAVEN_SECTION, null, GIT_EMAIL );
+       
+       // git config
+       if ( StringUtils.isBlank( authorMail ) && !user.isAuthorEmailImplicit() 
)
+       {
+               authorMail = user.getAuthorEmail();
+       }
+       
+       if ( StringUtils.isBlank( authorMail ) )
+       {
+               String defaultDomain = 
git.getRepository().getConfig().getString( GIT_MAVEN_SECTION, null, 
GIT_MAILDOMAIN );
+               defaultDomain = StringUtils.isNotBlank( defaultDomain ) ? 
defaultDomain : getHostname();
+
+               // mvn parameter (constructed with username) or git default
+               authorMail = StringUtils.isNotBlank( repo.getUser() ) ? 
repo.getUser() + "@" + defaultDomain : user.getAuthorEmail();
+       }
+       
+       return new UserInfo( authorName, authorMail );
+    }
+    
+       private String getHostname() 
+       {
+               String hostname;
+               try 
+               {
+                       InetAddress localhost = 
java.net.InetAddress.getLocalHost();
+                       hostname = localhost.getHostName();
+               } 
+               catch ( UnknownHostException e ) 
+               {
+                       getLogger().warn( "failed to resolve hostname to create 
mail address, defaulting to 'maven-scm-provider-jgit'" );
+                       hostname = "maven-scm-provider-jgit";
+               }
+               return hostname;
+       }
+
 }

http://git-wip-us.apache.org/repos/asf/maven-scm/blob/6a4ccf50/maven-scm-providers/maven-scm-providers-git/maven-scm-provider-jgit/src/test/java/org/apache/maven/scm/provider/git/jgit/command/checkin/JGitCheckInCommandCommitterAuthorTckTest.java
----------------------------------------------------------------------
diff --git 
a/maven-scm-providers/maven-scm-providers-git/maven-scm-provider-jgit/src/test/java/org/apache/maven/scm/provider/git/jgit/command/checkin/JGitCheckInCommandCommitterAuthorTckTest.java
 
b/maven-scm-providers/maven-scm-providers-git/maven-scm-provider-jgit/src/test/java/org/apache/maven/scm/provider/git/jgit/command/checkin/JGitCheckInCommandCommitterAuthorTckTest.java
new file mode 100644
index 0000000..260be1c
--- /dev/null
+++ 
b/maven-scm-providers/maven-scm-providers-git/maven-scm-provider-jgit/src/test/java/org/apache/maven/scm/provider/git/jgit/command/checkin/JGitCheckInCommandCommitterAuthorTckTest.java
@@ -0,0 +1,246 @@
+package org.apache.maven.scm.provider.git.jgit.command.checkin;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.PrintWriter;
+
+import org.apache.maven.scm.ScmException;
+import org.apache.maven.scm.ScmFileSet;
+import org.apache.maven.scm.command.add.AddScmResult;
+import org.apache.maven.scm.command.checkin.CheckInScmResult;
+import org.apache.maven.scm.provider.git.GitScmTestUtils;
+import 
org.apache.maven.scm.provider.git.command.checkin.GitCheckInCommandTckTest;
+import org.apache.maven.scm.provider.git.jgit.command.JGitUtils;
+import org.apache.maven.scm.repository.ScmRepository;
+import org.codehaus.plexus.util.IOUtil;
+import org.eclipse.jgit.api.Git;
+import org.eclipse.jgit.lib.AnyObjectId;
+import org.eclipse.jgit.lib.Constants;
+import org.eclipse.jgit.lib.Repository;
+import org.eclipse.jgit.lib.StoredConfig;
+import org.eclipse.jgit.revwalk.RevCommit;
+import org.eclipse.jgit.revwalk.RevWalk;
+import org.eclipse.jgit.util.FileUtils;
+
+/**
+ * @author Dominik Bartholdi (imod)
+ */
+public class JGitCheckInCommandCommitterAuthorTckTest
+    extends GitCheckInCommandTckTest
+{
+    /**
+     * {@inheritDoc}
+     */
+    public String getScmUrl()
+        throws Exception
+    {
+        return GitScmTestUtils.getScmUrl( getRepositoryRoot(), "jgit" );
+    }
+
+    @Override
+    protected void deleteDirectory( File directory )
+        throws IOException
+    {
+        if( directory.exists() )
+        {
+            FileUtils.delete( directory, FileUtils.RECURSIVE | FileUtils.RETRY 
);
+        }
+    }
+    
+    @Override
+    public void testCheckInCommandTest() throws Exception 
+    {
+       File fooJava = new File( getWorkingCopy(), "src/main/java/Foo.java" );
+       assertFalse( "check Foo.java doesn't yet exist", fooJava.canRead() );
+
+       Git git = Git.open( getWorkingCopy() );
+
+       RevCommit head = getHeadCommit( git.getRepository() );
+       // Mark created the test repo...
+       assertEquals( "Mark Struberg", head.getCommitterIdent().getName() );
+       JGitUtils.closeRepo(git);
+
+        createAndCommitFile( fooJava, null );
+        
+        // change user in config 
+        git = Git.open( getWorkingCopy() );
+        StoredConfig config = git.getRepository().getConfig();
+        unsetConfig(config);
+               config.setString( "user", null, "name", "Dominik" );
+               config.setString( "user", null, "email", "[email protected]" );
+               config.save();
+        
+               // make a commit
+               createAndCommitFile( fooJava, null );
+               
+               // check new commit is done with new user in config
+       head = getHeadCommit( git.getRepository() );
+       assertEquals( "Dominik", head.getCommitterIdent().getName() );
+       assertEquals( "Dominik", head.getAuthorIdent().getName() );
+       assertEquals( "[email protected]", 
head.getAuthorIdent().getEmailAddress() );
+       assertEquals( "[email protected]", 
head.getCommitterIdent().getEmailAddress() );
+       JGitUtils.closeRepo( git );
+
+       
+        // change user in config 
+        git = Git.open( getWorkingCopy() );
+        config = git.getRepository().getConfig();
+        unsetConfig(config);
+               config.setString( "user", null, "name", "dbartholdi" );
+               config.save();
+
+               // make a change
+               createAndCommitFile( fooJava, null );
+               
+               // check new commit is done with new user in config
+       head = getHeadCommit( git.getRepository() );
+       assertEquals( "dbartholdi", head.getCommitterIdent().getName() );
+       assertFalse( "no mail domain is configured, git system default should 
be used", head.getCommitterIdent().getEmailAddress().contains( "dbartholdi" ) );
+       JGitUtils.closeRepo( git );             
+
+       
+       
+       // set a user in the maven section of the git config 
+        git = Git.open( getWorkingCopy() );
+        config = git.getRepository().getConfig();
+        unsetConfig(config);
+               config.setString( JGitCheckInCommand.GIT_MAVEN_SECTION, null, 
JGitCheckInCommand.GIT_USERNAME, "Dude" );
+               config.setString( JGitCheckInCommand.GIT_MAVEN_SECTION, null, 
JGitCheckInCommand.GIT_EMAIL, "[email protected]" );
+               config.save();
+               
+               // make a change
+               createAndCommitFile( fooJava, null );
+                               
+               // check new commit is done with new maven user in config
+       head = getHeadCommit( git.getRepository() );
+       assertEquals( "Dude", head.getCommitterIdent().getName() );
+       assertEquals( "Dude", head.getAuthorIdent().getName() );
+       assertEquals( "[email protected]", 
head.getCommitterIdent().getEmailAddress() );
+       assertEquals( "[email protected]", 
head.getAuthorIdent().getEmailAddress() );
+       JGitUtils.closeRepo( git );             
+       
+       
+       // unset a user and maven user but set default mail domain 
+        git = Git.open( getWorkingCopy() );
+        config = git.getRepository().getConfig();
+        unsetConfig(config);
+               config.setString( JGitCheckInCommand.GIT_MAVEN_SECTION, null, 
JGitCheckInCommand.GIT_MAILDOMAIN, "comp.com" );
+               config.save();
+
+               // make a change with an user on the commandline
+               createAndCommitFile( fooJava, "dude" );
+                               
+               // check new commit is done with new maven user in config
+       head = getHeadCommit( git.getRepository() );
+       assertEquals( "dude", head.getCommitterIdent().getName() );
+       assertEquals( "[email protected]", 
head.getCommitterIdent().getEmailAddress() );
+       assertEquals( "dude", head.getAuthorIdent().getName() );
+       assertEquals( "[email protected]", head.getAuthorIdent().getEmailAddress() 
);       
+       JGitUtils.closeRepo( git );             
+
+       
+       // unset a user and full maven section 
+        git = Git.open( getWorkingCopy() );
+        config = git.getRepository().getConfig();
+        unsetConfig(config);
+               config.save();
+               config.getString("user", null, "name");
+
+               // make a change with an user on the commandline
+               createAndCommitFile( fooJava, "dundy" );
+                               
+               // check new commit is done with new maven user in config
+       head = getHeadCommit( git.getRepository() );
+       assertEquals( "dundy", head.getCommitterIdent().getName() );
+       assertEquals( "dundy", head.getAuthorIdent().getName() );
+       assertTrue( "the maven user (from parameter) name must be in the 
committer mail when nothing else is configured", 
head.getCommitterIdent().getEmailAddress().contains( "dundy" ) );
+       assertTrue( "the user name (from parameter) must be in the author mail 
when nothing else is configured", 
head.getAuthorIdent().getEmailAddress().contains( "dundy" ) );
+       JGitUtils.closeRepo( git );
+    }
+
+       private void unsetConfig(StoredConfig config) {
+               config.unsetSection( "user", null );
+               config.unset( "user", null, "name" );
+               // somehow unset does not always work on "user"
+               config.setString("user", null, "name", null);
+               config.setString("user", null, "email", null);
+               config.unsetSection( JGitCheckInCommand.GIT_MAVEN_SECTION, null 
);
+       }
+    
+    
+    
+
+       private void createAndCommitFile(File file, String username) throws 
Exception,
+                       ScmException, IOException {
+               createFooJava( file );
+
+        ScmRepository scmRepository = getScmRepository();
+        scmRepository.getProviderRepository().setUser(username);
+               AddScmResult addResult = getScmManager().add( scmRepository,
+                                                      new ScmFileSet( 
getWorkingCopy(), "**/*.java" ) );
+
+        assertResultIsSuccess( addResult );
+
+        CheckInScmResult result =
+            getScmManager().checkIn( scmRepository, new ScmFileSet( 
getWorkingCopy(), "**/Foo.java" ), "Commit message" );
+
+        assertResultIsSuccess( result );
+       }
+    
+    
+    private RevCommit getHeadCommit(Repository repository) throws Exception
+    {
+               RevWalk rw = new RevWalk(repository);
+       AnyObjectId headId = repository.resolve(Constants.HEAD);
+       RevCommit head = rw.parseCommit(headId);
+       rw.release();;
+               return head;
+    }
+    
+    private void createFooJava( File fooJava )
+            throws Exception
+    {
+        FileWriter output = new FileWriter( fooJava );
+
+        PrintWriter printer = new PrintWriter( output );
+        try
+        {
+            printer.println( "public class Foo" );
+            printer.println( "{" );
+
+            printer.println( "    public void foo()" );
+            printer.println( "    {" );
+            printer.println( "        //" + System.currentTimeMillis() );
+            printer.println( "        int i = 10;" );
+            printer.println( "    }" );
+
+            printer.println( "}" );
+        }
+        finally
+        {
+            IOUtil.close( output );
+            IOUtil.close( printer );
+        }
+    }
+
+}

Reply via email to