Skip to content

Commit 87d7772

Browse files
author
Guillaume Bort
committed
Refactor build.sbt
Change-Id: I26f35d29a9f35e9f0bacaad1641b8be5629a41bf
1 parent 2238a49 commit 87d7772

File tree

40 files changed

+322
-2098
lines changed

40 files changed

+322
-2098
lines changed

.flowconfig

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,5 @@ module.file_ext=.js
1414
module.file_ext=.css
1515
module.file_ext=.less
1616

17-
module.name_mapper='^VizSQL$' -> 'empty/object'
1817
module.name_mapper.extension='css' -> 'empty/object'
1918
module.name_mapper.extension='less' -> 'empty/object'

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,5 @@ project/target
22
target
33
node_modules
44
.idea
5+
dev.config.json
6+
.DS_Store

.pre-commit.sh

Lines changed: 0 additions & 3 deletions
This file was deleted.

README.md

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,20 @@
1-
# Langoustine++
1+
# Langoustine, the good parts
2+
3+
To work on th Scala API, run sbt using `sbt -DdevMode=true` (the devMode option allows to skip webpack execution to speed up execution). You can use `~compile` or `~test` on the root project or focus on a specific project using `~timeserie/test`.
4+
5+
To run an example application, use `example HelloWorld` where HelloWorld is the example class name.
6+
7+
To work on the web application:
8+
9+
- Install **yarn** (https://yarnpkg.com/en/).
10+
- Create a `dev.config.json` file in your project root:
11+
```
12+
{
13+
"env": {
14+
},
15+
"example": "HelloWorld"
16+
}
17+
```
18+
- Run, `yarn install` and `yarn start`.
219

3-
The time series scheduler that keeps your data fresh.
420

build.sbt

Lines changed: 102 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,43 +1,108 @@
1-
val devMode = Option(System.getProperty("devMode")).exists(_ == "true")
1+
val devMode = taskKey[Boolean]("Some build optimization are applied in devMode.")
22

3-
name := "langoustinepp"
4-
organization := "com.criteo"
5-
version := "0.1.0"
6-
scalaVersion := "2.12.1"
3+
lazy val commonSettings = Seq(
4+
organization := "org.criteo.langoustine",
5+
version := "dev-SNAPSHOT",
6+
scalaVersion := "2.11.8",
7+
scalacOptions ++= Seq(
8+
"-deprecation",
9+
"-encoding", "UTF-8",
10+
"-feature",
11+
"-unchecked",
12+
"-Xlint",
13+
"-Yno-adapted-args",
14+
"-Ywarn-dead-code",
15+
"-language:postfixOps",
16+
"-Xfuture",
17+
"-Ywarn-unused-import"
18+
),
19+
devMode := Option(System.getProperty("devMode")).exists(_ == "true"),
720

8-
scalacOptions := Seq("-feature", "-deprecation")
21+
// Maven config
22+
resolvers += "Nexus" at "http://nexus.criteo.prod/content/repositories/criteo.thirdparty/",
23+
publishTo := Some("Criteo thirdparty" at "http://nexus.criteo.prod/content/repositories/criteo.thirdparty"),
24+
credentials += Credentials("Sonatype Nexus Repository Manager", "nexus.criteo.prod", System.getenv("MAVEN_USER"), System.getenv("MAVEN_PASSWORD")),
925

10-
mainClass in(Compile, run) := Some("com.criteo.langoustinepp.LangoustinePP")
26+
// Useful to run flakey tests
27+
commands += Command.single("repeat") { (state, arg) =>
28+
arg :: s"repeat $arg" :: state
29+
},
1130

12-
libraryDependencies ++= Seq(
13-
"org.criteo.lolhttp" %% "lolhttp" % "0.2.2",
14-
"org.criteo.lolhttp" %% "loljson" % "0.2.2",
15-
"org.scala-stm" %% "scala-stm" % "0.8",
16-
"org.scalatest" %% "scalatest" % "3.0.1" % "test",
17-
"org.scalacheck" %% "scalacheck" % "1.13.4" % "provided",
18-
"codes.reactive" %% "scala-time" % "0.4.1"
31+
// Run an example in another JVM, and quit on key press
32+
commands += Command.single("example") { (state, arg) =>
33+
s"examples/test:runMain org.criteo.langoustine.examples.TestExample $arg" :: state
34+
}
1935
)
2036

21-
resolvers += "Nexus" at "http://nexus.criteo.prod/content/repositories/criteo.thirdparty/"
22-
23-
resourceGenerators in Compile += Def.task {
24-
if(devMode) Nil else {
25-
def listFiles(dir: File): Seq[File] = {
26-
IO.listFiles(dir).flatMap(f =>
27-
if (f.isDirectory) listFiles(f)
28-
else Seq(f)
29-
)
30-
}
31-
val webpackOutputDir: File = (resourceManaged in Compile).value / "public"
32-
val logger = new ProcessLogger {
33-
override def error(s: =>String): Unit = ()
34-
override def buffer[T](f: => T): T = f
35-
override def info(s: => String): Unit = streams.value.log.info(s)
36-
}
37-
logger.info(s"Generating UI assets to $webpackOutputDir...")
38-
assert("yarn install" ! logger == 0, "yarn failed")
39-
logger.info("Running webpack...")
40-
assert(s"./node_modules/webpack/bin/webpack.js --output-path $webpackOutputDir --bail" ! logger == 0, "webpack failed")
41-
listFiles(webpackOutputDir)
42-
}
43-
}.taskValue
37+
lazy val continuum = {
38+
ProjectRef(uri("git://github.com/danburkert/continuum.git#b2122f1980fb69eb0d047e47e9d7de730ccbd448"), "continuum")
39+
}
40+
41+
lazy val langoustine =
42+
(project in file("core")).
43+
settings(commonSettings: _*).
44+
settings(
45+
libraryDependencies ++= Seq(
46+
"org.criteo.lolhttp" %% "lolhttp",
47+
"org.criteo.lolhttp" %% "loljson"
48+
).map(_ % "0.2.2"),
49+
50+
libraryDependencies ++= Seq(
51+
"org.scala-stm" %% "scala-stm" % "0.8",
52+
"codes.reactive" %% "scala-time" % "0.4.1"
53+
),
54+
55+
libraryDependencies ++= Seq(
56+
"org.scalatest" %% "scalatest" % "3.0.1"
57+
).map(_ % "test"),
58+
59+
resourceGenerators in Compile += Def.task {
60+
if(devMode.value) {
61+
streams.value.log.warn(s"Skipping webpack resource generation.")
62+
Nil
63+
} else {
64+
def listFiles(dir: File): Seq[File] = {
65+
IO.listFiles(dir).flatMap(f =>
66+
if (f.isDirectory) listFiles(f)
67+
else Seq(f)
68+
)
69+
}
70+
val webpackOutputDir: File = (resourceManaged in Compile).value / "public"
71+
val logger = new ProcessLogger {
72+
override def error(s: =>String): Unit = ()
73+
override def buffer[T](f: => T): T = f
74+
override def info(s: => String): Unit = streams.value.log.info(s)
75+
}
76+
logger.info(s"Generating UI assets to $webpackOutputDir...")
77+
assert(s"yarn install" ! logger == 0, "yarn failed")
78+
logger.info("Running webpack...")
79+
assert(s"./node_modules/webpack/bin/webpack.js --output-path $webpackOutputDir --bail" ! logger == 0, "webpack failed")
80+
listFiles(webpackOutputDir)
81+
}
82+
}.taskValue
83+
).
84+
dependsOn(continuum)
85+
86+
lazy val timeserie =
87+
(project in file("timeserie")).
88+
settings(commonSettings: _*).
89+
settings(
90+
).
91+
dependsOn(langoustine % "compile->compile;test->test")
92+
93+
lazy val examples =
94+
(project in file("examples")).
95+
settings(commonSettings: _*).
96+
settings(
97+
fork in Test := true,
98+
connectInput in Test := true
99+
).
100+
dependsOn(langoustine, timeserie)
101+
102+
lazy val root =
103+
(project in file(".")).
104+
settings(commonSettings: _*).
105+
settings(
106+
publishArtifact := false
107+
).
108+
aggregate(langoustine, timeserie, examples)
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,6 @@
1-
package com.criteo.langoustinepp
1+
package org.criteo.langoustine
22

3-
import lol.http._
4-
5-
import scala.concurrent.Future
6-
import scala.concurrent.ExecutionContext
7-
import scala.concurrent.ExecutionContext.Implicits.global
3+
import scala.concurrent.{ ExecutionContext }
84

95
trait Scheduler[S <: Scheduling] {
106
def run(graph: Graph[S])(implicit executor: ExecutionContext): Unit
@@ -15,12 +11,11 @@ trait Scheduling {
1511
type DependencyDescriptor
1612
}
1713

18-
1914
sealed trait Graph[S <: Scheduling] {
2015
type Dependency = (Job[S], Job[S], S#DependencyDescriptor)
2116

22-
private[langoustinepp] def vertices: Set[Job[S]]
23-
private[langoustinepp] def edges: Set[Dependency]
17+
private[langoustine] def vertices: Set[Job[S]]
18+
private[langoustine] def edges: Set[Dependency]
2419

2520
def and(otherGraph: Graph[S]): Graph[S] = {
2621
val graph = this
@@ -30,14 +25,14 @@ sealed trait Graph[S <: Scheduling] {
3025
}
3126
}
3227

33-
private[langoustinepp] lazy val roots = vertices.filter (v =>
28+
private[langoustine] lazy val roots = vertices.filter (v =>
3429
edges.forall { case (v1, _, _) => v1 != v })
35-
private[langoustinepp] lazy val leaves = vertices.filter (v =>
30+
private[langoustine] lazy val leaves = vertices.filter (v =>
3631
edges.forall { case (_, v2, _) => v2 != v })
3732

3833
def dependsOn(right: Graph[S])
3934
(implicit depDescriptor: S#DependencyDescriptor): Graph[S] =
40-
dependsOn(right, depDescriptor)
35+
dependsOn((right, depDescriptor))
4136

4237
def dependsOn(right: (Graph[S], S#DependencyDescriptor)): Graph[S] = {
4338
val (rightGraph, depDescriptor) = right
@@ -57,26 +52,3 @@ case class Job[S <: Scheduling](name: String, scheduling: S) extends Graph[S] {
5752
val vertices = Set(this)
5853
val edges = Set.empty[Dependency]
5954
}
60-
61-
/* Ping-pong stuff */
62-
63-
object LangoustinePPServer {
64-
val routes: PartialService = {
65-
case GET at "/" =>
66-
Redirect("/ping")
67-
68-
case GET at "/ping" =>
69-
Ok("pong!")
70-
}
71-
72-
def main(args: Array[String]): Unit = {
73-
val httpPort = args.lift(0).map(_.toInt).getOrElse(8888)
74-
Server.listen(
75-
port = httpPort,
76-
onError = { e =>
77-
e.printStackTrace()
78-
InternalServerError("LOL.")
79-
})(routes)
80-
println(s"Listening on http://localhost:$httpPort")
81-
}
82-
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package org.criteo.langoustine
2+
3+
import lol.http._
4+
5+
import scala.concurrent.ExecutionContext.Implicits.global
6+
7+
object Langoustine {
8+
val routes: PartialService = {
9+
case GET at "/" =>
10+
Redirect("/ping")
11+
12+
case GET at "/ping" =>
13+
Ok("pong!!!")
14+
}
15+
16+
def run[S <: Scheduling](worflow: Graph[S], httpPort: Int = 8888)(implicit scheduler: Scheduler[S]) = {
17+
Server.listen(
18+
port = httpPort,
19+
onError = { e =>
20+
e.printStackTrace()
21+
InternalServerError("LOL.")
22+
})(routes)
23+
println(s"Listening on http://localhost:$httpPort")
24+
}
25+
}
File renamed without changes.

src/test/scala/com/criteo/langoustinepp/LangoustinePPSpec.scala renamed to core/src/test/scala/com/criteo/langoustinepp/LangoustineSpec.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package com.criteo.langoustinepp
1+
package org.criteo.langoustine
22

33
import org.scalatest.FunSuite
44

dev.config.json

Lines changed: 0 additions & 4 deletions
This file was deleted.

devloop.js

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
if(!require('fs').existsSync('dev.config.json')) {
2+
throw new Error(`Missing dev.config.json file in your project, please check the README.`);
3+
}
14
let config = loadJson('dev.config.json');
25

36
let sbt = startSbt({
@@ -7,30 +10,39 @@ let sbt = startSbt({
710

811
let compile = sbt.run({
912
command: 'compile',
10-
watch: ['src/**/*.scala']
13+
watch: ['**/*.scala']
1114
});
1215

1316
let packageDependencies = sbt.run({
14-
command: 'assemblyPackageDependency'
17+
command: 'examples/assemblyPackageDependency'
1518
});
1619

1720
let yarn = run({
1821
sh: 'yarn install',
1922
watch: 'package.json'
20-
}).dependsOn(packageDependencies);
23+
});
2124

2225
let front = webpack({
2326
watch: [
2427
'webpack.config.js',
25-
'src/main/javascript/**/*.js',
26-
'src/main/html/**/*.html',
27-
'src/main/style/**/*.*'
28+
'core/src/main/javascript/**/*.*',
29+
'core/src/main/html/**/*.*',
30+
'core/src/main/style/**/*.*'
2831
]
2932
}).dependsOn(yarn);
3033

34+
let classpath = [
35+
'examples/target/scala-2.11/langoustine-assembly-dev-SNAPSHOT-deps.jar',
36+
'core/target/scala-2.11/classes',
37+
'timeserie/target/scala-2.11/classes',
38+
'examples/target/scala-2.11/classes'
39+
];
40+
41+
let example = config.example || 'HelloWorld';
42+
3143
let server = runServer({
3244
httpPort,
33-
sh: `java -cp target/scala-2.11/langoustinepp-assembly-0.1.0-deps.jar:target/scala-2.11/classes com.criteo.langoustinepp.LangoustinePPServer ${httpPort}`,
45+
sh: `java -cp ${classpath.join(':')} org.criteo.langoustine.examples.${example} ${httpPort}`,
3446
env: config.env
3547
}).dependsOn(compile, packageDependencies);
3648

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package org.criteo.langoustine.examples
2+
3+
import org.criteo.langoustine._
4+
import timeserie._
5+
6+
object HelloWorld {
7+
8+
def main(args: Array[String]): Unit = {
9+
10+
val hello = Job("hello", hourly())
11+
val world = Job("world", hourly())
12+
13+
Langoustine.run(
14+
world dependsOn hello,
15+
httpPort = args.lift(0).map(_.toInt).getOrElse(8888))
16+
}
17+
18+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package org.criteo.langoustine.examples
2+
3+
object TestExample {
4+
5+
def main(args: Array[String]): Unit = {
6+
val example = args.headOption.getOrElse(sys.error("Please specify the example to run as argument"))
7+
val forked = new ProcessBuilder(
8+
"java", "-cp",
9+
System.getProperty("java.class.path"), s"org.criteo.langoustine.examples.$example").inheritIO.start()
10+
11+
new Thread() {
12+
override def run: Unit = {
13+
println(s"-- example `$example` started, press [Ctrl+D] to quit")
14+
while (System.in.read != -1) ()
15+
forked.destroy()
16+
}
17+
}.start()
18+
19+
forked.waitFor
20+
System.exit(0)
21+
}
22+
23+
}

0 commit comments

Comments
 (0)