(refs #2)Implementing the comparing view.

This commit is contained in:
takezoe
2013-07-13 20:09:19 +09:00
parent 2cc2902930
commit eb82af9006
5 changed files with 104 additions and 14 deletions

View File

@@ -6,35 +6,62 @@ import service._
import org.eclipse.jgit.treewalk.CanonicalTreeParser import org.eclipse.jgit.treewalk.CanonicalTreeParser
import util.JGitUtil.{DiffInfo, CommitInfo} import util.JGitUtil.{DiffInfo, CommitInfo}
import scala.collection.mutable.ArrayBuffer import scala.collection.mutable.ArrayBuffer
import org.eclipse.jgit.api.Git
import org.eclipse.jgit.lib.ObjectId
class PullRequestsController extends PullRequestsControllerBase class PullRequestsController extends PullRequestsControllerBase
with RepositoryService with AccountService with ReferrerAuthenticator with RepositoryService with AccountService with ReferrerAuthenticator
trait PullRequestsControllerBase extends ControllerBase { trait PullRequestsControllerBase extends ControllerBase {
self: ReferrerAuthenticator => self: ReferrerAuthenticator with RepositoryService =>
get("/:owner/:repository/pulls")(referrersOnly { repository => get("/:owner/:repository/pulls")(referrersOnly { repository =>
pulls.html.list(repository) pulls.html.list(repository)
}) })
// TODO Replace correct authenticator
get("/:owner/:repository/pulls/compare")(referrersOnly { newRepo =>
(newRepo.repository.originUserName, newRepo.repository.originRepositoryName) match {
case (None,_)|(_, None) => NotFound // TODO BadRequest?
case (Some(originUserName), Some(originRepositoryName)) => {
getRepository(originUserName, originRepositoryName, baseUrl).map { oldRepo =>
withGit(
getRepositoryDir(originUserName, originRepositoryName),
getRepositoryDir(params("owner"), params("repository"))
){ (oldGit, newGit) =>
val oldBranch = JGitUtil.getDefaultBranch(oldGit, oldRepo).get._2
val newBranch = JGitUtil.getDefaultBranch(newGit, newRepo).get._2
redirect(s"${context.path}/${newRepo.owner}/${newRepo.name}/pulls/compare/${originUserName}:${oldBranch}...${newBranch}")
}
} getOrElse NotFound
}
}
})
// TODO Replace correct authenticator // TODO Replace correct authenticator
get("/:owner/:repository/pulls/compare/*:*...*")(referrersOnly { repository => get("/:owner/:repository/pulls/compare/*:*...*")(referrersOnly { repository =>
if(repository.repository.originUserName.isEmpty || repository.repository.originRepositoryName.isEmpty){ if(repository.repository.originUserName.isEmpty || repository.repository.originRepositoryName.isEmpty){
NotFound // TODO BadRequest? NotFound // TODO BadRequest?
} else { } else {
val userName = params("owner") getRepository(
val repositoryName = params("repository") repository.repository.originUserName.get,
repository.repository.originRepositoryName.get, baseUrl
).map{ originRepository =>
val Seq(origin, originId, forkedId) = multiParams("splat") val Seq(origin, originId, forkedId) = multiParams("splat")
JGitUtil.withGit(getRepositoryDir(userName, repositoryName)){ newGit => withGit(
JGitUtil.withGit(getRepositoryDir(origin, repository.repository.originRepositoryName.get)){ oldGit => getRepositoryDir(origin, repository.repository.originRepositoryName.get),
getRepositoryDir(params("owner"), params("repository"))
){ (oldGit, newGit) =>
val oldReader = oldGit.getRepository.newObjectReader val oldReader = oldGit.getRepository.newObjectReader
val oldTreeIter = new CanonicalTreeParser val oldTreeIter = new CanonicalTreeParser
oldTreeIter.reset(oldReader, oldGit.getRepository.resolve("master^{tree}")) oldTreeIter.reset(oldReader, oldGit.getRepository.resolve(s"${originId}^{tree}"))
val newReader = newGit.getRepository.newObjectReader val newReader = newGit.getRepository.newObjectReader
val newTreeIter = new CanonicalTreeParser val newTreeIter = new CanonicalTreeParser
newTreeIter.reset(newReader, newGit.getRepository.resolve("master^{tree}")) newTreeIter.reset(newReader, newGit.getRepository.resolve(s"${forkedId}^{tree}"))
import scala.collection.JavaConverters._ import scala.collection.JavaConverters._
import util.Implicits._ import util.Implicits._
@@ -61,9 +88,21 @@ trait PullRequestsControllerBase extends ControllerBase {
pulls.html.compare(commits.toList.splitWith{ (commit1, commit2) => pulls.html.compare(commits.toList.splitWith{ (commit1, commit2) =>
view.helpers.date(commit1.time) == view.helpers.date(commit2.time) view.helpers.date(commit1.time) == view.helpers.date(commit2.time)
}, diffs.toList, origin, originId, forkedId, newId.getName, repository) }, diffs.toList, origin, originId, forkedId, newId.getName, repository, originRepository)
}
} }
} getOrElse NotFound
} }
}) })
private def withGit[T](oldDir: java.io.File, newDir: java.io.File)(action: (Git, Git) => T): T = {
val oldGit = Git.open(oldDir)
val newGit = Git.open(newDir)
try {
action(oldGit, newGit)
} finally {
oldGit.getRepository.close
newGit.getRepository.close
}
}
} }

View File

@@ -218,7 +218,7 @@ trait RepositoryViewerControllerBase extends ControllerBase {
JGitUtil.withGit(getRepositoryDir(repository.owner, repository.name)){ git => JGitUtil.withGit(getRepositoryDir(repository.owner, repository.name)){ git =>
val revisions = Seq(if(revstr.isEmpty) repository.repository.defaultBranch else revstr, repository.branchList.head) val revisions = Seq(if(revstr.isEmpty) repository.repository.defaultBranch else revstr, repository.branchList.head)
// get specified commit // get specified commit
revisions.map { rev => (git.getRepository.resolve(rev), rev)}.find(_._1 != null).map { case (objectId, revision) => JGitUtil.getDefaultBranch(git, repository, revstr).map { case (objectId, revision) =>
val revCommit = JGitUtil.getRevCommitFromId(git, objectId) val revCommit = JGitUtil.getRevCommitFromId(git, objectId)
// get files // get files

View File

@@ -185,6 +185,17 @@ trait RepositoryService { self: AccountService =>
} }
} }
// def getBaseRepositories(userName: String, repositoryName: String, repositories: List[String] = Nil): List[String] = {
// Query(Repositories).filter { t =>
// (t.originUserName is userName.bind) && (t.originRepositoryName is repositoryName.bind)
// }.map(_.userName).list match {
// case Nil => repositories.sorted
// case list => list.map { x =>
// getBaseRepositories(x, repositoryName, x :: repositories)
// }.flatten
// }
// }
} }
object RepositoryService { object RepositoryService {

View File

@@ -15,6 +15,7 @@ import org.eclipse.jgit.util.io.DisabledOutputStream
import org.eclipse.jgit.errors.MissingObjectException import org.eclipse.jgit.errors.MissingObjectException
import java.util.Date import java.util.Date
import org.eclipse.jgit.api.errors.NoHeadException import org.eclipse.jgit.api.errors.NoHeadException
import service.RepositoryService
/** /**
* Provides complex JGit operations. * Provides complex JGit operations.
@@ -532,4 +533,14 @@ object JGitUtil {
config.save config.save
} }
def getDefaultBranch(git: Git, repository: RepositoryService.RepositoryInfo,
revstr: String = ""): Option[(ObjectId, String)] = {
Seq(
if(revstr.isEmpty) repository.repository.defaultBranch else revstr,
repository.branchList.head
).map { rev =>
(git.getRepository.resolve(rev), rev)
}.find(_._1 != null)
}
} }

View File

@@ -1,14 +1,34 @@
@(commits: Seq[Seq[util.JGitUtil.CommitInfo]], diffs: List[util.JGitUtil.DiffInfo], @(commits: Seq[Seq[util.JGitUtil.CommitInfo]], diffs: List[util.JGitUtil.DiffInfo],
origin: String, originId: String, forkedId: String, commitId: String, origin: String, originId: String, forkedId: String, commitId: String,
repository: service.RepositoryService.RepositoryInfo)(implicit context: app.Context) repository: service.RepositoryService.RepositoryInfo,
originRepository: service.RepositoryService.RepositoryInfo)(implicit context: app.Context)
@import context._ @import context._
@import view.helpers._ @import view.helpers._
@import org.eclipse.jgit.diff.DiffEntry.ChangeType @import org.eclipse.jgit.diff.DiffEntry.ChangeType
@html.main("Pull Requests - " + repository.owner + "/" + repository.name){ @html.main("Pull Requests - " + repository.owner + "/" + repository.name){
@html.header("pulls", repository) @html.header("pulls", repository)
<div style="border: 1px solid #eee; background-color: #f8f8f8; margin-bottom: 10px; padding: 8px;"> <div style="border: 1px solid #eee; background-color: #f8f8f8; margin-bottom: 10px; padding: 8px;">
<div id="compare-info">
<a href="#" id="edit-compare-condition" class="btn btn-mini pull-right">Edit</a>
<span class="label label-info monospace">@origin:@originId</span> ... <span class="label label-info monospace">@repository.owner:@forkedId</span> <span class="label label-info monospace">@origin:@originId</span> ... <span class="label label-info monospace">@repository.owner:@forkedId</span>
</div> </div>
<div id="compare-edit" style="display: none;">
<a href="#" id="refresh-compare" class="pull-right"><i class="icon-remove-circle"></i></a>
<span class="label label-info monospace">@origin/@repository.name:</span>
@helper.html.dropdown(originId) {
@originRepository.branchList.map { branch =>
<li><a href="#">@helper.html.checkicon(branch == originId) @branch</a></li>
}
}
...
<span class="label label-info monospace">@repository.owner/@repository.name:</span>
@helper.html.dropdown(forkedId) {
@repository.branchList.map { branch =>
<li><a href="#">@helper.html.checkicon(branch == forkedId) @branch</a></li>
}
}
</div>
</div>
<div style="margin-bottom: 10px;"> <div style="margin-bottom: 10px;">
<a href="#" class="btn">Click to create a pull request for this comparison</a> <a href="#" class="btn">Click to create a pull request for this comparison</a>
</div> </div>
@@ -63,6 +83,15 @@
} }
<script> <script>
$(function(){ $(function(){
$('#edit-compare-condition').click(function(){
$('#compare-info').hide();
$('#compare-edit').show();
});
$('#refresh-compare').click(function(){
// TODO send request
});
$('#toggle-file-list').click(function(){ $('#toggle-file-list').click(function(){
$('#commit-file-list').toggle(); $('#commit-file-list').toggle();
if($(this).val() == 'Show file list'){ if($(this).val() == 'Show file list'){