Skip to content

Commit

Permalink
implement resource generators
Browse files Browse the repository at this point in the history
  • Loading branch information
bishabosha committed Apr 14, 2023
1 parent b2c81c4 commit 8ce459c
Show file tree
Hide file tree
Showing 12 changed files with 623 additions and 125 deletions.
58 changes: 58 additions & 0 deletions examples/full-stack-app/core-js.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
{
"scalaVersion": "3.2.2",
"platform": "JS",
"scalaJsVersion": "1.13.0",
"scopes": {
"main": {
"sources": [
"project.scala",
"src/main/scala/example/Macros.scala",
"src/main/scala/example/Note.scala"
],
"dependencies": [
{
"groupId": "com.lihaoyi",
"artifactId": {
"name": "upickle_sjs1",
"fullName": "upickle_sjs1_3"
},
"version": "3.1.0"
}
],
"resolvers": [
"https://repo1.maven.org/maven2",
"ivy:file:///Users/jamie/Library/Caches/ScalaCli/local-repo/v1.0.0-RC1-22-57a8dc//[organisation]/[module]/(scala_[scalaVersion]/)(sbt_[sbtVersion]/)[revision]/[type]s/[artifact](-[classifier]).[ext]",
"ivy:file:/Users/jamie/.ivy2/local/[organisation]/[module]/(scala_[scalaVersion]/)(sbt_[sbtVersion]/)[revision]/[type]s/[artifact](-[classifier]).[ext]"
]
},
"test": {
"sources": [
"project.test.scala",
"src/test/scala/example/JsonParsingSpec.scala"
],
"dependencies": [
{
"groupId": "com.lihaoyi",
"artifactId": {
"name": "upickle_sjs1",
"fullName": "upickle_sjs1_3"
},
"version": "3.1.0"
},
{
"groupId": "org.scalameta",
"artifactId": {
"name": "munit_sjs1",
"fullName": "munit_sjs1_3"
},
"version": "1.0.0-M7"
}
],
"resolvers": [
"https://repo1.maven.org/maven2",
"ivy:file:///Users/jamie/Library/Caches/ScalaCli/local-repo/v1.0.0-RC1-22-57a8dc//[organisation]/[module]/(scala_[scalaVersion]/)(sbt_[sbtVersion]/)[revision]/[type]s/[artifact](-[classifier]).[ext]",
"ivy:file:/Users/jamie/.ivy2/local/[organisation]/[module]/(scala_[scalaVersion]/)(sbt_[sbtVersion]/)[revision]/[type]s/[artifact](-[classifier]).[ext]"
]
}
}
}
57 changes: 57 additions & 0 deletions examples/full-stack-app/core-jvm.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
{
"scalaVersion": "3.2.2",
"platform": "JVM",
"scopes": {
"main": {
"sources": [
"project.scala",
"src/main/scala/example/Macros.scala",
"src/main/scala/example/Note.scala"
],
"dependencies": [
{
"groupId": "com.lihaoyi",
"artifactId": {
"name": "upickle",
"fullName": "upickle_3"
},
"version": "3.1.0"
}
],
"resolvers": [
"https://repo1.maven.org/maven2",
"ivy:file:///Users/jamie/Library/Caches/ScalaCli/local-repo/v1.0.0-RC1-22-57a8dc//[organisation]/[module]/(scala_[scalaVersion]/)(sbt_[sbtVersion]/)[revision]/[type]s/[artifact](-[classifier]).[ext]",
"ivy:file:/Users/jamie/.ivy2/local/[organisation]/[module]/(scala_[scalaVersion]/)(sbt_[sbtVersion]/)[revision]/[type]s/[artifact](-[classifier]).[ext]"
]
},
"test": {
"sources": [
"project.test.scala",
"src/test/scala/example/JsonParsingSpec.scala"
],
"dependencies": [
{
"groupId": "com.lihaoyi",
"artifactId": {
"name": "upickle",
"fullName": "upickle_3"
},
"version": "3.1.0"
},
{
"groupId": "org.scalameta",
"artifactId": {
"name": "munit",
"fullName": "munit_3"
},
"version": "1.0.0-M7"
}
],
"resolvers": [
"https://repo1.maven.org/maven2",
"ivy:file:///Users/jamie/Library/Caches/ScalaCli/local-repo/v1.0.0-RC1-22-57a8dc//[organisation]/[module]/(scala_[scalaVersion]/)(sbt_[sbtVersion]/)[revision]/[type]s/[artifact](-[classifier]).[ext]",
"ivy:file:/Users/jamie/.ivy2/local/[organisation]/[module]/(scala_[scalaVersion]/)(sbt_[sbtVersion]/)[revision]/[type]s/[artifact](-[classifier]).[ext]"
]
}
}
}
30 changes: 30 additions & 0 deletions examples/full-stack-app/webpage.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
{
"scalaVersion": "3.2.2",
"platform": "JS",
"scalaJsVersion": "1.13.0",
"scopes": {
"main": {
"sources": [
"src/main/scala/example/DomHelper.scala",
"src/main/scala/example/HttpClient.scala",
"src/main/scala/example/WebPage.scala",
"src/main/scala/project.scala"
],
"dependencies": [
{
"groupId": "org.scala-js",
"artifactId": {
"name": "scalajs-dom_sjs1",
"fullName": "scalajs-dom_sjs1_3"
},
"version": "2.4.0"
}
],
"resolvers": [
"https://repo1.maven.org/maven2",
"ivy:file:///Users/jamie/Library/Caches/ScalaCli/local-repo/v1.0.0-RC1-22-57a8dc//[organisation]/[module]/(scala_[scalaVersion]/)(sbt_[sbtVersion]/)[revision]/[type]s/[artifact](-[classifier]).[ext]",
"ivy:file:/Users/jamie/.ivy2/local/[organisation]/[module]/(scala_[scalaVersion]/)(sbt_[sbtVersion]/)[revision]/[type]s/[artifact](-[classifier]).[ext]"
]
}
}
}
81 changes: 81 additions & 0 deletions examples/full-stack-app/webserver.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
{
"scalaVersion": "3.2.2",
"platform": "JVM",
"scopes": {
"main": {
"sources": [
"project.scala",
"src/main/scala/caskx/restApi/endpoints.scala",
"src/main/scala/caskx/websocketApi/actors.scala",
"src/main/scala/example/Repository.scala",
"src/main/scala/example/WebServer.scala"
],
"dependencies": [
{
"groupId": "com.lihaoyi",
"artifactId": {
"name": "cask",
"fullName": "cask_3"
},
"version": "0.9.1"
},
{
"groupId": "com.lihaoyi",
"artifactId": {
"name": "os-lib",
"fullName": "os-lib_3"
},
"version": "0.9.1"
}
],
"resolvers": [
"https://repo1.maven.org/maven2",
"ivy:file:///Users/jamie/Library/Caches/ScalaCli/local-repo/v1.0.0-RC1-22-57a8dc//[organisation]/[module]/(scala_[scalaVersion]/)(sbt_[sbtVersion]/)[revision]/[type]s/[artifact](-[classifier]).[ext]",
"ivy:file:/Users/jamie/.ivy2/local/[organisation]/[module]/(scala_[scalaVersion]/)(sbt_[sbtVersion]/)[revision]/[type]s/[artifact](-[classifier]).[ext]"
],
"resourcesDirs": [
"/Users/jamie/workspace/scala3-full-stack-example/webserver/src/main/resources"
]
},
"test": {
"sources": [
"project.test.scala",
"src/test/scala/example/RepsitorySpec.scala"
],
"dependencies": [
{
"groupId": "com.lihaoyi",
"artifactId": {
"name": "cask",
"fullName": "cask_3"
},
"version": "0.9.1"
},
{
"groupId": "com.lihaoyi",
"artifactId": {
"name": "os-lib",
"fullName": "os-lib_3"
},
"version": "0.9.1"
},
{
"groupId": "org.scalameta",
"artifactId": {
"name": "munit",
"fullName": "munit_3"
},
"version": "1.0.0-M7"
}
],
"resolvers": [
"https://repo1.maven.org/maven2",
"ivy:file:///Users/jamie/Library/Caches/ScalaCli/local-repo/v1.0.0-RC1-22-57a8dc//[organisation]/[module]/(scala_[scalaVersion]/)(sbt_[sbtVersion]/)[revision]/[type]s/[artifact](-[classifier]).[ext]",
"ivy:file:/Users/jamie/.ivy2/local/[organisation]/[module]/(scala_[scalaVersion]/)(sbt_[sbtVersion]/)[revision]/[type]s/[artifact](-[classifier]).[ext]"
],
"resourcesDirs": [
"/Users/jamie/workspace/scala3-full-stack-example/webserver/src/main/resources"
]
}
}
}
59 changes: 53 additions & 6 deletions modules/scala-builder/src/main/scala/builder/Config.scala
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package builder

import toml.Value.*
import upickle.default.Writer
import upickle.default.*
import builder.errors.*

object Config:
Expand Down Expand Up @@ -37,6 +37,16 @@ object Config:
case Str(value) => value
case _ => failure(s"modules.${key}.kind must be a string")
}).getOrElse("library")
val platforms = values.get("platforms").map({
case Arr(values) => values.map({
case Str(value) => PlatformKind.lookup(value) match
case None => failure(s"unknown platform for modules.${key}.platforms: $value")
case Some(platform) => platform

case _ => failure(s"modules.${key}.platforms must be a list of strings")
})
case _ => failure(s"modules.${key}.platforms must be a list of strings")
}).getOrElse(List(PlatformKind.jvm))
val dependsOn = values.get("dependsOn").map({
case Arr(values) => values.map({
case Str(value) => value
Expand All @@ -54,27 +64,64 @@ object Config:
case _ => failure(s"unknown module kind for modules.${key}.kind: $kind")
if !moduleKind.isInstanceOf[ModuleKind.Application] && mainClass.nonEmpty then
failure(s"modules.${key}.mainClass is only valid for application modules")
// resourceGenerators = [{ module = "webpage", dest = "assets/main.js" }]
val resourceGenerators = values.get("resourceGenerators").map({
case Arr(values) => values.map(readResourceGenerator(key, _).?)
case _ => failure(s"modules.${key}.resourceGenerators must be a list of tables")
}).getOrElse(Nil)
Module(
name = key,
root = root,
platforms = platforms,
kind = moduleKind,
dependsOn = dependsOn
dependsOn = dependsOn,
resourceGenerators = resourceGenerators
)
case _ =>
failure(s"module.$key must be a table")
end readModule

private def readResourceGenerator[T](module: String, value: toml.Value): Result[ResourceGenerator, String] = Result:
value match
case Tbl(values) =>
val fromModule = values.get("module").map({
case Str(value) => value
case _ => failure(s"modules.${module}.resourceGenerators.module must be a string")
}).getOrElse(failure(s"modules.${module}.resourceGenerators.module must be a string"))
val dest = values.get("dest").map({
case Str(value) => value
case _ => failure(s"modules.${module}.resourceGenerators.dest must be a string")
}).getOrElse(failure(s"modules.${module}.resourceGenerators.dest must be a string"))
val target = targets.Target(fromModule, targets.TargetKind.Package)
ResourceGenerator.Copy(target = target, dest = dest)
case _ => failure(s"modules.${module}.resourceGenerators must be a list of tables")
end readResourceGenerator

case class Config(
scalaVersion: Option[String] = None,
modules: Map[String, Module] = Map.empty
) derives Writer
) derives ReadWriter

case class Module(
name: String,
root: String,
platforms: List[PlatformKind] = List(PlatformKind.`jvm`),
kind: ModuleKind = ModuleKind.Library,
dependsOn: List[String] = Nil
) derives Writer
dependsOn: List[String] = Nil,
resourceGenerators: List[ResourceGenerator] = Nil
) derives ReadWriter

enum PlatformKind derives ReadWriter:
case `jvm`, `scala-js`, `scala-native`

enum ModuleKind derives Writer:
object PlatformKind:
private val byName = values.view.map(kind => kind.toString -> kind).toMap

def lookup(str: String): Option[PlatformKind] = byName.get(str)

enum ModuleKind derives ReadWriter:
case Library
case Application(mainClass: Option[String])

enum ResourceGenerator derives ReadWriter:
case Copy(target: targets.Target, dest: String)
10 changes: 9 additions & 1 deletion modules/scala-builder/src/main/scala/builder/ScalaCommand.scala
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,13 @@ object ScalaCommand:

enum InternalCommand extends CommandReader:
case ExportJson, Compile
case Package(output: os.Path)

def commandString(module: Module)(rest: Settings ?=> List[Shellable])(using Settings): List[Shellable] = this match
case ExportJson => List("--power", "export", "--json", rest)
case Compile => "compile" :: rest
case Package(output) =>
List("--power", "package", "-f", "--output", output, rest)



Expand All @@ -30,13 +33,18 @@ object ScalaCommand:
case Repl => "repl" :: rest
case Clean => "clean" :: Nil

def makeArgs(module: Module, subcommand: CommandReader, classpath: List[String], extraArgs: Shellable*)(using Settings): List[os.Shellable] =
def makeArgs(module: Module, subcommand: CommandReader, classpath: List[String], platform: PlatformKind, extraArgs: Shellable*)(using Settings): List[os.Shellable] =
val workspace = os.pwd / os.RelPath(module.root)
extension (platform: PlatformKind) def asFlags: List[String] = platform match
case PlatformKind.jvm => Nil
case PlatformKind.`scala-js` => "--js" :: Nil
case PlatformKind.`scala-native` => "--native" :: Nil
List(
"scala",
subcommand.commandString(module)(
List(
(if classpath.nonEmpty then "--classpath" :: classpath.mkString(":") :: Nil else Nil),
platform.asFlags,
"--workspace", workspace,
extraArgs,
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import builder.ScalaCommand.SubCommand
import scala.concurrent.*
import scala.concurrent.duration.*
import scala.concurrent.ExecutionContext.Implicits.global
import builder.PlatformKind

/** A Plan operates over the target graph and produces a new one */
sealed trait Plan:
Expand All @@ -34,10 +35,13 @@ object Plan:
val stepss = stages.map: stage =>
val steps: List[Step] = stage.map: target =>
target.kind match
case TargetKind.Library => CompileScalaStep(lookup(target.module))
case TargetKind.Library(platform) =>
CompileScalaStep(lookup(target.module), platform)
case TargetKind.Application =>
val module = lookup(target.module)
RunScalaStep(module, module.kind.asInstanceOf[ModuleKind.Application])
case TargetKind.Package => PackageScalaStep.of(target, lookup(target.module)).?
case TargetKind.Copy(fromTarget) => CopyResourceStep(lookup(target.module), fromTarget)
steps

if settings.sequential then
Expand Down
Loading

0 comments on commit 8ce459c

Please sign in to comment.