001package org.apache.maven.scm.provider.svn.svnexe.command.changelog; 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 022import org.apache.maven.scm.ScmBranch; 023import org.apache.maven.scm.ScmException; 024import org.apache.maven.scm.ScmFileSet; 025import org.apache.maven.scm.ScmTag; 026import org.apache.maven.scm.ScmVersion; 027import org.apache.maven.scm.command.changelog.AbstractChangeLogCommand; 028import org.apache.maven.scm.command.changelog.ChangeLogScmRequest; 029import org.apache.maven.scm.command.changelog.ChangeLogScmResult; 030import org.apache.maven.scm.command.changelog.ChangeLogSet; 031import org.apache.maven.scm.provider.ScmProviderRepository; 032import org.apache.maven.scm.provider.svn.SvnTagBranchUtils; 033import org.apache.maven.scm.provider.svn.command.SvnCommand; 034import org.apache.maven.scm.provider.svn.repository.SvnScmProviderRepository; 035import org.apache.maven.scm.provider.svn.svnexe.command.SvnCommandLineUtils; 036import org.codehaus.plexus.util.Os; 037import org.codehaus.plexus.util.StringUtils; 038import org.codehaus.plexus.util.cli.CommandLineException; 039import org.codehaus.plexus.util.cli.CommandLineUtils; 040import org.codehaus.plexus.util.cli.Commandline; 041 042import java.io.File; 043import java.text.SimpleDateFormat; 044import java.util.Date; 045import java.util.Objects; 046import java.util.TimeZone; 047import org.apache.maven.scm.CommandParameter; 048import org.apache.maven.scm.CommandParameters; 049import org.apache.maven.scm.ScmResult; 050 051/** 052 * @author <a href="mailto:evenisse@apache.org">Emmanuel Venisse</a> 053 * @author Olivier Lamy 054 * 055 */ 056public class SvnChangeLogCommand 057 extends AbstractChangeLogCommand 058 implements SvnCommand 059{ 060 private static final String DATE_FORMAT = "yyyy-MM-dd HH:mm:ss Z"; 061 062 @Override 063 public ScmResult executeCommand( ScmProviderRepository repository, ScmFileSet fileSet, 064 CommandParameters parameters ) 065 throws ScmException 066 { 067 return executeChangeLogCommand( repository, fileSet, 068 parameters.getDate( CommandParameter.START_DATE, null ), 069 parameters.getDate( CommandParameter.END_DATE, null ), 070 (ScmBranch) parameters.getScmVersion( CommandParameter.BRANCH, null ), 071 parameters.getString( CommandParameter.CHANGELOG_DATE_PATTERN, null ), 072 parameters.getScmVersion( CommandParameter.START_SCM_VERSION, null ), 073 parameters.getScmVersion( CommandParameter.END_SCM_VERSION, null ), 074 parameters.getInt( CommandParameter.LIMIT, -1 ) ); 075 } 076 077 /** {@inheritDoc} */ 078 @Deprecated 079 @Override 080 protected ChangeLogScmResult executeChangeLogCommand( ScmProviderRepository repo, ScmFileSet fileSet, 081 ScmVersion startVersion, ScmVersion endVersion, 082 String datePattern ) 083 throws ScmException 084 { 085 return executeChangeLogCommand( repo, fileSet, null, null, null, datePattern, startVersion, endVersion, null ); 086 } 087 088 /** {@inheritDoc} */ 089 @Deprecated 090 @Override 091 protected ChangeLogScmResult executeChangeLogCommand( ScmProviderRepository repo, ScmFileSet fileSet, 092 Date startDate, Date endDate, ScmBranch branch, 093 String datePattern ) 094 throws ScmException 095 { 096 return executeChangeLogCommand( repo, fileSet, startDate, endDate, branch, datePattern, null, null, null ); 097 } 098 099 @Override 100 protected ChangeLogScmResult executeChangeLogCommand( ChangeLogScmRequest request ) 101 throws ScmException 102 { 103 final ScmVersion startVersion = request.getStartRevision(); 104 final ScmVersion endVersion = request.getEndRevision(); 105 final ScmFileSet fileSet = request.getScmFileSet(); 106 final String datePattern = request.getDatePattern(); 107 return executeChangeLogCommand( request.getScmRepository().getProviderRepository(), fileSet, 108 request.getStartDate(), request.getEndDate(), request.getScmBranch(), datePattern, startVersion, 109 endVersion, request.getLimit() ); 110 } 111 112 private ChangeLogScmResult executeChangeLogCommand( ScmProviderRepository repo, ScmFileSet fileSet, 113 Date startDate, Date endDate, ScmBranch branch, 114 String datePattern, ScmVersion startVersion, 115 ScmVersion endVersion, Integer limit ) 116 throws ScmException 117 { 118 Commandline cl = createCommandLine( (SvnScmProviderRepository) repo, fileSet.getBasedir(), branch, startDate, 119 endDate, startVersion, endVersion, limit ); 120 121 SvnChangeLogConsumer consumer = new SvnChangeLogConsumer( getLogger(), datePattern ); 122 123 CommandLineUtils.StringStreamConsumer stderr = new CommandLineUtils.StringStreamConsumer(); 124 125 if ( getLogger().isInfoEnabled() ) 126 { 127 getLogger().info( "Executing: " + SvnCommandLineUtils.cryptPassword( cl ) ); 128 129 if ( Os.isFamily( Os.FAMILY_WINDOWS ) ) 130 { 131 getLogger().info( "Working directory: " + cl.getWorkingDirectory().getAbsolutePath() ); 132 } 133 } 134 135 int exitCode; 136 137 try 138 { 139 exitCode = SvnCommandLineUtils.execute( cl, consumer, stderr, getLogger() ); 140 } 141 catch ( CommandLineException ex ) 142 { 143 throw new ScmException( "Error while executing svn command.", ex ); 144 } 145 146 if ( exitCode != 0 ) 147 { 148 return new ChangeLogScmResult( cl.toString(), "The svn command failed.", stderr.getOutput(), false ); 149 } 150 ChangeLogSet changeLogSet = new ChangeLogSet( consumer.getModifications(), startDate, endDate ); 151 changeLogSet.setStartVersion( startVersion ); 152 changeLogSet.setEndVersion( endVersion ); 153 154 return new ChangeLogScmResult( cl.toString(), changeLogSet ); 155 } 156 157 // ---------------------------------------------------------------------- 158 // 159 // ---------------------------------------------------------------------- 160 161 public static Commandline createCommandLine( SvnScmProviderRepository repository, File workingDirectory, 162 ScmBranch branch, Date startDate, Date endDate, 163 ScmVersion startVersion, ScmVersion endVersion ) 164 { 165 return createCommandLine( repository, workingDirectory, branch, startDate, endDate, startVersion, endVersion, 166 null ); 167 } 168 169 public static Commandline createCommandLine( SvnScmProviderRepository repository, File workingDirectory, 170 ScmBranch branch, Date startDate, Date endDate, 171 ScmVersion startVersion, ScmVersion endVersion, Integer limit ) 172 { 173 SimpleDateFormat dateFormat = new SimpleDateFormat( DATE_FORMAT ); 174 175 dateFormat.setTimeZone( TimeZone.getTimeZone( "GMT" ) ); 176 177 Commandline cl = SvnCommandLineUtils.getBaseSvnCommandLine( workingDirectory, repository ); 178 179 cl.createArg().setValue( "log" ); 180 181 cl.createArg().setValue( "-v" ); 182 183 // TODO: May want to add some kind of support for --stop-on-copy and --limit NUM 184 185 if ( limit != null && limit > 0 ) 186 { 187 cl.createArg().setValue( "--limit" ); 188 cl.createArg().setValue( Integer.toString( limit ) ); 189 } 190 191 if ( startDate != null ) 192 { 193 cl.createArg().setValue( "-r" ); 194 195 if ( endDate != null ) 196 { 197 cl.createArg().setValue( 198 "{" + dateFormat.format( startDate ) + "}" + ":" + "{" + dateFormat.format( endDate ) + "}" ); 199 } 200 else 201 { 202 cl.createArg().setValue( "{" + dateFormat.format( startDate ) + "}:HEAD" ); 203 } 204 } 205 206 if ( startVersion != null ) 207 { 208 cl.createArg().setValue( "-r" ); 209 210 if ( endVersion != null ) 211 { 212 if ( startVersion.getName().equals( endVersion.getName() ) ) 213 { 214 cl.createArg().setValue( startVersion.getName() ); 215 } 216 else 217 { 218 cl.createArg().setValue( startVersion.getName() + ":" + endVersion.getName() ); 219 } 220 } 221 else 222 { 223 cl.createArg().setValue( startVersion.getName() + ":HEAD" ); 224 } 225 } 226 227 if ( branch != null && StringUtils.isNotEmpty( branch.getName() ) ) 228 { 229 // By specifying a branch and this repository url below, subversion should show 230 // the changelog of that branch, but limit it to paths that also occur in this repository. 231 if ( branch instanceof ScmTag ) 232 { 233 String tagUrl = SvnTagBranchUtils.resolveTagUrl( repository, (ScmTag) branch ); 234 cl.createArg().setValue( tagUrl + "@" ); 235 } 236 else 237 { 238 String branchUrl = SvnTagBranchUtils.resolveBranchUrl( repository, branch ); 239 cl.createArg().setValue( branchUrl + "@" ); 240 } 241 } 242 243 if ( endVersion == null || !Objects.equals( "BASE", endVersion.getName() ) ) 244 { 245 cl.createArg().setValue( repository.getUrl() + "@" ); 246 } 247 248 return cl; 249 } 250}