001 package org.apache.maven.scm.provider.svn.svnexe.command; 002 003 /* 004 * Licensed to the Apache Software Foundation (ASF) under one 005 * or more contributor license agreements. See the NOTICE file 006 * distributed with this work for additional information 007 * regarding copyright ownership. The ASF licenses this file 008 * to you under the Apache License, Version 2.0 (the 009 * "License"); you may not use this file except in compliance 010 * with the License. You may obtain a copy of the License at 011 * 012 * http://www.apache.org/licenses/LICENSE-2.0 013 * 014 * Unless required by applicable law or agreed to in writing, 015 * software distributed under the License is distributed on an 016 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 017 * KIND, either express or implied. See the License for the 018 * specific language governing permissions and limitations 019 * under the License. 020 */ 021 022 import java.io.File; 023 import java.io.FileOutputStream; 024 import java.io.IOException; 025 import java.io.PrintStream; 026 import java.util.List; 027 028 import org.apache.maven.scm.log.ScmLogger; 029 import org.apache.maven.scm.provider.svn.repository.SvnScmProviderRepository; 030 import org.apache.maven.scm.provider.svn.util.SvnUtil; 031 import org.codehaus.plexus.util.Os; 032 import org.codehaus.plexus.util.StringUtils; 033 import org.codehaus.plexus.util.cli.CommandLineException; 034 import org.codehaus.plexus.util.cli.CommandLineUtils; 035 import org.codehaus.plexus.util.cli.Commandline; 036 import org.codehaus.plexus.util.cli.StreamConsumer; 037 038 /** 039 * Command line construction utility. 040 * 041 * @author Brett Porter 042 * @author Olivier Lamy 043 * @version $Id: SvnCommandLineUtils.java 1325497 2012-04-12 20:38:55Z rfscholte $ 044 */ 045 public final class SvnCommandLineUtils 046 { 047 private SvnCommandLineUtils() 048 { 049 } 050 051 public static void addTarget( Commandline cl, List<File> files ) 052 throws IOException 053 { 054 if ( files == null || files.isEmpty() ) 055 { 056 return; 057 } 058 059 StringBuilder sb = new StringBuilder(); 060 String ls = System.getProperty( "line.separator" ); 061 for ( File f : files ) 062 { 063 sb.append( f.getPath().replace( '\\', '/' ) ); 064 sb.append( ls ); 065 } 066 067 File targets = File.createTempFile( "maven-scm-", "-targets" ); 068 PrintStream out = new PrintStream( new FileOutputStream( targets ) ); 069 out.print( sb.toString() ); 070 out.flush(); 071 out.close(); 072 073 cl.createArg().setValue( "--targets" ); 074 cl.createArg().setValue( targets.getAbsolutePath() ); 075 076 targets.deleteOnExit(); 077 } 078 079 public static Commandline getBaseSvnCommandLine( File workingDirectory, SvnScmProviderRepository repository ) 080 { 081 Commandline cl = new Commandline(); 082 083 cl.setExecutable( "svn" ); 084 try 085 { 086 cl.addSystemEnvironment(); 087 cl.addEnvironment( "LC_MESSAGES", "C" ); 088 } 089 catch ( Exception e ) 090 { 091 //Do nothing 092 } 093 094 if ( workingDirectory != null ) 095 { 096 cl.setWorkingDirectory( workingDirectory.getAbsolutePath() ); 097 } 098 099 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 // [by Lenik] don't overwrite existing auth cache by default. 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 // SCM-482: force English resource bundle 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 }