View Javadoc
1   package org.apache.maven.scm.provider.git.jgit.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.ChangeSet;
23  import org.apache.maven.scm.ScmBranch;
24  import org.apache.maven.scm.ScmException;
25  import org.apache.maven.scm.ScmFileSet;
26  import org.apache.maven.scm.ScmVersion;
27  import org.apache.maven.scm.command.changelog.AbstractChangeLogCommand;
28  import org.apache.maven.scm.command.changelog.ChangeLogScmResult;
29  import org.apache.maven.scm.command.changelog.ChangeLogSet;
30  import org.apache.maven.scm.provider.ScmProviderRepository;
31  import org.apache.maven.scm.provider.git.command.GitCommand;
32  import org.apache.maven.scm.provider.git.jgit.command.JGitUtils;
33  import org.eclipse.jgit.api.Git;
34  import org.eclipse.jgit.errors.IncorrectObjectTypeException;
35  import org.eclipse.jgit.errors.MissingObjectException;
36  import org.eclipse.jgit.lib.Repository;
37  import org.eclipse.jgit.revwalk.RevCommit;
38  import org.eclipse.jgit.revwalk.RevSort;
39  
40  import java.io.File;
41  import java.io.IOException;
42  import java.util.ArrayList;
43  import java.util.Date;
44  import java.util.List;
45  
46  import static org.apache.maven.scm.provider.git.jgit.command.JGitUtils.getTags;
47  
48  /**
49   * @author <a href="mailto:struberg@yahoo.de">Mark Struberg</a>
50   * @author Dominik Bartholdi (imod)
51   * @since 1.9
52   */
53  public class JGitChangeLogCommand
54      extends AbstractChangeLogCommand
55      implements GitCommand
56  {
57  
58      /**
59       * {@inheritDoc}
60       */
61      protected ChangeLogScmResult executeChangeLogCommand( ScmProviderRepository repo, ScmFileSet fileSet,
62                                                            ScmVersion startVersion, ScmVersion endVersion,
63                                                            String datePattern )
64          throws ScmException
65      {
66          return executeChangeLogCommand( repo, fileSet, null, null, null, datePattern, startVersion, endVersion );
67      }
68  
69      @Override
70      protected ChangeLogScmResult executeChangeLogCommand( ScmProviderRepository repository, ScmFileSet fileSet,
71                                                            ScmVersion version, String datePattern )
72              throws ScmException
73      {
74          return executeChangeLogCommand( repository, fileSet, null, null, null, datePattern, null, null, version );
75      }
76  
77      /**
78       * {@inheritDoc}
79       */
80      protected ChangeLogScmResult executeChangeLogCommand( ScmProviderRepository repo, ScmFileSet fileSet,
81                                                            Date startDate, Date endDate, ScmBranch branch,
82                                                            String datePattern )
83          throws ScmException
84      {
85          return executeChangeLogCommand( repo, fileSet, startDate, endDate, branch, datePattern, null, null );
86      }
87  
88      protected ChangeLogScmResult executeChangeLogCommand( ScmProviderRepository repo, ScmFileSet fileSet,
89                                                            Date startDate, Date endDate, ScmBranch branch,
90                                                            String datePattern, ScmVersion startVersion,
91                                                            ScmVersion endVersion )
92          throws ScmException
93      {
94          return executeChangeLogCommand( repo, fileSet, startDate, endDate, branch, datePattern,
95                                          startVersion, endVersion, null );
96      }
97  
98      protected ChangeLogScmResult executeChangeLogCommand( ScmProviderRepository repo, ScmFileSet fileSet,
99                                                            Date startDate, Date endDate, ScmBranch branch,
100                                                           String datePattern, ScmVersion startVersion,
101                                                           ScmVersion endVersion, ScmVersion version )
102         throws ScmException
103     {
104         Git git = null;
105         boolean isARangeChangeLog = startVersion != null || endVersion != null;
106 
107         try
108         {
109             git = JGitUtils.openRepo( fileSet.getBasedir() );
110 
111             boolean versionOnly = startVersion == null && endVersion == null && version != null;
112 
113             String startRev;
114             String endRev;
115 
116             if ( versionOnly )
117             {
118                 startRev = null;
119                 endRev = version.getName();
120             }
121             else
122             {
123                 startRev = startVersion != null ? startVersion.getName() : ( isARangeChangeLog ? "HEAD" : null );
124                 endRev = endVersion != null ? endVersion.getName() : ( isARangeChangeLog ? "HEAD" : null );
125             }
126 
127             List<ChangeEntry> gitChanges =
128                 this.whatchanged( git.getRepository(), null, startRev, endRev, startDate, endDate, -1 );
129 
130             List<ChangeSet> modifications = new ArrayList<>( gitChanges.size() );
131 
132             for ( ChangeEntry change : gitChanges )
133             {
134                 ChangeSet scmChange = new ChangeSet();
135 
136                 scmChange.setAuthor( change.getAuthorName() );
137                 scmChange.setComment( change.getBody() );
138                 scmChange.setDate( change.getAuthorDate() );
139                 scmChange.setRevision( change.getCommitHash() );
140                 scmChange.setTags( change.getTags() );
141                 // X TODO scmChange.setFiles( change.get )
142 
143                 modifications.add( scmChange );
144             }
145 
146             ChangeLogSet changeLogSet = new ChangeLogSet( modifications, startDate, endDate );
147             changeLogSet.setStartVersion( startVersion );
148             changeLogSet.setEndVersion( endVersion );
149 
150             return new ChangeLogScmResult( "JGit changelog", changeLogSet );
151         }
152         catch ( Exception e )
153         {
154             throw new ScmException( "JGit changelog failure!", e );
155         }
156         finally
157         {
158             JGitUtils.closeRepo( git );
159         }
160     }
161 
162     public List<ChangeEntry> whatchanged( Repository repo, RevSort[] sortings, String fromRev, String toRev,
163                                           Date fromDate, Date toDate, int maxLines )
164         throws MissingObjectException, IncorrectObjectTypeException, IOException
165     {
166         List<RevCommit> revs = JGitUtils.getRevCommits( repo, sortings, fromRev, toRev, fromDate, toDate, maxLines );
167         List<ChangeEntry> changes = new ArrayList<>( revs.size() );
168 
169         if ( fromRev != null && fromRev.equals( toRev ) )
170         {
171             // there are no changes between 2 identical versions
172             return changes;
173         }
174 
175         for ( RevCommit c : revs )
176         {
177             ChangeEntry ce = new ChangeEntry();
178 
179             ce.setAuthorDate( c.getAuthorIdent().getWhen() );
180             ce.setAuthorEmail( c.getAuthorIdent().getEmailAddress() );
181             ce.setAuthorName( c.getAuthorIdent().getName() );
182             ce.setCommitterDate( c.getCommitterIdent().getWhen() );
183             ce.setCommitterEmail( c.getCommitterIdent().getEmailAddress() );
184             ce.setCommitterName( c.getCommitterIdent().getName() );
185 
186             ce.setSubject( c.getShortMessage() );
187             ce.setBody( c.getFullMessage() );
188 
189             ce.setCommitHash( c.getId().name() );
190             ce.setTreeHash( c.getTree().getId().name() );
191 
192             ce.setTags( getTags( repo, c ) );
193             // X TODO missing: file list
194 
195             changes.add( ce );
196         }
197 
198         return changes;
199     }
200 
201     /**
202      * 
203      */
204     public static final class ChangeEntry
205     {
206         private String commitHash;
207 
208         private String treeHash;
209 
210         private String authorName;
211 
212         private String authorEmail;
213 
214         private Date authorDate;
215 
216         private String committerName;
217 
218         private String committerEmail;
219 
220         private Date committerDate;
221 
222         private String subject;
223 
224         private String body;
225 
226         private List<File> files;
227         
228         private List<String> tags;
229 
230         public String getCommitHash()
231         {
232             return commitHash;
233         }
234 
235         public void setCommitHash( String commitHash )
236         {
237             this.commitHash = commitHash;
238         }
239 
240         public String getTreeHash()
241         {
242             return treeHash;
243         }
244 
245         public void setTreeHash( String treeHash )
246         {
247             this.treeHash = treeHash;
248         }
249 
250         public String getAuthorName()
251         {
252             return authorName;
253         }
254 
255         public void setAuthorName( String authorName )
256         {
257             this.authorName = authorName;
258         }
259 
260         public String getAuthorEmail()
261         {
262             return authorEmail;
263         }
264 
265         public void setAuthorEmail( String authorEmail )
266         {
267             this.authorEmail = authorEmail;
268         }
269 
270         public Date getAuthorDate()
271         {
272             return authorDate;
273         }
274 
275         public void setAuthorDate( Date authorDate )
276         {
277             this.authorDate = authorDate;
278         }
279 
280         public String getCommitterName()
281         {
282             return committerName;
283         }
284 
285         public void setCommitterName( String committerName )
286         {
287             this.committerName = committerName;
288         }
289 
290         public String getCommitterEmail()
291         {
292             return committerEmail;
293         }
294 
295         public void setCommitterEmail( String committerEmail )
296         {
297             this.committerEmail = committerEmail;
298         }
299 
300         public Date getCommitterDate()
301         {
302             return committerDate;
303         }
304 
305         public void setCommitterDate( Date committerDate )
306         {
307             this.committerDate = committerDate;
308         }
309 
310         public String getSubject()
311         {
312             return subject;
313         }
314 
315         public void setSubject( String subject )
316         {
317             this.subject = subject;
318         }
319 
320         public String getBody()
321         {
322             return body;
323         }
324 
325         public void setBody( String body )
326         {
327             this.body = body;
328         }
329 
330         public List<File> getFiles()
331         {
332             return files;
333         }
334 
335         public void setFiles( List<File> files )
336         {
337             this.files = files;
338         }
339 
340         public List<String> getTags()
341         {
342             return tags;
343         }
344 
345         public void setTags( List<String> tags )
346         {
347             this.tags = tags;
348         }
349     }
350 }