Skip to content

Commit e77e001

Browse files
kwinmichael-o
authored andcommitted
[SCM-992] Support explicitly configured SSH private key for gitexe provider
This closes #159
1 parent b8060d8 commit e77e001

File tree

5 files changed

+87
-24
lines changed

5 files changed

+87
-24
lines changed

maven-scm-providers/maven-scm-providers-git/maven-scm-provider-gitexe/src/main/java/org/apache/maven/scm/provider/git/gitexe/command/GitCommandLineUtils.java

Lines changed: 41 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,10 @@
2222
import org.apache.commons.io.FilenameUtils;
2323

2424
import org.apache.maven.scm.ScmException;
25+
import org.apache.maven.scm.provider.git.repository.GitScmProviderRepository;
2526
import org.apache.maven.scm.provider.git.util.GitUtil;
2627
import org.apache.maven.scm.providers.gitlib.settings.Settings;
28+
import org.codehaus.plexus.util.StringUtils;
2729
import org.codehaus.plexus.util.cli.CommandLineException;
2830
import org.codehaus.plexus.util.cli.CommandLineUtils;
2931
import org.codehaus.plexus.util.cli.Commandline;
@@ -33,7 +35,7 @@
3335

3436
import java.io.File;
3537
import java.io.IOException;
36-
import java.util.Collections;
38+
import java.util.HashMap;
3739
import java.util.List;
3840
import java.util.Map;
3941

@@ -48,6 +50,9 @@ public final class GitCommandLineUtils
4850
{
4951
private static final Logger LOGGER = LoggerFactory.getLogger( GitCommandLineUtils.class );
5052

53+
// https://git-scm.com/docs/git#Documentation/git.txt-codeGITSSHCOMMANDcode, requires git 2.3.0 or newer
54+
public static final String VARIABLE_GIT_SSH_COMMAND = "GIT_SSH_COMMAND";
55+
5156
private GitCommandLineUtils()
5257
{
5358
}
@@ -90,28 +95,36 @@ public static void addTarget( Commandline cl, List<File> files )
9095
}
9196

9297
/**
93-
*
98+
* Use this only for commands not requiring environment variables (i.e. local commands).
9499
* @param workingDirectory
95100
* @param command
96101
* @return TODO
97102
*/
98103
public static Commandline getBaseGitCommandLine( File workingDirectory, String command )
99104
{
100-
return getBaseGitCommandLine( workingDirectory, command, Collections.emptyMap() );
105+
return getBaseGitCommandLine( workingDirectory, command, null, null );
101106
}
102107

103108
/**
104-
*
109+
* Use this for commands requiring environment variables (i.e. remote commands).
105110
* @param workingDirectory
106111
* @param command
107112
* @param environment
108113
* @return TODO
109114
*/
110115
public static Commandline getBaseGitCommandLine( File workingDirectory, String command,
116+
GitScmProviderRepository repository,
111117
Map<String, String> environment )
112118
{
113119
Commandline cl = getAnonymousBaseGitCommandLine( workingDirectory, command );
114-
environment.forEach( cl::addEnvironment );
120+
if ( repository != null )
121+
{
122+
prepareEnvVariablesForRepository( repository, environment ).forEach( cl::addEnvironment );
123+
}
124+
else if ( environment != null )
125+
{
126+
environment.forEach( cl::addEnvironment );
127+
}
115128
return cl;
116129
}
117130

@@ -196,4 +209,27 @@ public static int execute( Commandline cl, CommandLineUtils.StringStreamConsumer
196209
return exitCode;
197210
}
198211

212+
static Map<String, String> prepareEnvVariablesForRepository( GitScmProviderRepository repository,
213+
Map<String, String> environmentVariables )
214+
{
215+
Map<String, String> effectiveEnvironmentVariables = new HashMap<>();
216+
if ( environmentVariables != null )
217+
{
218+
effectiveEnvironmentVariables.putAll( environmentVariables );
219+
}
220+
if ( StringUtils.isNotBlank( repository.getPrivateKey() ) )
221+
{
222+
if ( effectiveEnvironmentVariables.putIfAbsent( VARIABLE_GIT_SSH_COMMAND, "ssh -o IdentitiesOnly=yes -i "
223+
+ FilenameUtils.separatorsToUnix( repository.getPrivateKey() ) ) != null )
224+
{
225+
LOGGER.warn( "Ignore GitScmProviderRepository.privateKey as environment variable {} is already set",
226+
VARIABLE_GIT_SSH_COMMAND );
227+
}
228+
}
229+
if ( StringUtils.isNotBlank( repository.getPassphrase() ) )
230+
{
231+
LOGGER.warn( "GitScmProviderRepository.passphrase currently not supported by provider 'git'" );
232+
}
233+
return effectiveEnvironmentVariables;
234+
}
199235
}

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

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,14 @@
1919
* under the License.
2020
*/
2121

22+
import java.io.File;
23+
import java.io.IOException;
24+
import java.net.URI;
25+
import java.util.ArrayList;
26+
import java.util.Collections;
27+
import java.util.List;
28+
import java.util.Map;
29+
2230
import org.apache.commons.io.FilenameUtils;
2331
import org.apache.maven.scm.ScmException;
2432
import org.apache.maven.scm.ScmFile;
@@ -29,26 +37,18 @@
2937
import org.apache.maven.scm.command.checkin.CheckInScmResult;
3038
import org.apache.maven.scm.provider.ScmProviderRepository;
3139
import org.apache.maven.scm.provider.git.command.GitCommand;
32-
import org.apache.maven.scm.provider.git.repository.GitScmProviderRepository;
33-
import org.apache.maven.scm.provider.git.util.GitUtil;
3440
import org.apache.maven.scm.provider.git.gitexe.command.GitCommandLineUtils;
3541
import org.apache.maven.scm.provider.git.gitexe.command.add.GitAddCommand;
3642
import org.apache.maven.scm.provider.git.gitexe.command.branch.GitBranchCommand;
3743
import org.apache.maven.scm.provider.git.gitexe.command.status.GitStatusCommand;
3844
import org.apache.maven.scm.provider.git.gitexe.command.status.GitStatusConsumer;
45+
import org.apache.maven.scm.provider.git.repository.GitScmProviderRepository;
46+
import org.apache.maven.scm.provider.git.util.GitUtil;
3947
import org.codehaus.plexus.util.FileUtils;
4048
import org.codehaus.plexus.util.Os;
4149
import org.codehaus.plexus.util.cli.CommandLineUtils;
4250
import org.codehaus.plexus.util.cli.Commandline;
4351

44-
import java.io.File;
45-
import java.io.IOException;
46-
import java.net.URI;
47-
import java.util.ArrayList;
48-
import java.util.Collections;
49-
import java.util.List;
50-
import java.util.Map;
51-
5252
/**
5353
* @author <a href="mailto:[email protected]">Mark Struberg</a>
5454
* @author Olivier Lamy
@@ -224,7 +224,7 @@ public Commandline createPushCommandLine( GitScmProviderRepository repository,
224224
ScmFileSet fileSet, ScmVersion version )
225225
throws ScmException
226226
{
227-
Commandline cl = GitCommandLineUtils.getBaseGitCommandLine( fileSet.getBasedir(), "push",
227+
Commandline cl = GitCommandLineUtils.getBaseGitCommandLine( fileSet.getBasedir(), "push", repository,
228228
environmentVariables );
229229

230230
String branch = GitBranchCommand.getCurrentBranch( repository, fileSet );
@@ -252,8 +252,7 @@ public static Commandline createCommitCommandLine( GitScmProviderRepository repo
252252
File messageFile, Map<String, String> environmentVariables )
253253
throws ScmException
254254
{
255-
Commandline cl = GitCommandLineUtils.getBaseGitCommandLine( fileSet.getBasedir(), "commit",
256-
environmentVariables );
255+
Commandline cl = GitCommandLineUtils.getBaseGitCommandLine( fileSet.getBasedir(), "commit" );
257256

258257
cl.createArg().setValue( "--verbose" );
259258

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

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,7 @@ private Commandline createCloneCommand( GitScmProviderRepository repository, Fil
183183
ScmVersion version, boolean binary, boolean shallow )
184184
{
185185
Commandline cl = GitCommandLineUtils.getBaseGitCommandLine( workingDirectory.getParentFile(), "clone",
186-
environmentVariables );
186+
repository, environmentVariables );
187187

188188
forceBinary( cl, binary );
189189

@@ -235,13 +235,15 @@ private Commandline createPullCommand( GitScmProviderRepository repository, File
235235
// but create a 'detached HEAD'.
236236
// In fact, a tag in git may be in multiple branches. This occurs if
237237
// you create a branch after the tag has been created
238-
cl = GitCommandLineUtils.getBaseGitCommandLine( workingDirectory, "fetch" );
238+
cl = GitCommandLineUtils.getBaseGitCommandLine( workingDirectory, "fetch", repository,
239+
environmentVariables );
239240

240241
cl.createArg().setValue( repository.getFetchUrl() );
241242
}
242243
else
243244
{
244-
cl = GitCommandLineUtils.getBaseGitCommandLine( workingDirectory, "pull" );
245+
cl = GitCommandLineUtils.getBaseGitCommandLine( workingDirectory, "pull", repository,
246+
environmentVariables );
245247

246248
cl.createArg().setValue( repository.getFetchUrl() );
247249

@@ -250,7 +252,8 @@ private Commandline createPullCommand( GitScmProviderRepository repository, File
250252
}
251253
else
252254
{
253-
cl = GitCommandLineUtils.getBaseGitCommandLine( workingDirectory, "pull", environmentVariables );
255+
cl = GitCommandLineUtils.getBaseGitCommandLine( workingDirectory, "pull", repository,
256+
environmentVariables );
254257

255258
cl.createArg().setValue( repository.getFetchUrl() );
256259
cl.createArg().setValue( "master" );

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,8 @@ public RemoteInfoScmResult executeRemoteInfoCommand( ScmProviderRepository repos
7676

7777
public Commandline createCommandLine( GitScmProviderRepository repository )
7878
{
79-
Commandline cl = GitCommandLineUtils.getBaseGitCommandLine( null, "ls-remote", environmentVariables );
79+
Commandline cl = GitCommandLineUtils.getBaseGitCommandLine( null, "ls-remote", repository,
80+
environmentVariables );
8081

8182
cl.setWorkingDirectory( System.getProperty( "java.io.tmpdir" ) );
8283

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,16 +27,21 @@
2727
import java.io.File;
2828
import java.text.MessageFormat;
2929
import java.util.Arrays;
30+
import java.util.Collections;
31+
import java.util.HashMap;
3032
import java.util.List;
33+
import java.util.Map;
3134

35+
import org.apache.maven.scm.ScmException;
36+
import org.apache.maven.scm.provider.git.repository.GitScmProviderRepository;
3237
import org.codehaus.plexus.util.Os;
3338
import org.codehaus.plexus.util.cli.Commandline;
3439
import org.junit.Test;
3540

3641
/**
3742
* @author mfriedenhagen
3843
*/
39-
public class GitCommandLineUtilsAddTargetTest
44+
public class GitCommandLineUtilsTest
4045
{
4146

4247
/**
@@ -104,6 +109,25 @@ public void testPasswordAnonymous()
104109
scmUrlFakeForTest, cl.toString() ), cl.toString().contains( scmUrlFakeForTest ) );
105110
}
106111

112+
@Test
113+
public void testPrepareEnvVariablesForRepository() throws ScmException
114+
{
115+
GitScmProviderRepository repository = new GitScmProviderRepository( "http://localhost/repository.git" );
116+
assertEquals( Collections.emptyMap(), GitCommandLineUtils.prepareEnvVariablesForRepository( repository, null ) );
117+
118+
Map<String, String> testMap = new HashMap<>();
119+
testMap.put( "testKey", "testValue" );
120+
assertEquals( testMap, GitCommandLineUtils.prepareEnvVariablesForRepository( repository, testMap ) );
121+
122+
repository.setPrivateKey( "my\\private\\key" );
123+
testMap.clear();
124+
testMap.put( "GIT_SSH_COMMAND", "ssh -o IdentitiesOnly=yes -i my/private/key" );
125+
assertEquals( testMap, GitCommandLineUtils.prepareEnvVariablesForRepository( repository, null ) );
126+
127+
testMap.put( "GIT_SSH_COMMAND", "ssh -o IdentitiesOnly=yes -i my/other/key" );
128+
assertEquals( testMap, GitCommandLineUtils.prepareEnvVariablesForRepository( repository, testMap ) );
129+
}
130+
107131
private boolean runsOnWindows()
108132
{
109133
return Os.isFamily( Os.FAMILY_WINDOWS );

0 commit comments

Comments
 (0)