You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@maven.apache.org by mi...@apache.org on 2022/07/28 17:53:49 UTC

[maven-scm] branch master updated: [SCM-992] Support explicitly configured SSH private key for gitexe provider

This is an automated email from the ASF dual-hosted git repository.

michaelo pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/maven-scm.git


The following commit(s) were added to refs/heads/master by this push:
     new e77e00179 [SCM-992] Support explicitly configured SSH private key for gitexe provider
e77e00179 is described below

commit e77e0017971857158d1c4358f5ae66a22ef848f8
Author: Konrad Windszus <kw...@apache.org>
AuthorDate: Mon Jul 25 10:56:06 2022 +0200

    [SCM-992] Support explicitly configured SSH private key for gitexe provider
    
    This closes #159
---
 .../git/gitexe/command/GitCommandLineUtils.java    | 46 +++++++++++++++++++---
 .../gitexe/command/checkin/GitCheckInCommand.java  | 25 ++++++------
 .../command/checkout/GitCheckOutCommand.java       | 11 ++++--
 .../command/remoteinfo/GitRemoteInfoCommand.java   |  3 +-
 ...argetTest.java => GitCommandLineUtilsTest.java} | 26 +++++++++++-
 5 files changed, 87 insertions(+), 24 deletions(-)

diff --git a/maven-scm-providers/maven-scm-providers-git/maven-scm-provider-gitexe/src/main/java/org/apache/maven/scm/provider/git/gitexe/command/GitCommandLineUtils.java b/maven-scm-providers/maven-scm-providers-git/maven-scm-provider-gitexe/src/main/java/org/apache/maven/scm/provider/git/gitexe/command/GitCommandLineUtils.java
index 2dc908b9e..0f0484cc6 100644
--- a/maven-scm-providers/maven-scm-providers-git/maven-scm-provider-gitexe/src/main/java/org/apache/maven/scm/provider/git/gitexe/command/GitCommandLineUtils.java
+++ b/maven-scm-providers/maven-scm-providers-git/maven-scm-provider-gitexe/src/main/java/org/apache/maven/scm/provider/git/gitexe/command/GitCommandLineUtils.java
@@ -22,8 +22,10 @@ package org.apache.maven.scm.provider.git.gitexe.command;
 import org.apache.commons.io.FilenameUtils;
 
 import org.apache.maven.scm.ScmException;
+import org.apache.maven.scm.provider.git.repository.GitScmProviderRepository;
 import org.apache.maven.scm.provider.git.util.GitUtil;
 import org.apache.maven.scm.providers.gitlib.settings.Settings;
+import org.codehaus.plexus.util.StringUtils;
 import org.codehaus.plexus.util.cli.CommandLineException;
 import org.codehaus.plexus.util.cli.CommandLineUtils;
 import org.codehaus.plexus.util.cli.Commandline;
@@ -33,7 +35,7 @@ import org.slf4j.LoggerFactory;
 
 import java.io.File;
 import java.io.IOException;
-import java.util.Collections;
+import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
@@ -48,6 +50,9 @@ public final class GitCommandLineUtils
 {
     private static final Logger LOGGER = LoggerFactory.getLogger( GitCommandLineUtils.class );
 
+    // https://git-scm.com/docs/git#Documentation/git.txt-codeGITSSHCOMMANDcode, requires git 2.3.0 or newer
+    public static final String VARIABLE_GIT_SSH_COMMAND = "GIT_SSH_COMMAND";
+
     private GitCommandLineUtils()
     {
     }
@@ -90,28 +95,36 @@ public final class GitCommandLineUtils
     }
 
    /**
-    *
+    * Use this only for commands not requiring environment variables (i.e. local commands).
     * @param workingDirectory
     * @param command
     * @return TODO
     */
    public static Commandline getBaseGitCommandLine( File workingDirectory, String command )
    {
-       return getBaseGitCommandLine( workingDirectory, command, Collections.emptyMap() );
+       return getBaseGitCommandLine( workingDirectory, command, null, null );
    }
 
     /**
-     *
+     * Use this for commands requiring environment variables (i.e. remote commands).
      * @param workingDirectory
      * @param command
      * @param environment
      * @return TODO
      */
     public static Commandline getBaseGitCommandLine( File workingDirectory, String command,
+                                                     GitScmProviderRepository repository,
                                                      Map<String, String> environment )
     {
         Commandline cl = getAnonymousBaseGitCommandLine( workingDirectory, command );
-        environment.forEach( cl::addEnvironment );
+        if ( repository != null )
+        {
+            prepareEnvVariablesForRepository( repository, environment ).forEach( cl::addEnvironment );
+        }
+        else if ( environment != null )
+        {
+            environment.forEach( cl::addEnvironment );
+        }
         return cl;
     }
 
@@ -196,4 +209,27 @@ public final class GitCommandLineUtils
         return exitCode;
     }
 
+    static Map<String, String> prepareEnvVariablesForRepository( GitScmProviderRepository repository,
+                                                                 Map<String, String> environmentVariables )
+    {
+        Map<String, String> effectiveEnvironmentVariables = new HashMap<>();
+        if ( environmentVariables != null )
+        {
+            effectiveEnvironmentVariables.putAll( environmentVariables );
+        }
+        if ( StringUtils.isNotBlank( repository.getPrivateKey() ) )
+        {
+            if ( effectiveEnvironmentVariables.putIfAbsent( VARIABLE_GIT_SSH_COMMAND, "ssh -o IdentitiesOnly=yes -i "
+                            + FilenameUtils.separatorsToUnix( repository.getPrivateKey() ) ) != null )
+            {
+                LOGGER.warn( "Ignore GitScmProviderRepository.privateKey as environment variable {} is already set",
+                             VARIABLE_GIT_SSH_COMMAND );
+            }
+        }
+        if ( StringUtils.isNotBlank( repository.getPassphrase() ) )
+        {
+            LOGGER.warn( "GitScmProviderRepository.passphrase currently not supported by provider 'git'" );
+        }
+        return effectiveEnvironmentVariables;
+    }
 }
diff --git a/maven-scm-providers/maven-scm-providers-git/maven-scm-provider-gitexe/src/main/java/org/apache/maven/scm/provider/git/gitexe/command/checkin/GitCheckInCommand.java b/maven-scm-providers/maven-scm-providers-git/maven-scm-provider-gitexe/src/main/java/org/apache/maven/scm/provider/git/gitexe/command/checkin/GitCheckInCommand.java
index 09cbdb8a2..ee4809cbd 100644
--- a/maven-scm-providers/maven-scm-providers-git/maven-scm-provider-gitexe/src/main/java/org/apache/maven/scm/provider/git/gitexe/command/checkin/GitCheckInCommand.java
+++ b/maven-scm-providers/maven-scm-providers-git/maven-scm-provider-gitexe/src/main/java/org/apache/maven/scm/provider/git/gitexe/command/checkin/GitCheckInCommand.java
@@ -19,6 +19,14 @@ package org.apache.maven.scm.provider.git.gitexe.command.checkin;
  * under the License.
  */
 
+import java.io.File;
+import java.io.IOException;
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
 import org.apache.commons.io.FilenameUtils;
 import org.apache.maven.scm.ScmException;
 import org.apache.maven.scm.ScmFile;
@@ -29,26 +37,18 @@ import org.apache.maven.scm.command.checkin.AbstractCheckInCommand;
 import org.apache.maven.scm.command.checkin.CheckInScmResult;
 import org.apache.maven.scm.provider.ScmProviderRepository;
 import org.apache.maven.scm.provider.git.command.GitCommand;
-import org.apache.maven.scm.provider.git.repository.GitScmProviderRepository;
-import org.apache.maven.scm.provider.git.util.GitUtil;
 import org.apache.maven.scm.provider.git.gitexe.command.GitCommandLineUtils;
 import org.apache.maven.scm.provider.git.gitexe.command.add.GitAddCommand;
 import org.apache.maven.scm.provider.git.gitexe.command.branch.GitBranchCommand;
 import org.apache.maven.scm.provider.git.gitexe.command.status.GitStatusCommand;
 import org.apache.maven.scm.provider.git.gitexe.command.status.GitStatusConsumer;
+import org.apache.maven.scm.provider.git.repository.GitScmProviderRepository;
+import org.apache.maven.scm.provider.git.util.GitUtil;
 import org.codehaus.plexus.util.FileUtils;
 import org.codehaus.plexus.util.Os;
 import org.codehaus.plexus.util.cli.CommandLineUtils;
 import org.codehaus.plexus.util.cli.Commandline;
 
-import java.io.File;
-import java.io.IOException;
-import java.net.URI;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-
 /**
  * @author <a href="mailto:struberg@yahoo.de">Mark Struberg</a>
  * @author Olivier Lamy
@@ -224,7 +224,7 @@ public class GitCheckInCommand
                                               ScmFileSet fileSet, ScmVersion version )
         throws ScmException
     {
-        Commandline cl = GitCommandLineUtils.getBaseGitCommandLine( fileSet.getBasedir(), "push",
+        Commandline cl = GitCommandLineUtils.getBaseGitCommandLine( fileSet.getBasedir(), "push", repository,
                 environmentVariables );
 
         String branch = GitBranchCommand.getCurrentBranch( repository, fileSet );
@@ -252,8 +252,7 @@ public class GitCheckInCommand
                                                        File messageFile, Map<String, String> environmentVariables )
         throws ScmException
     {
-        Commandline cl = GitCommandLineUtils.getBaseGitCommandLine( fileSet.getBasedir(), "commit",
-                environmentVariables );
+        Commandline cl = GitCommandLineUtils.getBaseGitCommandLine( fileSet.getBasedir(), "commit" );
 
         cl.createArg().setValue( "--verbose" );
 
diff --git a/maven-scm-providers/maven-scm-providers-git/maven-scm-provider-gitexe/src/main/java/org/apache/maven/scm/provider/git/gitexe/command/checkout/GitCheckOutCommand.java b/maven-scm-providers/maven-scm-providers-git/maven-scm-provider-gitexe/src/main/java/org/apache/maven/scm/provider/git/gitexe/command/checkout/GitCheckOutCommand.java
index 915810651..74a06173a 100644
--- a/maven-scm-providers/maven-scm-providers-git/maven-scm-provider-gitexe/src/main/java/org/apache/maven/scm/provider/git/gitexe/command/checkout/GitCheckOutCommand.java
+++ b/maven-scm-providers/maven-scm-providers-git/maven-scm-provider-gitexe/src/main/java/org/apache/maven/scm/provider/git/gitexe/command/checkout/GitCheckOutCommand.java
@@ -183,7 +183,7 @@ public class GitCheckOutCommand
                                             ScmVersion version, boolean binary, boolean shallow )
     {
         Commandline cl = GitCommandLineUtils.getBaseGitCommandLine( workingDirectory.getParentFile(), "clone",
-                environmentVariables );
+                repository, environmentVariables );
 
         forceBinary( cl, binary );
 
@@ -235,13 +235,15 @@ public class GitCheckOutCommand
                 // but create a 'detached HEAD'.
                 // In fact, a tag in git may be in multiple branches. This occurs if
                 // you create a branch after the tag has been created
-                cl = GitCommandLineUtils.getBaseGitCommandLine( workingDirectory, "fetch" );
+                cl = GitCommandLineUtils.getBaseGitCommandLine( workingDirectory, "fetch", repository,
+                                                                environmentVariables );
 
                 cl.createArg().setValue( repository.getFetchUrl() );
             }
             else
             {
-                cl = GitCommandLineUtils.getBaseGitCommandLine( workingDirectory, "pull" );
+                cl = GitCommandLineUtils.getBaseGitCommandLine( workingDirectory, "pull", repository,
+                                                                environmentVariables );
 
                 cl.createArg().setValue( repository.getFetchUrl() );
 
@@ -250,7 +252,8 @@ public class GitCheckOutCommand
         }
         else
         {
-            cl = GitCommandLineUtils.getBaseGitCommandLine( workingDirectory, "pull", environmentVariables );
+            cl = GitCommandLineUtils.getBaseGitCommandLine( workingDirectory, "pull", repository,
+                                                            environmentVariables );
 
             cl.createArg().setValue( repository.getFetchUrl() );
             cl.createArg().setValue( "master" );
diff --git a/maven-scm-providers/maven-scm-providers-git/maven-scm-provider-gitexe/src/main/java/org/apache/maven/scm/provider/git/gitexe/command/remoteinfo/GitRemoteInfoCommand.java b/maven-scm-providers/maven-scm-providers-git/maven-scm-provider-gitexe/src/main/java/org/apache/maven/scm/provider/git/gitexe/command/remoteinfo/GitRemoteInfoCommand.java
index 87b207920..b3d73a81d 100644
--- a/maven-scm-providers/maven-scm-providers-git/maven-scm-provider-gitexe/src/main/java/org/apache/maven/scm/provider/git/gitexe/command/remoteinfo/GitRemoteInfoCommand.java
+++ b/maven-scm-providers/maven-scm-providers-git/maven-scm-provider-gitexe/src/main/java/org/apache/maven/scm/provider/git/gitexe/command/remoteinfo/GitRemoteInfoCommand.java
@@ -76,7 +76,8 @@ public class GitRemoteInfoCommand
 
     public Commandline createCommandLine( GitScmProviderRepository repository )
     {
-        Commandline cl = GitCommandLineUtils.getBaseGitCommandLine( null, "ls-remote", environmentVariables );
+        Commandline cl = GitCommandLineUtils.getBaseGitCommandLine( null, "ls-remote", repository,
+                                                                    environmentVariables );
 
         cl.setWorkingDirectory( System.getProperty( "java.io.tmpdir" ) );
 
diff --git a/maven-scm-providers/maven-scm-providers-git/maven-scm-provider-gitexe/src/test/java/org/apache/maven/scm/provider/git/gitexe/command/GitCommandLineUtilsAddTargetTest.java b/maven-scm-providers/maven-scm-providers-git/maven-scm-provider-gitexe/src/test/java/org/apache/maven/scm/provider/git/gitexe/command/GitCommandLineUtilsTest.java
similarity index 76%
rename from maven-scm-providers/maven-scm-providers-git/maven-scm-provider-gitexe/src/test/java/org/apache/maven/scm/provider/git/gitexe/command/GitCommandLineUtilsAddTargetTest.java
rename to maven-scm-providers/maven-scm-providers-git/maven-scm-provider-gitexe/src/test/java/org/apache/maven/scm/provider/git/gitexe/command/GitCommandLineUtilsTest.java
index 5005ceec6..c1bc067c2 100644
--- a/maven-scm-providers/maven-scm-providers-git/maven-scm-provider-gitexe/src/test/java/org/apache/maven/scm/provider/git/gitexe/command/GitCommandLineUtilsAddTargetTest.java
+++ b/maven-scm-providers/maven-scm-providers-git/maven-scm-provider-gitexe/src/test/java/org/apache/maven/scm/provider/git/gitexe/command/GitCommandLineUtilsTest.java
@@ -27,8 +27,13 @@ import static org.junit.Assume.assumeTrue;
 import java.io.File;
 import java.text.MessageFormat;
 import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 
+import org.apache.maven.scm.ScmException;
+import org.apache.maven.scm.provider.git.repository.GitScmProviderRepository;
 import org.codehaus.plexus.util.Os;
 import org.codehaus.plexus.util.cli.Commandline;
 import org.junit.Test;
@@ -36,7 +41,7 @@ import org.junit.Test;
 /**
  * @author mfriedenhagen
  */
-public class GitCommandLineUtilsAddTargetTest
+public class GitCommandLineUtilsTest
 {
 
     /**
@@ -104,6 +109,25 @@ public class GitCommandLineUtilsAddTargetTest
             scmUrlFakeForTest, cl.toString() ), cl.toString().contains( scmUrlFakeForTest ) );
     }
 
+    @Test
+    public void testPrepareEnvVariablesForRepository() throws ScmException
+    {
+        GitScmProviderRepository repository = new GitScmProviderRepository( "http://localhost/repository.git" );
+        assertEquals( Collections.emptyMap(), GitCommandLineUtils.prepareEnvVariablesForRepository( repository, null ) );
+
+        Map<String, String> testMap = new HashMap<>();
+        testMap.put( "testKey", "testValue" );
+        assertEquals( testMap, GitCommandLineUtils.prepareEnvVariablesForRepository( repository, testMap ) );
+
+        repository.setPrivateKey( "my\\private\\key" );
+        testMap.clear();
+        testMap.put( "GIT_SSH_COMMAND", "ssh -o IdentitiesOnly=yes -i my/private/key" );
+        assertEquals( testMap, GitCommandLineUtils.prepareEnvVariablesForRepository( repository, null ) );
+
+        testMap.put( "GIT_SSH_COMMAND", "ssh -o IdentitiesOnly=yes -i my/other/key" );
+        assertEquals( testMap, GitCommandLineUtils.prepareEnvVariablesForRepository( repository, testMap ) );
+    }
+
     private boolean runsOnWindows()
     {
         return Os.isFamily( Os.FAMILY_WINDOWS );