mirror of
https://github.com/gitbucket/gitbucket.git
synced 2025-11-07 14:05:52 +01:00
(refs #1823) Link submodule to the online repository viewer
Supports following services: - GitBucket (need to set the base url at the system settings) - GitHub - BitBucket - GitLab.com If a repository url doesn't match above services, generate a link to the git repository as before.
This commit is contained in:
@@ -841,7 +841,7 @@ trait RepositoryViewerControllerBase extends ControllerBase {
|
|||||||
defining(JGitUtil.getRevCommitFromId(git, objectId)) { revCommit =>
|
defining(JGitUtil.getRevCommitFromId(git, objectId)) { revCommit =>
|
||||||
val lastModifiedCommit = if(path == ".") revCommit else JGitUtil.getLastModifiedCommit(git, revCommit, path)
|
val lastModifiedCommit = if(path == ".") revCommit else JGitUtil.getLastModifiedCommit(git, revCommit, path)
|
||||||
// get files
|
// get files
|
||||||
val files = JGitUtil.getFileList(git, revision, path)
|
val files = JGitUtil.getFileList(git, revision, path, context.settings.baseUrl)
|
||||||
val parentPath = if (path == ".") Nil else path.split("/").toList
|
val parentPath = if (path == ".") Nil else path.split("/").toList
|
||||||
// process README.md or README.markdown
|
// process README.md or README.markdown
|
||||||
val readme = files.find { file =>
|
val readme = files.find { file =>
|
||||||
|
|||||||
@@ -151,9 +151,10 @@ object JGitUtil {
|
|||||||
*
|
*
|
||||||
* @param name the module name
|
* @param name the module name
|
||||||
* @param path the path in the repository
|
* @param path the path in the repository
|
||||||
* @param url the repository url of this module
|
* @param repositoryUrl the repository url of this module
|
||||||
|
* @param viewerUrl the repository viewer url of this module
|
||||||
*/
|
*/
|
||||||
case class SubmoduleInfo(name: String, path: String, url: String)
|
case class SubmoduleInfo(name: String, path: String, repositoryUrl: String, viewerUrl: String)
|
||||||
|
|
||||||
case class BranchMergeInfo(ahead: Int, behind: Int, isMerged: Boolean)
|
case class BranchMergeInfo(ahead: Int, behind: Int, isMerged: Boolean)
|
||||||
|
|
||||||
@@ -252,9 +253,10 @@ object JGitUtil {
|
|||||||
* @param git the Git object
|
* @param git the Git object
|
||||||
* @param revision the branch name or commit id
|
* @param revision the branch name or commit id
|
||||||
* @param path the directory path (optional)
|
* @param path the directory path (optional)
|
||||||
|
* @param baseUrl the base url of GitBucket instance. This parameter is used to generate links of submodules (optional)
|
||||||
* @return HTML of the file list
|
* @return HTML of the file list
|
||||||
*/
|
*/
|
||||||
def getFileList(git: Git, revision: String, path: String = "."): List[FileInfo] = {
|
def getFileList(git: Git, revision: String, path: String = ".", baseUrl: Option[String] = None): List[FileInfo] = {
|
||||||
using(new RevWalk(git.getRepository)){ revWalk =>
|
using(new RevWalk(git.getRepository)){ revWalk =>
|
||||||
val objectId = git.getRepository.resolve(revision)
|
val objectId = git.getRepository.resolve(revision)
|
||||||
if(objectId == null) return Nil
|
if(objectId == null) return Nil
|
||||||
@@ -340,7 +342,7 @@ object JGitUtil {
|
|||||||
useTreeWalk(revCommit){ treeWalk =>
|
useTreeWalk(revCommit){ treeWalk =>
|
||||||
while (treeWalk.next()) {
|
while (treeWalk.next()) {
|
||||||
val linkUrl = if (treeWalk.getFileMode(0) == FileMode.GITLINK) {
|
val linkUrl = if (treeWalk.getFileMode(0) == FileMode.GITLINK) {
|
||||||
getSubmodules(git, revCommit.getTree).find(_.path == treeWalk.getPathString).map(_.url)
|
getSubmodules(git, revCommit.getTree, baseUrl).find(_.path == treeWalk.getPathString).map(_.viewerUrl)
|
||||||
} else None
|
} else None
|
||||||
fileList +:= (treeWalk.getObjectId(0), treeWalk.getFileMode(0), treeWalk.getNameString, treeWalk.getPathString, linkUrl)
|
fileList +:= (treeWalk.getObjectId(0), treeWalk.getFileMode(0), treeWalk.getNameString, treeWalk.getPathString, linkUrl)
|
||||||
}
|
}
|
||||||
@@ -730,7 +732,7 @@ object JGitUtil {
|
|||||||
/**
|
/**
|
||||||
* Read submodule information from .gitmodules
|
* Read submodule information from .gitmodules
|
||||||
*/
|
*/
|
||||||
def getSubmodules(git: Git, tree: RevTree): List[SubmoduleInfo] = {
|
def getSubmodules(git: Git, tree: RevTree, baseUrl: Option[String]): List[SubmoduleInfo] = {
|
||||||
val repository = git.getRepository
|
val repository = git.getRepository
|
||||||
getContentFromPath(git, tree, ".gitmodules", true).map { bytes =>
|
getContentFromPath(git, tree, ".gitmodules", true).map { bytes =>
|
||||||
(try {
|
(try {
|
||||||
@@ -738,7 +740,7 @@ object JGitUtil {
|
|||||||
config.getSubsections("submodule").asScala.map { module =>
|
config.getSubsections("submodule").asScala.map { module =>
|
||||||
val path = config.getString("submodule", module, "path")
|
val path = config.getString("submodule", module, "path")
|
||||||
val url = config.getString("submodule", module, "url")
|
val url = config.getString("submodule", module, "url")
|
||||||
SubmoduleInfo(module, path, url)
|
SubmoduleInfo(module, path, url, StringUtil.getRepositoryViewerUrl(url, baseUrl))
|
||||||
}
|
}
|
||||||
} catch {
|
} catch {
|
||||||
case e: ConfigInvalidException => {
|
case e: ConfigInvalidException => {
|
||||||
|
|||||||
@@ -123,17 +123,22 @@ object StringUtil {
|
|||||||
"(?i)(?<!\\w)(?:fix(?:e[sd])?|resolve[sd]?|close[sd]?)\\s+#(\\d+)(?!\\w)".r
|
"(?i)(?<!\\w)(?:fix(?:e[sd])?|resolve[sd]?|close[sd]?)\\s+#(\\d+)(?!\\w)".r
|
||||||
.findAllIn(message).matchData.map(_.group(1)).toSeq.distinct
|
.findAllIn(message).matchData.map(_.group(1)).toSeq.distinct
|
||||||
|
|
||||||
|
private val GitBucketUrlPattern = "^(https?://.+)/git/(.+?)/(.+?)\\.git$".r
|
||||||
|
private val GitHubUrlPattern = "^https://(.+@)?github\\.com/(.+?)/(.+?)\\.git$".r
|
||||||
|
private val BitBucketUrlPattern = "^https?://(.+@)?bitbucket\\.org/(.+?)/(.+?)\\.git$".r
|
||||||
|
private val GitLabUrlPattern = "^https?://(.+@)?gitlab\\.com/(.+?)/(.+?)\\.git$".r
|
||||||
|
|
||||||
|
def getRepositoryViewerUrl(gitRepositoryUrl: String, baseUrl: Option[String]): String = {
|
||||||
|
def removeUserName(baseUrl: String): String = baseUrl.replaceFirst("(https?://).+@", "$1")
|
||||||
|
|
||||||
|
gitRepositoryUrl match {
|
||||||
|
case GitBucketUrlPattern(base, user, repository) if baseUrl.map(removeUserName(base).startsWith).getOrElse(false)
|
||||||
|
=> s"${removeUserName(base)}/$user/$repository"
|
||||||
|
case GitHubUrlPattern (_, user, repository) => s"https://github.com/$user/$repository"
|
||||||
|
case BitBucketUrlPattern(_, user, repository) => s"https://bitbucket.org/$user/$repository"
|
||||||
|
case GitLabUrlPattern (_, user, repository) => s"https://gitlab.com/$user/$repository"
|
||||||
|
case _ => gitRepositoryUrl
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// /**
|
|
||||||
// * Encode search string for LIKE condition.
|
|
||||||
// * This method has been copied from Slick's SqlUtilsComponent.
|
|
||||||
// */
|
|
||||||
// def likeEncode(s: String) = {
|
|
||||||
// val b = new StringBuilder
|
|
||||||
// for(c <- s) c match {
|
|
||||||
// case '%' | '_' | '^' => b append '^' append c
|
|
||||||
// case _ => b append c
|
|
||||||
// }
|
|
||||||
// b.toString
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -63,4 +63,24 @@ class StringUtilSpec extends FunSpec {
|
|||||||
assert(StringUtil.extractCloseId("(refs #123)").toSeq == Nil)
|
assert(StringUtil.extractCloseId("(refs #123)").toSeq == Nil)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
describe("getRepositoryViewerUrl") {
|
||||||
|
val baseUrl = Some("http://localhost:8080")
|
||||||
|
it("should convert GitBucket repository url"){
|
||||||
|
assert(StringUtil.getRepositoryViewerUrl("http://localhost:8080/git/root/gitbucket.git", baseUrl) == "http://localhost:8080/root/gitbucket")
|
||||||
|
assert(StringUtil.getRepositoryViewerUrl("http://root@localhost:8080/git/root/gitbucket.git", baseUrl) == "http://localhost:8080/root/gitbucket")
|
||||||
|
}
|
||||||
|
it("should convert GitHub repository url"){
|
||||||
|
assert(StringUtil.getRepositoryViewerUrl("https://github.com/root/gitbucket.git", baseUrl) == "https://github.com/root/gitbucket")
|
||||||
|
assert(StringUtil.getRepositoryViewerUrl("https://root@github.com/root/gitbucket.git", baseUrl) == "https://github.com/root/gitbucket")
|
||||||
|
}
|
||||||
|
it("should convert BitBucket repository url"){
|
||||||
|
assert(StringUtil.getRepositoryViewerUrl("https://bitbucket.org/root/gitbucket.git", baseUrl) == "https://bitbucket.org/root/gitbucket")
|
||||||
|
assert(StringUtil.getRepositoryViewerUrl("https://root@bitbucket.org/root/gitbucket.git", baseUrl) == "https://bitbucket.org/root/gitbucket")
|
||||||
|
}
|
||||||
|
it("should convert GitLab repository url"){
|
||||||
|
assert(StringUtil.getRepositoryViewerUrl("https://gitlab.com/root/gitbucket.git", baseUrl) == "https://gitlab.com/root/gitbucket")
|
||||||
|
assert(StringUtil.getRepositoryViewerUrl("https://root@gitlab.com/root/gitbucket.git", baseUrl) == "https://gitlab.com/root/gitbucket")
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user