GitBucket
+ @defining(AutoUpdate.getCurrentVersion){ version =>
+ @version.majorVersion.@version.minorVersion
+ }
+ change code !!!!!!!!!!!!!!!!
+
+:
+```
+
+If JRebel is doing is correctly installed you will see a notice for you:
+
+```
+1. Waiting for source changes... (press enter to interrupt)
+2016-01-03 21:48:42 JRebel: Reloading class 'gitbucket.core.html.main$'.
+[info] Wrote rebel.xml to /git/gitbucket/target/scala-2.11/resource_managed/main/rebel.xml
+[info] Compiling 1 Scala source to /git/gitbucket/target/scala-2.11/classes...
+[success] Total time: 3 s, completed Jan 3, 2016 9:48:55 PM
+2. Waiting for source changes... (press enter to interrupt)
+```
+
+And you reload browser, JRebel give notice of that it has reloaded classes:
+
+```
+[success] Total time: 3 s, completed Jan 3, 2016 9:48:55 PM
+2. Waiting for source changes... (press enter to interrupt)
+2016-01-03 21:49:13 JRebel: Reloading class 'gitbucket.core.html.main$'.
+```
+
+## 6. Limitations
+
+JRebel is nearly always able to eliminate the need to explicitly reload your container after a code change. However, if you change any of your routes patterns, there is nothing JRebel can do, you will have to run `jetty:start`.
diff --git a/doc/readme.md b/doc/readme.md
index d4e3c58e2..f8b23dec6 100644
--- a/doc/readme.md
+++ b/doc/readme.md
@@ -9,3 +9,4 @@ Developer's Guide
* [Notification Email](notification.md)
* [Automatic Schema Updating](auto_update.md)
* [Release Operation](release.md)
+ * [JRebel integration (optional)](jrebel.md)
diff --git a/project/build.scala b/project/build.scala
index 84822c985..493c620e4 100644
--- a/project/build.scala
+++ b/project/build.scala
@@ -5,6 +5,8 @@ import sbt._
import sbtassembly.AssemblyKeys._
import sbtassembly._
import JettyPlugin.autoImport._
+import fi.gekkio.sbtplugins.jrebel.JRebelPlugin._
+import com.earldouglas.xwp.WebappPlugin.autoImport.webappPrepare
object MyBuild extends Build {
val Organization = "gitbucket"
@@ -78,5 +80,10 @@ object MyBuild extends Build {
testOptions in Test += Tests.Setup( () => new java.io.File("target/gitbucket_home_for_test").mkdir() ),
fork in Test := true,
packageOptions += Package.MainClass("JettyLauncher")
+ ).settings(jrebelSettings: _*).settings(
+ jrebel.webLinks += (target in webappPrepare).value,
+ jrebel.enabled := System.getenv().get("JREBEL") != null,
+ javaOptions in Jetty ++= Option(System.getenv().get("JREBEL")).toSeq.flatMap(path =>
+ Seq("-noverify", "-XX:+UseConcMarkSweepGC", "-XX:+CMSClassUnloadingEnabled", s"-javaagent:${path}"))
).enablePlugins(SbtTwirl, JettyPlugin)
}
diff --git a/project/plugins.sbt b/project/plugins.sbt
index 5ed803b14..fe0d1bd08 100644
--- a/project/plugins.sbt
+++ b/project/plugins.sbt
@@ -2,4 +2,5 @@ scalacOptions ++= Seq("-unchecked", "-deprecation", "-feature")
addSbtPlugin("com.typesafe.sbt" % "sbt-twirl" % "1.0.4")
addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.12.0")
-addSbtPlugin("com.earldouglas" % "xsbt-web-plugin" % "2.1.0")
\ No newline at end of file
+addSbtPlugin("com.earldouglas" % "xsbt-web-plugin" % "2.1.0")
+addSbtPlugin("fi.gekkio.sbtplugins" % "sbt-jrebel-plugin" % "0.10.0")
diff --git a/src/main/scala/gitbucket/core/controller/RepositoryViewerController.scala b/src/main/scala/gitbucket/core/controller/RepositoryViewerController.scala
index 2e63b1746..155204b84 100644
--- a/src/main/scala/gitbucket/core/controller/RepositoryViewerController.scala
+++ b/src/main/scala/gitbucket/core/controller/RepositoryViewerController.scala
@@ -111,6 +111,7 @@ trait RepositoryViewerControllerBase extends ControllerBase {
enableRefsLink = params("enableRefsLink").toBoolean,
enableLineBreaks = params("enableLineBreaks").toBoolean,
enableTaskList = params("enableTaskList").toBoolean,
+ enableAnchor = false,
hasWritePermission = hasWritePermission(repository.owner, repository.name, context.loginAccount)
)
})
diff --git a/src/main/scala/gitbucket/core/view/Markdown.scala b/src/main/scala/gitbucket/core/view/Markdown.scala
index 2d7854682..5acaa1de2 100644
--- a/src/main/scala/gitbucket/core/view/Markdown.scala
+++ b/src/main/scala/gitbucket/core/view/Markdown.scala
@@ -33,28 +33,30 @@ object Markdown {
enableTaskList: Boolean = false,
hasWritePermission: Boolean = false,
pages: List[String] = Nil)(implicit context: Context): String = {
- // escape issue id
- val s = if(enableRefsLink){
- markdown.replaceAll("(?<=(\\W|^))#(\\d+)(?=(\\W|$))", "issue:$2")
- } else markdown
// escape task list
- val source = if(enableTaskList){
- escapeTaskList(s)
- } else s
+ val source = if(enableTaskList) escapeTaskList(markdown) else markdown
val options = new Options()
options.setSanitize(true)
options.setBreaks(enableLineBreaks)
- val renderer = new GitBucketMarkedRenderer(options, repository, enableWikiLink, enableRefsLink, enableAnchor, enableTaskList, hasWritePermission, pages)
+
+ val renderer = new GitBucketMarkedRenderer(options, repository,
+ enableWikiLink, enableRefsLink, enableAnchor, enableTaskList, hasWritePermission, pages)
+
Marked.marked(source, options, renderer)
}
/**
* Extends markedj Renderer for GitBucket
*/
- class GitBucketMarkedRenderer(options: Options, repository: RepositoryService.RepositoryInfo,
- enableWikiLink: Boolean, enableRefsLink: Boolean, enableAnchor: Boolean, enableTaskList: Boolean, hasWritePermission: Boolean,
+ class GitBucketMarkedRenderer(options: Options,
+ repository: RepositoryService.RepositoryInfo,
+ enableWikiLink: Boolean,
+ enableRefsLink: Boolean,
+ enableAnchor: Boolean,
+ enableTaskList: Boolean,
+ hasWritePermission: Boolean,
pages: List[String])
(implicit val context: Context) extends Renderer(options) with LinkConverter with RequestCache {
@@ -62,11 +64,14 @@ object Markdown {
val id = generateAnchorName(text)
val out = new StringBuilder()
- out.append("
Previewing...');
$.post('@url(repository)/_preview', {
- content : editor.getValue(),
- enableWikiLink : false,
- enableRefsLink : false,
- enableTaskList : false
+ content : editor.getValue(),
+ enableWikiLink : false,
+ enableRefsLink : false,
+ enableLineBreaks : false,
+ enableTaskList : false
}, function(data){
$('#preview').empty().append(
$('