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