Skip to content
This repository has been archived by the owner on Dec 10, 2018. It is now read-only.

Commit

Permalink
iss #12: frontend pipeline with babel js, less; dev mode; build info
Browse files Browse the repository at this point in the history
  • Loading branch information
maizy committed Apr 24, 2016
1 parent 78a3081 commit 037509f
Show file tree
Hide file tree
Showing 23 changed files with 215 additions and 44 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,5 @@ lib_managed/
src_managed/
project/boot/
project/plugins/project/

node_modules/
7 changes: 7 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,19 @@ cache:
- $HOME/.m2/repository
- $HOME/.sbt
- $HOME/.ivy2
- $HOME/.nvm
language: scala
jdk:
- oraclejdk8
scala:
- 2.11.7
script:
- nvm --version
- nvm install 4
- nvm use 4
- npm install -g npm@'>=2.5'
- node --version
- npm --version
- sbt ++$TRAVIS_SCALA_VERSION clean coverage test coverageReport
- sbt ++$TRAVIS_SCALA_VERSION coverageAggregate
after_success:
Expand Down
14 changes: 12 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,19 @@ _TBA_

`sbt test`

## Start the server

`sbt server/run`
## Start the server in dev mode

Dev requirements: node 4.1+, npm 2.5+.

Run server in dev mode
`sbt -DassetsMode=dev server/run`

Compile assets:
`sbt server/compile:assets`

or start in the watch mode (after any changes happens assets will be automatically recompiled):
`sbt ~server/compile:assets`


## Compile all artifacts
Expand Down
1 change: 1 addition & 0 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@ version := "0.0.1"
scalaVersion := "2.11.7"

lazy val api = project.in(file("api"))

lazy val server = project.in(file("server")).dependsOn(api)
7 changes: 6 additions & 1 deletion project/plugins.sbt
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
logLevel := Level.Warn
logLevel := Level.Info

resolvers += "sonatype-releases" at "https://oss.sonatype.org/content/repositories/releases/"
resolvers += "Typesafe repository" at "http://repo.typesafe.com/typesafe/releases/"

addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.14.1")

Expand All @@ -11,3 +12,7 @@ addSbtPlugin("org.scalastyle" %% "scalastyle-sbt-plugin" % "0.8.0")
addSbtPlugin("org.scoverage" % "sbt-scoverage" % "1.3.5")

addSbtPlugin("org.scoverage" % "sbt-coveralls" % "1.1.0")

addSbtPlugin("io.teamscala.sbt" % "sbt-babel" % "1.0.3")

addSbtPlugin("com.typesafe.sbt" % "sbt-less" % "1.1.0")
3 changes: 3 additions & 0 deletions server/.babelrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"presets": ["es2015", "react"]
}
30 changes: 29 additions & 1 deletion server/build.sbt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
enablePlugins(JavaServerAppPackaging)
enablePlugins(JavaServerAppPackaging, SbtWeb)

name := "cheesecake-server"
organization := "ru.maizy"
Expand All @@ -8,6 +8,10 @@ scalaVersion := "2.11.7"
val akkaVersion = "2.4.2"
val akkaStreamsVersion = akkaVersion

val immutableJsVersion = "3.8.1"
val reactVersion = "15.0.1"
val bootstrapVersion = "3.3.6"

libraryDependencies ++= Seq(
"ch.qos.logback" % "logback-classic" % "1.1.3",
"com.github.scopt" %% "scopt" % "3.3.0",
Expand Down Expand Up @@ -40,3 +44,27 @@ testScalastyle := org.scalastyle.sbt.ScalastylePlugin.scalastyle.in(Test).toTask
testScalastyleInCompile := org.scalastyle.sbt.ScalastylePlugin.scalastyle.in(Compile).toTask("").value
(test in Test) <<= (test in Test) dependsOn (testScalastyle, testScalastyleInCompile)
scalastyleFailOnError := true

// Build info
resourceGenerators in Compile += Def.task {
val file = (resourceManaged in Compile).value / "buildinfo.properties"
val contents = Seq(
s"version=${version.value}",
s"name=${name.value}",
s"buildTime=${System.currentTimeMillis()}",
s"frontend.immutable=$immutableJsVersion",
s"frontend.react=$reactVersion",
s"frontend.bootstrap=$bootstrapVersion"
).mkString("\n")
IO.write(file, contents)
Seq(file)
}.taskValue

// Frontend settings
JsEngineKeys.engineType := JsEngineKeys.EngineType.Node
libraryDependencies ++= Seq(
"org.webjars.npm" % "immutable" % immutableJsVersion,
"org.webjars.npm" % "react" % reactVersion,
"org.webjars.npm" % "react-dom" % reactVersion,
"org.webjars.npm" % "bootstrap" % bootstrapVersion
)
7 changes: 7 additions & 0 deletions server/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"devDependencies": {
"babel-core": "6.7.7",
"babel-preset-es2015": "6.6.0",
"babel-preset-react": "6.5.0"
}
}
15 changes: 15 additions & 0 deletions server/src/main/assets/js/test-react.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// tutorial1.js
var CommentBox = React.createClass({
render: function() {
return (
<div className="commentBox">
Hello, world! I am a CommentBox.
</div>
);
}
});

ReactDOM.render(
<CommentBox />,
document.getElementById('content')
);
3 changes: 3 additions & 0 deletions server/src/main/assets/js/test.es6
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
var test = [1, 2, 3].map(x => x * 2);
}
3 changes: 3 additions & 0 deletions server/src/main/assets/stylesheets/main.less
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
body {
background: #ddd;
}
Original file line number Diff line number Diff line change
@@ -1,18 +1,20 @@
<!DOCTYPE HTML>
<!DOCTYPE html>
<html lang="ru">
<head>
<title>cheesecake</title>
<meta charset="utf-8"/>
<link href="/assets/stylesheets/main.css" rel="stylesheet" type="text/css"/>
</head>

<body>

<h1>State</h1>

<div id="container"/>
<div id="container"></div>

<script src="/assets/js/http-utils.js"></script>
<script src="/assets/js/results.js"></script>
<script src="/libs/immutable/dist/immutable.min.js"></script>
<script>
cheesecake.results = new cheesecake.ResultsComponent({
container: document.getElementById("container"),
Expand Down
32 changes: 32 additions & 0 deletions server/src/main/scala/ru/maizy/cheesecake/server/BuildInfo.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package ru.maizy.cheesecake.server

import java.time.{ Instant, ZoneId, ZonedDateTime }
import java.util.Properties

/**
* Copyright (c) Nikita Kovaliov, maizy.ru, 2016
* See LICENSE.txt for details.
*/
case object BuildInfo {

private val buildProperties: Map[String, Option[String]] = {
val props = new Properties
Option(getClass.getClassLoader.getResourceAsStream("buildinfo.properties"))
.foreach(props.load)
Map(
"version" -> Option(props.getProperty("version")),
"name" -> Option(props.getProperty("name")),
"buildTime" -> Option(props.getProperty("buildTime"))
)
}

def version: String = buildProperties("version").getOrElse("0.0.0")
def projectName: String = buildProperties("name").getOrElse("cheesecake-server")
def buildTime: ZonedDateTime = {
val utc = ZoneId.of("UTC")
buildProperties("buildTime")
.map { t => ZonedDateTime.ofInstant(Instant.ofEpochMilli(t.toLong), utc) }
.getOrElse(ZonedDateTime.now().withZoneSameInstant(utc))
}

}
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
package ru.maizy.cheesecake.server

import java.util.Properties

/**
* Copyright (c) Nikita Kovaliov, maizy.ru, 2016
* See LICENSE.txt for details.
*/


object Version {
val asSeq: Seq[Int] = Seq(0, 0, 1)
val literal: String = asSeq.mkString(".")

val literal: String = BuildInfo.version
val asSeq: Seq[Int] = literal.split(".").map(_.toInt)

override def toString: String = literal
}
58 changes: 43 additions & 15 deletions server/src/main/scala/ru/maizy/cheesecake/server/WebUI.scala
Original file line number Diff line number Diff line change
Expand Up @@ -6,31 +6,59 @@ package ru.maizy.cheesecake.server
*/


import java.nio.file.{ Path, Paths }
import akka.actor.ActorSystem
import akka.http.scaladsl.server.Directives._
import akka.http.scaladsl.server.Route


class WebUI(system: ActorSystem) {

val routes: Route =
pathSingleSlash {
encodeResponse {
getFromResource("web-ui/index.html")
}
} ~
pathPrefix("assets") {
encodeResponse {
get {
getFromResourceDirectory("web-ui/assets")
val WEBJARS = "webjars"
val ASSETS = "assets"
val LIBS = "libs"

private val staticRoutes: Route = {
val devMode = System.getProperty("assetsMode") == "dev"
if (devMode) {
// TODO: is there any way to compile assets to the same dir as in an assemblied jar?
val webRoot = Paths.get("server/target/web").toAbsolutePath
val compiledStatic = s"${webRoot.toString}/public/main"
pathSingleSlash {
encodeResponse {
getFromFile(s"$compiledStatic/index.html")
}
} ~
pathPrefix(ASSETS) {
encodeResponse {
get(getFromDirectory(compiledStatic))
}
} ~
pathPrefix(LIBS) {
encodeResponse {
get(getFromDirectory(s"${webRoot.toString}/node-modules/main/$WEBJARS"))
}
}
} ~
path("ping") {
get {
complete {
"pong"
} else {
val projectWebjar = s"$WEBJARS/${BuildInfo.projectName}/$Version"
pathSingleSlash {
encodeResponse {
getFromResource(s"$projectWebjar/index.html")
}
} ~
pathPrefix(ASSETS) {
encodeResponse {
get(getFromResourceDirectory(s"$projectWebjar"))
}
} ~
// TODO: find better solution
pathPrefix(s"$LIBS/immutable") {
encodeResponse {
get(getFromResourceDirectory(s"$WEBJARS/immutable/3.7.5"))
}
}
}
}

val routes: Route = staticRoutes
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,9 @@ import akka.pattern.ask
import akka.http.scaladsl.server.Directives._
import akka.http.scaladsl.server.Route
import akka.util.Timeout
import ru.maizy.cheesecake.server.{ BuildInfo, Version }
import ru.maizy.cheesecake.server.checker.CheckStatus
import ru.maizy.cheesecake.server.jsonapi.models.{ AppConfigs, FullView }
import ru.maizy.cheesecake.server.jsonapi.models.{ AppConfigs, AppVersion, FullView }
import ru.maizy.cheesecake.server.resultsstorage.{ AggregateType, AggregatedResults, AllEndpoints }
import ru.maizy.cheesecake.server.resultsstorage.{ GetAggregatedResults, GetAllEndpoints, LastResultAggregate }
import ru.maizy.cheesecake.server.resultsstorage.SimpleAggregate
Expand All @@ -38,17 +39,28 @@ class JsonApi(system: ActorSystem, host: String, port: Int) extends JsonApiMarsh
path("configs") {
get {
complete {
// TODO: build from app config
AppConfigs(wsStateUrl = "/ws/state")
}
}
}

private val status: Route =
path("version") {
get {
complete {
AppVersion(Version.literal, BuildInfo.buildTime)
}
}
} ~ path("status") {
get {
complete("ok")
}
}

val routes: Route = logRequestResult("cheesecake-json-api") {
configs ~
pathPrefix("services") {
services
}
status ~
pathPrefix("services")(services)
}

def storageRef: Future[ActorRef] =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,17 @@ package ru.maizy.cheesecake.server.jsonapi
* See LICENSE.txt for details.
*/

import ru.maizy.cheesecake.server.jsonapi.models.AppConfigs
import ru.maizy.cheesecake.server.marshallers.{ FullViewJsonMarshallers, JsonMarshaller, ServiceJsonMarshallers }
import ru.maizy.cheesecake.server.jsonapi.models.{ AppConfigs, AppVersion }
import ru.maizy.cheesecake.server.marshallers.{ DateTimeMarshallers, FullViewJsonMarshallers, JsonMarshaller }
import ru.maizy.cheesecake.server.marshallers.ServiceJsonMarshallers


trait JsonApiMarshallers
extends ServiceJsonMarshallers
with FullViewJsonMarshallers
with DateTimeMarshallers
with JsonMarshaller
{
implicit val configFormat = jsonFormat1(AppConfigs)
implicit val versionFormat = jsonFormat2(AppVersion)
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
package ru.maizy.cheesecake.server.jsonapi.models

import java.time.ZonedDateTime

/**
* Copyright (c) Nikita Kovaliov, maizy.ru, 2016
* See LICENSE.txt for details.
*/
case class AppConfigs(wsStateUrl: String)
case class AppVersion(version: String, buildTime: ZonedDateTime)
Loading

0 comments on commit 037509f

Please sign in to comment.