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.svn.svnexe.command;
20
21 import java.io.File;
22 import java.io.FileOutputStream;
23 import java.io.IOException;
24 import java.io.PrintStream;
25 import java.util.List;
26
27 import org.apache.commons.lang3.StringUtils;
28 import org.apache.maven.scm.provider.svn.repository.SvnScmProviderRepository;
29 import org.apache.maven.scm.provider.svn.util.SvnUtil;
30 import org.codehaus.plexus.util.Os;
31 import org.codehaus.plexus.util.cli.CommandLineException;
32 import org.codehaus.plexus.util.cli.CommandLineUtils;
33 import org.codehaus.plexus.util.cli.Commandline;
34 import org.codehaus.plexus.util.cli.StreamConsumer;
35 import org.slf4j.Logger;
36 import org.slf4j.LoggerFactory;
37
38
39
40
41
42
43
44
45 public final class SvnCommandLineUtils {
46 private static final Logger LOGGER = LoggerFactory.getLogger(SvnCommandLineUtils.class);
47
48 private SvnCommandLineUtils() {}
49
50 public static void addTarget(Commandline cl, List<File> files) throws IOException {
51 if (files == null || files.isEmpty()) {
52 return;
53 }
54
55 StringBuilder sb = new StringBuilder();
56 String ls = System.getProperty("line.separator");
57 for (File f : files) {
58 sb.append(f.getPath().replace('\\', '/'));
59 sb.append(ls);
60 }
61
62 File targets = File.createTempFile("maven-scm-", "-targets");
63 PrintStream out = new PrintStream(new FileOutputStream(targets));
64 out.print(sb);
65 out.flush();
66 out.close();
67
68 cl.createArg().setValue("--targets");
69 cl.createArg().setValue(targets.getAbsolutePath());
70
71 targets.deleteOnExit();
72 }
73
74 public static Commandline getBaseSvnCommandLine(File workingDirectory, SvnScmProviderRepository repository) {
75 Commandline cl = new Commandline();
76
77 cl.setExecutable("svn");
78 try {
79 cl.addSystemEnvironment();
80 cl.addEnvironment("LC_MESSAGES", "C");
81 } catch (Exception e) {
82
83 }
84
85 if (workingDirectory != null) {
86 cl.setWorkingDirectory(workingDirectory.getAbsolutePath());
87 }
88
89 if (!StringUtils.isEmpty(System.getProperty("maven.scm.svn.config_directory"))) {
90 cl.createArg().setValue("--config-dir");
91 cl.createArg().setValue(System.getProperty("maven.scm.svn.config_directory"));
92 } else if (!StringUtils.isEmpty(SvnUtil.getSettings().getConfigDirectory())) {
93 cl.createArg().setValue("--config-dir");
94 cl.createArg().setValue(SvnUtil.getSettings().getConfigDirectory());
95 }
96
97 boolean hasAuthInfo = false;
98 if (repository != null && !StringUtils.isEmpty(repository.getUser())) {
99 hasAuthInfo = true;
100 cl.createArg().setValue("--username");
101 cl.createArg().setValue(repository.getUser());
102 }
103
104 if (repository != null && !StringUtils.isEmpty(repository.getPassword())) {
105 hasAuthInfo = true;
106 cl.createArg().setValue("--password");
107 cl.createArg().setValue(repository.getPassword());
108 }
109
110
111 if (hasAuthInfo && !SvnUtil.getSettings().isUseAuthCache()) {
112 cl.createArg().setValue("--no-auth-cache");
113 }
114
115 if (SvnUtil.getSettings().isUseNonInteractive()) {
116 cl.createArg().setValue("--non-interactive");
117 }
118
119 if (SvnUtil.getSettings().isTrustServerCert()) {
120 cl.createArg().setValue("--trust-server-cert");
121 }
122
123 return cl;
124 }
125
126 public static int execute(Commandline cl, StreamConsumer consumer, CommandLineUtils.StringStreamConsumer stderr)
127 throws CommandLineException {
128
129 cl.addEnvironment("LC_MESSAGES", "en");
130
131 int exitCode = CommandLineUtils.executeCommandLine(cl, consumer, stderr);
132
133 exitCode = checkIfCleanUpIsNeeded(exitCode, cl, consumer, stderr);
134
135 return exitCode;
136 }
137
138 public static int execute(
139 Commandline cl, CommandLineUtils.StringStreamConsumer stdout, CommandLineUtils.StringStreamConsumer stderr)
140 throws CommandLineException {
141 int exitCode = CommandLineUtils.executeCommandLine(cl, stdout, stderr);
142
143 exitCode = checkIfCleanUpIsNeeded(exitCode, cl, stdout, stderr);
144
145 return exitCode;
146 }
147
148 private static int checkIfCleanUpIsNeeded(
149 int exitCode, Commandline cl, StreamConsumer consumer, CommandLineUtils.StringStreamConsumer stderr)
150 throws CommandLineException {
151 if (exitCode != 0
152 && stderr.getOutput() != null
153 && stderr.getOutput().indexOf("'svn cleanup'") > 0
154 && stderr.getOutput().indexOf("'svn help cleanup'") > 0) {
155 if (LOGGER.isInfoEnabled()) {
156 LOGGER.info("Svn command failed due to some locks in working copy. We try to run a 'svn cleanup'.");
157 }
158
159 if (executeCleanUp(cl.getWorkingDirectory(), consumer, stderr) == 0) {
160 exitCode = CommandLineUtils.executeCommandLine(cl, consumer, stderr);
161 }
162 }
163 return exitCode;
164 }
165
166 public static int executeCleanUp(File workinDirectory, StreamConsumer stdout, StreamConsumer stderr)
167 throws CommandLineException {
168 Commandline cl = new Commandline();
169
170 cl.setExecutable("svn");
171
172 cl.setWorkingDirectory(workinDirectory.getAbsolutePath());
173
174 if (LOGGER.isInfoEnabled()) {
175 LOGGER.info("Executing: " + SvnCommandLineUtils.cryptPassword(cl));
176
177 if (Os.isFamily(Os.FAMILY_WINDOWS)) {
178 LOGGER.info("Working directory: " + cl.getWorkingDirectory().getAbsolutePath());
179 }
180 }
181
182 return CommandLineUtils.executeCommandLine(cl, stdout, stderr);
183 }
184
185 public static String cryptPassword(Commandline cl) {
186 String clString = cl.toString();
187
188 final String passwordOpt = "--password";
189 String quoteChar;
190 String escapedQuoteChar;
191 String cryptedPassword;
192
193 int pos = clString.indexOf(passwordOpt);
194
195 if (pos > 0) {
196 if (Os.isFamily(Os.FAMILY_WINDOWS)) {
197 quoteChar = "\"";
198 escapedQuoteChar = "\"\"";
199 cryptedPassword = "*****";
200 } else {
201 quoteChar = "'";
202 escapedQuoteChar = "'\"'\"'";
203 cryptedPassword = "'*****'";
204 }
205
206
207 pos += passwordOpt.length();
208
209
210 if (clString.substring(pos, pos + 1).equals(quoteChar)) {
211 pos++;
212 }
213
214
215 pos++;
216
217 String beforePassword = clString.substring(0, pos);
218 String afterPassword = clString.substring(pos);
219
220 if (afterPassword.startsWith(quoteChar)) {
221 pos = 1;
222 while (afterPassword.indexOf(escapedQuoteChar, pos) != -1) {
223 pos = afterPassword.indexOf(escapedQuoteChar, pos) + escapedQuoteChar.length();
224 }
225 afterPassword = afterPassword.substring(afterPassword.indexOf(quoteChar, pos) + quoteChar.length());
226 } else {
227
228 afterPassword = afterPassword.substring(afterPassword.indexOf(' '));
229 }
230
231 clString = beforePassword + cryptedPassword + afterPassword;
232 }
233
234 return clString;
235 }
236 }