1 package org.apache.maven.scm.provider.git.gitexe.command;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import org.apache.commons.io.FilenameUtils;
23
24 import org.apache.maven.scm.ScmException;
25 import org.apache.maven.scm.provider.git.repository.GitScmProviderRepository;
26 import org.apache.maven.scm.provider.git.util.GitUtil;
27 import org.apache.maven.scm.providers.gitlib.settings.Settings;
28 import org.codehaus.plexus.util.StringUtils;
29 import org.codehaus.plexus.util.cli.CommandLineException;
30 import org.codehaus.plexus.util.cli.CommandLineUtils;
31 import org.codehaus.plexus.util.cli.Commandline;
32 import org.codehaus.plexus.util.cli.StreamConsumer;
33 import org.slf4j.Logger;
34 import org.slf4j.LoggerFactory;
35
36 import java.io.File;
37 import java.io.IOException;
38 import java.util.HashMap;
39 import java.util.List;
40 import java.util.Map;
41
42
43
44
45
46
47
48
49 public final class GitCommandLineUtils
50 {
51 private static final Logger LOGGER = LoggerFactory.getLogger( GitCommandLineUtils.class );
52
53
54 public static final String VARIABLE_GIT_SSH_COMMAND = "GIT_SSH_COMMAND";
55
56 private GitCommandLineUtils()
57 {
58 }
59
60 public static void addTarget( Commandline cl, List<File> files )
61 {
62 if ( files == null || files.isEmpty() )
63 {
64 return;
65 }
66 final File workingDirectory = cl.getWorkingDirectory();
67 try
68 {
69 final String canonicalWorkingDirectory = workingDirectory.getCanonicalPath();
70 for ( File file : files )
71 {
72 String relativeFile = file.getPath();
73
74 final String canonicalFile = file.getCanonicalPath();
75 if ( canonicalFile.startsWith( canonicalWorkingDirectory ) )
76 {
77
78 relativeFile = canonicalFile.substring( canonicalWorkingDirectory.length() );
79
80 if ( relativeFile.startsWith( File.separator ) )
81 {
82 relativeFile = relativeFile.substring( File.separator.length() );
83 }
84 }
85
86
87 cl.createArg().setValue( FilenameUtils.separatorsToUnix( relativeFile ) );
88 }
89 }
90 catch ( IOException ex )
91 {
92 throw new IllegalArgumentException( "Could not get canonical paths for workingDirectory = "
93 + workingDirectory + " or files=" + files, ex );
94 }
95 }
96
97
98
99
100
101
102
103 public static Commandline getBaseGitCommandLine( File workingDirectory, String command )
104 {
105 return getBaseGitCommandLine( workingDirectory, command, null, null );
106 }
107
108
109
110
111
112
113
114
115 public static Commandline getBaseGitCommandLine( File workingDirectory, String command,
116 GitScmProviderRepository repository,
117 Map<String, String> environment )
118 {
119 Commandline cl = getAnonymousBaseGitCommandLine( workingDirectory, command );
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 }
128 return cl;
129 }
130
131
132
133
134
135
136
137
138
139 private static Commandline getAnonymousBaseGitCommandLine( File workingDirectory, String command )
140 {
141 if ( command == null || command.length() == 0 )
142 {
143 return null;
144 }
145
146 Commandline cl = new AnonymousCommandLine();
147
148 composeCommand( workingDirectory, command, cl );
149
150 return cl;
151 }
152
153 private static void composeCommand( File workingDirectory, String command, Commandline cl )
154 {
155 Settings settings = GitUtil.getSettings();
156
157 cl.setExecutable( settings.getGitCommand() );
158
159 cl.createArg().setValue( command );
160
161 if ( workingDirectory != null )
162 {
163 cl.setWorkingDirectory( workingDirectory.getAbsolutePath() );
164 }
165 }
166
167 public static int execute( Commandline cl, StreamConsumer consumer, CommandLineUtils.StringStreamConsumer stderr )
168 throws ScmException
169 {
170 if ( LOGGER.isInfoEnabled() )
171 {
172 LOGGER.info( "Executing: " + cl );
173 LOGGER.info( "Working directory: " + cl.getWorkingDirectory().getAbsolutePath() );
174 }
175
176 int exitCode;
177 try
178 {
179 exitCode = CommandLineUtils.executeCommandLine( cl, consumer, stderr );
180 }
181 catch ( CommandLineException ex )
182 {
183 throw new ScmException( "Error while executing command.", ex );
184 }
185
186 return exitCode;
187 }
188
189 public static int execute( Commandline cl, CommandLineUtils.StringStreamConsumer stdout,
190 CommandLineUtils.StringStreamConsumer stderr )
191 throws ScmException
192 {
193 if ( LOGGER.isInfoEnabled() )
194 {
195 LOGGER.info( "Executing: " + cl );
196 LOGGER.info( "Working directory: " + cl.getWorkingDirectory().getAbsolutePath() );
197 }
198
199 int exitCode;
200 try
201 {
202 exitCode = CommandLineUtils.executeCommandLine( cl, stdout, stderr );
203 }
204 catch ( CommandLineException ex )
205 {
206 throw new ScmException( "Error while executing command.", ex );
207 }
208
209 return exitCode;
210 }
211
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 }
235 }