001/* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, 013 * software distributed under the License is distributed on an 014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 015 * KIND, either express or implied. See the License for the 016 * specific language governing permissions and limitations 017 * under the License. 018 */ 019package org.apache.maven.scm.provider.git.jgit.command.changelog; 020 021import java.io.File; 022import java.io.IOException; 023import java.util.ArrayList; 024import java.util.Date; 025import java.util.List; 026 027import org.apache.maven.scm.ChangeSet; 028import org.apache.maven.scm.ScmBranch; 029import org.apache.maven.scm.ScmException; 030import org.apache.maven.scm.ScmFileSet; 031import org.apache.maven.scm.ScmVersion; 032import org.apache.maven.scm.command.changelog.AbstractChangeLogCommand; 033import org.apache.maven.scm.command.changelog.ChangeLogScmResult; 034import org.apache.maven.scm.command.changelog.ChangeLogSet; 035import org.apache.maven.scm.provider.ScmProviderRepository; 036import org.apache.maven.scm.provider.git.command.GitCommand; 037import org.apache.maven.scm.provider.git.jgit.command.JGitUtils; 038import org.eclipse.jgit.api.Git; 039import org.eclipse.jgit.errors.IncorrectObjectTypeException; 040import org.eclipse.jgit.errors.MissingObjectException; 041import org.eclipse.jgit.lib.Repository; 042import org.eclipse.jgit.revwalk.RevCommit; 043import org.eclipse.jgit.revwalk.RevSort; 044 045import static org.apache.maven.scm.provider.git.jgit.command.JGitUtils.getTags; 046 047/** 048 * @author <a href="mailto:struberg@yahoo.de">Mark Struberg</a> 049 * @author Dominik Bartholdi (imod) 050 * @since 1.9 051 */ 052public class JGitChangeLogCommand extends AbstractChangeLogCommand implements GitCommand { 053 054 /** 055 * {@inheritDoc} 056 */ 057 protected ChangeLogScmResult executeChangeLogCommand( 058 ScmProviderRepository repo, 059 ScmFileSet fileSet, 060 ScmVersion startVersion, 061 ScmVersion endVersion, 062 String datePattern) 063 throws ScmException { 064 return executeChangeLogCommand(repo, fileSet, null, null, null, datePattern, startVersion, endVersion); 065 } 066 067 @Override 068 protected ChangeLogScmResult executeChangeLogCommand( 069 ScmProviderRepository repository, ScmFileSet fileSet, ScmVersion version, String datePattern) 070 throws ScmException { 071 return executeChangeLogCommand(repository, fileSet, null, null, null, datePattern, null, null, version); 072 } 073 074 /** 075 * {@inheritDoc} 076 */ 077 protected ChangeLogScmResult executeChangeLogCommand( 078 ScmProviderRepository repo, 079 ScmFileSet fileSet, 080 Date startDate, 081 Date endDate, 082 ScmBranch branch, 083 String datePattern) 084 throws ScmException { 085 return executeChangeLogCommand(repo, fileSet, startDate, endDate, branch, datePattern, null, null); 086 } 087 088 protected ChangeLogScmResult executeChangeLogCommand( 089 ScmProviderRepository repo, 090 ScmFileSet fileSet, 091 Date startDate, 092 Date endDate, 093 ScmBranch branch, 094 String datePattern, 095 ScmVersion startVersion, 096 ScmVersion endVersion) 097 throws ScmException { 098 return executeChangeLogCommand( 099 repo, fileSet, startDate, endDate, branch, datePattern, startVersion, endVersion, null); 100 } 101 102 protected ChangeLogScmResult executeChangeLogCommand( 103 ScmProviderRepository repo, 104 ScmFileSet fileSet, 105 Date startDate, 106 Date endDate, 107 ScmBranch branch, 108 String datePattern, 109 ScmVersion startVersion, 110 ScmVersion endVersion, 111 ScmVersion version) 112 throws ScmException { 113 Git git = null; 114 boolean isARangeChangeLog = startVersion != null || endVersion != null; 115 116 try { 117 git = JGitUtils.openRepo(fileSet.getBasedir()); 118 119 boolean versionOnly = startVersion == null && endVersion == null && version != null; 120 121 String startRev; 122 String endRev; 123 124 if (versionOnly) { 125 startRev = null; 126 endRev = version.getName(); 127 } else { 128 startRev = startVersion != null ? startVersion.getName() : (isARangeChangeLog ? "HEAD" : null); 129 endRev = endVersion != null ? endVersion.getName() : (isARangeChangeLog ? "HEAD" : null); 130 } 131 132 List<ChangeEntry> gitChanges = 133 this.whatchanged(git.getRepository(), null, startRev, endRev, startDate, endDate, -1); 134 135 List<ChangeSet> modifications = new ArrayList<>(gitChanges.size()); 136 137 for (ChangeEntry change : gitChanges) { 138 ChangeSet scmChange = new ChangeSet(); 139 140 scmChange.setAuthor(change.getAuthorName()); 141 scmChange.setComment(change.getBody()); 142 scmChange.setDate(change.getAuthorDate()); 143 scmChange.setRevision(change.getCommitHash()); 144 scmChange.setTags(change.getTags()); 145 // X TODO scmChange.setFiles( change.get ) 146 147 modifications.add(scmChange); 148 } 149 150 ChangeLogSet changeLogSet = new ChangeLogSet(modifications, startDate, endDate); 151 changeLogSet.setStartVersion(startVersion); 152 changeLogSet.setEndVersion(endVersion); 153 154 return new ChangeLogScmResult("JGit changelog", changeLogSet); 155 } catch (Exception e) { 156 throw new ScmException("JGit changelog failure!", e); 157 } finally { 158 JGitUtils.closeRepo(git); 159 } 160 } 161 162 public List<ChangeEntry> whatchanged( 163 Repository repo, RevSort[] sortings, String fromRev, String toRev, Date fromDate, Date toDate, int maxLines) 164 throws MissingObjectException, IncorrectObjectTypeException, IOException { 165 List<RevCommit> revs = JGitUtils.getRevCommits(repo, sortings, fromRev, toRev, fromDate, toDate, maxLines); 166 List<ChangeEntry> changes = new ArrayList<>(revs.size()); 167 168 if (fromRev != null && fromRev.equals(toRev)) { 169 // there are no changes between 2 identical versions 170 return changes; 171 } 172 173 for (RevCommit c : revs) { 174 ChangeEntry ce = new ChangeEntry(); 175 176 ce.setAuthorDate(c.getAuthorIdent().getWhen()); 177 ce.setAuthorEmail(c.getAuthorIdent().getEmailAddress()); 178 ce.setAuthorName(c.getAuthorIdent().getName()); 179 ce.setCommitterDate(c.getCommitterIdent().getWhen()); 180 ce.setCommitterEmail(c.getCommitterIdent().getEmailAddress()); 181 ce.setCommitterName(c.getCommitterIdent().getName()); 182 183 ce.setSubject(c.getShortMessage()); 184 ce.setBody(c.getFullMessage()); 185 186 ce.setCommitHash(c.getId().name()); 187 ce.setTreeHash(c.getTree().getId().name()); 188 189 ce.setTags(getTags(repo, c)); 190 // X TODO missing: file list 191 192 changes.add(ce); 193 } 194 195 return changes; 196 } 197 198 /** 199 * 200 */ 201 public static final class ChangeEntry { 202 private String commitHash; 203 204 private String treeHash; 205 206 private String authorName; 207 208 private String authorEmail; 209 210 private Date authorDate; 211 212 private String committerName; 213 214 private String committerEmail; 215 216 private Date committerDate; 217 218 private String subject; 219 220 private String body; 221 222 private List<File> files; 223 224 private List<String> tags; 225 226 public String getCommitHash() { 227 return commitHash; 228 } 229 230 public void setCommitHash(String commitHash) { 231 this.commitHash = commitHash; 232 } 233 234 public String getTreeHash() { 235 return treeHash; 236 } 237 238 public void setTreeHash(String treeHash) { 239 this.treeHash = treeHash; 240 } 241 242 public String getAuthorName() { 243 return authorName; 244 } 245 246 public void setAuthorName(String authorName) { 247 this.authorName = authorName; 248 } 249 250 public String getAuthorEmail() { 251 return authorEmail; 252 } 253 254 public void setAuthorEmail(String authorEmail) { 255 this.authorEmail = authorEmail; 256 } 257 258 public Date getAuthorDate() { 259 return authorDate; 260 } 261 262 public void setAuthorDate(Date authorDate) { 263 this.authorDate = authorDate; 264 } 265 266 public String getCommitterName() { 267 return committerName; 268 } 269 270 public void setCommitterName(String committerName) { 271 this.committerName = committerName; 272 } 273 274 public String getCommitterEmail() { 275 return committerEmail; 276 } 277 278 public void setCommitterEmail(String committerEmail) { 279 this.committerEmail = committerEmail; 280 } 281 282 public Date getCommitterDate() { 283 return committerDate; 284 } 285 286 public void setCommitterDate(Date committerDate) { 287 this.committerDate = committerDate; 288 } 289 290 public String getSubject() { 291 return subject; 292 } 293 294 public void setSubject(String subject) { 295 this.subject = subject; 296 } 297 298 public String getBody() { 299 return body; 300 } 301 302 public void setBody(String body) { 303 this.body = body; 304 } 305 306 public List<File> getFiles() { 307 return files; 308 } 309 310 public void setFiles(List<File> files) { 311 this.files = files; 312 } 313 314 public List<String> getTags() { 315 return tags; 316 } 317 318 public void setTags(List<String> tags) { 319 this.tags = tags; 320 } 321 } 322}