mirror of
https://github.com/gitbucket/gitbucket.git
synced 2026-05-09 04:26:32 +02:00
Compare commits
42 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e4266f31a6 | ||
|
|
0405fccb69 | ||
|
|
9a41adcec8 | ||
|
|
1d54920165 | ||
|
|
7ace37cd07 | ||
|
|
eb6398654d | ||
|
|
10a4c3e2a4 | ||
|
|
d494014011 | ||
|
|
91bf562b91 | ||
|
|
ec3961555f | ||
|
|
33b46869b6 | ||
|
|
88db21ef07 | ||
|
|
d53948f4a9 | ||
|
|
f97992a776 | ||
|
|
f9d99703cb | ||
|
|
b015cdde74 | ||
|
|
92b35bd458 | ||
|
|
3c8026f135 | ||
|
|
6a3f51a784 | ||
|
|
160c4a8a72 | ||
|
|
c4ff760bda | ||
|
|
aaed8f595a | ||
|
|
3c0a2e8385 | ||
|
|
0eef0f9aa5 | ||
|
|
169e2f16fb | ||
|
|
3800391a0e | ||
|
|
1f564808d5 | ||
|
|
433639dd04 | ||
|
|
f1e4116672 | ||
|
|
6cf00c5c66 | ||
|
|
71248cd9b7 | ||
|
|
841e6d110c | ||
|
|
f7defffeab | ||
|
|
13e6f5f6cf | ||
|
|
130cbf0b24 | ||
|
|
642d85b6bf | ||
|
|
8fe7f85e1a | ||
|
|
d1fb794783 | ||
|
|
e7aedb405a | ||
|
|
9dc148dace | ||
|
|
8ad0b25023 | ||
|
|
f648d60abb |
6
.github/ISSUE_TEMPLATE.md
vendored
6
.github/ISSUE_TEMPLATE.md
vendored
@@ -1,8 +1,8 @@
|
|||||||
### Before submitting an issue to GitBucket I have first:
|
### Before submitting an issue to GitBucket I have first:
|
||||||
|
|
||||||
- [] read the [contribution guidelines](https://github.com/gitbucket/gitbucket/blob/master/.github/CONTRIBUTING.md)
|
- [ ] read the [contribution guidelines](https://github.com/gitbucket/gitbucket/blob/master/.github/CONTRIBUTING.md)
|
||||||
- [] searched for similar already existing issue
|
- [ ] searched for similar already existing issue
|
||||||
- [] read the documentation and [wiki](https://github.com/gitbucket/gitbucket/wiki)
|
- [ ] read the documentation and [wiki](https://github.com/gitbucket/gitbucket/wiki)
|
||||||
|
|
||||||
*(if you have performed all the above, remove the paragraph and continue describing the issue with template below)*
|
*(if you have performed all the above, remove the paragraph and continue describing the issue with template below)*
|
||||||
|
|
||||||
|
|||||||
12
.github/PULL_REQUEST_TEMPLATE.md
vendored
12
.github/PULL_REQUEST_TEMPLATE.md
vendored
@@ -1,8 +1,8 @@
|
|||||||
### Before submitting a pull-request to GitBucket I have first:
|
### Before submitting a pull-request to GitBucket I have first:
|
||||||
|
|
||||||
- [] read the [contribution guidelines](https://github.com/gitbucket/gitbucket/blob/master/.github/CONTRIBUTING.md)
|
- [ ] read the [contribution guidelines](https://github.com/gitbucket/gitbucket/blob/master/.github/CONTRIBUTING.md)
|
||||||
- [] rebased my branch over master
|
- [ ] rebased my branch over master
|
||||||
- [] verified that project is compiling
|
- [ ] verified that project is compiling
|
||||||
- [] verified that tests are passing
|
- [ ] verified that tests are passing
|
||||||
- [] squashed my commits as appropriate *(keep several commits if it is relevant to understand the PR)*
|
- [ ] squashed my commits as appropriate *(keep several commits if it is relevant to understand the PR)*
|
||||||
- [] [marked as closed using commit message](https://help.github.com/articles/closing-issues-via-commit-messages/) all issue ID that this PR should correct
|
- [ ] [marked as closed using commit message](https://help.github.com/articles/closing-issues-via-commit-messages/) all issue ID that this PR should correct
|
||||||
|
|||||||
4
.gitignore
vendored
4
.gitignore
vendored
@@ -24,3 +24,7 @@ project/plugins/project/
|
|||||||
.idea/
|
.idea/
|
||||||
.idea_modules/
|
.idea_modules/
|
||||||
*.iml
|
*.iml
|
||||||
|
|
||||||
|
# Metals specific
|
||||||
|
.metals
|
||||||
|
.bloop
|
||||||
@@ -1,8 +1,6 @@
|
|||||||
language: scala
|
language: scala
|
||||||
sudo: true
|
sudo: true
|
||||||
jdk:
|
jdk:
|
||||||
- oraclejdk8
|
|
||||||
- oraclejdk11
|
|
||||||
- openjdk8
|
- openjdk8
|
||||||
- openjdk11
|
- openjdk11
|
||||||
script:
|
script:
|
||||||
|
|||||||
12
CHANGELOG.md
12
CHANGELOG.md
@@ -1,6 +1,18 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
All changes to the project will be documented in this file.
|
All changes to the project will be documented in this file.
|
||||||
|
|
||||||
|
### 4.32.0 - 7 Aug 2019
|
||||||
|
|
||||||
|
- Bump to Scala 2.13.0 and Scalatra 2.7.0
|
||||||
|
- Draft pull request
|
||||||
|
- Drop network installation of plugins
|
||||||
|
- Compare view works for commit id
|
||||||
|
- Apply default priority to pull requests
|
||||||
|
- Focus title after clicking issue / pull request edit button
|
||||||
|
|
||||||
|
### 4.31.2 - 7 Apr 2019
|
||||||
|
- Bug and security fix
|
||||||
|
|
||||||
### 4.31.1 - 17 Mar 2019
|
### 4.31.1 - 17 Mar 2019
|
||||||
- Bug fix
|
- Bug fix
|
||||||
|
|
||||||
|
|||||||
19
README.md
19
README.md
@@ -22,7 +22,7 @@ The current version of GitBucket provides many features such as:
|
|||||||
- Account and group management with LDAP integration
|
- Account and group management with LDAP integration
|
||||||
- a Plug-in system
|
- a Plug-in system
|
||||||
|
|
||||||
If you want to try the development version of GitBucket, see the [Developer's Guide](https://github.com/gitbucket/gitbucket/blob/master/doc/how_to_run.md).
|
If you want to try the development version of GitBucket, see the [Developer's Guide](https://github.com/gitbucket/gitbucket/blob/master/doc/readme.md).
|
||||||
|
|
||||||
Installation
|
Installation
|
||||||
--------
|
--------
|
||||||
@@ -68,16 +68,15 @@ Support
|
|||||||
- If you can't find same question and report, send it to [gitter room](https://gitter.im/gitbucket/gitbucket) before raising an issue.
|
- If you can't find same question and report, send it to [gitter room](https://gitter.im/gitbucket/gitbucket) before raising an issue.
|
||||||
- The highest priority of GitBucket is the ease of installation and API compatibility with GitHub, so your feature request might be rejected if they go against those principles.
|
- The highest priority of GitBucket is the ease of installation and API compatibility with GitHub, so your feature request might be rejected if they go against those principles.
|
||||||
|
|
||||||
What's New in 4.31.x
|
What's New in 4.32.x
|
||||||
-------------
|
-------------
|
||||||
### 4.31.1 - 17 Mar 2019
|
### 4.32.0 - 7 Aug 2019
|
||||||
- Bug fix
|
|
||||||
|
|
||||||
### 4.31.0 - 17 Mar 2019
|
- Bump to Scala 2.13.0 and Scalatra 2.7.0
|
||||||
- Docker support in CI plugin
|
- Draft pull request
|
||||||
- Verify GPG key signed commit
|
- Drop network installation of plugins
|
||||||
- OAuth2 Token (sent as a parameter) authentication support and new APIs in Web API
|
- Compare view works for commit id
|
||||||
- OGP (Open Graph protocol) support
|
- Apply default priority to pull requests
|
||||||
- Username completion with avatars
|
- Focus title after clicking issue / pull request edit button
|
||||||
|
|
||||||
See the [change log](CHANGELOG.md) for all of the updates.
|
See the [change log](CHANGELOG.md) for all of the updates.
|
||||||
|
|||||||
54
build.sbt
54
build.sbt
@@ -3,10 +3,10 @@ import com.typesafe.sbt.pgp.PgpKeys._
|
|||||||
|
|
||||||
val Organization = "io.github.gitbucket"
|
val Organization = "io.github.gitbucket"
|
||||||
val Name = "gitbucket"
|
val Name = "gitbucket"
|
||||||
val GitBucketVersion = "4.31.1"
|
val GitBucketVersion = "4.32.0"
|
||||||
val ScalatraVersion = "2.6.3"
|
val ScalatraVersion = "2.7.0-RC1"
|
||||||
val JettyVersion = "9.4.14.v20181114"
|
val JettyVersion = "9.4.19.v20190610"
|
||||||
val JgitVersion = "5.2.0.201812061821-r"
|
val JgitVersion = "5.4.0.201906121030-r"
|
||||||
|
|
||||||
lazy val root = (project in file("."))
|
lazy val root = (project in file("."))
|
||||||
.enablePlugins(SbtTwirl, ScalatraPlugin)
|
.enablePlugins(SbtTwirl, ScalatraPlugin)
|
||||||
@@ -17,7 +17,7 @@ sourcesInBase := false
|
|||||||
organization := Organization
|
organization := Organization
|
||||||
name := Name
|
name := Name
|
||||||
version := GitBucketVersion
|
version := GitBucketVersion
|
||||||
scalaVersion := "2.12.8"
|
scalaVersion := "2.13.0"
|
||||||
|
|
||||||
scalafmtOnCompile := true
|
scalafmtOnCompile := true
|
||||||
|
|
||||||
@@ -38,28 +38,28 @@ libraryDependencies ++= Seq(
|
|||||||
"org.scalatra" %% "scalatra" % ScalatraVersion,
|
"org.scalatra" %% "scalatra" % ScalatraVersion,
|
||||||
"org.scalatra" %% "scalatra-json" % ScalatraVersion,
|
"org.scalatra" %% "scalatra-json" % ScalatraVersion,
|
||||||
"org.scalatra" %% "scalatra-forms" % ScalatraVersion,
|
"org.scalatra" %% "scalatra-forms" % ScalatraVersion,
|
||||||
"org.json4s" %% "json4s-jackson" % "3.5.2",
|
"org.json4s" %% "json4s-jackson" % "3.6.7",
|
||||||
"commons-io" % "commons-io" % "2.6",
|
"commons-io" % "commons-io" % "2.6",
|
||||||
"io.github.gitbucket" % "solidbase" % "1.0.3",
|
"io.github.gitbucket" % "solidbase" % "1.0.3",
|
||||||
"io.github.gitbucket" % "markedj" % "1.0.15",
|
"io.github.gitbucket" % "markedj" % "1.0.16",
|
||||||
"org.apache.commons" % "commons-compress" % "1.18",
|
"org.apache.commons" % "commons-compress" % "1.18",
|
||||||
"org.apache.commons" % "commons-email" % "1.5",
|
"org.apache.commons" % "commons-email" % "1.5",
|
||||||
"org.apache.httpcomponents" % "httpclient" % "4.5.6",
|
"org.apache.httpcomponents" % "httpclient" % "4.5.9",
|
||||||
"org.apache.sshd" % "apache-sshd" % "2.1.0" exclude ("org.slf4j", "slf4j-jdk14") exclude ("org.apache.sshd", "sshd-mina") exclude ("org.apache.sshd", "sshd-netty"),
|
"org.apache.sshd" % "apache-sshd" % "2.1.0" exclude ("org.slf4j", "slf4j-jdk14") exclude ("org.apache.sshd", "sshd-mina") exclude ("org.apache.sshd", "sshd-netty"),
|
||||||
"org.apache.tika" % "tika-core" % "1.19.1",
|
"org.apache.tika" % "tika-core" % "1.22",
|
||||||
"com.github.takezoe" %% "blocking-slick-32" % "0.0.11",
|
"com.github.takezoe" %% "blocking-slick-32" % "0.0.12",
|
||||||
"com.novell.ldap" % "jldap" % "2009-10-07",
|
"com.novell.ldap" % "jldap" % "2009-10-07",
|
||||||
"com.h2database" % "h2" % "1.4.197",
|
"com.h2database" % "h2" % "1.4.199",
|
||||||
"org.mariadb.jdbc" % "mariadb-java-client" % "2.3.0",
|
"org.mariadb.jdbc" % "mariadb-java-client" % "2.4.3",
|
||||||
"org.postgresql" % "postgresql" % "42.2.5",
|
"org.postgresql" % "postgresql" % "42.2.6",
|
||||||
"ch.qos.logback" % "logback-classic" % "1.2.3",
|
"ch.qos.logback" % "logback-classic" % "1.2.3",
|
||||||
"com.zaxxer" % "HikariCP" % "3.2.0",
|
"com.zaxxer" % "HikariCP" % "3.3.1",
|
||||||
"com.typesafe" % "config" % "1.3.3",
|
"com.typesafe" % "config" % "1.3.4",
|
||||||
"com.typesafe.akka" %% "akka-actor" % "2.5.18",
|
"com.typesafe.akka" %% "akka-actor" % "2.5.23",
|
||||||
"fr.brouillard.oss.security.xhub" % "xhub4j-core" % "1.0.0",
|
"fr.brouillard.oss.security.xhub" % "xhub4j-core" % "1.1.0",
|
||||||
"com.github.bkromhout" % "java-diff-utils" % "2.1.1",
|
"com.github.bkromhout" % "java-diff-utils" % "2.1.1",
|
||||||
"org.cache2k" % "cache2k-all" % "1.2.0.Final",
|
"org.cache2k" % "cache2k-all" % "1.2.2.Final",
|
||||||
"com.enragedginger" %% "akka-quartz-scheduler" % "1.7.0-akka-2.5.x" exclude ("c3p0", "c3p0") exclude ("com.zaxxer", "HikariCP-java6"),
|
"com.enragedginger" %% "akka-quartz-scheduler" % "1.8.1-akka-2.5.x" exclude ("com.mchange", "c3p0") exclude ("com.zaxxer", "HikariCP-java6"),
|
||||||
"net.coobird" % "thumbnailator" % "0.4.8",
|
"net.coobird" % "thumbnailator" % "0.4.8",
|
||||||
"com.github.zafarkhaja" % "java-semver" % "0.9.0",
|
"com.github.zafarkhaja" % "java-semver" % "0.9.0",
|
||||||
"com.nimbusds" % "oauth2-oidc-sdk" % "5.64.4",
|
"com.nimbusds" % "oauth2-oidc-sdk" % "5.64.4",
|
||||||
@@ -67,17 +67,17 @@ libraryDependencies ++= Seq(
|
|||||||
"javax.servlet" % "javax.servlet-api" % "3.1.0" % "provided",
|
"javax.servlet" % "javax.servlet-api" % "3.1.0" % "provided",
|
||||||
"junit" % "junit" % "4.12" % "test",
|
"junit" % "junit" % "4.12" % "test",
|
||||||
"org.scalatra" %% "scalatra-scalatest" % ScalatraVersion % "test",
|
"org.scalatra" %% "scalatra-scalatest" % ScalatraVersion % "test",
|
||||||
"org.mockito" % "mockito-core" % "2.23.4" % "test",
|
"org.mockito" % "mockito-core" % "3.0.0" % "test",
|
||||||
"com.dimafeng" %% "testcontainers-scala" % "0.22.0" % "test",
|
"com.dimafeng" %% "testcontainers-scala" % "0.29.0" % "test",
|
||||||
"org.testcontainers" % "mysql" % "1.10.3" % "test",
|
"org.testcontainers" % "mysql" % "1.12.0" % "test",
|
||||||
"org.testcontainers" % "postgresql" % "1.10.3" % "test",
|
"org.testcontainers" % "postgresql" % "1.12.0" % "test",
|
||||||
"net.i2p.crypto" % "eddsa" % "0.3.0",
|
"net.i2p.crypto" % "eddsa" % "0.3.0",
|
||||||
"is.tagomor.woothee" % "woothee-java" % "1.8.0",
|
"is.tagomor.woothee" % "woothee-java" % "1.10.1",
|
||||||
"org.ec4j.core" % "ec4j-core" % "0.0.3"
|
"org.ec4j.core" % "ec4j-core" % "0.0.3"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Compiler settings
|
// Compiler settings
|
||||||
scalacOptions := Seq("-deprecation", "-language:postfixOps", "-opt:l:method", "-Xfuture")
|
scalacOptions := Seq("-deprecation", "-language:postfixOps", "-opt:l:method")
|
||||||
javacOptions in compile ++= Seq("-target", "8", "-source", "8")
|
javacOptions in compile ++= Seq("-target", "8", "-source", "8")
|
||||||
javaOptions in Jetty += "-Dlogback.configurationFile=/logback-dev.xml"
|
javaOptions in Jetty += "-Dlogback.configurationFile=/logback-dev.xml"
|
||||||
|
|
||||||
@@ -165,8 +165,8 @@ executableKey := {
|
|||||||
plugins.foreach { plugin =>
|
plugins.foreach { plugin =>
|
||||||
plugin.trim.split(":") match {
|
plugin.trim.split(":") match {
|
||||||
case Array(pluginId, pluginVersion) =>
|
case Array(pluginId, pluginVersion) =>
|
||||||
val url = "https://plugins.gitbucket-community.org/releases/" +
|
val url = "https://github.com/" +
|
||||||
s"gitbucket-${pluginId}-plugin/gitbucket-${pluginId}-plugin-gitbucket_${version.value}-${pluginVersion}.jar"
|
s"gitbucket/gitbucket-${pluginId}-plugin/releases/download/${pluginVersion}/gitbucket-${pluginId}-plugin-${pluginVersion}.jar"
|
||||||
log info s"Download: ${url}"
|
log info s"Download: ${url}"
|
||||||
IO transfer (new java.net.URL(url).openStream, pluginsDir / url.substring(url.lastIndexOf("/") + 1))
|
IO transfer (new java.net.URL(url).openStream, pluginsDir / url.substring(url.lastIndexOf("/") + 1))
|
||||||
case _ => ()
|
case _ => ()
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ To build war file, run the following command:
|
|||||||
$ sbt package
|
$ sbt package
|
||||||
```
|
```
|
||||||
|
|
||||||
`gitbucket_2.12-x.x.x.war` is generated into `target/scala-2.12`.
|
`gitbucket_2.13-x.x.x.war` is generated into `target/scala-2.13`.
|
||||||
|
|
||||||
To build an executable war file, run
|
To build an executable war file, run
|
||||||
|
|
||||||
@@ -58,4 +58,4 @@ If you don't have docker, you can skip docker tests which require docker as foll
|
|||||||
|
|
||||||
```shell
|
```shell
|
||||||
$ sbt "testOnly * -- -l ExternalDBTest"
|
$ sbt "testOnly * -- -l ExternalDBTest"
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
sbt.version=1.2.6
|
sbt.version=1.2.8
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
scalacOptions ++= Seq("-unchecked", "-deprecation", "-feature")
|
scalacOptions ++= Seq("-unchecked", "-deprecation", "-feature")
|
||||||
|
|
||||||
addSbtPlugin("com.geirsson" % "sbt-scalafmt" % "1.5.0")
|
addSbtPlugin("com.geirsson" % "sbt-scalafmt" % "1.5.1")
|
||||||
addSbtPlugin("com.typesafe.sbt" % "sbt-twirl" % "1.3.15")
|
addSbtPlugin("com.typesafe.sbt" % "sbt-twirl" % "1.4.2")
|
||||||
addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.14.9")
|
addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.14.10")
|
||||||
addSbtPlugin("org.scalatra.sbt" % "sbt-scalatra" % "1.0.3")
|
addSbtPlugin("org.scalatra.sbt" % "sbt-scalatra" % "1.0.3")
|
||||||
addSbtPlugin("com.jsuereth" % "sbt-pgp" % "1.1.2")
|
addSbtPlugin("com.jsuereth" % "sbt-pgp" % "1.1.2")
|
||||||
addSbtPlugin("com.typesafe.sbt" % "sbt-license-report" % "1.2.0")
|
addSbtPlugin("com.typesafe.sbt" % "sbt-license-report" % "1.2.0")
|
||||||
addSbtPlugin("net.virtual-void" % "sbt-dependency-graph" % "0.9.2")
|
addSbtPlugin("net.virtual-void" % "sbt-dependency-graph" % "0.9.2")
|
||||||
addSbtPlugin("org.scoverage" % "sbt-scoverage" % "1.5.1")
|
addSbtPlugin("org.scoverage" % "sbt-scoverage" % "1.6.0")
|
||||||
|
|
||||||
addSbtCoursier
|
addSbtCoursier
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
addSbtPlugin("io.get-coursier" % "sbt-coursier" % "1.0.0")
|
addSbtPlugin("io.get-coursier" % "sbt-coursier" % "1.0.3")
|
||||||
|
|||||||
@@ -1 +1,4 @@
|
|||||||
notifications:1.7.0
|
notifications:1.8.0
|
||||||
|
gist:4.18.0
|
||||||
|
emoji:4.6.0
|
||||||
|
pages:1.8.0
|
||||||
|
|||||||
6
src/main/resources/update/gitbucket-core_4.32.xml
Normal file
6
src/main/resources/update/gitbucket-core_4.32.xml
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<changeSet>
|
||||||
|
<addColumn tableName="PULL_REQUEST">
|
||||||
|
<column name="IS_DRAFT" type="boolean" nullable="false" defaultValueBoolean="false" />
|
||||||
|
</addColumn>
|
||||||
|
</changeSet>
|
||||||
@@ -62,5 +62,7 @@ object GitBucketCoreModule
|
|||||||
new Version("4.30.0"),
|
new Version("4.30.0"),
|
||||||
new Version("4.30.1"),
|
new Version("4.30.1"),
|
||||||
new Version("4.31.0", new LiquibaseMigration("update/gitbucket-core_4.31.xml")),
|
new Version("4.31.0", new LiquibaseMigration("update/gitbucket-core_4.31.xml")),
|
||||||
new Version("4.31.1")
|
new Version("4.31.1"),
|
||||||
|
new Version("4.31.2"),
|
||||||
|
new Version("4.32.0", new LiquibaseMigration("update/gitbucket-core_4.32.xml"))
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ import java.io.File
|
|||||||
import gitbucket.core.account.html
|
import gitbucket.core.account.html
|
||||||
import gitbucket.core.helper
|
import gitbucket.core.helper
|
||||||
import gitbucket.core.model._
|
import gitbucket.core.model._
|
||||||
import gitbucket.core.plugin.PluginRegistry
|
|
||||||
import gitbucket.core.service._
|
import gitbucket.core.service._
|
||||||
import gitbucket.core.service.WebHookService._
|
import gitbucket.core.service.WebHookService._
|
||||||
import gitbucket.core.ssh.SshUtil
|
import gitbucket.core.ssh.SshUtil
|
||||||
@@ -347,7 +346,7 @@ trait AccountControllerBase extends AccountManagementControllerBase {
|
|||||||
|
|
||||||
updateImage(userName, form.fileId, form.clearImage)
|
updateImage(userName, form.fileId, form.clearImage)
|
||||||
updateAccountExtraMailAddresses(userName, form.extraMailAddresses.filter(_ != ""))
|
updateAccountExtraMailAddresses(userName, form.extraMailAddresses.filter(_ != ""))
|
||||||
flash += "info" -> "Account information has been updated."
|
flash.update("info", "Account information has been updated.")
|
||||||
redirect(s"/${userName}/_edit")
|
redirect(s"/${userName}/_edit")
|
||||||
|
|
||||||
} getOrElse NotFound()
|
} getOrElse NotFound()
|
||||||
@@ -359,7 +358,7 @@ trait AccountControllerBase extends AccountManagementControllerBase {
|
|||||||
getAccountByUserName(userName, true).map {
|
getAccountByUserName(userName, true).map {
|
||||||
account =>
|
account =>
|
||||||
if (isLastAdministrator(account)) {
|
if (isLastAdministrator(account)) {
|
||||||
flash += "error" -> "Account can't be removed because this is last one administrator."
|
flash.update("error", "Account can't be removed because this is last one administrator.")
|
||||||
redirect(s"/${userName}/_edit")
|
redirect(s"/${userName}/_edit")
|
||||||
} else {
|
} else {
|
||||||
// // Remove repositories
|
// // Remove repositories
|
||||||
@@ -439,7 +438,7 @@ trait AccountControllerBase extends AccountManagementControllerBase {
|
|||||||
val userName = params("userName")
|
val userName = params("userName")
|
||||||
getAccountByUserName(userName).map { x =>
|
getAccountByUserName(userName).map { x =>
|
||||||
val (tokenId, token) = generateAccessToken(userName, form.note)
|
val (tokenId, token) = generateAccessToken(userName, form.note)
|
||||||
flash += "generatedToken" -> (tokenId, token)
|
flash.update("generatedToken", (tokenId, token))
|
||||||
}
|
}
|
||||||
redirect(s"/${userName}/_application")
|
redirect(s"/${userName}/_application")
|
||||||
})
|
})
|
||||||
@@ -475,7 +474,7 @@ trait AccountControllerBase extends AccountManagementControllerBase {
|
|||||||
post("/:userName/_hooks/new", accountWebHookForm(false))(managersOnly { form =>
|
post("/:userName/_hooks/new", accountWebHookForm(false))(managersOnly { form =>
|
||||||
val userName = params("userName")
|
val userName = params("userName")
|
||||||
addAccountWebHook(userName, form.url, form.events, form.ctype, form.token)
|
addAccountWebHook(userName, form.url, form.events, form.ctype, form.token)
|
||||||
flash += "info" -> s"Webhook ${form.url} created"
|
flash.update("info", s"Webhook ${form.url} created")
|
||||||
redirect(s"/${userName}/_hooks")
|
redirect(s"/${userName}/_hooks")
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -485,7 +484,7 @@ trait AccountControllerBase extends AccountManagementControllerBase {
|
|||||||
get("/:userName/_hooks/delete")(managersOnly {
|
get("/:userName/_hooks/delete")(managersOnly {
|
||||||
val userName = params("userName")
|
val userName = params("userName")
|
||||||
deleteAccountWebHook(userName, params("url"))
|
deleteAccountWebHook(userName, params("url"))
|
||||||
flash += "info" -> s"Webhook ${params("url")} deleted"
|
flash.update("info", s"Webhook ${params("url")} deleted")
|
||||||
redirect(s"/${userName}/_hooks")
|
redirect(s"/${userName}/_hooks")
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -508,7 +507,7 @@ trait AccountControllerBase extends AccountManagementControllerBase {
|
|||||||
post("/:userName/_hooks/edit", accountWebHookForm(true))(managersOnly { form =>
|
post("/:userName/_hooks/edit", accountWebHookForm(true))(managersOnly { form =>
|
||||||
val userName = params("userName")
|
val userName = params("userName")
|
||||||
updateAccountWebHook(userName, form.url, form.events, form.ctype, form.token)
|
updateAccountWebHook(userName, form.url, form.events, form.ctype, form.token)
|
||||||
flash += "info" -> s"webhook ${form.url} updated"
|
flash.update("info", s"webhook ${form.url} updated")
|
||||||
redirect(s"/${userName}/_hooks")
|
redirect(s"/${userName}/_hooks")
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -543,7 +542,7 @@ trait AccountControllerBase extends AccountManagementControllerBase {
|
|||||||
case e: java.net.UnknownHostException => Map("error" -> ("Unknown host " + e.getMessage))
|
case e: java.net.UnknownHostException => Map("error" -> ("Unknown host " + e.getMessage))
|
||||||
case e: java.lang.IllegalArgumentException => Map("error" -> ("invalid url"))
|
case e: java.lang.IllegalArgumentException => Map("error" -> ("invalid url"))
|
||||||
case e: org.apache.http.client.ClientProtocolException => Map("error" -> ("invalid url"))
|
case e: org.apache.http.client.ClientProtocolException => Map("error" -> ("invalid url"))
|
||||||
case NonFatal(e) => Map("error" -> (e.getClass + " " + e.getMessage))
|
case NonFatal(e) => Map("error" -> (s"${e.getClass} ${e.getMessage}"))
|
||||||
}
|
}
|
||||||
|
|
||||||
contentType = formats("json")
|
contentType = formats("json")
|
||||||
@@ -683,7 +682,7 @@ trait AccountControllerBase extends AccountManagementControllerBase {
|
|||||||
|
|
||||||
updateImage(form.groupName, form.fileId, form.clearImage)
|
updateImage(form.groupName, form.fileId, form.clearImage)
|
||||||
|
|
||||||
flash += "info" -> "Account information has been updated."
|
flash.update("info", "Account information has been updated.")
|
||||||
redirect(s"/${groupName}/_editgroup")
|
redirect(s"/${groupName}/_editgroup")
|
||||||
|
|
||||||
} getOrElse NotFound()
|
} getOrElse NotFound()
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ import javax.servlet.{FilterChain, ServletRequest, ServletResponse}
|
|||||||
import is.tagomor.woothee.Classifier
|
import is.tagomor.woothee.Classifier
|
||||||
|
|
||||||
import scala.util.Try
|
import scala.util.Try
|
||||||
|
import scala.util.Using
|
||||||
import net.coobird.thumbnailator.Thumbnails
|
import net.coobird.thumbnailator.Thumbnails
|
||||||
import org.eclipse.jgit.api.Git
|
import org.eclipse.jgit.api.Git
|
||||||
import org.eclipse.jgit.lib.ObjectId
|
import org.eclipse.jgit.lib.ObjectId
|
||||||
@@ -240,7 +241,7 @@ abstract class ControllerBase
|
|||||||
case false => None
|
case false => None
|
||||||
}
|
}
|
||||||
|
|
||||||
using(new TreeWalk(git.getRepository)) { treeWalk =>
|
Using.resource(new TreeWalk(git.getRepository)) { treeWalk =>
|
||||||
treeWalk.addTree(revCommit.getTree)
|
treeWalk.addTree(revCommit.getTree)
|
||||||
treeWalk.setRecursive(true)
|
treeWalk.setRecursive(true)
|
||||||
_getPathObjectId(path, treeWalk)
|
_getPathObjectId(path, treeWalk)
|
||||||
@@ -268,7 +269,7 @@ abstract class ControllerBase
|
|||||||
response.setContentLength(attrs("size").toInt)
|
response.setContentLength(attrs("size").toInt)
|
||||||
val oid = attrs("oid").split(":")(1)
|
val oid = attrs("oid").split(":")(1)
|
||||||
|
|
||||||
using(new FileInputStream(FileUtil.getLfsFilePath(repository.owner, repository.name, oid))) { in =>
|
Using.resource(new FileInputStream(FileUtil.getLfsFilePath(repository.owner, repository.name, oid))) { in =>
|
||||||
IOUtils.copy(in, response.getOutputStream)
|
IOUtils.copy(in, response.getOutputStream)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -324,6 +325,8 @@ case class Context(
|
|||||||
trait AccountManagementControllerBase extends ControllerBase {
|
trait AccountManagementControllerBase extends ControllerBase {
|
||||||
self: AccountService =>
|
self: AccountService =>
|
||||||
|
|
||||||
|
private val logger = LoggerFactory.getLogger(getClass)
|
||||||
|
|
||||||
protected def updateImage(userName: String, fileId: Option[String], clearImage: Boolean): Unit =
|
protected def updateImage(userName: String, fileId: Option[String], clearImage: Boolean): Unit =
|
||||||
if (clearImage) {
|
if (clearImage) {
|
||||||
getAccountByUserName(userName).flatMap(_.image).foreach { image =>
|
getAccountByUserName(userName).flatMap(_.image).foreach { image =>
|
||||||
@@ -331,17 +334,21 @@ trait AccountManagementControllerBase extends ControllerBase {
|
|||||||
updateAvatarImage(userName, None)
|
updateAvatarImage(userName, None)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
fileId.foreach { fileId =>
|
try {
|
||||||
val filename = "avatar." + FileUtil.getExtension(session.getAndRemove(Keys.Session.Upload(fileId)).get)
|
fileId.foreach { fileId =>
|
||||||
val uploadDir = getUserUploadDir(userName)
|
val filename = "avatar." + FileUtil.getExtension(session.getAndRemove(Keys.Session.Upload(fileId)).get)
|
||||||
if (!uploadDir.exists) {
|
val uploadDir = getUserUploadDir(userName)
|
||||||
uploadDir.mkdirs()
|
if (!uploadDir.exists) {
|
||||||
|
uploadDir.mkdirs()
|
||||||
|
}
|
||||||
|
Thumbnails
|
||||||
|
.of(new File(getTemporaryDir(session.getId), FileUtil.checkFilename(fileId)))
|
||||||
|
.size(324, 324)
|
||||||
|
.toFile(new File(uploadDir, FileUtil.checkFilename(filename)))
|
||||||
|
updateAvatarImage(userName, Some(filename))
|
||||||
}
|
}
|
||||||
Thumbnails
|
} catch {
|
||||||
.of(new File(getTemporaryDir(session.getId), FileUtil.checkFilename(fileId)))
|
case e: Exception => logger.info("Error while updateImage" + e.getMessage)
|
||||||
.size(324, 324)
|
|
||||||
.toFile(new File(uploadDir, FileUtil.checkFilename(filename)))
|
|
||||||
updateAvatarImage(userName, Some(filename))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -359,7 +366,7 @@ trait AccountManagementControllerBase extends ControllerBase {
|
|||||||
params: Map[String, Seq[String]],
|
params: Map[String, Seq[String]],
|
||||||
messages: Messages
|
messages: Messages
|
||||||
): Option[String] = {
|
): Option[String] = {
|
||||||
val extraMailAddresses = params.filterKeys(k => k.startsWith("extraMailAddresses"))
|
val extraMailAddresses = params.view.filterKeys(k => k.startsWith("extraMailAddresses"))
|
||||||
if (extraMailAddresses.exists {
|
if (extraMailAddresses.exists {
|
||||||
case (k, v) =>
|
case (k, v) =>
|
||||||
v.contains(value)
|
v.contains(value)
|
||||||
@@ -382,7 +389,7 @@ trait AccountManagementControllerBase extends ControllerBase {
|
|||||||
params: Map[String, Seq[String]],
|
params: Map[String, Seq[String]],
|
||||||
messages: Messages
|
messages: Messages
|
||||||
): Option[String] = {
|
): Option[String] = {
|
||||||
val extraMailAddresses = params.filterKeys(k => k.startsWith("extraMailAddresses"))
|
val extraMailAddresses = params.view.filterKeys(k => k.startsWith("extraMailAddresses"))
|
||||||
if (Some(value) == params.optionValue("mailAddress") || extraMailAddresses.count {
|
if (Some(value) == params.optionValue("mailAddress") || extraMailAddresses.count {
|
||||||
case (k, v) =>
|
case (k, v) =>
|
||||||
v.contains(value)
|
v.contains(value)
|
||||||
|
|||||||
@@ -16,6 +16,8 @@ import org.scalatra._
|
|||||||
import org.scalatra.servlet.{FileItem, FileUploadSupport, MultipartConfig}
|
import org.scalatra.servlet.{FileItem, FileUploadSupport, MultipartConfig}
|
||||||
import org.apache.commons.io.{FileUtils, IOUtils}
|
import org.apache.commons.io.{FileUtils, IOUtils}
|
||||||
|
|
||||||
|
import scala.util.Using
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides Ajax based file upload functionality.
|
* Provides Ajax based file upload functionality.
|
||||||
*
|
*
|
||||||
@@ -80,7 +82,7 @@ class FileUploadController
|
|||||||
{ (file, fileId) =>
|
{ (file, fileId) =>
|
||||||
val fileName = file.getName
|
val fileName = file.getName
|
||||||
LockUtil.lock(s"${owner}/${repository}/wiki") {
|
LockUtil.lock(s"${owner}/${repository}/wiki") {
|
||||||
using(Git.open(Directory.getWikiRepositoryDir(owner, repository))) {
|
Using.resource(Git.open(Directory.getWikiRepositoryDir(owner, repository))) {
|
||||||
git =>
|
git =>
|
||||||
val builder = DirCache.newInCore.builder()
|
val builder = DirCache.newInCore.builder()
|
||||||
val inserter = git.getRepository.newObjectInserter()
|
val inserter = git.getRepository.newObjectInserter()
|
||||||
|
|||||||
@@ -83,7 +83,7 @@ trait IndexControllerBase extends ControllerBase {
|
|||||||
get("/signin") {
|
get("/signin") {
|
||||||
val redirect = params.get("redirect")
|
val redirect = params.get("redirect")
|
||||||
if (redirect.isDefined && redirect.get.startsWith("/")) {
|
if (redirect.isDefined && redirect.get.startsWith("/")) {
|
||||||
flash += Keys.Flash.Redirect -> redirect.get
|
flash.update(Keys.Flash.Redirect, redirect.get)
|
||||||
}
|
}
|
||||||
gitbucket.core.html.signin(flash.get("userName"), flash.get("password"), flash.get("error"))
|
gitbucket.core.html.signin(flash.get("userName"), flash.get("password"), flash.get("error"))
|
||||||
}
|
}
|
||||||
@@ -96,9 +96,9 @@ trait IndexControllerBase extends ControllerBase {
|
|||||||
case _ => signin(account)
|
case _ => signin(account)
|
||||||
}
|
}
|
||||||
case None =>
|
case None =>
|
||||||
flash += "userName" -> form.userName
|
flash.update("userName", form.userName)
|
||||||
flash += "password" -> form.password
|
flash.update("password", form.password)
|
||||||
flash += "error" -> "Sorry, your Username and/or Password is incorrect. Please try again."
|
flash.update("error", "Sorry, your Username and/or Password is incorrect. Please try again.")
|
||||||
redirect("/signin")
|
redirect("/signin")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -132,15 +132,15 @@ trait IndexControllerBase extends ControllerBase {
|
|||||||
val redirectURI = new URI(s"$baseUrl/signin/oidc")
|
val redirectURI = new URI(s"$baseUrl/signin/oidc")
|
||||||
session.get(Keys.Session.OidcContext) match {
|
session.get(Keys.Session.OidcContext) match {
|
||||||
case Some(context: OidcContext) =>
|
case Some(context: OidcContext) =>
|
||||||
authenticate(params, redirectURI, context.state, context.nonce, oidc) map { account =>
|
authenticate(params.toMap, redirectURI, context.state, context.nonce, oidc).map { account =>
|
||||||
signin(account, context.redirectBackURI)
|
signin(account, context.redirectBackURI)
|
||||||
} orElse {
|
} orElse {
|
||||||
flash += "error" -> "Sorry, authentication failed. Please try again."
|
flash.update("error", "Sorry, authentication failed. Please try again.")
|
||||||
session.invalidate()
|
session.invalidate()
|
||||||
redirect("/signin")
|
redirect("/signin")
|
||||||
}
|
}
|
||||||
case _ =>
|
case _ =>
|
||||||
flash += "error" -> "Sorry, something wrong. Please try again."
|
flash.update("error", "Sorry, something wrong. Please try again.")
|
||||||
session.invalidate()
|
session.invalidate()
|
||||||
redirect("/signin")
|
redirect("/signin")
|
||||||
}
|
}
|
||||||
@@ -227,7 +227,7 @@ trait IndexControllerBase extends ControllerBase {
|
|||||||
} getOrElse ""
|
} getOrElse ""
|
||||||
})
|
})
|
||||||
|
|
||||||
// TODO Move to RepositoryViwerController?
|
// TODO Move to RepositoryViewrController?
|
||||||
get("/:owner/:repository/search")(referrersOnly { repository =>
|
get("/:owner/:repository/search")(referrersOnly { repository =>
|
||||||
defining(params.getOrElse("q", "").trim, params.getOrElse("type", "code")) {
|
defining(params.getOrElse("q", "").trim, params.getOrElse("type", "code")) {
|
||||||
case (query, target) =>
|
case (query, target) =>
|
||||||
|
|||||||
@@ -145,7 +145,7 @@ trait IssuesControllerBase extends ControllerBase {
|
|||||||
form.assignedUserName,
|
form.assignedUserName,
|
||||||
form.milestoneId,
|
form.milestoneId,
|
||||||
form.priorityId,
|
form.priorityId,
|
||||||
form.labelNames.toArray.flatMap(_.split(",")),
|
form.labelNames.toSeq.flatMap(_.split(",")),
|
||||||
context.loginAccount.get
|
context.loginAccount.get
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,12 @@
|
|||||||
package gitbucket.core.controller
|
package gitbucket.core.controller
|
||||||
|
|
||||||
import gitbucket.core.issues.milestones.html
|
import gitbucket.core.issues.milestones.html
|
||||||
import gitbucket.core.service.{RepositoryService, MilestonesService, AccountService}
|
import gitbucket.core.service.{AccountService, MilestonesService, RepositoryService}
|
||||||
import gitbucket.core.util.{ReferrerAuthenticator, WritableUsersAuthenticator}
|
|
||||||
import gitbucket.core.util.Implicits._
|
import gitbucket.core.util.Implicits._
|
||||||
|
import gitbucket.core.util.{ReferrerAuthenticator, WritableUsersAuthenticator}
|
||||||
|
import gitbucket.core.util.SyntaxSugars._
|
||||||
import org.scalatra.forms._
|
import org.scalatra.forms._
|
||||||
|
import org.scalatra.i18n.Messages
|
||||||
|
|
||||||
class MilestonesController
|
class MilestonesController
|
||||||
extends MilestonesControllerBase
|
extends MilestonesControllerBase
|
||||||
@@ -20,7 +22,7 @@ trait MilestonesControllerBase extends ControllerBase {
|
|||||||
case class MilestoneForm(title: String, description: Option[String], dueDate: Option[java.util.Date])
|
case class MilestoneForm(title: String, description: Option[String], dueDate: Option[java.util.Date])
|
||||||
|
|
||||||
val milestoneForm = mapping(
|
val milestoneForm = mapping(
|
||||||
"title" -> trim(label("Title", text(required, maxlength(100)))),
|
"title" -> trim(label("Title", text(required, maxlength(100), uniqueMilestone))),
|
||||||
"description" -> trim(label("Description", optional(text()))),
|
"description" -> trim(label("Description", optional(text()))),
|
||||||
"dueDate" -> trim(label("Due Date", optional(date())))
|
"dueDate" -> trim(label("Due Date", optional(date())))
|
||||||
)(MilestoneForm.apply)
|
)(MilestoneForm.apply)
|
||||||
@@ -86,4 +88,20 @@ trait MilestonesControllerBase extends ControllerBase {
|
|||||||
} getOrElse NotFound()
|
} getOrElse NotFound()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
private def uniqueMilestone: Constraint = new Constraint() {
|
||||||
|
override def validate(
|
||||||
|
name: String,
|
||||||
|
value: String,
|
||||||
|
params: Map[String, Seq[String]],
|
||||||
|
messages: Messages
|
||||||
|
): Option[String] = {
|
||||||
|
for {
|
||||||
|
owner <- params.optionValue("owner")
|
||||||
|
repository <- params.optionValue("repository")
|
||||||
|
_ <- getMilestones(owner, repository).find(_.title.equalsIgnoreCase(value))
|
||||||
|
} yield {
|
||||||
|
"Milestone already exists."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,5 @@
|
|||||||
package gitbucket.core.controller
|
package gitbucket.core.controller
|
||||||
|
|
||||||
import gitbucket.core.model.{CommitComment, CommitComments, IssueComment, WebHook}
|
|
||||||
import gitbucket.core.plugin.PluginRegistry
|
|
||||||
import gitbucket.core.pulls.html
|
import gitbucket.core.pulls.html
|
||||||
import gitbucket.core.service.CommitStatusService
|
import gitbucket.core.service.CommitStatusService
|
||||||
import gitbucket.core.service.MergeService
|
import gitbucket.core.service.MergeService
|
||||||
@@ -15,11 +13,9 @@ import gitbucket.core.util.Implicits._
|
|||||||
import gitbucket.core.util._
|
import gitbucket.core.util._
|
||||||
import org.scalatra.forms._
|
import org.scalatra.forms._
|
||||||
import org.eclipse.jgit.api.Git
|
import org.eclipse.jgit.api.Git
|
||||||
import org.eclipse.jgit.lib.{ObjectId, PersonIdent}
|
|
||||||
import org.eclipse.jgit.revwalk.RevWalk
|
|
||||||
import org.scalatra.BadRequest
|
import org.scalatra.BadRequest
|
||||||
|
|
||||||
import scala.collection.JavaConverters._
|
import scala.util.Using
|
||||||
|
|
||||||
class PullRequestsController
|
class PullRequestsController
|
||||||
extends PullRequestsControllerBase
|
extends PullRequestsControllerBase
|
||||||
@@ -69,6 +65,7 @@ trait PullRequestsControllerBase extends ControllerBase {
|
|||||||
"requestBranch" -> trim(text(required, maxlength(100))),
|
"requestBranch" -> trim(text(required, maxlength(100))),
|
||||||
"commitIdFrom" -> trim(text(required, maxlength(40))),
|
"commitIdFrom" -> trim(text(required, maxlength(40))),
|
||||||
"commitIdTo" -> trim(text(required, maxlength(40))),
|
"commitIdTo" -> trim(text(required, maxlength(40))),
|
||||||
|
"isDraft" -> trim(boolean(required)),
|
||||||
"assignedUserName" -> trim(optional(text())),
|
"assignedUserName" -> trim(optional(text())),
|
||||||
"milestoneId" -> trim(optional(number())),
|
"milestoneId" -> trim(optional(number())),
|
||||||
"priorityId" -> trim(optional(number())),
|
"priorityId" -> trim(optional(number())),
|
||||||
@@ -77,7 +74,8 @@ trait PullRequestsControllerBase extends ControllerBase {
|
|||||||
|
|
||||||
val mergeForm = mapping(
|
val mergeForm = mapping(
|
||||||
"message" -> trim(label("Message", text(required))),
|
"message" -> trim(label("Message", text(required))),
|
||||||
"strategy" -> trim(label("Strategy", text(required)))
|
"strategy" -> trim(label("Strategy", text(required))),
|
||||||
|
"isDraft" -> trim(boolean(required))
|
||||||
)(MergeForm.apply)
|
)(MergeForm.apply)
|
||||||
|
|
||||||
case class PullRequestForm(
|
case class PullRequestForm(
|
||||||
@@ -90,13 +88,14 @@ trait PullRequestsControllerBase extends ControllerBase {
|
|||||||
requestBranch: String,
|
requestBranch: String,
|
||||||
commitIdFrom: String,
|
commitIdFrom: String,
|
||||||
commitIdTo: String,
|
commitIdTo: String,
|
||||||
|
isDraft: Boolean,
|
||||||
assignedUserName: Option[String],
|
assignedUserName: Option[String],
|
||||||
milestoneId: Option[Int],
|
milestoneId: Option[Int],
|
||||||
priorityId: Option[Int],
|
priorityId: Option[Int],
|
||||||
labelNames: Option[String]
|
labelNames: Option[String]
|
||||||
)
|
)
|
||||||
|
|
||||||
case class MergeForm(message: String, strategy: String)
|
case class MergeForm(message: String, strategy: String, isDraft: Boolean)
|
||||||
|
|
||||||
get("/:owner/:repository/pulls")(referrersOnly { repository =>
|
get("/:owner/:repository/pulls")(referrersOnly { repository =>
|
||||||
val q = request.getParameter("q")
|
val q = request.getParameter("q")
|
||||||
@@ -133,7 +132,7 @@ trait PullRequestsControllerBase extends ControllerBase {
|
|||||||
hasDeveloperRole(pullreq.requestUserName, pullreq.requestRepositoryName, context.loginAccount),
|
hasDeveloperRole(pullreq.requestUserName, pullreq.requestRepositoryName, context.loginAccount),
|
||||||
repository,
|
repository,
|
||||||
getRepository(pullreq.requestUserName, pullreq.requestRepositoryName),
|
getRepository(pullreq.requestUserName, pullreq.requestRepositoryName),
|
||||||
flash.toMap.map(f => f._1 -> f._2.toString)
|
flash.iterator.map(f => f._1 -> f._2.toString).toMap
|
||||||
)
|
)
|
||||||
|
|
||||||
// html.pullreq(
|
// html.pullreq(
|
||||||
@@ -266,11 +265,11 @@ trait PullRequestsControllerBase extends ControllerBase {
|
|||||||
val repository = getRepository(owner, name).get
|
val repository = getRepository(owner, name).get
|
||||||
val branchProtection = getProtectedBranchInfo(owner, name, pullreq.requestBranch)
|
val branchProtection = getProtectedBranchInfo(owner, name, pullreq.requestBranch)
|
||||||
if (branchProtection.enabled) {
|
if (branchProtection.enabled) {
|
||||||
flash += "error" -> s"branch ${pullreq.requestBranch} is protected."
|
flash.update("error", s"branch ${pullreq.requestBranch} is protected.")
|
||||||
} else {
|
} else {
|
||||||
if (repository.repository.defaultBranch != pullreq.requestBranch) {
|
if (repository.repository.defaultBranch != pullreq.requestBranch) {
|
||||||
val userName = context.loginAccount.get.userName
|
val userName = context.loginAccount.get.userName
|
||||||
using(Git.open(getRepositoryDir(repository.owner, repository.name))) { git =>
|
Using.resource(Git.open(getRepositoryDir(repository.owner, repository.name))) { git =>
|
||||||
git.branchDelete().setForce(true).setBranchNames(pullreq.requestBranch).call()
|
git.branchDelete().setForce(true).setBranchNames(pullreq.requestBranch).call()
|
||||||
recordDeleteBranchActivity(repository.owner, repository.name, userName, pullreq.requestBranch)
|
recordDeleteBranchActivity(repository.owner, repository.name, userName, pullreq.requestBranch)
|
||||||
}
|
}
|
||||||
@@ -283,9 +282,10 @@ trait PullRequestsControllerBase extends ControllerBase {
|
|||||||
"delete_branch"
|
"delete_branch"
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
flash += "error" -> s"""Can't delete the default branch "${pullreq.requestBranch}"."""
|
flash.update("error", s"""Can't delete the default branch "${pullreq.requestBranch}".""")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
redirect(s"/${baseRepository.owner}/${baseRepository.name}/pull/${issueId}")
|
redirect(s"/${baseRepository.owner}/${baseRepository.name}/pull/${issueId}")
|
||||||
}) getOrElse NotFound()
|
}) getOrElse NotFound()
|
||||||
})
|
})
|
||||||
@@ -303,7 +303,7 @@ trait PullRequestsControllerBase extends ControllerBase {
|
|||||||
} yield {
|
} yield {
|
||||||
val branchProtection = getProtectedBranchInfo(owner, name, pullreq.requestBranch)
|
val branchProtection = getProtectedBranchInfo(owner, name, pullreq.requestBranch)
|
||||||
if (branchProtection.needStatusCheck(loginAccount.userName)) {
|
if (branchProtection.needStatusCheck(loginAccount.userName)) {
|
||||||
flash += "error" -> s"branch ${pullreq.requestBranch} is protected need status check."
|
flash.update("error", s"branch ${pullreq.requestBranch} is protected need status check.")
|
||||||
} else {
|
} else {
|
||||||
LockUtil.lock(s"${owner}/${name}") {
|
LockUtil.lock(s"${owner}/${name}") {
|
||||||
val alias =
|
val alias =
|
||||||
@@ -312,9 +312,11 @@ trait PullRequestsControllerBase extends ControllerBase {
|
|||||||
} else {
|
} else {
|
||||||
s"${pullreq.userName}:${pullreq.branch}"
|
s"${pullreq.userName}:${pullreq.branch}"
|
||||||
}
|
}
|
||||||
val existIds = using(Git.open(Directory.getRepositoryDir(owner, name))) { git =>
|
val existIds = Using
|
||||||
JGitUtil.getAllCommitIds(git)
|
.resource(Git.open(Directory.getRepositoryDir(owner, name))) { git =>
|
||||||
}.toSet
|
JGitUtil.getAllCommitIds(git)
|
||||||
|
}
|
||||||
|
.toSet
|
||||||
pullRemote(
|
pullRemote(
|
||||||
repository,
|
repository,
|
||||||
pullreq.requestBranch,
|
pullreq.requestBranch,
|
||||||
@@ -325,11 +327,11 @@ trait PullRequestsControllerBase extends ControllerBase {
|
|||||||
Some(pullreq)
|
Some(pullreq)
|
||||||
) match {
|
) match {
|
||||||
case None => // conflict
|
case None => // conflict
|
||||||
flash += "error" -> s"Can't automatic merging branch '${alias}' into ${pullreq.requestBranch}."
|
flash.update("error", s"Can't automatic merging branch '${alias}' into ${pullreq.requestBranch}.")
|
||||||
case Some(oldId) =>
|
case Some(oldId) =>
|
||||||
// update pull request
|
// update pull request
|
||||||
updatePullRequests(owner, name, pullreq.requestBranch, loginAccount, "synchronize")
|
updatePullRequests(owner, name, pullreq.requestBranch, loginAccount, "synchronize")
|
||||||
flash += "info" -> s"Merge branch '${alias}' into ${pullreq.requestBranch}"
|
flash.update("info", s"Merge branch '${alias}' into ${pullreq.requestBranch}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -338,14 +340,26 @@ trait PullRequestsControllerBase extends ControllerBase {
|
|||||||
}) getOrElse NotFound()
|
}) getOrElse NotFound()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
post("/:owner/:repository/pull/:id/update_draft")(readableUsersOnly { baseRepository =>
|
||||||
|
(for {
|
||||||
|
issueId <- params("id").toIntOpt
|
||||||
|
(_, pullreq) <- getPullRequest(baseRepository.owner, baseRepository.name, issueId)
|
||||||
|
owner = pullreq.requestUserName
|
||||||
|
name = pullreq.requestRepositoryName
|
||||||
|
if hasDeveloperRole(owner, name, context.loginAccount)
|
||||||
|
} yield {
|
||||||
|
updateDraftToPullRequest(baseRepository.owner, baseRepository.name, issueId)
|
||||||
|
}) getOrElse NotFound()
|
||||||
|
})
|
||||||
|
|
||||||
post("/:owner/:repository/pull/:id/merge", mergeForm)(writableUsersOnly { (form, repository) =>
|
post("/:owner/:repository/pull/:id/merge", mergeForm)(writableUsersOnly { (form, repository) =>
|
||||||
params("id").toIntOpt.flatMap { issueId =>
|
params("id").toIntOpt.flatMap { issueId =>
|
||||||
val owner = repository.owner
|
val owner = repository.owner
|
||||||
val name = repository.name
|
val name = repository.name
|
||||||
|
|
||||||
mergePullRequest(repository, issueId, context.loginAccount.get, form.message, form.strategy) match {
|
mergePullRequest(repository, issueId, context.loginAccount.get, form.message, form.strategy, form.isDraft) match {
|
||||||
case Right(objectId) => redirect(s"/${owner}/${name}/pull/${issueId}")
|
case Right(objectId) => redirect(s"/${owner}/${name}/pull/${issueId}")
|
||||||
case Left(message) => Some(BadRequest())
|
case Left(message) => Some(BadRequest(message))
|
||||||
}
|
}
|
||||||
} getOrElse NotFound()
|
} getOrElse NotFound()
|
||||||
})
|
})
|
||||||
@@ -356,7 +370,7 @@ trait PullRequestsControllerBase extends ControllerBase {
|
|||||||
case (Some(originUserName), Some(originRepositoryName)) => {
|
case (Some(originUserName), Some(originRepositoryName)) => {
|
||||||
getRepository(originUserName, originRepositoryName).map {
|
getRepository(originUserName, originRepositoryName).map {
|
||||||
originRepository =>
|
originRepository =>
|
||||||
using(
|
Using.resources(
|
||||||
Git.open(getRepositoryDir(originUserName, originRepositoryName)),
|
Git.open(getRepositoryDir(originUserName, originRepositoryName)),
|
||||||
Git.open(getRepositoryDir(forkedRepository.owner, forkedRepository.name))
|
Git.open(getRepositoryDir(forkedRepository.owner, forkedRepository.name))
|
||||||
) { (oldGit, newGit) =>
|
) { (oldGit, newGit) =>
|
||||||
@@ -372,7 +386,7 @@ trait PullRequestsControllerBase extends ControllerBase {
|
|||||||
} getOrElse NotFound()
|
} getOrElse NotFound()
|
||||||
}
|
}
|
||||||
case _ => {
|
case _ => {
|
||||||
using(Git.open(getRepositoryDir(forkedRepository.owner, forkedRepository.name))) { git =>
|
Using.resource(Git.open(getRepositoryDir(forkedRepository.owner, forkedRepository.name))) { git =>
|
||||||
JGitUtil.getDefaultBranch(git, forkedRepository).map {
|
JGitUtil.getDefaultBranch(git, forkedRepository).map {
|
||||||
case (_, defaultBranch) =>
|
case (_, defaultBranch) =>
|
||||||
redirect(
|
redirect(
|
||||||
@@ -464,6 +478,7 @@ trait PullRequestsControllerBase extends ControllerBase {
|
|||||||
getAssignableUserNames(originRepository.owner, originRepository.name),
|
getAssignableUserNames(originRepository.owner, originRepository.name),
|
||||||
getMilestones(originRepository.owner, originRepository.name),
|
getMilestones(originRepository.owner, originRepository.name),
|
||||||
getPriorities(originRepository.owner, originRepository.name),
|
getPriorities(originRepository.owner, originRepository.name),
|
||||||
|
getDefaultPriority(originRepository.owner, originRepository.name),
|
||||||
getLabels(originRepository.owner, originRepository.name)
|
getLabels(originRepository.owner, originRepository.name)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -493,7 +508,7 @@ trait PullRequestsControllerBase extends ControllerBase {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
originRepository <- getRepository(originOwner, originRepositoryName)) yield {
|
originRepository <- getRepository(originOwner, originRepositoryName)) yield {
|
||||||
using(
|
Using.resources(
|
||||||
Git.open(getRepositoryDir(originRepository.owner, originRepository.name)),
|
Git.open(getRepositoryDir(originRepository.owner, originRepository.name)),
|
||||||
Git.open(getRepositoryDir(forkedRepository.owner, forkedRepository.name))
|
Git.open(getRepositoryDir(forkedRepository.owner, forkedRepository.name))
|
||||||
) {
|
) {
|
||||||
@@ -542,6 +557,7 @@ trait PullRequestsControllerBase extends ControllerBase {
|
|||||||
requestBranch = form.requestBranch,
|
requestBranch = form.requestBranch,
|
||||||
commitIdFrom = form.commitIdFrom,
|
commitIdFrom = form.commitIdFrom,
|
||||||
commitIdTo = form.commitIdTo,
|
commitIdTo = form.commitIdTo,
|
||||||
|
isDraft = form.isDraft,
|
||||||
loginAccount = context.loginAccount.get
|
loginAccount = context.loginAccount.get
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -567,7 +583,7 @@ trait PullRequestsControllerBase extends ControllerBase {
|
|||||||
context.loginAccount.map(x => Seq(x.mailAddress) ++ getAccountExtraMailAddresses(x.userName)).getOrElse(Nil)
|
context.loginAccount.map(x => Seq(x.mailAddress) ++ getAccountExtraMailAddresses(x.userName)).getOrElse(Nil)
|
||||||
|
|
||||||
val branches =
|
val branches =
|
||||||
using(Git.open(getRepositoryDir(repository.owner, repository.name))) {
|
Using.resource(Git.open(getRepositoryDir(repository.owner, repository.name))) {
|
||||||
git =>
|
git =>
|
||||||
JGitUtil
|
JGitUtil
|
||||||
.getBranches(
|
.getBranches(
|
||||||
|
|||||||
@@ -8,9 +8,9 @@ import gitbucket.core.util.Directory._
|
|||||||
import gitbucket.core.util.Implicits._
|
import gitbucket.core.util.Implicits._
|
||||||
import org.scalatra.forms._
|
import org.scalatra.forms._
|
||||||
import gitbucket.core.releases.html
|
import gitbucket.core.releases.html
|
||||||
import gitbucket.core.util.SyntaxSugars.using
|
|
||||||
import org.apache.commons.io.FileUtils
|
import org.apache.commons.io.FileUtils
|
||||||
import org.eclipse.jgit.api.Git
|
import org.eclipse.jgit.api.Git
|
||||||
|
import scala.util.Using
|
||||||
|
|
||||||
class ReleaseController
|
class ReleaseController
|
||||||
extends ReleaseControllerBase
|
extends ReleaseControllerBase
|
||||||
@@ -106,7 +106,7 @@ trait ReleaseControllerBase extends ControllerBase {
|
|||||||
createRelease(repository.owner, repository.name, form.name, form.content, tagName, loginAccount)
|
createRelease(repository.owner, repository.name, form.name, form.content, tagName, loginAccount)
|
||||||
|
|
||||||
// Insert into RELEASE_ASSET
|
// Insert into RELEASE_ASSET
|
||||||
val files = params.collect {
|
val files = params.toMap.collect {
|
||||||
case (name, value) if name.startsWith("file:") =>
|
case (name, value) if name.startsWith("file:") =>
|
||||||
val Array(_, fileId) = name.split(":")
|
val Array(_, fileId) = name.split(":")
|
||||||
(fileId, value)
|
(fileId, value)
|
||||||
@@ -130,7 +130,7 @@ trait ReleaseControllerBase extends ControllerBase {
|
|||||||
val Seq(previousTag, currentTag) = multiParams("splat")
|
val Seq(previousTag, currentTag) = multiParams("splat")
|
||||||
val previousTagId = repository.tags.collectFirst { case x if x.name == previousTag => x.id }.getOrElse("")
|
val previousTagId = repository.tags.collectFirst { case x if x.name == previousTag => x.id }.getOrElse("")
|
||||||
|
|
||||||
val commitLog = using(Git.open(getRepositoryDir(repository.owner, repository.name))) { git =>
|
val commitLog = Using.resource(Git.open(getRepositoryDir(repository.owner, repository.name))) { git =>
|
||||||
val commits = JGitUtil.getCommitLog(git, previousTagId, currentTag).reverse
|
val commits = JGitUtil.getCommitLog(git, previousTagId, currentTag).reverse
|
||||||
commits
|
commits
|
||||||
.map { commit =>
|
.map { commit =>
|
||||||
@@ -174,7 +174,7 @@ trait ReleaseControllerBase extends ControllerBase {
|
|||||||
val assets = getReleaseAssets(repository.owner, repository.name, tagName)
|
val assets = getReleaseAssets(repository.owner, repository.name, tagName)
|
||||||
deleteReleaseAssets(repository.owner, repository.name, tagName)
|
deleteReleaseAssets(repository.owner, repository.name, tagName)
|
||||||
|
|
||||||
val files = params.collect {
|
val files = params.toMap.collect {
|
||||||
case (name, value) if name.startsWith("file:") =>
|
case (name, value) if name.startsWith("file:") =>
|
||||||
val Array(_, fileId) = name.split(":")
|
val Array(_, fileId) = name.split(":")
|
||||||
(fileId, value)
|
(fileId, value)
|
||||||
|
|||||||
@@ -12,12 +12,14 @@ import gitbucket.core.util.JGitUtil._
|
|||||||
import gitbucket.core.util.SyntaxSugars._
|
import gitbucket.core.util.SyntaxSugars._
|
||||||
import gitbucket.core.util.Implicits._
|
import gitbucket.core.util.Implicits._
|
||||||
import gitbucket.core.util.Directory._
|
import gitbucket.core.util.Directory._
|
||||||
|
import gitbucket.core.model.WebHookContentType
|
||||||
import org.scalatra.forms._
|
import org.scalatra.forms._
|
||||||
import org.scalatra.i18n.Messages
|
import org.scalatra.i18n.Messages
|
||||||
import org.eclipse.jgit.api.Git
|
import org.eclipse.jgit.api.Git
|
||||||
import org.eclipse.jgit.lib.Constants
|
import org.eclipse.jgit.lib.Constants
|
||||||
import org.eclipse.jgit.lib.ObjectId
|
import org.eclipse.jgit.lib.ObjectId
|
||||||
import gitbucket.core.model.WebHookContentType
|
|
||||||
|
import scala.util.Using
|
||||||
|
|
||||||
class RepositorySettingsController
|
class RepositorySettingsController
|
||||||
extends RepositorySettingsControllerBase
|
extends RepositorySettingsControllerBase
|
||||||
@@ -147,7 +149,7 @@ trait RepositorySettingsControllerBase extends ControllerBase {
|
|||||||
// Update database
|
// Update database
|
||||||
renameRepository(repository.owner, repository.name, repository.owner, form.repositoryName)
|
renameRepository(repository.owner, repository.name, repository.owner, form.repositoryName)
|
||||||
}
|
}
|
||||||
flash += "info" -> "Repository settings has been updated."
|
flash.update("info", "Repository settings has been updated.")
|
||||||
redirect(s"/${repository.owner}/${form.repositoryName}/settings/options")
|
redirect(s"/${repository.owner}/${form.repositoryName}/settings/options")
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -164,10 +166,10 @@ trait RepositorySettingsControllerBase extends ControllerBase {
|
|||||||
} else {
|
} else {
|
||||||
saveRepositoryDefaultBranch(repository.owner, repository.name, form.defaultBranch)
|
saveRepositoryDefaultBranch(repository.owner, repository.name, form.defaultBranch)
|
||||||
// Change repository HEAD
|
// Change repository HEAD
|
||||||
using(Git.open(getRepositoryDir(repository.owner, repository.name))) { git =>
|
Using.resource(Git.open(getRepositoryDir(repository.owner, repository.name))) { git =>
|
||||||
git.getRepository.updateRef(Constants.HEAD, true).link(Constants.R_HEADS + form.defaultBranch)
|
git.getRepository.updateRef(Constants.HEAD, true).link(Constants.R_HEADS + form.defaultBranch)
|
||||||
}
|
}
|
||||||
flash += "info" -> "Repository default branch has been updated."
|
flash.update("info", "Repository default branch has been updated.")
|
||||||
redirect(s"/${repository.owner}/${repository.name}/settings/branches")
|
redirect(s"/${repository.owner}/${repository.name}/settings/branches")
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -231,7 +233,7 @@ trait RepositorySettingsControllerBase extends ControllerBase {
|
|||||||
*/
|
*/
|
||||||
post("/:owner/:repository/settings/hooks/new", webHookForm(false))(ownerOnly { (form, repository) =>
|
post("/:owner/:repository/settings/hooks/new", webHookForm(false))(ownerOnly { (form, repository) =>
|
||||||
addWebHook(repository.owner, repository.name, form.url, form.events, form.ctype, form.token)
|
addWebHook(repository.owner, repository.name, form.url, form.events, form.ctype, form.token)
|
||||||
flash += "info" -> s"Webhook ${form.url} created"
|
flash.update("info", s"Webhook ${form.url} created")
|
||||||
redirect(s"/${repository.owner}/${repository.name}/settings/hooks")
|
redirect(s"/${repository.owner}/${repository.name}/settings/hooks")
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -240,7 +242,7 @@ trait RepositorySettingsControllerBase extends ControllerBase {
|
|||||||
*/
|
*/
|
||||||
get("/:owner/:repository/settings/hooks/delete")(ownerOnly { repository =>
|
get("/:owner/:repository/settings/hooks/delete")(ownerOnly { repository =>
|
||||||
deleteWebHook(repository.owner, repository.name, params("url"))
|
deleteWebHook(repository.owner, repository.name, params("url"))
|
||||||
flash += "info" -> s"Webhook ${params("url")} deleted"
|
flash.update("info", s"Webhook ${params("url")} deleted")
|
||||||
redirect(s"/${repository.owner}/${repository.name}/settings/hooks")
|
redirect(s"/${repository.owner}/${repository.name}/settings/hooks")
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -252,11 +254,11 @@ trait RepositorySettingsControllerBase extends ControllerBase {
|
|||||||
Array(h.getName, h.getValue)
|
Array(h.getName, h.getValue)
|
||||||
}
|
}
|
||||||
|
|
||||||
using(Git.open(getRepositoryDir(repository.owner, repository.name))) {
|
Using.resource(Git.open(getRepositoryDir(repository.owner, repository.name))) {
|
||||||
git =>
|
git =>
|
||||||
import scala.collection.JavaConverters._
|
|
||||||
import scala.concurrent.duration._
|
import scala.concurrent.duration._
|
||||||
import scala.concurrent._
|
import scala.concurrent._
|
||||||
|
import scala.jdk.CollectionConverters._
|
||||||
import scala.util.control.NonFatal
|
import scala.util.control.NonFatal
|
||||||
import org.apache.http.util.EntityUtils
|
import org.apache.http.util.EntityUtils
|
||||||
import scala.concurrent.ExecutionContext.Implicits.global
|
import scala.concurrent.ExecutionContext.Implicits.global
|
||||||
@@ -298,7 +300,7 @@ trait RepositorySettingsControllerBase extends ControllerBase {
|
|||||||
case e: java.net.UnknownHostException => Map("error" -> ("Unknown host " + e.getMessage))
|
case e: java.net.UnknownHostException => Map("error" -> ("Unknown host " + e.getMessage))
|
||||||
case e: java.lang.IllegalArgumentException => Map("error" -> ("invalid url"))
|
case e: java.lang.IllegalArgumentException => Map("error" -> ("invalid url"))
|
||||||
case e: org.apache.http.client.ClientProtocolException => Map("error" -> ("invalid url"))
|
case e: org.apache.http.client.ClientProtocolException => Map("error" -> ("invalid url"))
|
||||||
case NonFatal(e) => Map("error" -> (e.getClass + " " + e.getMessage))
|
case NonFatal(e) => Map("error" -> (s"${e.getClass} ${e.getMessage}"))
|
||||||
}
|
}
|
||||||
|
|
||||||
contentType = formats("json")
|
contentType = formats("json")
|
||||||
@@ -350,7 +352,7 @@ trait RepositorySettingsControllerBase extends ControllerBase {
|
|||||||
*/
|
*/
|
||||||
post("/:owner/:repository/settings/hooks/edit", webHookForm(true))(ownerOnly { (form, repository) =>
|
post("/:owner/:repository/settings/hooks/edit", webHookForm(true))(ownerOnly { (form, repository) =>
|
||||||
updateWebHook(repository.owner, repository.name, form.url, form.events, form.ctype, form.token)
|
updateWebHook(repository.owner, repository.name, form.url, form.events, form.ctype, form.token)
|
||||||
flash += "info" -> s"webhook ${form.url} updated"
|
flash.update("info", s"webhook ${form.url} updated")
|
||||||
redirect(s"/${repository.owner}/${repository.name}/settings/hooks")
|
redirect(s"/${repository.owner}/${repository.name}/settings/hooks")
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -386,11 +388,11 @@ trait RepositorySettingsControllerBase extends ControllerBase {
|
|||||||
*/
|
*/
|
||||||
post("/:owner/:repository/settings/gc")(ownerOnly { repository =>
|
post("/:owner/:repository/settings/gc")(ownerOnly { repository =>
|
||||||
LockUtil.lock(s"${repository.owner}/${repository.name}") {
|
LockUtil.lock(s"${repository.owner}/${repository.name}") {
|
||||||
using(Git.open(getRepositoryDir(repository.owner, repository.name))) { git =>
|
Using.resource(Git.open(getRepositoryDir(repository.owner, repository.name))) { git =>
|
||||||
git.gc().call()
|
git.gc().call()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
flash += "info" -> "Garbage collection has been executed."
|
flash.update("info", "Garbage collection has been executed.")
|
||||||
redirect(s"/${repository.owner}/${repository.name}/settings/danger")
|
redirect(s"/${repository.owner}/${repository.name}/settings/danger")
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
package gitbucket.core.controller
|
package gitbucket.core.controller
|
||||||
|
|
||||||
import java.io.File
|
import java.io.{File, FileInputStream, FileOutputStream}
|
||||||
|
|
||||||
|
import scala.util.Using
|
||||||
import javax.servlet.http.{HttpServletRequest, HttpServletResponse}
|
import javax.servlet.http.{HttpServletRequest, HttpServletResponse}
|
||||||
import gitbucket.core.plugin.PluginRegistry
|
import gitbucket.core.plugin.PluginRegistry
|
||||||
import gitbucket.core.repo.html
|
import gitbucket.core.repo.html
|
||||||
@@ -258,11 +259,11 @@ trait RepositoryViewerControllerBase extends ControllerBase {
|
|||||||
def getSummary(statuses: List[CommitStatus]): (CommitState, String) = {
|
def getSummary(statuses: List[CommitStatus]): (CommitState, String) = {
|
||||||
val stateMap = statuses.groupBy(_.state)
|
val stateMap = statuses.groupBy(_.state)
|
||||||
val state = CommitState.combine(stateMap.keySet)
|
val state = CommitState.combine(stateMap.keySet)
|
||||||
val summary = stateMap.map { case (keyState, states) => states.size + " " + keyState.name }.mkString(", ")
|
val summary = stateMap.map { case (keyState, states) => s"${states.size} ${keyState.name}" }.mkString(", ")
|
||||||
state -> summary
|
state -> summary
|
||||||
}
|
}
|
||||||
|
|
||||||
using(Git.open(getRepositoryDir(repository.owner, repository.name))) {
|
Using.resource(Git.open(getRepositoryDir(repository.owner, repository.name))) {
|
||||||
git =>
|
git =>
|
||||||
def getTags(sha: String): List[String] = {
|
def getTags(sha: String): List[String] = {
|
||||||
JGitUtil.getTagsOnCommit(git, sha)
|
JGitUtil.getTagsOnCommit(git, sha)
|
||||||
@@ -315,7 +316,7 @@ trait RepositoryViewerControllerBase extends ControllerBase {
|
|||||||
val protectedBranch = getProtectedBranchInfo(repository.owner, repository.name, branch)
|
val protectedBranch = getProtectedBranchInfo(repository.owner, repository.name, branch)
|
||||||
.needStatusCheck(context.loginAccount.get.userName)
|
.needStatusCheck(context.loginAccount.get.userName)
|
||||||
|
|
||||||
using(Git.open(getRepositoryDir(repository.owner, repository.name))) { git =>
|
Using.resource(Git.open(getRepositoryDir(repository.owner, repository.name))) { git =>
|
||||||
val revCommit = JGitUtil.getRevCommitFromId(git, git.getRepository.resolve(branch))
|
val revCommit = JGitUtil.getRevCommitFromId(git, git.getRepository.resolve(branch))
|
||||||
|
|
||||||
html.editor(
|
html.editor(
|
||||||
@@ -351,7 +352,7 @@ trait RepositoryViewerControllerBase extends ControllerBase {
|
|||||||
repository = repository,
|
repository = repository,
|
||||||
branch = form.branch,
|
branch = form.branch,
|
||||||
path = form.path,
|
path = form.path,
|
||||||
files = files,
|
files = files.toIndexedSeq,
|
||||||
message = form.message.getOrElse("Add files via upload"),
|
message = form.message.getOrElse("Add files via upload"),
|
||||||
loginAccount = context.loginAccount.get
|
loginAccount = context.loginAccount.get
|
||||||
) {
|
) {
|
||||||
@@ -384,7 +385,7 @@ trait RepositoryViewerControllerBase extends ControllerBase {
|
|||||||
val protectedBranch = getProtectedBranchInfo(repository.owner, repository.name, branch)
|
val protectedBranch = getProtectedBranchInfo(repository.owner, repository.name, branch)
|
||||||
.needStatusCheck(context.loginAccount.get.userName)
|
.needStatusCheck(context.loginAccount.get.userName)
|
||||||
|
|
||||||
using(Git.open(getRepositoryDir(repository.owner, repository.name))) {
|
Using.resource(Git.open(getRepositoryDir(repository.owner, repository.name))) {
|
||||||
git =>
|
git =>
|
||||||
val revCommit = JGitUtil.getRevCommitFromId(git, git.getRepository.resolve(branch))
|
val revCommit = JGitUtil.getRevCommitFromId(git, git.getRepository.resolve(branch))
|
||||||
|
|
||||||
@@ -411,7 +412,7 @@ trait RepositoryViewerControllerBase extends ControllerBase {
|
|||||||
|
|
||||||
get("/:owner/:repository/remove/*")(writableUsersOnly { repository =>
|
get("/:owner/:repository/remove/*")(writableUsersOnly { repository =>
|
||||||
val (branch, path) = repository.splitPath(multiParams("splat").head)
|
val (branch, path) = repository.splitPath(multiParams("splat").head)
|
||||||
using(Git.open(getRepositoryDir(repository.owner, repository.name))) {
|
Using.resource(Git.open(getRepositoryDir(repository.owner, repository.name))) {
|
||||||
git =>
|
git =>
|
||||||
val revCommit = JGitUtil.getRevCommitFromId(git, git.getRepository.resolve(branch))
|
val revCommit = JGitUtil.getRevCommitFromId(git, git.getRepository.resolve(branch))
|
||||||
|
|
||||||
@@ -487,8 +488,6 @@ trait RepositoryViewerControllerBase extends ControllerBase {
|
|||||||
loginAccount = context.loginAccount.get
|
loginAccount = context.loginAccount.get
|
||||||
)
|
)
|
||||||
|
|
||||||
println(form.path)
|
|
||||||
|
|
||||||
redirect(
|
redirect(
|
||||||
s"/${repository.owner}/${repository.name}/tree/${form.branch}${if (form.path.length == 0) "" else "/" + form.path}"
|
s"/${repository.owner}/${repository.name}/tree/${form.branch}${if (form.path.length == 0) "" else "/" + form.path}"
|
||||||
)
|
)
|
||||||
@@ -496,7 +495,7 @@ trait RepositoryViewerControllerBase extends ControllerBase {
|
|||||||
|
|
||||||
get("/:owner/:repository/raw/*")(referrersOnly { repository =>
|
get("/:owner/:repository/raw/*")(referrersOnly { repository =>
|
||||||
val (id, path) = repository.splitPath(multiParams("splat").head)
|
val (id, path) = repository.splitPath(multiParams("splat").head)
|
||||||
using(Git.open(getRepositoryDir(repository.owner, repository.name))) { git =>
|
Using.resource(Git.open(getRepositoryDir(repository.owner, repository.name))) { git =>
|
||||||
val revCommit = JGitUtil.getRevCommitFromId(git, git.getRepository.resolve(id))
|
val revCommit = JGitUtil.getRevCommitFromId(git, git.getRepository.resolve(id))
|
||||||
|
|
||||||
getPathObjectId(git, path, revCommit).map { objectId =>
|
getPathObjectId(git, path, revCommit).map { objectId =>
|
||||||
@@ -511,7 +510,7 @@ trait RepositoryViewerControllerBase extends ControllerBase {
|
|||||||
val blobRoute = get("/:owner/:repository/blob/*")(referrersOnly { repository =>
|
val blobRoute = get("/:owner/:repository/blob/*")(referrersOnly { repository =>
|
||||||
val (id, path) = repository.splitPath(multiParams("splat").head)
|
val (id, path) = repository.splitPath(multiParams("splat").head)
|
||||||
val raw = params.get("raw").getOrElse("false").toBoolean
|
val raw = params.get("raw").getOrElse("false").toBoolean
|
||||||
using(Git.open(getRepositoryDir(repository.owner, repository.name))) {
|
Using.resource(Git.open(getRepositoryDir(repository.owner, repository.name))) {
|
||||||
git =>
|
git =>
|
||||||
val revCommit = JGitUtil.getRevCommitFromId(git, git.getRepository.resolve(id))
|
val revCommit = JGitUtil.getRevCommitFromId(git, git.getRepository.resolve(id))
|
||||||
getPathObjectId(git, path, revCommit).map {
|
getPathObjectId(git, path, revCommit).map {
|
||||||
@@ -551,7 +550,7 @@ trait RepositoryViewerControllerBase extends ControllerBase {
|
|||||||
ajaxGet("/:owner/:repository/get-blame/*")(referrersOnly { repository =>
|
ajaxGet("/:owner/:repository/get-blame/*")(referrersOnly { repository =>
|
||||||
val (id, path) = repository.splitPath(multiParams("splat").head)
|
val (id, path) = repository.splitPath(multiParams("splat").head)
|
||||||
contentType = formats("json")
|
contentType = formats("json")
|
||||||
using(Git.open(getRepositoryDir(repository.owner, repository.name))) {
|
Using.resource(Git.open(getRepositoryDir(repository.owner, repository.name))) {
|
||||||
git =>
|
git =>
|
||||||
val last = git.log.add(git.getRepository.resolve(id)).addPath(path).setMaxCount(1).call.iterator.next.name
|
val last = git.log.add(git.getRepository.resolve(id)).addPath(path).setMaxCount(1).call.iterator.next.name
|
||||||
Serialization.write(
|
Serialization.write(
|
||||||
@@ -586,7 +585,7 @@ trait RepositoryViewerControllerBase extends ControllerBase {
|
|||||||
val id = params("id")
|
val id = params("id")
|
||||||
|
|
||||||
try {
|
try {
|
||||||
using(Git.open(getRepositoryDir(repository.owner, repository.name))) {
|
Using.resource(Git.open(getRepositoryDir(repository.owner, repository.name))) {
|
||||||
git =>
|
git =>
|
||||||
defining(JGitUtil.getRevCommitFromId(git, git.getRepository.resolve(id))) {
|
defining(JGitUtil.getRevCommitFromId(git, git.getRepository.resolve(id))) {
|
||||||
revCommit =>
|
revCommit =>
|
||||||
@@ -615,7 +614,7 @@ trait RepositoryViewerControllerBase extends ControllerBase {
|
|||||||
|
|
||||||
get("/:owner/:repository/patch/:id")(referrersOnly { repository =>
|
get("/:owner/:repository/patch/:id")(referrersOnly { repository =>
|
||||||
try {
|
try {
|
||||||
using(Git.open(getRepositoryDir(repository.owner, repository.name))) { git =>
|
Using.resource(Git.open(getRepositoryDir(repository.owner, repository.name))) { git =>
|
||||||
val diff = JGitUtil.getPatch(git, None, params("id"))
|
val diff = JGitUtil.getPatch(git, None, params("id"))
|
||||||
contentType = formats("txt")
|
contentType = formats("txt")
|
||||||
diff
|
diff
|
||||||
@@ -628,7 +627,7 @@ trait RepositoryViewerControllerBase extends ControllerBase {
|
|||||||
get("/:owner/:repository/patch/*...*")(referrersOnly { repository =>
|
get("/:owner/:repository/patch/*...*")(referrersOnly { repository =>
|
||||||
try {
|
try {
|
||||||
val Seq(fromId, toId) = multiParams("splat")
|
val Seq(fromId, toId) = multiParams("splat")
|
||||||
using(Git.open(getRepositoryDir(repository.owner, repository.name))) { git =>
|
Using.resource(Git.open(getRepositoryDir(repository.owner, repository.name))) { git =>
|
||||||
val diff = JGitUtil.getPatch(git, Some(fromId), toId)
|
val diff = JGitUtil.getPatch(git, Some(fromId), toId)
|
||||||
contentType = formats("txt")
|
contentType = formats("txt")
|
||||||
diff
|
diff
|
||||||
@@ -748,7 +747,7 @@ trait RepositoryViewerControllerBase extends ControllerBase {
|
|||||||
*/
|
*/
|
||||||
get("/:owner/:repository/branches")(referrersOnly { repository =>
|
get("/:owner/:repository/branches")(referrersOnly { repository =>
|
||||||
val protectedBranches = getProtectedBranchList(repository.owner, repository.name).toSet
|
val protectedBranches = getProtectedBranchList(repository.owner, repository.name).toSet
|
||||||
val branches = using(Git.open(getRepositoryDir(repository.owner, repository.name))) {
|
val branches = Using.resource(Git.open(getRepositoryDir(repository.owner, repository.name))) {
|
||||||
git =>
|
git =>
|
||||||
JGitUtil
|
JGitUtil
|
||||||
.getBranches(
|
.getBranches(
|
||||||
@@ -788,14 +787,14 @@ trait RepositoryViewerControllerBase extends ControllerBase {
|
|||||||
* Creates a tag.
|
* Creates a tag.
|
||||||
*/
|
*/
|
||||||
post("/:owner/:repository/tag", tagForm)(writableUsersOnly { (form, repository) =>
|
post("/:owner/:repository/tag", tagForm)(writableUsersOnly { (form, repository) =>
|
||||||
using(Git.open(getRepositoryDir(repository.owner, repository.name))) { git =>
|
Using.resource(Git.open(getRepositoryDir(repository.owner, repository.name))) { git =>
|
||||||
JGitUtil.createTag(git, form.tagName, form.message, form.commitId)
|
JGitUtil.createTag(git, form.tagName, form.message, form.commitId)
|
||||||
} match {
|
} match {
|
||||||
case Right(message) =>
|
case Right(message) =>
|
||||||
flash += "info" -> message
|
flash.update("info", message)
|
||||||
redirect(s"/${repository.owner}/${repository.name}/commit/${form.commitId}")
|
redirect(s"/${repository.owner}/${repository.name}/commit/${form.commitId}")
|
||||||
case Left(message) =>
|
case Left(message) =>
|
||||||
flash += "error" -> message
|
flash.update("error", message)
|
||||||
redirect(s"/${repository.owner}/${repository.name}/commit/${form.commitId}")
|
redirect(s"/${repository.owner}/${repository.name}/commit/${form.commitId}")
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -806,16 +805,16 @@ trait RepositoryViewerControllerBase extends ControllerBase {
|
|||||||
post("/:owner/:repository/branches")(writableUsersOnly { repository =>
|
post("/:owner/:repository/branches")(writableUsersOnly { repository =>
|
||||||
val newBranchName = params.getOrElse("new", halt(400))
|
val newBranchName = params.getOrElse("new", halt(400))
|
||||||
val fromBranchName = params.getOrElse("from", halt(400))
|
val fromBranchName = params.getOrElse("from", halt(400))
|
||||||
using(Git.open(getRepositoryDir(repository.owner, repository.name))) { git =>
|
Using.resource(Git.open(getRepositoryDir(repository.owner, repository.name))) { git =>
|
||||||
JGitUtil.createBranch(git, fromBranchName, newBranchName)
|
JGitUtil.createBranch(git, fromBranchName, newBranchName)
|
||||||
} match {
|
} match {
|
||||||
case Right(message) =>
|
case Right(message) =>
|
||||||
flash += "info" -> message
|
flash.update("info", message)
|
||||||
redirect(
|
redirect(
|
||||||
s"/${repository.owner}/${repository.name}/tree/${StringUtil.urlEncode(newBranchName).replace("%2F", "/")}"
|
s"/${repository.owner}/${repository.name}/tree/${StringUtil.urlEncode(newBranchName).replace("%2F", "/")}"
|
||||||
)
|
)
|
||||||
case Left(message) =>
|
case Left(message) =>
|
||||||
flash += "error" -> message
|
flash.update("error", message)
|
||||||
redirect(s"/${repository.owner}/${repository.name}/tree/${fromBranchName}")
|
redirect(s"/${repository.owner}/${repository.name}/tree/${fromBranchName}")
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -827,7 +826,7 @@ trait RepositoryViewerControllerBase extends ControllerBase {
|
|||||||
val branchName = multiParams("splat").head
|
val branchName = multiParams("splat").head
|
||||||
val userName = context.loginAccount.get.userName
|
val userName = context.loginAccount.get.userName
|
||||||
if (repository.repository.defaultBranch != branchName) {
|
if (repository.repository.defaultBranch != branchName) {
|
||||||
using(Git.open(getRepositoryDir(repository.owner, repository.name))) { git =>
|
Using.resource(Git.open(getRepositoryDir(repository.owner, repository.name))) { git =>
|
||||||
git.branchDelete().setForce(true).setBranchNames(branchName).call()
|
git.branchDelete().setForce(true).setBranchNames(branchName).call()
|
||||||
recordDeleteBranchActivity(repository.owner, repository.name, userName, branchName)
|
recordDeleteBranchActivity(repository.owner, repository.name, userName, branchName)
|
||||||
}
|
}
|
||||||
@@ -879,7 +878,7 @@ trait RepositoryViewerControllerBase extends ControllerBase {
|
|||||||
* Displays the file find of branch.
|
* Displays the file find of branch.
|
||||||
*/
|
*/
|
||||||
get("/:owner/:repository/find/*")(referrersOnly { repository =>
|
get("/:owner/:repository/find/*")(referrersOnly { repository =>
|
||||||
using(Git.open(getRepositoryDir(repository.owner, repository.name))) { git =>
|
Using.resource(Git.open(getRepositoryDir(repository.owner, repository.name))) { git =>
|
||||||
val ref = multiParams("splat").head
|
val ref = multiParams("splat").head
|
||||||
JGitUtil.getTreeId(git, ref).map { treeId =>
|
JGitUtil.getTreeId(git, ref).map { treeId =>
|
||||||
html.find(ref, treeId, repository)
|
html.find(ref, treeId, repository)
|
||||||
@@ -891,7 +890,7 @@ trait RepositoryViewerControllerBase extends ControllerBase {
|
|||||||
* Get all file list of branch.
|
* Get all file list of branch.
|
||||||
*/
|
*/
|
||||||
ajaxGet("/:owner/:repository/tree-list/:tree")(referrersOnly { repository =>
|
ajaxGet("/:owner/:repository/tree-list/:tree")(referrersOnly { repository =>
|
||||||
using(Git.open(getRepositoryDir(repository.owner, repository.name))) { git =>
|
Using.resource(Git.open(getRepositoryDir(repository.owner, repository.name))) { git =>
|
||||||
val treeId = params("tree")
|
val treeId = params("tree")
|
||||||
contentType = formats("json")
|
contentType = formats("json")
|
||||||
Map("paths" -> JGitUtil.getAllFileListByTreeId(git, treeId))
|
Map("paths" -> JGitUtil.getAllFileListByTreeId(git, treeId))
|
||||||
@@ -915,7 +914,7 @@ trait RepositoryViewerControllerBase extends ControllerBase {
|
|||||||
* @return HTML of the file list
|
* @return HTML of the file list
|
||||||
*/
|
*/
|
||||||
private def fileList(repository: RepositoryService.RepositoryInfo, revstr: String = "", path: String = ".") = {
|
private def fileList(repository: RepositoryService.RepositoryInfo, revstr: String = "", path: String = ".") = {
|
||||||
using(Git.open(getRepositoryDir(repository.owner, repository.name))) { git =>
|
Using.resource(Git.open(getRepositoryDir(repository.owner, repository.name))) { git =>
|
||||||
if (JGitUtil.isEmpty(git)) {
|
if (JGitUtil.isEmpty(git)) {
|
||||||
html.guide(repository, hasDeveloperRole(repository.owner, repository.name, context.loginAccount))
|
html.guide(repository, hasDeveloperRole(repository.owner, repository.name, context.loginAccount))
|
||||||
} else {
|
} else {
|
||||||
@@ -974,16 +973,16 @@ trait RepositoryViewerControllerBase extends ControllerBase {
|
|||||||
def archive(revision: String, archiveFormat: String, archive: ArchiveOutputStream)(
|
def archive(revision: String, archiveFormat: String, archive: ArchiveOutputStream)(
|
||||||
entryCreator: (String, Long, java.util.Date, Int) => ArchiveEntry
|
entryCreator: (String, Long, java.util.Date, Int) => ArchiveEntry
|
||||||
): Unit = {
|
): Unit = {
|
||||||
using(Git.open(getRepositoryDir(repository.owner, repository.name))) { git =>
|
Using.resource(Git.open(getRepositoryDir(repository.owner, repository.name))) { git =>
|
||||||
val oid = git.getRepository.resolve(revision)
|
val oid = git.getRepository.resolve(revision)
|
||||||
val commit = JGitUtil.getRevCommitFromId(git, oid)
|
val commit = JGitUtil.getRevCommitFromId(git, oid)
|
||||||
val date = commit.getCommitterIdent.getWhen
|
val date = commit.getCommitterIdent.getWhen
|
||||||
val sha1 = oid.getName()
|
val sha1 = oid.getName()
|
||||||
val repositorySuffix = (if (sha1.startsWith(revision)) sha1 else revision).replace('/', '-')
|
val repositorySuffix = (if (sha1.startsWith(revision)) sha1 else revision).replace('/', '-')
|
||||||
val pathSuffix = if (path.isEmpty) "" else '-' + path.replace('/', '-')
|
val pathSuffix = if (path.isEmpty) "" else s"-${path.replace('/', '-')}"
|
||||||
val baseName = repository.name + "-" + repositorySuffix + pathSuffix
|
val baseName = repository.name + "-" + repositorySuffix + pathSuffix
|
||||||
|
|
||||||
using(new TreeWalk(git.getRepository)) { treeWalk =>
|
Using.resource(new TreeWalk(git.getRepository)) { treeWalk =>
|
||||||
treeWalk.addTree(commit.getTree)
|
treeWalk.addTree(commit.getTree)
|
||||||
treeWalk.setRecursive(true)
|
treeWalk.setRecursive(true)
|
||||||
if (!path.isEmpty) {
|
if (!path.isEmpty) {
|
||||||
@@ -994,24 +993,31 @@ trait RepositoryViewerControllerBase extends ControllerBase {
|
|||||||
val entryPath =
|
val entryPath =
|
||||||
if (path.isEmpty) baseName + "/" + treeWalk.getPathString
|
if (path.isEmpty) baseName + "/" + treeWalk.getPathString
|
||||||
else path.split("/").last + treeWalk.getPathString.substring(path.length)
|
else path.split("/").last + treeWalk.getPathString.substring(path.length)
|
||||||
val size = JGitUtil.getContentSize(git.getRepository.open(treeWalk.getObjectId(0)))
|
|
||||||
val mode = treeWalk.getFileMode.getBits
|
val mode = treeWalk.getFileMode.getBits
|
||||||
val entry: ArchiveEntry = entryCreator(entryPath, size, date, mode)
|
|
||||||
JGitUtil.openFile(git, repository, commit.getTree, treeWalk.getPathString) { in =>
|
JGitUtil.openFile(git, repository, commit.getTree, treeWalk.getPathString) { in =>
|
||||||
|
val tempFile = File.createTempFile("gitbucket", ".archive")
|
||||||
|
val size = Using.resource(new FileOutputStream(tempFile)) { out =>
|
||||||
|
IOUtils.copy(
|
||||||
|
EolStreamTypeUtil.wrapInputStream(
|
||||||
|
in,
|
||||||
|
EolStreamTypeUtil
|
||||||
|
.detectStreamType(
|
||||||
|
OperationType.CHECKOUT_OP,
|
||||||
|
git.getRepository.getConfig.get(WorkingTreeOptions.KEY),
|
||||||
|
treeWalk.getAttributes
|
||||||
|
)
|
||||||
|
),
|
||||||
|
out
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
val entry: ArchiveEntry = entryCreator(entryPath, size, date, mode)
|
||||||
archive.putArchiveEntry(entry)
|
archive.putArchiveEntry(entry)
|
||||||
IOUtils.copy(
|
Using.resource(new FileInputStream(tempFile)) { in =>
|
||||||
EolStreamTypeUtil.wrapInputStream(
|
IOUtils.copy(in, archive)
|
||||||
in,
|
}
|
||||||
EolStreamTypeUtil
|
|
||||||
.detectStreamType(
|
|
||||||
OperationType.CHECKOUT_OP,
|
|
||||||
git.getRepository.getConfig.get(WorkingTreeOptions.KEY),
|
|
||||||
treeWalk.getAttributes
|
|
||||||
)
|
|
||||||
),
|
|
||||||
archive
|
|
||||||
)
|
|
||||||
archive.closeArchiveEntry()
|
archive.closeArchiveEntry()
|
||||||
|
tempFile.delete()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1032,9 +1038,10 @@ trait RepositoryViewerControllerBase extends ControllerBase {
|
|||||||
)
|
)
|
||||||
contentType = "application/octet-stream"
|
contentType = "application/octet-stream"
|
||||||
response.setBufferSize(1024 * 1024)
|
response.setBufferSize(1024 * 1024)
|
||||||
using(new ZipArchiveOutputStream(response.getOutputStream)) { zip =>
|
Using.resource(new ZipArchiveOutputStream(response.getOutputStream)) { zip =>
|
||||||
archive(revision, ".zip", zip) { (path, size, date, mode) =>
|
archive(revision, ".zip", zip) { (path, size, date, mode) =>
|
||||||
val entry = new ZipArchiveEntry(path)
|
val entry = new ZipArchiveEntry(path)
|
||||||
|
entry.setSize(size)
|
||||||
entry.setUnixMode(mode)
|
entry.setUnixMode(mode)
|
||||||
entry.setTime(date.getTime)
|
entry.setTime(date.getTime)
|
||||||
entry
|
entry
|
||||||
@@ -1048,17 +1055,18 @@ trait RepositoryViewerControllerBase extends ControllerBase {
|
|||||||
)
|
)
|
||||||
contentType = "application/octet-stream"
|
contentType = "application/octet-stream"
|
||||||
response.setBufferSize(1024 * 1024)
|
response.setBufferSize(1024 * 1024)
|
||||||
using(compressor match {
|
Using.resource(compressor match {
|
||||||
case "gz" => new GzipCompressorOutputStream(response.getOutputStream)
|
case "gz" => new GzipCompressorOutputStream(response.getOutputStream)
|
||||||
case "bz2" => new BZip2CompressorOutputStream(response.getOutputStream)
|
case "bz2" => new BZip2CompressorOutputStream(response.getOutputStream)
|
||||||
case "xz" => new XZCompressorOutputStream(response.getOutputStream)
|
case "xz" => new XZCompressorOutputStream(response.getOutputStream)
|
||||||
}) { compressorOutputStream =>
|
}) { compressorOutputStream =>
|
||||||
using(new TarArchiveOutputStream(compressorOutputStream)) { tar =>
|
Using.resource(new TarArchiveOutputStream(compressorOutputStream)) { tar =>
|
||||||
tar.setBigNumberMode(TarArchiveOutputStream.BIGNUMBER_STAR)
|
tar.setBigNumberMode(TarArchiveOutputStream.BIGNUMBER_STAR)
|
||||||
tar.setLongFileMode(TarArchiveOutputStream.LONGFILE_GNU)
|
tar.setLongFileMode(TarArchiveOutputStream.LONGFILE_GNU)
|
||||||
tar.setAddPaxHeadersForNonAsciiNames(true)
|
tar.setAddPaxHeadersForNonAsciiNames(true)
|
||||||
archive(revision, ".tar.gz", tar) { (path, size, date, mode) =>
|
archive(revision, ".tar.gz", tar) { (path, size, date, mode) =>
|
||||||
val entry = new TarArchiveEntry(path)
|
val entry = new TarArchiveEntry(path)
|
||||||
|
entry.setSize(size)
|
||||||
entry.setModTime(date)
|
entry.setModTime(date)
|
||||||
entry.setMode(mode)
|
entry.setMode(mode)
|
||||||
entry
|
entry
|
||||||
@@ -1081,7 +1089,7 @@ trait RepositoryViewerControllerBase extends ControllerBase {
|
|||||||
val branch = params("branch")
|
val branch = params("branch")
|
||||||
|
|
||||||
LockUtil.lock(s"${owner}/${repository}") {
|
LockUtil.lock(s"${owner}/${repository}") {
|
||||||
using(Git.open(getRepositoryDir(owner, repository))) { git =>
|
Using.resource(Git.open(getRepositoryDir(owner, repository))) { git =>
|
||||||
val headName = s"refs/heads/${branch}"
|
val headName = s"refs/heads/${branch}"
|
||||||
val headTip = git.getRepository.resolve(headName)
|
val headTip = git.getRepository.resolve(headName)
|
||||||
if (headTip.getName != value) {
|
if (headTip.getName != value) {
|
||||||
|
|||||||
@@ -2,14 +2,11 @@ package gitbucket.core.controller
|
|||||||
|
|
||||||
import java.io.FileInputStream
|
import java.io.FileInputStream
|
||||||
|
|
||||||
import com.github.zafarkhaja.semver.{Version => Semver}
|
|
||||||
import gitbucket.core.GitBucketCoreModule
|
|
||||||
import gitbucket.core.admin.html
|
import gitbucket.core.admin.html
|
||||||
import gitbucket.core.plugin.{PluginInfoBase, PluginRegistry, PluginRepository}
|
import gitbucket.core.plugin.PluginRegistry
|
||||||
import gitbucket.core.service.SystemSettingsService._
|
import gitbucket.core.service.SystemSettingsService._
|
||||||
import gitbucket.core.service.{AccountService, RepositoryService}
|
import gitbucket.core.service.{AccountService, RepositoryService}
|
||||||
import gitbucket.core.ssh.SshServer
|
import gitbucket.core.ssh.SshServer
|
||||||
import gitbucket.core.util.Directory._
|
|
||||||
import gitbucket.core.util.Implicits._
|
import gitbucket.core.util.Implicits._
|
||||||
import gitbucket.core.util.StringUtil._
|
import gitbucket.core.util.StringUtil._
|
||||||
import gitbucket.core.util.SyntaxSugars._
|
import gitbucket.core.util.SyntaxSugars._
|
||||||
@@ -21,8 +18,8 @@ import org.scalatra._
|
|||||||
import org.scalatra.forms._
|
import org.scalatra.forms._
|
||||||
import org.scalatra.i18n.Messages
|
import org.scalatra.i18n.Messages
|
||||||
|
|
||||||
import scala.collection.JavaConverters._
|
|
||||||
import scala.collection.mutable.ListBuffer
|
import scala.collection.mutable.ListBuffer
|
||||||
|
import scala.util.Using
|
||||||
|
|
||||||
class SystemSettingsController
|
class SystemSettingsController
|
||||||
extends SystemSettingsControllerBase
|
extends SystemSettingsControllerBase
|
||||||
@@ -93,17 +90,17 @@ trait SystemSettingsControllerBase extends AccountManagementControllerBase {
|
|||||||
)(OIDC.apply)
|
)(OIDC.apply)
|
||||||
),
|
),
|
||||||
"skinName" -> trim(label("AdminLTE skin name", text(required))),
|
"skinName" -> trim(label("AdminLTE skin name", text(required))),
|
||||||
"showMailAddress" -> trim(label("Show mail address", boolean())),
|
"showMailAddress" -> trim(label("Show mail address", boolean())) //,
|
||||||
"pluginNetworkInstall" -> trim(label("Network plugin installation", boolean())),
|
// "pluginNetworkInstall" -> trim(label("Network plugin installation", boolean())),
|
||||||
"proxy" -> optionalIfNotChecked(
|
// "proxy" -> optionalIfNotChecked(
|
||||||
"useProxy",
|
// "useProxy",
|
||||||
mapping(
|
// mapping(
|
||||||
"host" -> trim(label("Proxy host", text(required))),
|
// "host" -> trim(label("Proxy host", text(required))),
|
||||||
"port" -> trim(label("Proxy port", number())),
|
// "port" -> trim(label("Proxy port", number())),
|
||||||
"user" -> trim(label("Keystore", optional(text()))),
|
// "user" -> trim(label("Keystore", optional(text()))),
|
||||||
"password" -> trim(label("Keystore", optional(text())))
|
// "password" -> trim(label("Keystore", optional(text())))
|
||||||
)(Proxy.apply)
|
// )(Proxy.apply)
|
||||||
)
|
// )
|
||||||
)(SystemSettings.apply).verifying { settings =>
|
)(SystemSettings.apply).verifying { settings =>
|
||||||
Vector(
|
Vector(
|
||||||
if (settings.ssh.enabled && settings.baseUrl.isEmpty) {
|
if (settings.ssh.enabled && settings.baseUrl.isEmpty) {
|
||||||
@@ -229,30 +226,30 @@ trait SystemSettingsControllerBase extends AccountManagementControllerBase {
|
|||||||
val conn = request2Session(request).conn
|
val conn = request2Session(request).conn
|
||||||
val meta = conn.getMetaData
|
val meta = conn.getMetaData
|
||||||
val tables = ListBuffer[Table]()
|
val tables = ListBuffer[Table]()
|
||||||
using(meta.getTables(null, "%", "%", Array("TABLE", "VIEW"))) {
|
Using.resource(meta.getTables(null, "%", "%", Array("TABLE", "VIEW"))) {
|
||||||
rs =>
|
rs =>
|
||||||
while (rs.next()) {
|
while (rs.next()) {
|
||||||
val tableName = rs.getString("TABLE_NAME")
|
val tableName = rs.getString("TABLE_NAME")
|
||||||
|
|
||||||
val pkColumns = ListBuffer[String]()
|
val pkColumns = ListBuffer[String]()
|
||||||
using(meta.getPrimaryKeys(null, null, tableName)) { rs =>
|
Using.resource(meta.getPrimaryKeys(null, null, tableName)) { rs =>
|
||||||
while (rs.next()) {
|
while (rs.next()) {
|
||||||
pkColumns += rs.getString("COLUMN_NAME").toUpperCase
|
pkColumns += rs.getString("COLUMN_NAME").toUpperCase
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val columns = ListBuffer[Column]()
|
val columns = ListBuffer[Column]()
|
||||||
using(meta.getColumns(null, "%", tableName, "%")) { rs =>
|
Using.resource(meta.getColumns(null, "%", tableName, "%")) { rs =>
|
||||||
while (rs.next()) {
|
while (rs.next()) {
|
||||||
val columnName = rs.getString("COLUMN_NAME").toUpperCase
|
val columnName = rs.getString("COLUMN_NAME").toUpperCase
|
||||||
columns += Column(columnName, pkColumns.contains(columnName))
|
columns += Column(columnName, pkColumns.contains(columnName))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
tables += Table(tableName.toUpperCase, columns)
|
tables += Table(tableName.toUpperCase, columns.toSeq)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
html.dbviewer(tables)
|
html.dbviewer(tables.toSeq)
|
||||||
})
|
})
|
||||||
|
|
||||||
post("/admin/dbviewer/_query")(adminOnly {
|
post("/admin/dbviewer/_query")(adminOnly {
|
||||||
@@ -263,10 +260,10 @@ trait SystemSettingsControllerBase extends AccountManagementControllerBase {
|
|||||||
if (trimmedQuery.nonEmpty) {
|
if (trimmedQuery.nonEmpty) {
|
||||||
try {
|
try {
|
||||||
val conn = request2Session(request).conn
|
val conn = request2Session(request).conn
|
||||||
using(conn.prepareStatement(query)) {
|
Using.resource(conn.prepareStatement(query)) {
|
||||||
stmt =>
|
stmt =>
|
||||||
if (trimmedQuery.toUpperCase.startsWith("SELECT")) {
|
if (trimmedQuery.toUpperCase.startsWith("SELECT")) {
|
||||||
using(stmt.executeQuery()) {
|
Using.resource(stmt.executeQuery()) {
|
||||||
rs =>
|
rs =>
|
||||||
val meta = rs.getMetaData
|
val meta = rs.getMetaData
|
||||||
val columns = for (i <- 1 to meta.getColumnCount) yield {
|
val columns = for (i <- 1 to meta.getColumnCount) yield {
|
||||||
@@ -309,7 +306,7 @@ trait SystemSettingsControllerBase extends AccountManagementControllerBase {
|
|||||||
} SshServer.start(sshAddress, baseUrl)
|
} SshServer.start(sshAddress, baseUrl)
|
||||||
}
|
}
|
||||||
|
|
||||||
flash += "info" -> "System settings has been updated."
|
flash.update("info", "System settings has been updated.")
|
||||||
redirect("/admin/system")
|
redirect("/admin/system")
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -332,63 +329,12 @@ trait SystemSettingsControllerBase extends AccountManagementControllerBase {
|
|||||||
})
|
})
|
||||||
|
|
||||||
get("/admin/plugins")(adminOnly {
|
get("/admin/plugins")(adminOnly {
|
||||||
// Installed plugins
|
html.plugins(PluginRegistry().getPlugins(), flash.get("info"))
|
||||||
val enabledPlugins = PluginRegistry().getPlugins()
|
|
||||||
val gitbucketVersion = GitBucketCoreModule.getVersions.asScala.last.getVersion
|
|
||||||
val gitbucketSemver = Semver.valueOf(gitbucketVersion)
|
|
||||||
|
|
||||||
// Plugins in the remote repository
|
|
||||||
val repositoryPlugins = if (context.settings.pluginNetworkInstall) {
|
|
||||||
PluginRepository
|
|
||||||
.getPlugins()
|
|
||||||
.map {
|
|
||||||
meta =>
|
|
||||||
(meta, meta.versions.reverse.find {
|
|
||||||
version =>
|
|
||||||
val semver = Semver.valueOf(version.version)
|
|
||||||
gitbucketVersion == version.gitbucketVersion && !enabledPlugins.exists { plugin =>
|
|
||||||
if (plugin.pluginId == meta.id) {
|
|
||||||
Semver.valueOf(plugin.pluginVersion) match {
|
|
||||||
case x if x.greaterThan(semver) => true
|
|
||||||
case x if x.equals(semver) =>
|
|
||||||
plugin.gitbucketVersion match {
|
|
||||||
case None => true
|
|
||||||
case Some(x) => Semver.valueOf(x).greaterThanOrEqualTo(gitbucketSemver)
|
|
||||||
}
|
|
||||||
case _ => false
|
|
||||||
}
|
|
||||||
} else false
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
.collect {
|
|
||||||
case (meta, Some(version)) =>
|
|
||||||
new PluginInfoBase(
|
|
||||||
pluginId = meta.id,
|
|
||||||
pluginName = meta.name,
|
|
||||||
pluginVersion = version.version,
|
|
||||||
gitbucketVersion = Some(version.gitbucketVersion),
|
|
||||||
description = meta.description
|
|
||||||
)
|
|
||||||
}
|
|
||||||
} else Nil
|
|
||||||
|
|
||||||
// Merge
|
|
||||||
val plugins = (enabledPlugins.map((_, true)) ++ repositoryPlugins.map((_, false)))
|
|
||||||
.groupBy(_._1.pluginId)
|
|
||||||
.map {
|
|
||||||
case (pluginId, plugins) =>
|
|
||||||
val (plugin, enabled) = plugins.head
|
|
||||||
(plugin, enabled, if (plugins.length > 1) plugins.last._1.pluginVersion else "")
|
|
||||||
}
|
|
||||||
.toList
|
|
||||||
|
|
||||||
html.plugins(plugins, flash.get("info"))
|
|
||||||
})
|
})
|
||||||
|
|
||||||
post("/admin/plugins/_reload")(adminOnly {
|
post("/admin/plugins/_reload")(adminOnly {
|
||||||
PluginRegistry.reload(request.getServletContext(), loadSystemSettings(), request2Session(request).conn)
|
PluginRegistry.reload(request.getServletContext(), loadSystemSettings(), request2Session(request).conn)
|
||||||
flash += "info" -> "All plugins were reloaded."
|
flash.update("info", "All plugins were reloaded.")
|
||||||
redirect("/admin/plugins")
|
redirect("/admin/plugins")
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -398,37 +344,7 @@ trait SystemSettingsControllerBase extends AccountManagementControllerBase {
|
|||||||
if (PluginRegistry().getPlugins().exists(_.pluginId == pluginId)) {
|
if (PluginRegistry().getPlugins().exists(_.pluginId == pluginId)) {
|
||||||
PluginRegistry
|
PluginRegistry
|
||||||
.uninstall(pluginId, request.getServletContext, loadSystemSettings(), request2Session(request).conn)
|
.uninstall(pluginId, request.getServletContext, loadSystemSettings(), request2Session(request).conn)
|
||||||
flash += "info" -> s"${pluginId} was uninstalled."
|
flash.update("info", s"${pluginId} was uninstalled.")
|
||||||
}
|
|
||||||
|
|
||||||
redirect("/admin/plugins")
|
|
||||||
})
|
|
||||||
|
|
||||||
post("/admin/plugins/:pluginId/:version/_install")(adminOnly {
|
|
||||||
if (context.settings.pluginNetworkInstall) {
|
|
||||||
val pluginId = params("pluginId")
|
|
||||||
val version = params("version")
|
|
||||||
val gitbucketVersion = GitBucketCoreModule.getVersions.asScala.last.getVersion
|
|
||||||
|
|
||||||
PluginRepository
|
|
||||||
.getPlugins()
|
|
||||||
.collectFirst {
|
|
||||||
case meta if meta.id == pluginId =>
|
|
||||||
(meta, meta.versions.find(x => x.gitbucketVersion == gitbucketVersion && x.version == version))
|
|
||||||
}
|
|
||||||
.foreach {
|
|
||||||
case (meta, version) =>
|
|
||||||
version.foreach { version =>
|
|
||||||
PluginRegistry.install(
|
|
||||||
pluginId,
|
|
||||||
new java.net.URL(version.url),
|
|
||||||
request.getServletContext,
|
|
||||||
loadSystemSettings(),
|
|
||||||
request2Session(request).conn
|
|
||||||
)
|
|
||||||
flash += "info" -> s"${pluginId}:${version.version} was installed."
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
redirect("/admin/plugins")
|
redirect("/admin/plugins")
|
||||||
@@ -476,7 +392,7 @@ trait SystemSettingsControllerBase extends AccountManagementControllerBase {
|
|||||||
getAccountByUserName(userName, true).map {
|
getAccountByUserName(userName, true).map {
|
||||||
account =>
|
account =>
|
||||||
if (account.isAdmin && (form.isRemoved || !form.isAdmin) && isLastAdministrator(account)) {
|
if (account.isAdmin && (form.isRemoved || !form.isAdmin) && isLastAdministrator(account)) {
|
||||||
flash += "error" -> "Account can't be turned off because this is last one administrator."
|
flash.update("error", "Account can't be turned off because this is last one administrator.")
|
||||||
redirect(s"/admin/users/${userName}/_edituser")
|
redirect(s"/admin/users/${userName}/_edituser")
|
||||||
} else {
|
} else {
|
||||||
if (form.isRemoved) {
|
if (form.isRemoved) {
|
||||||
@@ -601,7 +517,7 @@ trait SystemSettingsControllerBase extends AccountManagementControllerBase {
|
|||||||
response.setHeader("Content-Disposition", "attachment; filename=" + file.getName)
|
response.setHeader("Content-Disposition", "attachment; filename=" + file.getName)
|
||||||
response.setContentLength(file.length.toInt)
|
response.setContentLength(file.length.toInt)
|
||||||
|
|
||||||
using(new FileInputStream(file)) { in =>
|
Using.resource(new FileInputStream(file)) { in =>
|
||||||
IOUtils.copy(in, response.outputStream)
|
IOUtils.copy(in, response.outputStream)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import gitbucket.core.util.Directory._
|
|||||||
import org.scalatra.forms._
|
import org.scalatra.forms._
|
||||||
import org.eclipse.jgit.api.Git
|
import org.eclipse.jgit.api.Git
|
||||||
import org.scalatra.i18n.Messages
|
import org.scalatra.i18n.Messages
|
||||||
|
import scala.util.Using
|
||||||
|
|
||||||
class WikiController
|
class WikiController
|
||||||
extends WikiControllerBase
|
extends WikiControllerBase
|
||||||
@@ -90,7 +91,7 @@ trait WikiControllerBase extends ControllerBase {
|
|||||||
get("/:owner/:repository/wiki/:page/_history")(referrersOnly { repository =>
|
get("/:owner/:repository/wiki/:page/_history")(referrersOnly { repository =>
|
||||||
val pageName = StringUtil.urlDecode(params("page"))
|
val pageName = StringUtil.urlDecode(params("page"))
|
||||||
|
|
||||||
using(Git.open(getWikiRepositoryDir(repository.owner, repository.name))) { git =>
|
Using.resource(Git.open(getWikiRepositoryDir(repository.owner, repository.name))) { git =>
|
||||||
JGitUtil.getCommitLog(git, "master", path = pageName + ".md") match {
|
JGitUtil.getCommitLog(git, "master", path = pageName + ".md") match {
|
||||||
case Right((logs, hasNext)) => html.history(Some(pageName), logs, repository, isEditable(repository))
|
case Right((logs, hasNext)) => html.history(Some(pageName), logs, repository, isEditable(repository))
|
||||||
case Left(_) => NotFound()
|
case Left(_) => NotFound()
|
||||||
@@ -102,7 +103,7 @@ trait WikiControllerBase extends ControllerBase {
|
|||||||
val pageName = StringUtil.urlDecode(params("page"))
|
val pageName = StringUtil.urlDecode(params("page"))
|
||||||
val Array(from, to) = params("commitId").split("\\.\\.\\.")
|
val Array(from, to) = params("commitId").split("\\.\\.\\.")
|
||||||
|
|
||||||
using(Git.open(getWikiRepositoryDir(repository.owner, repository.name))) { git =>
|
Using.resource(Git.open(getWikiRepositoryDir(repository.owner, repository.name))) { git =>
|
||||||
html.compare(
|
html.compare(
|
||||||
Some(pageName),
|
Some(pageName),
|
||||||
from,
|
from,
|
||||||
@@ -118,7 +119,7 @@ trait WikiControllerBase extends ControllerBase {
|
|||||||
get("/:owner/:repository/wiki/_compare/:commitId")(referrersOnly { repository =>
|
get("/:owner/:repository/wiki/_compare/:commitId")(referrersOnly { repository =>
|
||||||
val Array(from, to) = params("commitId").split("\\.\\.\\.")
|
val Array(from, to) = params("commitId").split("\\.\\.\\.")
|
||||||
|
|
||||||
using(Git.open(getWikiRepositoryDir(repository.owner, repository.name))) { git =>
|
Using.resource(Git.open(getWikiRepositoryDir(repository.owner, repository.name))) { git =>
|
||||||
html.compare(
|
html.compare(
|
||||||
None,
|
None,
|
||||||
from,
|
from,
|
||||||
@@ -139,7 +140,7 @@ trait WikiControllerBase extends ControllerBase {
|
|||||||
if (revertWikiPage(repository.owner, repository.name, from, to, context.loginAccount.get, Some(pageName))) {
|
if (revertWikiPage(repository.owner, repository.name, from, to, context.loginAccount.get, Some(pageName))) {
|
||||||
redirect(s"/${repository.owner}/${repository.name}/wiki/${StringUtil.urlEncode(pageName)}")
|
redirect(s"/${repository.owner}/${repository.name}/wiki/${StringUtil.urlEncode(pageName)}")
|
||||||
} else {
|
} else {
|
||||||
flash += "info" -> "This patch was not able to be reversed."
|
flash.update("info", "This patch was not able to be reversed.")
|
||||||
redirect(
|
redirect(
|
||||||
s"/${repository.owner}/${repository.name}/wiki/${StringUtil.urlEncode(pageName)}/_compare/${from}...${to}"
|
s"/${repository.owner}/${repository.name}/wiki/${StringUtil.urlEncode(pageName)}/_compare/${from}...${to}"
|
||||||
)
|
)
|
||||||
@@ -154,7 +155,7 @@ trait WikiControllerBase extends ControllerBase {
|
|||||||
if (revertWikiPage(repository.owner, repository.name, from, to, context.loginAccount.get, None)) {
|
if (revertWikiPage(repository.owner, repository.name, from, to, context.loginAccount.get, None)) {
|
||||||
redirect(s"/${repository.owner}/${repository.name}/wiki")
|
redirect(s"/${repository.owner}/${repository.name}/wiki")
|
||||||
} else {
|
} else {
|
||||||
flash += "info" -> "This patch was not able to be reversed."
|
flash.update("info", "This patch was not able to be reversed.")
|
||||||
redirect(s"/${repository.owner}/${repository.name}/wiki/_compare/${from}...${to}")
|
redirect(s"/${repository.owner}/${repository.name}/wiki/_compare/${from}...${to}")
|
||||||
}
|
}
|
||||||
} else Unauthorized()
|
} else Unauthorized()
|
||||||
@@ -269,7 +270,7 @@ trait WikiControllerBase extends ControllerBase {
|
|||||||
})
|
})
|
||||||
|
|
||||||
get("/:owner/:repository/wiki/_history")(referrersOnly { repository =>
|
get("/:owner/:repository/wiki/_history")(referrersOnly { repository =>
|
||||||
using(Git.open(getWikiRepositoryDir(repository.owner, repository.name))) { git =>
|
Using.resource(Git.open(getWikiRepositoryDir(repository.owner, repository.name))) { git =>
|
||||||
JGitUtil.getCommitLog(git, "master") match {
|
JGitUtil.getCommitLog(git, "master") match {
|
||||||
case Right((logs, hasNext)) => html.history(None, logs, repository, isEditable(repository))
|
case Right((logs, hasNext)) => html.history(None, logs, repository, isEditable(repository))
|
||||||
case Left(_) => NotFound()
|
case Left(_) => NotFound()
|
||||||
@@ -279,7 +280,7 @@ trait WikiControllerBase extends ControllerBase {
|
|||||||
|
|
||||||
get("/:owner/:repository/wiki/_blob/*")(referrersOnly { repository =>
|
get("/:owner/:repository/wiki/_blob/*")(referrersOnly { repository =>
|
||||||
val path = multiParams("splat").head
|
val path = multiParams("splat").head
|
||||||
using(Git.open(getWikiRepositoryDir(repository.owner, repository.name))) { git =>
|
Using.resource(Git.open(getWikiRepositoryDir(repository.owner, repository.name))) { git =>
|
||||||
val revCommit = JGitUtil.getRevCommitFromId(git, git.getRepository.resolve("master"))
|
val revCommit = JGitUtil.getRevCommitFromId(git, git.getRepository.resolve("master"))
|
||||||
|
|
||||||
getPathObjectId(git, path, revCommit).map { objectId =>
|
getPathObjectId(git, path, revCommit).map { objectId =>
|
||||||
|
|||||||
@@ -3,10 +3,11 @@ import gitbucket.core.api.{ApiObject, ApiRef, JsonFormat}
|
|||||||
import gitbucket.core.controller.ControllerBase
|
import gitbucket.core.controller.ControllerBase
|
||||||
import gitbucket.core.util.Directory.getRepositoryDir
|
import gitbucket.core.util.Directory.getRepositoryDir
|
||||||
import gitbucket.core.util.ReferrerAuthenticator
|
import gitbucket.core.util.ReferrerAuthenticator
|
||||||
import gitbucket.core.util.SyntaxSugars.using
|
|
||||||
import gitbucket.core.util.Implicits._
|
import gitbucket.core.util.Implicits._
|
||||||
import org.eclipse.jgit.api.Git
|
import org.eclipse.jgit.api.Git
|
||||||
import scala.collection.JavaConverters._
|
|
||||||
|
import scala.jdk.CollectionConverters._
|
||||||
|
import scala.util.Using
|
||||||
|
|
||||||
trait ApiGitReferenceControllerBase extends ControllerBase {
|
trait ApiGitReferenceControllerBase extends ControllerBase {
|
||||||
self: ReferrerAuthenticator =>
|
self: ReferrerAuthenticator =>
|
||||||
@@ -17,7 +18,7 @@ trait ApiGitReferenceControllerBase extends ControllerBase {
|
|||||||
*/
|
*/
|
||||||
get("/api/v3/repos/:owner/:repository/git/refs/*")(referrersOnly { repository =>
|
get("/api/v3/repos/:owner/:repository/git/refs/*")(referrersOnly { repository =>
|
||||||
val revstr = multiParams("splat").head
|
val revstr = multiParams("splat").head
|
||||||
using(Git.open(getRepositoryDir(params("owner"), params("repository")))) { git =>
|
Using.resource(Git.open(getRepositoryDir(params("owner"), params("repository")))) { git =>
|
||||||
val ref = git.getRepository().findRef(revstr)
|
val ref = git.getRepository().findRef(revstr)
|
||||||
|
|
||||||
if (ref != null) {
|
if (ref != null) {
|
||||||
|
|||||||
@@ -8,12 +8,12 @@ import gitbucket.core.service.PullRequestService.PullRequestLimit
|
|||||||
import gitbucket.core.util.Directory.getRepositoryDir
|
import gitbucket.core.util.Directory.getRepositoryDir
|
||||||
import gitbucket.core.util.Implicits._
|
import gitbucket.core.util.Implicits._
|
||||||
import gitbucket.core.util.JGitUtil.CommitInfo
|
import gitbucket.core.util.JGitUtil.CommitInfo
|
||||||
import gitbucket.core.util.SyntaxSugars.using
|
|
||||||
import gitbucket.core.util._
|
import gitbucket.core.util._
|
||||||
import org.eclipse.jgit.api.Git
|
import org.eclipse.jgit.api.Git
|
||||||
import org.scalatra.NoContent
|
import org.scalatra.NoContent
|
||||||
|
import scala.util.Using
|
||||||
|
|
||||||
import scala.collection.JavaConverters._
|
import scala.jdk.CollectionConverters._
|
||||||
|
|
||||||
trait ApiPullRequestControllerBase extends ControllerBase {
|
trait ApiPullRequestControllerBase extends ControllerBase {
|
||||||
self: AccountService
|
self: AccountService
|
||||||
@@ -114,6 +114,7 @@ trait ApiPullRequestControllerBase extends ControllerBase {
|
|||||||
requestBranch = reqBranch,
|
requestBranch = reqBranch,
|
||||||
commitIdFrom = commitIdFrom.getName,
|
commitIdFrom = commitIdFrom.getName,
|
||||||
commitIdTo = commitIdTo.getName,
|
commitIdTo = commitIdTo.getName,
|
||||||
|
isDraft = false,
|
||||||
loginAccount = context.loginAccount.get
|
loginAccount = context.loginAccount.get
|
||||||
)
|
)
|
||||||
getApiPullRequest(repository, issueId).map(JsonFormat(_))
|
getApiPullRequest(repository, issueId).map(JsonFormat(_))
|
||||||
@@ -141,6 +142,7 @@ trait ApiPullRequestControllerBase extends ControllerBase {
|
|||||||
requestBranch = reqBranch,
|
requestBranch = reqBranch,
|
||||||
commitIdFrom = commitIdFrom.getName,
|
commitIdFrom = commitIdFrom.getName,
|
||||||
commitIdTo = commitIdTo.getName,
|
commitIdTo = commitIdTo.getName,
|
||||||
|
isDraft = false,
|
||||||
loginAccount = context.loginAccount.get
|
loginAccount = context.loginAccount.get
|
||||||
)
|
)
|
||||||
getApiPullRequest(repository, createPullReqAlt.issue).map(JsonFormat(_))
|
getApiPullRequest(repository, createPullReqAlt.issue).map(JsonFormat(_))
|
||||||
@@ -171,7 +173,7 @@ trait ApiPullRequestControllerBase extends ControllerBase {
|
|||||||
issueId =>
|
issueId =>
|
||||||
getPullRequest(owner, name, issueId) map {
|
getPullRequest(owner, name, issueId) map {
|
||||||
case (issue, pullreq) =>
|
case (issue, pullreq) =>
|
||||||
using(Git.open(getRepositoryDir(owner, name))) { git =>
|
Using.resource(Git.open(getRepositoryDir(owner, name))) { git =>
|
||||||
val oldId = git.getRepository.resolve(pullreq.commitIdFrom)
|
val oldId = git.getRepository.resolve(pullreq.commitIdFrom)
|
||||||
val newId = git.getRepository.resolve(pullreq.commitIdTo)
|
val newId = git.getRepository.resolve(pullreq.commitIdTo)
|
||||||
val repoFullName = RepositoryName(repository)
|
val repoFullName = RepositoryName(repository)
|
||||||
|
|||||||
@@ -3,11 +3,11 @@ import gitbucket.core.api._
|
|||||||
import gitbucket.core.controller.ControllerBase
|
import gitbucket.core.controller.ControllerBase
|
||||||
import gitbucket.core.service.{AccountService, ProtectedBranchService, RepositoryService}
|
import gitbucket.core.service.{AccountService, ProtectedBranchService, RepositoryService}
|
||||||
import gitbucket.core.util._
|
import gitbucket.core.util._
|
||||||
import gitbucket.core.util.SyntaxSugars._
|
|
||||||
import gitbucket.core.util.Directory._
|
import gitbucket.core.util.Directory._
|
||||||
import gitbucket.core.util.Implicits._
|
import gitbucket.core.util.Implicits._
|
||||||
import gitbucket.core.util.JGitUtil.getBranches
|
import gitbucket.core.util.JGitUtil.getBranches
|
||||||
import org.eclipse.jgit.api.Git
|
import org.eclipse.jgit.api.Git
|
||||||
|
import scala.util.Using
|
||||||
|
|
||||||
trait ApiRepositoryBranchControllerBase extends ControllerBase {
|
trait ApiRepositoryBranchControllerBase extends ControllerBase {
|
||||||
self: RepositoryService
|
self: RepositoryService
|
||||||
@@ -25,7 +25,7 @@ trait ApiRepositoryBranchControllerBase extends ControllerBase {
|
|||||||
* https://developer.github.com/v3/repos/branches/#list-branches
|
* https://developer.github.com/v3/repos/branches/#list-branches
|
||||||
*/
|
*/
|
||||||
get("/api/v3/repos/:owner/:repository/branches")(referrersOnly { repository =>
|
get("/api/v3/repos/:owner/:repository/branches")(referrersOnly { repository =>
|
||||||
using(Git.open(getRepositoryDir(repository.owner, repository.name))) { git =>
|
Using.resource(Git.open(getRepositoryDir(repository.owner, repository.name))) { git =>
|
||||||
JsonFormat(
|
JsonFormat(
|
||||||
JGitUtil
|
JGitUtil
|
||||||
.getBranches(
|
.getBranches(
|
||||||
@@ -45,7 +45,7 @@ trait ApiRepositoryBranchControllerBase extends ControllerBase {
|
|||||||
* https://developer.github.com/v3/repos/branches/#get-branch
|
* https://developer.github.com/v3/repos/branches/#get-branch
|
||||||
*/
|
*/
|
||||||
get("/api/v3/repos/:owner/:repository/branches/*")(referrersOnly { repository =>
|
get("/api/v3/repos/:owner/:repository/branches/*")(referrersOnly { repository =>
|
||||||
using(Git.open(getRepositoryDir(repository.owner, repository.name))) {
|
Using.resource(Git.open(getRepositoryDir(repository.owner, repository.name))) {
|
||||||
git =>
|
git =>
|
||||||
(for {
|
(for {
|
||||||
branch <- params.get("splat") if repository.branchList.contains(branch)
|
branch <- params.get("splat") if repository.branchList.contains(branch)
|
||||||
@@ -214,7 +214,7 @@ trait ApiRepositoryBranchControllerBase extends ControllerBase {
|
|||||||
*/
|
*/
|
||||||
patch("/api/v3/repos/:owner/:repository/branches/*")(ownerOnly { repository =>
|
patch("/api/v3/repos/:owner/:repository/branches/*")(ownerOnly { repository =>
|
||||||
import gitbucket.core.api._
|
import gitbucket.core.api._
|
||||||
using(Git.open(getRepositoryDir(repository.owner, repository.name))) {
|
Using.resource(Git.open(getRepositoryDir(repository.owner, repository.name))) {
|
||||||
git =>
|
git =>
|
||||||
(for {
|
(for {
|
||||||
branch <- params.get("splat") if repository.branchList.contains(branch)
|
branch <- params.get("splat") if repository.branchList.contains(branch)
|
||||||
|
|||||||
@@ -7,9 +7,9 @@ import gitbucket.core.util.Directory.getRepositoryDir
|
|||||||
import gitbucket.core.util.Implicits._
|
import gitbucket.core.util.Implicits._
|
||||||
import gitbucket.core.util.JGitUtil.CommitInfo
|
import gitbucket.core.util.JGitUtil.CommitInfo
|
||||||
import gitbucket.core.util.{JGitUtil, ReferrerAuthenticator, RepositoryName}
|
import gitbucket.core.util.{JGitUtil, ReferrerAuthenticator, RepositoryName}
|
||||||
import gitbucket.core.util.SyntaxSugars.using
|
|
||||||
import org.eclipse.jgit.api.Git
|
import org.eclipse.jgit.api.Git
|
||||||
import org.eclipse.jgit.revwalk.RevWalk
|
import org.eclipse.jgit.revwalk.RevWalk
|
||||||
|
import scala.util.Using
|
||||||
|
|
||||||
trait ApiRepositoryCommitControllerBase extends ControllerBase {
|
trait ApiRepositoryCommitControllerBase extends ControllerBase {
|
||||||
self: AccountService with CommitsService with ReferrerAuthenticator =>
|
self: AccountService with CommitsService with ReferrerAuthenticator =>
|
||||||
@@ -27,11 +27,11 @@ trait ApiRepositoryCommitControllerBase extends ControllerBase {
|
|||||||
val name = repository.name
|
val name = repository.name
|
||||||
val sha = params("sha")
|
val sha = params("sha")
|
||||||
|
|
||||||
using(Git.open(getRepositoryDir(owner, name))) {
|
Using.resource(Git.open(getRepositoryDir(owner, name))) {
|
||||||
git =>
|
git =>
|
||||||
val repo = git.getRepository
|
val repo = git.getRepository
|
||||||
val objectId = repo.resolve(sha)
|
val objectId = repo.resolve(sha)
|
||||||
val commitInfo = using(new RevWalk(repo)) { revWalk =>
|
val commitInfo = Using.resource(new RevWalk(repo)) { revWalk =>
|
||||||
new CommitInfo(revWalk.parseCommit(objectId))
|
new CommitInfo(revWalk.parseCommit(objectId))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,10 +5,10 @@ import gitbucket.core.service.{RepositoryCommitFileService, RepositoryService}
|
|||||||
import gitbucket.core.util.Directory.getRepositoryDir
|
import gitbucket.core.util.Directory.getRepositoryDir
|
||||||
import gitbucket.core.util.JGitUtil.{FileInfo, getContentFromId, getFileList}
|
import gitbucket.core.util.JGitUtil.{FileInfo, getContentFromId, getFileList}
|
||||||
import gitbucket.core.util._
|
import gitbucket.core.util._
|
||||||
import gitbucket.core.util.SyntaxSugars.using
|
|
||||||
import gitbucket.core.view.helpers.{isRenderable, renderMarkup}
|
import gitbucket.core.view.helpers.{isRenderable, renderMarkup}
|
||||||
import gitbucket.core.util.Implicits._
|
import gitbucket.core.util.Implicits._
|
||||||
import org.eclipse.jgit.api.Git
|
import org.eclipse.jgit.api.Git
|
||||||
|
import scala.util.Using
|
||||||
|
|
||||||
trait ApiRepositoryContentsControllerBase extends ControllerBase {
|
trait ApiRepositoryContentsControllerBase extends ControllerBase {
|
||||||
self: ReferrerAuthenticator with WritableUsersAuthenticator with RepositoryCommitFileService =>
|
self: ReferrerAuthenticator with WritableUsersAuthenticator with RepositoryCommitFileService =>
|
||||||
@@ -45,7 +45,7 @@ trait ApiRepositoryContentsControllerBase extends ControllerBase {
|
|||||||
getFileList(git, revision, dirName).find(f => f.name.equals(fileName))
|
getFileList(git, revision, dirName).find(f => f.name.equals(fileName))
|
||||||
}
|
}
|
||||||
|
|
||||||
using(Git.open(getRepositoryDir(params("owner"), params("repository")))) { git =>
|
Using.resource(Git.open(getRepositoryDir(params("owner"), params("repository")))) { git =>
|
||||||
val fileList = getFileList(git, refStr, path)
|
val fileList = getFileList(git, refStr, path)
|
||||||
if (fileList.isEmpty) { // file or NotFound
|
if (fileList.isEmpty) { // file or NotFound
|
||||||
getFileInfo(git, refStr, path)
|
getFileInfo(git, refStr, path)
|
||||||
@@ -113,7 +113,7 @@ trait ApiRepositoryContentsControllerBase extends ControllerBase {
|
|||||||
data <- extractFromJsonBody[CreateAFile]
|
data <- extractFromJsonBody[CreateAFile]
|
||||||
} yield {
|
} yield {
|
||||||
val branch = data.branch.getOrElse(repository.repository.defaultBranch)
|
val branch = data.branch.getOrElse(repository.repository.defaultBranch)
|
||||||
val commit = using(Git.open(getRepositoryDir(repository.owner, repository.name))) { git =>
|
val commit = Using.resource(Git.open(getRepositoryDir(repository.owner, repository.name))) { git =>
|
||||||
val revCommit = JGitUtil.getRevCommitFromId(git, git.getRepository.resolve(branch))
|
val revCommit = JGitUtil.getRevCommitFromId(git, git.getRepository.resolve(branch))
|
||||||
revCommit.name
|
revCommit.name
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,12 +6,12 @@ import gitbucket.core.servlet.Database
|
|||||||
import gitbucket.core.util.Directory.getRepositoryDir
|
import gitbucket.core.util.Directory.getRepositoryDir
|
||||||
import gitbucket.core.util._
|
import gitbucket.core.util._
|
||||||
import gitbucket.core.util.Implicits._
|
import gitbucket.core.util.Implicits._
|
||||||
import gitbucket.core.util.SyntaxSugars.using
|
|
||||||
import gitbucket.core.model.Profile.profile.blockingApi._
|
import gitbucket.core.model.Profile.profile.blockingApi._
|
||||||
import org.eclipse.jgit.api.Git
|
import org.eclipse.jgit.api.Git
|
||||||
|
|
||||||
import scala.concurrent.Await
|
import scala.concurrent.Await
|
||||||
import scala.concurrent.duration.Duration
|
import scala.concurrent.duration.Duration
|
||||||
|
import scala.util.Using
|
||||||
|
|
||||||
trait ApiRepositoryControllerBase extends ControllerBase {
|
trait ApiRepositoryControllerBase extends ControllerBase {
|
||||||
self: RepositoryService
|
self: RepositoryService
|
||||||
@@ -193,7 +193,7 @@ trait ApiRepositoryControllerBase extends ControllerBase {
|
|||||||
*/
|
*/
|
||||||
get("/api/v3/repos/:owner/:repository/raw/*")(referrersOnly { repository =>
|
get("/api/v3/repos/:owner/:repository/raw/*")(referrersOnly { repository =>
|
||||||
val (id, path) = repository.splitPath(multiParams("splat").head)
|
val (id, path) = repository.splitPath(multiParams("splat").head)
|
||||||
using(Git.open(getRepositoryDir(repository.owner, repository.name))) { git =>
|
Using.resource(Git.open(getRepositoryDir(repository.owner, repository.name))) { git =>
|
||||||
val revCommit = JGitUtil.getRevCommitFromId(git, git.getRepository.resolve(id))
|
val revCommit = JGitUtil.getRevCommitFromId(git, git.getRepository.resolve(id))
|
||||||
|
|
||||||
getPathObjectId(git, path, revCommit).map { objectId =>
|
getPathObjectId(git, path, revCommit).map { objectId =>
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ trait PullRequestComponent extends TemplateComponent { self: Profile =>
|
|||||||
val requestBranch = column[String]("REQUEST_BRANCH")
|
val requestBranch = column[String]("REQUEST_BRANCH")
|
||||||
val commitIdFrom = column[String]("COMMIT_ID_FROM")
|
val commitIdFrom = column[String]("COMMIT_ID_FROM")
|
||||||
val commitIdTo = column[String]("COMMIT_ID_TO")
|
val commitIdTo = column[String]("COMMIT_ID_TO")
|
||||||
|
val isDraft = column[Boolean]("IS_DRAFT")
|
||||||
def * =
|
def * =
|
||||||
(
|
(
|
||||||
userName,
|
userName,
|
||||||
@@ -22,7 +23,8 @@ trait PullRequestComponent extends TemplateComponent { self: Profile =>
|
|||||||
requestRepositoryName,
|
requestRepositoryName,
|
||||||
requestBranch,
|
requestBranch,
|
||||||
commitIdFrom,
|
commitIdFrom,
|
||||||
commitIdTo
|
commitIdTo,
|
||||||
|
isDraft
|
||||||
) <> (PullRequest.tupled, PullRequest.unapply)
|
) <> (PullRequest.tupled, PullRequest.unapply)
|
||||||
|
|
||||||
def byPrimaryKey(userName: String, repositoryName: String, issueId: Int) =
|
def byPrimaryKey(userName: String, repositoryName: String, issueId: Int) =
|
||||||
@@ -41,5 +43,6 @@ case class PullRequest(
|
|||||||
requestRepositoryName: String,
|
requestRepositoryName: String,
|
||||||
requestBranch: String,
|
requestBranch: String,
|
||||||
commitIdFrom: String,
|
commitIdFrom: String,
|
||||||
commitIdTo: String
|
commitIdTo: String,
|
||||||
|
isDraft: Boolean
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -6,10 +6,10 @@ import gitbucket.core.controller.{Context, ControllerBase}
|
|||||||
import gitbucket.core.model.{Account, Issue}
|
import gitbucket.core.model.{Account, Issue}
|
||||||
import gitbucket.core.service.RepositoryService.RepositoryInfo
|
import gitbucket.core.service.RepositoryService.RepositoryInfo
|
||||||
import gitbucket.core.service.SystemSettingsService.SystemSettings
|
import gitbucket.core.service.SystemSettingsService.SystemSettings
|
||||||
import gitbucket.core.util.SyntaxSugars._
|
|
||||||
import io.github.gitbucket.solidbase.model.Version
|
import io.github.gitbucket.solidbase.model.Version
|
||||||
import org.apache.sshd.server.command.Command
|
import org.apache.sshd.server.command.Command
|
||||||
import play.twirl.api.Html
|
import play.twirl.api.Html
|
||||||
|
import scala.util.Using
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Trait for define plugin interface.
|
* Trait for define plugin interface.
|
||||||
@@ -434,7 +434,7 @@ abstract class Plugin {
|
|||||||
* Helper method to get a resource from classpath.
|
* Helper method to get a resource from classpath.
|
||||||
*/
|
*/
|
||||||
protected def fromClassPath(path: String): Array[Byte] =
|
protected def fromClassPath(path: String): Array[Byte] =
|
||||||
using(getClass.getClassLoader.getResourceAsStream(path)) { in =>
|
Using.resource(getClass.getClassLoader.getResourceAsStream(path)) { in =>
|
||||||
val bytes = new Array[Byte](in.available)
|
val bytes = new Array[Byte](in.available)
|
||||||
in.read(bytes)
|
in.read(bytes)
|
||||||
bytes
|
bytes
|
||||||
|
|||||||
@@ -17,17 +17,15 @@ import gitbucket.core.service.SystemSettingsService
|
|||||||
import gitbucket.core.service.SystemSettingsService.SystemSettings
|
import gitbucket.core.service.SystemSettingsService.SystemSettings
|
||||||
import gitbucket.core.util.DatabaseConfig
|
import gitbucket.core.util.DatabaseConfig
|
||||||
import gitbucket.core.util.Directory._
|
import gitbucket.core.util.Directory._
|
||||||
import gitbucket.core.util.HttpClientUtil._
|
|
||||||
import io.github.gitbucket.solidbase.Solidbase
|
import io.github.gitbucket.solidbase.Solidbase
|
||||||
import io.github.gitbucket.solidbase.manager.JDBCVersionManager
|
import io.github.gitbucket.solidbase.manager.JDBCVersionManager
|
||||||
import io.github.gitbucket.solidbase.model.Module
|
import io.github.gitbucket.solidbase.model.Module
|
||||||
import org.apache.commons.io.FileUtils
|
import org.apache.commons.io.FileUtils
|
||||||
import org.apache.http.client.methods.HttpGet
|
|
||||||
import org.apache.sshd.server.command.Command
|
import org.apache.sshd.server.command.Command
|
||||||
import org.slf4j.LoggerFactory
|
import org.slf4j.LoggerFactory
|
||||||
import play.twirl.api.Html
|
import play.twirl.api.Html
|
||||||
|
|
||||||
import scala.collection.JavaConverters._
|
import scala.jdk.CollectionConverters._
|
||||||
|
|
||||||
class PluginRegistry {
|
class PluginRegistry {
|
||||||
|
|
||||||
@@ -227,40 +225,6 @@ object PluginRegistry {
|
|||||||
initialize(context, settings, conn)
|
initialize(context, settings, conn)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Install a plugin from a specified jar file.
|
|
||||||
*/
|
|
||||||
def install(
|
|
||||||
pluginId: String,
|
|
||||||
url: java.net.URL,
|
|
||||||
context: ServletContext,
|
|
||||||
settings: SystemSettings,
|
|
||||||
conn: java.sql.Connection
|
|
||||||
): Unit =
|
|
||||||
synchronized {
|
|
||||||
shutdown(context, settings)
|
|
||||||
|
|
||||||
new File(PluginHome)
|
|
||||||
.listFiles((_: File, name: String) => {
|
|
||||||
name.startsWith(s"gitbucket-${pluginId}-plugin") && name.endsWith(".jar")
|
|
||||||
})
|
|
||||||
.foreach(_.delete())
|
|
||||||
|
|
||||||
withHttpClient(settings.pluginProxy) { httpClient =>
|
|
||||||
val httpGet = new HttpGet(url.toString)
|
|
||||||
try {
|
|
||||||
val response = httpClient.execute(httpGet)
|
|
||||||
val in = response.getEntity.getContent
|
|
||||||
FileUtils.copyToFile(in, new File(PluginHome, new File(url.getFile).getName))
|
|
||||||
} finally {
|
|
||||||
httpGet.releaseConnection()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
instance = new PluginRegistry()
|
|
||||||
initialize(context, settings, conn)
|
|
||||||
}
|
|
||||||
|
|
||||||
private def listPluginJars(dir: File): Seq[File] = {
|
private def listPluginJars(dir: File): Seq[File] = {
|
||||||
dir
|
dir
|
||||||
.listFiles(new FilenameFilter {
|
.listFiles(new FilenameFilter {
|
||||||
@@ -449,7 +413,6 @@ case class PluginInfo(
|
|||||||
|
|
||||||
class PluginWatchThread(context: ServletContext, dir: String) extends Thread with SystemSettingsService {
|
class PluginWatchThread(context: ServletContext, dir: String) extends Thread with SystemSettingsService {
|
||||||
import gitbucket.core.model.Profile.profile.blockingApi._
|
import gitbucket.core.model.Profile.profile.blockingApi._
|
||||||
import scala.collection.JavaConverters._
|
|
||||||
|
|
||||||
private val logger = LoggerFactory.getLogger(classOf[PluginWatchThread])
|
private val logger = LoggerFactory.getLogger(classOf[PluginWatchThread])
|
||||||
|
|
||||||
@@ -479,7 +442,7 @@ class PluginWatchThread(context: ServletContext, dir: String) extends Thread wit
|
|||||||
}
|
}
|
||||||
if (events.nonEmpty) {
|
if (events.nonEmpty) {
|
||||||
events.foreach { event =>
|
events.foreach { event =>
|
||||||
logger.info(event.kind + ": " + event.context)
|
logger.info(s"${event.kind}: ${event.context}")
|
||||||
}
|
}
|
||||||
new Thread {
|
new Thread {
|
||||||
override def run(): Unit = {
|
override def run(): Unit = {
|
||||||
|
|||||||
@@ -1,59 +0,0 @@
|
|||||||
package gitbucket.core.plugin
|
|
||||||
|
|
||||||
import gitbucket.core.controller.Context
|
|
||||||
import gitbucket.core.util.SyntaxSugars.using
|
|
||||||
import gitbucket.core.util.HttpClientUtil._
|
|
||||||
import org.json4s._
|
|
||||||
import org.apache.commons.io.IOUtils
|
|
||||||
|
|
||||||
import org.apache.http.client.methods.HttpGet
|
|
||||||
import org.slf4j.LoggerFactory
|
|
||||||
|
|
||||||
object PluginRepository {
|
|
||||||
private val logger = LoggerFactory.getLogger(getClass)
|
|
||||||
implicit val formats = DefaultFormats
|
|
||||||
|
|
||||||
def parsePluginJson(json: String): Seq[PluginMetadata] = {
|
|
||||||
org.json4s.jackson.JsonMethods.parse(json).extract[Seq[PluginMetadata]]
|
|
||||||
}
|
|
||||||
|
|
||||||
def getPlugins()(implicit context: Context): Seq[PluginMetadata] = {
|
|
||||||
try {
|
|
||||||
val url = new java.net.URL("https://plugins.gitbucket-community.org/releases/plugins.json")
|
|
||||||
|
|
||||||
withHttpClient(context.settings.pluginProxy) { httpClient =>
|
|
||||||
val httpGet = new HttpGet(url.toString)
|
|
||||||
try {
|
|
||||||
val response = httpClient.execute(httpGet)
|
|
||||||
using(response.getEntity.getContent) { in =>
|
|
||||||
val str = IOUtils.toString(in, "UTF-8")
|
|
||||||
parsePluginJson(str)
|
|
||||||
}
|
|
||||||
} finally {
|
|
||||||
httpGet.releaseConnection()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch {
|
|
||||||
case t: Throwable =>
|
|
||||||
logger.warn("Failed to access to the plugin repository: " + t.toString)
|
|
||||||
Nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Mapped from plugins.json
|
|
||||||
case class PluginMetadata(
|
|
||||||
id: String,
|
|
||||||
name: String,
|
|
||||||
description: String,
|
|
||||||
versions: Seq[VersionDef],
|
|
||||||
default: Boolean = false
|
|
||||||
) {
|
|
||||||
lazy val latestVersion: VersionDef = versions.last
|
|
||||||
}
|
|
||||||
|
|
||||||
case class VersionDef(
|
|
||||||
version: String,
|
|
||||||
url: String,
|
|
||||||
gitbucketVersion: String
|
|
||||||
)
|
|
||||||
@@ -3,14 +3,14 @@ package gitbucket.core.service
|
|||||||
import java.io.ByteArrayInputStream
|
import java.io.ByteArrayInputStream
|
||||||
|
|
||||||
import gitbucket.core.model.GpgKey
|
import gitbucket.core.model.GpgKey
|
||||||
|
|
||||||
import collection.JavaConverters._
|
|
||||||
import gitbucket.core.model.Profile._
|
import gitbucket.core.model.Profile._
|
||||||
import gitbucket.core.model.Profile.profile.blockingApi._
|
import gitbucket.core.model.Profile.profile.blockingApi._
|
||||||
import org.bouncycastle.bcpg.ArmoredInputStream
|
import org.bouncycastle.bcpg.ArmoredInputStream
|
||||||
import org.bouncycastle.openpgp.PGPPublicKeyRing
|
import org.bouncycastle.openpgp.PGPPublicKeyRing
|
||||||
import org.bouncycastle.openpgp.bc.BcPGPObjectFactory
|
import org.bouncycastle.openpgp.bc.BcPGPObjectFactory
|
||||||
|
|
||||||
|
import scala.jdk.CollectionConverters._
|
||||||
|
|
||||||
trait GpgKeyService {
|
trait GpgKeyService {
|
||||||
def getGpgPublicKeys(userName: String)(implicit s: Session): List[GpgKey] =
|
def getGpgPublicKeys(userName: String)(implicit s: Session): List[GpgKey] =
|
||||||
GpgKeys.filter(_.userName === userName.bind).sortBy(_.gpgKeyId).list
|
GpgKeys.filter(_.userName === userName.bind).sortBy(_.gpgKeyId).list
|
||||||
|
|||||||
@@ -752,7 +752,7 @@ trait IssuesService {
|
|||||||
implicit s: Session
|
implicit s: Session
|
||||||
): Unit = {
|
): Unit = {
|
||||||
extractIssueId(message).foreach { issueId =>
|
extractIssueId(message).foreach { issueId =>
|
||||||
val content = fromIssue.issueId + ":" + fromIssue.title
|
val content = s"${fromIssue.issueId}:${fromIssue.title}"
|
||||||
if (getIssue(owner, repository, issueId).isDefined) {
|
if (getIssue(owner, repository, issueId).isDefined) {
|
||||||
// Not add if refer comment already exist.
|
// Not add if refer comment already exist.
|
||||||
if (!getComments(owner, repository, issueId.toInt).exists { x =>
|
if (!getComments(owner, repository, issueId.toInt).exists { x =>
|
||||||
|
|||||||
@@ -7,9 +7,6 @@ import gitbucket.core.plugin.PluginRegistry
|
|||||||
import gitbucket.core.service.RepositoryService.RepositoryInfo
|
import gitbucket.core.service.RepositoryService.RepositoryInfo
|
||||||
import gitbucket.core.util.Directory._
|
import gitbucket.core.util.Directory._
|
||||||
import gitbucket.core.util.{JGitUtil, LockUtil}
|
import gitbucket.core.util.{JGitUtil, LockUtil}
|
||||||
import gitbucket.core.util.SyntaxSugars._
|
|
||||||
import gitbucket.core.model.Profile._
|
|
||||||
import gitbucket.core.model.Profile.profile._
|
|
||||||
import gitbucket.core.model.Profile.profile.blockingApi._
|
import gitbucket.core.model.Profile.profile.blockingApi._
|
||||||
import org.eclipse.jgit.merge.{MergeStrategy, Merger, RecursiveMerger}
|
import org.eclipse.jgit.merge.{MergeStrategy, Merger, RecursiveMerger}
|
||||||
import org.eclipse.jgit.api.Git
|
import org.eclipse.jgit.api.Git
|
||||||
@@ -18,7 +15,8 @@ import org.eclipse.jgit.errors.NoMergeBaseException
|
|||||||
import org.eclipse.jgit.lib.{CommitBuilder, ObjectId, PersonIdent, Repository}
|
import org.eclipse.jgit.lib.{CommitBuilder, ObjectId, PersonIdent, Repository}
|
||||||
import org.eclipse.jgit.revwalk.{RevCommit, RevWalk}
|
import org.eclipse.jgit.revwalk.{RevCommit, RevWalk}
|
||||||
|
|
||||||
import scala.collection.JavaConverters._
|
import scala.jdk.CollectionConverters._
|
||||||
|
import scala.util.Using
|
||||||
|
|
||||||
trait MergeService {
|
trait MergeService {
|
||||||
self: AccountService
|
self: AccountService
|
||||||
@@ -35,7 +33,7 @@ trait MergeService {
|
|||||||
* Returns true if conflict will be caused.
|
* Returns true if conflict will be caused.
|
||||||
*/
|
*/
|
||||||
def checkConflict(userName: String, repositoryName: String, branch: String, issueId: Int): Option[String] = {
|
def checkConflict(userName: String, repositoryName: String, branch: String, issueId: Int): Option[String] = {
|
||||||
using(Git.open(getRepositoryDir(userName, repositoryName))) { git =>
|
Using.resource(Git.open(getRepositoryDir(userName, repositoryName))) { git =>
|
||||||
new MergeCacheInfo(git, branch, issueId).checkConflict()
|
new MergeCacheInfo(git, branch, issueId).checkConflict()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -52,7 +50,7 @@ trait MergeService {
|
|||||||
branch: String,
|
branch: String,
|
||||||
issueId: Int
|
issueId: Int
|
||||||
): Option[Option[String]] = {
|
): Option[Option[String]] = {
|
||||||
using(Git.open(getRepositoryDir(userName, repositoryName))) { git =>
|
Using.resource(Git.open(getRepositoryDir(userName, repositoryName))) { git =>
|
||||||
new MergeCacheInfo(git, branch, issueId).checkConflictCache()
|
new MergeCacheInfo(git, branch, issueId).checkConflictCache()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -99,7 +97,7 @@ trait MergeService {
|
|||||||
requestBranch: String,
|
requestBranch: String,
|
||||||
issueId: Int
|
issueId: Int
|
||||||
): Unit = {
|
): Unit = {
|
||||||
using(Git.open(getRepositoryDir(userName, repositoryName))) { git =>
|
Using.resource(Git.open(getRepositoryDir(userName, repositoryName))) { git =>
|
||||||
git.fetch
|
git.fetch
|
||||||
.setRemote(getRepositoryDir(requestUserName, requestRepositoryName).toURI.toString)
|
.setRemote(getRepositoryDir(requestUserName, requestRepositoryName).toURI.toString)
|
||||||
.setRefSpecs(new RefSpec(s"refs/heads/${requestBranch}:refs/pull/${issueId}/head"))
|
.setRefSpecs(new RefSpec(s"refs/heads/${requestBranch}:refs/pull/${issueId}/head"))
|
||||||
@@ -118,7 +116,7 @@ trait MergeService {
|
|||||||
remoteRepositoryName: String,
|
remoteRepositoryName: String,
|
||||||
remoteBranch: String
|
remoteBranch: String
|
||||||
): Either[String, (ObjectId, ObjectId, ObjectId)] = {
|
): Either[String, (ObjectId, ObjectId, ObjectId)] = {
|
||||||
using(Git.open(getRepositoryDir(localUserName, localRepositoryName))) { git =>
|
Using.resource(Git.open(getRepositoryDir(localUserName, localRepositoryName))) { git =>
|
||||||
val remoteRefName = s"refs/heads/${remoteBranch}"
|
val remoteRefName = s"refs/heads/${remoteBranch}"
|
||||||
val tmpRefName = s"refs/remote-temp/${remoteUserName}/${remoteRepositoryName}/${remoteBranch}"
|
val tmpRefName = s"refs/remote-temp/${remoteUserName}/${remoteRepositoryName}/${remoteBranch}"
|
||||||
val refSpec = new RefSpec(s"${remoteRefName}:${tmpRefName}").setForceUpdate(true)
|
val refSpec = new RefSpec(s"${remoteRefName}:${tmpRefName}").setForceUpdate(true)
|
||||||
@@ -177,7 +175,7 @@ trait MergeService {
|
|||||||
val remoteRepositoryName = remoteRepository.name
|
val remoteRepositoryName = remoteRepository.name
|
||||||
tryMergeRemote(localUserName, localRepositoryName, localBranch, remoteUserName, remoteRepositoryName, remoteBranch).map {
|
tryMergeRemote(localUserName, localRepositoryName, localBranch, remoteUserName, remoteRepositoryName, remoteBranch).map {
|
||||||
case (newTreeId, oldBaseId, oldHeadId) =>
|
case (newTreeId, oldBaseId, oldHeadId) =>
|
||||||
using(Git.open(getRepositoryDir(localUserName, localRepositoryName))) { git =>
|
Using.resource(Git.open(getRepositoryDir(localUserName, localRepositoryName))) { git =>
|
||||||
val existIds = JGitUtil.getAllCommitIds(git).toSet
|
val existIds = JGitUtil.getAllCommitIds(git).toSet
|
||||||
|
|
||||||
val committer = new PersonIdent(loginAccount.fullName, loginAccount.mailAddress)
|
val committer = new PersonIdent(loginAccount.fullName, loginAccount.mailAddress)
|
||||||
@@ -252,135 +250,139 @@ trait MergeService {
|
|||||||
issueId: Int,
|
issueId: Int,
|
||||||
loginAccount: Account,
|
loginAccount: Account,
|
||||||
message: String,
|
message: String,
|
||||||
strategy: String
|
strategy: String,
|
||||||
|
isDraft: Boolean
|
||||||
)(implicit s: Session, c: JsonFormat.Context, context: Context): Either[String, ObjectId] = {
|
)(implicit s: Session, c: JsonFormat.Context, context: Context): Either[String, ObjectId] = {
|
||||||
if (repository.repository.options.mergeOptions.split(",").contains(strategy)) {
|
if (!isDraft) {
|
||||||
LockUtil.lock(s"${repository.owner}/${repository.name}") {
|
if (repository.repository.options.mergeOptions.split(",").contains(strategy)) {
|
||||||
getPullRequest(repository.owner, repository.name, issueId)
|
LockUtil.lock(s"${repository.owner}/${repository.name}") {
|
||||||
.map {
|
getPullRequest(repository.owner, repository.name, issueId)
|
||||||
case (issue, pullreq) =>
|
.map {
|
||||||
using(Git.open(getRepositoryDir(repository.owner, repository.name))) { git =>
|
case (issue, pullreq) =>
|
||||||
// mark issue as merged and close.
|
Using.resource(Git.open(getRepositoryDir(repository.owner, repository.name))) { git =>
|
||||||
val commentId =
|
// mark issue as merged and close.
|
||||||
createComment(repository.owner, repository.name, loginAccount.userName, issueId, message, "merge")
|
val commentId =
|
||||||
createComment(repository.owner, repository.name, loginAccount.userName, issueId, "Close", "close")
|
createComment(repository.owner, repository.name, loginAccount.userName, issueId, message, "merge")
|
||||||
updateClosed(repository.owner, repository.name, issueId, true)
|
createComment(repository.owner, repository.name, loginAccount.userName, issueId, "Close", "close")
|
||||||
|
updateClosed(repository.owner, repository.name, issueId, true)
|
||||||
|
|
||||||
// record activity
|
// record activity
|
||||||
recordMergeActivity(repository.owner, repository.name, loginAccount.userName, issueId, message)
|
recordMergeActivity(repository.owner, repository.name, loginAccount.userName, issueId, message)
|
||||||
|
|
||||||
val (commits, _) = getRequestCompareInfo(
|
val (commits, _) = getRequestCompareInfo(
|
||||||
repository.owner,
|
repository.owner,
|
||||||
repository.name,
|
repository.name,
|
||||||
pullreq.commitIdFrom,
|
pullreq.commitIdFrom,
|
||||||
pullreq.requestUserName,
|
pullreq.requestUserName,
|
||||||
pullreq.requestRepositoryName,
|
pullreq.requestRepositoryName,
|
||||||
pullreq.commitIdTo
|
pullreq.commitIdTo
|
||||||
)
|
)
|
||||||
|
|
||||||
val revCommits = using(new RevWalk(git.getRepository)) { revWalk =>
|
val revCommits = Using
|
||||||
commits.flatten.map { commit =>
|
.resource(new RevWalk(git.getRepository)) { revWalk =>
|
||||||
revWalk.parseCommit(git.getRepository.resolve(commit.id))
|
commits.flatten.map { commit =>
|
||||||
}
|
revWalk.parseCommit(git.getRepository.resolve(commit.id))
|
||||||
}.reverse
|
}
|
||||||
|
}
|
||||||
|
.reverse
|
||||||
|
|
||||||
// merge git repository
|
// merge git repository
|
||||||
(strategy match {
|
(strategy match {
|
||||||
case "merge-commit" =>
|
case "merge-commit" =>
|
||||||
Some(
|
Some(
|
||||||
mergePullRequest(
|
mergePullRequest(
|
||||||
git,
|
git,
|
||||||
pullreq.branch,
|
pullreq.branch,
|
||||||
issueId,
|
issueId,
|
||||||
s"Merge pull request #${issueId} from ${pullreq.requestUserName}/${pullreq.requestBranch}\n\n" + message,
|
s"Merge pull request #${issueId} from ${pullreq.requestUserName}/${pullreq.requestBranch}\n\n" + message,
|
||||||
new PersonIdent(loginAccount.fullName, loginAccount.mailAddress)
|
new PersonIdent(loginAccount.fullName, loginAccount.mailAddress)
|
||||||
|
)
|
||||||
)
|
)
|
||||||
)
|
case "rebase" =>
|
||||||
case "rebase" =>
|
Some(
|
||||||
Some(
|
rebasePullRequest(
|
||||||
rebasePullRequest(
|
git,
|
||||||
git,
|
pullreq.branch,
|
||||||
pullreq.branch,
|
issueId,
|
||||||
issueId,
|
revCommits,
|
||||||
revCommits,
|
new PersonIdent(loginAccount.fullName, loginAccount.mailAddress)
|
||||||
new PersonIdent(loginAccount.fullName, loginAccount.mailAddress)
|
)
|
||||||
)
|
)
|
||||||
)
|
case "squash" =>
|
||||||
case "squash" =>
|
Some(
|
||||||
Some(
|
squashPullRequest(
|
||||||
squashPullRequest(
|
git,
|
||||||
git,
|
pullreq.branch,
|
||||||
pullreq.branch,
|
issueId,
|
||||||
issueId,
|
s"${issue.title} (#${issueId})\n\n" + message,
|
||||||
s"${issue.title} (#${issueId})\n\n" + message,
|
new PersonIdent(loginAccount.fullName, loginAccount.mailAddress)
|
||||||
new PersonIdent(loginAccount.fullName, loginAccount.mailAddress)
|
)
|
||||||
)
|
)
|
||||||
)
|
case _ =>
|
||||||
case _ =>
|
None
|
||||||
None
|
}) match {
|
||||||
}) match {
|
case Some(newCommitId) =>
|
||||||
case Some(newCommitId) =>
|
// close issue by content of pull request
|
||||||
// close issue by content of pull request
|
val defaultBranch = getRepository(repository.owner, repository.name).get.repository.defaultBranch
|
||||||
val defaultBranch = getRepository(repository.owner, repository.name).get.repository.defaultBranch
|
if (pullreq.branch == defaultBranch) {
|
||||||
if (pullreq.branch == defaultBranch) {
|
commits.flatten.foreach { commit =>
|
||||||
commits.flatten.foreach { commit =>
|
closeIssuesFromMessage(
|
||||||
|
commit.fullMessage,
|
||||||
|
loginAccount.userName,
|
||||||
|
repository.owner,
|
||||||
|
repository.name
|
||||||
|
).foreach { issueId =>
|
||||||
|
getIssue(repository.owner, repository.name, issueId.toString).foreach { issue =>
|
||||||
|
callIssuesWebHook("closed", repository, issue, loginAccount)
|
||||||
|
PluginRegistry().getIssueHooks
|
||||||
|
.foreach(_.closedByCommitComment(issue, repository, commit.fullMessage, loginAccount))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
val issueContent = issue.title + " " + issue.content.getOrElse("")
|
||||||
closeIssuesFromMessage(
|
closeIssuesFromMessage(
|
||||||
commit.fullMessage,
|
issueContent,
|
||||||
loginAccount.userName,
|
loginAccount.userName,
|
||||||
repository.owner,
|
repository.owner,
|
||||||
repository.name
|
repository.name
|
||||||
).foreach { issueId =>
|
).foreach { issueId =>
|
||||||
getIssue(repository.owner, repository.name, issueId.toString).foreach { issue =>
|
|
||||||
callIssuesWebHook("closed", repository, issue, loginAccount)
|
|
||||||
PluginRegistry().getIssueHooks
|
|
||||||
.foreach(_.closedByCommitComment(issue, repository, commit.fullMessage, loginAccount))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
val issueContent = issue.title + " " + issue.content.getOrElse("")
|
|
||||||
closeIssuesFromMessage(
|
|
||||||
issueContent,
|
|
||||||
loginAccount.userName,
|
|
||||||
repository.owner,
|
|
||||||
repository.name
|
|
||||||
).foreach { issueId =>
|
|
||||||
getIssue(repository.owner, repository.name, issueId.toString).foreach { issue =>
|
|
||||||
callIssuesWebHook("closed", repository, issue, loginAccount)
|
|
||||||
PluginRegistry().getIssueHooks
|
|
||||||
.foreach(_.closedByCommitComment(issue, repository, issueContent, loginAccount))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
closeIssuesFromMessage(message, loginAccount.userName, repository.owner, repository.name)
|
|
||||||
.foreach { issueId =>
|
|
||||||
getIssue(repository.owner, repository.name, issueId.toString).foreach { issue =>
|
getIssue(repository.owner, repository.name, issueId.toString).foreach { issue =>
|
||||||
callIssuesWebHook("closed", repository, issue, loginAccount)
|
callIssuesWebHook("closed", repository, issue, loginAccount)
|
||||||
PluginRegistry().getIssueHooks
|
PluginRegistry().getIssueHooks
|
||||||
.foreach(_.closedByCommitComment(issue, repository, issueContent, loginAccount))
|
.foreach(_.closedByCommitComment(issue, repository, issueContent, loginAccount))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
closeIssuesFromMessage(message, loginAccount.userName, repository.owner, repository.name)
|
||||||
|
.foreach { issueId =>
|
||||||
|
getIssue(repository.owner, repository.name, issueId.toString).foreach { issue =>
|
||||||
|
callIssuesWebHook("closed", repository, issue, loginAccount)
|
||||||
|
PluginRegistry().getIssueHooks
|
||||||
|
.foreach(_.closedByCommitComment(issue, repository, issueContent, loginAccount))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
callPullRequestWebHook("closed", repository, issueId, context.loginAccount.get)
|
callPullRequestWebHook("closed", repository, issueId, context.loginAccount.get)
|
||||||
|
|
||||||
updatePullRequests(repository.owner, repository.name, pullreq.branch, loginAccount, "closed")
|
updatePullRequests(repository.owner, repository.name, pullreq.branch, loginAccount, "closed")
|
||||||
|
|
||||||
// call hooks
|
// call hooks
|
||||||
PluginRegistry().getPullRequestHooks.foreach { h =>
|
PluginRegistry().getPullRequestHooks.foreach { h =>
|
||||||
h.addedComment(commentId, message, issue, repository)
|
h.addedComment(commentId, message, issue, repository)
|
||||||
h.merged(issue, repository)
|
h.merged(issue, repository)
|
||||||
}
|
}
|
||||||
|
|
||||||
Right(newCommitId)
|
Right(newCommitId)
|
||||||
case None =>
|
case None =>
|
||||||
Left("Unknown strategy")
|
Left("Unknown strategy")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
case _ => Left("Unknown error")
|
||||||
case _ => Left("Unknown error")
|
}
|
||||||
}
|
.getOrElse(Left("Pull request not found"))
|
||||||
.getOrElse(Left("Pull request not found"))
|
}
|
||||||
}
|
} else Left("Strategy not allowed")
|
||||||
} else Left("Strategy not allowed")
|
} else Left("Draft pull requests cannot be merged")
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -402,7 +404,7 @@ object MergeService {
|
|||||||
mergeCommit.setCommitter(committer)
|
mergeCommit.setCommitter(committer)
|
||||||
mergeCommit.setMessage(message)
|
mergeCommit.setMessage(message)
|
||||||
// insertObject and got mergeCommit Object Id
|
// insertObject and got mergeCommit Object Id
|
||||||
using(repository.newObjectInserter) { inserter =>
|
Using.resource(repository.newObjectInserter) { inserter =>
|
||||||
val mergeCommitId = inserter.insert(mergeCommit)
|
val mergeCommitId = inserter.insert(mergeCommit)
|
||||||
inserter.flush()
|
inserter.flush()
|
||||||
mergeCommitId
|
mergeCommitId
|
||||||
@@ -470,7 +472,7 @@ object MergeService {
|
|||||||
} catch {
|
} catch {
|
||||||
case e: NoMergeBaseException => true
|
case e: NoMergeBaseException => true
|
||||||
}
|
}
|
||||||
val mergeTipCommit = using(new RevWalk(repository))(_.parseCommit(mergeTip))
|
val mergeTipCommit = Using.resource(new RevWalk(repository))(_.parseCommit(mergeTip))
|
||||||
val committer = mergeTipCommit.getCommitterIdent
|
val committer = mergeTipCommit.getCommitterIdent
|
||||||
|
|
||||||
def _updateBranch(treeId: ObjectId, message: String, branchName: String): Unit = {
|
def _updateBranch(treeId: ObjectId, message: String, branchName: String): Unit = {
|
||||||
@@ -523,10 +525,10 @@ object MergeService {
|
|||||||
newCommit
|
newCommit
|
||||||
}
|
}
|
||||||
|
|
||||||
val mergeBaseTipCommit = using(new RevWalk(repository))(_.parseCommit(mergeBaseTip))
|
val mergeBaseTipCommit = Using.resource(new RevWalk(repository))(_.parseCommit(mergeBaseTip))
|
||||||
var previousId = mergeBaseTipCommit.getId
|
var previousId = mergeBaseTipCommit.getId
|
||||||
|
|
||||||
using(repository.newObjectInserter) { inserter =>
|
Using.resource(repository.newObjectInserter) { inserter =>
|
||||||
commits.foreach { commit =>
|
commits.foreach { commit =>
|
||||||
val nextCommit = _cloneCommit(commit, previousId, mergeBaseTipCommit.getId)
|
val nextCommit = _cloneCommit(commit, previousId, mergeBaseTipCommit.getId)
|
||||||
previousId = inserter.insert(nextCommit)
|
previousId = inserter.insert(nextCommit)
|
||||||
@@ -542,8 +544,9 @@ object MergeService {
|
|||||||
throw new RuntimeException("This pull request can't merge automatically.")
|
throw new RuntimeException("This pull request can't merge automatically.")
|
||||||
}
|
}
|
||||||
|
|
||||||
val mergeBaseTipCommit = using(new RevWalk(repository))(_.parseCommit(mergeBaseTip))
|
val mergeBaseTipCommit = Using.resource(new RevWalk(repository))(_.parseCommit(mergeBaseTip))
|
||||||
val mergeBranchHeadCommit = using(new RevWalk(repository))(_.parseCommit(repository.resolve(mergedBranchName)))
|
val mergeBranchHeadCommit =
|
||||||
|
Using.resource(new RevWalk(repository))(_.parseCommit(repository.resolve(mergedBranchName)))
|
||||||
|
|
||||||
// Create squash commit
|
// Create squash commit
|
||||||
val mergeCommit = new CommitBuilder()
|
val mergeCommit = new CommitBuilder()
|
||||||
@@ -554,7 +557,7 @@ object MergeService {
|
|||||||
mergeCommit.setMessage(message)
|
mergeCommit.setMessage(message)
|
||||||
|
|
||||||
// insertObject and got squash commit Object Id
|
// insertObject and got squash commit Object Id
|
||||||
val newCommitId = using(repository.newObjectInserter) { inserter =>
|
val newCommitId = Using.resource(repository.newObjectInserter) { inserter =>
|
||||||
val newCommitId = inserter.insert(mergeCommit)
|
val newCommitId = inserter.insert(mergeCommit)
|
||||||
inserter.flush()
|
inserter.flush()
|
||||||
newCommitId
|
newCommitId
|
||||||
@@ -577,7 +580,7 @@ object MergeService {
|
|||||||
private def createMergeCommit(treeId: ObjectId, committer: PersonIdent, message: String) =
|
private def createMergeCommit(treeId: ObjectId, committer: PersonIdent, message: String) =
|
||||||
Util.createMergeCommit(repository, treeId, committer, message, Seq[ObjectId](mergeBaseTip, mergeTip))
|
Util.createMergeCommit(repository, treeId, committer, message, Seq[ObjectId](mergeBaseTip, mergeTip))
|
||||||
|
|
||||||
private def parseCommit(id: ObjectId) = using(new RevWalk(repository))(_.parseCommit(id))
|
private def parseCommit(id: ObjectId) = Using.resource(new RevWalk(repository))(_.parseCommit(id))
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ import gitbucket.core.model.Account
|
|||||||
import gitbucket.core.model.Profile.profile.blockingApi._
|
import gitbucket.core.model.Profile.profile.blockingApi._
|
||||||
import org.slf4j.LoggerFactory
|
import org.slf4j.LoggerFactory
|
||||||
|
|
||||||
import scala.collection.JavaConverters.{asScalaSet, mapAsJavaMap}
|
import scala.jdk.CollectionConverters._
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Service class for the OpenID Connect authentication.
|
* Service class for the OpenID Connect authentication.
|
||||||
@@ -101,7 +101,7 @@ trait OpenIDConnectService {
|
|||||||
redirectURI: URI
|
redirectURI: URI
|
||||||
): Option[AuthenticationSuccessResponse] =
|
): Option[AuthenticationSuccessResponse] =
|
||||||
try {
|
try {
|
||||||
AuthenticationResponseParser.parse(redirectURI, mapAsJavaMap(params)) match {
|
AuthenticationResponseParser.parse(redirectURI, params.asJava) match {
|
||||||
case response: AuthenticationSuccessResponse =>
|
case response: AuthenticationSuccessResponse =>
|
||||||
if (response.getState == state) {
|
if (response.getState == state) {
|
||||||
Some(response)
|
Some(response)
|
||||||
@@ -207,5 +207,5 @@ object OpenIDConnectService {
|
|||||||
"RSA" -> Family.RSA,
|
"RSA" -> Family.RSA,
|
||||||
"ECDSA" -> Family.EC,
|
"ECDSA" -> Family.EC,
|
||||||
"EdDSA" -> Family.ED
|
"EdDSA" -> Family.ED
|
||||||
).toMap.map { case (name, family) => (name, asScalaSet(family).toSet) }
|
).toMap.map { case (name, family) => (name, family.asScala.toSet) }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ import gitbucket.core.service.RepositoryService.RepositoryInfo
|
|||||||
import gitbucket.core.api.JsonFormat
|
import gitbucket.core.api.JsonFormat
|
||||||
import gitbucket.core.controller.Context
|
import gitbucket.core.controller.Context
|
||||||
import gitbucket.core.plugin.PluginRegistry
|
import gitbucket.core.plugin.PluginRegistry
|
||||||
import gitbucket.core.util.SyntaxSugars._
|
|
||||||
import gitbucket.core.util.Directory._
|
import gitbucket.core.util.Directory._
|
||||||
import gitbucket.core.util.Implicits._
|
import gitbucket.core.util.Implicits._
|
||||||
import gitbucket.core.util.JGitUtil
|
import gitbucket.core.util.JGitUtil
|
||||||
@@ -19,7 +18,8 @@ import gitbucket.core.view.helpers
|
|||||||
import org.eclipse.jgit.api.Git
|
import org.eclipse.jgit.api.Git
|
||||||
import org.eclipse.jgit.lib.ObjectId
|
import org.eclipse.jgit.lib.ObjectId
|
||||||
|
|
||||||
import scala.collection.JavaConverters._
|
import scala.jdk.CollectionConverters._
|
||||||
|
import scala.util.Using
|
||||||
|
|
||||||
trait PullRequestService {
|
trait PullRequestService {
|
||||||
self: IssuesService
|
self: IssuesService
|
||||||
@@ -48,6 +48,14 @@ trait PullRequestService {
|
|||||||
.map(pr => pr.commitIdTo -> pr.commitIdFrom)
|
.map(pr => pr.commitIdTo -> pr.commitIdFrom)
|
||||||
.update((commitIdTo, commitIdFrom))
|
.update((commitIdTo, commitIdFrom))
|
||||||
|
|
||||||
|
def updateDraftToPullRequest(owner: String, repository: String, issueId: Int)(
|
||||||
|
implicit s: Session
|
||||||
|
): Unit =
|
||||||
|
PullRequests
|
||||||
|
.filter(_.byPrimaryKey(owner, repository, issueId))
|
||||||
|
.map(pr => pr.isDraft)
|
||||||
|
.update(false)
|
||||||
|
|
||||||
def getPullRequestCountGroupByUser(closed: Boolean, owner: Option[String], repository: Option[String])(
|
def getPullRequestCountGroupByUser(closed: Boolean, owner: Option[String], repository: Option[String])(
|
||||||
implicit s: Session
|
implicit s: Session
|
||||||
): List[PullRequestCount] =
|
): List[PullRequestCount] =
|
||||||
@@ -97,6 +105,7 @@ trait PullRequestService {
|
|||||||
requestBranch: String,
|
requestBranch: String,
|
||||||
commitIdFrom: String,
|
commitIdFrom: String,
|
||||||
commitIdTo: String,
|
commitIdTo: String,
|
||||||
|
isDraft: Boolean,
|
||||||
loginAccount: Account
|
loginAccount: Account
|
||||||
)(implicit s: Session, context: Context): Unit = {
|
)(implicit s: Session, context: Context): Unit = {
|
||||||
getIssue(originRepository.owner, originRepository.name, issueId.toString).foreach { baseIssue =>
|
getIssue(originRepository.owner, originRepository.name, issueId.toString).foreach { baseIssue =>
|
||||||
@@ -109,7 +118,8 @@ trait PullRequestService {
|
|||||||
requestRepositoryName,
|
requestRepositoryName,
|
||||||
requestBranch,
|
requestBranch,
|
||||||
commitIdFrom,
|
commitIdFrom,
|
||||||
commitIdTo
|
commitIdTo,
|
||||||
|
isDraft
|
||||||
)
|
)
|
||||||
|
|
||||||
// fetch requested branch
|
// fetch requested branch
|
||||||
@@ -377,7 +387,7 @@ trait PullRequestService {
|
|||||||
requestRepositoryName: String,
|
requestRepositoryName: String,
|
||||||
requestCommitId: String
|
requestCommitId: String
|
||||||
): (Seq[Seq[CommitInfo]], Seq[DiffInfo]) =
|
): (Seq[Seq[CommitInfo]], Seq[DiffInfo]) =
|
||||||
using(
|
Using.resources(
|
||||||
Git.open(getRepositoryDir(userName, repositoryName)),
|
Git.open(getRepositoryDir(userName, repositoryName)),
|
||||||
Git.open(getRepositoryDir(requestUserName, requestRepositoryName))
|
Git.open(getRepositoryDir(requestUserName, requestRepositoryName))
|
||||||
) { (oldGit, newGit) =>
|
) { (oldGit, newGit) =>
|
||||||
@@ -468,7 +478,7 @@ trait PullRequestService {
|
|||||||
originId: String,
|
originId: String,
|
||||||
forkedId: String
|
forkedId: String
|
||||||
): (Option[ObjectId], Option[ObjectId]) = {
|
): (Option[ObjectId], Option[ObjectId]) = {
|
||||||
using(
|
Using.resources(
|
||||||
Git.open(getRepositoryDir(originRepository.owner, originRepository.name)),
|
Git.open(getRepositoryDir(originRepository.owner, originRepository.name)),
|
||||||
Git.open(getRepositoryDir(forkedRepository.owner, forkedRepository.name))
|
Git.open(getRepositoryDir(forkedRepository.owner, forkedRepository.name))
|
||||||
) {
|
) {
|
||||||
@@ -534,7 +544,7 @@ object PullRequestService {
|
|||||||
lazy val commitStateSummary: (CommitState, String) = {
|
lazy val commitStateSummary: (CommitState, String) = {
|
||||||
val stateMap = statuses.groupBy(_.state)
|
val stateMap = statuses.groupBy(_.state)
|
||||||
val state = CommitState.combine(stateMap.keySet)
|
val state = CommitState.combine(stateMap.keySet)
|
||||||
val summary = stateMap.map { case (keyState, states) => states.size + " " + keyState.name }.mkString(", ")
|
val summary = stateMap.map { case (keyState, states) => s"${states.size} ${keyState.name}" }.mkString(", ")
|
||||||
state -> summary
|
state -> summary
|
||||||
}
|
}
|
||||||
lazy val statusesAndRequired: List[(CommitStatus, Boolean)] = statuses.map { s =>
|
lazy val statusesAndRequired: List[(CommitStatus, Boolean)] = statuses.map { s =>
|
||||||
|
|||||||
@@ -8,11 +8,11 @@ import gitbucket.core.service.WebHookService.WebHookPushPayload
|
|||||||
import gitbucket.core.util.Directory.getRepositoryDir
|
import gitbucket.core.util.Directory.getRepositoryDir
|
||||||
import gitbucket.core.util.JGitUtil.CommitInfo
|
import gitbucket.core.util.JGitUtil.CommitInfo
|
||||||
import gitbucket.core.util.{JGitUtil, LockUtil}
|
import gitbucket.core.util.{JGitUtil, LockUtil}
|
||||||
import gitbucket.core.util.SyntaxSugars.using
|
|
||||||
import org.eclipse.jgit.api.Git
|
import org.eclipse.jgit.api.Git
|
||||||
import org.eclipse.jgit.dircache.{DirCache, DirCacheBuilder}
|
import org.eclipse.jgit.dircache.{DirCache, DirCacheBuilder}
|
||||||
import org.eclipse.jgit.lib._
|
import org.eclipse.jgit.lib._
|
||||||
import org.eclipse.jgit.transport.{ReceiveCommand, ReceivePack}
|
import org.eclipse.jgit.transport.{ReceiveCommand, ReceivePack}
|
||||||
|
import scala.util.Using
|
||||||
|
|
||||||
trait RepositoryCommitFileService {
|
trait RepositoryCommitFileService {
|
||||||
self: AccountService with ActivityService with IssuesService with PullRequestService with WebHookPullRequestService =>
|
self: AccountService with ActivityService with IssuesService with PullRequestService with WebHookPullRequestService =>
|
||||||
@@ -117,7 +117,7 @@ trait RepositoryCommitFileService {
|
|||||||
)(implicit s: Session, c: JsonFormat.Context): ObjectId = {
|
)(implicit s: Session, c: JsonFormat.Context): ObjectId = {
|
||||||
|
|
||||||
LockUtil.lock(s"${repository.owner}/${repository.name}") {
|
LockUtil.lock(s"${repository.owner}/${repository.name}") {
|
||||||
using(Git.open(getRepositoryDir(repository.owner, repository.name))) { git =>
|
Using.resource(Git.open(getRepositoryDir(repository.owner, repository.name))) { git =>
|
||||||
val builder = DirCache.newInCore.builder()
|
val builder = DirCache.newInCore.builder()
|
||||||
val inserter = git.getRepository.newObjectInserter()
|
val inserter = git.getRepository.newObjectInserter()
|
||||||
val headName = s"refs/heads/${branch}"
|
val headName = s"refs/heads/${branch}"
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ import java.nio.file.Files
|
|||||||
import java.util.concurrent.ConcurrentHashMap
|
import java.util.concurrent.ConcurrentHashMap
|
||||||
|
|
||||||
import gitbucket.core.model.Profile.profile.blockingApi._
|
import gitbucket.core.model.Profile.profile.blockingApi._
|
||||||
import gitbucket.core.util.SyntaxSugars._
|
|
||||||
import gitbucket.core.util.Directory._
|
import gitbucket.core.util.Directory._
|
||||||
import gitbucket.core.util.{FileUtil, JGitUtil, LockUtil}
|
import gitbucket.core.util.{FileUtil, JGitUtil, LockUtil}
|
||||||
import gitbucket.core.model.{Account, Role}
|
import gitbucket.core.model.{Account, Role}
|
||||||
@@ -18,6 +17,7 @@ import org.eclipse.jgit.lib.{Constants, FileMode}
|
|||||||
|
|
||||||
import scala.concurrent.ExecutionContext.Implicits.global
|
import scala.concurrent.ExecutionContext.Implicits.global
|
||||||
import scala.concurrent.Future
|
import scala.concurrent.Future
|
||||||
|
import scala.util.Using
|
||||||
|
|
||||||
object RepositoryCreationService {
|
object RepositoryCreationService {
|
||||||
|
|
||||||
@@ -107,7 +107,7 @@ trait RepositoryCreationService {
|
|||||||
JGitUtil.initRepository(gitdir)
|
JGitUtil.initRepository(gitdir)
|
||||||
|
|
||||||
if (initOption == "README" || initOption == "EMPTY_COMMIT") {
|
if (initOption == "README" || initOption == "EMPTY_COMMIT") {
|
||||||
using(Git.open(gitdir)) { git =>
|
Using.resource(Git.open(gitdir)) { git =>
|
||||||
val builder = DirCache.newInCore.builder()
|
val builder = DirCache.newInCore.builder()
|
||||||
val inserter = git.getRepository.newObjectInserter()
|
val inserter = git.getRepository.newObjectInserter()
|
||||||
val headId = git.getRepository.resolve(Constants.HEAD + "^{commit}")
|
val headId = git.getRepository.resolve(Constants.HEAD + "^{commit}")
|
||||||
@@ -148,7 +148,7 @@ trait RepositoryCreationService {
|
|||||||
|
|
||||||
copyRepositoryDir.foreach { dir =>
|
copyRepositoryDir.foreach { dir =>
|
||||||
try {
|
try {
|
||||||
using(Git.open(dir)) { git =>
|
Using.resource(Git.open(dir)) { git =>
|
||||||
git.push().setRemote(gitdir.toURI.toString).setPushAll().setPushTags().call()
|
git.push().setRemote(gitdir.toURI.toString).setPushAll().setPushTags().call()
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
|
|||||||
@@ -4,12 +4,12 @@ import gitbucket.core.model.Issue
|
|||||||
import gitbucket.core.util._
|
import gitbucket.core.util._
|
||||||
import gitbucket.core.util.StringUtil
|
import gitbucket.core.util.StringUtil
|
||||||
import Directory._
|
import Directory._
|
||||||
import SyntaxSugars._
|
|
||||||
import org.eclipse.jgit.revwalk.RevWalk
|
import org.eclipse.jgit.revwalk.RevWalk
|
||||||
import org.eclipse.jgit.treewalk.TreeWalk
|
import org.eclipse.jgit.treewalk.TreeWalk
|
||||||
import org.eclipse.jgit.lib.FileMode
|
import org.eclipse.jgit.lib.FileMode
|
||||||
import org.eclipse.jgit.api.Git
|
import org.eclipse.jgit.api.Git
|
||||||
import gitbucket.core.model.Profile.profile.blockingApi._
|
import gitbucket.core.model.Profile.profile.blockingApi._
|
||||||
|
import scala.util.Using
|
||||||
|
|
||||||
trait RepositorySearchService { self: IssuesService =>
|
trait RepositorySearchService { self: IssuesService =>
|
||||||
import RepositorySearchService._
|
import RepositorySearchService._
|
||||||
@@ -37,12 +37,12 @@ trait RepositorySearchService { self: IssuesService =>
|
|||||||
}
|
}
|
||||||
|
|
||||||
def countFiles(owner: String, repository: String, query: String): Int =
|
def countFiles(owner: String, repository: String, query: String): Int =
|
||||||
using(Git.open(getRepositoryDir(owner, repository))) { git =>
|
Using.resource(Git.open(getRepositoryDir(owner, repository))) { git =>
|
||||||
if (JGitUtil.isEmpty(git)) 0 else searchRepositoryFiles(git, query).length
|
if (JGitUtil.isEmpty(git)) 0 else searchRepositoryFiles(git, query).length
|
||||||
}
|
}
|
||||||
|
|
||||||
def searchFiles(owner: String, repository: String, query: String): List[FileSearchResult] =
|
def searchFiles(owner: String, repository: String, query: String): List[FileSearchResult] =
|
||||||
using(Git.open(getRepositoryDir(owner, repository))) { git =>
|
Using.resource(Git.open(getRepositoryDir(owner, repository))) { git =>
|
||||||
if (JGitUtil.isEmpty(git)) {
|
if (JGitUtil.isEmpty(git)) {
|
||||||
Nil
|
Nil
|
||||||
} else {
|
} else {
|
||||||
@@ -57,12 +57,12 @@ trait RepositorySearchService { self: IssuesService =>
|
|||||||
}
|
}
|
||||||
|
|
||||||
def countWikiPages(owner: String, repository: String, query: String): Int =
|
def countWikiPages(owner: String, repository: String, query: String): Int =
|
||||||
using(Git.open(Directory.getWikiRepositoryDir(owner, repository))) { git =>
|
Using.resource(Git.open(Directory.getWikiRepositoryDir(owner, repository))) { git =>
|
||||||
if (JGitUtil.isEmpty(git)) 0 else searchRepositoryFiles(git, query).length
|
if (JGitUtil.isEmpty(git)) 0 else searchRepositoryFiles(git, query).length
|
||||||
}
|
}
|
||||||
|
|
||||||
def searchWikiPages(owner: String, repository: String, query: String): List[FileSearchResult] =
|
def searchWikiPages(owner: String, repository: String, query: String): List[FileSearchResult] =
|
||||||
using(Git.open(Directory.getWikiRepositoryDir(owner, repository))) { git =>
|
Using.resource(Git.open(Directory.getWikiRepositoryDir(owner, repository))) { git =>
|
||||||
if (JGitUtil.isEmpty(git)) {
|
if (JGitUtil.isEmpty(git)) {
|
||||||
Nil
|
Nil
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ import org.eclipse.jgit.api.Git
|
|||||||
import org.eclipse.jgit.dircache.{DirCache, DirCacheBuilder}
|
import org.eclipse.jgit.dircache.{DirCache, DirCacheBuilder}
|
||||||
import org.eclipse.jgit.lib.{Repository => _, _}
|
import org.eclipse.jgit.lib.{Repository => _, _}
|
||||||
import org.eclipse.jgit.transport.{ReceiveCommand, ReceivePack}
|
import org.eclipse.jgit.transport.{ReceiveCommand, ReceivePack}
|
||||||
|
import scala.util.Using
|
||||||
|
|
||||||
trait RepositoryService {
|
trait RepositoryService {
|
||||||
self: AccountService =>
|
self: AccountService =>
|
||||||
@@ -763,7 +764,7 @@ trait RepositoryService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Get template file from project root. When didn't find, will lookup default folder.
|
// Get template file from project root. When didn't find, will lookup default folder.
|
||||||
using(Git.open(Directory.getRepositoryDir(repository.owner, repository.name))) { git =>
|
Using.resource(Git.open(Directory.getRepositoryDir(repository.owner, repository.name))) { git =>
|
||||||
choiceTemplate(JGitUtil.getFileList(git, repository.repository.defaultBranch, "."))
|
choiceTemplate(JGitUtil.getFileList(git, repository.repository.defaultBranch, "."))
|
||||||
.orElse {
|
.orElse {
|
||||||
choiceTemplate(JGitUtil.getFileList(git, repository.repository.defaultBranch, ".gitbucket"))
|
choiceTemplate(JGitUtil.getFileList(git, repository.repository.defaultBranch, ".gitbucket"))
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import gitbucket.core.service.SystemSettingsService._
|
|||||||
import gitbucket.core.util.ConfigUtil._
|
import gitbucket.core.util.ConfigUtil._
|
||||||
import gitbucket.core.util.Directory._
|
import gitbucket.core.util.Directory._
|
||||||
import gitbucket.core.util.SyntaxSugars._
|
import gitbucket.core.util.SyntaxSugars._
|
||||||
|
import scala.util.Using
|
||||||
|
|
||||||
trait SystemSettingsService {
|
trait SystemSettingsService {
|
||||||
|
|
||||||
@@ -69,19 +70,8 @@ trait SystemSettingsService {
|
|||||||
}
|
}
|
||||||
props.setProperty(SkinName, settings.skinName.toString)
|
props.setProperty(SkinName, settings.skinName.toString)
|
||||||
props.setProperty(ShowMailAddress, settings.showMailAddress.toString)
|
props.setProperty(ShowMailAddress, settings.showMailAddress.toString)
|
||||||
props.setProperty(PluginNetworkInstall, settings.pluginNetworkInstall.toString)
|
|
||||||
settings.pluginProxy.foreach { proxy =>
|
|
||||||
props.setProperty(PluginProxyHost, proxy.host)
|
|
||||||
props.setProperty(PluginProxyPort, proxy.port.toString)
|
|
||||||
proxy.user.foreach { user =>
|
|
||||||
props.setProperty(PluginProxyUser, user)
|
|
||||||
}
|
|
||||||
proxy.password.foreach { password =>
|
|
||||||
props.setProperty(PluginProxyPassword, password)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
using(new java.io.FileOutputStream(GitBucketConf)) { out =>
|
Using.resource(new java.io.FileOutputStream(GitBucketConf)) { out =>
|
||||||
props.store(out, null)
|
props.store(out, null)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -90,7 +80,7 @@ trait SystemSettingsService {
|
|||||||
def loadSystemSettings(): SystemSettings = {
|
def loadSystemSettings(): SystemSettings = {
|
||||||
defining(new java.util.Properties()) { props =>
|
defining(new java.util.Properties()) { props =>
|
||||||
if (GitBucketConf.exists) {
|
if (GitBucketConf.exists) {
|
||||||
using(new java.io.FileInputStream(GitBucketConf)) { in =>
|
Using.resource(new java.io.FileInputStream(GitBucketConf)) { in =>
|
||||||
props.load(in)
|
props.load(in)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -156,18 +146,7 @@ trait SystemSettingsService {
|
|||||||
None
|
None
|
||||||
},
|
},
|
||||||
getValue(props, SkinName, "skin-blue"),
|
getValue(props, SkinName, "skin-blue"),
|
||||||
getValue(props, ShowMailAddress, false),
|
getValue(props, ShowMailAddress, false)
|
||||||
getValue(props, PluginNetworkInstall, false),
|
|
||||||
if (getValue(props, PluginProxyHost, "").nonEmpty) {
|
|
||||||
Some(
|
|
||||||
Proxy(
|
|
||||||
getValue(props, PluginProxyHost, ""),
|
|
||||||
getValue(props, PluginProxyPort, 8080),
|
|
||||||
getOptionValue(props, PluginProxyUser, None),
|
|
||||||
getOptionValue(props, PluginProxyPassword, None)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
} else None
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -196,9 +175,7 @@ object SystemSettingsService {
|
|||||||
oidcAuthentication: Boolean,
|
oidcAuthentication: Boolean,
|
||||||
oidc: Option[OIDC],
|
oidc: Option[OIDC],
|
||||||
skinName: String,
|
skinName: String,
|
||||||
showMailAddress: Boolean,
|
showMailAddress: Boolean
|
||||||
pluginNetworkInstall: Boolean,
|
|
||||||
pluginProxy: Option[Proxy]
|
|
||||||
) {
|
) {
|
||||||
|
|
||||||
def baseUrl(request: HttpServletRequest): String =
|
def baseUrl(request: HttpServletRequest): String =
|
||||||
|
|||||||
@@ -55,6 +55,7 @@ trait WebHookService {
|
|||||||
.map { case (w, t) => w -> t.event }
|
.map { case (w, t) => w -> t.event }
|
||||||
.list
|
.list
|
||||||
.groupBy(_._1)
|
.groupBy(_._1)
|
||||||
|
.view
|
||||||
.mapValues(_.map(_._2).toSet)
|
.mapValues(_.map(_._2).toSet)
|
||||||
.toList
|
.toList
|
||||||
.sortBy(_._1.url)
|
.sortBy(_._1.url)
|
||||||
@@ -87,6 +88,7 @@ trait WebHookService {
|
|||||||
.map { case (w, t) => w -> t.event }
|
.map { case (w, t) => w -> t.event }
|
||||||
.list
|
.list
|
||||||
.groupBy(_._1)
|
.groupBy(_._1)
|
||||||
|
.view
|
||||||
.mapValues(_.map(_._2).toSet)
|
.mapValues(_.map(_._2).toSet)
|
||||||
.headOption
|
.headOption
|
||||||
|
|
||||||
@@ -136,6 +138,7 @@ trait WebHookService {
|
|||||||
.map { case (w, t) => w -> t.event }
|
.map { case (w, t) => w -> t.event }
|
||||||
.list
|
.list
|
||||||
.groupBy(_._1)
|
.groupBy(_._1)
|
||||||
|
.view
|
||||||
.mapValues(_.map(_._2).toSet)
|
.mapValues(_.map(_._2).toSet)
|
||||||
.toList
|
.toList
|
||||||
.sortBy(_._1.url)
|
.sortBy(_._1.url)
|
||||||
@@ -164,6 +167,7 @@ trait WebHookService {
|
|||||||
.map { case (w, t) => w -> t.event }
|
.map { case (w, t) => w -> t.event }
|
||||||
.list
|
.list
|
||||||
.groupBy(_._1)
|
.groupBy(_._1)
|
||||||
|
.view
|
||||||
.mapValues(_.map(_._2).toSet)
|
.mapValues(_.map(_._2).toSet)
|
||||||
.headOption
|
.headOption
|
||||||
|
|
||||||
@@ -396,7 +400,7 @@ trait WebHookPullRequestService extends WebHookService {
|
|||||||
if wht.event === WebHook.PullRequest.asInstanceOf[WebHook.Event].bind && wht.byRepositoryWebHook(wh)
|
if wht.event === WebHook.PullRequest.asInstanceOf[WebHook.Event].bind && wht.byRepositoryWebHook(wh)
|
||||||
} yield {
|
} yield {
|
||||||
((is, iu, pr, bu, ru), wh)
|
((is, iu, pr, bu, ru), wh)
|
||||||
}).list.groupBy(_._1).mapValues(_.map(_._2))
|
}).list.groupBy(_._1).map { case (k, v) => (k, v.map(_._2)) }
|
||||||
|
|
||||||
def callPullRequestWebHookByRequestBranch(
|
def callPullRequestWebHookByRequestBranch(
|
||||||
action: String,
|
action: String,
|
||||||
|
|||||||
@@ -14,7 +14,9 @@ import org.eclipse.jgit.diff.{DiffEntry, DiffFormatter}
|
|||||||
import java.io.ByteArrayInputStream
|
import java.io.ByteArrayInputStream
|
||||||
import org.eclipse.jgit.patch._
|
import org.eclipse.jgit.patch._
|
||||||
import org.eclipse.jgit.api.errors.PatchFormatException
|
import org.eclipse.jgit.api.errors.PatchFormatException
|
||||||
import scala.collection.JavaConverters._
|
|
||||||
|
import scala.jdk.CollectionConverters._
|
||||||
|
import scala.util.Using
|
||||||
|
|
||||||
object WikiService {
|
object WikiService {
|
||||||
|
|
||||||
@@ -73,7 +75,7 @@ trait WikiService {
|
|||||||
* Returns the wiki page.
|
* Returns the wiki page.
|
||||||
*/
|
*/
|
||||||
def getWikiPage(owner: String, repository: String, pageName: String): Option[WikiPageInfo] = {
|
def getWikiPage(owner: String, repository: String, pageName: String): Option[WikiPageInfo] = {
|
||||||
using(Git.open(Directory.getWikiRepositoryDir(owner, repository))) { git =>
|
Using.resource(Git.open(Directory.getWikiRepositoryDir(owner, repository))) { git =>
|
||||||
if (!JGitUtil.isEmpty(git)) {
|
if (!JGitUtil.isEmpty(git)) {
|
||||||
JGitUtil.getFileList(git, "master", ".").find(_.name == pageName + ".md").map { file =>
|
JGitUtil.getFileList(git, "master", ".").find(_.name == pageName + ".md").map { file =>
|
||||||
WikiPageInfo(
|
WikiPageInfo(
|
||||||
@@ -92,7 +94,7 @@ trait WikiService {
|
|||||||
* Returns the list of wiki page names.
|
* Returns the list of wiki page names.
|
||||||
*/
|
*/
|
||||||
def getWikiPageList(owner: String, repository: String): List[String] = {
|
def getWikiPageList(owner: String, repository: String): List[String] = {
|
||||||
using(Git.open(Directory.getWikiRepositoryDir(owner, repository))) { git =>
|
Using.resource(Git.open(Directory.getWikiRepositoryDir(owner, repository))) { git =>
|
||||||
JGitUtil
|
JGitUtil
|
||||||
.getFileList(git, "master", ".")
|
.getFileList(git, "master", ".")
|
||||||
.filter(_.name.endsWith(".md"))
|
.filter(_.name.endsWith(".md"))
|
||||||
@@ -118,7 +120,7 @@ trait WikiService {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
LockUtil.lock(s"${owner}/${repository}/wiki") {
|
LockUtil.lock(s"${owner}/${repository}/wiki") {
|
||||||
using(Git.open(Directory.getWikiRepositoryDir(owner, repository))) { git =>
|
Using.resource(Git.open(Directory.getWikiRepositoryDir(owner, repository))) { git =>
|
||||||
val reader = git.getRepository.newObjectReader
|
val reader = git.getRepository.newObjectReader
|
||||||
val oldTreeIter = new CanonicalTreeParser
|
val oldTreeIter = new CanonicalTreeParser
|
||||||
oldTreeIter.reset(reader, git.getRepository.resolve(from + "^{tree}"))
|
oldTreeIter.reset(reader, git.getRepository.resolve(from + "^{tree}"))
|
||||||
@@ -133,7 +135,7 @@ trait WikiService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val patch = using(new java.io.ByteArrayOutputStream()) { out =>
|
val patch = Using.resource(new java.io.ByteArrayOutputStream()) { out =>
|
||||||
val formatter = new DiffFormatter(out)
|
val formatter = new DiffFormatter(out)
|
||||||
formatter.setRepository(git.getRepository)
|
formatter.setRepository(git.getRepository)
|
||||||
formatter.format(diffs.asJava)
|
formatter.format(diffs.asJava)
|
||||||
@@ -237,7 +239,7 @@ trait WikiService {
|
|||||||
currentId: Option[String]
|
currentId: Option[String]
|
||||||
): Option[String] = {
|
): Option[String] = {
|
||||||
LockUtil.lock(s"${owner}/${repository}/wiki") {
|
LockUtil.lock(s"${owner}/${repository}/wiki") {
|
||||||
using(Git.open(Directory.getWikiRepositoryDir(owner, repository))) { git =>
|
Using.resource(Git.open(Directory.getWikiRepositoryDir(owner, repository))) { git =>
|
||||||
val builder = DirCache.newInCore.builder()
|
val builder = DirCache.newInCore.builder()
|
||||||
val inserter = git.getRepository.newObjectInserter()
|
val inserter = git.getRepository.newObjectInserter()
|
||||||
val headId = git.getRepository.resolve(Constants.HEAD + "^{commit}")
|
val headId = git.getRepository.resolve(Constants.HEAD + "^{commit}")
|
||||||
@@ -309,7 +311,7 @@ trait WikiService {
|
|||||||
message: String
|
message: String
|
||||||
): Unit = {
|
): Unit = {
|
||||||
LockUtil.lock(s"${owner}/${repository}/wiki") {
|
LockUtil.lock(s"${owner}/${repository}/wiki") {
|
||||||
using(Git.open(Directory.getWikiRepositoryDir(owner, repository))) { git =>
|
Using.resource(Git.open(Directory.getWikiRepositoryDir(owner, repository))) { git =>
|
||||||
val builder = DirCache.newInCore.builder()
|
val builder = DirCache.newInCore.builder()
|
||||||
val inserter = git.getRepository.newObjectInserter()
|
val inserter = git.getRepository.newObjectInserter()
|
||||||
val headId = git.getRepository.resolve(Constants.HEAD + "^{commit}")
|
val headId = git.getRepository.resolve(Constants.HEAD + "^{commit}")
|
||||||
|
|||||||
@@ -7,6 +7,10 @@ import gitbucket.core.model.Account
|
|||||||
import gitbucket.core.service.SystemSettingsService.SystemSettings
|
import gitbucket.core.service.SystemSettingsService.SystemSettings
|
||||||
import gitbucket.core.service.{AccessTokenService, AccountService, SystemSettingsService}
|
import gitbucket.core.service.{AccessTokenService, AccountService, SystemSettingsService}
|
||||||
import gitbucket.core.util.{AuthUtil, Keys}
|
import gitbucket.core.util.{AuthUtil, Keys}
|
||||||
|
import gitbucket.core.model.Profile.profile.blockingApi._
|
||||||
|
// Imported names have higher precedence than names, defined in other files.
|
||||||
|
// If Database is not bound by explicit import, then "Database" refers to the Database introduced by the wildcard import above.
|
||||||
|
import gitbucket.core.servlet.Database
|
||||||
|
|
||||||
class ApiAuthenticationFilter extends Filter with AccessTokenService with AccountService with SystemSettingsService {
|
class ApiAuthenticationFilter extends Filter with AccessTokenService with AccountService with SystemSettingsService {
|
||||||
|
|
||||||
@@ -33,7 +37,9 @@ class ApiAuthenticationFilter extends Filter with AccessTokenService with Accoun
|
|||||||
} match {
|
} match {
|
||||||
case Some(Right(account)) =>
|
case Some(Right(account)) =>
|
||||||
request.setAttribute(Keys.Session.LoginAccount, account)
|
request.setAttribute(Keys.Session.LoginAccount, account)
|
||||||
updateLastLoginDate(account.userName)
|
Database() withTransaction { implicit session =>
|
||||||
|
updateLastLoginDate(account.userName)
|
||||||
|
}
|
||||||
chain.doFilter(req, res)
|
chain.doFilter(req, res)
|
||||||
case None => chain.doFilter(req, res)
|
case None => chain.doFilter(req, res)
|
||||||
case Some(Left(_)) => {
|
case Some(Left(_)) => {
|
||||||
|
|||||||
@@ -4,12 +4,16 @@ import javax.servlet._
|
|||||||
import javax.servlet.http._
|
import javax.servlet.http._
|
||||||
|
|
||||||
import gitbucket.core.model.Account
|
import gitbucket.core.model.Account
|
||||||
import gitbucket.core.model.Profile.profile.blockingApi._
|
|
||||||
import gitbucket.core.plugin.{GitRepositoryFilter, GitRepositoryRouting, PluginRegistry}
|
import gitbucket.core.plugin.{GitRepositoryFilter, GitRepositoryRouting, PluginRegistry}
|
||||||
import gitbucket.core.service.SystemSettingsService.SystemSettings
|
import gitbucket.core.service.SystemSettingsService.SystemSettings
|
||||||
import gitbucket.core.service.{AccessTokenService, AccountService, RepositoryService, SystemSettingsService}
|
import gitbucket.core.service.{AccessTokenService, AccountService, RepositoryService, SystemSettingsService}
|
||||||
import gitbucket.core.util.Implicits._
|
import gitbucket.core.util.Implicits._
|
||||||
import gitbucket.core.util.{AuthUtil, Implicits, Keys}
|
import gitbucket.core.util.{AuthUtil, Keys}
|
||||||
|
import gitbucket.core.model.Profile.profile.blockingApi._
|
||||||
|
// Imported names have higher precedence than names, defined in other files.
|
||||||
|
// If Database is not bound by explicit import, then "Database" refers to the Database introduced by the wildcard import above.
|
||||||
|
import gitbucket.core.servlet.Database
|
||||||
|
|
||||||
import org.slf4j.LoggerFactory
|
import org.slf4j.LoggerFactory
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -8,7 +8,8 @@ import gitbucket.core.util.{FileUtil, StringUtil}
|
|||||||
import org.apache.commons.io.{FileUtils, IOUtils}
|
import org.apache.commons.io.{FileUtils, IOUtils}
|
||||||
import org.json4s.jackson.Serialization._
|
import org.json4s.jackson.Serialization._
|
||||||
import org.apache.http.HttpStatus
|
import org.apache.http.HttpStatus
|
||||||
import gitbucket.core.util.SyntaxSugars._
|
|
||||||
|
import scala.util.Using
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides GitLFS Transfer API
|
* Provides GitLFS Transfer API
|
||||||
@@ -28,8 +29,8 @@ class GitLfsTransferServlet extends HttpServlet {
|
|||||||
if (file.exists()) {
|
if (file.exists()) {
|
||||||
res.setStatus(HttpStatus.SC_OK)
|
res.setStatus(HttpStatus.SC_OK)
|
||||||
res.setContentType("application/octet-stream")
|
res.setContentType("application/octet-stream")
|
||||||
res.setContentLength(file.length.toInt)
|
res.setHeader("Content-Length", file.length.toString)
|
||||||
using(new FileInputStream(file), res.getOutputStream) { (in, out) =>
|
Using.resources(new FileInputStream(file), res.getOutputStream) { (in, out) =>
|
||||||
IOUtils.copy(in, out)
|
IOUtils.copy(in, out)
|
||||||
out.flush()
|
out.flush()
|
||||||
}
|
}
|
||||||
@@ -45,7 +46,7 @@ class GitLfsTransferServlet extends HttpServlet {
|
|||||||
} yield {
|
} yield {
|
||||||
val file = new File(FileUtil.getLfsFilePath(owner, repository, oid))
|
val file = new File(FileUtil.getLfsFilePath(owner, repository, oid))
|
||||||
FileUtils.forceMkdir(file.getParentFile)
|
FileUtils.forceMkdir(file.getParentFile)
|
||||||
using(req.getInputStream, new FileOutputStream(file)) { (in, out) =>
|
Using.resources(req.getInputStream, new FileOutputStream(file)) { (in, out) =>
|
||||||
IOUtils.copy(in, out)
|
IOUtils.copy(in, out)
|
||||||
}
|
}
|
||||||
res.setStatus(HttpStatus.SC_OK)
|
res.setStatus(HttpStatus.SC_OK)
|
||||||
@@ -71,7 +72,7 @@ class GitLfsTransferServlet extends HttpServlet {
|
|||||||
|
|
||||||
private def sendError(res: HttpServletResponse, status: Int, message: String): Unit = {
|
private def sendError(res: HttpServletResponse, status: Int, message: String): Unit = {
|
||||||
res.setStatus(status)
|
res.setStatus(status)
|
||||||
using(res.getWriter()) { out =>
|
Using.resource(res.getWriter()) { out =>
|
||||||
out.write(write(GitLfs.Error(message)))
|
out.write(write(GitLfs.Error(message)))
|
||||||
out.flush()
|
out.flush()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,9 +4,10 @@ import java.io.File
|
|||||||
import java.util
|
import java.util
|
||||||
import java.util.Date
|
import java.util.Date
|
||||||
|
|
||||||
|
import scala.util.Using
|
||||||
|
|
||||||
import gitbucket.core.api
|
import gitbucket.core.api
|
||||||
import gitbucket.core.model.WebHook
|
import gitbucket.core.model.WebHook
|
||||||
import gitbucket.core.model.Profile.profile.blockingApi._
|
|
||||||
import gitbucket.core.plugin.{GitRepositoryRouting, PluginRegistry}
|
import gitbucket.core.plugin.{GitRepositoryRouting, PluginRegistry}
|
||||||
import gitbucket.core.service.IssuesService.IssueSearchCondition
|
import gitbucket.core.service.IssuesService.IssueSearchCondition
|
||||||
import gitbucket.core.service.WebHookService._
|
import gitbucket.core.service.WebHookService._
|
||||||
@@ -14,6 +15,11 @@ import gitbucket.core.service._
|
|||||||
import gitbucket.core.util.SyntaxSugars._
|
import gitbucket.core.util.SyntaxSugars._
|
||||||
import gitbucket.core.util.Implicits._
|
import gitbucket.core.util.Implicits._
|
||||||
import gitbucket.core.util._
|
import gitbucket.core.util._
|
||||||
|
import gitbucket.core.model.Profile.profile.blockingApi._
|
||||||
|
// Imported names have higher precedence than names, defined in other files.
|
||||||
|
// If Database is not bound by explicit import, then "Database" refers to the Database introduced by the wildcard import above.
|
||||||
|
import gitbucket.core.servlet.Database
|
||||||
|
|
||||||
import org.eclipse.jgit.api.Git
|
import org.eclipse.jgit.api.Git
|
||||||
import org.eclipse.jgit.http.server.GitServlet
|
import org.eclipse.jgit.http.server.GitServlet
|
||||||
import org.eclipse.jgit.lib._
|
import org.eclipse.jgit.lib._
|
||||||
@@ -108,7 +114,7 @@ class GitRepositoryServlet extends GitServlet with SystemSettingsService {
|
|||||||
GitLfs.Action(
|
GitLfs.Action(
|
||||||
href = baseUrl + "/git-lfs/" + owner + "/" + repository + "/" + requestObject.oid,
|
href = baseUrl + "/git-lfs/" + owner + "/" + repository + "/" + requestObject.oid,
|
||||||
header =
|
header =
|
||||||
Map("Authorization" -> StringUtil.encodeBlowfish(timeout + " " + requestObject.oid)),
|
Map("Authorization" -> StringUtil.encodeBlowfish(s"$timeout ${requestObject.oid}")),
|
||||||
expires_at = new Date(timeout)
|
expires_at = new Date(timeout)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
@@ -129,7 +135,7 @@ class GitRepositoryServlet extends GitServlet with SystemSettingsService {
|
|||||||
GitLfs.Action(
|
GitLfs.Action(
|
||||||
href = baseUrl + "/git-lfs/" + owner + "/" + repository + "/" + requestObject.oid,
|
href = baseUrl + "/git-lfs/" + owner + "/" + repository + "/" + requestObject.oid,
|
||||||
header =
|
header =
|
||||||
Map("Authorization" -> StringUtil.encodeBlowfish(timeout + " " + requestObject.oid)),
|
Map("Authorization" -> StringUtil.encodeBlowfish(s"$timeout ${requestObject.oid}")),
|
||||||
expires_at = new Date(timeout)
|
expires_at = new Date(timeout)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
@@ -140,7 +146,7 @@ class GitRepositoryServlet extends GitServlet with SystemSettingsService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
res.setContentType("application/vnd.git-lfs+json")
|
res.setContentType("application/vnd.git-lfs+json")
|
||||||
using(res.getWriter) { out =>
|
Using.resource(res.getWriter) { out =>
|
||||||
out.print(write(batchResponse))
|
out.print(write(batchResponse))
|
||||||
out.flush()
|
out.flush()
|
||||||
}
|
}
|
||||||
@@ -216,7 +222,7 @@ class GitBucketReceivePackFactory extends ReceivePackFactory[HttpServletRequest]
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
import scala.collection.JavaConverters._
|
import scala.jdk.CollectionConverters._
|
||||||
|
|
||||||
class CommitLogHook(owner: String, repository: String, pusher: String, baseUrl: String, sshUrl: Option[String])
|
class CommitLogHook(owner: String, repository: String, pusher: String, baseUrl: String, sshUrl: Option[String])
|
||||||
extends PostReceiveHook
|
extends PostReceiveHook
|
||||||
@@ -250,7 +256,7 @@ class CommitLogHook(owner: String, repository: String, pusher: String, baseUrl:
|
|||||||
command.setResult(ReceiveCommand.Result.REJECTED_OTHER_REASON, error)
|
command.setResult(ReceiveCommand.Result.REJECTED_OTHER_REASON, error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
using(Git.open(Directory.getRepositoryDir(owner, repository))) { git =>
|
Using.resource(Git.open(Directory.getRepositoryDir(owner, repository))) { git =>
|
||||||
existIds = JGitUtil.getAllCommitIds(git)
|
existIds = JGitUtil.getAllCommitIds(git)
|
||||||
}
|
}
|
||||||
} catch {
|
} catch {
|
||||||
@@ -265,7 +271,7 @@ class CommitLogHook(owner: String, repository: String, pusher: String, baseUrl:
|
|||||||
def onPostReceive(receivePack: ReceivePack, commands: java.util.Collection[ReceiveCommand]): Unit = {
|
def onPostReceive(receivePack: ReceivePack, commands: java.util.Collection[ReceiveCommand]): Unit = {
|
||||||
Database() withTransaction { implicit session =>
|
Database() withTransaction { implicit session =>
|
||||||
try {
|
try {
|
||||||
using(Git.open(Directory.getRepositoryDir(owner, repository))) { git =>
|
Using.resource(Git.open(Directory.getRepositoryDir(owner, repository))) { git =>
|
||||||
JGitUtil.removeCache(git)
|
JGitUtil.removeCache(git)
|
||||||
|
|
||||||
val pushedIds = scala.collection.mutable.Set[String]()
|
val pushedIds = scala.collection.mutable.Set[String]()
|
||||||
@@ -289,7 +295,7 @@ class CommitLogHook(owner: String, repository: String, pusher: String, baseUrl:
|
|||||||
if (JGitUtil.isEmpty(git) && commits.nonEmpty && branchName != repositoryInfo.repository.defaultBranch) {
|
if (JGitUtil.isEmpty(git) && commits.nonEmpty && branchName != repositoryInfo.repository.defaultBranch) {
|
||||||
saveRepositoryDefaultBranch(owner, repository, branchName)
|
saveRepositoryDefaultBranch(owner, repository, branchName)
|
||||||
// Change repository HEAD
|
// Change repository HEAD
|
||||||
using(Git.open(Directory.getRepositoryDir(owner, repository))) { git =>
|
Using.resource(Git.open(Directory.getRepositoryDir(owner, repository))) { git =>
|
||||||
git.getRepository.updateRef(Constants.HEAD, true).link(Constants.R_HEADS + branchName)
|
git.getRepository.updateRef(Constants.HEAD, true).link(Constants.R_HEADS + branchName)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -443,7 +449,7 @@ class WikiCommitHook(owner: String, repository: String, pusher: String, baseUrl:
|
|||||||
|
|
||||||
commitIds.foreach {
|
commitIds.foreach {
|
||||||
case (oldCommitId, newCommitId) =>
|
case (oldCommitId, newCommitId) =>
|
||||||
val commits = using(Git.open(Directory.getWikiRepositoryDir(owner, repository))) { git =>
|
val commits = Using.resource(Git.open(Directory.getWikiRepositoryDir(owner, repository))) { git =>
|
||||||
JGitUtil.getCommitLog(git, oldCommitId, newCommitId).flatMap { commit =>
|
JGitUtil.getCommitLog(git, oldCommitId, newCommitId).flatMap { commit =>
|
||||||
val diffs = JGitUtil.getDiffs(git, None, commit.id, false, false)
|
val diffs = JGitUtil.getDiffs(git, None, commit.id, false, false)
|
||||||
diffs.collect {
|
diffs.collect {
|
||||||
|
|||||||
@@ -9,9 +9,12 @@ import gitbucket.core.plugin.PluginRegistry
|
|||||||
import gitbucket.core.service.{ActivityService, SystemSettingsService}
|
import gitbucket.core.service.{ActivityService, SystemSettingsService}
|
||||||
import gitbucket.core.util.DatabaseConfig
|
import gitbucket.core.util.DatabaseConfig
|
||||||
import gitbucket.core.util.Directory._
|
import gitbucket.core.util.Directory._
|
||||||
import gitbucket.core.util.SyntaxSugars._
|
|
||||||
import gitbucket.core.util.JDBCUtil._
|
import gitbucket.core.util.JDBCUtil._
|
||||||
import gitbucket.core.model.Profile.profile.blockingApi._
|
import gitbucket.core.model.Profile.profile.blockingApi._
|
||||||
|
// Imported names have higher precedence than names, defined in other files.
|
||||||
|
// If Database is not bound by explicit import, then "Database" refers to the Database introduced by the wildcard import above.
|
||||||
|
import gitbucket.core.servlet.Database
|
||||||
|
|
||||||
import io.github.gitbucket.solidbase.Solidbase
|
import io.github.gitbucket.solidbase.Solidbase
|
||||||
import io.github.gitbucket.solidbase.manager.JDBCVersionManager
|
import io.github.gitbucket.solidbase.manager.JDBCVersionManager
|
||||||
import javax.servlet.{ServletContextEvent, ServletContextListener}
|
import javax.servlet.{ServletContextEvent, ServletContextListener}
|
||||||
@@ -21,7 +24,8 @@ import org.slf4j.LoggerFactory
|
|||||||
import akka.actor.{Actor, ActorSystem, Props}
|
import akka.actor.{Actor, ActorSystem, Props}
|
||||||
import com.typesafe.akka.extension.quartz.QuartzSchedulerExtension
|
import com.typesafe.akka.extension.quartz.QuartzSchedulerExtension
|
||||||
|
|
||||||
import scala.collection.JavaConverters._
|
import scala.jdk.CollectionConverters._
|
||||||
|
import scala.util.Using
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize GitBucket system.
|
* Initialize GitBucket system.
|
||||||
@@ -84,7 +88,7 @@ class InitializeListener extends ServletContextListener with SystemSettingsServi
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Install bundled plugins
|
// Install bundled plugins
|
||||||
extractBundledPlugins(gitbucketVersion)
|
extractBundledPlugins()
|
||||||
|
|
||||||
// Load plugins
|
// Load plugins
|
||||||
logger.info("Initialize plugins")
|
logger.info("Initialize plugins")
|
||||||
@@ -134,11 +138,11 @@ class InitializeListener extends ServletContextListener with SystemSettingsServi
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private def extractBundledPlugins(gitbucketVersion: String): Unit = {
|
private def extractBundledPlugins(): Unit = {
|
||||||
logger.info("Extract bundled plugins...")
|
logger.info("Extract bundled plugins...")
|
||||||
val cl = Thread.currentThread.getContextClassLoader
|
val cl = Thread.currentThread.getContextClassLoader
|
||||||
try {
|
try {
|
||||||
using(cl.getResourceAsStream("bundle-plugins.txt")) { pluginsFile =>
|
Using.resource(cl.getResourceAsStream("bundle-plugins.txt")) { pluginsFile =>
|
||||||
if (pluginsFile != null) {
|
if (pluginsFile != null) {
|
||||||
val plugins = IOUtils.readLines(pluginsFile, "UTF-8")
|
val plugins = IOUtils.readLines(pluginsFile, "UTF-8")
|
||||||
val gitbucketVersion = GitBucketCoreModule.getVersions.asScala.last.getVersion
|
val gitbucketVersion = GitBucketCoreModule.getVersions.asScala.last.getVersion
|
||||||
@@ -146,14 +150,14 @@ class InitializeListener extends ServletContextListener with SystemSettingsServi
|
|||||||
plugins.asScala.foreach { plugin =>
|
plugins.asScala.foreach { plugin =>
|
||||||
plugin.trim.split(":") match {
|
plugin.trim.split(":") match {
|
||||||
case Array(pluginId, pluginVersion) =>
|
case Array(pluginId, pluginVersion) =>
|
||||||
val fileName = s"gitbucket-${pluginId}-plugin-gitbucket_${gitbucketVersion}-${pluginVersion}.jar"
|
val fileName = s"gitbucket-${pluginId}-plugin-${pluginVersion}.jar"
|
||||||
val in = cl.getResourceAsStream("plugins/" + fileName)
|
val in = cl.getResourceAsStream("plugins/" + fileName)
|
||||||
if (in != null) {
|
if (in != null) {
|
||||||
val file = new File(PluginHome, fileName)
|
val file = new File(PluginHome, fileName)
|
||||||
logger.info(s"Extract to ${file.getAbsolutePath}")
|
logger.info(s"Extract to ${file.getAbsolutePath}")
|
||||||
|
|
||||||
FileUtils.forceMkdirParent(file)
|
FileUtils.forceMkdirParent(file)
|
||||||
using(in, new FileOutputStream(file)) {
|
Using.resources(in, new FileOutputStream(file)) {
|
||||||
case (in, out) => IOUtils.copy(in, out)
|
case (in, out) => IOUtils.copy(in, out)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,13 +11,13 @@ import org.apache.sshd.server.session.ServerSession
|
|||||||
import org.slf4j.LoggerFactory
|
import org.slf4j.LoggerFactory
|
||||||
import java.io.{File, InputStream, OutputStream}
|
import java.io.{File, InputStream, OutputStream}
|
||||||
|
|
||||||
import SyntaxSugars._
|
|
||||||
import org.eclipse.jgit.api.Git
|
import org.eclipse.jgit.api.Git
|
||||||
import Directory._
|
import Directory._
|
||||||
import gitbucket.core.ssh.PublicKeyAuthenticator.AuthType
|
import gitbucket.core.ssh.PublicKeyAuthenticator.AuthType
|
||||||
import org.eclipse.jgit.transport.{ReceivePack, UploadPack}
|
import org.eclipse.jgit.transport.{ReceivePack, UploadPack}
|
||||||
import org.apache.sshd.server.shell.UnknownCommand
|
import org.apache.sshd.server.shell.UnknownCommand
|
||||||
import org.eclipse.jgit.errors.RepositoryNotFoundException
|
import org.eclipse.jgit.errors.RepositoryNotFoundException
|
||||||
|
import scala.util.Using
|
||||||
|
|
||||||
object GitCommand {
|
object GitCommand {
|
||||||
val DefaultCommandRegex = """\Agit-(upload|receive)-pack '/([a-zA-Z0-9\-_.]+)/([a-zA-Z0-9\-\+_.]+).git'\Z""".r
|
val DefaultCommandRegex = """\Agit-(upload|receive)-pack '/([a-zA-Z0-9\-_.]+)/([a-zA-Z0-9\-\+_.]+).git'\Z""".r
|
||||||
@@ -152,7 +152,7 @@ class DefaultGitUploadPack(owner: String, repoName: String)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (execute) {
|
if (execute) {
|
||||||
using(Git.open(getRepositoryDir(owner, repoName))) { git =>
|
Using.resource(Git.open(getRepositoryDir(owner, repoName))) { git =>
|
||||||
val repository = git.getRepository
|
val repository = git.getRepository
|
||||||
val upload = new UploadPack(repository)
|
val upload = new UploadPack(repository)
|
||||||
upload.upload(in, out, err)
|
upload.upload(in, out, err)
|
||||||
@@ -177,7 +177,7 @@ class DefaultGitReceivePack(owner: String, repoName: String, baseUrl: String, ss
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (execute) {
|
if (execute) {
|
||||||
using(Git.open(getRepositoryDir(owner, repoName))) { git =>
|
Using.resource(Git.open(getRepositoryDir(owner, repoName))) { git =>
|
||||||
val repository = git.getRepository
|
val repository = git.getRepository
|
||||||
val receive = new ReceivePack(repository)
|
val receive = new ReceivePack(repository)
|
||||||
if (!repoName.endsWith(".wiki")) {
|
if (!repoName.endsWith(".wiki")) {
|
||||||
@@ -202,7 +202,7 @@ class PluginGitUploadPack(repoName: String, routing: GitRepositoryRouting)
|
|||||||
|
|
||||||
if (execute) {
|
if (execute) {
|
||||||
val path = routing.urlPattern.r.replaceFirstIn(repoName, routing.localPath)
|
val path = routing.urlPattern.r.replaceFirstIn(repoName, routing.localPath)
|
||||||
using(Git.open(new File(Directory.GitBucketHome, path))) { git =>
|
Using.resource(Git.open(new File(Directory.GitBucketHome, path))) { git =>
|
||||||
val repository = git.getRepository
|
val repository = git.getRepository
|
||||||
val upload = new UploadPack(repository)
|
val upload = new UploadPack(repository)
|
||||||
upload.upload(in, out, err)
|
upload.upload(in, out, err)
|
||||||
@@ -222,7 +222,7 @@ class PluginGitReceivePack(repoName: String, routing: GitRepositoryRouting)
|
|||||||
|
|
||||||
if (execute) {
|
if (execute) {
|
||||||
val path = routing.urlPattern.r.replaceFirstIn(repoName, routing.localPath)
|
val path = routing.urlPattern.r.replaceFirstIn(repoName, routing.localPath)
|
||||||
using(Git.open(new File(Directory.GitBucketHome, path))) { git =>
|
Using.resource(Git.open(new File(Directory.GitBucketHome, path))) { git =>
|
||||||
val repository = git.getRepository
|
val repository = git.getRepository
|
||||||
val receive = new ReceivePack(repository)
|
val receive = new ReceivePack(repository)
|
||||||
receive.receive(in, out, err)
|
receive.receive(in, out, err)
|
||||||
|
|||||||
@@ -12,7 +12,8 @@ import org.eclipse.jgit.api.Git
|
|||||||
import org.eclipse.jgit.lib.{ObjectReader, Repository}
|
import org.eclipse.jgit.lib.{ObjectReader, Repository}
|
||||||
import org.eclipse.jgit.revwalk.{RevTree, RevWalk}
|
import org.eclipse.jgit.revwalk.{RevTree, RevWalk}
|
||||||
import org.eclipse.jgit.treewalk.TreeWalk
|
import org.eclipse.jgit.treewalk.TreeWalk
|
||||||
import gitbucket.core.util.SyntaxSugars._
|
|
||||||
|
import scala.util.Using
|
||||||
|
|
||||||
object EditorConfigUtil {
|
object EditorConfigUtil {
|
||||||
private class JGitResource(repo: Repository, revStr: String, path: Ec4jPath) extends Resource {
|
private class JGitResource(repo: Repository, revStr: String, path: Ec4jPath) extends Resource {
|
||||||
@@ -27,7 +28,7 @@ object EditorConfigUtil {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private def getRevTree: RevTree = {
|
private def getRevTree: RevTree = {
|
||||||
using(repo.newObjectReader()) { reader: ObjectReader =>
|
Using.resource(repo.newObjectReader()) { reader: ObjectReader =>
|
||||||
val revWalk = new RevWalk(reader)
|
val revWalk = new RevWalk(reader)
|
||||||
val id = repo.resolve(revStr)
|
val id = repo.resolve(revStr)
|
||||||
val commit = revWalk.parseCommit(id)
|
val commit = revWalk.parseCommit(id)
|
||||||
@@ -36,7 +37,7 @@ object EditorConfigUtil {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override def exists(): Boolean = {
|
override def exists(): Boolean = {
|
||||||
using(repo.newObjectReader()) { reader: ObjectReader =>
|
Using.resource(repo.newObjectReader()) { reader: ObjectReader =>
|
||||||
try {
|
try {
|
||||||
val treeWalk = Option(TreeWalk.forPath(reader, removeInitialSlash(path), getRevTree))
|
val treeWalk = Option(TreeWalk.forPath(reader, removeInitialSlash(path), getRevTree))
|
||||||
treeWalk.isDefined
|
treeWalk.isDefined
|
||||||
@@ -59,7 +60,7 @@ object EditorConfigUtil {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override def openReader(): Reader = {
|
override def openReader(): Reader = {
|
||||||
using(repo.newObjectReader) { reader: ObjectReader =>
|
Using.resource(repo.newObjectReader) { reader: ObjectReader =>
|
||||||
val treeWalk = TreeWalk.forPath(reader, removeInitialSlash(path), getRevTree)
|
val treeWalk = TreeWalk.forPath(reader, removeInitialSlash(path), getRevTree)
|
||||||
new InputStreamReader(reader.open(treeWalk.getObjectId(0)).openStream, StandardCharsets.UTF_8)
|
new InputStreamReader(reader.open(treeWalk.getObjectId(0)).openStream, StandardCharsets.UTF_8)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ object FileUtil {
|
|||||||
|
|
||||||
def isText(content: Array[Byte]): Boolean = !content.contains(0)
|
def isText(content: Array[Byte]): Boolean = !content.contains(0)
|
||||||
|
|
||||||
def generateFileId: String = System.currentTimeMillis + Random.alphanumeric.take(10).mkString
|
def generateFileId: String = s"${System.currentTimeMillis}${Random.alphanumeric.take(10).mkString}"
|
||||||
|
|
||||||
def getExtension(name: String): String =
|
def getExtension(name: String): String =
|
||||||
name.lastIndexOf('.') match {
|
name.lastIndexOf('.') match {
|
||||||
@@ -56,7 +56,7 @@ object FileUtil {
|
|||||||
}
|
}
|
||||||
|
|
||||||
def getLfsFilePath(owner: String, repository: String, oid: String): String =
|
def getLfsFilePath(owner: String, repository: String, oid: String): String =
|
||||||
Directory.getLfsDir(owner, repository) + "/" + checkFilename(oid)
|
s"${Directory.getLfsDir(owner, repository)}/${checkFilename(oid)}"
|
||||||
|
|
||||||
def readableSize(size: Long): String = FileUtils.byteCountToDisplaySize(size)
|
def readableSize(size: Long): String = FileUtils.byteCountToDisplaySize(size)
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
package gitbucket.core.util
|
package gitbucket.core.util
|
||||||
import java.io.ByteArrayInputStream
|
import java.io.ByteArrayInputStream
|
||||||
|
|
||||||
import collection.JavaConverters._
|
import scala.jdk.CollectionConverters._
|
||||||
|
|
||||||
import gitbucket.core.model.Profile._
|
import gitbucket.core.model.Profile._
|
||||||
import gitbucket.core.model.Profile.profile.blockingApi._
|
import gitbucket.core.model.Profile.profile.blockingApi._
|
||||||
import org.bouncycastle.bcpg.ArmoredInputStream
|
import org.bouncycastle.bcpg.ArmoredInputStream
|
||||||
|
|||||||
@@ -3,9 +3,9 @@ package gitbucket.core.util
|
|||||||
import java.io._
|
import java.io._
|
||||||
import java.sql._
|
import java.sql._
|
||||||
import java.text.SimpleDateFormat
|
import java.text.SimpleDateFormat
|
||||||
import SyntaxSugars._
|
|
||||||
import scala.annotation.tailrec
|
import scala.annotation.tailrec
|
||||||
import scala.collection.mutable.ListBuffer
|
import scala.collection.mutable.ListBuffer
|
||||||
|
import scala.util.Using
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides implicit class which extends java.sql.Connection.
|
* Provides implicit class which extends java.sql.Connection.
|
||||||
@@ -26,7 +26,7 @@ object JDBCUtil {
|
|||||||
|
|
||||||
def find[T](sql: String, params: Any*)(f: ResultSet => T): Option[T] = {
|
def find[T](sql: String, params: Any*)(f: ResultSet => T): Option[T] = {
|
||||||
execute(sql, params: _*) { stmt =>
|
execute(sql, params: _*) { stmt =>
|
||||||
using(stmt.executeQuery()) { rs =>
|
Using.resource(stmt.executeQuery()) { rs =>
|
||||||
if (rs.next) Some(f(rs)) else None
|
if (rs.next) Some(f(rs)) else None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -34,7 +34,7 @@ object JDBCUtil {
|
|||||||
|
|
||||||
def select[T](sql: String, params: Any*)(f: ResultSet => T): Seq[T] = {
|
def select[T](sql: String, params: Any*)(f: ResultSet => T): Seq[T] = {
|
||||||
execute(sql, params: _*) { stmt =>
|
execute(sql, params: _*) { stmt =>
|
||||||
using(stmt.executeQuery()) { rs =>
|
Using.resource(stmt.executeQuery()) { rs =>
|
||||||
val list = new ListBuffer[T]
|
val list = new ListBuffer[T]
|
||||||
while (rs.next) {
|
while (rs.next) {
|
||||||
list += f(rs)
|
list += f(rs)
|
||||||
@@ -46,14 +46,14 @@ object JDBCUtil {
|
|||||||
|
|
||||||
def selectInt(sql: String, params: Any*): Int = {
|
def selectInt(sql: String, params: Any*): Int = {
|
||||||
execute(sql, params: _*) { stmt =>
|
execute(sql, params: _*) { stmt =>
|
||||||
using(stmt.executeQuery()) { rs =>
|
Using.resource(stmt.executeQuery()) { rs =>
|
||||||
if (rs.next) rs.getInt(1) else 0
|
if (rs.next) rs.getInt(1) else 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private def execute[T](sql: String, params: Any*)(f: (PreparedStatement) => T): T = {
|
private def execute[T](sql: String, params: Any*)(f: (PreparedStatement) => T): T = {
|
||||||
using(conn.prepareStatement(sql)) { stmt =>
|
Using.resource(conn.prepareStatement(sql)) { stmt =>
|
||||||
params.zipWithIndex.foreach {
|
params.zipWithIndex.foreach {
|
||||||
case (p, i) =>
|
case (p, i) =>
|
||||||
p match {
|
p match {
|
||||||
@@ -68,7 +68,7 @@ object JDBCUtil {
|
|||||||
def importAsSQL(in: InputStream): Unit = {
|
def importAsSQL(in: InputStream): Unit = {
|
||||||
conn.setAutoCommit(false)
|
conn.setAutoCommit(false)
|
||||||
try {
|
try {
|
||||||
using(in) { in =>
|
Using.resource(in) { in =>
|
||||||
var out = new ByteArrayOutputStream()
|
var out = new ByteArrayOutputStream()
|
||||||
|
|
||||||
var length = 0
|
var length = 0
|
||||||
@@ -111,7 +111,7 @@ object JDBCUtil {
|
|||||||
val dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss")
|
val dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss")
|
||||||
val file = File.createTempFile("gitbucket-export-", ".sql")
|
val file = File.createTempFile("gitbucket-export-", ".sql")
|
||||||
|
|
||||||
using(new FileOutputStream(file)) { out =>
|
Using.resource(new FileOutputStream(file)) { out =>
|
||||||
val dbMeta = conn.getMetaData
|
val dbMeta = conn.getMetaData
|
||||||
val allTablesInDatabase = allTablesOrderByDependencies(dbMeta)
|
val allTablesInDatabase = allTablesOrderByDependencies(dbMeta)
|
||||||
|
|
||||||
@@ -168,7 +168,7 @@ object JDBCUtil {
|
|||||||
}
|
}
|
||||||
|
|
||||||
def allTableNames(): Seq[String] = {
|
def allTableNames(): Seq[String] = {
|
||||||
using(conn.getMetaData.getTables(null, null, "%", Seq("TABLE").toArray)) { rs =>
|
Using.resource(conn.getMetaData.getTables(null, null, "%", Seq("TABLE").toArray)) { rs =>
|
||||||
val tableNames = new ListBuffer[String]
|
val tableNames = new ListBuffer[String]
|
||||||
while (rs.next) {
|
while (rs.next) {
|
||||||
val name = rs.getString("TABLE_NAME").toUpperCase
|
val name = rs.getString("TABLE_NAME").toUpperCase
|
||||||
@@ -188,7 +188,7 @@ object JDBCUtil {
|
|||||||
tableName
|
tableName
|
||||||
}
|
}
|
||||||
|
|
||||||
using(meta.getExportedKeys(null, null, normalizedTableName)) { rs =>
|
Using.resource(meta.getExportedKeys(null, null, normalizedTableName)) { rs =>
|
||||||
val children = new ListBuffer[String]
|
val children = new ListBuffer[String]
|
||||||
while (rs.next) {
|
while (rs.next) {
|
||||||
val childTableName = rs.getString("FKTABLE_NAME").toUpperCase
|
val childTableName = rs.getString("FKTABLE_NAME").toUpperCase
|
||||||
@@ -218,7 +218,7 @@ object JDBCUtil {
|
|||||||
ordered ++ orphans
|
ordered ++ orphans
|
||||||
}
|
}
|
||||||
|
|
||||||
def tsort[A](edges: Traversable[(A, A)]): Iterable[A] = {
|
def tsort[A](edges: Iterable[(A, A)]): Iterable[A] = {
|
||||||
@tailrec
|
@tailrec
|
||||||
def tsort(toPreds: Map[A, Set[A]], done: Iterable[A]): Iterable[A] = {
|
def tsort(toPreds: Map[A, Set[A]], done: Iterable[A]): Iterable[A] = {
|
||||||
val (noPreds, hasPreds) = toPreds.partition { _._2.isEmpty }
|
val (noPreds, hasPreds) = toPreds.partition { _._2.isEmpty }
|
||||||
@@ -226,7 +226,7 @@ object JDBCUtil {
|
|||||||
if (hasPreds.isEmpty) done else sys.error(hasPreds.toString)
|
if (hasPreds.isEmpty) done else sys.error(hasPreds.toString)
|
||||||
} else {
|
} else {
|
||||||
val found = noPreds.map { _._1 }
|
val found = noPreds.map { _._1 }
|
||||||
tsort(hasPreds.mapValues { _ -- found }, done ++ found)
|
tsort(hasPreds.map { case (k, v) => (k, v -- found) }, done ++ found)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -9,7 +9,8 @@ import StringUtil._
|
|||||||
import SyntaxSugars._
|
import SyntaxSugars._
|
||||||
|
|
||||||
import scala.annotation.tailrec
|
import scala.annotation.tailrec
|
||||||
import scala.collection.JavaConverters._
|
import scala.jdk.CollectionConverters._
|
||||||
|
import scala.util.Using
|
||||||
import org.eclipse.jgit.lib._
|
import org.eclipse.jgit.lib._
|
||||||
import org.eclipse.jgit.revwalk._
|
import org.eclipse.jgit.revwalk._
|
||||||
import org.eclipse.jgit.revwalk.filter._
|
import org.eclipse.jgit.revwalk.filter._
|
||||||
@@ -20,7 +21,6 @@ import org.eclipse.jgit.errors.{ConfigInvalidException, IncorrectObjectTypeExcep
|
|||||||
import org.eclipse.jgit.transport.RefSpec
|
import org.eclipse.jgit.transport.RefSpec
|
||||||
import java.util.Date
|
import java.util.Date
|
||||||
import java.util.concurrent.TimeUnit
|
import java.util.concurrent.TimeUnit
|
||||||
import java.util.function.Consumer
|
|
||||||
|
|
||||||
import org.cache2k.Cache2kBuilder
|
import org.cache2k.Cache2kBuilder
|
||||||
import org.eclipse.jgit.api.errors._
|
import org.eclipse.jgit.api.errors._
|
||||||
@@ -29,6 +29,8 @@ import org.eclipse.jgit.dircache.DirCacheEntry
|
|||||||
import org.eclipse.jgit.util.io.DisabledOutputStream
|
import org.eclipse.jgit.util.io.DisabledOutputStream
|
||||||
import org.slf4j.LoggerFactory
|
import org.slf4j.LoggerFactory
|
||||||
|
|
||||||
|
import scala.util.Using.Releasable
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides complex JGit operations.
|
* Provides complex JGit operations.
|
||||||
*/
|
*/
|
||||||
@@ -36,6 +38,10 @@ object JGitUtil {
|
|||||||
|
|
||||||
private val logger = LoggerFactory.getLogger(JGitUtil.getClass)
|
private val logger = LoggerFactory.getLogger(JGitUtil.getClass)
|
||||||
|
|
||||||
|
implicit val objectDatabaseReleasable = new Releasable[ObjectDatabase] {
|
||||||
|
override def release(resource: ObjectDatabase): Unit = resource.close()
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The repository data.
|
* The repository data.
|
||||||
*
|
*
|
||||||
@@ -318,7 +324,7 @@ object JGitUtil {
|
|||||||
* Returns the repository information. It contains branch names and tag names.
|
* Returns the repository information. It contains branch names and tag names.
|
||||||
*/
|
*/
|
||||||
def getRepositoryInfo(owner: String, repository: String): RepositoryInfo = {
|
def getRepositoryInfo(owner: String, repository: String): RepositoryInfo = {
|
||||||
using(Git.open(getRepositoryDir(owner, repository))) { git =>
|
Using.resource(Git.open(getRepositoryDir(owner, repository))) { git =>
|
||||||
try {
|
try {
|
||||||
RepositoryInfo(
|
RepositoryInfo(
|
||||||
owner,
|
owner,
|
||||||
@@ -365,7 +371,7 @@ object JGitUtil {
|
|||||||
* @return HTML of the file list
|
* @return HTML of the file list
|
||||||
*/
|
*/
|
||||||
def getFileList(git: Git, revision: String, path: String = ".", baseUrl: Option[String] = None): List[FileInfo] = {
|
def getFileList(git: Git, revision: String, path: String = ".", baseUrl: Option[String] = None): List[FileInfo] = {
|
||||||
using(new RevWalk(git.getRepository)) { revWalk =>
|
Using.resource(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
|
||||||
val revCommit = revWalk.parseCommit(objectId)
|
val revCommit = revWalk.parseCommit(objectId)
|
||||||
@@ -374,12 +380,12 @@ object JGitUtil {
|
|||||||
if (path == ".") {
|
if (path == ".") {
|
||||||
val treeWalk = new TreeWalk(git.getRepository)
|
val treeWalk = new TreeWalk(git.getRepository)
|
||||||
treeWalk.addTree(rev.getTree)
|
treeWalk.addTree(rev.getTree)
|
||||||
using(treeWalk)(f)
|
Using.resource(treeWalk)(f)
|
||||||
} else {
|
} else {
|
||||||
val treeWalk = TreeWalk.forPath(git.getRepository, path, rev.getTree)
|
val treeWalk = TreeWalk.forPath(git.getRepository, path, rev.getTree)
|
||||||
if (treeWalk != null) {
|
if (treeWalk != null) {
|
||||||
treeWalk.enterSubtree
|
treeWalk.enterSubtree
|
||||||
using(treeWalk)(f)
|
Using.resource(treeWalk)(f)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@tailrec
|
@tailrec
|
||||||
@@ -387,7 +393,7 @@ object JGitUtil {
|
|||||||
tuple: (ObjectId, FileMode, String, String, Option[String], RevCommit)
|
tuple: (ObjectId, FileMode, String, String, Option[String], RevCommit)
|
||||||
): (ObjectId, FileMode, String, String, Option[String], RevCommit) = tuple match {
|
): (ObjectId, FileMode, String, String, Option[String], RevCommit) = tuple match {
|
||||||
case (oid, FileMode.TREE, name, path, _, commit) =>
|
case (oid, FileMode.TREE, name, path, _, commit) =>
|
||||||
(using(new TreeWalk(git.getRepository)) { walk =>
|
(Using.resource(new TreeWalk(git.getRepository)) { walk =>
|
||||||
walk.addTree(oid)
|
walk.addTree(oid)
|
||||||
// single tree child, or None
|
// single tree child, or None
|
||||||
if (walk.next() && walk.getFileMode(0) == FileMode.TREE) {
|
if (walk.next() && walk.getFileMode(0) == FileMode.TREE) {
|
||||||
@@ -521,7 +527,7 @@ object JGitUtil {
|
|||||||
* get all file list by revision. only file.
|
* get all file list by revision. only file.
|
||||||
*/
|
*/
|
||||||
def getTreeId(git: Git, revision: String): Option[String] = {
|
def getTreeId(git: Git, revision: String): Option[String] = {
|
||||||
using(new RevWalk(git.getRepository)) { revWalk =>
|
Using.resource(new RevWalk(git.getRepository)) { revWalk =>
|
||||||
val objectId = git.getRepository.resolve(revision)
|
val objectId = git.getRepository.resolve(revision)
|
||||||
if (objectId == null) return None
|
if (objectId == null) return None
|
||||||
val revCommit = revWalk.parseCommit(objectId)
|
val revCommit = revWalk.parseCommit(objectId)
|
||||||
@@ -533,10 +539,10 @@ object JGitUtil {
|
|||||||
* get all file list by tree object id.
|
* get all file list by tree object id.
|
||||||
*/
|
*/
|
||||||
def getAllFileListByTreeId(git: Git, treeId: String): List[String] = {
|
def getAllFileListByTreeId(git: Git, treeId: String): List[String] = {
|
||||||
using(new RevWalk(git.getRepository)) { revWalk =>
|
Using.resource(new RevWalk(git.getRepository)) { revWalk =>
|
||||||
val objectId = git.getRepository.resolve(treeId + "^{tree}")
|
val objectId = git.getRepository.resolve(treeId + "^{tree}")
|
||||||
if (objectId == null) return Nil
|
if (objectId == null) return Nil
|
||||||
using(new TreeWalk(git.getRepository)) { treeWalk =>
|
Using.resource(new TreeWalk(git.getRepository)) { treeWalk =>
|
||||||
treeWalk.addTree(objectId)
|
treeWalk.addTree(objectId)
|
||||||
treeWalk.setRecursive(true)
|
treeWalk.setRecursive(true)
|
||||||
var ret: List[String] = Nil
|
var ret: List[String] = Nil
|
||||||
@@ -587,7 +593,7 @@ object JGitUtil {
|
|||||||
case _ => (logs, i.hasNext)
|
case _ => (logs, i.hasNext)
|
||||||
}
|
}
|
||||||
|
|
||||||
using(new RevWalk(git.getRepository)) { revWalk =>
|
Using.resource(new RevWalk(git.getRepository)) { revWalk =>
|
||||||
defining(git.getRepository.resolve(revision)) { objectId =>
|
defining(git.getRepository.resolve(revision)) { objectId =>
|
||||||
if (objectId == null) {
|
if (objectId == null) {
|
||||||
Left(s"${revision} can't be resolved.")
|
Left(s"${revision} can't be resolved.")
|
||||||
@@ -619,7 +625,7 @@ object JGitUtil {
|
|||||||
case false => logs
|
case false => logs
|
||||||
}
|
}
|
||||||
|
|
||||||
using(new RevWalk(git.getRepository)) { revWalk =>
|
Using.resource(new RevWalk(git.getRepository)) { revWalk =>
|
||||||
revWalk.markStart(revWalk.parseCommit(git.getRepository.resolve(begin)))
|
revWalk.markStart(revWalk.parseCommit(git.getRepository.resolve(begin)))
|
||||||
getCommitLog(revWalk.iterator, Nil).reverse
|
getCommitLog(revWalk.iterator, Nil).reverse
|
||||||
}
|
}
|
||||||
@@ -679,12 +685,12 @@ object JGitUtil {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private def getDiffEntries(git: Git, from: Option[String], to: String): Seq[DiffEntry] = {
|
private def getDiffEntries(git: Git, from: Option[String], to: String): Seq[DiffEntry] = {
|
||||||
using(new RevWalk(git.getRepository)) { revWalk =>
|
Using.resource(new RevWalk(git.getRepository)) { revWalk =>
|
||||||
val df = new DiffFormatter(DisabledOutputStream.INSTANCE)
|
val df = new DiffFormatter(DisabledOutputStream.INSTANCE)
|
||||||
df.setRepository(git.getRepository)
|
df.setRepository(git.getRepository)
|
||||||
|
|
||||||
val toCommit = revWalk.parseCommit(git.getRepository.resolve(to))
|
val toCommit = revWalk.parseCommit(git.getRepository.resolve(to))
|
||||||
from match {
|
(from match {
|
||||||
case None => {
|
case None => {
|
||||||
toCommit.getParentCount match {
|
toCommit.getParentCount match {
|
||||||
case 0 =>
|
case 0 =>
|
||||||
@@ -700,12 +706,12 @@ object JGitUtil {
|
|||||||
val fromCommit = revWalk.parseCommit(git.getRepository.resolve(from))
|
val fromCommit = revWalk.parseCommit(git.getRepository.resolve(from))
|
||||||
df.scan(fromCommit.getTree, toCommit.getTree).asScala
|
df.scan(fromCommit.getTree, toCommit.getTree).asScala
|
||||||
}
|
}
|
||||||
}
|
}).toSeq
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
def getParentCommitId(git: Git, id: String): Option[String] = {
|
def getParentCommitId(git: Git, id: String): Option[String] = {
|
||||||
using(new RevWalk(git.getRepository)) { revWalk =>
|
Using.resource(new RevWalk(git.getRepository)) { revWalk =>
|
||||||
val commit = revWalk.parseCommit(git.getRepository.resolve(id))
|
val commit = revWalk.parseCommit(git.getRepository.resolve(id))
|
||||||
commit.getParentCount match {
|
commit.getParentCount match {
|
||||||
case 0 => None
|
case 0 => None
|
||||||
@@ -787,7 +793,7 @@ object JGitUtil {
|
|||||||
|
|
||||||
private def makePatchFromDiffEntry(git: Git, diff: DiffEntry): String = {
|
private def makePatchFromDiffEntry(git: Git, diff: DiffEntry): String = {
|
||||||
val out = new ByteArrayOutputStream()
|
val out = new ByteArrayOutputStream()
|
||||||
using(new DiffFormatter(out)) { formatter =>
|
Using.resource(new DiffFormatter(out)) { formatter =>
|
||||||
formatter.setRepository(git.getRepository)
|
formatter.setRepository(git.getRepository)
|
||||||
formatter.format(diff)
|
formatter.format(diff)
|
||||||
val patch = new String(out.toByteArray) // TODO charset???
|
val patch = new String(out.toByteArray) // TODO charset???
|
||||||
@@ -799,7 +805,7 @@ object JGitUtil {
|
|||||||
* Returns the list of branch names of the specified commit.
|
* Returns the list of branch names of the specified commit.
|
||||||
*/
|
*/
|
||||||
def getBranchesOfCommit(git: Git, commitId: String): List[String] =
|
def getBranchesOfCommit(git: Git, commitId: String): List[String] =
|
||||||
using(new RevWalk(git.getRepository)) { revWalk =>
|
Using.resource(new RevWalk(git.getRepository)) { revWalk =>
|
||||||
defining(revWalk.parseCommit(git.getRepository.resolve(commitId + "^0"))) { commit =>
|
defining(revWalk.parseCommit(git.getRepository.resolve(commitId + "^0"))) { commit =>
|
||||||
git.getRepository.getRefDatabase
|
git.getRepository.getRefDatabase
|
||||||
.getRefsByPrefix(Constants.R_HEADS)
|
.getRefsByPrefix(Constants.R_HEADS)
|
||||||
@@ -842,7 +848,7 @@ object JGitUtil {
|
|||||||
* Returns the list of tags which contains the specified commit.
|
* Returns the list of tags which contains the specified commit.
|
||||||
*/
|
*/
|
||||||
def getTagsOfCommit(git: Git, commitId: String): List[String] =
|
def getTagsOfCommit(git: Git, commitId: String): List[String] =
|
||||||
using(new RevWalk(git.getRepository)) { revWalk =>
|
Using.resource(new RevWalk(git.getRepository)) { revWalk =>
|
||||||
defining(revWalk.parseCommit(git.getRepository.resolve(commitId + "^0"))) { commit =>
|
defining(revWalk.parseCommit(git.getRepository.resolve(commitId + "^0"))) { commit =>
|
||||||
git.getRepository.getRefDatabase
|
git.getRepository.getRefDatabase
|
||||||
.getRefsByPrefix(Constants.R_TAGS)
|
.getRefsByPrefix(Constants.R_TAGS)
|
||||||
@@ -863,13 +869,13 @@ object JGitUtil {
|
|||||||
}
|
}
|
||||||
|
|
||||||
def initRepository(dir: java.io.File): Unit =
|
def initRepository(dir: java.io.File): Unit =
|
||||||
using(new RepositoryBuilder().setGitDir(dir).setBare.build) { repository =>
|
Using.resource(new RepositoryBuilder().setGitDir(dir).setBare.build) { repository =>
|
||||||
repository.create(true)
|
repository.create(true)
|
||||||
setReceivePack(repository)
|
setReceivePack(repository)
|
||||||
}
|
}
|
||||||
|
|
||||||
def cloneRepository(from: java.io.File, to: java.io.File): Unit =
|
def cloneRepository(from: java.io.File, to: java.io.File): Unit =
|
||||||
using(Git.cloneRepository.setURI(from.toURI.toString).setDirectory(to).setBare(true).call) { git =>
|
Using.resource(Git.cloneRepository.setURI(from.toURI.toString).setDirectory(to).setBare(true).call) { git =>
|
||||||
setReceivePack(git.getRepository)
|
setReceivePack(git.getRepository)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -899,7 +905,7 @@ object JGitUtil {
|
|||||||
def createTag(git: Git, name: String, message: Option[String], commitId: String) = {
|
def createTag(git: Git, name: String, message: Option[String], commitId: String) = {
|
||||||
try {
|
try {
|
||||||
val objectId: ObjectId = git.getRepository.resolve(commitId)
|
val objectId: ObjectId = git.getRepository.resolve(commitId)
|
||||||
using(new RevWalk(git.getRepository)) { walk =>
|
Using.resource(new RevWalk(git.getRepository)) { walk =>
|
||||||
val tagCommand = git.tag().setName(name).setObjectId(walk.parseCommit(objectId))
|
val tagCommand = git.tag().setName(name).setObjectId(walk.parseCommit(objectId))
|
||||||
message.foreach { message =>
|
message.foreach { message =>
|
||||||
tagCommand.setMessage(message)
|
tagCommand.setMessage(message)
|
||||||
@@ -908,10 +914,10 @@ object JGitUtil {
|
|||||||
}
|
}
|
||||||
Right("Tag added.")
|
Right("Tag added.")
|
||||||
} catch {
|
} catch {
|
||||||
case e: GitAPIException => Left("Sorry, some Git operation error occurs.")
|
case e: ConcurrentRefUpdateException => Left("Sorry, some error occurs.")
|
||||||
case e: ConcurrentRefUpdateException => Left("Sorry some error occurs.")
|
|
||||||
case e: InvalidTagNameException => Left("Sorry, that name is invalid.")
|
case e: InvalidTagNameException => Left("Sorry, that name is invalid.")
|
||||||
case e: NoHeadException => Left("Sorry, this repo doesn't have HEAD reference")
|
case e: NoHeadException => Left("Sorry, this repo doesn't have HEAD reference")
|
||||||
|
case e: GitAPIException => Left("Sorry, some Git operation error occurs.")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1004,7 +1010,7 @@ object JGitUtil {
|
|||||||
case false => None
|
case false => None
|
||||||
}
|
}
|
||||||
|
|
||||||
using(new TreeWalk(git.getRepository)) { treeWalk =>
|
Using.resource(new TreeWalk(git.getRepository)) { treeWalk =>
|
||||||
treeWalk.addTree(revTree)
|
treeWalk.addTree(revTree)
|
||||||
treeWalk.setRecursive(true)
|
treeWalk.setRecursive(true)
|
||||||
getPathObjectId(path, treeWalk)
|
getPathObjectId(path, treeWalk)
|
||||||
@@ -1049,7 +1055,7 @@ object JGitUtil {
|
|||||||
|
|
||||||
def getContentInfo(git: Git, path: String, objectId: ObjectId): ContentInfo = {
|
def getContentInfo(git: Git, path: String, objectId: ObjectId): ContentInfo = {
|
||||||
// Viewer
|
// Viewer
|
||||||
using(git.getRepository.getObjectDatabase) { db =>
|
Using.resource(git.getRepository.getObjectDatabase) { db =>
|
||||||
val loader = db.open(objectId)
|
val loader = db.open(objectId)
|
||||||
val isLfs = isLfsPointer(loader)
|
val isLfs = isLfsPointer(loader)
|
||||||
val large = FileUtil.isLarge(loader.getSize)
|
val large = FileUtil.isLarge(loader.getSize)
|
||||||
@@ -1087,7 +1093,7 @@ object JGitUtil {
|
|||||||
*/
|
*/
|
||||||
def getContentFromId(git: Git, id: ObjectId, fetchLargeFile: Boolean): Option[Array[Byte]] =
|
def getContentFromId(git: Git, id: ObjectId, fetchLargeFile: Boolean): Option[Array[Byte]] =
|
||||||
try {
|
try {
|
||||||
using(git.getRepository.getObjectDatabase) { db =>
|
Using.resource(git.getRepository.getObjectDatabase) { db =>
|
||||||
val loader = db.open(id)
|
val loader = db.open(id)
|
||||||
if (loader.isLarge || (fetchLargeFile == false && FileUtil.isLarge(loader.getSize))) {
|
if (loader.isLarge || (fetchLargeFile == false && FileUtil.isLarge(loader.getSize))) {
|
||||||
None
|
None
|
||||||
@@ -1109,7 +1115,7 @@ object JGitUtil {
|
|||||||
*/
|
*/
|
||||||
def getObjectLoaderFromId[A](git: Git, id: ObjectId)(f: ObjectLoader => A): Option[A] =
|
def getObjectLoaderFromId[A](git: Git, id: ObjectId)(f: ObjectLoader => A): Option[A] =
|
||||||
try {
|
try {
|
||||||
using(git.getRepository.getObjectDatabase) { db =>
|
Using.resource(git.getRepository.getObjectDatabase) { db =>
|
||||||
Some(f(db.open(id)))
|
Some(f(db.open(id)))
|
||||||
}
|
}
|
||||||
} catch {
|
} catch {
|
||||||
@@ -1132,8 +1138,8 @@ object JGitUtil {
|
|||||||
}
|
}
|
||||||
|
|
||||||
def processTree[T](git: Git, id: ObjectId)(f: (String, CanonicalTreeParser) => T): Seq[T] = {
|
def processTree[T](git: Git, id: ObjectId)(f: (String, CanonicalTreeParser) => T): Seq[T] = {
|
||||||
using(new RevWalk(git.getRepository)) { revWalk =>
|
Using.resource(new RevWalk(git.getRepository)) { revWalk =>
|
||||||
using(new TreeWalk(git.getRepository)) { treeWalk =>
|
Using.resource(new TreeWalk(git.getRepository)) { treeWalk =>
|
||||||
val index = treeWalk.addTree(revWalk.parseTree(id))
|
val index = treeWalk.addTree(revWalk.parseTree(id))
|
||||||
treeWalk.setRecursive(true)
|
treeWalk.setRecursive(true)
|
||||||
val result = new collection.mutable.ListBuffer[T]()
|
val result = new collection.mutable.ListBuffer[T]()
|
||||||
@@ -1177,7 +1183,7 @@ object JGitUtil {
|
|||||||
requestRepositoryName: String,
|
requestRepositoryName: String,
|
||||||
requestBranch: String
|
requestBranch: String
|
||||||
): (String, String) =
|
): (String, String) =
|
||||||
using(
|
Using.resources(
|
||||||
Git.open(Directory.getRepositoryDir(userName, repositoryName)),
|
Git.open(Directory.getRepositoryDir(userName, repositoryName)),
|
||||||
Git.open(Directory.getRepositoryDir(requestUserName, requestRepositoryName))
|
Git.open(Directory.getRepositoryDir(requestUserName, requestRepositoryName))
|
||||||
) { (oldGit, newGit) =>
|
) { (oldGit, newGit) =>
|
||||||
@@ -1247,7 +1253,7 @@ object JGitUtil {
|
|||||||
} finally {
|
} finally {
|
||||||
walk.dispose()
|
walk.dispose()
|
||||||
}
|
}
|
||||||
}
|
}.toSeq
|
||||||
}
|
}
|
||||||
|
|
||||||
def getBlame(git: Git, id: String, path: String): Iterable[BlameInfo] = {
|
def getBlame(git: Git, id: String, path: String): Iterable[BlameInfo] = {
|
||||||
@@ -1277,7 +1283,7 @@ object JGitUtil {
|
|||||||
}
|
}
|
||||||
idLine :+= (c.name, i)
|
idLine :+= (c.name, i)
|
||||||
}
|
}
|
||||||
val limeMap = idLine.groupBy(_._1).mapValues(_.map(_._2).toSet)
|
val limeMap = idLine.groupBy(_._1).view.mapValues(_.map(_._2).toSet)
|
||||||
blameMap.values.map { b =>
|
blameMap.values.map { b =>
|
||||||
b.copy(lines = limeMap(b.id))
|
b.copy(lines = limeMap(b.id))
|
||||||
}
|
}
|
||||||
@@ -1294,7 +1300,7 @@ object JGitUtil {
|
|||||||
* @return sha1
|
* @return sha1
|
||||||
*/
|
*/
|
||||||
def getShaByRef(owner: String, name: String, revstr: String): Option[String] = {
|
def getShaByRef(owner: String, name: String, revstr: String): Option[String] = {
|
||||||
using(Git.open(getRepositoryDir(owner, name))) { git =>
|
Using.resource(Git.open(getRepositoryDir(owner, name))) { git =>
|
||||||
Option(git.getRepository.resolve(revstr)).map(ObjectId.toString(_))
|
Option(git.getRepository.resolve(revstr)).map(ObjectId.toString(_))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1309,14 +1315,14 @@ object JGitUtil {
|
|||||||
if (lfsAttrs.nonEmpty) {
|
if (lfsAttrs.nonEmpty) {
|
||||||
val oid = lfsAttrs("oid").split(":")(1)
|
val oid = lfsAttrs("oid").split(":")(1)
|
||||||
|
|
||||||
using(new FileInputStream(FileUtil.getLfsFilePath(repository.owner, repository.name, oid))) { in =>
|
Using.resource(new FileInputStream(FileUtil.getLfsFilePath(repository.owner, repository.name, oid))) { in =>
|
||||||
f(in)
|
f(in)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
throw new NoSuchElementException("LFS attribute is empty.")
|
throw new NoSuchElementException("LFS attribute is empty.")
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
using(loader.openStream()) { in =>
|
Using.resource(loader.openStream()) { in =>
|
||||||
f(in)
|
f(in)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1325,7 +1331,7 @@ object JGitUtil {
|
|||||||
def openFile[T](git: Git, repository: RepositoryService.RepositoryInfo, tree: RevTree, path: String)(
|
def openFile[T](git: Git, repository: RepositoryService.RepositoryInfo, tree: RevTree, path: String)(
|
||||||
f: InputStream => T
|
f: InputStream => T
|
||||||
): T = {
|
): T = {
|
||||||
using(TreeWalk.forPath(git.getRepository, path, tree)) { treeWalk =>
|
Using.resource(TreeWalk.forPath(git.getRepository, path, tree)) { treeWalk =>
|
||||||
openFile(git, repository, treeWalk)(f)
|
openFile(git, repository, treeWalk)(f)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ object SyntaxSugars {
|
|||||||
|
|
||||||
def defining[A, B](value: A)(f: A => B): B = f(value)
|
def defining[A, B](value: A)(f: A => B): B = f(value)
|
||||||
|
|
||||||
|
@deprecated("Use scala.util.Using.resource instead", "4.32.0")
|
||||||
def using[A <: { def close(): Unit }, B](resource: A)(f: A => B): B =
|
def using[A <: { def close(): Unit }, B](resource: A)(f: A => B): B =
|
||||||
try f(resource)
|
try f(resource)
|
||||||
finally {
|
finally {
|
||||||
@@ -21,6 +22,7 @@ object SyntaxSugars {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@deprecated("Use scala.util.Using.resources instead", "4.32.0")
|
||||||
def using[A <: { def close(): Unit }, B <: { def close(): Unit }, C](resource1: A, resource2: B)(f: (A, B) => C): C =
|
def using[A <: { def close(): Unit }, B <: { def close(): Unit }, C](resource1: A, resource2: B)(f: (A, B) => C): C =
|
||||||
try f(resource1, resource2)
|
try f(resource1, resource2)
|
||||||
finally {
|
finally {
|
||||||
@@ -36,10 +38,12 @@ object SyntaxSugars {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@deprecated("Use scala.util.Using.resource instead", "4.32.0")
|
||||||
def using[T](git: Git)(f: Git => T): T =
|
def using[T](git: Git)(f: Git => T): T =
|
||||||
try f(git)
|
try f(git)
|
||||||
finally git.getRepository.close()
|
finally git.getRepository.close()
|
||||||
|
|
||||||
|
@deprecated("Use scala.util.Using.resources instead", "4.32.0")
|
||||||
def using[T](git1: Git, git2: Git)(f: (Git, Git) => T): T =
|
def using[T](git1: Git, git2: Git)(f: (Git, Git) => T): T =
|
||||||
try f(git1, git2)
|
try f(git1, git2)
|
||||||
finally {
|
finally {
|
||||||
|
|||||||
@@ -169,22 +169,31 @@ object Markdown {
|
|||||||
private def fixUrl(url: String, branch: String, isImage: Boolean = false): String = {
|
private def fixUrl(url: String, branch: String, isImage: Boolean = false): String = {
|
||||||
lazy val urlWithRawParam: String = url + (if (isImage && !url.endsWith("?raw=true")) "?raw=true" else "")
|
lazy val urlWithRawParam: String = url + (if (isImage && !url.endsWith("?raw=true")) "?raw=true" else "")
|
||||||
|
|
||||||
if (url.startsWith("http://") || url.startsWith("https://") || url.startsWith("mailto:") || url.startsWith("/")) {
|
if (url.startsWith("http://") || url.startsWith("https://") || url.startsWith("mailto:")) {
|
||||||
url
|
url
|
||||||
|
} else if (url.startsWith("/")) {
|
||||||
|
context.baseUrl + url
|
||||||
} else if (url.startsWith("#")) {
|
} else if (url.startsWith("#")) {
|
||||||
("#" + generateAnchorName(url.substring(1)))
|
("#" + generateAnchorName(url.substring(1)))
|
||||||
} else if (!enableWikiLink) {
|
|
||||||
if (context.currentPath.contains("/blob/")) {
|
|
||||||
urlWithRawParam
|
|
||||||
} else if (context.currentPath.contains("/tree/")) {
|
|
||||||
val paths = context.currentPath.split("/")
|
|
||||||
val path = if (paths.length > 3) paths.drop(4).mkString("/") else branch
|
|
||||||
repository.httpUrl.replaceFirst("/git/", "/").stripSuffix(".git") + "/blob/" + path + "/" + urlWithRawParam
|
|
||||||
} else {
|
|
||||||
repository.httpUrl.replaceFirst("/git/", "/").stripSuffix(".git") + "/blob/" + branch + "/" + urlWithRawParam
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
repository.httpUrl.replaceFirst("/git/", "/").stripSuffix(".git") + "/wiki/_blob/" + url
|
// Relative path
|
||||||
|
if (!enableWikiLink) {
|
||||||
|
if (context.currentPath.contains("/blob/")) {
|
||||||
|
val paths = context.currentPath.split("/").dropRight(1)
|
||||||
|
val path = if (paths.length > 3) paths.drop(4).mkString("/") else branch
|
||||||
|
repository.httpUrl.replaceFirst("/git/", "/").stripSuffix(".git") + "/blob/" + path + "/" + urlWithRawParam
|
||||||
|
} else if (context.currentPath.contains("/tree/")) {
|
||||||
|
val paths = context.currentPath.split("/")
|
||||||
|
val path = if (paths.length > 3) paths.drop(4).mkString("/") else branch
|
||||||
|
repository.httpUrl.replaceFirst("/git/", "/").stripSuffix(".git") + "/blob/" + path + "/" + urlWithRawParam
|
||||||
|
} else {
|
||||||
|
repository.httpUrl
|
||||||
|
.replaceFirst("/git/", "/")
|
||||||
|
.stripSuffix(".git") + "/blob/" + branch + "/" + urlWithRawParam
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
repository.httpUrl.replaceFirst("/git/", "/").stripSuffix(".git") + "/wiki/_blob/" + url
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -218,14 +218,18 @@ object helpers extends AvatarImageProvider with LinkConverter with RequestCache
|
|||||||
.replaceAll(
|
.replaceAll(
|
||||||
"\\[branch:([^\\s]+?)/([^\\s]+?)#([^\\s]+?)\\]",
|
"\\[branch:([^\\s]+?)/([^\\s]+?)#([^\\s]+?)\\]",
|
||||||
(m: Match) =>
|
(m: Match) =>
|
||||||
s"""<a href="${context.path}/${m.group(1)}/${m.group(2)}/tree/${encodeRefName(m.group(3))}">${m
|
s"""<a href="${context.path}/${m.group(1)}/${m.group(2)}/tree/${encodeRefName(m.group(3))}">${StringUtil
|
||||||
.group(3)}</a>"""
|
.escapeHtml(
|
||||||
|
m.group(3)
|
||||||
|
)}</a>"""
|
||||||
)
|
)
|
||||||
.replaceAll(
|
.replaceAll(
|
||||||
"\\[tag:([^\\s]+?)/([^\\s]+?)#([^\\s]+?)\\]",
|
"\\[tag:([^\\s]+?)/([^\\s]+?)#([^\\s]+?)\\]",
|
||||||
(m: Match) =>
|
(m: Match) =>
|
||||||
s"""<a href="${context.path}/${m.group(1)}/${m.group(2)}/tree/${encodeRefName(m.group(3))}">${m
|
s"""<a href="${context.path}/${m.group(1)}/${m.group(2)}/tree/${encodeRefName(m.group(3))}">${StringUtil
|
||||||
.group(3)}</a>"""
|
.escapeHtml(
|
||||||
|
m.group(3)
|
||||||
|
)}</a>"""
|
||||||
)
|
)
|
||||||
.replaceAll("\\[user:([^\\s]+?)\\]", (m: Match) => user(m.group(1)).body)
|
.replaceAll("\\[user:([^\\s]+?)\\]", (m: Match) => user(m.group(1)).body)
|
||||||
.replaceAll(
|
.replaceAll(
|
||||||
@@ -237,8 +241,10 @@ object helpers extends AvatarImageProvider with LinkConverter with RequestCache
|
|||||||
.replaceAll(
|
.replaceAll(
|
||||||
"\\[release:([^\\s]+?)/([^\\s]+?)/([^\\s]+?):(.+)\\]",
|
"\\[release:([^\\s]+?)/([^\\s]+?)/([^\\s]+?):(.+)\\]",
|
||||||
(m: Match) =>
|
(m: Match) =>
|
||||||
s"""<a href="${context.path}/${m.group(1)}/${m.group(2)}/releases/${encodeRefName(m.group(3))}">${m
|
s"""<a href="${context.path}/${m.group(1)}/${m.group(2)}/releases/${encodeRefName(m.group(3))}">${StringUtil
|
||||||
.group(4)}</a>"""
|
.escapeHtml(
|
||||||
|
m.group(4)
|
||||||
|
)}</a>"""
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -12,21 +12,26 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div style="padding-left: 10px; padding-right: 10px;">
|
<div style="padding-left: 10px; padding-right: 10px;">
|
||||||
@account.description.map{ description =>
|
@account.description.map { description =>
|
||||||
<p style="color: #999">@description</p>
|
<p style="color: #999">@description</p>
|
||||||
}
|
}
|
||||||
@if(account.url.isDefined){
|
@account.url.map { url =>
|
||||||
<p style="white-space: nowrap; overflow: hidden; text-overflow: ellipsis;">
|
<p style="white-space: nowrap; overflow: hidden; text-overflow: ellipsis;">
|
||||||
<i class="octicon octicon-home"></i> <a href="@account.url">@account.url</a>
|
<i class="octicon octicon-home"></i>
|
||||||
|
@if(url.startsWith("http://") || url.startsWith("https://")){
|
||||||
|
<a href="@url">@url</a>
|
||||||
|
} else {
|
||||||
|
<span style="color: #999">@url</span>
|
||||||
|
}
|
||||||
</p>
|
</p>
|
||||||
}
|
}
|
||||||
@if(context.settings.showMailAddress){
|
@if(context.settings.showMailAddress){
|
||||||
<p style="white-space: nowrap; overflow: hidden; text-overflow: ellipsis;">
|
<p style="white-space: nowrap; overflow: hidden; text-overflow: ellipsis;">
|
||||||
<i class="octicon octicon-mail"></i> <a href="mailto: @account.mailAddress">@account.mailAddress</a>
|
<i class="octicon octicon-mail"></i> <a href="mailto:@account.mailAddress">@account.mailAddress</a>
|
||||||
</p>
|
</p>
|
||||||
@extraMailAddresses.map{ mail =>
|
@extraMailAddresses.map { mail =>
|
||||||
<p style="white-space: nowrap; overflow: hidden; text-overflow: ellipsis;">
|
<p style="white-space: nowrap; overflow: hidden; text-overflow: ellipsis;">
|
||||||
<i class="octicon octicon-mail"></i> <a href="mailto: @mail">@mail</a>
|
<i class="octicon octicon-mail"></i> <a href="mailto:@mail">@mail</a>
|
||||||
</p>
|
</p>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -84,10 +84,10 @@ isCreateRepoOptionPublic: Boolean)(implicit context: gitbucket.core.controller.C
|
|||||||
<span class="strong">Copy existing git repository</span>
|
<span class="strong">Copy existing git repository</span>
|
||||||
<div class="normal muted">
|
<div class="normal muted">
|
||||||
Create new repository from existing git repository.
|
Create new repository from existing git repository.
|
||||||
<input type="text" class="form-control" name="sourceUrl" id="sourceUrl" disabled placeholder="Source git repository URL..."/>
|
|
||||||
<span id="error-sourceUrl" class="error"></span>
|
|
||||||
</div>
|
</div>
|
||||||
</label>
|
</label>
|
||||||
|
<input type="text" class="form-control" name="sourceUrl" id="sourceUrl" disabled placeholder="Source git repository URL..."/>
|
||||||
|
<span id="error-sourceUrl" class="error"></span>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
<fieldset class="border-top form-actions">
|
<fieldset class="border-top form-actions">
|
||||||
<input type="submit" class="btn btn-success" value="Create repository"/>
|
<input type="submit" class="btn btn-success" value="Create repository"/>
|
||||||
|
|||||||
@@ -19,7 +19,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<form method="POST" action="@context.path/@account.userName/_ssh" validate="true" autocomplete="off">
|
<form method="POST" action="@context.path/@account.userName/_ssh" validate="true" autocomplete="off">
|
||||||
<div class="panel panel-default">
|
<div class="panel panel-default">
|
||||||
<div class="panel-heading strong">Add a SSH Key</div>
|
<div class="panel-heading strong">Add a public SSH Key</div>
|
||||||
<div class="panel-body">
|
<div class="panel-body">
|
||||||
<fieldset class="form-group">
|
<fieldset class="form-group">
|
||||||
<label for="title" class="strong">Title</label>
|
<label for="title" class="strong">Title</label>
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
@(plugins: List[(gitbucket.core.plugin.PluginInfoBase, Boolean, String)], info: Option[Any])(implicit context: gitbucket.core.controller.Context)
|
@(plugins: List[gitbucket.core.plugin.PluginInfoBase], info: Option[Any])(implicit context: gitbucket.core.controller.Context)
|
||||||
@gitbucket.core.html.main("Plugins"){
|
@gitbucket.core.html.main("Plugins"){
|
||||||
@gitbucket.core.admin.html.menu("plugins") {
|
@gitbucket.core.admin.html.menu("plugins") {
|
||||||
@gitbucket.core.helper.html.information(info)
|
@gitbucket.core.helper.html.information(info)
|
||||||
@@ -8,26 +8,17 @@
|
|||||||
<h1 class="system-settings-title">Plugins</h1>
|
<h1 class="system-settings-title">Plugins</h1>
|
||||||
@if(plugins.size > 0) {
|
@if(plugins.size > 0) {
|
||||||
<ul>
|
<ul>
|
||||||
@plugins.map { case (plugin, enabled, updatableVersion) =>
|
@plugins.map { plugin =>
|
||||||
<li><a href="#@plugin.pluginId">@plugin.pluginId:@plugin.pluginVersion</a></li>
|
<li><a href="#@plugin.pluginId">@plugin.pluginId:@plugin.pluginVersion</a></li>
|
||||||
}
|
}
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
@plugins.map { case (plugin, enabled, updatableVersion) =>
|
@plugins.map { plugin =>
|
||||||
<div class="panel panel-default">
|
<div class="panel panel-default">
|
||||||
<div class="panel-heading strong" id="@plugin.pluginId">
|
<div class="panel-heading strong" id="@plugin.pluginId">
|
||||||
<form method="POST" class="pull-right">
|
<form method="POST" class="pull-right">
|
||||||
@if(enabled){
|
<input type="submit" value="Uninstall" class="btn btn-danger btn-sm uninstall-plugin" style="position: relative; top: -5px; left: 10px;"
|
||||||
@if(updatableVersion.nonEmpty){
|
data-name="@plugin.pluginName" formaction="@{context.path}/admin/plugins/@{plugin.pluginId}/_uninstall">
|
||||||
<input type="submit" value="Update" class="btn btn-success btn-sm update-plugin" style="position: relative; top: -5px; left: 10px;"
|
|
||||||
data-name="@plugin.pluginName" formaction="@{context.path}/admin/plugins/@{plugin.pluginId}/@{updatableVersion}/_install">
|
|
||||||
}
|
|
||||||
<input type="submit" value="Uninstall" class="btn btn-danger btn-sm uninstall-plugin" style="position: relative; top: -5px; left: 10px;"
|
|
||||||
data-name="@plugin.pluginName" formaction="@{context.path}/admin/plugins/@{plugin.pluginId}/_uninstall">
|
|
||||||
} else {
|
|
||||||
<input type="submit" value="Install" class="btn btn-success btn-sm install-plugin" style="position: relative; top: -5px; left: 10px;"
|
|
||||||
data-name="@plugin.pluginName" formaction="@{context.path}/admin/plugins/@{plugin.pluginId}/@{plugin.pluginVersion}/_install">
|
|
||||||
}
|
|
||||||
</form>
|
</form>
|
||||||
@plugin.pluginName
|
@plugin.pluginName
|
||||||
</div>
|
</div>
|
||||||
@@ -58,15 +49,5 @@
|
|||||||
var name = $(e.target).data('name');
|
var name = $(e.target).data('name');
|
||||||
return confirm('Uninstall ' + name + '. Are you sure?');
|
return confirm('Uninstall ' + name + '. Are you sure?');
|
||||||
});
|
});
|
||||||
|
|
||||||
$('.install-plugin').click(function(e){
|
|
||||||
var name = $(e.target).data('name');
|
|
||||||
return confirm('Install ' + name + '. Are you sure?');
|
|
||||||
});
|
|
||||||
|
|
||||||
$('.update-plugin').click(function(e){
|
|
||||||
var name = $(e.target).data('name');
|
|
||||||
return confirm('Update ' + name + '. Are you sure?');
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -17,9 +17,6 @@
|
|||||||
<div class="tab-pane" id="authentication">
|
<div class="tab-pane" id="authentication">
|
||||||
@settings_authentication(info)
|
@settings_authentication(info)
|
||||||
</div>
|
</div>
|
||||||
<div class="tab-pane" id="plugins">
|
|
||||||
@settings_plugins(info)
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<hr>
|
<hr>
|
||||||
<div class="align-right" style="margin-top: 20px;">
|
<div class="align-right" style="margin-top: 20px;">
|
||||||
@@ -34,9 +31,6 @@ $(function(){
|
|||||||
if(location.hash == '#authentication'){
|
if(location.hash == '#authentication'){
|
||||||
$('li:has(a[href="#authentication"])').addClass('active');
|
$('li:has(a[href="#authentication"])').addClass('active');
|
||||||
$('div#authentication').addClass('active');
|
$('div#authentication').addClass('active');
|
||||||
} else if(location.hash == '#plugins'){
|
|
||||||
$('li:has(a[href="#plugins"])').addClass('active');
|
|
||||||
$('div#plugins').addClass('active');
|
|
||||||
} else {
|
} else {
|
||||||
$('li:has(a[href="#system"])').addClass('active');
|
$('li:has(a[href="#system"])').addClass('active');
|
||||||
$('div#system').addClass('active');
|
$('div#system').addClass('active');
|
||||||
|
|||||||
@@ -1,52 +0,0 @@
|
|||||||
@(info: Option[Any])(implicit context: gitbucket.core.controller.Context)
|
|
||||||
<label class="strong">Plugin repositories</label>
|
|
||||||
<fieldset>
|
|
||||||
<label class="checkbox">
|
|
||||||
<input type="checkbox" id="pluginNetworkInstall" name="pluginNetworkInstall"@if(context.settings.pluginNetworkInstall){ checked} />
|
|
||||||
<a href="https://plugins.gitbucket-community.org" target="_blank">plugins.gitbucket-community.org</a>
|
|
||||||
</label>
|
|
||||||
</fieldset>
|
|
||||||
<hr>
|
|
||||||
<fieldset>
|
|
||||||
<label class="checkbox">
|
|
||||||
<input type="checkbox" id="useProxy" name="useProxy"@if(context.settings.pluginProxy.isDefined){ checked} />
|
|
||||||
Use proxy
|
|
||||||
</label>
|
|
||||||
</fieldset>
|
|
||||||
<div class="proxy">
|
|
||||||
<div class="form-group">
|
|
||||||
<label class="control-label col-md-2" for="proxyHost">Proxy host</label>
|
|
||||||
<div class="col-md-10">
|
|
||||||
<input type="text" id="proxyHost" name="proxy.host" class="form-control" value="@context.settings.pluginProxy.map(_.host)"/>
|
|
||||||
<span id="error-proxy_host" class="error"></span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="form-group">
|
|
||||||
<label class="control-label col-md-2" for="proxyPort">Proxy port</label>
|
|
||||||
<div class="col-md-10">
|
|
||||||
<input type="text" id="proxyPort" name="proxy.port" class="form-control input-mini" value="@context.settings.pluginProxy.map(_.port)"/>
|
|
||||||
<span id="error-proxy_port" class="error"></span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="form-group">
|
|
||||||
<label class="control-label col-md-2" for="proxyUser">Proxy user</label>
|
|
||||||
<div class="col-md-10">
|
|
||||||
<input type="text" id="proxyUser" name="proxy.user" class="form-control" value="@context.settings.pluginProxy.map(_.user)"/>
|
|
||||||
<span id="error-proxy_user" class="error"></span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="form-group">
|
|
||||||
<label class="control-label col-md-2" for="proxyPassword">Proxy password</label>
|
|
||||||
<div class="col-md-10">
|
|
||||||
<input type="password" id="proxyPassword" name="proxy.password" class="form-control" value="@context.settings.pluginProxy.map(_.password)"/>
|
|
||||||
<span id="error-proxy_password" class="error"></span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<script>
|
|
||||||
$(function(){
|
|
||||||
$('#useProxy').change(function(){
|
|
||||||
$('.proxy input').prop('disabled', !$(this).prop('checked'));
|
|
||||||
}).change();
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
@@ -17,7 +17,7 @@
|
|||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
@issues.map { case IssueInfo(issue, labels, milestone, priority, commentCount, commitStatus) =>
|
@issues.map { case IssueInfo(issue, labels, milestone, priority, commentCount, commitStatus) => {
|
||||||
<tr>
|
<tr>
|
||||||
<td style="padding-top: 12px; padding-bottom: 12px;">
|
<td style="padding-top: 12px; padding-bottom: 12px;">
|
||||||
<a href="@context.path/@issue.userName/@issue.repositoryName">@issue.userName/@issue.repositoryName</a> ・
|
<a href="@context.path/@issue.userName/@issue.repositoryName">@issue.userName/@issue.repositoryName</a> ・
|
||||||
@@ -52,7 +52,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
}
|
}}
|
||||||
@if(issues.isEmpty){
|
@if(issues.isEmpty){
|
||||||
<tr>
|
<tr>
|
||||||
<td style="padding: 20px; background-color: #eee; text-align: center;">
|
<td style="padding: 20px; background-color: #eee; text-align: center;">
|
||||||
|
|||||||
@@ -114,9 +114,9 @@
|
|||||||
@gitbucket.core.helper.html.datetimeago(comment.registeredDate)
|
@gitbucket.core.helper.html.datetimeago(comment.registeredDate)
|
||||||
</div>
|
</div>
|
||||||
<div style="discussion-item-content">
|
<div style="discussion-item-content">
|
||||||
@defining(comment.content.split(":")){ case Array(issueId, rest @ _*) =>
|
@defining(comment.content.split(":")){ case Array(issueId, rest @ _*) => {
|
||||||
@helpers.issueLink(repository, issueId.toInt, rest.mkString(":"))
|
@helpers.issueLink(repository, issueId.toInt, rest.mkString(":"))
|
||||||
}
|
}}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -65,6 +65,7 @@ $(function(){
|
|||||||
$('#edit').click(function(){
|
$('#edit').click(function(){
|
||||||
$('.edit-title').show();
|
$('.edit-title').show();
|
||||||
$('.show-title').hide();
|
$('.show-title').hide();
|
||||||
|
$('#edit-title').focus();
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -79,9 +80,9 @@ $(function(){
|
|||||||
}).done(function(data){
|
}).done(function(data){
|
||||||
$('#show-title').empty().text(data.title);
|
$('#show-title').empty().text(data.title);
|
||||||
$('#cancel').click();
|
$('#cancel').click();
|
||||||
$(this).removeAttr('disabled');
|
$('#update').removeAttr('disabled');
|
||||||
}).fail(function(req){
|
}).fail(function(req){
|
||||||
$(this).removeAttr('disabled');
|
$('#update').removeAttr('disabled');
|
||||||
$('#error-edit-title').text($.parseJSON(req.responseText).title);
|
$('#error-edit-title').text($.parseJSON(req.responseText).title);
|
||||||
});
|
});
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -56,9 +56,9 @@
|
|||||||
</div>
|
</div>
|
||||||
<span id="label-priority">
|
<span id="label-priority">
|
||||||
@issue.flatMap(_.priorityId).orElse(defaultPriority.map(_.priorityId)).map { priorityId =>
|
@issue.flatMap(_.priorityId).orElse(defaultPriority.map(_.priorityId)).map { priorityId =>
|
||||||
@priorities.collect { case priority if(priority.priorityId == priorityId) =>
|
@priorities.collect { case priority if(priority.priorityId == priorityId) => {
|
||||||
<a class="issue-priority" style="background-color: #@priority.color; color: #@priority.fontColor;" href="@helpers.url(repository)/issues?priority=@helpers.urlEncode(priority.priorityName)&state=open"@if(!priority.description.isEmpty) { title="@priority.description.get" }>@priority.priorityName</a>
|
<a class="issue-priority" style="background-color: #@priority.color; color: #@priority.fontColor;" href="@helpers.url(repository)/issues?priority=@helpers.urlEncode(priority.priorityName)&state=open"@if(!priority.description.isEmpty) { title="@priority.description.get" }>@priority.priorityName</a>
|
||||||
}
|
}}
|
||||||
}.getOrElse {
|
}.getOrElse {
|
||||||
<span class="muted small">No priority</span>
|
<span class="muted small">No priority</span>
|
||||||
}
|
}
|
||||||
@@ -102,16 +102,16 @@
|
|||||||
</div>
|
</div>
|
||||||
<div id="milestone-progress-area">
|
<div id="milestone-progress-area">
|
||||||
@issue.flatMap(_.milestoneId).map { milestoneId =>
|
@issue.flatMap(_.milestoneId).map { milestoneId =>
|
||||||
@milestones.collect { case (milestone, openCount, closeCount) if(milestone.milestoneId == milestoneId) =>
|
@milestones.collect { case (milestone, openCount, closeCount) if(milestone.milestoneId == milestoneId) => {
|
||||||
@gitbucket.core.issues.milestones.html.progress(openCount + closeCount, closeCount)
|
@gitbucket.core.issues.milestones.html.progress(openCount + closeCount, closeCount)
|
||||||
}
|
}}
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
<span id="label-milestone">
|
<span id="label-milestone">
|
||||||
@issue.flatMap(_.milestoneId).map { milestoneId =>
|
@issue.flatMap(_.milestoneId).map { milestoneId =>
|
||||||
@milestones.collect { case (milestone, _, _) if(milestone.milestoneId == milestoneId) =>
|
@milestones.collect { case (milestone, _, _) if(milestone.milestoneId == milestoneId) => {
|
||||||
<a class="strong small username" href="@helpers.url(repository)/issues?milestone=@helpers.urlEncode(milestone.title)&state=open">@milestone.title</a>
|
<a class="strong small username" href="@helpers.url(repository)/issues?milestone=@helpers.urlEncode(milestone.title)&state=open">@milestone.title</a>
|
||||||
}
|
}}
|
||||||
}.getOrElse {
|
}.getOrElse {
|
||||||
<span class="muted small">No milestone</span>
|
<span class="muted small">No milestone</span>
|
||||||
}
|
}
|
||||||
@@ -307,7 +307,7 @@ $(function(){
|
|||||||
$('#label-assigned').empty()
|
$('#label-assigned').empty()
|
||||||
.append($this.find('img.avatar-mini').clone(false)).append(' ')
|
.append($this.find('img.avatar-mini').clone(false)).append(' ')
|
||||||
.append($('<a class="username strong small">').attr('href', '@context.path/' + userName).text(userName));
|
.append($('<a class="username strong small">').attr('href', '@context.path/' + userName).text(userName));
|
||||||
$('a.assign[data-name=' + jqSelectorEscape(userName) + '] i').addClass('octicon-check');
|
$('a.assign[data-name=' + jqSelectorEscape(userName.toString()) + '] i').addClass('octicon-check');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -22,7 +22,7 @@
|
|||||||
<script>
|
<script>
|
||||||
$(function(){
|
$(function(){
|
||||||
$('#submit-@labelId').click(function(e){
|
$('#submit-@labelId').click(function(e){
|
||||||
$.post('@helpers.url(repository)/issues/labels/@{if(labelId == "new") "new" else labelId + "/edit"}', {
|
$.post('@helpers.url(repository)/issues/labels/@{if(labelId == "new") "new" else s"$labelId/edit"}', {
|
||||||
'labelName' : $('#labelName-@labelId').val(),
|
'labelName' : $('#labelName-@labelId').val(),
|
||||||
'labelColor': $('#labelColor-@labelId').val()
|
'labelColor': $('#labelColor-@labelId').val()
|
||||||
}, function(data, status){
|
}, function(data, status){
|
||||||
|
|||||||
@@ -206,7 +206,7 @@
|
|||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
}
|
}
|
||||||
@issues.map { case IssueInfo(issue, labels, milestone, priority, commentCount, commitStatus) =>
|
@issues.map { case IssueInfo(issue, labels, milestone, priority, commentCount, commitStatus) => {
|
||||||
<tr>
|
<tr>
|
||||||
<td style="padding-top: 12px; padding-bottom: 12px;">
|
<td style="padding-top: 12px; padding-bottom: 12px;">
|
||||||
@if(isManageable){
|
@if(isManageable){
|
||||||
@@ -253,7 +253,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
}
|
}}
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
<div class="pull-right">
|
<div class="pull-right">
|
||||||
|
|||||||
@@ -32,7 +32,7 @@
|
|||||||
<td style="padding-top: 15px; padding-bottom: 15px;">
|
<td style="padding-top: 15px; padding-bottom: 15px;">
|
||||||
<div class="milestone row">
|
<div class="milestone row">
|
||||||
<div class="col-md-4">
|
<div class="col-md-4">
|
||||||
<a href="@helpers.url(repository)/issues?milestone=@milestone.title&state=open" class="milestone-title">@milestone.title</a>
|
<a href="@helpers.url(repository)/issues?milestone=@helpers.urlEncode(milestone.title)&state=open" class="milestone-title">@milestone.title</a>
|
||||||
<div>
|
<div>
|
||||||
@if(milestone.closedDate.isDefined){
|
@if(milestone.closedDate.isDefined){
|
||||||
<span class="muted">Closed @gitbucket.core.helper.html.datetimeago(milestone.closedDate.get)</span>
|
<span class="muted">Closed @gitbucket.core.helper.html.datetimeago(milestone.closedDate.get)</span>
|
||||||
|
|||||||
@@ -23,7 +23,7 @@
|
|||||||
<script>
|
<script>
|
||||||
$(function(){
|
$(function(){
|
||||||
$('#submit-@priorityId').click(function(e){
|
$('#submit-@priorityId').click(function(e){
|
||||||
$.post('@helpers.url(repository)/issues/priorities/@{if(priorityId == "new") "new" else priorityId + "/edit"}', {
|
$.post('@helpers.url(repository)/issues/priorities/@{if(priorityId == "new") "new" else s"$priorityId/edit"}', {
|
||||||
'priorityName' : $('#priorityName-@priorityId').val(),
|
'priorityName' : $('#priorityName-@priorityId').val(),
|
||||||
'description' : $('#description-@priorityId').val(),
|
'description' : $('#description-@priorityId').val(),
|
||||||
'priorityColor': $('#priorityColor-@priorityId').val()
|
'priorityColor': $('#priorityColor-@priorityId').val()
|
||||||
|
|||||||
@@ -15,6 +15,7 @@
|
|||||||
collaborators: List[String],
|
collaborators: List[String],
|
||||||
milestones: List[gitbucket.core.model.Milestone],
|
milestones: List[gitbucket.core.model.Milestone],
|
||||||
priorities: List[gitbucket.core.model.Priority],
|
priorities: List[gitbucket.core.model.Priority],
|
||||||
|
defaultPriority: Option[gitbucket.core.model.Priority],
|
||||||
labels: List[gitbucket.core.model.Label])(implicit context: gitbucket.core.controller.Context)
|
labels: List[gitbucket.core.model.Label])(implicit context: gitbucket.core.controller.Context)
|
||||||
@import gitbucket.core.view.helpers
|
@import gitbucket.core.view.helpers
|
||||||
@gitbucket.core.html.main(s"Pull requests - ${repository.owner}/${repository.name}", Some(repository)){
|
@gitbucket.core.html.main(s"Pull requests - ${repository.owner}/${repository.name}", Some(repository)){
|
||||||
@@ -27,6 +28,9 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
@gitbucket.core.helper.html.dropdown(originId, "base", filter=("origin_branch", "Find Branch...")) {
|
@gitbucket.core.helper.html.dropdown(originId, "base", filter=("origin_branch", "Find Branch...")) {
|
||||||
|
@if(!originRepository.branchList.contains(originId)){
|
||||||
|
<li><a href="#" class="origin-branch" data-branch="@helpers.encodeRefName(originId)">@gitbucket.core.helper.html.checkicon(true) @originId</a></li>
|
||||||
|
}
|
||||||
@originRepository.branchList.map { branch =>
|
@originRepository.branchList.map { branch =>
|
||||||
<li><a href="#" class="origin-branch" data-branch="@helpers.encodeRefName(branch)">@gitbucket.core.helper.html.checkicon(branch == originId) @branch</a></li>
|
<li><a href="#" class="origin-branch" data-branch="@helpers.encodeRefName(branch)">@gitbucket.core.helper.html.checkicon(branch == originId) @branch</a></li>
|
||||||
}
|
}
|
||||||
@@ -38,16 +42,21 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
@gitbucket.core.helper.html.dropdown(forkedId, "compare", filter=("forked_branch", "Find Branch...")) {
|
@gitbucket.core.helper.html.dropdown(forkedId, "compare", filter=("forked_branch", "Find Branch...")) {
|
||||||
|
@if(!forkedRepository.branchList.contains(forkedId)){
|
||||||
|
<li><a href="#" class="origin-branch" data-branch="@helpers.encodeRefName(forkedId)">@gitbucket.core.helper.html.checkicon(true) @forkedId</a></li>
|
||||||
|
}
|
||||||
@forkedRepository.branchList.map { branch =>
|
@forkedRepository.branchList.map { branch =>
|
||||||
<li><a href="#" class="forked-branch" data-branch="@helpers.encodeRefName(branch)">@gitbucket.core.helper.html.checkicon(branch == forkedId) @branch</a></li>
|
<li><a href="#" class="forked-branch" data-branch="@helpers.encodeRefName(branch)">@gitbucket.core.helper.html.checkicon(branch == forkedId) @branch</a></li>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
<div class="check-conflict" style="display: none;">
|
@if(originRepository.branchList.contains(originId) && forkedRepository.branchList.contains(forkedId)){
|
||||||
<img src="@helpers.assets("/common/images/indicator.gif")"/> Checking...
|
<div class="check-conflict" style="display: none;">
|
||||||
</div>
|
<img src="@helpers.assets("/common/images/indicator.gif")"/> Checking...
|
||||||
|
</div>
|
||||||
|
}
|
||||||
</div>
|
</div>
|
||||||
@if(commits.nonEmpty && context.loginAccount.isDefined){
|
@if(commits.nonEmpty && context.loginAccount.isDefined && originRepository.branchList.contains(originId) && forkedRepository.branchList.contains(forkedId)){
|
||||||
<div style="margin-bottom: 10px; padding: 8px; background-color: #fff9ea" id="create-pull-request" class="box-content">
|
<div style="margin-bottom: 10px; padding: 8px; background-color: #fff9ea" id="create-pull-request" class="box-content">
|
||||||
<a href="#" class="btn btn-success" id="show-form">Create pull request</a>
|
<a href="#" class="btn btn-success" id="show-form">Create pull request</a>
|
||||||
|
|
||||||
@@ -70,19 +79,29 @@
|
|||||||
completionContext = "issues",
|
completionContext = "issues",
|
||||||
style = "height: 200px;"
|
style = "height: 200px;"
|
||||||
)
|
)
|
||||||
<input type="hidden" name="targetUserName" value="@originRepository.owner"/>
|
<div class="text-right">
|
||||||
<input type="hidden" name="targetBranch" value="@originId"/>
|
<input type="hidden" name="targetUserName" value="@originRepository.owner"/>
|
||||||
<input type="hidden" name="requestUserName" value="@forkedRepository.owner"/>
|
<input type="hidden" name="targetBranch" value="@originId"/>
|
||||||
<input type="hidden" name="requestRepositoryName" value="@forkedRepository.name"/>
|
<input type="hidden" name="requestUserName" value="@forkedRepository.owner"/>
|
||||||
<input type="hidden" name="requestBranch" value="@forkedId"/>
|
<input type="hidden" name="requestRepositoryName" value="@forkedRepository.name"/>
|
||||||
<input type="hidden" name="commitIdFrom" value="@sourceId"/>
|
<input type="hidden" name="requestBranch" value="@forkedId"/>
|
||||||
<input type="hidden" name="commitIdTo" value="@commitId"/>
|
<input type="hidden" name="commitIdFrom" value="@sourceId"/>
|
||||||
<div class="align-right">
|
<input type="hidden" name="commitIdTo" value="@commitId"/>
|
||||||
<input type="submit" class="btn btn-success" value="Create pull request"/>
|
<input type="hidden" id="is-draft" name="isDraft" value=false />
|
||||||
|
<div class="btn-group dropdown">
|
||||||
|
<input type="submit" class="btn btn-success" tabindex="2" value="Create pull request" id="submit-button" validate="true" formaction="@context.path/@originRepository.owner/@originRepository.name/pulls/new"/>
|
||||||
|
<button type="button" class="btn btn-success dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||||
|
<span class="caret"></span>
|
||||||
|
</button>
|
||||||
|
<ul class="dropdown-menu dropdown-menu-right">
|
||||||
|
<li><a id="pull-request">Create pull request</a></li>
|
||||||
|
<li><a id="draft-request">Create draft request</a></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-3">
|
<div class="col-md-3">
|
||||||
@gitbucket.core.issues.html.issueinfo(None, Nil, Nil, collaborators, milestones.map((_, 0, 0)), priorities, None, labels, hasOriginWritePermission, repository)
|
@gitbucket.core.issues.html.issueinfo(None, Nil, Nil, collaborators, milestones.map((_, 0, 0)), priorities, defaultPriority, labels, hasOriginWritePermission, repository)
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
@@ -93,16 +112,6 @@
|
|||||||
<h4>There isn't anything to compare.</h4>
|
<h4>There isn't anything to compare.</h4>
|
||||||
<span class="strong">@originRepository.owner:@originId</span> and <span class="strong">@forkedRepository.owner:@forkedId</span> are identical.
|
<span class="strong">@originRepository.owner:@originId</span> and <span class="strong">@forkedRepository.owner:@forkedId</span> are identical.
|
||||||
</div>
|
</div>
|
||||||
@*
|
|
||||||
<table class="table table-bordered table-hover table-issues">
|
|
||||||
<tr>
|
|
||||||
<td style="padding: 20px; background-color: #eee; text-align: center;">
|
|
||||||
<h4>There isn't anything to compare.</h4>
|
|
||||||
<span class="strong">@originRepository.owner:@originId</span> and <span class="strong">@forkedRepository.owner:@forkedId</span> are identical.
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
*@
|
|
||||||
} else {
|
} else {
|
||||||
<div style="margin-bottom: 10px; padding: 4px;" class="panel panel-default">
|
<div style="margin-bottom: 10px; padding: 4px;" class="panel panel-default">
|
||||||
<table class="fill-width">
|
<table class="fill-width">
|
||||||
@@ -146,14 +155,6 @@
|
|||||||
@helpers.user(commit.authorName, commit.authorEmailAddress, "username strong")
|
@helpers.user(commit.authorName, commit.authorEmailAddress, "username strong")
|
||||||
</td>
|
</td>
|
||||||
<td><span class="monospace">@commit.shortMessage</span></td>
|
<td><span class="monospace">@commit.shortMessage</span></td>
|
||||||
@*
|
|
||||||
<span class="badge" style="display: inline">@if(comments.isDefined){
|
|
||||||
@comments.get.flatMap @{
|
|
||||||
case comment: CommitComment => Some(comment)
|
|
||||||
case other => None
|
|
||||||
}.count(t => t.commitId == commit.id && !t.pullRequest)
|
|
||||||
}</span>
|
|
||||||
*@
|
|
||||||
<td style="width: 10%; text-align: right;">
|
<td style="width: 10%; text-align: right;">
|
||||||
<a href="@helpers.url(repository)/commit/@commit.id" class="monospace">@commit.id.substring(0, 7)</a>
|
<a href="@helpers.url(repository)/commit/@commit.id" class="monospace">@commit.id.substring(0, 7)</a>
|
||||||
</td>
|
</td>
|
||||||
@@ -163,12 +164,24 @@
|
|||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
@gitbucket.core.helper.html.diff(diffs, repository, Some(commitId), Some(sourceId), true, None, false, false)
|
@gitbucket.core.helper.html.diff(diffs, repository, Some(commitId), Some(sourceId), true, None, false, false)
|
||||||
<p>Showing you all comments on commits in this comparison.</p>
|
|
||||||
@gitbucket.core.issues.html.commentlist(None, comments, false, repository, None)
|
@gitbucket.core.issues.html.commentlist(None, comments, false, repository, None)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
<script>
|
<script>
|
||||||
|
|
||||||
|
$(function(){
|
||||||
|
$('#draft-request').click(function(){
|
||||||
|
$("#is-draft").val(true);
|
||||||
|
$('#submit-button').attr('value', 'Create draft request')
|
||||||
|
});
|
||||||
|
$('#pull-request').click(function(){
|
||||||
|
$("#is-draft").val(false);
|
||||||
|
$('#submit-button').attr('value', 'Create pull request')
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
$(function(){
|
$(function(){
|
||||||
function updateSelector(e){
|
function updateSelector(e){
|
||||||
e.parents('ul').find('i').attr('class', 'octicon');
|
e.parents('ul').find('i').attr('class', 'octicon');
|
||||||
@@ -220,7 +233,7 @@ $(function(){
|
|||||||
$('#show-form').click();
|
$('#show-form').click();
|
||||||
}
|
}
|
||||||
|
|
||||||
@if(context.loginAccount.isDefined){
|
@if(context.loginAccount.isDefined && originRepository.branchList.contains(originId) && forkedRepository.branchList.contains(forkedId)){
|
||||||
function checkConflict(from, to){
|
function checkConflict(from, to){
|
||||||
$('.check-conflict').show();
|
$('.check-conflict').show();
|
||||||
$.get('@helpers.url(forkedRepository)/compare/' + from + '...' + to + '/mergecheck',
|
$.get('@helpers.url(forkedRepository)/compare/' + from + '...' + to + '/mergecheck',
|
||||||
|
|||||||
@@ -91,6 +91,7 @@
|
|||||||
$('#edit').click(function(){
|
$('#edit').click(function(){
|
||||||
$('.edit-title').show();
|
$('.edit-title').show();
|
||||||
$('.show-title').hide();
|
$('.show-title').hide();
|
||||||
|
$('#edit-title').focus();
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -76,6 +76,16 @@
|
|||||||
</div>
|
</div>
|
||||||
} else {
|
} else {
|
||||||
<div class="merge-indicator merge-indicator-success"><span class="octicon octicon-check"></span></div>
|
<div class="merge-indicator merge-indicator-success"><span class="octicon octicon-check"></span></div>
|
||||||
|
|
||||||
|
@if(pullreq.isDraft){
|
||||||
|
<span class="strong">This pull request is still a work in progress.</span>
|
||||||
|
<div class="pull-right">
|
||||||
|
<input type="button" class="btn btn-default" value="Ready for review" id="ready-for-review" />
|
||||||
|
</div>
|
||||||
|
<div class="small">
|
||||||
|
Draft pull requests cannot be merged.
|
||||||
|
</div>
|
||||||
|
} else {
|
||||||
@if(status.hasMergePermission){
|
@if(status.hasMergePermission){
|
||||||
<span class="strong">Merging can be performed automatically.</span>
|
<span class="strong">Merging can be performed automatically.</span>
|
||||||
<div class="small">
|
<div class="small">
|
||||||
@@ -87,13 +97,14 @@
|
|||||||
Only those with write access to this repository can merge pull requests.
|
Only those with write access to this repository can merge pull requests.
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
@if(status.hasMergePermission){
|
@if(status.hasMergePermission){
|
||||||
<div style="padding:15px; border-top:solid 1px #e5e5e5; background:#fafafa">
|
<div style="padding:15px; border-top:solid 1px #e5e5e5; background:#fafafa">
|
||||||
<input type="button" class="btn @if(!status.hasProblem){btn-success} else {btn-default}" id="merge-pull-request-button" value="Merge pull request"@if(!status.canMerge){ disabled="true"}/>
|
<input type="button" class="btn @if(!status.hasProblem){btn-success} else {btn-default}" id="merge-pull-request-button" value="Merge pull request"@if(!status.canMerge || pullreq.isDraft){ disabled="true"}/>
|
||||||
You can also merge branches on the <a href="#" class="show-command-line">command line</a>.
|
You can also merge branches on the <a href="#" class="show-command-line">command line</a>.
|
||||||
<div id="command-line" style="display: none;margin-top: 15px;">
|
<div id="command-line" style="display: none;margin-top: 15px;">
|
||||||
<hr />
|
<hr />
|
||||||
@@ -191,6 +202,7 @@
|
|||||||
<input type="button" class="btn btn-default" value="Cancel" id="cancel-merge-pull-request"/>
|
<input type="button" class="btn btn-default" value="Cancel" id="cancel-merge-pull-request"/>
|
||||||
<input type="submit" class="btn btn-success" value="Confirm merge"/>
|
<input type="submit" class="btn btn-success" value="Confirm merge"/>
|
||||||
<input type="hidden" name="strategy" value="@originRepository.repository.options.defaultMergeOption"/>
|
<input type="hidden" name="strategy" value="@originRepository.repository.options.defaultMergeOption"/>
|
||||||
|
<input type="hidden" name="isDraft" value="@pullreq.isDraft" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
@@ -199,6 +211,15 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
|
||||||
|
$(function(){
|
||||||
|
$('#ready-for-review').click(function(){
|
||||||
|
$.post('@helpers.url(originRepository)/pull/@issue.issueId/update_draft', function(data, status){
|
||||||
|
location.reload();
|
||||||
|
})
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
$(function(){
|
$(function(){
|
||||||
$('.show-command-line').click(function(){
|
$('.show-command-line').click(function(){
|
||||||
$('#command-line').toggle();
|
$('#command-line').toggle();
|
||||||
|
|||||||
@@ -30,10 +30,10 @@ class GitBucketCoreModuleSpec extends FunSuite {
|
|||||||
override val container = new org.testcontainers.containers.MySQLContainer(s"mysql:$tag") {
|
override val container = new org.testcontainers.containers.MySQLContainer(s"mysql:$tag") {
|
||||||
override def getDriverClassName = "org.mariadb.jdbc.Driver"
|
override def getDriverClassName = "org.mariadb.jdbc.Driver"
|
||||||
}
|
}
|
||||||
// TODO https://github.com/testcontainers/testcontainers-java/issues/736
|
// TODO https://jira.mariadb.org/browse/CONJ-663
|
||||||
container.withCommand("mysqld --default-authentication-plugin=mysql_native_password")
|
container.withCommand("mysqld --default-authentication-plugin=mysql_native_password")
|
||||||
}
|
}
|
||||||
container.starting()
|
container.start()
|
||||||
try {
|
try {
|
||||||
new Solidbase().migrate(
|
new Solidbase().migrate(
|
||||||
DriverManager.getConnection(s"${container.jdbcUrl}?useSSL=false", container.username, container.password),
|
DriverManager.getConnection(s"${container.jdbcUrl}?useSSL=false", container.username, container.password),
|
||||||
@@ -42,7 +42,7 @@ class GitBucketCoreModuleSpec extends FunSuite {
|
|||||||
new Module(GitBucketCoreModule.getModuleId, GitBucketCoreModule.getVersions)
|
new Module(GitBucketCoreModule.getModuleId, GitBucketCoreModule.getVersions)
|
||||||
)
|
)
|
||||||
} finally {
|
} finally {
|
||||||
container.finished()
|
container.stop()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -51,7 +51,7 @@ class GitBucketCoreModuleSpec extends FunSuite {
|
|||||||
test(s"Migration PostgreSQL $tag", ExternalDBTest) {
|
test(s"Migration PostgreSQL $tag", ExternalDBTest) {
|
||||||
val container = PostgreSQLContainer(s"postgres:$tag")
|
val container = PostgreSQLContainer(s"postgres:$tag")
|
||||||
|
|
||||||
container.starting()
|
container.start()
|
||||||
try {
|
try {
|
||||||
new Solidbase().migrate(
|
new Solidbase().migrate(
|
||||||
DriverManager.getConnection(container.jdbcUrl, container.username, container.password),
|
DriverManager.getConnection(container.jdbcUrl, container.username, container.password),
|
||||||
@@ -60,7 +60,7 @@ class GitBucketCoreModuleSpec extends FunSuite {
|
|||||||
new Module(GitBucketCoreModule.getModuleId, GitBucketCoreModule.getVersions)
|
new Module(GitBucketCoreModule.getModuleId, GitBucketCoreModule.getVersions)
|
||||||
)
|
)
|
||||||
} finally {
|
} finally {
|
||||||
container.finished()
|
container.stop()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -139,7 +139,8 @@ object ApiSpecModels {
|
|||||||
requestRepositoryName = repo1Name.name,
|
requestRepositoryName = repo1Name.name,
|
||||||
requestBranch = "new-topic",
|
requestBranch = "new-topic",
|
||||||
commitIdFrom = sha1,
|
commitIdFrom = sha1,
|
||||||
commitIdTo = sha1
|
commitIdTo = sha1,
|
||||||
|
isDraft = true
|
||||||
)
|
)
|
||||||
|
|
||||||
val commitComment = CommitComment(
|
val commitComment = CommitComment(
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
package gitbucket.core.service
|
package gitbucket.core.service
|
||||||
|
|
||||||
import gitbucket.core.util.Directory._
|
import gitbucket.core.util.Directory._
|
||||||
import gitbucket.core.util.SyntaxSugars._
|
|
||||||
import gitbucket.core.util.GitSpecUtil._
|
import gitbucket.core.util.GitSpecUtil._
|
||||||
|
|
||||||
import org.eclipse.jgit.api.Git
|
import org.eclipse.jgit.api.Git
|
||||||
@@ -10,6 +9,7 @@ import org.eclipse.jgit.revwalk._
|
|||||||
import org.scalatest.FunSpec
|
import org.scalatest.FunSpec
|
||||||
|
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
import scala.util.Using
|
||||||
|
|
||||||
class MergeServiceSpec extends FunSpec {
|
class MergeServiceSpec extends FunSpec {
|
||||||
val service = new MergeService with AccountService with ActivityService with IssuesService with LabelsService
|
val service = new MergeService with AccountService with ActivityService with IssuesService with LabelsService
|
||||||
@@ -19,7 +19,7 @@ class MergeServiceSpec extends FunSpec {
|
|||||||
val issueId = 10
|
val issueId = 10
|
||||||
def initRepository(owner: String, name: String): File = {
|
def initRepository(owner: String, name: String): File = {
|
||||||
val dir = createTestRepository(getRepositoryDir(owner, name))
|
val dir = createTestRepository(getRepositoryDir(owner, name))
|
||||||
using(Git.open(dir)) { git =>
|
Using.resource(Git.open(dir)) { git =>
|
||||||
createFile(git, "refs/heads/master", "test.txt", "hoge")
|
createFile(git, "refs/heads/master", "test.txt", "hoge")
|
||||||
git.branchCreate().setStartPoint(s"refs/heads/master").setName(s"refs/pull/${issueId}/head").call()
|
git.branchCreate().setStartPoint(s"refs/heads/master").setName(s"refs/pull/${issueId}/head").call()
|
||||||
}
|
}
|
||||||
@@ -39,7 +39,7 @@ class MergeServiceSpec extends FunSpec {
|
|||||||
}
|
}
|
||||||
it("checkConflict true if not conflicted, and create cache") {
|
it("checkConflict true if not conflicted, and create cache") {
|
||||||
val repo2Dir = initRepository("user1", "repo2")
|
val repo2Dir = initRepository("user1", "repo2")
|
||||||
using(Git.open(repo2Dir)) { git =>
|
Using.resource(Git.open(repo2Dir)) { git =>
|
||||||
createConfrict(git)
|
createConfrict(git)
|
||||||
}
|
}
|
||||||
assert(service.checkConflictCache("user1", "repo2", branch, issueId) == None)
|
assert(service.checkConflictCache("user1", "repo2", branch, issueId) == None)
|
||||||
@@ -56,7 +56,7 @@ class MergeServiceSpec extends FunSpec {
|
|||||||
val repo3Dir = initRepository("user1", "repo3")
|
val repo3Dir = initRepository("user1", "repo3")
|
||||||
assert(service.checkConflict("user1", "repo3", branch, issueId).isEmpty)
|
assert(service.checkConflict("user1", "repo3", branch, issueId).isEmpty)
|
||||||
assert(service.checkConflictCache("user1", "repo3", branch, issueId) == Some(None))
|
assert(service.checkConflictCache("user1", "repo3", branch, issueId) == Some(None))
|
||||||
using(Git.open(repo3Dir)) { git =>
|
Using.resource(Git.open(repo3Dir)) { git =>
|
||||||
createFile(git, s"refs/heads/${branch}", "test.txt", "hoge2")
|
createFile(git, s"refs/heads/${branch}", "test.txt", "hoge2")
|
||||||
}
|
}
|
||||||
assert(service.checkConflictCache("user1", "repo3", branch, issueId) == None)
|
assert(service.checkConflictCache("user1", "repo3", branch, issueId) == None)
|
||||||
@@ -65,7 +65,7 @@ class MergeServiceSpec extends FunSpec {
|
|||||||
val repo4Dir = initRepository("user1", "repo4")
|
val repo4Dir = initRepository("user1", "repo4")
|
||||||
assert(service.checkConflict("user1", "repo4", branch, issueId).isEmpty)
|
assert(service.checkConflict("user1", "repo4", branch, issueId).isEmpty)
|
||||||
assert(service.checkConflictCache("user1", "repo4", branch, issueId) == Some(None))
|
assert(service.checkConflictCache("user1", "repo4", branch, issueId) == Some(None))
|
||||||
using(Git.open(repo4Dir)) { git =>
|
Using.resource(Git.open(repo4Dir)) { git =>
|
||||||
createFile(git, s"refs/pull/${issueId}/head", "test.txt", "hoge4")
|
createFile(git, s"refs/pull/${issueId}/head", "test.txt", "hoge4")
|
||||||
}
|
}
|
||||||
assert(service.checkConflictCache("user1", "repo4", branch, issueId) == None)
|
assert(service.checkConflictCache("user1", "repo4", branch, issueId) == None)
|
||||||
@@ -74,14 +74,14 @@ class MergeServiceSpec extends FunSpec {
|
|||||||
val repo5Dir = initRepository("user1", "repo5")
|
val repo5Dir = initRepository("user1", "repo5")
|
||||||
assert(service.checkConflict("user1", "repo5", branch, issueId).isEmpty)
|
assert(service.checkConflict("user1", "repo5", branch, issueId).isEmpty)
|
||||||
assert(service.checkConflictCache("user1", "repo5", branch, issueId) == Some(None))
|
assert(service.checkConflictCache("user1", "repo5", branch, issueId) == Some(None))
|
||||||
using(Git.open(repo5Dir)) { git =>
|
Using.resource(Git.open(repo5Dir)) { git =>
|
||||||
createFile(git, s"refs/heads/${branch}", "test.txt", "hoge2")
|
createFile(git, s"refs/heads/${branch}", "test.txt", "hoge2")
|
||||||
}
|
}
|
||||||
assert(service.checkConflictCache("user1", "repo5", branch, issueId) == None)
|
assert(service.checkConflictCache("user1", "repo5", branch, issueId) == None)
|
||||||
}
|
}
|
||||||
it("conflicted cache invalid if request branch moved") {
|
it("conflicted cache invalid if request branch moved") {
|
||||||
val repo6Dir = initRepository("user1", "repo6")
|
val repo6Dir = initRepository("user1", "repo6")
|
||||||
using(Git.open(repo6Dir)) { git =>
|
Using.resource(Git.open(repo6Dir)) { git =>
|
||||||
createConfrict(git)
|
createConfrict(git)
|
||||||
}
|
}
|
||||||
assert(service.checkConflict("user1", "repo6", branch, issueId).isDefined)
|
assert(service.checkConflict("user1", "repo6", branch, issueId).isDefined)
|
||||||
@@ -89,14 +89,14 @@ class MergeServiceSpec extends FunSpec {
|
|||||||
case Some(Some(_: String)) => true
|
case Some(Some(_: String)) => true
|
||||||
case _ => false
|
case _ => false
|
||||||
})
|
})
|
||||||
using(Git.open(repo6Dir)) { git =>
|
Using.resource(Git.open(repo6Dir)) { git =>
|
||||||
createFile(git, s"refs/pull/${issueId}/head", "test.txt", "hoge4")
|
createFile(git, s"refs/pull/${issueId}/head", "test.txt", "hoge4")
|
||||||
}
|
}
|
||||||
assert(service.checkConflictCache("user1", "repo6", branch, issueId) == None)
|
assert(service.checkConflictCache("user1", "repo6", branch, issueId) == None)
|
||||||
}
|
}
|
||||||
it("conflicted cache invalid if origin branch moved") {
|
it("conflicted cache invalid if origin branch moved") {
|
||||||
val repo7Dir = initRepository("user1", "repo7")
|
val repo7Dir = initRepository("user1", "repo7")
|
||||||
using(Git.open(repo7Dir)) { git =>
|
Using.resource(Git.open(repo7Dir)) { git =>
|
||||||
createConfrict(git)
|
createConfrict(git)
|
||||||
}
|
}
|
||||||
assert(service.checkConflict("user1", "repo7", branch, issueId).isDefined)
|
assert(service.checkConflict("user1", "repo7", branch, issueId).isDefined)
|
||||||
@@ -104,7 +104,7 @@ class MergeServiceSpec extends FunSpec {
|
|||||||
case Some(Some(_)) => true
|
case Some(Some(_)) => true
|
||||||
case _ => false
|
case _ => false
|
||||||
})
|
})
|
||||||
using(Git.open(repo7Dir)) { git =>
|
Using.resource(Git.open(repo7Dir)) { git =>
|
||||||
createFile(git, s"refs/heads/${branch}", "test.txt", "hoge4")
|
createFile(git, s"refs/heads/${branch}", "test.txt", "hoge4")
|
||||||
}
|
}
|
||||||
assert(service.checkConflictCache("user1", "repo7", branch, issueId) == None)
|
assert(service.checkConflictCache("user1", "repo7", branch, issueId) == None)
|
||||||
@@ -113,7 +113,7 @@ class MergeServiceSpec extends FunSpec {
|
|||||||
describe("mergePullRequest") {
|
describe("mergePullRequest") {
|
||||||
it("can merge") {
|
it("can merge") {
|
||||||
val repo8Dir = initRepository("user1", "repo8")
|
val repo8Dir = initRepository("user1", "repo8")
|
||||||
using(Git.open(repo8Dir)) { git =>
|
Using.resource(Git.open(repo8Dir)) { git =>
|
||||||
createFile(git, s"refs/pull/${issueId}/head", "test.txt", "hoge2")
|
createFile(git, s"refs/pull/${issueId}/head", "test.txt", "hoge2")
|
||||||
val committer = new PersonIdent("dummy2", "dummy2@example.com")
|
val committer = new PersonIdent("dummy2", "dummy2@example.com")
|
||||||
assert(getFile(git, branch, "test.txt").content.get == "hoge")
|
assert(getFile(git, branch, "test.txt").content.get == "hoge")
|
||||||
@@ -121,7 +121,7 @@ class MergeServiceSpec extends FunSpec {
|
|||||||
val masterId = git.getRepository.resolve(branch)
|
val masterId = git.getRepository.resolve(branch)
|
||||||
service.mergePullRequest(git, branch, issueId, "merged", committer)
|
service.mergePullRequest(git, branch, issueId, "merged", committer)
|
||||||
val lastCommitId = git.getRepository.resolve(branch)
|
val lastCommitId = git.getRepository.resolve(branch)
|
||||||
val commit = using(new RevWalk(git.getRepository))(_.parseCommit(lastCommitId))
|
val commit = Using.resource(new RevWalk(git.getRepository))(_.parseCommit(lastCommitId))
|
||||||
assert(commit.getCommitterIdent() == committer)
|
assert(commit.getCommitterIdent() == committer)
|
||||||
assert(commit.getAuthorIdent() == committer)
|
assert(commit.getAuthorIdent() == committer)
|
||||||
assert(commit.getFullMessage() == "merged")
|
assert(commit.getFullMessage() == "merged")
|
||||||
|
|||||||
@@ -2,13 +2,10 @@ package gitbucket.core.service
|
|||||||
|
|
||||||
import gitbucket.core.GitBucketCoreModule
|
import gitbucket.core.GitBucketCoreModule
|
||||||
import gitbucket.core.util.{DatabaseConfig, Directory, FileUtil, JGitUtil}
|
import gitbucket.core.util.{DatabaseConfig, Directory, FileUtil, JGitUtil}
|
||||||
import gitbucket.core.util.SyntaxSugars._
|
|
||||||
import io.github.gitbucket.solidbase.Solidbase
|
import io.github.gitbucket.solidbase.Solidbase
|
||||||
import liquibase.database.core.H2Database
|
import liquibase.database.core.H2Database
|
||||||
import liquibase.database.jvm.JdbcConnection
|
import liquibase.database.jvm.JdbcConnection
|
||||||
import gitbucket.core.model._
|
import gitbucket.core.model._
|
||||||
import gitbucket.core.model.Profile._
|
|
||||||
import gitbucket.core.model.Profile.profile._
|
|
||||||
import gitbucket.core.model.Profile.profile.blockingApi._
|
import gitbucket.core.model.Profile.profile.blockingApi._
|
||||||
import org.apache.commons.io.FileUtils
|
import org.apache.commons.io.FileUtils
|
||||||
import java.sql.DriverManager
|
import java.sql.DriverManager
|
||||||
@@ -17,10 +14,11 @@ import java.io.File
|
|||||||
import gitbucket.core.controller.Context
|
import gitbucket.core.controller.Context
|
||||||
import gitbucket.core.service.SystemSettingsService.{Ssh, SystemSettings}
|
import gitbucket.core.service.SystemSettingsService.{Ssh, SystemSettings}
|
||||||
import javax.servlet.http.{HttpServletRequest, HttpSession}
|
import javax.servlet.http.{HttpServletRequest, HttpSession}
|
||||||
import org.scalatest.mockito.MockitoSugar
|
import org.scalatestplus.mockito.MockitoSugar
|
||||||
import org.mockito.Mockito._
|
import org.mockito.Mockito._
|
||||||
|
|
||||||
import scala.util.Random
|
import scala.util.Random
|
||||||
|
import scala.util.Using
|
||||||
|
|
||||||
trait ServiceSpecBase extends MockitoSugar {
|
trait ServiceSpecBase extends MockitoSugar {
|
||||||
|
|
||||||
@@ -53,16 +51,14 @@ trait ServiceSpecBase extends MockitoSugar {
|
|||||||
oidcAuthentication = false,
|
oidcAuthentication = false,
|
||||||
oidc = None,
|
oidc = None,
|
||||||
skinName = "skin-blue",
|
skinName = "skin-blue",
|
||||||
showMailAddress = false,
|
showMailAddress = false
|
||||||
pluginNetworkInstall = false,
|
|
||||||
pluginProxy = None
|
|
||||||
)
|
)
|
||||||
|
|
||||||
def withTestDB[A](action: (Session) => A): A = {
|
def withTestDB[A](action: (Session) => A): A = {
|
||||||
FileUtil.withTmpDir(new File(FileUtils.getTempDirectory(), Random.alphanumeric.take(10).mkString)) { dir =>
|
FileUtil.withTmpDir(new File(FileUtils.getTempDirectory(), Random.alphanumeric.take(10).mkString)) { dir =>
|
||||||
val (url, user, pass) = (DatabaseConfig.url(Some(dir.toString)), DatabaseConfig.user, DatabaseConfig.password)
|
val (url, user, pass) = (DatabaseConfig.url(Some(dir.toString)), DatabaseConfig.user, DatabaseConfig.password)
|
||||||
org.h2.Driver.load()
|
org.h2.Driver.load()
|
||||||
using(DriverManager.getConnection(url, user, pass)) { conn =>
|
Using.resource(DriverManager.getConnection(url, user, pass)) { conn =>
|
||||||
val solidbase = new Solidbase()
|
val solidbase = new Solidbase()
|
||||||
val db = new H2Database()
|
val db = new H2Database()
|
||||||
db.setConnection(new JdbcConnection(conn)) // TODO Remove setConnection in the future
|
db.setConnection(new JdbcConnection(conn)) // TODO Remove setConnection in the future
|
||||||
@@ -140,6 +136,7 @@ trait ServiceSpecBase extends MockitoSugar {
|
|||||||
requestBranch = requestBranch,
|
requestBranch = requestBranch,
|
||||||
commitIdFrom = baesBranch,
|
commitIdFrom = baesBranch,
|
||||||
commitIdTo = requestBranch,
|
commitIdTo = requestBranch,
|
||||||
|
isDraft = false,
|
||||||
loginAccount = loginAccount.get
|
loginAccount = loginAccount.get
|
||||||
)
|
)
|
||||||
dummyService.getPullRequest(baseUserName, baseRepositoryName, issueId).get
|
dummyService.getPullRequest(baseUserName, baseRepositoryName, issueId).get
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ class WebHookServiceSpec extends FunSuite with ServiceSpecBase {
|
|||||||
|
|
||||||
assert(service.getPullRequestsByRequestForWebhook("user1", "repo1", "master1") == Map.empty)
|
assert(service.getPullRequestsByRequestForWebhook("user1", "repo1", "master1") == Map.empty)
|
||||||
|
|
||||||
val r = service.getPullRequestsByRequestForWebhook("user2", "repo2", "master2").mapValues(_.map(_.url).toSet)
|
val r = service.getPullRequestsByRequestForWebhook("user2", "repo2", "master2").view.mapValues(_.map(_.url).toSet)
|
||||||
|
|
||||||
assert(r.size == 3)
|
assert(r.size == 3)
|
||||||
assert(r((issue1, issueUser, pullreq1, user1, user2)) == Set("webhook1-1", "webhook1-2"))
|
assert(r((issue1, issueUser, pullreq1, user1, user2)) == Set("webhook1-1", "webhook1-2"))
|
||||||
@@ -39,7 +39,8 @@ class WebHookServiceSpec extends FunSuite with ServiceSpecBase {
|
|||||||
// when closed, it not founds.
|
// when closed, it not founds.
|
||||||
service.updateClosed("user1", "repo1", issue1.issueId, true)
|
service.updateClosed("user1", "repo1", issue1.issueId, true)
|
||||||
|
|
||||||
val r2 = service.getPullRequestsByRequestForWebhook("user2", "repo2", "master2").mapValues(_.map(_.url).toSet)
|
val r2 =
|
||||||
|
service.getPullRequestsByRequestForWebhook("user2", "repo2", "master2").view.mapValues(_.map(_.url).toSet)
|
||||||
assert(r2.size == 2)
|
assert(r2.size == 2)
|
||||||
assert(r2((issue3, issueUser, pullreq3, user3, user2)) == Set("webhook3-1", "webhook3-2"))
|
assert(r2((issue3, issueUser, pullreq3, user3, user2)) == Set("webhook3-1", "webhook3-2"))
|
||||||
assert(r2((issue32, issueUser, pullreq32, user3, user2)) == Set("webhook3-1", "webhook3-2"))
|
assert(r2((issue32, issueUser, pullreq32, user3, user2)) == Set("webhook3-1", "webhook3-2"))
|
||||||
|
|||||||
@@ -1,7 +1,5 @@
|
|||||||
package gitbucket.core.util
|
package gitbucket.core.util
|
||||||
|
|
||||||
import gitbucket.core.util.SyntaxSugars._
|
|
||||||
|
|
||||||
import org.apache.commons.io.FileUtils
|
import org.apache.commons.io.FileUtils
|
||||||
import org.eclipse.jgit.api.Git
|
import org.eclipse.jgit.api.Git
|
||||||
import org.eclipse.jgit.dircache.DirCache
|
import org.eclipse.jgit.dircache.DirCache
|
||||||
@@ -13,6 +11,7 @@ import org.eclipse.jgit.errors._
|
|||||||
|
|
||||||
import java.nio.file._
|
import java.nio.file._
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
import scala.util.Using
|
||||||
|
|
||||||
object GitSpecUtil {
|
object GitSpecUtil {
|
||||||
|
|
||||||
@@ -28,7 +27,8 @@ object GitSpecUtil {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
def withTestRepository[U](f: Git => U): U = withTestFolder(folder => using(Git.open(createTestRepository(folder)))(f))
|
def withTestRepository[U](f: Git => U): U =
|
||||||
|
withTestFolder(folder => Using.resource(Git.open(createTestRepository(folder)))(f))
|
||||||
|
|
||||||
def createTestRepository(dir: File): File = {
|
def createTestRepository(dir: File): File = {
|
||||||
RepositoryCache.clear()
|
RepositoryCache.clear()
|
||||||
@@ -81,7 +81,7 @@ object GitSpecUtil {
|
|||||||
|
|
||||||
def getFile(git: Git, branch: String, path: String) = {
|
def getFile(git: Git, branch: String, path: String) = {
|
||||||
val revCommit = JGitUtil.getRevCommitFromId(git, git.getRepository.resolve(branch))
|
val revCommit = JGitUtil.getRevCommitFromId(git, git.getRepository.resolve(branch))
|
||||||
val objectId = using(new TreeWalk(git.getRepository)) { walk =>
|
val objectId = Using.resource(new TreeWalk(git.getRepository)) { walk =>
|
||||||
walk.addTree(revCommit.getTree)
|
walk.addTree(revCommit.getTree)
|
||||||
walk.setRecursive(true)
|
walk.setRecursive(true)
|
||||||
@scala.annotation.tailrec
|
@scala.annotation.tailrec
|
||||||
@@ -108,7 +108,7 @@ object GitSpecUtil {
|
|||||||
if (conflicted) {
|
if (conflicted) {
|
||||||
throw new RuntimeException("conflict!")
|
throw new RuntimeException("conflict!")
|
||||||
}
|
}
|
||||||
val mergeTipCommit = using(new RevWalk(repository))(_.parseCommit(mergeTip))
|
val mergeTipCommit = Using.resource(new RevWalk(repository))(_.parseCommit(mergeTip))
|
||||||
val committer = mergeTipCommit.getCommitterIdent
|
val committer = mergeTipCommit.getCommitterIdent
|
||||||
// creates merge commit
|
// creates merge commit
|
||||||
val mergeCommit = new CommitBuilder()
|
val mergeCommit = new CommitBuilder()
|
||||||
|
|||||||
@@ -1,15 +1,12 @@
|
|||||||
package gitbucket.core.util
|
package gitbucket.core.util
|
||||||
|
|
||||||
import GitSpecUtil._
|
import GitSpecUtil._
|
||||||
import gitbucket.core.util.SyntaxSugars.using
|
|
||||||
import org.apache.commons.io.IOUtils
|
import org.apache.commons.io.IOUtils
|
||||||
import org.eclipse.jgit.diff.DiffEntry
|
|
||||||
import org.eclipse.jgit.diff.DiffEntry.ChangeType
|
import org.eclipse.jgit.diff.DiffEntry.ChangeType
|
||||||
import org.eclipse.jgit.lib.Constants
|
import org.eclipse.jgit.lib.Constants
|
||||||
import org.eclipse.jgit.treewalk.TreeWalk
|
|
||||||
import org.scalatest.FunSuite
|
import org.scalatest.FunSuite
|
||||||
|
|
||||||
import scala.collection.JavaConverters._
|
import scala.jdk.CollectionConverters._
|
||||||
|
|
||||||
class JGitUtilSpec extends FunSuite {
|
class JGitUtilSpec extends FunSuite {
|
||||||
|
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import gitbucket.core.service.RequestCache
|
|||||||
import gitbucket.core.service.SystemSettingsService.{Ssh, SystemSettings}
|
import gitbucket.core.service.SystemSettingsService.{Ssh, SystemSettings}
|
||||||
import org.mockito.Mockito._
|
import org.mockito.Mockito._
|
||||||
import org.scalatest.FunSpec
|
import org.scalatest.FunSpec
|
||||||
import org.scalatest.mockito.MockitoSugar
|
import org.scalatestplus.mockito.MockitoSugar
|
||||||
import play.twirl.api.Html
|
import play.twirl.api.Html
|
||||||
|
|
||||||
class AvatarImageProviderSpec extends FunSpec with MockitoSugar {
|
class AvatarImageProviderSpec extends FunSpec with MockitoSugar {
|
||||||
@@ -137,9 +137,7 @@ class AvatarImageProviderSpec extends FunSpec with MockitoSugar {
|
|||||||
oidcAuthentication = false,
|
oidcAuthentication = false,
|
||||||
oidc = None,
|
oidc = None,
|
||||||
skinName = "skin-blue",
|
skinName = "skin-blue",
|
||||||
showMailAddress = false,
|
showMailAddress = false
|
||||||
pluginNetworkInstall = false,
|
|
||||||
pluginProxy = None
|
|
||||||
)
|
)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ package gitbucket.core.view
|
|||||||
import gitbucket.core.controller.Context
|
import gitbucket.core.controller.Context
|
||||||
import gitbucket.core.service.RepositoryService.RepositoryInfo
|
import gitbucket.core.service.RepositoryService.RepositoryInfo
|
||||||
import org.scalatest.FunSpec
|
import org.scalatest.FunSpec
|
||||||
import org.scalatest.mockito.MockitoSugar
|
import org.scalatestplus.mockito.MockitoSugar
|
||||||
import java.util.Date
|
import java.util.Date
|
||||||
import java.util.TimeZone
|
import java.util.TimeZone
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ package gitbucket.core.view
|
|||||||
import gitbucket.core.controller.Context
|
import gitbucket.core.controller.Context
|
||||||
import gitbucket.core.service.RepositoryService.RepositoryInfo
|
import gitbucket.core.service.RepositoryService.RepositoryInfo
|
||||||
import org.scalatest.FunSpec
|
import org.scalatest.FunSpec
|
||||||
import org.scalatest.mockito.MockitoSugar
|
import org.scalatestplus.mockito.MockitoSugar
|
||||||
import org.mockito.Mockito._
|
import org.mockito.Mockito._
|
||||||
|
|
||||||
class MarkdownSpec extends FunSpec with MockitoSugar {
|
class MarkdownSpec extends FunSpec with MockitoSugar {
|
||||||
@@ -154,7 +154,7 @@ tasks
|
|||||||
)(context)
|
)(context)
|
||||||
|
|
||||||
assert(
|
assert(
|
||||||
html == """<p><a href="CHANGELOG.md">ChangeLog</a></p>"""
|
html == """<p><a href="http://localhost:8080/user/repo/blob/master/sub/dir/CHANGELOG.md">ChangeLog</a></p>"""
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user