GitBucket: The perfect Github clone by Scala

Post on 21-Nov-2014

6.091 views 2 download

description

ScalaMatsuri 2014

Transcript of GitBucket: The perfect Github clone by Scala

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

DemoDemo site (Thanks to @xuwei_k)

http://gitbucket.herokuapp.com/

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