diff --git a/src/main/scala/ScalatraBootstrap.scala b/src/main/scala/ScalatraBootstrap.scala index f84c99c..69ba545 100644 --- a/src/main/scala/ScalatraBootstrap.scala +++ b/src/main/scala/ScalatraBootstrap.scala @@ -16,6 +16,7 @@ context.mount(new LabelsController, "/*") context.mount(new MilestonesController, "/*") context.mount(new IssuesController, "/*") + context.mount(new PullRequestsController, "/*") context.mount(new RepositorySettingsController, "/*") val dir = new java.io.File(_root_.util.Directory.GitBucketHome) diff --git a/src/main/scala/app/PullRequestsController.scala b/src/main/scala/app/PullRequestsController.scala new file mode 100644 index 0000000..dee821f --- /dev/null +++ b/src/main/scala/app/PullRequestsController.scala @@ -0,0 +1,69 @@ +package app + +import util.{FileUtil, JGitUtil, ReferrerAuthenticator} +import util.Directory._ +import service._ +import org.eclipse.jgit.treewalk.CanonicalTreeParser +import util.JGitUtil.{DiffInfo, CommitInfo} +import scala.collection.mutable.ArrayBuffer + +class PullRequestsController extends PullRequestsControllerBase + with RepositoryService with AccountService with ReferrerAuthenticator + +trait PullRequestsControllerBase extends ControllerBase { + self: ReferrerAuthenticator => + + get("/:owner/:repository/pulls")(referrersOnly { repository => + pulls.html.list(repository) + }) + + // TODO Replace correct authenticator + get("/:owner/:repository/pulls/compare/*:*...*")(referrersOnly { repository => + if(repository.repository.originUserName.isEmpty || repository.repository.originRepositoryName.isEmpty){ + NotFound // TODO BadRequest? + } else { + val userName = params("owner") + val repositoryName = params("repository") + val Seq(origin, originId, forkedId) = multiParams("splat") + + JGitUtil.withGit(getRepositoryDir(userName, repositoryName)){ newGit => + JGitUtil.withGit(getRepositoryDir(origin, repository.repository.originRepositoryName.get)){ oldGit => + val oldReader = oldGit.getRepository.newObjectReader + val oldTreeIter = new CanonicalTreeParser + oldTreeIter.reset(oldReader, oldGit.getRepository.resolve("master^{tree}")) + + val newReader = newGit.getRepository.newObjectReader + val newTreeIter = new CanonicalTreeParser + newTreeIter.reset(newReader, newGit.getRepository.resolve("master^{tree}")) + + import scala.collection.JavaConverters._ + import util.Implicits._ + + val oldId = oldGit.getRepository.resolve(originId) + val newId = newGit.getRepository.resolve(forkedId) + val i = newGit.log.addRange(oldId, newId).call.iterator + + val commits = new ArrayBuffer[CommitInfo] + while(i.hasNext){ + val revCommit = i.next + commits += new CommitInfo(revCommit) + } + + val diffs = newGit.diff.setOldTree(oldTreeIter).setNewTree(newTreeIter).call.asScala.map { diff => + if(FileUtil.isImage(diff.getOldPath) || FileUtil.isImage(diff.getNewPath)){ + DiffInfo(diff.getChangeType, diff.getOldPath, diff.getNewPath, None, None) + } else { + DiffInfo(diff.getChangeType, diff.getOldPath, diff.getNewPath, + JGitUtil.getContent(oldGit, diff.getOldId.toObjectId, false).filter(FileUtil.isText).map(new String(_, "UTF-8")), + JGitUtil.getContent(newGit, diff.getNewId.toObjectId, false).filter(FileUtil.isText).map(new String(_, "UTF-8"))) + } + } + + pulls.html.compare(commits.toList.splitWith{ (commit1, commit2) => + view.helpers.date(commit1.time) == view.helpers.date(commit2.time) + }, diffs.toList, origin, originId, forkedId, newId.getName, repository) + } + } + } + }) +} diff --git a/src/main/twirl/pulls/compare.scala.html b/src/main/twirl/pulls/compare.scala.html new file mode 100644 index 0000000..e3decca --- /dev/null +++ b/src/main/twirl/pulls/compare.scala.html @@ -0,0 +1,75 @@ +@(commits: Seq[Seq[util.JGitUtil.CommitInfo]], diffs: List[util.JGitUtil.DiffInfo], + origin: String, originId: String, forkedId: String, commitId: String, + repository: service.RepositoryService.RepositoryInfo)(implicit context: app.Context) +@import context._ +@import view.helpers._ +@import org.eclipse.jgit.diff.DiffEntry.ChangeType +@html.main("Pull Requests - " + repository.owner + "/" + repository.name){ + @html.header("pulls", repository) +
@date(day.head.time) | +||
---|---|---|
+ @avatar(commit.committer, 20) + @commit.committer + | +@commit.shortMessage | ++ @commit.id.substring(0, 7) + | +