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