(refs #1348)Keep pull request comment if new commits are pushed

This commit is contained in:
Naoki Takezoe
2016-12-11 14:16:35 +09:00
parent 5d928b1a62
commit 00eab5d584
9 changed files with 155 additions and 44 deletions

View File

@@ -15,6 +15,7 @@ scalaVersion := "2.11.8"
// dependency settings
resolvers ++= Seq(
Classpaths.typesafeReleases,
Resolver.jcenterRepo,
"amateras" at "http://amateras.sourceforge.jp/mvn/",
"sonatype-snapshot" at "https://oss.sonatype.org/content/repositories/snapshots/",
"amateras-snapshot" at "http://amateras.sourceforge.jp/mvn-snapshot/"
@@ -45,6 +46,7 @@ libraryDependencies ++= Seq(
"com.typesafe" % "config" % "1.3.0",
"com.typesafe.akka" %% "akka-actor" % "2.3.15",
"fr.brouillard.oss.security.xhub" % "xhub4j-core" % "1.0.0",
"com.github.bkromhout" % "java-diff-utils" % "2.1.1",
"com.enragedginger" %% "akka-quartz-scheduler" % "1.4.0-akka-2.3.x" exclude("c3p0","c3p0"),
"org.eclipse.jetty" % "jetty-webapp" % JettyVersion % "provided",
"javax.servlet" % "javax.servlet-api" % "3.1.0" % "provided",

View File

@@ -22,6 +22,7 @@ class ApiController extends ApiControllerBase
with IssuesService
with LabelsService
with PullRequestService
with CommitsService
with CommitStatusService
with RepositoryCreationService
with HandleCommentService

View File

@@ -1,13 +1,13 @@
package gitbucket.core.controller
import gitbucket.core.dashboard.html
import gitbucket.core.service.{RepositoryService, PullRequestService, AccountService, IssuesService}
import gitbucket.core.util.{StringUtil, Keys, UsersAuthenticator}
import gitbucket.core.service._
import gitbucket.core.util.{Keys, UsersAuthenticator}
import gitbucket.core.util.Implicits._
import gitbucket.core.service.IssuesService._
class DashboardController extends DashboardControllerBase
with IssuesService with PullRequestService with RepositoryService with AccountService
with IssuesService with PullRequestService with RepositoryService with AccountService with CommitsService
with UsersAuthenticator
trait DashboardControllerBase extends ControllerBase {

View File

@@ -14,12 +14,33 @@ import org.scalatra.Ok
class IssuesController extends IssuesControllerBase
with IssuesService with RepositoryService with AccountService with LabelsService with MilestonesService with ActivityService with HandleCommentService
with ReadableUsersAuthenticator with ReferrerAuthenticator with WritableUsersAuthenticator with PullRequestService with WebHookIssueCommentService
with IssuesService
with RepositoryService
with AccountService
with LabelsService
with MilestonesService
with ActivityService
with HandleCommentService
with ReadableUsersAuthenticator
with ReferrerAuthenticator
with WritableUsersAuthenticator
with PullRequestService
with WebHookIssueCommentService
with CommitsService
trait IssuesControllerBase extends ControllerBase {
self: IssuesService with RepositoryService with AccountService with LabelsService with MilestonesService with ActivityService with HandleCommentService
with ReadableUsersAuthenticator with ReferrerAuthenticator with WritableUsersAuthenticator with PullRequestService with WebHookIssueCommentService =>
self: IssuesService
with RepositoryService
with AccountService
with LabelsService
with MilestonesService
with ActivityService
with HandleCommentService
with ReadableUsersAuthenticator
with ReferrerAuthenticator
with WritableUsersAuthenticator
with PullRequestService
with WebHookIssueCommentService =>
case class IssueCreateForm(title: String, content: Option[String],
assignedUserName: Option[String], milestoneId: Option[Int], labelNames: Option[String])

View File

@@ -11,7 +11,6 @@ import gitbucket.core.service._
import gitbucket.core.util.ControlUtil._
import gitbucket.core.util.Directory._
import gitbucket.core.util.Implicits._
import gitbucket.core.util.JGitUtil._
import gitbucket.core.util._
import gitbucket.core.view
import gitbucket.core.view.helpers
@@ -498,25 +497,25 @@ trait PullRequestsControllerBase extends ControllerBase {
(defaultOwner, value)
}
private def getRequestCompareInfo(userName: String, repositoryName: String, branch: String,
requestUserName: String, requestRepositoryName: String, requestCommitId: String): (Seq[Seq[CommitInfo]], Seq[DiffInfo]) =
using(
Git.open(getRepositoryDir(userName, repositoryName)),
Git.open(getRepositoryDir(requestUserName, requestRepositoryName))
){ (oldGit, newGit) =>
val oldId = oldGit.getRepository.resolve(branch)
val newId = newGit.getRepository.resolve(requestCommitId)
val commits = newGit.log.addRange(oldId, newId).call.iterator.asScala.map { revCommit =>
new CommitInfo(revCommit)
}.toList.splitWith { (commit1, commit2) =>
helpers.date(commit1.commitTime) == view.helpers.date(commit2.commitTime)
}
val diffs = JGitUtil.getDiffs(newGit, oldId.getName, newId.getName, true)
(commits, diffs)
}
// private def getRequestCompareInfo(userName: String, repositoryName: String, branch: String,
// requestUserName: String, requestRepositoryName: String, requestCommitId: String): (Seq[Seq[CommitInfo]], Seq[DiffInfo]) =
// using(
// Git.open(getRepositoryDir(userName, repositoryName)),
// Git.open(getRepositoryDir(requestUserName, requestRepositoryName))
// ){ (oldGit, newGit) =>
// val oldId = oldGit.getRepository.resolve(branch)
// val newId = newGit.getRepository.resolve(requestCommitId)
//
// val commits = newGit.log.addRange(oldId, newId).call.iterator.asScala.map { revCommit =>
// new CommitInfo(revCommit)
// }.toList.splitWith { (commit1, commit2) =>
// helpers.date(commit1.commitTime) == view.helpers.date(commit2.commitTime)
// }
//
// val diffs = JGitUtil.getDiffs(newGit, oldId.getName, newId.getName, true)
//
// (commits, diffs)
// }
private def searchPullRequests(userName: Option[String], repository: RepositoryService.RepositoryInfo) =
defining(repository.owner, repository.name){ case (owner, repoName) =>

View File

@@ -42,12 +42,18 @@ trait CommitsService {
updatedDate = currentDate,
issueId = issueId)
def updateCommitCommentPosition(commentId: Int, commitId: String, oldLine: Option[Int], newLine: Option[Int])(implicit s: Session): Unit =
CommitComments.filter(_.byPrimaryKey(commentId))
.map { t =>
(t.commitId, t.oldLine, t.newLine)
}.update(commitId, oldLine, newLine)
def updateCommitComment(commentId: Int, content: String)(implicit s: Session) =
CommitComments
.filter (_.byPrimaryKey(commentId))
.map { t =>
t.content -> t.updatedDate
}.update (content, currentDate)
t.content -> t.updatedDate
}.update (content, currentDate)
def deleteCommitComment(commentId: Int)(implicit s: Session) =
CommitComments filter (_.byPrimaryKey(commentId)) delete

View File

@@ -1,12 +1,22 @@
package gitbucket.core.service
import gitbucket.core.model.{Account, Issue, PullRequest, WebHook, CommitStatus, CommitState}
import difflib.{Delta, DiffUtils}
import gitbucket.core.model.{Session => _, _}
import gitbucket.core.model.Profile._
import gitbucket.core.util.ControlUtil._
import gitbucket.core.util.Directory._
import gitbucket.core.util.Implicits._
import gitbucket.core.util.JGitUtil
import gitbucket.core.util.JGitUtil.{CommitInfo, DiffInfo}
import gitbucket.core.view
import gitbucket.core.view.helpers
import org.eclipse.jgit.api.Git
import profile.simple._
import scala.collection.JavaConverters._
trait PullRequestService { self: IssuesService =>
trait PullRequestService { self: IssuesService with CommitsService =>
import PullRequestService._
def getPullRequest(owner: String, repository: String, issueId: Int)
@@ -111,9 +121,26 @@ trait PullRequestService { self: IssuesService =>
def updatePullRequests(owner: String, repository: String, branch: String)(implicit s: Session): Unit =
getPullRequestsByRequest(owner, repository, branch, false).foreach { pullreq =>
if(Repositories.filter(_.byRepository(pullreq.userName, pullreq.repositoryName)).exists.run){
// Update the git repository
val (commitIdTo, commitIdFrom) = JGitUtil.updatePullRequest(
pullreq.userName, pullreq.repositoryName, pullreq.branch, pullreq.issueId,
pullreq.requestUserName, pullreq.requestRepositoryName, pullreq.requestBranch)
// Update comments position
val comments = getCommitComments(pullreq.userName, pullreq.repositoryName, pullreq.commitIdTo, true)
println(comments)
comments.foreach { comment =>
comment match {
case CommitComment(_, _, _, commitId, _, _, Some(fileName), _, Some(newLine), _, _, _) => {
getNewLineNumber(fileName, newLine, pullreq.requestUserName, pullreq.requestRepositoryName, pullreq.commitIdTo, commitIdTo).foreach { lineNumber =>
updateCommitCommentPosition(commitId, commitIdTo, None, Some(lineNumber))
}
}
case _ => // Do nothing
}
}
// Update commit id in the PULL_REQUEST table
updateCommitId(pullreq.userName, pullreq.repositoryName, pullreq.issueId, commitIdTo, commitIdFrom)
}
}
@@ -137,6 +164,62 @@ trait PullRequestService { self: IssuesService =>
.firstOption
}
}
def getNewLineNumber(file: String, lineNumber: Int, userName: String, repositoryName: String, oldCommitId: String, newCommitId: String): Option[Int] = {
val (_, diffs) = getRequestCompareInfo(userName, repositoryName, oldCommitId, userName, repositoryName, newCommitId)
var counter = lineNumber
diffs.find(x => x.oldPath == "test").foreach { diff =>
(diff.oldContent, diff.newContent) match {
case (Some(oldContent), Some(newContent)) => {
val oldLines = oldContent.replace("\r\n", "\n").split("\n")
val newLines = newContent.replace("\r\n", "\n").split("\n")
val deltas = DiffUtils.diff(oldLines.toList.asJava, newLines.toList.asJava)
deltas.getDeltas.asScala.filter(_.getOriginal.getPosition < lineNumber).foreach { delta =>
delta.getType match {
case Delta.TYPE.CHANGE =>
if(delta.getOriginal.getPosition <= lineNumber - 1 && lineNumber <= delta.getOriginal.getPosition + delta.getRevised.getLines.size){
counter = -1
} else {
counter = counter + (delta.getRevised.getLines.size - delta.getOriginal.getLines.size)
}
case Delta.TYPE.INSERT =>
counter = counter + delta.getRevised.getLines.size
case Delta.TYPE.DELETE =>
counter = counter - delta.getOriginal.getLines.size
}
}
counter
}
case _ => counter = -1
}
}
if(counter >= 0) Some(counter) else None
}
def getRequestCompareInfo(userName: String, repositoryName: String, branch: String,
requestUserName: String, requestRepositoryName: String, requestCommitId: String): (Seq[Seq[CommitInfo]], Seq[DiffInfo]) =
using(
Git.open(getRepositoryDir(userName, repositoryName)),
Git.open(getRepositoryDir(requestUserName, requestRepositoryName))
){ (oldGit, newGit) =>
val oldId = oldGit.getRepository.resolve(branch)
val newId = newGit.getRepository.resolve(requestCommitId)
val commits = newGit.log.addRange(oldId, newId).call.iterator.asScala.map { revCommit =>
new CommitInfo(revCommit)
}.toList.splitWith { (commit1, commit2) =>
helpers.date(commit1.commitTime) == view.helpers.date(commit2.commitTime)
}
val diffs = JGitUtil.getDiffs(newGit, oldId.getName, newId.getName, true)
(commits, diffs)
}
}
object PullRequestService {

View File

@@ -110,7 +110,7 @@ import scala.collection.JavaConverters._
class CommitLogHook(owner: String, repository: String, pusher: String, baseUrl: String)(implicit session: Session)
extends PostReceiveHook with PreReceiveHook
with RepositoryService with AccountService with IssuesService with ActivityService with PullRequestService with WebHookService
with WebHookPullRequestService {
with WebHookPullRequestService with CommitsService {
private val logger = LoggerFactory.getLogger(classOf[CommitLogHook])
private var existIds: Seq[String] = Nil

View File

@@ -240,7 +240,6 @@ $(function(){
var oldline = $v.attr('oldline');
var newline = $v.attr('newline');
var tmp;
var diff;
if (typeof oldline !== 'undefined') {
if (typeof newline !== 'undefined') {
tmp = getInlineContainer();
@@ -248,13 +247,11 @@ $(function(){
tmp = getInlineContainer('old');
}
tmp.children('td:first').html($v.clone().show());
diff.find('table.diff').find('.oldline[line-number=' + oldline + ']')
.parent().nextAll(':not(.not-diff):first').before(tmp);
diff.find('table.diff').find('.oldline[line-number=' + oldline + ']').parent().nextAll(':not(.not-diff):first').before(tmp);
} else {
tmp = getInlineContainer('new');
tmp.children('td:last').html($v.clone().show());
diff.find('table.diff').find('.newline[line-number=' + newline + ']')
.parent().nextAll(':not(.not-diff):first').before(tmp);
diff.find('table.diff').find('.newline[line-number=' + newline + ']').parent().nextAll(':not(.not-diff):first').before(tmp);
}
if (!diff.find('.toggle-notes').prop('checked')) {
tmp.hide();
@@ -263,10 +260,10 @@ $(function(){
function renderStatBar(add, del){
if(add + del > 5){
if(add){
if(add<del){
add = Math.floor(1 + (add * 4 / (add+del)));
if(add < del){
add = Math.floor(1 + (add * 4 / (add + del)));
} else {
add = Math.ceil(1 + (add * 4 / (add+del)));
add = Math.ceil(1 + (add * 4 / (add + del)));
}
}
del = 5 - add;
@@ -290,10 +287,12 @@ $(function(){
var i = table.data("diff-id");
var ignoreWhiteSpace = table.find('.ignore-whitespace').prop('checked');
diffUsingJS('oldText-'+i, 'newText-'+i, diffText.attr('id'), viewType, ignoreWhiteSpace);
var add = diffText.find("table").attr("add")*1;
var del = diffText.find("table").attr("del")*1;
var add = diffText.find("table").attr("add") * 1;
var del = diffText.find("table").attr("del") * 1;
table.find(".diffstat").text(add+del+" ").append(renderStatBar(add,del)).attr("title",add+" additions & "+del+" deletions").tooltip();
$('span.diffstat[data-diff-id="'+i+'"]').html('<span class="text-diff-added">+'+add+'</span><span class="text-diff-deleted">-'+del+'</span>').append(renderStatBar(add,del).attr('title',(add+del)+" lines changed").tooltip());
$('span.diffstat[data-diff-id="'+i+'"]')
.html('<span class="text-diff-added">+' + add + '</span><span class="text-diff-deleted">-' + del + '</span>')
.append(renderStatBar(add, del).attr('title', (add + del) + " lines changed").tooltip());
@if(hasWritePermission) {
diffText.find('.body').each(function(){ $('<b class="add-comment">+</b>').prependTo(this); });
@@ -301,7 +300,7 @@ $(function(){
@if(showLineNotes){
var fileName = table.attr('filename');
$('.inline-comment').each(function(i, v) {
if($(this).attr('filename')==fileName){
if($(this).attr('filename') == fileName){
renderOneCommitCommentIntoDiff($(this), table);
}
});