View Javadoc
1   package org.apache.maven.scm.provider.svn.svnexe.command.changelog;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   * http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import org.apache.maven.scm.ScmBranch;
23  import org.apache.maven.scm.ScmException;
24  import org.apache.maven.scm.ScmFileSet;
25  import org.apache.maven.scm.ScmTag;
26  import org.apache.maven.scm.ScmVersion;
27  import org.apache.maven.scm.command.changelog.AbstractChangeLogCommand;
28  import org.apache.maven.scm.command.changelog.ChangeLogScmRequest;
29  import org.apache.maven.scm.command.changelog.ChangeLogScmResult;
30  import org.apache.maven.scm.command.changelog.ChangeLogSet;
31  import org.apache.maven.scm.provider.ScmProviderRepository;
32  import org.apache.maven.scm.provider.svn.SvnTagBranchUtils;
33  import org.apache.maven.scm.provider.svn.command.SvnCommand;
34  import org.apache.maven.scm.provider.svn.repository.SvnScmProviderRepository;
35  import org.apache.maven.scm.provider.svn.svnexe.command.SvnCommandLineUtils;
36  import org.codehaus.plexus.util.Os;
37  import org.codehaus.plexus.util.StringUtils;
38  import org.codehaus.plexus.util.cli.CommandLineException;
39  import org.codehaus.plexus.util.cli.CommandLineUtils;
40  import org.codehaus.plexus.util.cli.Commandline;
41  
42  import java.io.File;
43  import java.text.SimpleDateFormat;
44  import java.util.Date;
45  import java.util.TimeZone;
46  
47  /**
48   * @author <a href="mailto:evenisse@apache.org">Emmanuel Venisse</a>
49   * @author Olivier Lamy
50   *
51   */
52  public class SvnChangeLogCommand
53      extends AbstractChangeLogCommand
54      implements SvnCommand
55  {
56      private static final String DATE_FORMAT = "yyyy-MM-dd HH:mm:ss Z";
57  
58      /** {@inheritDoc} */
59      @Deprecated
60      protected ChangeLogScmResult executeChangeLogCommand( ScmProviderRepository repo, ScmFileSet fileSet,
61                                                            ScmVersion startVersion, ScmVersion endVersion,
62                                                            String datePattern )
63          throws ScmException
64      {
65          return executeChangeLogCommand( repo, fileSet, null, null, null, datePattern, startVersion, endVersion, null );
66      }
67  
68      /** {@inheritDoc} */
69      @Deprecated
70      protected ChangeLogScmResult executeChangeLogCommand( ScmProviderRepository repo, ScmFileSet fileSet,
71                                                            Date startDate, Date endDate, ScmBranch branch,
72                                                            String datePattern )
73          throws ScmException
74      {
75          return executeChangeLogCommand( repo, fileSet, startDate, endDate, branch, datePattern, null, null, null );
76      }
77  
78      @Override
79      protected ChangeLogScmResult executeChangeLogCommand( ChangeLogScmRequest request )
80          throws ScmException
81      {
82          final ScmVersion startVersion = request.getStartRevision();
83          final ScmVersion endVersion = request.getEndRevision();
84          final ScmFileSet fileSet = request.getScmFileSet();
85          final String datePattern = request.getDatePattern();
86          return executeChangeLogCommand( request.getScmRepository().getProviderRepository(), fileSet,
87              request.getStartDate(), request.getEndDate(), request.getScmBranch(), datePattern, startVersion,
88                  endVersion, request.getLimit() );
89      }
90  
91      private ChangeLogScmResult executeChangeLogCommand( ScmProviderRepository repo, ScmFileSet fileSet,
92                                                            Date startDate, Date endDate, ScmBranch branch,
93                                                            String datePattern, ScmVersion startVersion,
94                                                            ScmVersion endVersion, Integer limit )
95          throws ScmException
96      {
97          Commandline cl = createCommandLine( (SvnScmProviderRepository) repo, fileSet.getBasedir(), branch, startDate,
98                                              endDate, startVersion, endVersion, limit );
99  
100         SvnChangeLogConsumer consumer = new SvnChangeLogConsumer( getLogger(), datePattern );
101 
102         CommandLineUtils.StringStreamConsumer stderr = new CommandLineUtils.StringStreamConsumer();
103 
104         if ( getLogger().isInfoEnabled() )
105         {
106             getLogger().info( "Executing: " + SvnCommandLineUtils.cryptPassword( cl ) );
107 
108             if ( Os.isFamily( Os.FAMILY_WINDOWS ) )
109             {
110                 getLogger().info( "Working directory: " + cl.getWorkingDirectory().getAbsolutePath() );
111             }
112         }
113 
114         int exitCode;
115 
116         try
117         {
118             exitCode = SvnCommandLineUtils.execute( cl, consumer, stderr, getLogger() );
119         }
120         catch ( CommandLineException ex )
121         {
122             throw new ScmException( "Error while executing svn command.", ex );
123         }
124 
125         if ( exitCode != 0 )
126         {
127             return new ChangeLogScmResult( cl.toString(), "The svn command failed.", stderr.getOutput(), false );
128         }
129         ChangeLogSet changeLogSet = new ChangeLogSet( consumer.getModifications(), startDate, endDate );
130         changeLogSet.setStartVersion( startVersion );
131         changeLogSet.setEndVersion( endVersion );
132 
133         return new ChangeLogScmResult( cl.toString(), changeLogSet );
134     }
135 
136     // ----------------------------------------------------------------------
137     //
138     // ----------------------------------------------------------------------
139 
140     public static Commandline createCommandLine( SvnScmProviderRepository repository, File workingDirectory,
141                                                  ScmBranch branch, Date startDate, Date endDate,
142                                                  ScmVersion startVersion, ScmVersion endVersion )
143     {
144         return createCommandLine( repository, workingDirectory, branch, startDate, endDate, startVersion, endVersion,
145                                   null );
146     }
147 
148     public static Commandline createCommandLine( SvnScmProviderRepository repository, File workingDirectory,
149                                                  ScmBranch branch, Date startDate, Date endDate,
150                                                  ScmVersion startVersion, ScmVersion endVersion, Integer limit )
151     {
152         SimpleDateFormat dateFormat = new SimpleDateFormat( DATE_FORMAT );
153 
154         dateFormat.setTimeZone( TimeZone.getTimeZone( "GMT" ) );
155 
156         Commandline cl = SvnCommandLineUtils.getBaseSvnCommandLine( workingDirectory, repository );
157 
158         cl.createArg().setValue( "log" );
159 
160         cl.createArg().setValue( "-v" );
161 
162         // TODO: May want to add some kind of support for --stop-on-copy and --limit NUM
163 
164         if ( limit != null && limit > 0 )
165         {
166             cl.createArg().setValue( "--limit" );
167             cl.createArg().setValue( Integer.toString( limit ) );
168         }
169 
170         if ( startDate != null )
171         {
172             cl.createArg().setValue( "-r" );
173 
174             if ( endDate != null )
175             {
176                 cl.createArg().setValue(
177                     "{" + dateFormat.format( startDate ) + "}" + ":" + "{" + dateFormat.format( endDate ) + "}" );
178             }
179             else
180             {
181                 cl.createArg().setValue( "{" + dateFormat.format( startDate ) + "}:HEAD" );
182             }
183         }
184 
185         if ( startVersion != null )
186         {
187             cl.createArg().setValue( "-r" );
188 
189             if ( endVersion != null )
190             {
191                 if ( startVersion.getName().equals( endVersion.getName() ) )
192                 {
193                     cl.createArg().setValue( startVersion.getName() );
194                 }
195                 else
196                 {
197                     cl.createArg().setValue( startVersion.getName() + ":" + endVersion.getName() );
198                 }
199             }
200             else
201             {
202                 cl.createArg().setValue( startVersion.getName() + ":HEAD" );
203             }
204         }
205 
206         if ( branch != null && StringUtils.isNotEmpty( branch.getName() ) )
207         {
208             // By specifying a branch and this repository url below, subversion should show
209             // the changelog of that branch, but limit it to paths that also occur in this repository.
210             if ( branch instanceof ScmTag )
211             {
212                 cl.createArg().setValue( SvnTagBranchUtils.resolveTagUrl( repository, (ScmTag) branch ) );
213             }
214             else
215             {
216                 cl.createArg().setValue( SvnTagBranchUtils.resolveBranchUrl( repository, branch ) );
217             }
218         }
219 
220         if ( endVersion == null || !StringUtils.equals( "BASE", endVersion.getName() ) )
221         {
222             cl.createArg().setValue( repository.getUrl() );
223         }
224 
225         return cl;
226     }
227 }