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 cl.createArg().setValue( "--non-interactive" );
133 }
134
135 if (SvnUtil.getSettings().isTrustServerCert()) {
136 cl.createArg().setValue( "--trust-server-cert" );
137 }
138
139 return cl;
140 }
141
142 public static int execute( Commandline cl, StreamConsumer consumer, CommandLineUtils.StringStreamConsumer stderr,
143 ScmLogger logger )
144 throws CommandLineException
145 {
146
147 cl.addEnvironment( "LC_MESSAGES", "en" );
148
149 int exitCode = CommandLineUtils.executeCommandLine( cl, consumer, stderr );
150
151 exitCode = checkIfCleanUpIsNeeded( exitCode, cl, consumer, stderr, logger );
152
153 return exitCode;
154 }
155
156 public static int execute( Commandline cl, CommandLineUtils.StringStreamConsumer stdout,
157 CommandLineUtils.StringStreamConsumer stderr, ScmLogger logger )
158 throws CommandLineException
159 {
160 int exitCode = CommandLineUtils.executeCommandLine( cl, stdout, stderr );
161
162 exitCode = checkIfCleanUpIsNeeded( exitCode, cl, stdout, stderr, logger );
163
164 return exitCode;
165 }
166
167 private static int checkIfCleanUpIsNeeded( int exitCode, Commandline cl, StreamConsumer consumer,
168 CommandLineUtils.StringStreamConsumer stderr, ScmLogger logger )
169 throws CommandLineException
170 {
171 if ( exitCode != 0 && stderr.getOutput() != null && stderr.getOutput().indexOf( "'svn cleanup'" ) > 0
172 && stderr.getOutput().indexOf( "'svn help cleanup'" ) > 0 )
173 {
174 if ( logger.isInfoEnabled() )
175 {
176 logger.info( "Svn command failed due to some locks in working copy. We try to run a 'svn cleanup'." );
177 }
178
179 if ( executeCleanUp( cl.getWorkingDirectory(), consumer, stderr, logger ) == 0 )
180 {
181 exitCode = CommandLineUtils.executeCommandLine( cl, consumer, stderr );
182 }
183 }
184 return exitCode;
185 }
186
187 public static int executeCleanUp( File workinDirectory, StreamConsumer stdout, StreamConsumer stderr )
188 throws CommandLineException
189 {
190 return executeCleanUp( workinDirectory, stdout, stderr, null );
191 }
192
193 public static int executeCleanUp( File workinDirectory, StreamConsumer stdout, StreamConsumer stderr,
194 ScmLogger logger )
195 throws CommandLineException
196 {
197 Commandline cl = new Commandline();
198
199 cl.setExecutable( "svn" );
200
201 cl.setWorkingDirectory( workinDirectory.getAbsolutePath() );
202
203 if ( logger != null )
204 {
205 if ( logger.isInfoEnabled() )
206 {
207 logger.info( "Executing: " + SvnCommandLineUtils.cryptPassword( cl ) );
208 logger.info( "Working directory: " + cl.getWorkingDirectory().getAbsolutePath() );
209 }
210 }
211
212 return CommandLineUtils.executeCommandLine( cl, stdout, stderr );
213 }
214
215 public static String cryptPassword( Commandline cl )
216 {
217 String clString = cl.toString();
218
219 int pos = clString.indexOf( "--password" );
220
221 if ( pos > 0 )
222 {
223 String beforePassword = clString.substring( 0, pos + "--password ".length() );
224 String afterPassword = clString.substring( pos + "--password ".length() );
225 afterPassword = afterPassword.substring( afterPassword.indexOf( ' ' ) );
226 if ( Os.isFamily( Os.FAMILY_WINDOWS ) )
227 {
228 clString = beforePassword + "*****" + afterPassword;
229 }
230 else
231 {
232 clString = beforePassword + "'*****'" + afterPassword;
233 }
234 }
235
236 return clString;
237 }
238 }