Add commit hook extension point for plugins

This commit is contained in:
Naoki Takezoe
2016-01-17 01:38:11 +09:00
parent 58078989f8
commit b599219852
9 changed files with 55 additions and 29 deletions

View File

@@ -1,6 +1,6 @@
package gitbucket.core.api
import gitbucket.core.service.ProtectedBrancheService
import gitbucket.core.service.ProtectedBranchService
import org.json4s._
/** https://developer.github.com/v3/repos/#enabling-and-disabling-branch-protection */
@@ -12,7 +12,7 @@ object ApiBranchProtection{
/** form for enabling-and-disabling-branch-protection */
case class EnablingAndDisabling(protection: ApiBranchProtection)
def apply(info: ProtectedBrancheService.ProtectedBranchInfo): ApiBranchProtection = ApiBranchProtection(
def apply(info: ProtectedBranchService.ProtectedBranchInfo): ApiBranchProtection = ApiBranchProtection(
enabled = info.enabled,
required_status_checks = Some(Status(EnforcementLevel(info.enabled, info.includeAdministrators), info.contexts)))
val statusNone = Status(Off, Seq.empty)

View File

@@ -27,13 +27,13 @@ import scala.collection.JavaConverters._
class PullRequestsController extends PullRequestsControllerBase
with RepositoryService with AccountService with IssuesService with PullRequestService with MilestonesService with LabelsService
with CommitsService with ActivityService with WebHookPullRequestService with ReferrerAuthenticator with CollaboratorsAuthenticator
with CommitStatusService with MergeService with ProtectedBrancheService
with CommitStatusService with MergeService with ProtectedBranchService
trait PullRequestsControllerBase extends ControllerBase {
self: RepositoryService with AccountService with IssuesService with MilestonesService with LabelsService
with CommitsService with ActivityService with PullRequestService with WebHookPullRequestService with ReferrerAuthenticator with CollaboratorsAuthenticator
with CommitStatusService with MergeService with ProtectedBrancheService =>
with CommitStatusService with MergeService with ProtectedBranchService =>
private val logger = LoggerFactory.getLogger(classOf[PullRequestsControllerBase])

View File

@@ -2,7 +2,7 @@ package gitbucket.core.controller
import gitbucket.core.settings.html
import gitbucket.core.model.WebHook
import gitbucket.core.service.{RepositoryService, AccountService, WebHookService, ProtectedBrancheService, CommitStatusService}
import gitbucket.core.service.{RepositoryService, AccountService, WebHookService, ProtectedBranchService, CommitStatusService}
import gitbucket.core.service.WebHookService._
import gitbucket.core.util._
import gitbucket.core.util.JGitUtil._
@@ -18,11 +18,11 @@ import org.eclipse.jgit.lib.ObjectId
class RepositorySettingsController extends RepositorySettingsControllerBase
with RepositoryService with AccountService with WebHookService with ProtectedBrancheService with CommitStatusService
with RepositoryService with AccountService with WebHookService with ProtectedBranchService with CommitStatusService
with OwnerAuthenticator with UsersAuthenticator
trait RepositorySettingsControllerBase extends ControllerBase {
self: RepositoryService with AccountService with WebHookService with ProtectedBrancheService with CommitStatusService
self: RepositoryService with AccountService with WebHookService with ProtectedBranchService with CommitStatusService
with OwnerAuthenticator with UsersAuthenticator =>
// for repository options

View File

@@ -33,7 +33,7 @@ import org.scalatra._
class RepositoryViewerController extends RepositoryViewerControllerBase
with RepositoryService with AccountService with ActivityService with IssuesService with WebHookService with CommitsService
with ReadableUsersAuthenticator with ReferrerAuthenticator with CollaboratorsAuthenticator with PullRequestService with CommitStatusService
with WebHookPullRequestService with WebHookPullRequestReviewCommentService with ProtectedBrancheService
with WebHookPullRequestService with WebHookPullRequestReviewCommentService with ProtectedBranchService
/**
* The repository viewer.
@@ -41,7 +41,7 @@ class RepositoryViewerController extends RepositoryViewerControllerBase
trait RepositoryViewerControllerBase extends ControllerBase {
self: RepositoryService with AccountService with ActivityService with IssuesService with WebHookService with CommitsService
with ReadableUsersAuthenticator with ReferrerAuthenticator with CollaboratorsAuthenticator with PullRequestService with CommitStatusService
with WebHookPullRequestService with WebHookPullRequestReviewCommentService with ProtectedBrancheService =>
with WebHookPullRequestService with WebHookPullRequestReviewCommentService with ProtectedBranchService =>
ArchiveCommand.registerFormat("zip", new ZipFormat)
ArchiveCommand.registerFormat("tar.gz", new TgzFormat)

View File

@@ -0,0 +1,12 @@
package gitbucket.core.plugin
import gitbucket.core.model.Profile._
import org.eclipse.jgit.transport.ReceiveCommand
import profile.simple._
trait CommitHook {
def hook(owner: String, repository: String, isAllowNonFastForwards: Boolean, command: ReceiveCommand, pusher: String)
(implicit session: Session): Option[String]
}

View File

@@ -6,6 +6,7 @@ import javax.servlet.ServletContext
import javax.servlet.http.{HttpServletRequest, HttpServletResponse}
import gitbucket.core.controller.{Context, ControllerBase}
import gitbucket.core.service.ProtectedBranchService.ProtectedBranchCommitHook
import gitbucket.core.service.RepositoryService.RepositoryInfo
import gitbucket.core.service.SystemSettingsService.SystemSettings
import gitbucket.core.util.ControlUtil._
@@ -29,6 +30,8 @@ class PluginRegistry {
"md" -> MarkdownRenderer, "markdown" -> MarkdownRenderer
)
private val repositoryRoutings = new ListBuffer[GitRepositoryRouting]
private val commitHooks = new ListBuffer[CommitHook]
commitHooks += new ProtectedBranchCommitHook()
def addPlugin(pluginInfo: PluginInfo): Unit = {
plugins += pluginInfo
@@ -98,6 +101,12 @@ class PluginRegistry {
}
}
def addCommitHook(commitHook: CommitHook): Unit = {
commitHooks += commitHook
}
def getCommitHooks: Seq[CommitHook] = commitHooks.toSeq
private case class GlobalAction(
method: String,
path: String,

View File

@@ -1,17 +1,15 @@
package gitbucket.core.service
import gitbucket.core.model.{Collaborator, Repository, Account, CommitState, CommitStatus, ProtectedBranch, ProtectedBranchContext}
import gitbucket.core.model._
import gitbucket.core.model.Profile._
import gitbucket.core.util.JGitUtil
import gitbucket.core.plugin.CommitHook
import profile.simple._
import org.eclipse.jgit.transport.ReceiveCommand
import org.eclipse.jgit.transport.ReceivePack
import org.eclipse.jgit.lib.ObjectId
trait ProtectedBrancheService {
import ProtectedBrancheService._
trait ProtectedBranchService {
import ProtectedBranchService._
private def getProtectedBranchInfoOpt(owner: String, repository: String, branch: String)(implicit session: Session): Option[ProtectedBranchInfo] =
ProtectedBranches
.leftJoin(ProtectedBranchContexts)
@@ -43,17 +41,23 @@ trait ProtectedBrancheService {
def disableBranchProtection(owner: String, repository: String, branch:String)(implicit session: Session): Unit =
ProtectedBranches.filter(_.byPrimaryKey(owner, repository, branch)).delete
def getBranchProtectedReason(owner: String, repository: String, isAllowNonFastForwards: Boolean, command: ReceiveCommand, pusher: String)
(implicit session: Session): Option[String] = {
val branch = command.getRefName.stripPrefix("refs/heads/")
if(branch != command.getRefName){
getProtectedBranchInfo(owner, repository, branch).getStopReason(isAllowNonFastForwards, command, pusher)
} else {
None
}
object ProtectedBranchService {
class ProtectedBranchCommitHook extends CommitHook with ProtectedBranchService {
override def hook(owner: String, repository: String, isAllowNonFastForwards: Boolean, command: ReceiveCommand, pusher: String)
(implicit session: Session): Option[String] = {
val branch = command.getRefName.stripPrefix("refs/heads/")
if(branch != command.getRefName){
getProtectedBranchInfo(owner, repository, branch).getStopReason(isAllowNonFastForwards, command, pusher)
} else {
None
}
}
}
}
object ProtectedBrancheService {
case class ProtectedBranchInfo(
owner: String,
repository: String,

View File

@@ -148,7 +148,7 @@ object PullRequestService {
case class MergeStatus(
hasConflict: Boolean,
commitStatues:List[CommitStatus],
branchProtection: ProtectedBrancheService.ProtectedBranchInfo,
branchProtection: ProtectedBranchService.ProtectedBranchInfo,
branchIsOutOfDate: Boolean,
hasUpdatePermission: Boolean,
needStatusCheck: Boolean,

View File

@@ -111,7 +111,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 ProtectedBrancheService {
with WebHookPullRequestService with ProtectedBranchService {
private val logger = LoggerFactory.getLogger(classOf[CommitLogHook])
private var existIds: Seq[String] = Nil
@@ -119,9 +119,10 @@ class CommitLogHook(owner: String, repository: String, pusher: String, baseUrl:
def onPreReceive(receivePack: ReceivePack, commands: java.util.Collection[ReceiveCommand]): Unit = {
try {
commands.asScala.foreach { command =>
getBranchProtectedReason(owner, repository, receivePack.isAllowNonFastForwards, command, pusher).map { reason =>
command.setResult(ReceiveCommand.Result.REJECTED_OTHER_REASON, reason)
PluginRegistry().getCommitHooks
.flatMap(_.hook(owner, repository, receivePack.isAllowNonFastForwards, command, pusher))
.headOption.foreach { error =>
command.setResult(ReceiveCommand.Result.REJECTED_OTHER_REASON, error)
}
}
using(Git.open(Directory.getRepositoryDir(owner, repository))) { git =>