Merge remote-tracking branch 'origin/master' into api-support

Conflicts:
	src/main/scala/ScalatraBootstrap.scala
	src/main/scala/gitbucket/core/controller/AccountController.scala
	src/main/scala/gitbucket/core/controller/ControllerBase.scala
	src/main/scala/gitbucket/core/controller/IssuesController.scala
	src/main/scala/gitbucket/core/controller/PullRequestsController.scala
	src/main/scala/gitbucket/core/controller/RepositorySettingsController.scala
	src/main/scala/gitbucket/core/controller/RepositoryViewerController.scala
	src/main/scala/gitbucket/core/model/Profile.scala
	src/main/scala/gitbucket/core/service/PullRequestService.scala
	src/main/scala/gitbucket/core/service/WebHookService.scala
	src/main/scala/gitbucket/core/servlet/InitializeListener.scala
	src/main/scala/gitbucket/core/view/helpers.scala
	src/main/twirl/gitbucket/core/pulls/conversation.scala.html
	src/main/twirl/gitbucket/core/pulls/mergeguide.scala.html
	src/main/twirl/issues/listparts.scala.html
This commit is contained in:
Tomofumi Tanaka
2015-03-16 22:49:47 +09:00
215 changed files with 1127 additions and 916 deletions

View File

@@ -79,6 +79,12 @@ Run the following commands in `Terminal` to
Release Notes
--------
### 3.0 - 3 Mar 2015
- New plug-in system is available
- Connection pooling by c3p0
- New branch UI
- Compare between specified commit ids
### 2.8 - 1 Feb 2015
- New logo and icons
- New system setting options to control visibility

View File

@@ -5,7 +5,7 @@
<property name="embed.classes.dir" value="${target.dir}/embed-classes"/>
<property name="jetty.dir" value="embed-jetty"/>
<property name="scala.version" value="2.11"/>
<property name="gitbucket.version" value="0.0.1"/>
<property name="gitbucket.version" value="3.0.0"/>
<property name="jetty.version" value="8.1.8.v20121106"/>
<property name="servlet.version" value="3.0.0.v201112011016"/>

8
etc/deploy-assemby-jar.sh Normal file → Executable file
View File

@@ -1,9 +1,9 @@
#!/bin/sh
mvn deploy:deploy-file \
-DgroupId=jp.sf.amateras\
-DgroupId=gitbucket\
-DartifactId=gitbucket-assembly\
-Dversion=0.0.1\
-Dversion=3.0.0\
-Dpackaging=jar\
-Dfile=../target/scala-2.11/gitbucket-assembly-0.0.1.jar\
-Dfile=../target/scala-2.11/gitbucket-assembly-3.0.0.jar\
-DrepositoryId=sourceforge.jp\
-Durl=scp://shell.sourceforge.jp/home/groups/a/am/amateras/htdocs/mvn/
-Durl=scp://shell.sourceforge.jp/home/groups/a/am/amateras/htdocs/mvn/

View File

@@ -8,9 +8,9 @@ import sbtassembly._
import sbtassembly.AssemblyKeys._
object MyBuild extends Build {
val Organization = "jp.sf.amateras"
val Organization = "gitbucket"
val Name = "gitbucket"
val Version = "0.0.1"
val Version = "3.0.0"
val ScalaVersion = "2.11.2"
val ScalatraVersion = "2.3.0"
@@ -66,6 +66,7 @@ object MyBuild extends Build {
"com.typesafe" % "config" % "1.2.1",
"com.typesafe.play" %% "twirl-compiler" % "1.0.2"
),
play.twirl.sbt.Import.TwirlKeys.templateImports += "gitbucket.core._",
EclipseKeys.withSource := true,
javacOptions in compile ++= Seq("-target", "7", "-source", "7"),
testOptions in Test += Tests.Argument(TestFrameworks.Specs2, "junitxml", "console"),

View File

@@ -1,4 +1,4 @@
package util;
package gitbucket.core.util;
import org.eclipse.jgit.api.errors.PatchApplyException;
import org.eclipse.jgit.diff.RawText;

View File

@@ -1,11 +1,14 @@
import _root_.servlet.{BasicAuthenticationFilter, TransactionFilter, AccessTokenAuthenticationFilter}
import app._
import plugin.PluginRegistry
//import jp.sf.amateras.scalatra.forms.ValidationJavaScriptProvider
import org.scalatra._
import javax.servlet._
import gitbucket.core.controller._
import gitbucket.core.plugin.PluginRegistry
import gitbucket.core.servlet.{AccessTokenAuthenticationFilter, BasicAuthenticationFilter, TransactionFilter}
import gitbucket.core.util.Directory
import java.util.EnumSet
import javax.servlet._
import org.scalatra._
class ScalatraBootstrap extends LifeCycle {
override def init(context: ServletContext) {
@@ -39,9 +42,9 @@ class ScalatraBootstrap extends LifeCycle {
context.mount(new RepositorySettingsController, "/*")
// Create GITBUCKET_HOME directory if it does not exist
val dir = new java.io.File(_root_.util.Directory.GitBucketHome)
val dir = new java.io.File(Directory.GitBucketHome)
if(!dir.exists){
dir.mkdirs()
}
}
}
}

View File

@@ -1,8 +1,7 @@
package api
import model.Account
import model.CommitStatus
import model.CommitState
import gitbucket.core.model.{Account, CommitState, CommitStatus}
/**
* https://developer.github.com/v3/repos/statuses/#get-the-combined-status-for-a-specific-ref

View File

@@ -1,7 +1,7 @@
package api
import java.util.Date
import model.IssueComment
import gitbucket.core.model.IssueComment
/**
* https://developer.github.com/v3/issues/comments/

View File

@@ -2,10 +2,10 @@ package api
import java.util.Date
import org.eclipse.jgit.diff.DiffEntry
import util.JGitUtil
import util.JGitUtil.CommitInfo
import gitbucket.core.util.JGitUtil
import gitbucket.core.util.JGitUtil.CommitInfo
import gitbucket.core.util.RepositoryName
import org.eclipse.jgit.api.Git
import util.RepositoryName
/**
* https://developer.github.com/v3/repos/commits/

View File

@@ -1,8 +1,9 @@
package api
import util.JGitUtil.CommitInfo
import gitbucket.core.util.JGitUtil.CommitInfo
// TODO(tanacasino): Fix package name
import gitbucket.core.util.RepositoryName
import ApiCommitListItem._
import util.RepositoryName
/**
* https://developer.github.com/v3/repos/commits/

View File

@@ -1,8 +1,8 @@
package api
import java.util.Date
import model.CommitStatus
import util.RepositoryName
import gitbucket.core.model.CommitStatus
import gitbucket.core.util.RepositoryName
/**
* https://developer.github.com/v3/repos/statuses/#create-a-status

View File

@@ -1,7 +1,7 @@
package api
import java.util.Date
import model.Issue
import gitbucket.core.model.Issue
/**
* https://developer.github.com/v3/issues/

View File

@@ -1,7 +1,7 @@
package api
import java.util.Date
import util.JGitUtil.CommitInfo
import gitbucket.core.util.JGitUtil.CommitInfo
case class ApiPersonIdent(
name: String,

View File

@@ -1,8 +1,7 @@
package api
import java.util.Date
import model.{Issue, PullRequest}
import ApiPullRequest._
import gitbucket.core.model.{Issue, PullRequest}
/**
* https://developer.github.com/v3/pulls/

View File

@@ -1,8 +1,8 @@
package api
import util.JGitUtil.CommitInfo
import service.RepositoryService.RepositoryInfo
import model.{Account, Repository}
import gitbucket.core.util.JGitUtil.CommitInfo
import gitbucket.core.service.RepositoryService.RepositoryInfo
import gitbucket.core.model.{Account, Repository}
// https://developer.github.com/v3/repos/
case class ApiRepository(

View File

@@ -1,7 +1,7 @@
package api
import java.util.Date
import model.Account
import gitbucket.core.model.Account
case class ApiUser(
login: String,

View File

@@ -1,6 +1,6 @@
package api
import model.CommitState
import gitbucket.core.model.CommitState
/**
* https://developer.github.com/v3/repos/statuses/#create-a-status

View File

@@ -1,4 +1,5 @@
package api
import org.json4s._
import org.json4s.jackson.Serialization
import scala.util.Try
@@ -6,6 +7,8 @@ import org.joda.time.format._
import org.joda.time.DateTime
import org.joda.time.DateTimeZone
import java.util.Date
object JsonFormat {
case class Context(baseUrl:String)
val parserISO = DateTimeFormat.forPattern("yyyy-MM-dd'T'HH:mm:ss'Z'")

View File

@@ -1,22 +1,28 @@
package app
package gitbucket.core.controller
import service._
import util._
import util.StringUtil._
import util.Directory._
import util.ControlUtil._
import util.Implicits._
import ssh.SshUtil
import gitbucket.core.account.html
import gitbucket.core.helper
import gitbucket.core.model.GroupMember
import gitbucket.core.util._
import gitbucket.core.util.Implicits._
import gitbucket.core.util.Directory._
import gitbucket.core.util.ControlUtil._
import gitbucket.core.util.StringUtil._
import gitbucket.core.ssh.SshUtil
import gitbucket.core.service._
import gitbucket.core.service.WebHookService._
import jp.sf.amateras.scalatra.forms._
import org.apache.commons.io.FileUtils
import org.scalatra.i18n.Messages
import org.eclipse.jgit.api.Git
import org.eclipse.jgit.lib.{FileMode, Constants}
import org.eclipse.jgit.dircache.DirCache
import model.GroupMember
import service.WebHookService._
// TODO(tanacasino): Fix package name
import api._
class AccountController extends AccountControllerBase
with AccountService with RepositoryService with ActivityService with WikiService with LabelsService with SshKeyService
with OneselfAuthenticator with UsersAuthenticator with GroupManagerAuthenticator with ReadableUsersAuthenticator
@@ -113,21 +119,21 @@ trait AccountControllerBase extends AccountManagementControllerBase {
params.getOrElse("tab", "repositories") match {
// Public Activity
case "activity" =>
_root_.account.html.activity(account,
gitbucket.core.account.html.activity(account,
if(account.isGroupAccount) Nil else getGroupsByUserName(userName),
getActivitiesByUser(userName, true))
// Members
case "members" if(account.isGroupAccount) => {
val members = getGroupMembers(account.userName)
_root_.account.html.members(account, members.map(_.userName),
gitbucket.core.account.html.members(account, members.map(_.userName),
context.loginAccount.exists(x => members.exists { member => member.userName == x.userName && member.isManager }))
}
// Repositories
case _ => {
val members = getGroupMembers(account.userName)
_root_.account.html.repositories(account,
gitbucket.core.account.html.repositories(account,
if(account.isGroupAccount) Nil else getGroupsByUserName(userName),
getVisibleRepositories(context.loginAccount, context.baseUrl, Some(userName)),
context.loginAccount.exists(x => members.exists { member => member.userName == x.userName && member.isManager }))
@@ -174,7 +180,7 @@ trait AccountControllerBase extends AccountManagementControllerBase {
get("/:userName/_edit")(oneselfOnly {
val userName = params("userName")
getAccountByUserName(userName).map { x =>
account.html.edit(x, flash.get("info"))
html.edit(x, flash.get("info"))
} getOrElse NotFound
})
@@ -218,7 +224,7 @@ trait AccountControllerBase extends AccountManagementControllerBase {
get("/:userName/_ssh")(oneselfOnly {
val userName = params("userName")
getAccountByUserName(userName).map { x =>
account.html.ssh(x, getPublicKeys(x.userName))
html.ssh(x, getPublicKeys(x.userName))
} getOrElse NotFound
})
@@ -249,7 +255,7 @@ trait AccountControllerBase extends AccountManagementControllerBase {
}
case _ => None
}
account.html.application(x, tokens, generatedToken)
html.application(x, tokens, generatedToken)
} getOrElse NotFound
})
@@ -274,7 +280,7 @@ trait AccountControllerBase extends AccountManagementControllerBase {
if(context.loginAccount.isDefined){
redirect("/")
} else {
account.html.register()
html.register()
}
} else NotFound
}
@@ -288,7 +294,7 @@ trait AccountControllerBase extends AccountManagementControllerBase {
}
get("/groups/new")(usersOnly {
account.html.group(None, List(GroupMember("", context.loginAccount.get.userName, true)))
html.group(None, List(GroupMember("", context.loginAccount.get.userName, true)))
})
post("/groups/new", newGroupForm)(usersOnly { form =>
@@ -304,7 +310,7 @@ trait AccountControllerBase extends AccountManagementControllerBase {
get("/:groupName/_editgroup")(managersOnly {
defining(params("groupName")){ groupName =>
account.html.group(getAccountByUserName(groupName, true), getGroupMembers(groupName))
html.group(getAccountByUserName(groupName, true), getGroupMembers(groupName))
}
})
@@ -353,7 +359,7 @@ trait AccountControllerBase extends AccountManagementControllerBase {
* Show the new repository form.
*/
get("/new")(usersOnly {
account.html.newrepo(getGroupsByUserName(context.loginAccount.get.userName), context.settings.isCreateRepoOptionPublic)
html.newrepo(getGroupsByUserName(context.loginAccount.get.userName), context.settings.isCreateRepoOptionPublic)
})
/**
@@ -429,7 +435,7 @@ trait AccountControllerBase extends AccountManagementControllerBase {
val members = getGroupMembers(group)
context.loginAccount.exists(x => members.exists { member => member.userName == x.userName && member.isManager })
}
_root_.helper.html.forkrepository(
helper.html.forkrepository(
repository,
(groups zip managerPermissions).toMap
)

View File

@@ -1,4 +1,4 @@
package app
package gitbucket.core.controller
class AnonymousAccessController extends AnonymousAccessControllerBase

View File

@@ -1,20 +1,25 @@
package app
package gitbucket.core.controller
import gitbucket.core.model.Account
import gitbucket.core.service.{AccountService, SystemSettingsService}
import gitbucket.core.util.ControlUtil._
import gitbucket.core.util.Directory._
import gitbucket.core.util.Implicits._
import gitbucket.core.util._
import _root_.util.Directory._
import _root_.util.Implicits._
import _root_.util.ControlUtil._
import _root_.util.{StringUtil, FileUtil, Validations, Keys}
import org.scalatra._
import org.scalatra.json._
import org.json4s._
import jp.sf.amateras.scalatra.forms._
import org.apache.commons.io.FileUtils
import model._
import service.{SystemSettingsService, AccountService, AccessTokenService}
import org.json4s._
import org.scalatra._
import org.scalatra.i18n._
import org.scalatra.json._
import javax.servlet.http.{HttpServletResponse, HttpServletRequest}
import javax.servlet.{FilterChain, ServletResponse, ServletRequest}
import org.scalatra.i18n._
import scala.util.Try
/**
* Provides generic features for controller implementations.
*/
@@ -110,10 +115,10 @@ abstract class ControllerBase extends ScalatraFilter
contentType = formats("json")
org.scalatra.NotFound(api.ApiError("Not Found"))
} else {
org.scalatra.NotFound(html.error("Not Found"))
org.scalatra.NotFound(gitbucket.core.html.error("Not Found"))
}
protected def Unauthorized()(implicit context: app.Context) =
protected def Unauthorized()(implicit context: Context) =
if(request.hasAttribute(Keys.Request.Ajax)){
org.scalatra.Unauthorized()
} else if(request.hasAttribute(Keys.Request.APIv3)){

View File

@@ -1,9 +1,10 @@
package app
package gitbucket.core.controller
import service._
import util.{StringUtil, UsersAuthenticator, Keys}
import util.Implicits._
import service.IssuesService.IssueSearchCondition
import gitbucket.core.dashboard.html
import gitbucket.core.service.{RepositoryService, PullRequestService, AccountService, IssuesService}
import gitbucket.core.util.{StringUtil, Keys, UsersAuthenticator}
import gitbucket.core.util.Implicits._
import gitbucket.core.service.IssuesService._
class DashboardController extends DashboardControllerBase
with IssuesService with PullRequestService with RepositoryService with AccountService
@@ -96,7 +97,7 @@ trait DashboardControllerBase extends ControllerBase {
val userRepos = getUserRepositories(userName, context.baseUrl, true).map(repo => repo.owner -> repo.name)
val page = IssueSearchCondition.page(request)
dashboard.html.issues(
html.issues(
searchIssue(condition, false, (page - 1) * IssueLimit, IssueLimit, userRepos: _*),
page,
countIssue(condition.copy(state = "open" ), false, userRepos: _*),
@@ -119,7 +120,7 @@ trait DashboardControllerBase extends ControllerBase {
val allRepos = getAllRepositories(userName)
val page = IssueSearchCondition.page(request)
dashboard.html.pulls(
html.pulls(
searchIssue(condition, true, (page - 1) * PullRequestLimit, PullRequestLimit, allRepos: _*),
page,
countIssue(condition.copy(state = "open" ), true, allRepos: _*),

View File

@@ -1,8 +1,8 @@
package app
package gitbucket.core.controller
import util.{Keys, FileUtil}
import util.ControlUtil._
import util.Directory._
import gitbucket.core.util.{Keys, FileUtil}
import gitbucket.core.util.ControlUtil._
import gitbucket.core.util.Directory._
import org.scalatra._
import org.scalatra.servlet.{MultipartConfig, FileUploadSupport, FileItem}
import org.apache.commons.io.FileUtils

View File

@@ -1,8 +1,11 @@
package app
package gitbucket.core.controller
import util._
import util.Implicits._
import service._
import gitbucket.core.html
import gitbucket.core.helper.xml
import gitbucket.core.model.Account
import gitbucket.core.service.{RepositoryService, ActivityService, AccountService}
import gitbucket.core.util.{LDAPUtil, Keys, UsersAuthenticator}
import gitbucket.core.util.Implicits._
import jp.sf.amateras.scalatra.forms._
import api._
@@ -62,13 +65,13 @@ trait IndexControllerBase extends ControllerBase {
get("/activities.atom"){
contentType = "application/atom+xml; type=feed"
helper.xml.feed(getRecentActivities())
xml.feed(getRecentActivities())
}
/**
* Set account information into HttpSession and redirect.
*/
private def signin(account: model.Account) = {
private def signin(account: Account) = {
session.setAttribute(Keys.Session.LoginAccount, account)
updateLastLoginDate(account.userName)

View File

@@ -1,18 +1,25 @@
package app
package gitbucket.core.controller
import gitbucket.core.issues.html
import gitbucket.core.model.Issue
import gitbucket.core.service._
import gitbucket.core.service.WebHookService._
import gitbucket.core.util._
import gitbucket.core.util.ControlUtil._
import gitbucket.core.util.Implicits._
import gitbucket.core.view
import gitbucket.core.view.Markdown
import jp.sf.amateras.scalatra.forms._
import service._
import IssuesService._
import util._
import util.Implicits._
import util.ControlUtil._
import org.scalatra.Ok
import model.Issue
import service.WebHookService._
import scala.util.Try
// TODO(tanacasino): Fix package name
import api._
class IssuesController extends IssuesControllerBase
with IssuesService with RepositoryService with AccountService with LabelsService with MilestonesService with ActivityService
with ReadableUsersAuthenticator with ReferrerAuthenticator with CollaboratorsAuthenticator with PullRequestService with WebHookIssueCommentService
@@ -63,7 +70,7 @@ trait IssuesControllerBase extends ControllerBase {
get("/:owner/:repository/issues/:id")(referrersOnly { repository =>
defining(repository.owner, repository.name, params("id")){ case (owner, name, issueId) =>
getIssue(owner, name, issueId) map {
issues.html.issue(
html.issue(
_,
getComments(owner, name, issueId.toInt),
getIssueLabels(owner, name, issueId.toInt),
@@ -90,7 +97,7 @@ trait IssuesControllerBase extends ControllerBase {
get("/:owner/:repository/issues/new")(readableUsersOnly { repository =>
defining(repository.owner, repository.name){ case (owner, name) =>
issues.html.create(
html.create(
(getCollaborators(owner, name) ::: (if(getAccountByUserName(owner).get.isGroupAccount) Nil else List(owner))).sorted,
getMilestones(owner, name),
getLabels(owner, name),
@@ -224,13 +231,13 @@ trait IssuesControllerBase extends ControllerBase {
getIssue(repository.owner, repository.name, params("id")) map { x =>
if(isEditable(x.userName, x.repositoryName, x.openedUserName)){
params.get("dataType") collect {
case t if t == "html" => issues.html.editissue(
case t if t == "html" => html.editissue(
x.content, x.issueId, x.userName, x.repositoryName)
} getOrElse {
contentType = formats("json")
org.json4s.jackson.Serialization.write(
Map("title" -> x.title,
"content" -> view.Markdown.toHtml(x.content getOrElse "No description given.",
"content" -> Markdown.toHtml(x.content getOrElse "No description given.",
repository, false, true, true, isEditable(x.userName, x.repositoryName, x.openedUserName))
))
}
@@ -242,7 +249,7 @@ trait IssuesControllerBase extends ControllerBase {
getComment(repository.owner, repository.name, params("id")) map { x =>
if(isEditable(x.userName, x.repositoryName, x.commentedUserName)){
params.get("dataType") collect {
case t if t == "html" => issues.html.editcomment(
case t if t == "html" => html.editcomment(
x.content, x.commentId, x.userName, x.repositoryName)
} getOrElse {
contentType = formats("json")
@@ -258,14 +265,14 @@ trait IssuesControllerBase extends ControllerBase {
ajaxPost("/:owner/:repository/issues/:id/label/new")(collaboratorsOnly { repository =>
defining(params("id").toInt){ issueId =>
registerIssueLabel(repository.owner, repository.name, issueId, params("labelId").toInt)
issues.html.labellist(getIssueLabels(repository.owner, repository.name, issueId))
html.labellist(getIssueLabels(repository.owner, repository.name, issueId))
}
})
ajaxPost("/:owner/:repository/issues/:id/label/delete")(collaboratorsOnly { repository =>
defining(params("id").toInt){ issueId =>
deleteIssueLabel(repository.owner, repository.name, issueId, params("labelId").toInt)
issues.html.labellist(getIssueLabels(repository.owner, repository.name, issueId))
html.labellist(getIssueLabels(repository.owner, repository.name, issueId))
}
})
@@ -279,7 +286,7 @@ trait IssuesControllerBase extends ControllerBase {
milestoneId("milestoneId").map { milestoneId =>
getMilestonesWithIssueCount(repository.owner, repository.name)
.find(_._1.milestoneId == milestoneId).map { case (_, openCount, closeCount) =>
issues.milestones.html.progress(openCount + closeCount, closeCount)
gitbucket.core.issues.milestones.html.progress(openCount + closeCount, closeCount)
} getOrElse NotFound
} getOrElse Ok()
})
@@ -333,7 +340,7 @@ trait IssuesControllerBase extends ControllerBase {
val assignedUserName = (key: String) => params.get(key) filter (_.trim != "")
val milestoneId: String => Option[Int] = (key: String) => params.get(key).flatMap(_.toIntOpt)
private def isEditable(owner: String, repository: String, author: String)(implicit context: app.Context): Boolean =
private def isEditable(owner: String, repository: String, author: String)(implicit context: Context): Boolean =
hasWritePermission(owner, repository, context.loginAccount) || author == context.loginAccount.get.userName
private def executeBatch(repository: RepositoryService.RepositoryInfo)(execute: Int => Unit) = {
@@ -357,7 +364,7 @@ trait IssuesControllerBase extends ControllerBase {
* @see [[https://github.com/takezoe/gitbucket/wiki/CommentAction]]
*/
private def handleComment(issueId: Int, content: Option[String], repository: RepositoryService.RepositoryInfo)
(getAction: model.Issue => Option[String] =
(getAction: Issue => Option[String] =
p1 => params.get("action").filter(_ => isEditable(p1.userName, p1.repositoryName, p1.openedUserName))) = {
defining(repository.owner, repository.name){ case (owner, name) =>
@@ -450,7 +457,7 @@ trait IssuesControllerBase extends ControllerBase {
} else session.getAs[IssueSearchCondition](sessionKey).getOrElse(IssueSearchCondition())
)
issues.html.list(
html.list(
"issues",
searchIssue(condition, false, (page - 1) * IssueLimit, IssueLimit, owner -> repoName),
page,

View File

@@ -1,9 +1,10 @@
package app
package gitbucket.core.controller
import gitbucket.core.issues.labels.html
import gitbucket.core.service.{RepositoryService, AccountService, IssuesService, LabelsService}
import gitbucket.core.util.{ReferrerAuthenticator, CollaboratorsAuthenticator}
import gitbucket.core.util.Implicits._
import jp.sf.amateras.scalatra.forms._
import service._
import util.{ReferrerAuthenticator, CollaboratorsAuthenticator}
import util.Implicits._
import org.scalatra.i18n.Messages
import org.scalatra.Ok
@@ -23,7 +24,7 @@ trait LabelsControllerBase extends ControllerBase {
)(LabelForm.apply)
get("/:owner/:repository/issues/labels")(referrersOnly { repository =>
issues.labels.html.list(
html.list(
getLabels(repository.owner, repository.name),
countIssueGroupByLabels(repository.owner, repository.name, IssuesService.IssueSearchCondition(), Map.empty),
repository,
@@ -31,12 +32,12 @@ trait LabelsControllerBase extends ControllerBase {
})
ajaxGet("/:owner/:repository/issues/labels/new")(collaboratorsOnly { repository =>
issues.labels.html.edit(None, repository)
html.edit(None, repository)
})
ajaxPost("/:owner/:repository/issues/labels/new", labelForm)(collaboratorsOnly { (form, repository) =>
val labelId = createLabel(repository.owner, repository.name, form.labelName, form.color.substring(1))
issues.labels.html.label(
html.label(
getLabel(repository.owner, repository.name, labelId).get,
// TODO futility
countIssueGroupByLabels(repository.owner, repository.name, IssuesService.IssueSearchCondition(), Map.empty),
@@ -46,13 +47,13 @@ trait LabelsControllerBase extends ControllerBase {
ajaxGet("/:owner/:repository/issues/labels/:labelId/edit")(collaboratorsOnly { repository =>
getLabel(repository.owner, repository.name, params("labelId").toInt).map { label =>
issues.labels.html.edit(Some(label), repository)
html.edit(Some(label), repository)
} getOrElse NotFound()
})
ajaxPost("/:owner/:repository/issues/labels/:labelId/edit", labelForm)(collaboratorsOnly { (form, repository) =>
updateLabel(repository.owner, repository.name, params("labelId").toInt, form.labelName, form.color.substring(1))
issues.labels.html.label(
html.label(
getLabel(repository.owner, repository.name, params("labelId").toInt).get,
// TODO futility
countIssueGroupByLabels(repository.owner, repository.name, IssuesService.IssueSearchCondition(), Map.empty),

View File

@@ -1,11 +1,11 @@
package app
package gitbucket.core.controller
import gitbucket.core.issues.milestones.html
import gitbucket.core.service.{RepositoryService, MilestonesService, AccountService}
import gitbucket.core.util.{ReferrerAuthenticator, CollaboratorsAuthenticator}
import gitbucket.core.util.Implicits._
import jp.sf.amateras.scalatra.forms._
import service._
import util.{CollaboratorsAuthenticator, ReferrerAuthenticator}
import util.Implicits._
class MilestonesController extends MilestonesControllerBase
with MilestonesService with RepositoryService with AccountService
with ReferrerAuthenticator with CollaboratorsAuthenticator
@@ -23,7 +23,7 @@ trait MilestonesControllerBase extends ControllerBase {
)(MilestoneForm.apply)
get("/:owner/:repository/issues/milestones")(referrersOnly { repository =>
issues.milestones.html.list(
html.list(
params.getOrElse("state", "open"),
getMilestonesWithIssueCount(repository.owner, repository.name),
repository,
@@ -31,7 +31,7 @@ trait MilestonesControllerBase extends ControllerBase {
})
get("/:owner/:repository/issues/milestones/new")(collaboratorsOnly {
issues.milestones.html.edit(None, _)
html.edit(None, _)
})
post("/:owner/:repository/issues/milestones/new", milestoneForm)(collaboratorsOnly { (form, repository) =>
@@ -41,7 +41,7 @@ trait MilestonesControllerBase extends ControllerBase {
get("/:owner/:repository/issues/milestones/:milestoneId/edit")(collaboratorsOnly { repository =>
params("milestoneId").toIntOpt.map{ milestoneId =>
issues.milestones.html.edit(getMilestone(repository.owner, repository.name, milestoneId), repository)
html.edit(getMilestone(repository.owner, repository.name, milestoneId), repository)
} getOrElse NotFound
})

View File

@@ -1,26 +1,35 @@
package app
package gitbucket.core.controller
import gitbucket.core.model.{Account, CommitStatus, CommitState, Repository, PullRequest, Issue}
import gitbucket.core.pulls.html
import gitbucket.core.service.CommitStatusService
import gitbucket.core.service.MergeService
import gitbucket.core.service.IssuesService._
import gitbucket.core.service.PullRequestService._
import gitbucket.core.service.WebHookService._
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
import util._
import util.Directory._
import util.Implicits._
import util.ControlUtil._
import service._
import org.eclipse.jgit.api.Git
import jp.sf.amateras.scalatra.forms._
import org.eclipse.jgit.transport.RefSpec
import scala.collection.JavaConverters._
import org.eclipse.jgit.lib.{ObjectId, CommitBuilder, PersonIdent}
import service.IssuesService._
import service.PullRequestService._
import org.slf4j.LoggerFactory
import org.eclipse.jgit.merge.MergeStrategy
import org.eclipse.jgit.api.Git
import org.eclipse.jgit.errors.NoMergeBaseException
import service.WebHookService._
import util.JGitUtil.DiffInfo
import util.JGitUtil.CommitInfo
import model.{PullRequest, Issue, CommitState}
import org.eclipse.jgit.lib.{ObjectId, CommitBuilder, PersonIdent}
import org.eclipse.jgit.merge.MergeStrategy
import org.eclipse.jgit.transport.RefSpec
import org.slf4j.LoggerFactory
import scala.collection.JavaConverters._
// TODO(tanacasino): Fix package name
import api._
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
@@ -79,7 +88,7 @@ trait PullRequestsControllerBase extends ControllerBase {
// TODO: more api spec condition
val condition = IssueSearchCondition(request)
val baseOwner = getAccountByUserName(repository.owner).get
val issues:List[(model.Issue, model.Account, Int, model.PullRequest, model.Repository, model.Account)] = searchPullRequestByApi(condition, (page - 1) * PullRequestLimit, PullRequestLimit, repository.owner -> repository.name)
val issues:List[(Issue, Account, Int, PullRequest, Repository, Account)] = searchPullRequestByApi(condition, (page - 1) * PullRequestLimit, PullRequestLimit, repository.owner -> repository.name)
JsonFormat(issues.map{case (issue, issueUser, commentCount, pullRequest, headRepo, headOwner) =>
ApiPullRequest(
issue,
@@ -97,7 +106,7 @@ trait PullRequestsControllerBase extends ControllerBase {
using(Git.open(getRepositoryDir(owner, name))){ git =>
val (commits, diffs) =
getRequestCompareInfo(owner, name, pullreq.commitIdFrom, owner, name, pullreq.commitIdTo)
pulls.html.pullreq(
html.pullreq(
issue, pullreq,
(commits.flatten.map(commit => getCommitComments(owner, name, commit.id, true)).flatten.toList ::: getComments(owner, name, issueId))
.sortWith((a, b) => a.registeredDate before b.registeredDate),
@@ -147,7 +156,7 @@ trait PullRequestsControllerBase extends ControllerBase {
using(Git.open(getRepositoryDir(owner, name))){ git =>
val oldId = git.getRepository.resolve(pullreq.commitIdFrom)
val newId = git.getRepository.resolve(pullreq.commitIdTo)
val repoFullName = util.RepositoryName(repository)
val repoFullName = RepositoryName(repository)
val commits = git.log.addRange(oldId, newId).call.iterator.asScala.map(c => ApiCommitListItem(new CommitInfo(c), repoFullName)).toList
JsonFormat(commits)
}
@@ -165,7 +174,7 @@ trait PullRequestsControllerBase extends ControllerBase {
checkConflict(owner, name, pullreq.branch, issueId)
}
val hasProblem = hasConfrict || (!statuses.isEmpty && CommitState.combine(statuses.map(_.state).toSet) != CommitState.SUCCESS)
pulls.html.mergeguide(
html.mergeguide(
hasConfrict,
hasProblem,
issue,
@@ -272,8 +281,8 @@ trait PullRequestsControllerBase extends ControllerBase {
get("/:owner/:repository/compare/*...*")(referrersOnly { forkedRepository =>
val Seq(origin, forked) = multiParams("splat")
val (originOwner, tmpOriginBranch) = parseCompareIdentifie(origin, forkedRepository.owner)
val (forkedOwner, tmpForkedBranch) = parseCompareIdentifie(forked, forkedRepository.owner)
val (originOwner, originId) = parseCompareIdentifie(origin, forkedRepository.owner)
val (forkedOwner, forkedId) = parseCompareIdentifie(forked, forkedRepository.owner)
(for(
originRepositoryName <- if(originOwner == forkedOwner){
@@ -289,21 +298,24 @@ trait PullRequestsControllerBase extends ControllerBase {
Git.open(getRepositoryDir(originRepository.owner, originRepository.name)),
Git.open(getRepositoryDir(forkedRepository.owner, forkedRepository.name))
){ case (oldGit, newGit) =>
val originBranch = JGitUtil.getDefaultBranch(oldGit, originRepository, tmpOriginBranch).get._2
val forkedBranch = JGitUtil.getDefaultBranch(newGit, forkedRepository, tmpForkedBranch).get._2
val (oldId, newId) =
if(originRepository.branchList.contains(originId) && forkedRepository.branchList.contains(forkedId)){
// Branch name
val rootId = JGitUtil.getForkedCommitId(oldGit, newGit,
originRepository.owner, originRepository.name, originId,
forkedRepository.owner, forkedRepository.name, forkedId)
val forkedId = JGitUtil.getForkedCommitId(oldGit, newGit,
originRepository.owner, originRepository.name, originBranch,
forkedRepository.owner, forkedRepository.name, forkedBranch)
val oldId = oldGit.getRepository.resolve(forkedId)
val newId = newGit.getRepository.resolve(forkedBranch)
(oldGit.getRepository.resolve(rootId), newGit.getRepository.resolve(forkedId))
} else {
// Commit id
(oldGit.getRepository.resolve(originId), newGit.getRepository.resolve(forkedId))
}
val (commits, diffs) = getRequestCompareInfo(
originRepository.owner, originRepository.name, oldId.getName,
forkedRepository.owner, forkedRepository.name, newId.getName)
pulls.html.compare(
html.compare(
commits,
diffs,
(forkedRepository.repository.originUserName, forkedRepository.repository.originRepositoryName) match {
@@ -311,8 +323,8 @@ trait PullRequestsControllerBase extends ControllerBase {
case _ => (forkedRepository.owner, forkedRepository.name) :: getForkedRepositories(forkedRepository.owner, forkedRepository.name)
},
commits.flatten.map(commit => getCommitComments(forkedRepository.owner, forkedRepository.name, commit.id, false)).flatten.toList,
originBranch,
forkedBranch,
originId,
forkedId,
oldId.getName,
newId.getName,
forkedRepository,
@@ -344,12 +356,11 @@ trait PullRequestsControllerBase extends ControllerBase {
){ case (oldGit, newGit) =>
val originBranch = JGitUtil.getDefaultBranch(oldGit, originRepository, tmpOriginBranch).get._2
val forkedBranch = JGitUtil.getDefaultBranch(newGit, forkedRepository, tmpForkedBranch).get._2
val conflict = LockUtil.lock(s"${originRepository.owner}/${originRepository.name}"){
checkConflict(originRepository.owner, originRepository.name, originBranch,
forkedRepository.owner, forkedRepository.name, forkedBranch)
}
pulls.html.mergecheck(conflict)
html.mergecheck(conflict)
}
}) getOrElse NotFound
})
@@ -421,7 +432,7 @@ trait PullRequestsControllerBase extends ControllerBase {
val commits = newGit.log.addRange(oldId, newId).call.iterator.asScala.map { revCommit =>
new CommitInfo(revCommit)
}.toList.splitWith { (commit1, commit2) =>
view.helpers.date(commit1.commitTime) == view.helpers.date(commit2.commitTime)
helpers.date(commit1.commitTime) == view.helpers.date(commit2.commitTime)
}
val diffs = JGitUtil.getDiffs(newGit, oldId.getName, newId.getName, true)
@@ -440,7 +451,7 @@ trait PullRequestsControllerBase extends ControllerBase {
else session.getAs[IssueSearchCondition](sessionKey).getOrElse(IssueSearchCondition())
)
issues.html.list(
gitbucket.core.issues.html.list(
"pulls",
searchIssue(condition, true, (page - 1) * PullRequestLimit, PullRequestLimit, owner -> repoName),
page,

View File

@@ -1,18 +1,21 @@
package app
package gitbucket.core.controller
import service._
import util.Directory._
import util.Implicits._
import util.{LockUtil, UsersAuthenticator, OwnerAuthenticator}
import gitbucket.core.settings.html
import gitbucket.core.model.WebHook
import gitbucket.core.service.{RepositoryService, AccountService, WebHookService}
import gitbucket.core.service.WebHookService._
import gitbucket.core.util._
import gitbucket.core.util.JGitUtil._
import gitbucket.core.util.ControlUtil._
import gitbucket.core.util.Implicits._
import gitbucket.core.util.Directory._
import jp.sf.amateras.scalatra.forms._
import org.apache.commons.io.FileUtils
import org.scalatra.i18n.Messages
import service.WebHookService.WebHookPushPayload
import util.JGitUtil.CommitInfo
import util.ControlUtil._
import org.eclipse.jgit.api.Git
import org.eclipse.jgit.lib.Constants
class RepositorySettingsController extends RepositorySettingsControllerBase
with RepositoryService with AccountService with WebHookService
with OwnerAuthenticator with UsersAuthenticator
@@ -63,7 +66,7 @@ trait RepositorySettingsControllerBase extends ControllerBase {
* Display the Options page.
*/
get("/:owner/:repository/settings/options")(ownerOnly {
settings.html.options(_, flash.get("info"))
html.options(_, flash.get("info"))
})
/**
@@ -105,7 +108,7 @@ trait RepositorySettingsControllerBase extends ControllerBase {
* Display the Collaborators page.
*/
get("/:owner/:repository/settings/collaborators")(ownerOnly { repository =>
settings.html.collaborators(
html.collaborators(
getCollaborators(repository.owner, repository.name),
getAccountByUserName(repository.owner).get.isGroupAccount,
repository)
@@ -135,7 +138,7 @@ trait RepositorySettingsControllerBase extends ControllerBase {
* Display the web hook page.
*/
get("/:owner/:repository/settings/hooks")(ownerOnly { repository =>
settings.html.hooks(getWebHookURLs(repository.owner, repository.name), flash.get("url"), repository, flash.get("info"))
html.hooks(getWebHookURLs(repository.owner, repository.name), flash.get("url"), repository, flash.get("info"))
})
/**
@@ -167,7 +170,7 @@ trait RepositorySettingsControllerBase extends ControllerBase {
getAccountByUserName(repository.owner).foreach { ownerAccount =>
callWebHook("push",
List(model.WebHook(repository.owner, repository.name, form.url)),
List(WebHook(repository.owner, repository.name, form.url)),
WebHookPushPayload(git, ownerAccount, "refs/heads/" + repository.repository.defaultBranch, repository, commits.toList, ownerAccount)
)
}
@@ -181,7 +184,7 @@ trait RepositorySettingsControllerBase extends ControllerBase {
* Display the danger zone.
*/
get("/:owner/:repository/settings/danger")(ownerOnly {
settings.html.danger(_)
html.danger(_)
})
/**
@@ -271,4 +274,4 @@ trait RepositorySettingsControllerBase extends ControllerBase {
}
}
}
}
}

View File

@@ -1,26 +1,33 @@
package app
package gitbucket.core.controller
import _root_.util.JGitUtil.CommitInfo
import util.Directory._
import util.Implicits._
import _root_.util.ControlUtil._
import _root_.util._
import service._
import org.scalatra._
import java.io.File
import gitbucket.core.repo.html
import gitbucket.core.helper
import gitbucket.core.service._
import gitbucket.core.util._
import gitbucket.core.util.JGitUtil._
import gitbucket.core.util.ControlUtil._
import gitbucket.core.util.Implicits._
import gitbucket.core.util.Directory._
import gitbucket.core.model.{Account, CommitState}
import gitbucket.core.service.CommitStatusService
import gitbucket.core.service.WebHookService._
import gitbucket.core.view
import gitbucket.core.view.helpers
import jp.sf.amateras.scalatra.forms._
import org.apache.commons.io.FileUtils
import org.eclipse.jgit.api.{ArchiveCommand, Git}
import org.eclipse.jgit.archive.{TgzFormat, ZipFormat}
import org.eclipse.jgit.lib._
import org.apache.commons.io.FileUtils
import org.eclipse.jgit.treewalk._
import jp.sf.amateras.scalatra.forms._
import org.eclipse.jgit.dircache.DirCache
import org.eclipse.jgit.lib._
import org.eclipse.jgit.revwalk.RevCommit
import service.WebHookService._
import model.CommitState
import org.eclipse.jgit.treewalk._
import org.scalatra._
// TODO(tanacasino) Fix package name
import api._
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
@@ -95,7 +102,7 @@ trait RepositoryViewerControllerBase extends ControllerBase {
*/
post("/:owner/:repository/_preview")(referrersOnly { repository =>
contentType = "text/html"
view.helpers.markdown(params("content"), repository,
helpers.markdown(params("content"), repository,
params("enableWikiLink").toBoolean,
params("enableRefsLink").toBoolean,
params("enableTaskList").toBoolean,
@@ -138,7 +145,7 @@ trait RepositoryViewerControllerBase extends ControllerBase {
using(Git.open(getRepositoryDir(repository.owner, repository.name))){ git =>
JGitUtil.getCommitLog(git, branchName, page, 30, path) match {
case Right((logs, hasNext)) =>
repo.html.commits(if(path.isEmpty) Nil else path.split("/").toList, branchName, repository,
html.commits(if(path.isEmpty) Nil else path.split("/").toList, branchName, repository,
logs.splitWith{ (commit1, commit2) =>
view.helpers.date(commit1.commitTime) == view.helpers.date(commit2.commitTime)
}, page, hasNext, hasWritePermission(repository.owner, repository.name, context.loginAccount))
@@ -156,7 +163,7 @@ trait RepositoryViewerControllerBase extends ControllerBase {
sha <- JGitUtil.getShaByRef(repository.owner, repository.name, ref)
data <- extractFromJsonBody[CreateAStatus] if data.isValid
creator <- context.loginAccount
state <- model.CommitState.valueOf(data.state)
state <- CommitState.valueOf(data.state)
statusId = createCommitStatus(repository.owner, repository.name, sha, data.context.getOrElse("default"),
state, data.target_url, data.description, new java.util.Date(), creator)
status <- getCommitStatus(repository.owner, repository.name, statusId)
@@ -199,7 +206,7 @@ trait RepositoryViewerControllerBase extends ControllerBase {
get("/:owner/:repository/new/*")(collaboratorsOnly { repository =>
val (branch, path) = splitPath(repository, multiParams("splat").head)
repo.html.editor(branch, repository, if(path.length == 0) Nil else path.split("/").toList,
html.editor(branch, repository, if(path.length == 0) Nil else path.split("/").toList,
None, JGitUtil.ContentInfo("text", None, Some("UTF-8")))
})
@@ -211,7 +218,7 @@ trait RepositoryViewerControllerBase extends ControllerBase {
getPathObjectId(git, path, revCommit).map { objectId =>
val paths = path.split("/")
repo.html.editor(branch, repository, paths.take(paths.size - 1).toList, Some(paths.last),
html.editor(branch, repository, paths.take(paths.size - 1).toList, Some(paths.last),
JGitUtil.getContentInfo(git, path, objectId))
} getOrElse NotFound
}
@@ -224,7 +231,7 @@ trait RepositoryViewerControllerBase extends ControllerBase {
getPathObjectId(git, path, revCommit).map { objectId =>
val paths = path.split("/")
repo.html.delete(branch, repository, paths.take(paths.size - 1).toList, paths.last,
html.delete(branch, repository, paths.take(paths.size - 1).toList, paths.last,
JGitUtil.getContentInfo(git, path, objectId))
} getOrElse NotFound
}
@@ -278,7 +285,7 @@ trait RepositoryViewerControllerBase extends ControllerBase {
RawData(FileUtil.getContentType(path, bytes), bytes)
}
} else {
repo.html.blob(id, repository, path.split("/").toList, JGitUtil.getContentInfo(git, path, objectId),
html.blob(id, repository, path.split("/").toList, JGitUtil.getContentInfo(git, path, objectId),
new JGitUtil.CommitInfo(lastModifiedCommit), hasWritePermission(repository.owner, repository.name, context.loginAccount))
}
} getOrElse NotFound
@@ -294,7 +301,7 @@ trait RepositoryViewerControllerBase extends ControllerBase {
using(Git.open(getRepositoryDir(repository.owner, repository.name))){ git =>
defining(JGitUtil.getRevCommitFromId(git, git.getRepository.resolve(id))){ revCommit =>
JGitUtil.getDiffs(git, id) match { case (diffs, oldCommitId) =>
repo.html.commit(id, new JGitUtil.CommitInfo(revCommit),
html.commit(id, new JGitUtil.CommitInfo(revCommit),
JGitUtil.getBranchesOfCommit(git, revCommit.getName),
JGitUtil.getTagsOfCommit(git, revCommit.getName),
getCommitComments(repository.owner, repository.name, id, false),
@@ -321,7 +328,7 @@ trait RepositoryViewerControllerBase extends ControllerBase {
val oldLineNumber = params.get("oldLineNumber") map (_.toInt)
val newLineNumber = params.get("newLineNumber") map (_.toInt)
val issueId = params.get("issueId") map (_.toInt)
repo.html.commentform(
html.commentform(
commitId = id,
fileName, oldLineNumber, newLineNumber, issueId,
hasWritePermission = hasWritePermission(repository.owner, repository.name, context.loginAccount),
@@ -345,7 +352,7 @@ trait RepositoryViewerControllerBase extends ControllerBase {
getCommitComment(repository.owner, repository.name, params("id")) map { x =>
if(isEditable(x.userName, x.repositoryName, x.commentedUserName)){
params.get("dataType") collect {
case t if t == "html" => repo.html.editcomment(
case t if t == "html" => html.editcomment(
x.content, x.commentId, x.userName, x.repositoryName)
} getOrElse {
contentType = formats("json")
@@ -387,7 +394,7 @@ trait RepositoryViewerControllerBase extends ControllerBase {
.sortBy(br => (br.mergeInfo.isEmpty, br.commitTime))
.map(br => br -> getPullRequestByRequestCommit(repository.owner, repository.name, repository.repository.defaultBranch, br.name, br.commitId))
.reverse
repo.html.branches(branches, hasWritePermission(repository.owner, repository.name, context.loginAccount), repository)
html.branches(branches, hasWritePermission(repository.owner, repository.name, context.loginAccount), repository)
})
/**
@@ -427,7 +434,7 @@ trait RepositoryViewerControllerBase extends ControllerBase {
* Displays tags.
*/
get("/:owner/:repository/tags")(referrersOnly {
repo.html.tags(_)
html.tags(_)
})
/**
@@ -444,7 +451,7 @@ trait RepositoryViewerControllerBase extends ControllerBase {
})
get("/:owner/:repository/network/members")(referrersOnly { repository =>
repo.html.forked(
html.forked(
getRepository(
repository.repository.originUserName.getOrElse(repository.owner),
repository.repository.originRepositoryName.getOrElse(repository.name),
@@ -455,7 +462,7 @@ trait RepositoryViewerControllerBase extends ControllerBase {
repository)
})
private def splitPath(repository: service.RepositoryService.RepositoryInfo, path: String): (String, String) = {
private def splitPath(repository: RepositoryService.RepositoryInfo, path: String): (String, String) = {
val id = repository.branchList.collectFirst {
case branch if(path == branch || path.startsWith(branch + "/")) => branch
} orElse repository.tags.collectFirst {
@@ -478,7 +485,7 @@ trait RepositoryViewerControllerBase extends ControllerBase {
*/
private def fileList(repository: RepositoryService.RepositoryInfo, revstr: String = "", path: String = ".") = {
if(repository.commitCount == 0){
repo.html.guide(repository, hasWritePermission(repository.owner, repository.name, context.loginAccount))
html.guide(repository, hasWritePermission(repository.owner, repository.name, context.loginAccount))
} else {
using(Git.open(getRepositoryDir(repository.owner, repository.name))){ git =>
// get specified commit
@@ -497,11 +504,11 @@ trait RepositoryViewerControllerBase extends ControllerBase {
Git.open(getRepositoryDir(repository.owner, repository.name)), file.id, true).get)
}
repo.html.files(revision, repository,
html.files(revision, repository,
if(path == ".") Nil else path.split("/").toList, // current path
context.loginAccount match {
case None => List()
case account: Option[model.Account] => getGroupsByUserName(account.get.userName)
case account: Option[Account] => getGroupsByUserName(account.get.userName)
}, // groups of current user
new JGitUtil.CommitInfo(lastModifiedCommit), // last modified commit
files, readme, hasWritePermission(repository.owner, repository.name, context.loginAccount),
@@ -512,7 +519,7 @@ trait RepositoryViewerControllerBase extends ControllerBase {
}
}
private def commitFile(repository: service.RepositoryService.RepositoryInfo,
private def commitFile(repository: RepositoryService.RepositoryInfo,
branch: String, path: String, newFileName: Option[String], oldFileName: Option[String],
content: String, charset: String, message: String) = {
@@ -618,6 +625,6 @@ trait RepositoryViewerControllerBase extends ControllerBase {
}
}
private def isEditable(owner: String, repository: String, author: String)(implicit context: app.Context): Boolean =
private def isEditable(owner: String, repository: String, author: String)(implicit context: Context): Boolean =
hasWritePermission(owner, repository, context.loginAccount) || author == context.loginAccount.get.userName
}

View File

@@ -1,9 +1,10 @@
package app
package gitbucket.core.controller
import util._
import gitbucket.core.search.html
import gitbucket.core.service._
import gitbucket.core.util.{StringUtil, ControlUtil, ReferrerAuthenticator, Implicits}
import ControlUtil._
import Implicits._
import service._
import jp.sf.amateras.scalatra.forms._
class SearchController extends SearchControllerBase
@@ -34,12 +35,12 @@ trait SearchControllerBase extends ControllerBase { self: RepositoryService
}
target.toLowerCase match {
case "issue" => search.html.issues(
case "issue" => html.issues(
searchIssues(repository.owner, repository.name, query),
countFiles(repository.owner, repository.name, query),
query, page, repository)
case _ => search.html.code(
case _ => html.code(
searchFiles(repository.owner, repository.name, query),
countIssues(repository.owner, repository.name, query),
query, page, repository)

View File

@@ -1,10 +1,11 @@
package app
package gitbucket.core.controller
import service.{AccountService, SystemSettingsService}
import gitbucket.core.admin.html
import gitbucket.core.service.{AccountService, SystemSettingsService}
import gitbucket.core.util.AdminAuthenticator
import gitbucket.core.ssh.SshServer
import SystemSettingsService._
import util.AdminAuthenticator
import jp.sf.amateras.scalatra.forms._
import ssh.SshServer
class SystemSettingsController extends SystemSettingsControllerBase
with AccountService with AdminAuthenticator
@@ -59,7 +60,7 @@ trait SystemSettingsControllerBase extends ControllerBase {
case class PluginForm(pluginIds: List[String])
get("/admin/system")(adminOnly {
admin.html.system(flash.get("info"))
html.system(flash.get("info"))
})
post("/admin/system", form)(adminOnly { form =>

View File

@@ -1,11 +1,12 @@
package app
package gitbucket.core.controller
import service._
import util.AdminAuthenticator
import util.StringUtil._
import util.ControlUtil._
import util.Directory._
import util.Implicits._
import gitbucket.core.service.{RepositoryService, AccountService}
import gitbucket.core.admin.users.html
import gitbucket.core.util._
import gitbucket.core.util.ControlUtil._
import gitbucket.core.util.StringUtil._
import gitbucket.core.util.Implicits._
import gitbucket.core.util.Directory._
import jp.sf.amateras.scalatra.forms._
import org.scalatra.i18n.Messages
import org.apache.commons.io.FileUtils
@@ -75,11 +76,11 @@ trait UserManagementControllerBase extends AccountManagementControllerBase {
account.userName -> getGroupMembers(account.userName).map(_.userName)
}.toMap
admin.users.html.list(users, members, includeRemoved)
html.list(users, members, includeRemoved)
})
get("/admin/users/_newuser")(adminOnly {
admin.users.html.user(None)
html.user(None)
})
post("/admin/users/_newuser", newUserForm)(adminOnly { form =>
@@ -90,7 +91,7 @@ trait UserManagementControllerBase extends AccountManagementControllerBase {
get("/admin/users/:userName/_edituser")(adminOnly {
val userName = params("userName")
admin.users.html.user(getAccountByUserName(userName, true))
html.user(getAccountByUserName(userName, true))
})
post("/admin/users/:name/_edituser", editUserForm)(adminOnly { form =>
@@ -124,7 +125,7 @@ trait UserManagementControllerBase extends AccountManagementControllerBase {
})
get("/admin/users/_newgroup")(adminOnly {
admin.users.html.group(None, Nil)
html.group(None, Nil)
})
post("/admin/users/_newgroup", newGroupForm)(adminOnly { form =>
@@ -140,7 +141,7 @@ trait UserManagementControllerBase extends AccountManagementControllerBase {
get("/admin/users/:groupName/_editgroup")(adminOnly {
defining(params("groupName")){ groupName =>
admin.users.html.group(getAccountByUserName(groupName, true), getGroupMembers(groupName))
html.group(getAccountByUserName(groupName, true), getGroupMembers(groupName))
}
})
@@ -193,7 +194,7 @@ trait UserManagementControllerBase extends AccountManagementControllerBase {
protected def disableByNotYourself(paramName: String): Constraint = new Constraint() {
override def validate(name: String, value: String, messages: Messages): Option[String] = {
params.get(paramName).flatMap { userName =>
if(userName == context.loginAccount.get.userName)
if(userName == context.loginAccount.get.userName && params.get("removed") == Some("true"))
Some("You can't disable your account yourself")
else
None

View File

@@ -1,14 +1,14 @@
package app
package gitbucket.core.controller
import service._
import util._
import util.Directory._
import util.ControlUtil._
import util.Implicits._
import gitbucket.core.wiki.html
import gitbucket.core.service.{RepositoryService, WikiService, ActivityService, AccountService}
import gitbucket.core.util._
import gitbucket.core.util.ControlUtil._
import gitbucket.core.util.Implicits._
import gitbucket.core.util.Directory._
import jp.sf.amateras.scalatra.forms._
import org.eclipse.jgit.api.Git
import org.scalatra.i18n.Messages
import java.util.ResourceBundle
class WikiController extends WikiControllerBase
with WikiService with RepositoryService with AccountService with ActivityService with CollaboratorsAuthenticator with ReferrerAuthenticator
@@ -36,7 +36,7 @@ trait WikiControllerBase extends ControllerBase {
get("/:owner/:repository/wiki")(referrersOnly { repository =>
getWikiPage(repository.owner, repository.name, "Home").map { page =>
wiki.html.page("Home", page, getWikiPageList(repository.owner, repository.name),
html.page("Home", page, getWikiPageList(repository.owner, repository.name),
repository, hasWritePermission(repository.owner, repository.name, context.loginAccount))
} getOrElse redirect(s"/${repository.owner}/${repository.name}/wiki/Home/_edit")
})
@@ -45,7 +45,7 @@ trait WikiControllerBase extends ControllerBase {
val pageName = StringUtil.urlDecode(params("page"))
getWikiPage(repository.owner, repository.name, pageName).map { page =>
wiki.html.page(pageName, page, getWikiPageList(repository.owner, repository.name),
html.page(pageName, page, getWikiPageList(repository.owner, repository.name),
repository, hasWritePermission(repository.owner, repository.name, context.loginAccount))
} getOrElse redirect(s"/${repository.owner}/${repository.name}/wiki/${StringUtil.urlEncode(pageName)}/_edit")
})
@@ -55,7 +55,7 @@ trait WikiControllerBase extends ControllerBase {
using(Git.open(getWikiRepositoryDir(repository.owner, repository.name))){ git =>
JGitUtil.getCommitLog(git, "master", path = pageName + ".md") match {
case Right((logs, hasNext)) => wiki.html.history(Some(pageName), logs, repository)
case Right((logs, hasNext)) => html.history(Some(pageName), logs, repository)
case Left(_) => NotFound
}
}
@@ -66,7 +66,7 @@ trait WikiControllerBase extends ControllerBase {
val Array(from, to) = params("commitId").split("\\.\\.\\.")
using(Git.open(getWikiRepositoryDir(repository.owner, repository.name))){ git =>
wiki.html.compare(Some(pageName), from, to, JGitUtil.getDiffs(git, from, to, true).filter(_.newPath == pageName + ".md"), repository,
html.compare(Some(pageName), from, to, JGitUtil.getDiffs(git, from, to, true).filter(_.newPath == pageName + ".md"), repository,
hasWritePermission(repository.owner, repository.name, context.loginAccount), flash.get("info"))
}
})
@@ -75,7 +75,7 @@ trait WikiControllerBase extends ControllerBase {
val Array(from, to) = params("commitId").split("\\.\\.\\.")
using(Git.open(getWikiRepositoryDir(repository.owner, repository.name))){ git =>
wiki.html.compare(None, from, to, JGitUtil.getDiffs(git, from, to, true), repository,
html.compare(None, from, to, JGitUtil.getDiffs(git, from, to, true), repository,
hasWritePermission(repository.owner, repository.name, context.loginAccount), flash.get("info"))
}
})
@@ -105,7 +105,7 @@ trait WikiControllerBase extends ControllerBase {
get("/:owner/:repository/wiki/:page/_edit")(collaboratorsOnly { repository =>
val pageName = StringUtil.urlDecode(params("page"))
wiki.html.edit(pageName, getWikiPage(repository.owner, repository.name, pageName), repository)
html.edit(pageName, getWikiPage(repository.owner, repository.name, pageName), repository)
})
post("/:owner/:repository/wiki/_edit", editForm)(collaboratorsOnly { (form, repository) =>
@@ -120,7 +120,7 @@ trait WikiControllerBase extends ControllerBase {
})
get("/:owner/:repository/wiki/_new")(collaboratorsOnly {
wiki.html.edit("", None, _)
html.edit("", None, _)
})
post("/:owner/:repository/wiki/_new", newForm)(collaboratorsOnly { (form, repository) =>
@@ -147,14 +147,14 @@ trait WikiControllerBase extends ControllerBase {
})
get("/:owner/:repository/wiki/_pages")(referrersOnly { repository =>
wiki.html.pages(getWikiPageList(repository.owner, repository.name), repository,
html.pages(getWikiPageList(repository.owner, repository.name), repository,
hasWritePermission(repository.owner, repository.name, context.loginAccount))
})
get("/:owner/:repository/wiki/_history")(referrersOnly { repository =>
using(Git.open(getWikiRepositoryDir(repository.owner, repository.name))){ git =>
JGitUtil.getCommitLog(git, "master") match {
case Right((logs, hasNext)) => wiki.html.history(None, logs, repository)
case Right((logs, hasNext)) => html.history(None, logs, repository)
case Left(_) => NotFound
}
}

View File

@@ -1,4 +1,5 @@
package model
package gitbucket.core.model
trait AccessTokenComponent { self: Profile =>
import profile.simple._

View File

@@ -1,4 +1,4 @@
package model
package gitbucket.core.model
trait AccountComponent { self: Profile =>
import profile.simple._

View File

@@ -1,4 +1,4 @@
package model
package gitbucket.core.model
trait ActivityComponent extends TemplateComponent { self: Profile =>
import profile.simple._

View File

@@ -1,4 +1,4 @@
package model
package gitbucket.core.model
protected[model] trait TemplateComponent { self: Profile =>
import profile.simple._

View File

@@ -1,4 +1,4 @@
package model
package gitbucket.core.model
trait CollaboratorComponent extends TemplateComponent { self: Profile =>
import profile.simple._

View File

@@ -1,4 +1,4 @@
package model
package gitbucket.core.model
trait Comment {
val commentedUserName: String

View File

@@ -1,4 +1,4 @@
package model
package gitbucket.core.model
import scala.slick.lifted.MappedTo
import scala.slick.jdbc._
@@ -24,6 +24,7 @@ trait CommitStatusComponent extends TemplateComponent { self: Profile =>
}
}
case class CommitStatus(
commitStatusId: Int = 0,
userName: String,
@@ -37,16 +38,26 @@ case class CommitStatus(
registeredDate: java.util.Date,
updatedDate: java.util.Date
)
sealed abstract class CommitState(val name: String)
object CommitState {
object ERROR extends CommitState("error")
object FAILURE extends CommitState("failure")
object PENDING extends CommitState("pending")
object SUCCESS extends CommitState("success")
val values: Vector[CommitState] = Vector(PENDING, SUCCESS, ERROR, FAILURE)
private val map: Map[String, CommitState] = values.map(enum => enum.name -> enum).toMap
def apply(name: String): CommitState = map(name)
def valueOf(name: String): Option[CommitState] = map.get(name)
/**
@@ -57,11 +68,11 @@ object CommitState {
def combine(statuses: Set[CommitState]): CommitState = {
if(statuses.isEmpty){
PENDING
}else if(statuses.contains(CommitState.ERROR) || statuses.contains(CommitState.FAILURE)){
} else if(statuses.contains(CommitState.ERROR) || statuses.contains(CommitState.FAILURE)) {
FAILURE
}else if(statuses.contains(CommitState.PENDING)){
} else if(statuses.contains(CommitState.PENDING)) {
PENDING
}else{
} else {
SUCCESS
}
}
@@ -69,3 +80,4 @@ object CommitState {
implicit val getResult: GetResult[CommitState] = GetResult(r => CommitState(r.<<))
implicit val getResultOpt: GetResult[Option[CommitState]] = GetResult(r => r.<<?[String].map(CommitState(_)))
}

View File

@@ -1,4 +1,4 @@
package model
package gitbucket.core.model
trait GroupMemberComponent { self: Profile =>
import profile.simple._

View File

@@ -1,4 +1,4 @@
package model
package gitbucket.core.model
trait IssueComponent extends TemplateComponent { self: Profile =>
import profile.simple._

View File

@@ -1,4 +1,4 @@
package model
package gitbucket.core.model
trait IssueLabelComponent extends TemplateComponent { self: Profile =>
import profile.simple._

View File

@@ -1,4 +1,4 @@
package model
package gitbucket.core.model
trait LabelComponent extends TemplateComponent { self: Profile =>
import profile.simple._

View File

@@ -1,4 +1,4 @@
package model
package gitbucket.core.model
trait MilestoneComponent extends TemplateComponent { self: Profile =>
import profile.simple._

View File

@@ -1,4 +1,4 @@
package model
package gitbucket.core.model
trait PluginComponent extends TemplateComponent { self: Profile =>
import profile.simple._

View File

@@ -1,25 +1,38 @@
package model
package gitbucket.core.model
trait Profile {
val profile: slick.driver.JdbcProfile
import profile.simple._
// java.util.Date Mapped Column Types
/**
* java.util.Date Mapped Column Types
*/
implicit val dateColumnType = MappedColumnType.base[java.util.Date, java.sql.Timestamp](
d => new java.sql.Timestamp(d.getTime),
t => new java.util.Date(t.getTime)
d => new java.sql.Timestamp(d.getTime),
t => new java.util.Date(t.getTime)
)
/**
* Extends Column to add conditional condition
*/
implicit class RichColumn(c1: Column[Boolean]){
def &&(c2: => Column[Boolean], guard: => Boolean): Column[Boolean] = if(guard) c1 && c2 else c1
}
/**
* Returns system date.
*/
def currentDate = new java.util.Date()
}
object Profile extends {
trait ProfileProvider { self: Profile =>
val profile = slick.driver.H2Driver
}
} with AccessTokenComponent
trait CoreProfile extends ProfileProvider with Profile
with AccessTokenComponent
with AccountComponent
with ActivityComponent
with CollaboratorComponent
@@ -35,11 +48,6 @@ object Profile extends {
with RepositoryComponent
with SshKeyComponent
with WebHookComponent
with PluginComponent with Profile {
with PluginComponent
/**
* Returns system date.
*/
def currentDate = new java.util.Date()
}
object Profile extends CoreProfile

View File

@@ -1,4 +1,4 @@
package model
package gitbucket.core.model
trait PullRequestComponent extends TemplateComponent { self: Profile =>
import profile.simple._

View File

@@ -1,4 +1,4 @@
package model
package gitbucket.core.model
trait RepositoryComponent extends TemplateComponent { self: Profile =>
import profile.simple._

View File

@@ -1,4 +1,4 @@
package model
package gitbucket.core.model
trait SshKeyComponent { self: Profile =>
import profile.simple._

View File

@@ -1,4 +1,4 @@
package model
package gitbucket.core.model
trait WebHookComponent extends TemplateComponent { self: Profile =>
import profile.simple._

View File

@@ -1,3 +1,5 @@
package gitbucket.core
package object model {
type Session = slick.jdbc.JdbcBackend#Session
}

View File

@@ -0,0 +1,10 @@
package gitbucket.core.plugin
/**
* Provides a helper method to generate data URI of images registered by plug-in.
*/
object Images {
def dataURI(id: String) = s"data:image/png;base64,${PluginRegistry().getImage(id)}"
}

View File

@@ -1,8 +1,6 @@
package plugin
package gitbucket.core.plugin
import javax.servlet.ServletContext
import util.Version
import gitbucket.core.util.Version
/**
* Trait for define plugin interface.

View File

@@ -1,24 +1,28 @@
package plugin
package gitbucket.core.plugin
import java.io.{FilenameFilter, File}
import java.io.{File, FilenameFilter, InputStream}
import java.net.URLClassLoader
import javax.servlet.ServletContext
import javax.servlet.http.{HttpServletRequest, HttpServletResponse}
import gitbucket.core.controller.{Context, ControllerBase}
import gitbucket.core.service.RepositoryService.RepositoryInfo
import gitbucket.core.util.ControlUtil._
import gitbucket.core.util.Directory._
import gitbucket.core.util.JDBCUtil._
import gitbucket.core.util.{Version, Versions}
import org.apache.commons.codec.binary.{Base64, StringUtils}
import org.slf4j.LoggerFactory
import service.RepositoryService.RepositoryInfo
import util.Directory._
import util.JDBCUtil._
import util.{Version, Versions}
import scala.collection.mutable
import scala.collection.mutable.ListBuffer
import app.{ControllerBase, Context}
class PluginRegistry {
private val plugins = new ListBuffer[PluginInfo]
private val javaScripts = new ListBuffer[(String, String)]
private val controllers = new ListBuffer[(ControllerBase, String)]
private val images = mutable.Map[String, String]()
def addPlugin(pluginInfo: PluginInfo): Unit = {
plugins += pluginInfo
@@ -26,6 +30,18 @@ class PluginRegistry {
def getPlugins(): List[PluginInfo] = plugins.toList
def addImage(id: String, in: InputStream): Unit = {
val bytes = using(in){ in =>
val bytes = new Array[Byte](in.available)
in.read(bytes)
bytes
}
val encoded = StringUtils.newStringUtf8(Base64.encodeBase64(bytes, false))
images += ((id, encoded))
}
def getImage(id: String): String = images(id)
def addController(controller: ControllerBase, path: String): Unit = {
controllers += ((controller, path))
}
@@ -38,8 +54,8 @@ class PluginRegistry {
//def getJavaScripts(): List[(String, String)] = javaScripts.toList
def getJavaScript(currentPath: String): Option[String] = {
javaScripts.find(x => currentPath.matches(x._1)).map(_._2)
def getJavaScript(currentPath: String): List[String] = {
javaScripts.filter(x => currentPath.matches(x._1)).toList.map(_._2)
}
private case class GlobalAction(
@@ -142,4 +158,4 @@ case class PluginInfo(
version: String,
description: String,
pluginClass: Plugin
)
)

View File

@@ -1,4 +1,4 @@
package plugin
package gitbucket.core.plugin
import play.twirl.api.Html

View File

@@ -1,6 +1,6 @@
package plugin
package gitbucket.core.plugin
import slick.jdbc.JdbcBackend.Session
import scala.slick.jdbc.JdbcBackend.Session
/**
* Provides Slick Session to Plug-ins.

View File

@@ -1,11 +1,14 @@
package service
package gitbucket.core.service
import model.Profile._
import gitbucket.core.model.Profile._
import profile.simple._
import model.{Account, AccessToken}
import util.StringUtil
import gitbucket.core.model.{Account, AccessToken}
import gitbucket.core.util.StringUtil
import scala.util.Random
trait AccessTokenService {
def makeAccessTokenString: String = {

View File

@@ -1,14 +1,14 @@
package service
package gitbucket.core.service
import model.Profile._
import gitbucket.core.model.{GroupMember, Account}
import gitbucket.core.model.Profile._
import gitbucket.core.util.{StringUtil, LDAPUtil}
import gitbucket.core.service.SystemSettingsService.SystemSettings
import profile.simple._
import model.{Account, GroupMember}
// TODO [Slick 2.0]NOT import directly?
import model.Profile.dateColumnType
import service.SystemSettingsService.SystemSettings
import util.StringUtil._
import util.LDAPUtil
import StringUtil._
import org.slf4j.LoggerFactory
// TODO Why is direct import required?
import gitbucket.core.model.Profile.dateColumnType
trait AccountService {

View File

@@ -1,8 +1,9 @@
package service
package gitbucket.core.service
import model.Profile._
import gitbucket.core.model.Activity
import gitbucket.core.model.Profile._
import gitbucket.core.util.JGitUtil
import profile.simple._
import model.Activity
trait ActivityService {
@@ -121,7 +122,7 @@ trait ActivityService {
currentDate)
def recordPushActivity(userName: String, repositoryName: String, activityUserName: String,
branchName: String, commits: List[util.JGitUtil.CommitInfo])(implicit s: Session): Unit =
branchName: String, commits: List[JGitUtil.CommitInfo])(implicit s: Session): Unit =
Activities insert Activity(userName, repositoryName, activityUserName,
"push",
s"[user:${activityUserName}] pushed to [branch:${userName}/${repositoryName}#${branchName}] at [repo:${userName}/${repositoryName}]",
@@ -129,7 +130,7 @@ trait ActivityService {
currentDate)
def recordCreateTagActivity(userName: String, repositoryName: String, activityUserName: String,
tagName: String, commits: List[util.JGitUtil.CommitInfo])(implicit s: Session): Unit =
tagName: String, commits: List[JGitUtil.CommitInfo])(implicit s: Session): Unit =
Activities insert Activity(userName, repositoryName, activityUserName,
"create_tag",
s"[user:${activityUserName}] created tag [tag:${userName}/${repositoryName}#${tagName}] at [repo:${userName}/${repositoryName}]",
@@ -137,7 +138,7 @@ trait ActivityService {
currentDate)
def recordDeleteTagActivity(userName: String, repositoryName: String, activityUserName: String,
tagName: String, commits: List[util.JGitUtil.CommitInfo])(implicit s: Session): Unit =
tagName: String, commits: List[JGitUtil.CommitInfo])(implicit s: Session): Unit =
Activities insert Activity(userName, repositoryName, activityUserName,
"delete_tag",
s"[user:${activityUserName}] deleted tag ${tagName} at [repo:${userName}/${repositoryName}]",

View File

@@ -1,11 +1,13 @@
package service
package gitbucket.core.service
import model.Profile._
import gitbucket.core.model.Profile._
import profile.simple._
import model.{CommitState, CommitStatus, Account}
import util.Implicits._
import util.StringUtil._
import service.RepositoryService.RepositoryInfo
import gitbucket.core.model.{CommitState, CommitStatus, Account}
import gitbucket.core.util.Implicits._
import gitbucket.core.util.StringUtil._
import gitbucket.core.service.RepositoryService.RepositoryInfo
trait CommitStatusService {
/** insert or update */

View File

@@ -1,13 +1,14 @@
package service
package gitbucket.core.service
import gitbucket.core.model.CommitComment
import gitbucket.core.util.{StringUtil, Implicits}
import scala.slick.jdbc.{StaticQuery => Q}
import Q.interpolation
import model.Profile._
import gitbucket.core.model.Profile._
import profile.simple._
import model.CommitComment
import util.Implicits._
import util.StringUtil._
import Implicits._
import StringUtil._
trait CommitsService {

View File

@@ -1,13 +1,15 @@
package service
package gitbucket.core.service
import gitbucket.core.model.Profile._
import profile.simple._
import gitbucket.core.util.StringUtil._
import gitbucket.core.util.Implicits._
import gitbucket.core.model._
import scala.slick.jdbc.{StaticQuery => Q}
import Q.interpolation
import model.Profile._
import profile.simple._
import model.{Issue, IssueComment, IssueLabel, Label}
import util.Implicits._
import util.StringUtil._
trait IssuesService {
import IssuesService._
@@ -98,8 +100,8 @@ trait IssuesService {
pp.setInt(a._3)
}
}
import model.Profile.commitStateColumnType
val query = Q.query[Seq[(String, String, Int)], (String, String, Int, Int, Int, Option[String], Option[model.CommitState], Option[String], Option[String])](s"""
import gitbucket.core.model.Profile.commitStateColumnType
val query = Q.query[Seq[(String, String, Int)], (String, String, Int, Int, Int, Option[String], Option[CommitState], Option[String], Option[String])](s"""
SELECT SUMM.USER_NAME, SUMM.REPOSITORY_NAME, SUMM.ISSUE_ID, CS_ALL, CS_SUCCESS
, CSD.CONTEXT, CSD.STATE, CSD.TARGET_URL, CSD.DESCRIPTION
FROM (SELECT
@@ -169,7 +171,7 @@ trait IssuesService {
* @return (issue, commentCount, pullRequest, headRepository, headOwner)
*/
def searchPullRequestByApi(condition: IssueSearchCondition, offset: Int, limit: Int, repos: (String, String)*)
(implicit s: Session): List[(Issue, model.Account, Int, model.PullRequest, model.Repository, model.Account)] = {
(implicit s: Session): List[(Issue, Account, Int, PullRequest, Repository, Account)] = {
// get issues and comment count and labels
searchIssueQueryBase(condition, true, offset, limit, repos)
.innerJoin(PullRequests).on { case ((t1, t2), t3) => t3.byPrimaryKey(t1.userName, t1.repositoryName, t1.issueId) }
@@ -533,7 +535,7 @@ object IssuesService {
}
}
case class CommitStatusInfo(count: Int, successCount: Int, context: Option[String], state: Option[model.CommitState], targetUrl: Option[String], description: Option[String])
case class CommitStatusInfo(count: Int, successCount: Int, context: Option[String], state: Option[CommitState], targetUrl: Option[String], description: Option[String])
case class IssueInfo(issue: Issue, labels: List[Label], milestone: Option[String], commentCount: Int, status:Option[CommitStatusInfo])

View File

@@ -1,8 +1,8 @@
package service
package gitbucket.core.service
import model.Profile._
import gitbucket.core.model.Label
import gitbucket.core.model.Profile._
import profile.simple._
import model.Label
trait LabelsService {

View File

@@ -1,15 +1,19 @@
package service
import util.LockUtil
import util.Directory._
import util.Implicits._
import util.ControlUtil._
package gitbucket.core.service
import gitbucket.core.model.Account
import gitbucket.core.util.LockUtil
import gitbucket.core.util.Directory._
import gitbucket.core.util.Implicits._
import gitbucket.core.util.ControlUtil._
import org.eclipse.jgit.merge.MergeStrategy
import org.eclipse.jgit.api.Git
import org.eclipse.jgit.transport.RefSpec
import org.eclipse.jgit.errors.NoMergeBaseException
import org.eclipse.jgit.lib.{ObjectId, CommitBuilder, PersonIdent}
import model.Account
import org.eclipse.jgit.revwalk.RevWalk
trait MergeService {
import MergeService._
/**

View File

@@ -1,10 +1,10 @@
package service
package gitbucket.core.service
import model.Profile._
import gitbucket.core.model.Milestone
import gitbucket.core.model.Profile._
import profile.simple._
import model.Milestone
// TODO [Slick 2.0]NOT import directly?
import model.Profile.dateColumnType
// TODO Why is direct import required?
import gitbucket.core.model.Profile.dateColumnType
trait MilestonesService {

View File

@@ -1,8 +1,8 @@
package service
package gitbucket.core.service
import model.Profile._
import gitbucket.core.model.Plugin
import gitbucket.core.model.Profile._
import profile.simple._
import model.Plugin
trait PluginService {

View File

@@ -1,9 +1,10 @@
package service
package gitbucket.core.service
import model.Profile._
import gitbucket.core.model.{Account, Issue, PullRequest, WebHook}
import gitbucket.core.model.Profile._
import gitbucket.core.util.JGitUtil
import profile.simple._
import model.{PullRequest, Issue, WebHook, Account}
import util.JGitUtil
trait PullRequestService { self: IssuesService =>
import PullRequestService._

View File

@@ -1,13 +1,15 @@
package service
package gitbucket.core.service
import util.{FileUtil, StringUtil, JGitUtil}
import util.Directory._
import util.ControlUtil._
import gitbucket.core.model.Issue
import gitbucket.core.util._
import gitbucket.core.util.StringUtil
import Directory._
import ControlUtil._
import org.eclipse.jgit.revwalk.RevWalk
import org.eclipse.jgit.treewalk.TreeWalk
import org.eclipse.jgit.lib.FileMode
import org.eclipse.jgit.api.Git
import model.Profile._
import gitbucket.core.model.Profile._
import profile.simple._
trait RepositorySearchService { self: IssuesService =>
@@ -108,7 +110,7 @@ object RepositorySearchService {
case class SearchResult(
files : List[(String, String)],
issues: List[(model.Issue, Int, String)])
issues: List[(Issue, Int, String)])
case class IssueSearchResult(
issueId: Int,

View File

@@ -1,9 +1,9 @@
package service
package gitbucket.core.service
import model.Profile._
import gitbucket.core.model.{Collaborator, Repository, Account}
import gitbucket.core.model.Profile._
import gitbucket.core.util.JGitUtil
import profile.simple._
import model.{Repository, Account, Collaborator, Label}
import util.JGitUtil
trait RepositoryService { self: AccountService =>
import RepositoryService._
@@ -377,7 +377,7 @@ object RepositoryService {
case class RepositoryInfo(owner: String, name: String, httpUrl: String, repository: Repository,
issueCount: Int, pullCount: Int, commitCount: Int, forkedCount: Int,
branchList: Seq[String], tags: Seq[util.JGitUtil.TagInfo], managers: Seq[String]){
branchList: Seq[String], tags: Seq[JGitUtil.TagInfo], managers: Seq[String]){
lazy val host = """^https?://(.+?)(:\d+)?/""".r.findFirstMatchIn(httpUrl).get.group(1)

View File

@@ -1,7 +1,9 @@
package service
package gitbucket.core.service
import model.{Account, Issue, Session}
import util.Implicits.request2Session
import gitbucket.core.model.{Session, Issue, Account}
import gitbucket.core.util.Implicits
import gitbucket.core.controller.Context
import Implicits.request2Session
/**
* This service is used for a view helper mainly.
@@ -11,25 +13,22 @@ import util.Implicits.request2Session
*/
trait RequestCache extends SystemSettingsService with AccountService with IssuesService {
private implicit def context2Session(implicit context: app.Context): Session =
private implicit def context2Session(implicit context: Context): Session =
request2Session(context.request)
def getIssue(userName: String, repositoryName: String, issueId: String)
(implicit context: app.Context): Option[Issue] = {
def getIssue(userName: String, repositoryName: String, issueId: String)(implicit context: Context): Option[Issue] = {
context.cache(s"issue.${userName}/${repositoryName}#${issueId}"){
super.getIssue(userName, repositoryName, issueId)
}
}
def getAccountByUserName(userName: String)
(implicit context: app.Context): Option[Account] = {
def getAccountByUserName(userName: String)(implicit context: Context): Option[Account] = {
context.cache(s"account.${userName}"){
super.getAccountByUserName(userName)
}
}
def getAccountByMailAddress(mailAddress: String)
(implicit context: app.Context): Option[Account] = {
def getAccountByMailAddress(mailAddress: String)(implicit context: Context): Option[Account] = {
context.cache(s"account.${mailAddress}"){
super.getAccountByMailAddress(mailAddress)
}

View File

@@ -1,8 +1,8 @@
package service
package gitbucket.core.service
import model.Profile._
import gitbucket.core.model.SshKey
import gitbucket.core.model.Profile._
import profile.simple._
import model.SshKey
trait SshKeyService {

View File

@@ -1,7 +1,8 @@
package service
package gitbucket.core.service
import util.Directory._
import util.ControlUtil._
import gitbucket.core.util.{Directory, ControlUtil}
import Directory._
import ControlUtil._
import SystemSettingsService._
import javax.servlet.http.HttpServletRequest

View File

@@ -1,19 +1,35 @@
package service
package gitbucket.core.service
import model.Profile._
import gitbucket.core.model.{WebHook, Account, Issue, PullRequest, IssueComment, Repository}
import gitbucket.core.model.Profile._
import profile.simple._
import model.{WebHook, Account, Issue, PullRequest, IssueComment, Repository, CommitStatus, CommitState}
import gitbucket.core.service.RepositoryService.RepositoryInfo
import gitbucket.core.util.JGitUtil
import gitbucket.core.util.JGitUtil.CommitInfo
import gitbucket.core.util.RepositoryName
import org.slf4j.LoggerFactory
import service.RepositoryService.RepositoryInfo
import util.JGitUtil
import util.JGitUtil.CommitInfo
import gitbucket.core.service.RepositoryService.RepositoryInfo
import org.slf4j.LoggerFactory
import RepositoryService.RepositoryInfo
import org.eclipse.jgit.diff.DiffEntry
import JGitUtil.CommitInfo
import org.eclipse.jgit.api.Git
import org.apache.http.message.BasicNameValuePair
import org.apache.http.client.entity.UrlEncodedFormEntity
import org.apache.http.NameValuePair
import java.util.Date
// TODO(tanacasino): Fix package name
import api._
trait WebHookService {
import WebHookService._
@@ -77,7 +93,7 @@ trait WebHookPullRequestService extends WebHookService {
import WebHookService._
// https://developer.github.com/v3/activity/events/types/#issuesevent
def callIssuesWebHook(action: String, repository: RepositoryService.RepositoryInfo, issue: Issue, baseUrl: String, sender: model.Account)(implicit s: Session, context:JsonFormat.Context): Unit = {
def callIssuesWebHook(action: String, repository: RepositoryService.RepositoryInfo, issue: Issue, baseUrl: String, sender: Account)(implicit s: Session, context:JsonFormat.Context): Unit = {
callWebHookOf(repository.owner, repository.name, "issues"){
val users = getAccountsByUserNames(Set(repository.owner, issue.userName), Set(sender))
for{
@@ -94,7 +110,7 @@ trait WebHookPullRequestService extends WebHookService {
}
}
def callPullRequestWebHook(action: String, repository: RepositoryService.RepositoryInfo, issueId: Int, baseUrl: String, sender: model.Account)(implicit s: Session, context:JsonFormat.Context): Unit = {
def callPullRequestWebHook(action: String, repository: RepositoryService.RepositoryInfo, issueId: Int, baseUrl: String, sender: Account)(implicit s: Session, context:JsonFormat.Context): Unit = {
import WebHookService._
callWebHookOf(repository.owner, repository.name, "pull_request"){
for{
@@ -132,7 +148,7 @@ trait WebHookPullRequestService extends WebHookService {
((is, pr, bu, ru), wh)
}).list.groupBy(_._1).mapValues(_.map(_._2))
def callPullRequestWebHookByRequestBranch(action: String, requestRepository: RepositoryService.RepositoryInfo, requestBranch: String, baseUrl: String, sender: model.Account)(implicit s: Session, context:JsonFormat.Context): Unit = {
def callPullRequestWebHookByRequestBranch(action: String, requestRepository: RepositoryService.RepositoryInfo, requestBranch: String, baseUrl: String, sender: Account)(implicit s: Session, context:JsonFormat.Context): Unit = {
import WebHookService._
for{
((issue, pullRequest, baseOwner, headOwner), webHooks) <- getPullRequestsByRequestForWebhook(requestRepository.owner, requestRepository.name, requestBranch)
@@ -156,7 +172,7 @@ trait WebHookIssueCommentService extends WebHookPullRequestService {
self: AccountService with RepositoryService with PullRequestService with IssuesService =>
import WebHookService._
def callIssueCommentWebHook(repository: RepositoryService.RepositoryInfo, issue: Issue, issueCommentId: Int, sender: model.Account)(implicit s: Session, context:JsonFormat.Context): Unit = {
def callIssueCommentWebHook(repository: RepositoryService.RepositoryInfo, issue: Issue, issueCommentId: Int, sender: Account)(implicit s: Session, context:JsonFormat.Context): Unit = {
callWebHookOf(repository.owner, repository.name, "issue_comment"){
for{
issueComment <- getComment(repository.owner, repository.name, issueCommentId.toString())
@@ -195,7 +211,7 @@ object WebHookService {
WebHookPushPayload(
ApiUser(pusher),
refName,
commits.map{ commit => ApiCommit(git, util.RepositoryName(repositoryInfo), commit) },
commits.map{ commit => ApiCommit(git, RepositoryName(repositoryInfo), commit) },
ApiRepository(
repositoryInfo,
owner= ApiUser(repositoryOwner)
@@ -228,7 +244,7 @@ object WebHookService {
headOwner: Account,
baseRepository: RepositoryInfo,
baseOwner: Account,
sender: model.Account): WebHookPullRequestPayload = {
sender: Account): WebHookPullRequestPayload = {
val headRepoPayload = ApiRepository(headRepository, headOwner)
val baseRepoPayload = ApiRepository(baseRepository, baseOwner)
val senderPayload = ApiUser(sender)

View File

@@ -1,9 +1,10 @@
package service
package gitbucket.core.service
import java.util.Date
import gitbucket.core.model.Account
import gitbucket.core.util._
import gitbucket.core.util.ControlUtil._
import org.eclipse.jgit.api.Git
import util._
import _root_.util.ControlUtil._
import org.eclipse.jgit.treewalk.CanonicalTreeParser
import org.eclipse.jgit.lib._
import org.eclipse.jgit.dircache.DirCache
@@ -12,7 +13,7 @@ import java.io.ByteArrayInputStream
import org.eclipse.jgit.patch._
import org.eclipse.jgit.api.errors.PatchFormatException
import scala.collection.JavaConverters._
import service.RepositoryService.RepositoryInfo
import RepositoryService.RepositoryInfo
object WikiService {
@@ -46,7 +47,7 @@ object WikiService {
trait WikiService {
import WikiService._
def createWikiRepository(loginAccount: model.Account, owner: String, repository: String): Unit =
def createWikiRepository(loginAccount: Account, owner: String, repository: String): Unit =
LockUtil.lock(s"${owner}/${repository}/wiki"){
defining(Directory.getWikiRepositoryDir(owner, repository)){ dir =>
if(!dir.exists){
@@ -102,7 +103,7 @@ trait WikiService {
* Reverts specified changes.
*/
def revertWikiPage(owner: String, repository: String, from: String, to: String,
committer: model.Account, pageName: Option[String]): Boolean = {
committer: Account, pageName: Option[String]): Boolean = {
case class RevertInfo(operation: String, filePath: String, source: String)
@@ -204,7 +205,7 @@ trait WikiService {
* Save the wiki page.
*/
def saveWikiPage(owner: String, repository: String, currentPageName: String, newPageName: String,
content: String, committer: model.Account, message: String, currentId: Option[String]): Option[String] = {
content: String, committer: Account, message: String, currentId: Option[String]): Option[String] = {
LockUtil.lock(s"${owner}/${repository}/wiki"){
using(Git.open(Directory.getWikiRepositoryDir(owner, repository))){ git =>
val builder = DirCache.newInCore.builder()

View File

@@ -1,14 +1,16 @@
package servlet
package gitbucket.core.servlet
import javax.servlet._
import javax.servlet.http.{HttpServletRequest, HttpServletResponse}
import service.AccessTokenService
import util.Keys
import gitbucket.core.model.Account
import gitbucket.core.service.AccessTokenService
import gitbucket.core.util.Keys
import org.scalatra.servlet.ServletApiImplicits._
import model.Account
import org.scalatra._
class AccessTokenAuthenticationFilter extends Filter with AccessTokenService {
private val tokenHeaderPrefix = "token "

View File

@@ -1,16 +1,15 @@
package servlet
package gitbucket.core.servlet
import javax.servlet._
import javax.servlet.http._
import service.{SystemSettingsService, AccountService, RepositoryService}
import model._
import gitbucket.core.service.{RepositoryService, AccountService, SystemSettingsService}
import gitbucket.core.util.{ControlUtil, Keys, Implicits}
import org.slf4j.LoggerFactory
import util.Implicits._
import util.ControlUtil._
import util.Keys
import Implicits._
import ControlUtil._
/**
* Provides BASIC Authentication for [[servlet.GitRepositoryServlet]].
* Provides BASIC Authentication for [[GitRepositoryServlet]].
*/
class BasicAuthenticationFilter extends Filter with RepositoryService with AccountService with SystemSettingsService {
@@ -29,7 +28,6 @@ class BasicAuthenticationFilter extends Filter with RepositoryService with Accou
}
val isUpdating = request.getRequestURI.endsWith("/git-receive-pack") || "service=git-receive-pack".equals(request.getQueryString)
val settings = loadSystemSettings()
try {
@@ -45,13 +43,15 @@ class BasicAuthenticationFilter extends Filter with RepositoryService with Accou
case auth => decodeAuthHeader(auth).split(":") match {
case Array(username, password) => {
authenticate(settings, username, password) match {
case Some(account) => {
if(isUpdating && hasWritePermission(repository.owner, repository.name, Some(account))){
case Some(account) if (isUpdating || repository.repository.isPrivate) => {
if(hasWritePermission(repository.owner, repository.name, Some(account))){
request.setAttribute(Keys.Request.UserName, account.userName)
chain.doFilter(req, wrappedResponse)
} else {
requireAuth(response)
}
chain.doFilter(req, wrappedResponse)
}
case None => requireAuth(response)
case _ => requireAuth(response)
}
}
case _ => requireAuth(response)

View File

@@ -1,5 +1,8 @@
package servlet
package gitbucket.core.servlet
import gitbucket.core.model.Session
import gitbucket.core.service._
import gitbucket.core.util._
import org.eclipse.jgit.http.server.GitServlet
import org.eclipse.jgit.lib._
import org.eclipse.jgit.transport._
@@ -9,21 +12,19 @@ import org.slf4j.LoggerFactory
import javax.servlet.ServletConfig
import javax.servlet.ServletContext
import javax.servlet.http.{HttpServletResponse, HttpServletRequest}
import util.{StringUtil, Keys, JGitUtil, Directory}
import util.ControlUtil._
import util.Implicits._
import service._
import gitbucket.core.util.StringUtil
import gitbucket.core.util.ControlUtil._
import gitbucket.core.util.Implicits._
import WebHookService._
import org.eclipse.jgit.api.Git
import util.JGitUtil.CommitInfo
import service.IssuesService.IssueSearchCondition
import model.Session
import JGitUtil.CommitInfo
import IssuesService.IssueSearchCondition
/**
* Provides Git repository via HTTP.
*
* This servlet provides only Git repository functionality.
* Authentication is provided by [[servlet.BasicAuthenticationFilter]].
* Authentication is provided by [[BasicAuthenticationFilter]].
*/
class GitRepositoryServlet extends GitServlet with SystemSettingsService {

View File

@@ -1,17 +1,19 @@
package servlet
package gitbucket.core.servlet
import java.io.File
import java.sql.{DriverManager, Connection}
import gitbucket.core.plugin.PluginRegistry
import gitbucket.core.util._
import org.apache.commons.io.FileUtils
import javax.servlet.{ServletContextListener, ServletContextEvent}
import org.slf4j.LoggerFactory
import util.Directory._
import util.ControlUtil._
import util.JDBCUtil._
import Directory._
import ControlUtil._
import JDBCUtil._
import org.eclipse.jgit.api.Git
import util.{Version, Versions}
import plugin._
import util.{DatabaseConfig, Directory}
import gitbucket.core.util.Versions
import gitbucket.core.util.Directory
import gitbucket.core.plugin._
object AutoUpdate {
@@ -19,7 +21,8 @@ object AutoUpdate {
* The history of versions. A head of this sequence is the current BitBucket version.
*/
val versions = Seq(
new Version(2, 9),
// TODO(tanacasino): Add 3.1 migration
new Version(3, 0),
new Version(2, 8),
new Version(2, 7) {
override def update(conn: Connection, cl: ClassLoader): Unit = {

View File

@@ -1,8 +1,9 @@
package servlet
package gitbucket.core.servlet
import javax.servlet.http.{HttpSessionEvent, HttpSessionListener}
import gitbucket.core.util.Directory
import org.apache.commons.io.FileUtils
import util.Directory._
import Directory._
/**
* Removes session associated temporary files when session is destroyed.

View File

@@ -1,11 +1,12 @@
package servlet
package gitbucket.core.servlet
import javax.servlet._
import javax.servlet.http.HttpServletRequest
import com.mchange.v2.c3p0.ComboPooledDataSource
import gitbucket.core.util.DatabaseConfig
import org.slf4j.LoggerFactory
import slick.jdbc.JdbcBackend.{Database => SlickDatabase, Session}
import util.{DatabaseConfig, Keys}
import gitbucket.core.util.Keys
/**
* Controls the transaction with the open session in view pattern.

View File

@@ -1,17 +1,18 @@
package ssh
package gitbucket.core.ssh
import gitbucket.core.model.Session
import gitbucket.core.service.{RepositoryService, AccountService, SystemSettingsService}
import gitbucket.core.servlet.{Database, CommitLogHook}
import gitbucket.core.util.{Directory, ControlUtil}
import org.apache.sshd.server.{CommandFactory, Environment, ExitCallback, Command}
import org.slf4j.LoggerFactory
import java.io.{InputStream, OutputStream}
import util.ControlUtil._
import ControlUtil._
import org.eclipse.jgit.api.Git
import util.Directory._
import Directory._
import org.eclipse.jgit.transport.{ReceivePack, UploadPack}
import org.apache.sshd.server.command.UnknownCommand
import servlet.{Database, CommitLogHook}
import service.{AccountService, RepositoryService, SystemSettingsService}
import org.eclipse.jgit.errors.RepositoryNotFoundException
import model.Session
object GitCommand {
val CommandRegex = """\Agit-(upload|receive)-pack '/([a-zA-Z0-9\-_.]+)/([a-zA-Z0-9\-_.]+).git'\Z""".r

View File

@@ -1,10 +1,10 @@
package ssh
package gitbucket.core.ssh
import gitbucket.core.service.SystemSettingsService
import org.apache.sshd.common.Factory
import org.apache.sshd.server.{Environment, ExitCallback, Command}
import java.io.{OutputStream, InputStream}
import org.eclipse.jgit.lib.Constants
import service.SystemSettingsService
class NoShell extends Factory[Command] with SystemSettingsService {
override def create(): Command = new Command() {

View File

@@ -1,10 +1,10 @@
package ssh
package gitbucket.core.ssh
import gitbucket.core.service.SshKeyService
import gitbucket.core.servlet.Database
import org.apache.sshd.server.PublickeyAuthenticator
import org.apache.sshd.server.session.ServerSession
import java.security.PublicKey
import service.SshKeyService
import servlet.Database
class PublicKeyAuthenticator extends PublickeyAuthenticator with SshKeyService {

View File

@@ -1,10 +1,10 @@
package ssh
package gitbucket.core.ssh
import javax.servlet.{ServletContextEvent, ServletContextListener}
import gitbucket.core.service.SystemSettingsService
import gitbucket.core.util.Directory
import org.apache.sshd.server.keyprovider.SimpleGeneratorHostKeyProvider
import org.slf4j.LoggerFactory
import util.Directory
import service.SystemSettingsService
import java.util.concurrent.atomic.AtomicBoolean
object SshServer {

View File

@@ -1,4 +1,4 @@
package ssh
package gitbucket.core.ssh
import java.security.PublicKey
import org.slf4j.LoggerFactory

View File

@@ -1,10 +1,10 @@
package util
package gitbucket.core.util
import app.ControllerBase
import service._
import gitbucket.core.controller.ControllerBase
import gitbucket.core.service.{RepositoryService, AccountService}
import RepositoryService.RepositoryInfo
import util.Implicits._
import util.ControlUtil._
import Implicits._
import ControlUtil._
/**
* Allows only oneself and administrators.

View File

@@ -1,4 +1,4 @@
package util
package gitbucket.core.util
import org.eclipse.jgit.api.Git
import org.eclipse.jgit.revwalk.RevWalk

View File

@@ -1,7 +1,7 @@
package util
package gitbucket.core.util
import com.typesafe.config.ConfigFactory
import util.Directory.DatabaseHome
import Directory.DatabaseHome
object DatabaseConfig {

View File

@@ -1,7 +1,7 @@
package util
package gitbucket.core.util
import java.io.File
import util.ControlUtil._
import ControlUtil._
import org.apache.commons.io.FileUtils
/**

View File

@@ -1,9 +1,9 @@
package util
package gitbucket.core.util
import org.apache.commons.io.FileUtils
import java.net.URLConnection
import java.io.File
import util.ControlUtil._
import ControlUtil._
import scala.util.Random
object FileUtil {

View File

@@ -1,10 +1,15 @@
package util
package gitbucket.core.util
import gitbucket.core.controller.Context
import gitbucket.core.servlet.Database
import javax.servlet.http.{HttpSession, HttpServletRequest}
import scala.util.matching.Regex
import scala.util.control.Exception._
import slick.jdbc.JdbcBackend
import servlet.Database
import javax.servlet.http.{HttpSession, HttpServletRequest}
/**
* Provides some usable implicit conversions.
@@ -14,7 +19,7 @@ object Implicits {
// Convert to slick session.
implicit def request2Session(implicit request: HttpServletRequest): JdbcBackend#Session = Database.getSession(request)
implicit def context2ApiJsonFormatContext(implicit context: app.Context): api.JsonFormat.Context = api.JsonFormat.Context(context.baseUrl)
implicit def context2ApiJsonFormatContext(implicit context: Context): api.JsonFormat.Context = api.JsonFormat.Context(context.baseUrl)
implicit class RichSeq[A](seq: Seq[A]) {

View File

@@ -1,7 +1,7 @@
package util
package gitbucket.core.util
import java.sql._
import util.ControlUtil._
import ControlUtil._
import scala.collection.mutable.ListBuffer
/**

View File

@@ -1,9 +1,10 @@
package util
package gitbucket.core.util
import gitbucket.core.service.RepositoryService
import org.eclipse.jgit.api.Git
import util.Directory._
import util.StringUtil._
import util.ControlUtil._
import Directory._
import StringUtil._
import ControlUtil._
import scala.annotation.tailrec
import scala.collection.JavaConverters._
import org.eclipse.jgit.lib._
@@ -16,7 +17,6 @@ import org.eclipse.jgit.errors.{ConfigInvalidException, MissingObjectException}
import org.eclipse.jgit.transport.RefSpec
import java.util.Date
import org.eclipse.jgit.api.errors.{JGitInternalException, InvalidRefNameException, RefAlreadyExistsException, NoHeadException}
import service.RepositoryService
import org.eclipse.jgit.dircache.DirCacheEntry
import org.slf4j.LoggerFactory
@@ -176,7 +176,7 @@ object JGitUtil {
git.tagList.call.asScala.map { ref =>
val revCommit = getRevCommitFromId(git, ref.getObjectId)
TagInfo(ref.getName.stripPrefix("refs/tags/"), revCommit.getCommitterIdent.getWhen, revCommit.getName)
}.toList
}.sortBy(_.time).toList
)
} catch {
// not initialized

View File

@@ -1,4 +1,4 @@
package util
package gitbucket.core.util
/**
* Define key strings for request attributes, session attributes or flash attributes.

View File

@@ -1,13 +1,13 @@
package util
package gitbucket.core.util
import util.ControlUtil._
import service.SystemSettingsService
import gitbucket.core.model.Account
import ControlUtil._
import gitbucket.core.service.SystemSettingsService
import gitbucket.core.service.SystemSettingsService.Ldap
import com.novell.ldap._
import java.security.Security
import org.slf4j.LoggerFactory
import service.SystemSettingsService.Ldap
import scala.annotation.tailrec
import model.Account
/**
* Utility for LDAP authentication.

View File

@@ -1,8 +1,8 @@
package util
package gitbucket.core.util
import java.util.concurrent.ConcurrentHashMap
import java.util.concurrent.locks.{ReentrantLock, Lock}
import util.ControlUtil._
import ControlUtil._
object LockUtil {

View File

@@ -1,22 +1,24 @@
package util
package gitbucket.core.util
import gitbucket.core.model.{Session, Issue}
import gitbucket.core.service.{RepositoryService, AccountService, IssuesService, SystemSettingsService}
import gitbucket.core.servlet.Database
import gitbucket.core.view.Markdown
import scala.concurrent._
import ExecutionContext.Implicits.global
import org.apache.commons.mail.{DefaultAuthenticator, HtmlEmail}
import org.slf4j.LoggerFactory
import app.Context
import model.Session
import service.{AccountService, RepositoryService, IssuesService, SystemSettingsService}
import servlet.Database
import gitbucket.core.controller.Context
import SystemSettingsService.Smtp
import _root_.util.ControlUtil.defining
import ControlUtil.defining
trait Notifier extends RepositoryService with AccountService with IssuesService {
def toNotify(r: RepositoryService.RepositoryInfo, issueId: Int, content: String)
(msg: String => String)(implicit context: Context): Unit
protected def recipients(issue: model.Issue)(notify: String => Unit)(implicit session: Session, context: Context) =
protected def recipients(issue: Issue)(notify: String => Unit)(implicit session: Session, context: Context) =
(
// individual repository's owner
issue.userName ::
@@ -74,7 +76,7 @@ class Mailer(private val smtp: Smtp) extends Notifier {
getIssue(r.owner, r.name, issueId.toString) foreach { issue =>
defining(
s"[${r.name}] ${issue.title} (#${issueId})" ->
msg(view.Markdown.toHtml(content, r, false, true))) { case (subject, msg) =>
msg(Markdown.toHtml(content, r, false, true))) { case (subject, msg) =>
recipients(issue) { to =>
val email = new HtmlEmail
email.setHostName(smtp.host)

View File

@@ -0,0 +1,18 @@
package gitbucket.core.util
case class RepositoryName(owner:String, name:String){
val fullName = s"${owner}/${name}"
}
object RepositoryName{
def apply(fullName: String): RepositoryName = {
fullName.split("/").toList match {
case owner :: name :: Nil => RepositoryName(owner, name)
case _ => throw new IllegalArgumentException(s"${fullName} is not repositoryName (only 'owner/name')")
}
}
def apply(repository: gitbucket.core.model.Repository): RepositoryName = RepositoryName(repository.userName, repository.repositoryName)
def apply(repository: gitbucket.core.util.JGitUtil.RepositoryInfo): RepositoryName = RepositoryName(repository.owner, repository.name)
def apply(repository: gitbucket.core.service.RepositoryService.RepositoryInfo): RepositoryName = RepositoryName(repository.owner, repository.name)
def apply(repository: gitbucket.core.model.CommitStatus): RepositoryName = RepositoryName(repository.userName, repository.repositoryName)
}

Some files were not shown because too many files have changed in this diff Show More