Upload
takezoe
View
6.096
Download
2
Embed Size (px)
DESCRIPTION
ScalaMatsuri 2014
Citation preview
GitBucket: The perfect Github clone by Scala
Naoki Takezoe @takezoen
BizReach, Inc
What’s GitBucket?https://github.com/takezoe/gitbucket
What’s GitBucket?• Open-Source Github clone based on Scala and JGit
• Easy installation by pure JVM based solution
• Main target is intranet users who can’t use Github by political reason
Over 3000 Stars, Thanks!!
3197stars!!
at 18 Aug 2014
Over 3000 Stars, Thanks!!
Product StarsScala 2785Slick 952Scalatra 1428sbt 1921Play2 5103
at 18 Aug 2014Play is Great!!
Features• Public / Private Git repository (http and ssh access) • Repository viewer and online file editing • Repository search (Code and Issues) • Wiki • Issues • Fork / Pull request • Mail notification • Activity timeline • User management (for Administrators) • Group (like Organization in Github) • LDAP integration • Gravatar support
Easy Installation$ wget https://github.com/takezoe/gitbucket/releases/download/2.3/gitbucket.war !$ java -jar gitbucket.war
Showcase• docker-gitbuckethttps://github.com/f99aq8ove/docker-gitbucket
• Jenkins GitBucket Pluginhttps://wiki.jenkins-ci.org/display/JENKINS/GitBucket+Plugin
• Amiagehttp://amiage.com/apps/gitbucket/
About development of GitBucket
GitBucket Team
and 36 Contributors
and 36 Contributors
but our resource is not enough...
We need max development
speed by the minimum cost
Technologies and Tools
Technologies• Scalatra • Twirl • Slick • JGit • H2 • Jetty • Apache MINA
(Server-side)
Technologies• jQuery + Plugins • Bootstrap2 • jsdifflib • google-code-prettify • AceEditor • DropZone • ZeroClipboard
(Front-end)
Architecture
GitServlet Scalatra / Twirl
Git Repository (Source code, Wiki)
H2 (Account, Issues etc)
Jetty
MINA SSHD
SlickJGit
Git Client Web Browser
SSH HTTP
Technologies• Type safety supports our aggressive development
• Based on existing Java resources
• Pure JVM based solution makes easy installation
Scalatra• Simple and powerful servlet based web framework inspired by Sinatra
• More dynamic than Play2, but high extendibility
class MyServlet extends ScalatraServlet with ScalateSupport {! get("/") {! <html>! <body>! <h1>Hello, world!</h1>! Say <a href="hello-scalate">hello to Scalate</a>.! </body>! </html>! }!}
scalatra-forms• Extension library for Scalatra • Server side and client side validation at once
case class SignInForm(userName: String, password: String)!!val form = mapping(! "userName" -> trim(label("Username", text(required))),! "password" -> trim(label("Password", text(required)))!)(SignInForm.apply)!!!post("/signin", form){ form =>! authenticate(context.settings, form.userName, form.password) match {! case Some(account) => signin(account)! case None => redirect("/signin")! }!}
scalatra-forms
Web Browser Server
Send form data to /signin/validate by Ajax
Validation result as JSON
Send form data to /signin if validation passed
Response
Added by scalatra-forms automatically
Display errors if validation failed
Validate again
System error if validation failed
Twirl• Scala syntax template compiler • Also used in Play2@(systemSettings: service.SystemSettingsService.SystemSettings)(implicit context: app.Context)!@import context._!<div class="signin-form">! <div class="header-metal">! @if(systemSettings.allowAccountRegistration){! <div class="pull-right">! <a href="@path/register" class="btn btn-mini">Create new account</a>! </div>! }! Sign in! </div>! <div class="form-body">! <form action="@path/signin" method="POST" validate="true">! <label for="userName">Username:</label>! <span id="error-userName" class="error"></span>! <input type="text" name="userName" id="userName" style="width: 95%"/>! <label for="password">Password:</label>! <span id="error-password" class="error"></span>! <input type="password" name="password" id="password" style="width: 95%"/>! <div><input type="submit" class="btn btn-success" value="Sign in"/></div>! </form>! </div>!</div>
Slick• Typesafe database query library • GitBucket does not use native SQL
Issues filter { t1 =>! condition.repo! .map { _.split('/') match { case array => Seq(array(0) -> array(1)) } }! .getOrElse (repos)! .map { case (owner, repository) => t1.byRepository(owner, repository) }! .foldLeft[Column[Boolean]](false) ( _ || _ ) &&! (t1.closed === (condition.state == "closed").bind) &&! (t1.milestoneId === condition.milestoneId.get.get.bind, condition.milestoneId.flatten.isDefined) &&! (t1.milestoneId.? isEmpty, condition.milestoneId == Some(None)) &&! (t1.assignedUserName === filterUser("assigned").bind, filterUser.get("assigned").isDefined) &&! (t1.openedUserName === filterUser("created_by").bind, filterUser.get("created_by").isDefined) &&! (t1.openedUserName =!= filterUser("not_created_by").bind, filterUser.get("not_created_by").isDefined) &&! (t1.pullRequest === true.bind, onlyPullRequest) &&! (IssueLabels filter { t2 =>! (t2.byIssue(t1.userName, t1.repositoryName, t1.issueId)) &&! (t2.labelId in! (Labels filter { t3 =>! (t3.byRepository(t1.userName, t1.repositoryName)) &&! (t3.labelName inSetBind condition.labels)! } map(_.labelId)))! } exists, condition.labels.nonEmpty)
JGit• Git implementation in Java • Includes GitServlet which provides Git server
// Clone repository!Git.cloneRepository()! .setURI("https://github.com/takezoe/solr-scala-client.git")! .setDirectory(new File("git"))! .call()!!// Show logs!val logs = Git.open(new java.io.File("git")).log().call()!logs.asScala.foreach { rev =>! println(rev.getCommitterIdent().getEmailAddress() + " - " + rev.getCommitTime())! println(rev.getFullMessage())!}
H2• Embeddable pure Java RDBMS • GitBucket has automatic migration system on H2
Differences of these SQLs are run in order.
Apache MINA• Apache MINA is a framework for NIO based network applications
• GitBucket uses MINA SSHD which is an sshd implementation based on MINA
Apache MINAimport org.apache.sshd.SshServer;!import org.apache.sshd.server.keyprovider.SimpleGeneratorHostKeyProvider;!import org.apache.sshd.server.shell.ProcessShellFactory;!import java.util.EnumSet;!!public class Main {!! public static void main(String[] args) throws Exception {! SshServer server = SshServer.setUpDefaultServer();! server.setPort(8080);! server.setKeyPairProvider(new SimpleGeneratorHostKeyProvider("key.ser"));! server.setPasswordAuthenticator((userName, password, serverSession) -> true);! server.setPublickeyAuthenticator((userName, publicKey, serverSession) -> true);!! server.setShellFactory(new ProcessShellFactory(new String[]{"cmd.exe"},! EnumSet.of(! ProcessShellFactory.TtyOptions.Echo,! ProcessShellFactory.TtyOptions.ONlCr,! ProcessShellFactory.TtyOptions.ICrNl)));!! server.start();! }!}
Development Tools• Github • IntelliJ IDEA • Gitter • ZenHub
Github• The greatest source code hosting service and social coding platform
• We are always watching Github to catch up new features or changes
IntelliJ IDEA• The best IDE for Scala • Not perfect, but practical enough • GitBucket project has OpenSource license
Gitter• Chat service which has high affinity with Github
• Sign-in by Github account • Chat room which corresponds to Github repository
• Displays users who saw the message
ZenHub• Provides “Kanban” to Github Issues by Chrome Extension
• Visualizes issue status and priority
Roadmap• Scala based plug-in system
• Features for code review
• Mobile support
• Performance Improvement
Gist PluginPerfect Gist clone built on GitBucket
Write plugin using Scala
Thanks!
All feedback and contributions are always welcome.
https://github.com/takezoe/gitbucket