From 316fab29c7a87e89fa253fd09504b8b54b66911e Mon Sep 17 00:00:00 2001 From: Jean Helou Date: Wed, 13 Feb 2019 23:29:33 +0100 Subject: switch to T.sources for the routesFiles setting --- .../playlib/api/src/RouteCompilerWorkerApi.scala | 2 +- .../src/mill/playlib/RouteCompilerWorkerApi.scala | 7 +- .../playlib/src/mill/playlib/RouterModule.scala | 29 ++++++-- .../test/resources/hello-world/core/conf/routes | 1 + .../resources/hello-world/core/conf/sub.routes | 2 + .../test/resources/invalid/core/conf/routes | 3 +- .../test/resources/invalidsub/core/conf/routes | 4 ++ .../test/resources/invalidsub/core/conf/sub.routes | 3 + .../test/src/mill/playlib/HelloWorldTests.scala | 21 ++++-- .../worker/2.6.0/src/RouteCompilerWorker.scala | 77 +++++++++++++++------- .../worker/2.7.0/src/RouteCompilerWorker.scala | 27 ++++++-- 11 files changed, 135 insertions(+), 41 deletions(-) create mode 100644 contrib/playlib/test/resources/hello-world/core/conf/sub.routes create mode 100644 contrib/playlib/test/resources/invalidsub/core/conf/routes create mode 100644 contrib/playlib/test/resources/invalidsub/core/conf/sub.routes (limited to 'contrib') diff --git a/contrib/playlib/api/src/RouteCompilerWorkerApi.scala b/contrib/playlib/api/src/RouteCompilerWorkerApi.scala index 0467b774..447dfa46 100644 --- a/contrib/playlib/api/src/RouteCompilerWorkerApi.scala +++ b/contrib/playlib/api/src/RouteCompilerWorkerApi.scala @@ -8,7 +8,7 @@ import mill.scalalib.api.CompilationResult trait RouteCompilerWorkerApi { - def compile(file: Path, + def compile(files: Seq[Path], additionalImports: Seq[String], forwardsRouter: Boolean, reverseRouter: Boolean, diff --git a/contrib/playlib/src/mill/playlib/RouteCompilerWorkerApi.scala b/contrib/playlib/src/mill/playlib/RouteCompilerWorkerApi.scala index 6e9f68ed..6be0f3f6 100644 --- a/contrib/playlib/src/mill/playlib/RouteCompilerWorkerApi.scala +++ b/contrib/playlib/src/mill/playlib/RouteCompilerWorkerApi.scala @@ -35,7 +35,7 @@ class RouteCompilerWorker { def compile(routerClasspath: Agg[Path], - file: Path, + files: Seq[Path], additionalImports: Seq[String], forwardsRouter: Boolean, reverseRouter: Boolean, @@ -43,9 +43,11 @@ class RouteCompilerWorker { generatorType: RouteCompilerType, dest: Path)(implicit ctx: Ctx) : Result[CompilationResult] = { + //the routes file must come last as it can include the routers generated + //by the others bridge(routerClasspath) .compile( - file, + files, additionalImports, forwardsRouter, reverseRouter, @@ -56,6 +58,7 @@ class RouteCompilerWorker { } + } object RouteCompilerWorkerModule extends ExternalModule { diff --git a/contrib/playlib/src/mill/playlib/RouterModule.scala b/contrib/playlib/src/mill/playlib/RouterModule.scala index ac1f71ff..a1dce169 100644 --- a/contrib/playlib/src/mill/playlib/RouterModule.scala +++ b/contrib/playlib/src/mill/playlib/RouterModule.scala @@ -7,6 +7,7 @@ import mill.playlib.api.RouteCompilerType import mill.scalalib.Lib.resolveDependencies import mill.scalalib._ import mill.scalalib.api._ +import os.Path trait RouterModule extends mill.Module with ScalaModule { @@ -16,7 +17,9 @@ trait RouterModule extends mill.Module with ScalaModule { */ def playVersion: T[String] - override def generatedSources = T{ super.generatedSources() ++ Seq(compileRouter().classes) } + override def generatedSources = T { + super.generatedSources() ++ Seq(compileRouter().classes) + } /** * The [[PathRef]] to the main routes file. @@ -24,11 +27,22 @@ trait RouterModule extends mill.Module with ScalaModule { * This is the default path for play projects and it should be fine but you * can override it if needed. */ - def routesFile: T[PathRef] = T { - val routesPath = millSourcePath / "conf" / "routes" - PathRef(routesPath) + def routesDirectory = T.sources { + millSourcePath / "conf" + } + + private def routesFiles = T { + val files = routesDirectory() + locateFilesBy(files, _.last.endsWith(".routes")) ++ locateFilesBy(files, _.last == "routes") } + private def locateFilesBy(files: Seq[PathRef], p: Path => Boolean) = { + files.flatMap(file => { + os.walk(file.path).filter(p).map(f => PathRef(f)) + }) + } + + /** * A [[Seq]] of additional imports to be added to the routes file. * Defaults to : @@ -51,9 +65,10 @@ trait RouterModule extends mill.Module with ScalaModule { /** * The routes compiler type to be used. Can only be one of: * + * * @return */ def generatorType: RouteCompilerType = RouteCompilerType.InjectedGenerator @@ -75,7 +90,7 @@ trait RouterModule extends mill.Module with ScalaModule { T.ctx().log.debug(s"compiling play routes with ${playVersion()} worker") RouteCompilerWorkerModule.routeCompilerWorker().compile( toolsClasspath().map(_.path), - routesFile().path, + routesFiles().map(_.path), routesAdditionalImport, generateForwardsRouter, generateReverseRouter, diff --git a/contrib/playlib/test/resources/hello-world/core/conf/routes b/contrib/playlib/test/resources/hello-world/core/conf/routes index 7d5e5498..f71b0cdd 100644 --- a/contrib/playlib/test/resources/hello-world/core/conf/routes +++ b/contrib/playlib/test/resources/hello-world/core/conf/routes @@ -1,2 +1,3 @@ GET / controllers.HomeController.index GET /assets/*file controllers.Assets.versioned(path="/public", file: Asset) +-> /sub sub.Routes \ No newline at end of file diff --git a/contrib/playlib/test/resources/hello-world/core/conf/sub.routes b/contrib/playlib/test/resources/hello-world/core/conf/sub.routes new file mode 100644 index 00000000..4597a19b --- /dev/null +++ b/contrib/playlib/test/resources/hello-world/core/conf/sub.routes @@ -0,0 +1,2 @@ +GET / controllers.SubController.index +GET /assets/*file controllers.Assets.versioned(path="/public/sub", file: Asset) diff --git a/contrib/playlib/test/resources/invalid/core/conf/routes b/contrib/playlib/test/resources/invalid/core/conf/routes index 1b31139f..5c946fc6 100644 --- a/contrib/playlib/test/resources/invalid/core/conf/routes +++ b/contrib/playlib/test/resources/invalid/core/conf/routes @@ -1,3 +1,4 @@ GET / controllers.HomeController.index -BOB =error controllers.HomeController.error(foo) +-> /sub sub.Routes GET /assets/*file controllers.Assets.versioned(path="/public", file: Asset) +BOB =error controllers.HomeController.error(foo) \ No newline at end of file diff --git a/contrib/playlib/test/resources/invalidsub/core/conf/routes b/contrib/playlib/test/resources/invalidsub/core/conf/routes new file mode 100644 index 00000000..5c946fc6 --- /dev/null +++ b/contrib/playlib/test/resources/invalidsub/core/conf/routes @@ -0,0 +1,4 @@ +GET / controllers.HomeController.index +-> /sub sub.Routes +GET /assets/*file controllers.Assets.versioned(path="/public", file: Asset) +BOB =error controllers.HomeController.error(foo) \ No newline at end of file diff --git a/contrib/playlib/test/resources/invalidsub/core/conf/sub.routes b/contrib/playlib/test/resources/invalidsub/core/conf/sub.routes new file mode 100644 index 00000000..9c844a4a --- /dev/null +++ b/contrib/playlib/test/resources/invalidsub/core/conf/sub.routes @@ -0,0 +1,3 @@ +GET / controllers.SubController.index +GET /assets/*file controllers.Assets.versioned(path="/public/sub", file: Asset) +BOB =error controllers.HomeController.error(foo) \ No newline at end of file diff --git a/contrib/playlib/test/src/mill/playlib/HelloWorldTests.scala b/contrib/playlib/test/src/mill/playlib/HelloWorldTests.scala index 71ee6c4d..20e8ce55 100644 --- a/contrib/playlib/test/src/mill/playlib/HelloWorldTests.scala +++ b/contrib/playlib/test/src/mill/playlib/HelloWorldTests.scala @@ -32,6 +32,7 @@ object HelloWorldTests extends TestSuite { val resourcePath: Path = pwd / 'contrib / 'playlib / 'test / 'resources / "hello-world" val invalidResourcePath: Path = pwd / 'contrib / 'playlib / 'test / 'resources / "invalid" + val invalidSubResourcePath: Path = pwd / 'contrib / 'playlib / 'test / 'resources / "invalidsub" def workspaceTest[T, M <: TestUtil.BaseModule](m: M, resourcePath: Path = resourcePath) (t: TestEvaluator => T) @@ -65,6 +66,8 @@ object HelloWorldTests extends TestSuite { RelPath("controllers/routes.java"), RelPath("router/Routes.scala"), RelPath("router/RoutesPrefix.scala"), + RelPath("sub/Routes.scala"), + RelPath("sub/RoutesPrefix.scala"), RelPath("controllers/javascript/JavaScriptReverseRoutes.scala") ).map( eval.outPath / 'core / 'compileRouter / 'dest / _ @@ -73,7 +76,7 @@ object HelloWorldTests extends TestSuite { result.classes.path == eval.outPath / 'core / 'compileRouter / 'dest, outputFiles.nonEmpty, outputFiles.forall(expectedClassfiles.contains), - outputFiles.size == 5, + outputFiles.size == 7, evalCount > 0 ) @@ -85,9 +88,19 @@ object HelloWorldTests extends TestSuite { 'compileRouter - workspaceTest(HelloWorld, resourcePath = invalidResourcePath) { eval => val eitherResult = eval.apply(HelloWorld.core.compileRouter) val Left(Failure(message, x)) = eitherResult - val expectedMessage = "Unable to compile play routes, compilation error in " + - HelloWorld.millSourcePath.toIO.getAbsolutePath + "/core/conf/routes at line 2, column 1: " + - "HTTP Verb (GET, POST, ...), include (->), comment (#), or modifier line (+) expected" + val expectedMessage = "Unable to compile play routes\ncompilation error in " + + HelloWorld.millSourcePath.toIO.getAbsolutePath + "/core/conf/routes at line 4, column" + + " 1: HTTP Verb (GET, POST, ...), include (->), comment (#), or modifier line (+) expected" + assert( + message == expectedMessage + ) + } + 'compileRouter - workspaceTest(HelloWorld, resourcePath = invalidSubResourcePath) { eval => + val eitherResult = eval.apply(HelloWorld.core.compileRouter) + val Left(Failure(message, x)) = eitherResult + val expectedMessage = "Unable to compile play routes\ncompilation error in " + + HelloWorld.millSourcePath.toIO.getAbsolutePath + "/core/conf/sub.routes at line 3, column" + + " 1: HTTP Verb (GET, POST, ...), include (->), comment (#), or modifier line (+) expected" assert( message == expectedMessage ) diff --git a/contrib/playlib/worker/2.6.0/src/RouteCompilerWorker.scala b/contrib/playlib/worker/2.6.0/src/RouteCompilerWorker.scala index f46f8c7b..be911af8 100644 --- a/contrib/playlib/worker/2.6.0/src/RouteCompilerWorker.scala +++ b/contrib/playlib/worker/2.6.0/src/RouteCompilerWorker.scala @@ -5,33 +5,65 @@ package worker import java.io.File import ammonite.ops.Path -import mill.api.Result +import mill.api.{Ctx, Result} import mill.eval.PathRef import mill.playlib.api.{RouteCompilerType, RouteCompilerWorkerApi} import mill.scalalib.api.CompilationResult +import play.routes.compiler import play.routes.compiler.RoutesCompiler.RoutesCompilerTask -import play.routes.compiler.{InjectedRoutesGenerator, RoutesCompiler, StaticRoutesGenerator} +import play.routes.compiler._ class RouteCompilerWorker extends RouteCompilerWorkerApi { - override def compile( - file: Path, - additionalImports: Seq[String], - forwardsRouter: Boolean, - reverseRouter: Boolean, - namespaceReverseRouter: Boolean, - generatorType: RouteCompilerType, - dest: Path) + override def compile(files: Seq[Path], + additionalImports: Seq[String], + forwardsRouter: Boolean, + reverseRouter: Boolean, + namespaceReverseRouter: Boolean, + generatorType: RouteCompilerType, + dest: Path) (implicit ctx: mill.api.Ctx): mill.api.Result[CompilationResult] = { - val routesGenerator = generatorType match { - case RouteCompilerType.InjectedGenerator => InjectedRoutesGenerator + generatorType match { + case RouteCompilerType.InjectedGenerator => + val result = compileWithPlay(files, additionalImports, forwardsRouter, reverseRouter, + namespaceReverseRouter, dest, ctx, InjectedRoutesGenerator) + asMillResult(ctx, result) case RouteCompilerType.StaticGenerator => ctx.log.error("Static generator was deprecated in 2.6.0 and will be removed in 2.7.0") - StaticRoutesGenerator + val result = compileWithPlay(files, additionalImports, forwardsRouter, reverseRouter, + namespaceReverseRouter, dest, ctx, StaticRoutesGenerator) + asMillResult(ctx, result) case _ => throw new Exception(s"Unrecognized generator type: $generatorType. Use injected or static") } - ctx.log.debug(s"compiling file $file with generator $generatorType") + } + + private def compileWithPlay(files: Seq[Path], + additionalImports: Seq[String], + forwardsRouter: Boolean, + reverseRouter: Boolean, + namespaceReverseRouter: Boolean, + dest: Path, + ctx: Ctx, + routesGenerator: RoutesGenerator): Either[Seq[compiler.RoutesCompilationError], Seq[File]] = { + val seed: Either[Seq[compiler.RoutesCompilationError], List[File]] = Right(List.empty[File]) + files.map(file => compileWithPlay(file, additionalImports, forwardsRouter, reverseRouter, + namespaceReverseRouter, dest, ctx, routesGenerator)).foldLeft(seed) { + case (Right(accFiles), Right(files)) => Right(accFiles ++ files) + case (Right(accFiles), Left(errors)) => Left(errors) + case (left@Left(errors), _) => left + } + } + + private def compileWithPlay(file: Path, + additionalImports: Seq[String], + forwardsRouter: Boolean, + reverseRouter: Boolean, + namespaceReverseRouter: Boolean, + dest: Path, + ctx: Ctx, + routesGenerator: RoutesGenerator): Either[Seq[compiler.RoutesCompilationError], Seq[File]] = { + ctx.log.debug(s"compiling $file with play generator $routesGenerator") val result = RoutesCompiler.compile( RoutesCompilerTask(file.toIO, additionalImports, forwardsRouter, reverseRouter, @@ -39,20 +71,21 @@ class RouteCompilerWorker extends RouteCompilerWorkerApi { generator = routesGenerator, generatedDir = dest.toIO ) - ctx.log.debug("compilation result:" + result) + ctx.log.debug(s"compilation result: $result") + result + } + + private def asMillResult(ctx: Ctx, result: Either[Seq[RoutesCompilationError], Seq[File]]): Result[CompilationResult] = { result match { case Right(_) => val zincFile = ctx.dest / 'zinc Result.Success(CompilationResult(zincFile, PathRef(ctx.dest))) case Left(errors) => val errorMsg = errors.map(error => - s"compilation error in ${error.source.getPath} at line ${error.line.getOrElse("?")}," + - s" column ${error.column.getOrElse("?")}: ${error.message}".stripMargin) + s"compilation error in ${error.source.getPath} at line ${error.line.getOrElse("?")}, " + + s"column ${error.column.getOrElse("?")}: ${error.message}") .mkString("\n") - Result.Failure("Unable to compile play routes, " + errorMsg) + Result.Failure("Unable to compile play routes\n" + errorMsg) } } -} - - -case class RoutesCompilationError(source: File, message: String, line: Option[Int], column: Option[Int]) \ No newline at end of file +} \ No newline at end of file diff --git a/contrib/playlib/worker/2.7.0/src/RouteCompilerWorker.scala b/contrib/playlib/worker/2.7.0/src/RouteCompilerWorker.scala index 99e2b493..616ab943 100644 --- a/contrib/playlib/worker/2.7.0/src/RouteCompilerWorker.scala +++ b/contrib/playlib/worker/2.7.0/src/RouteCompilerWorker.scala @@ -9,13 +9,14 @@ import mill.api.{Ctx, Result} import mill.eval.PathRef import mill.playlib.api.{RouteCompilerType, RouteCompilerWorkerApi} import mill.scalalib.api.CompilationResult +import play.routes.compiler import play.routes.compiler.RoutesCompiler.RoutesCompilerTask import play.routes.compiler.{InjectedRoutesGenerator, RoutesCompilationError, RoutesCompiler, RoutesGenerator} class RouteCompilerWorker extends RouteCompilerWorkerApi { - override def compile(file: Path, + override def compile(files: Seq[Path], additionalImports: Seq[String], forwardsRouter: Boolean, reverseRouter: Boolean, @@ -25,7 +26,7 @@ class RouteCompilerWorker extends RouteCompilerWorkerApi { (implicit ctx: mill.api.Ctx): mill.api.Result[CompilationResult] = { generatorType match { case RouteCompilerType.InjectedGenerator => - val result = compileWithPlay(file, additionalImports, forwardsRouter, reverseRouter, + val result = compileWithPlay(files, additionalImports, forwardsRouter, reverseRouter, namespaceReverseRouter, dest, ctx, InjectedRoutesGenerator) asMillResult(ctx, result) case RouteCompilerType.StaticGenerator => @@ -36,6 +37,23 @@ class RouteCompilerWorker extends RouteCompilerWorkerApi { // the following code is duplicated between play worker versions because it depends on play types // which are not guaranteed to stay the same between versions even though they are currently // identical + private def compileWithPlay(files: Seq[Path], + additionalImports: Seq[String], + forwardsRouter: Boolean, + reverseRouter: Boolean, + namespaceReverseRouter: Boolean, + dest: Path, + ctx: Ctx, + routesGenerator: RoutesGenerator): Either[Seq[compiler.RoutesCompilationError], Seq[File]] = { + val seed: Either[Seq[compiler.RoutesCompilationError], List[File]] = Right(List.empty[File]) + files.map(file => compileWithPlay(file, additionalImports, forwardsRouter, reverseRouter, + namespaceReverseRouter, dest, ctx, routesGenerator)).foldLeft(seed) { + case (Right(accFiles), Right(files)) => Right(accFiles ++ files) + case (Right(accFiles), Left(errors)) => Left(errors) + case (left@Left(errors), _) => left + } + } + private def compileWithPlay(file: Path, additionalImports: Seq[String], forwardsRouter: Boolean, reverseRouter: Boolean, namespaceReverseRouter: Boolean, dest: Path, ctx: Ctx, routesGenerator: RoutesGenerator) = { ctx.log.debug(s"compiling file $file with play generator $routesGenerator") val result = @@ -56,9 +74,10 @@ class RouteCompilerWorker extends RouteCompilerWorkerApi { Result.Success(CompilationResult(zincFile, PathRef(ctx.dest))) case Left(errors) => val errorMsg = errors.map(error => - s"""compilation error in ${error.source.getName} at line${error.line}, column ${error.column}: ${error.message}"""") + s"compilation error in ${error.source.getPath} at line ${error.line.getOrElse("?")}, " + + s"column ${error.column.getOrElse("?")}: ${error.message}") .mkString("\n") - Result.Failure("Unable to compile play routes" + errorMsg) + Result.Failure("Unable to compile play routes, " + errorMsg) } } } \ No newline at end of file -- cgit v1.2.3