From e74ade7ac9bfff9239c0243c0fdf01b18d4a0ec3 Mon Sep 17 00:00:00 2001 From: Li Haoyi Date: Mon, 13 Aug 2018 21:11:11 +0800 Subject: 0.1.0 --- build.sc | 4 ++-- cask/src/cask/endpoints/StaticEndpoints.scala | 19 +++++++++++++++++-- cask/src/cask/endpoints/WebSocketEndpoint.scala | 2 +- cask/src/cask/model/Response.scala | 18 +++++++++++++++++- cask/src/cask/package.scala | 3 ++- cask/test/resources/cask/example.txt | 1 - docs/pages/1 - Cask: a Scala HTTP micro-framework .md | 14 +++++++++++++- example/compress/build.sc | 2 +- example/compress2/build.sc | 2 +- example/compress3/build.sc | 2 +- example/cookies/build.sc | 2 +- example/decorated/build.sc | 2 +- example/decorated2/build.sc | 2 +- example/endpoints/build.sc | 2 +- example/formJsonPost/build.sc | 2 +- example/httpMethods/build.sc | 2 +- example/minimalApplication/build.sc | 2 +- example/minimalApplication2/build.sc | 2 +- example/redirectAbort/build.sc | 2 +- example/scalatags/build.sc | 2 +- example/staticFiles/app/resources/cask/example.txt | 1 + example/staticFiles/app/src/StaticFiles.scala | 7 +++++-- example/staticFiles/app/test/src/ExampleTests.scala | 5 ++++- example/staticFiles/build.sc | 11 ++++++++++- example/todo/app/src/TodoServer.scala | 4 ++-- example/todo/build.sc | 2 +- example/todoApi/build.sc | 2 +- example/todoDb/build.sc | 2 +- example/variableRoutes/build.sc | 2 +- example/websockets/build.sc | 2 +- 30 files changed, 92 insertions(+), 33 deletions(-) delete mode 100644 cask/test/resources/cask/example.txt create mode 100644 example/staticFiles/app/resources/cask/example.txt diff --git a/build.sc b/build.sc index b542ad3..9ea4c7b 100644 --- a/build.sc +++ b/build.sc @@ -58,7 +58,7 @@ object cask extends ScalaModule with PublishModule { } object example extends Module{ trait LocalModule extends ScalaModule{ - def ivyDeps = super.ivyDeps().filter(_ != ivy"com.lihaoyi::cask:0.0.9") + def ivyDeps = super.ivyDeps().filter(_ != ivy"com.lihaoyi::cask:0.1.0") override def millSourcePath = super.millSourcePath / "app" def moduleDeps = Seq(cask) @@ -136,7 +136,7 @@ def uploadToGithub(authKey: String) = T.command{ |if [ ! -f out/mill-cask ]; then | echo "Initializing Cask/Mill build tool for the first time" | mkdir -p out && - | (echo "#!/usr/bin/env sh" && curl -L https://github.com/lihaoyi/mill/releases/download/0.2.6/0.2.6) > out/mill-cask + | (echo "#!/usr/bin/env sh" && curl -L https://github.com/lihaoyi/mill/releases/download/0.2.6/0.2.6-13-b9b133) > out/mill-cask |fi | |chmod +x out/mill-cask diff --git a/cask/src/cask/endpoints/StaticEndpoints.scala b/cask/src/cask/endpoints/StaticEndpoints.scala index 726af21..1d66b2c 100644 --- a/cask/src/cask/endpoints/StaticEndpoints.scala +++ b/cask/src/cask/endpoints/StaticEndpoints.scala @@ -3,14 +3,29 @@ package cask.endpoints import cask.main.Endpoint import cask.model.ParamContext -class static(val path: String) extends Endpoint{ +class staticFiles(val path: String) extends Endpoint{ type Output = String val methods = Seq("get") type Input = Seq[String] type InputParser[T] = QueryParamReader[T] override def subpath = true def wrapFunction(ctx: ParamContext, delegate: Delegate): Returned = { - delegate(Map()).map(t => cask.model.Static(t + "/" + ctx.remaining.mkString("/"))) + delegate(Map()).map(t => cask.model.StaticFile(t + "/" + ctx.remaining.mkString("/"))) + } + + def wrapPathSegment(s: String): Input = Seq(s) +} + +class staticResources(val path: String, resourceRoot: ClassLoader = getClass.getClassLoader) extends Endpoint{ + type Output = String + val methods = Seq("get") + type Input = Seq[String] + type InputParser[T] = QueryParamReader[T] + override def subpath = true + def wrapFunction(ctx: ParamContext, delegate: Delegate): Returned = { + delegate(Map()).map(t => + cask.model.StaticResource(t + "/" + ctx.remaining.mkString("/"), resourceRoot) + ) } def wrapPathSegment(s: String): Input = Seq(s) diff --git a/cask/src/cask/endpoints/WebSocketEndpoint.scala b/cask/src/cask/endpoints/WebSocketEndpoint.scala index a795afd..89c05b9 100644 --- a/cask/src/cask/endpoints/WebSocketEndpoint.scala +++ b/cask/src/cask/endpoints/WebSocketEndpoint.scala @@ -38,7 +38,7 @@ object WebsocketResult{ implicit class Listener(val value: WebSocketConnectionCallback) extends WebsocketResult } -class websocket(val path: String, subpath: Boolean = false) extends cask.main.BaseEndpoint{ +class websocket(val path: String, override val subpath: Boolean = false) extends cask.main.BaseEndpoint{ type Output = WebsocketResult val methods = Seq("websocket") type Input = Seq[String] diff --git a/cask/src/cask/model/Response.scala b/cask/src/cask/model/Response.scala index 979c442..9ac5664 100644 --- a/cask/src/cask/model/Response.scala +++ b/cask/src/cask/model/Response.scala @@ -62,7 +62,7 @@ case class Abort(code: Int) extends Response { override def cookies = Nil } -case class Static(path: String) extends Response { +case class StaticFile(path: String) extends Response { val relPath = java.nio.file.Paths.get(path) val (data0, statusCode0) = if (java.nio.file.Files.exists(relPath) && java.nio.file.Files.isRegularFile(relPath)){ @@ -79,6 +79,22 @@ case class Static(path: String) extends Response { override def cookies = Nil } +case class StaticResource(path: String, resourceRoot: ClassLoader) extends Response { + val relPath = java.nio.file.Paths.get(path) + val (data0, statusCode0) = resourceRoot.getResourceAsStream(path) match{ + case null => ("": Response.Data, 404) + case res => (res: Response.Data, 200) + } + + override def data = data0 + + override def statusCode = statusCode0 + + override def headers = Nil + + override def cookies = Nil +} + diff --git a/cask/src/cask/package.scala b/cask/src/cask/package.scala index b1a1550..06d9738 100644 --- a/cask/src/cask/package.scala +++ b/cask/src/cask/package.scala @@ -30,7 +30,8 @@ package object cask { type post = endpoints.post type put = endpoints.put type route = endpoints.route - type static = endpoints.static + type staticFiles = endpoints.staticFiles + type staticResources = endpoints.staticResources type postJson = endpoints.postJson type postForm = endpoints.postForm diff --git a/cask/test/resources/cask/example.txt b/cask/test/resources/cask/example.txt deleted file mode 100644 index 5184576..0000000 --- a/cask/test/resources/cask/example.txt +++ /dev/null @@ -1 +0,0 @@ -the quick brown fox jumps over the lazy dog \ No newline at end of file diff --git a/docs/pages/1 - Cask: a Scala HTTP micro-framework .md b/docs/pages/1 - Cask: a Scala HTTP micro-framework .md index b87c5a6..78046da 100644 --- a/docs/pages/1 - Cask: a Scala HTTP micro-framework .md +++ b/docs/pages/1 - Cask: a Scala HTTP micro-framework .md @@ -65,6 +65,15 @@ can run using: ./cask -w app.test ``` +To configure your Cask application to work with IntelliJ, you can use: + +```bash +./cask mill.scalalib.GenIdea/idea +``` + +This will need to be re-run when you re-configure your `build.sc` file, e.g. +when adding additional modules or third-party dependencies. + Cask is just a Scala library, and you can use Cask in any existing Scala project via the following coordinates: @@ -188,11 +197,14 @@ ago) $$$staticFiles -You can ask Cask to serve static files by defining a `@cask.static` endpoint. +You can ask Cask to serve static files by defining a `@cask.staticFiles` endpoint. This will match any subpath of the value returned by the endpoint (e.g. above `/static/file.txt`, `/static/folder/file.txt`, etc.) and return the file contents from the corresponding file on disk (and 404 otherwise). +Similarly, `@cask.staticResources` attempts to serve a request based on the JVM +resource path, returning the data if a resource is present and a 404 otherwise. + ### Redirects or Aborts $$$redirectAbort diff --git a/example/compress/build.sc b/example/compress/build.sc index 0e803b8..2166763 100644 --- a/example/compress/build.sc +++ b/example/compress/build.sc @@ -4,7 +4,7 @@ import mill._, scalalib._ trait AppModule extends ScalaModule{ def scalaVersion = "2.12.6" def ivyDeps = Agg( - ivy"com.lihaoyi::cask:0.0.9", + ivy"com.lihaoyi::cask:0.1.0", ) object test extends Tests{ diff --git a/example/compress2/build.sc b/example/compress2/build.sc index 0e803b8..2166763 100644 --- a/example/compress2/build.sc +++ b/example/compress2/build.sc @@ -4,7 +4,7 @@ import mill._, scalalib._ trait AppModule extends ScalaModule{ def scalaVersion = "2.12.6" def ivyDeps = Agg( - ivy"com.lihaoyi::cask:0.0.9", + ivy"com.lihaoyi::cask:0.1.0", ) object test extends Tests{ diff --git a/example/compress3/build.sc b/example/compress3/build.sc index 0e803b8..2166763 100644 --- a/example/compress3/build.sc +++ b/example/compress3/build.sc @@ -4,7 +4,7 @@ import mill._, scalalib._ trait AppModule extends ScalaModule{ def scalaVersion = "2.12.6" def ivyDeps = Agg( - ivy"com.lihaoyi::cask:0.0.9", + ivy"com.lihaoyi::cask:0.1.0", ) object test extends Tests{ diff --git a/example/cookies/build.sc b/example/cookies/build.sc index 0e803b8..2166763 100644 --- a/example/cookies/build.sc +++ b/example/cookies/build.sc @@ -4,7 +4,7 @@ import mill._, scalalib._ trait AppModule extends ScalaModule{ def scalaVersion = "2.12.6" def ivyDeps = Agg( - ivy"com.lihaoyi::cask:0.0.9", + ivy"com.lihaoyi::cask:0.1.0", ) object test extends Tests{ diff --git a/example/decorated/build.sc b/example/decorated/build.sc index 0e803b8..2166763 100644 --- a/example/decorated/build.sc +++ b/example/decorated/build.sc @@ -4,7 +4,7 @@ import mill._, scalalib._ trait AppModule extends ScalaModule{ def scalaVersion = "2.12.6" def ivyDeps = Agg( - ivy"com.lihaoyi::cask:0.0.9", + ivy"com.lihaoyi::cask:0.1.0", ) object test extends Tests{ diff --git a/example/decorated2/build.sc b/example/decorated2/build.sc index 0e803b8..2166763 100644 --- a/example/decorated2/build.sc +++ b/example/decorated2/build.sc @@ -4,7 +4,7 @@ import mill._, scalalib._ trait AppModule extends ScalaModule{ def scalaVersion = "2.12.6" def ivyDeps = Agg( - ivy"com.lihaoyi::cask:0.0.9", + ivy"com.lihaoyi::cask:0.1.0", ) object test extends Tests{ diff --git a/example/endpoints/build.sc b/example/endpoints/build.sc index 0e803b8..2166763 100644 --- a/example/endpoints/build.sc +++ b/example/endpoints/build.sc @@ -4,7 +4,7 @@ import mill._, scalalib._ trait AppModule extends ScalaModule{ def scalaVersion = "2.12.6" def ivyDeps = Agg( - ivy"com.lihaoyi::cask:0.0.9", + ivy"com.lihaoyi::cask:0.1.0", ) object test extends Tests{ diff --git a/example/formJsonPost/build.sc b/example/formJsonPost/build.sc index 0e803b8..2166763 100644 --- a/example/formJsonPost/build.sc +++ b/example/formJsonPost/build.sc @@ -4,7 +4,7 @@ import mill._, scalalib._ trait AppModule extends ScalaModule{ def scalaVersion = "2.12.6" def ivyDeps = Agg( - ivy"com.lihaoyi::cask:0.0.9", + ivy"com.lihaoyi::cask:0.1.0", ) object test extends Tests{ diff --git a/example/httpMethods/build.sc b/example/httpMethods/build.sc index 0e803b8..2166763 100644 --- a/example/httpMethods/build.sc +++ b/example/httpMethods/build.sc @@ -4,7 +4,7 @@ import mill._, scalalib._ trait AppModule extends ScalaModule{ def scalaVersion = "2.12.6" def ivyDeps = Agg( - ivy"com.lihaoyi::cask:0.0.9", + ivy"com.lihaoyi::cask:0.1.0", ) object test extends Tests{ diff --git a/example/minimalApplication/build.sc b/example/minimalApplication/build.sc index 0e803b8..2166763 100644 --- a/example/minimalApplication/build.sc +++ b/example/minimalApplication/build.sc @@ -4,7 +4,7 @@ import mill._, scalalib._ trait AppModule extends ScalaModule{ def scalaVersion = "2.12.6" def ivyDeps = Agg( - ivy"com.lihaoyi::cask:0.0.9", + ivy"com.lihaoyi::cask:0.1.0", ) object test extends Tests{ diff --git a/example/minimalApplication2/build.sc b/example/minimalApplication2/build.sc index 0e803b8..2166763 100644 --- a/example/minimalApplication2/build.sc +++ b/example/minimalApplication2/build.sc @@ -4,7 +4,7 @@ import mill._, scalalib._ trait AppModule extends ScalaModule{ def scalaVersion = "2.12.6" def ivyDeps = Agg( - ivy"com.lihaoyi::cask:0.0.9", + ivy"com.lihaoyi::cask:0.1.0", ) object test extends Tests{ diff --git a/example/redirectAbort/build.sc b/example/redirectAbort/build.sc index 0e803b8..2166763 100644 --- a/example/redirectAbort/build.sc +++ b/example/redirectAbort/build.sc @@ -4,7 +4,7 @@ import mill._, scalalib._ trait AppModule extends ScalaModule{ def scalaVersion = "2.12.6" def ivyDeps = Agg( - ivy"com.lihaoyi::cask:0.0.9", + ivy"com.lihaoyi::cask:0.1.0", ) object test extends Tests{ diff --git a/example/scalatags/build.sc b/example/scalatags/build.sc index 31bf5f6..d517c6b 100644 --- a/example/scalatags/build.sc +++ b/example/scalatags/build.sc @@ -4,7 +4,7 @@ import mill._, scalalib._ trait AppModule extends ScalaModule{ def scalaVersion = "2.12.6" def ivyDeps = Agg( - ivy"com.lihaoyi::cask:0.0.9", + ivy"com.lihaoyi::cask:0.1.0", ivy"com.lihaoyi::scalatags:0.6.7", ) diff --git a/example/staticFiles/app/resources/cask/example.txt b/example/staticFiles/app/resources/cask/example.txt new file mode 100644 index 0000000..5184576 --- /dev/null +++ b/example/staticFiles/app/resources/cask/example.txt @@ -0,0 +1 @@ +the quick brown fox jumps over the lazy dog \ No newline at end of file diff --git a/example/staticFiles/app/src/StaticFiles.scala b/example/staticFiles/app/src/StaticFiles.scala index 4da9805..e47f0a1 100644 --- a/example/staticFiles/app/src/StaticFiles.scala +++ b/example/staticFiles/app/src/StaticFiles.scala @@ -5,8 +5,11 @@ object StaticFiles extends cask.MainRoutes{ "Hello!" } - @cask.static("/static") - def staticRoutes() = "cask/test/resources/cask" + @cask.staticFiles("/static/file") + def staticFileRoutes() = "app/resources/cask" + + @cask.staticResources("/static/resource") + def staticResourceRoutes() = "cask" initialize() } diff --git a/example/staticFiles/app/test/src/ExampleTests.scala b/example/staticFiles/app/test/src/ExampleTests.scala index ddf7de3..c60f443 100644 --- a/example/staticFiles/app/test/src/ExampleTests.scala +++ b/example/staticFiles/app/test/src/ExampleTests.scala @@ -19,7 +19,10 @@ object ExampleTests extends TestSuite{ val tests = Tests{ 'StaticFiles - test(StaticFiles){ host => - requests.get(s"$host/static/example.txt").text() ==> + requests.get(s"$host/static/file/example.txt").text() ==> + "the quick brown fox jumps over the lazy dog" + + requests.get(s"$host/static/resource/example.txt").text() ==> "the quick brown fox jumps over the lazy dog" } diff --git a/example/staticFiles/build.sc b/example/staticFiles/build.sc index 0e803b8..00a7ee3 100644 --- a/example/staticFiles/build.sc +++ b/example/staticFiles/build.sc @@ -4,9 +4,11 @@ import mill._, scalalib._ trait AppModule extends ScalaModule{ def scalaVersion = "2.12.6" def ivyDeps = Agg( - ivy"com.lihaoyi::cask:0.0.9", + ivy"com.lihaoyi::cask:0.1.0", ) + def forkWorkingDir = build.millSourcePath + object test extends Tests{ def testFrameworks = Seq("utest.runner.Framework") @@ -14,5 +16,12 @@ trait AppModule extends ScalaModule{ ivy"com.lihaoyi::utest::0.6.3", ivy"com.lihaoyi::requests::0.1.2", ) + + def forkWorkingDir = build.millSourcePath + + // redirect this to the forked `test` to make sure static file serving works + def testLocal(args: String*) = T.command{ + test(args:_*) + } } } \ No newline at end of file diff --git a/example/todo/app/src/TodoServer.scala b/example/todo/app/src/TodoServer.scala index bfe4ea0..1a768d1 100644 --- a/example/todo/app/src/TodoServer.scala +++ b/example/todo/app/src/TodoServer.scala @@ -173,8 +173,8 @@ object TodoServer extends cask.MainRoutes{ ) } - @cask.static("/static") - def static() = "example/todo/resources/todo" + @cask.staticResources("/static") + def static() = "todo" initialize() } diff --git a/example/todo/build.sc b/example/todo/build.sc index c8cbe8e..ca0716a 100644 --- a/example/todo/build.sc +++ b/example/todo/build.sc @@ -4,7 +4,7 @@ import mill._, scalalib._ trait AppModule extends ScalaModule{ def scalaVersion = "2.12.6" def ivyDeps = Agg( - ivy"com.lihaoyi::cask:0.0.9", + ivy"com.lihaoyi::cask:0.1.0", ivy"org.xerial:sqlite-jdbc:3.18.0", ivy"io.getquill::quill-jdbc:2.5.4", ivy"com.lihaoyi::scalatags:0.6.7", diff --git a/example/todoApi/build.sc b/example/todoApi/build.sc index 0e803b8..2166763 100644 --- a/example/todoApi/build.sc +++ b/example/todoApi/build.sc @@ -4,7 +4,7 @@ import mill._, scalalib._ trait AppModule extends ScalaModule{ def scalaVersion = "2.12.6" def ivyDeps = Agg( - ivy"com.lihaoyi::cask:0.0.9", + ivy"com.lihaoyi::cask:0.1.0", ) object test extends Tests{ diff --git a/example/todoDb/build.sc b/example/todoDb/build.sc index 55e7b40..046e2e1 100644 --- a/example/todoDb/build.sc +++ b/example/todoDb/build.sc @@ -4,7 +4,7 @@ import mill._, scalalib._ trait AppModule extends ScalaModule{ def scalaVersion = "2.12.6" def ivyDeps = Agg( - ivy"com.lihaoyi::cask:0.0.9", + ivy"com.lihaoyi::cask:0.1.0", ivy"org.xerial:sqlite-jdbc:3.18.0", ivy"io.getquill::quill-jdbc:2.5.4" ) diff --git a/example/variableRoutes/build.sc b/example/variableRoutes/build.sc index 0e803b8..2166763 100644 --- a/example/variableRoutes/build.sc +++ b/example/variableRoutes/build.sc @@ -4,7 +4,7 @@ import mill._, scalalib._ trait AppModule extends ScalaModule{ def scalaVersion = "2.12.6" def ivyDeps = Agg( - ivy"com.lihaoyi::cask:0.0.9", + ivy"com.lihaoyi::cask:0.1.0", ) object test extends Tests{ diff --git a/example/websockets/build.sc b/example/websockets/build.sc index 561c652..96991eb 100644 --- a/example/websockets/build.sc +++ b/example/websockets/build.sc @@ -4,7 +4,7 @@ import mill._, scalalib._ trait AppModule extends ScalaModule{ def scalaVersion = "2.12.6" def ivyDeps = Agg( - ivy"com.lihaoyi::cask:0.0.9", + ivy"com.lihaoyi::cask:0.1.0", ) object test extends Tests{ -- cgit v1.2.3