GitBucket: The perfect Github clone by Scala

37
GitBucket: The perfect Github clone by Scala Naoki Takezoe @takezoen BizReach, Inc

description

ScalaMatsuri 2014

Transcript of GitBucket: The perfect Github clone by Scala

Page 1: GitBucket: The perfect Github clone by Scala

GitBucket: The perfect Github clone by Scala

Naoki Takezoe @takezoen

BizReach, Inc

Page 2: GitBucket: The perfect Github clone by Scala

What’s GitBucket?https://github.com/takezoe/gitbucket

Page 3: GitBucket: The perfect Github clone by Scala

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

Page 4: GitBucket: The perfect Github clone by Scala

DemoDemo site (Thanks to @xuwei_k)

http://gitbucket.herokuapp.com/

Page 5: GitBucket: The perfect Github clone by Scala

Over 3000 Stars, Thanks!!

3197stars!!

at 18 Aug 2014

Page 6: GitBucket: The perfect Github clone by Scala

Over 3000 Stars, Thanks!!

Product StarsScala 2785Slick 952Scalatra 1428sbt 1921Play2 5103

at 18 Aug 2014Play is Great!!

Page 7: GitBucket: The perfect Github clone by Scala

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

Page 8: GitBucket: The perfect Github clone by Scala

Easy Installation$ wget https://github.com/takezoe/gitbucket/releases/download/2.3/gitbucket.war !$ java -jar gitbucket.war

Page 9: GitBucket: The perfect Github clone by Scala

Showcase• docker-gitbuckethttps://github.com/f99aq8ove/docker-gitbucket

• Jenkins GitBucket Pluginhttps://wiki.jenkins-ci.org/display/JENKINS/GitBucket+Plugin

• Amiagehttp://amiage.com/apps/gitbucket/

Page 10: GitBucket: The perfect Github clone by Scala

About development of GitBucket

Page 11: GitBucket: The perfect Github clone by Scala

GitBucket Team

Page 12: GitBucket: The perfect Github clone by Scala

and 36 Contributors

Page 13: GitBucket: The perfect Github clone by Scala

and 36 Contributors

but our resource is not enough...

Page 14: GitBucket: The perfect Github clone by Scala

We need max development

speed by the minimum cost

Page 15: GitBucket: The perfect Github clone by Scala

Technologies and Tools

Page 16: GitBucket: The perfect Github clone by Scala

Technologies• Scalatra • Twirl • Slick • JGit • H2 • Jetty • Apache MINA

(Server-side)

Page 17: GitBucket: The perfect Github clone by Scala

Technologies• jQuery + Plugins • Bootstrap2 • jsdifflib • google-code-prettify • AceEditor • DropZone • ZeroClipboard

(Front-end)

Page 18: GitBucket: The perfect Github clone by Scala

Architecture

GitServlet Scalatra / Twirl

Git Repository (Source code, Wiki)

H2 (Account, Issues etc)

Jetty

MINA SSHD

SlickJGit

Git Client Web Browser

SSH HTTP

Page 19: GitBucket: The perfect Github clone by Scala

Technologies• Type safety supports our aggressive development

• Based on existing Java resources

• Pure JVM based solution makes easy installation

Page 20: GitBucket: The perfect Github clone by Scala

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>! }!}

Page 21: GitBucket: The perfect Github clone by Scala

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")! }!}

Page 22: GitBucket: The perfect Github clone by Scala

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

Page 23: GitBucket: The perfect Github clone by Scala

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>

Page 24: GitBucket: The perfect Github clone by Scala

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)

Page 25: GitBucket: The perfect Github clone by Scala

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())!}

Page 26: GitBucket: The perfect Github clone by Scala

H2• Embeddable pure Java RDBMS • GitBucket has automatic migration system on H2

Differences of these SQLs are run in order.

Page 27: GitBucket: The perfect Github clone by Scala

Apache MINA• Apache MINA is a framework for NIO based network applications

• GitBucket uses MINA SSHD which is an sshd implementation based on MINA

Page 28: GitBucket: The perfect Github clone by Scala

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();! }!}

Page 29: GitBucket: The perfect Github clone by Scala

Development Tools• Github • IntelliJ IDEA • Gitter • ZenHub

Page 30: GitBucket: The perfect Github clone by Scala

Github• The greatest source code hosting service and social coding platform

• We are always watching Github to catch up new features or changes

Page 31: GitBucket: The perfect Github clone by Scala

IntelliJ IDEA• The best IDE for Scala • Not perfect, but practical enough • GitBucket project has OpenSource license

Page 32: GitBucket: The perfect Github clone by Scala

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

Page 33: GitBucket: The perfect Github clone by Scala

ZenHub• Provides “Kanban” to Github Issues by Chrome Extension

• Visualizes issue status and priority

Page 34: GitBucket: The perfect Github clone by Scala

Roadmap• Scala based plug-in system

• Features for code review

• Mobile support

• Performance Improvement

Page 35: GitBucket: The perfect Github clone by Scala

Gist PluginPerfect Gist clone built on GitBucket

Page 36: GitBucket: The perfect Github clone by Scala

Write plugin using Scala

Page 37: GitBucket: The perfect Github clone by Scala

Thanks!

All feedback and contributions are always welcome.

https://github.com/takezoe/gitbucket