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 (IOException 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 public static final class ChangeEntry { 199 private String commitHash; 200 201 private String treeHash; 202 203 private String authorName; 204 205 private String authorEmail; 206 207 private Date authorDate; 208 209 private String committerName; 210 211 private String committerEmail; 212 213 private Date committerDate; 214 215 private String subject; 216 217 private String body; 218 219 private List<File> files; 220 221 private List<String> tags; 222 223 public String getCommitHash() { 224 return commitHash; 225 } 226 227 public void setCommitHash(String commitHash) { 228 this.commitHash = commitHash; 229 } 230 231 public String getTreeHash() { 232 return treeHash; 233 } 234 235 public void setTreeHash(String treeHash) { 236 this.treeHash = treeHash; 237 } 238 239 public String getAuthorName() { 240 return authorName; 241 } 242 243 public void setAuthorName(String authorName) { 244 this.authorName = authorName; 245 } 246 247 public String getAuthorEmail() { 248 return authorEmail; 249 } 250 251 public void setAuthorEmail(String authorEmail) { 252 this.authorEmail = authorEmail; 253 } 254 255 public Date getAuthorDate() { 256 return authorDate; 257 } 258 259 public void setAuthorDate(Date authorDate) { 260 this.authorDate = authorDate; 261 } 262 263 public String getCommitterName() { 264 return committerName; 265 } 266 267 public void setCommitterName(String committerName) { 268 this.committerName = committerName; 269 } 270 271 public String getCommitterEmail() { 272 return committerEmail; 273 } 274 275 public void setCommitterEmail(String committerEmail) { 276 this.committerEmail = committerEmail; 277 } 278 279 public Date getCommitterDate() { 280 return committerDate; 281 } 282 283 public void setCommitterDate(Date committerDate) { 284 this.committerDate = committerDate; 285 } 286 287 public String getSubject() { 288 return subject; 289 } 290 291 public void setSubject(String subject) { 292 this.subject = subject; 293 } 294 295 public String getBody() { 296 return body; 297 } 298 299 public void setBody(String body) { 300 this.body = body; 301 } 302 303 public List<File> getFiles() { 304 return files; 305 } 306 307 public void setFiles(List<File> files) { 308 this.files = files; 309 } 310 311 public List<String> getTags() { 312 return tags; 313 } 314 315 public void setTags(List<String> tags) { 316 this.tags = tags; 317 } 318 } 319}