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 commandLine, List<File> files) {
56 if (files == null || files.isEmpty()) {
57 return;
58 }
59 final File workingDirectory = commandLine.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 commandLine.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 public static Commandline getBaseGitCommandLine(File workingDirectory, String command) {
89 return getBaseGitCommandLine(workingDirectory, command, null, null);
90 }
91
92
93
94
95 public static Commandline getBaseGitCommandLine(
96 File workingDirectory,
97 String command,
98 GitScmProviderRepository repository,
99 Map<String, String> environment) {
100 Commandline commandLine = getAnonymousBaseGitCommandLine(workingDirectory, command);
101 if (repository != null) {
102 prepareEnvVariablesForRepository(repository, environment).forEach(commandLine::addEnvironment);
103 } else if (environment != null) {
104 environment.forEach(commandLine::addEnvironment);
105 }
106 return commandLine;
107 }
108
109
110
111
112
113
114
115
116
117 private static Commandline getAnonymousBaseGitCommandLine(File workingDirectory, String command) {
118 if (command == null || command.isEmpty()) {
119 return null;
120 }
121
122 Commandline commandLine = new AnonymousCommandLine();
123
124 composeCommand(workingDirectory, command, commandLine);
125
126 return commandLine;
127 }
128
129 private static void composeCommand(File workingDirectory, String command, Commandline commandLine) {
130 Settings settings = GitUtil.getSettings();
131
132 commandLine.setExecutable(settings.getGitCommand());
133
134 commandLine.createArg().setValue(command);
135
136 if (workingDirectory != null) {
137 commandLine.setWorkingDirectory(workingDirectory.getAbsolutePath());
138 }
139 }
140
141 public static int execute(
142 Commandline commandline, StreamConsumer consumer, CommandLineUtils.StringStreamConsumer stderr)
143 throws ScmException {
144 if (LOGGER.isInfoEnabled()) {
145 LOGGER.info("Executing: " + commandline);
146 LOGGER.info(
147 "Working directory: " + commandline.getWorkingDirectory().getAbsolutePath());
148 }
149
150 int exitCode;
151 try {
152 exitCode = CommandLineUtils.executeCommandLine(commandline, consumer, stderr);
153 } catch (CommandLineException ex) {
154 throw new ScmException("Error while executing command.", ex);
155 }
156
157 return exitCode;
158 }
159
160 public static int execute(
161 Commandline commandLine,
162 CommandLineUtils.StringStreamConsumer stdout,
163 CommandLineUtils.StringStreamConsumer stderr)
164 throws ScmException {
165 if (LOGGER.isInfoEnabled()) {
166 LOGGER.info("Executing: " + commandLine);
167 LOGGER.info(
168 "Working directory: " + commandLine.getWorkingDirectory().getAbsolutePath());
169 }
170
171 int exitCode;
172 try {
173 exitCode = CommandLineUtils.executeCommandLine(commandLine, stdout, stderr);
174 } catch (CommandLineException ex) {
175 throw new ScmException("Error while executing command.", ex);
176 }
177
178 return exitCode;
179 }
180
181 static Map<String, String> prepareEnvVariablesForRepository(
182 GitScmProviderRepository repository, Map<String, String> environmentVariables) {
183 Map<String, String> effectiveEnvironmentVariables = new HashMap<>();
184 if (environmentVariables != null) {
185 effectiveEnvironmentVariables.putAll(environmentVariables);
186 }
187 if (StringUtils.isNotBlank(repository.getPrivateKey())) {
188 if (effectiveEnvironmentVariables.putIfAbsent(
189 VARIABLE_GIT_SSH_COMMAND,
190 "ssh -o IdentitiesOnly=yes -i "
191 + FilenameUtils.separatorsToUnix(repository.getPrivateKey()))
192 != null) {
193 LOGGER.warn(
194 "Ignore GitScmProviderRepository.privateKey as environment variable {} is already set",
195 VARIABLE_GIT_SSH_COMMAND);
196 }
197 }
198 if (StringUtils.isNotBlank(repository.getPassphrase())) {
199 LOGGER.warn("GitScmProviderRepository.passphrase currently not supported by provider 'git'");
200 }
201 return effectiveEnvironmentVariables;
202 }
203 }