From 940210bb5f14e55094c4d1243ba2d844030cd585 Mon Sep 17 00:00:00 2001 From: Tim Nieradzik Date: Wed, 7 Aug 2019 09:54:44 +0300 Subject: [PATCH] Inherit fields when loading build file Centralise the logic for inheriting settings defined on the project level or on base modules. Inheritance is now performed during loading of build files. As a consequence, many functions do not need to be aware of the project or the parent module anymore which greatly simplifies the code for generating Bloop and IDEA configurations. Also, several missing fields which were only available on the project-level were added to `Module`. Closes #18. --- src/main/scala/seed/Cli.scala | 15 +- .../seed/artefact/ArtefactResolution.scala | 241 ++++++-------- src/main/scala/seed/cli/Build.scala | 9 +- src/main/scala/seed/cli/BuildTarget.scala | 12 +- src/main/scala/seed/cli/Generate.scala | 4 +- src/main/scala/seed/cli/Link.scala | 6 +- src/main/scala/seed/cli/Package.scala | 24 +- src/main/scala/seed/cli/Server.scala | 4 +- src/main/scala/seed/cli/Update.scala | 15 +- src/main/scala/seed/cli/util/BloopCli.scala | 12 +- src/main/scala/seed/cli/util/Target.scala | 19 +- src/main/scala/seed/config/BuildConfig.scala | 306 +++++++++--------- .../scala/seed/config/util/TomlUtils.scala | 6 +- src/main/scala/seed/generation/Bloop.scala | 278 ++++++---------- src/main/scala/seed/generation/Idea.scala | 180 +++++------ .../seed/generation/util/ScalaCompiler.scala | 5 +- src/main/scala/seed/model/Build.scala | 32 +- .../artefact/ArtefactResolutionSpec.scala | 48 ++- src/test/scala/seed/cli/util/TargetSpec.scala | 32 +- .../scala/seed/config/BuildConfigSpec.scala | 101 ++++-- .../generation/BloopIntegrationSpec.scala | 12 +- src/test/scala/seed/generation/IdeaSpec.scala | 65 ++-- .../scala/seed/generation/PackageSpec.scala | 2 +- .../generation/util/ProjectGeneration.scala | 42 ++- 24 files changed, 684 insertions(+), 786 deletions(-) diff --git a/src/main/scala/seed/Cli.scala b/src/main/scala/seed/Cli.scala index 25eac35..4d44827 100644 --- a/src/main/scala/seed/Cli.scala +++ b/src/main/scala/seed/Cli.scala @@ -270,12 +270,12 @@ ${underlined("Usage:")} seed [--build=] [--config=] import command._ val config = SeedConfig.load(configPath) val log = Log(config) - val BuildConfig.Result(build, projectPath, _) = + val BuildConfig.Result(projectPath, modules) = BuildConfig.load(buildPath, log).getOrElse(sys.exit(1)) cli.Package.ui( config, projectPath, - build, + modules, module, output, libs, @@ -287,9 +287,16 @@ ${underlined("Usage:")} seed [--build=] [--config=] ) => val config = SeedConfig.load(configPath) val log = Log(config) - val BuildConfig.Result(build, projectPath, _) = + val BuildConfig.Result(projectPath, modules) = BuildConfig.load(buildPath, log).getOrElse(sys.exit(1)) - cli.Generate.ui(config, projectPath, projectPath, build, command, log) + cli.Generate.ui( + config, + projectPath, + projectPath, + modules, + command, + log + ) case Success(Config(configPath, _, command: Command.Server)) => val config = SeedConfig.load(configPath) val log = Log(config) diff --git a/src/main/scala/seed/artefact/ArtefactResolution.scala b/src/main/scala/seed/artefact/ArtefactResolution.scala index d6b4fe9..7ba0424 100644 --- a/src/main/scala/seed/artefact/ArtefactResolution.scala +++ b/src/main/scala/seed/artefact/ArtefactResolution.scala @@ -5,11 +5,12 @@ import java.nio.file.Path import seed.Cli.PackageConfig import MavenCentral.{CompilerVersion, PlatformVersion} import seed.cli.util.Ansi -import seed.model.Build.{Dep, JavaDep, Module, ScalaDep} +import seed.model.Build.{Dep, JavaDep, Module, Resolvers, ScalaDep} import seed.model.Platform.{JVM, JavaScript, Native} -import seed.model.{Artefact, Build, Platform, Resolution} +import seed.model.{Artefact, Platform, Resolution} import seed.Log import seed.config.BuildConfig +import seed.config.BuildConfig.Build object ArtefactResolution { def javaDepFromScalaDep( @@ -52,9 +53,9 @@ object ArtefactResolution { version ) - def jsPlatformDeps(build: Build, module: Module): Set[JavaDep] = { - val scalaVersion = BuildConfig.scalaVersion(build.project, List(module)) - val scalaJsVersion = build.project.scalaJsVersion.get + def jsPlatformDeps(module: Module): Set[JavaDep] = { + val scalaVersion = module.scalaVersion.get + val scalaJsVersion = module.scalaJsVersion.get Set( Artefact.ScalaJsLibrary @@ -70,9 +71,9 @@ object ArtefactResolution { ) } - def nativePlatformDeps(build: Build, modules: List[Module]): Set[JavaDep] = { - val scalaVersion = BuildConfig.scalaVersion(build.project, modules) - val scalaNativeVersion = build.project.scalaNativeVersion.get + def nativePlatformDeps(module: Module): Set[JavaDep] = { + val scalaVersion = module.scalaVersion.get + val scalaNativeVersion = module.scalaNativeVersion.get Set( Artefact.ScalaNativeJavalib, @@ -91,9 +92,9 @@ object ArtefactResolution { ) } - def nativeLibraryDep(build: Build, modules: List[Module]): JavaDep = { - val scalaVersion = BuildConfig.scalaVersion(build.project, modules) - val scalaNativeVersion = build.project.scalaNativeVersion.get + def nativeLibraryDep(module: Module): JavaDep = { + val scalaVersion = module.scalaVersion.get + val scalaNativeVersion = module.scalaNativeVersion.get javaDepFromArtefact( Artefact.ScalaNativeNativelib, @@ -104,67 +105,67 @@ object ArtefactResolution { ) } - def jvmArtefacts(stack: List[Module]): Set[(Platform, Dep)] = - stack.flatMap(_.scalaDeps).map(dep => JVM -> dep).toSet ++ - stack.flatMap(_.javaDeps).map(dep => JVM -> dep).toSet - - def jvmDeps(build: Build, stack: List[Module]): Set[JavaDep] = { - val scalaVersion = BuildConfig.scalaVersion(build.project, stack) - - stack - .flatMap(_.scalaDeps) - .map(dep => javaDepFromScalaDep(dep, JVM, scalaVersion, scalaVersion)) + def jvmArtefacts(module: Module): Set[(Platform, Dep)] = + (module.scalaDeps ++ module.javaDeps).map(dep => JVM -> dep).toSet + + def jvmDeps(module: Module): Set[JavaDep] = + module.scalaDeps + .map( + dep => + javaDepFromScalaDep( + dep, + JVM, + module.scalaVersion.get, + module.scalaVersion.get + ) + ) .toSet ++ - stack.flatMap(_.javaDeps).toSet - } - - def jsArtefacts(stack: List[Module]): Set[(Platform, Dep)] = - stack.flatMap(_.scalaDeps).map(dep => JavaScript -> dep).toSet - - def jsDeps(build: Build, stack: List[Module]): Set[JavaDep] = - build.project.scalaJsVersion match { - case None => Set() - case Some(scalaJsVersion) => - val scalaVersion = BuildConfig.scalaVersion(build.project, stack) - stack - .flatMap(_.scalaDeps) - .map( - dep => - javaDepFromScalaDep(dep, JavaScript, scalaJsVersion, scalaVersion) + module.javaDeps.toSet + + def jsArtefacts(module: Module): Set[(Platform, Dep)] = + module.scalaDeps.map(dep => JavaScript -> dep).toSet + + def jsDeps(module: Module): Set[JavaDep] = + module.scalaDeps + .map( + dep => + javaDepFromScalaDep( + dep, + JavaScript, + module.scalaJsVersion.get, + module.scalaVersion.get ) - .toSet - } - - def nativeArtefacts(stack: List[Module]): Set[(Platform, Dep)] = - stack.flatMap(_.scalaDeps).map(dep => Native -> dep).toSet - - def nativeDeps(build: Build, stack: List[Module]): Set[JavaDep] = - build.project.scalaNativeVersion match { - case None => Set() - case Some(scalaNativeVersion) => - val scalaVersion = BuildConfig.scalaVersion(build.project, stack) - stack - .flatMap(_.scalaDeps) - .map( - dep => - javaDepFromScalaDep(dep, Native, scalaNativeVersion, scalaVersion) + ) + .toSet + + def nativeArtefacts(module: Module): Set[(Platform, Dep)] = + module.scalaDeps.map(dep => Native -> dep).toSet + + def nativeDeps(module: Module): Set[JavaDep] = + module.scalaDeps + .map( + dep => + javaDepFromScalaDep( + dep, + Native, + module.scalaNativeVersion.get, + module.scalaVersion.get ) - .toSet - } + ) + .toSet - def compilerDeps(build: Build, module: Module): List[Set[JavaDep]] = { - def f(build: Build, module: Module, platform: Platform): Set[JavaDep] = { - import build.project.scalaOrganisation - val platformModule = BuildConfig.platformModule(module, platform) + def compilerDeps(module: Module): List[Set[JavaDep]] = { + def f(module: Module, platform: Platform): Set[JavaDep] = { + val platformModule = BuildConfig.platformModule(module, platform).get - val platformVer = BuildConfig.platformVersion(build, module, platform) - val compilerVer = - BuildConfig.scalaVersion(build.project, platformModule.toList :+ module) + val platformVer = BuildConfig.platformVersion(module, platform) + val compilerVer = platformModule.scalaVersion.get + val organisation = platformModule.scalaOrganisation.get val scalaDeps = Set( - Artefact.scalaCompiler(scalaOrganisation) -> compilerVer, - Artefact.scalaLibrary(scalaOrganisation) -> compilerVer, - Artefact.scalaReflect(scalaOrganisation) -> compilerVer + Artefact.scalaCompiler(organisation) -> compilerVer, + Artefact.scalaLibrary(organisation) -> compilerVer, + Artefact.scalaReflect(organisation) -> compilerVer ) ++ ( if (platform == Platform.Native) Set(Artefact.ScalaNativePlugin -> platformVer) @@ -173,10 +174,6 @@ object ArtefactResolution { else Set() ) - val dependencies = mergeDeps[ScalaDep]( - module.compilerDeps ++ platformModule.toList.flatMap(_.compilerDeps) - ) - scalaDeps.map { case (artefact, version) => javaDepFromArtefact( @@ -186,110 +183,51 @@ object ArtefactResolution { platformVer, compilerVer ) - } ++ dependencies.map( + } ++ platformModule.compilerDeps.map( dep => javaDepFromScalaDep(dep, platform, platformVer, compilerVer) ) } - module.targets.map(target => f(build, module, target)).filter(_.nonEmpty) + module.targets.map(target => f(module, target)).filter(_.nonEmpty) } def allCompilerDeps(build: Build): List[Set[JavaDep]] = - build.module.values.toList.flatMap(compilerDeps(build, _)).distinct + build.values.toList.flatMap(m => compilerDeps(m.module)).distinct def platformDeps(build: Build, module: Module): Set[JavaDep] = module.targets.toSet[Platform].flatMap { target => - if (target == JavaScript) - jsPlatformDeps(build, module.js.getOrElse(Module())) - else if (target == Native) - nativePlatformDeps(build, module.native.toList) + if (target == JavaScript) jsPlatformDeps(module.js.get) + else if (target == Native) nativePlatformDeps(module.native.get) else Set[JavaDep]() } - def libraryDeps( - build: Build, - module: Module, - platforms: Set[Platform], - parent: Module = Module() - ): Set[JavaDep] = { - val targets = if (module.targets.isEmpty) parent.targets else module.targets - targets.toSet[Platform].intersect(platforms).flatMap { target => - // Shared libraries - if (target == JVM) - jvmDeps( - build, - module.jvm.toList ++ parent.jvm.toList ++ List(module, parent) - ) - else if (target == JavaScript) - jsDeps( - build, - module.js.toList ++ parent.js.toList ++ List(module, parent) - ) - else - nativeDeps( - build, - module.native.toList ++ parent.native.toList ++ List(module, parent) - ) - } ++ - (if (!platforms.contains(JVM)) Set() - else - module.jvm.toSet.flatMap( - jvm => - jvmDeps(build, List(jvm, parent.jvm.getOrElse(Module()), module)) - )) ++ + def libraryDeps(module: Module, platforms: Set[Platform]): Set[JavaDep] = + (if (!platforms.contains(JVM)) Set() + else module.jvm.toSet.flatMap(jvmDeps)) ++ (if (!platforms.contains(JavaScript)) Set() - else - module.js.toSet.flatMap( - js => jsDeps(build, List(js, parent.js.getOrElse(Module()), module)) - )) ++ + else module.js.toSet.flatMap(jsDeps)) ++ (if (!platforms.contains(Native)) Set() - else - module.native.toSet.flatMap( - native => - nativeDeps( - build, - List(native, parent.native.getOrElse(Module()), module) - ) - )) ++ - module.test.toSet.flatMap(libraryDeps(build, _, platforms, module)) - } + else module.native.toSet.flatMap(nativeDeps)) ++ + module.test.toSet.flatMap(libraryDeps(_, platforms)) - def libraryArtefacts( - build: Build, - module: Module, - parent: Module = Module() - ): Set[(Platform, Dep)] = - module.targets.toSet[Platform].flatMap { target => - if (target == JVM) jvmArtefacts(List(module, parent)) - else if (target == JavaScript) jsArtefacts(List(module, parent)) - else nativeArtefacts(List(module, parent)) - } ++ - module.jvm.toSet.flatMap( - jvm => jvmArtefacts(List(jvm, parent.jvm.getOrElse(Module()), module)) - ) ++ - module.js.toSet.flatMap( - js => jsArtefacts(List(js, parent.js.getOrElse(Module()), module)) - ) ++ - module.native.toSet.flatMap( - native => - nativeArtefacts( - List(native, parent.native.getOrElse(Module()), module) - ) - ) ++ - module.test.toSet.flatMap(libraryArtefacts(build, _, module)) + def libraryArtefacts(module: Module): Set[(Platform, Dep)] = + module.jvm.toSet.flatMap(jvmArtefacts) ++ + module.js.toSet.flatMap(jsArtefacts) ++ + module.native.toSet.flatMap(nativeArtefacts) ++ + module.test.toSet.flatMap(libraryArtefacts) def allPlatformDeps(build: Build): Set[JavaDep] = - build.module.values.toSet.flatMap(platformDeps(build, _)) + build.values.toSet.flatMap(m => platformDeps(build, m.module)) def allLibraryDeps( build: Build, platforms: Set[Platform] = Set(JVM, JavaScript, Native) ): Set[JavaDep] = - build.module.values.toSet.flatMap(libraryDeps(build, _, platforms)) + build.values.toSet.flatMap(m => libraryDeps(m.module, platforms)) def allLibraryArtefacts(build: Build): Map[Platform, Set[Dep]] = - build.module.values.toSet - .flatMap(libraryArtefacts(build, _)) + build.values.toSet + .flatMap(m => libraryArtefacts(m.module)) .groupBy(_._1) .mapValues(_.map(_._2)) @@ -340,6 +278,7 @@ object ArtefactResolution { def resolution( seedConfig: seed.model.Config, + resolvers: Resolvers, build: Build, packageConfig: PackageConfig, optionalArtefacts: Boolean, @@ -356,15 +295,15 @@ object ArtefactResolution { log.info("Configured resolvers:") log.detail("- " + Ansi.italic(resolvedIvyPath.toString) + " (Ivy)") log.detail("- " + Ansi.italic(resolvedCachePath.toString) + " (Coursier)") - build.resolvers.ivy + resolvers.ivy .foreach(ivy => log.detail("- " + Ansi.italic(ivy.url) + " (Ivy)")) - build.resolvers.maven + resolvers.maven .foreach(maven => log.detail("- " + Ansi.italic(maven) + " (Maven)")) def resolve(deps: Set[JavaDep]) = Coursier.resolveAndDownload( deps, - build.resolvers, + resolvers, resolvedIvyPath, resolvedCachePath, optionalArtefacts, diff --git a/src/main/scala/seed/cli/Build.scala b/src/main/scala/seed/cli/Build.scala index d23ed6d..c424ad3 100644 --- a/src/main/scala/seed/cli/Build.scala +++ b/src/main/scala/seed/cli/Build.scala @@ -6,9 +6,9 @@ import java.nio.file.Path import seed.Log import seed.cli.util.{Ansi, RTS, WsClient} import seed.config.BuildConfig -import seed.model import seed.model.Config import seed.Cli.Command +import seed.config.BuildConfig.Build import zio._ object Build { @@ -61,20 +61,17 @@ object Build { watch: Boolean, tmpfs: Boolean, log: Log, - onStdOut: model.Build => String => Unit + onStdOut: Build => String => Unit ): Either[List[String], UIO[Unit]] = BuildConfig.load(buildPath, log) match { case None => Left(List()) - case Some( - BuildConfig.Result(build, buildProjectPath, moduleProjectPaths) - ) => + case Some(BuildConfig.Result(buildProjectPath, build)) => val parsedModules = modules.map(util.Target.parseModuleString(build)) util.Validation.unpack(parsedModules).right.map { allModules => val processes = BuildTarget.buildTargets( build, allModules, projectPath.getOrElse(buildProjectPath), - moduleProjectPaths, watch, tmpfs, log diff --git a/src/main/scala/seed/cli/BuildTarget.scala b/src/main/scala/seed/cli/BuildTarget.scala index 89ae809..bc3e2d6 100644 --- a/src/main/scala/seed/cli/BuildTarget.scala +++ b/src/main/scala/seed/cli/BuildTarget.scala @@ -5,18 +5,16 @@ import java.nio.file.{Files, Path} import seed.Log import seed.cli.util.Ansi import seed.config.BuildConfig +import seed.config.BuildConfig.Build import seed.generation.util.PathUtil -import seed.model import seed.process.ProcessHelper - import zio._ object BuildTarget { def buildTargets( - build: model.Build, + build: Build, modules: List[util.Target.Parsed], projectPath: Path, - moduleProjectPaths: Map[String, Path], watch: Boolean, tmpfs: Boolean, log: Log @@ -38,7 +36,7 @@ object BuildTarget { case util.Target.Parsed(module, None) => module.name +: BuildConfig.collectModuleDeps(build, module.module) } - .flatMap(m => build.module(m).target.keys.toList.map(m -> _)) + .flatMap(m => build(m).module.target.keys.toList.map(m -> _)) .distinct if (targets.nonEmpty) @@ -57,8 +55,8 @@ object BuildTarget { case (m, t) => val customLog = log.prefix(Ansi.bold(s"[${format(m, t)}]: ")) - val modulePath = moduleProjectPaths(m) - val target = build.module(m).target(t) + val modulePath = build(m).path + val target = build(m).module.target(t) target.`class` match { case Some(c) => diff --git a/src/main/scala/seed/cli/Generate.scala b/src/main/scala/seed/cli/Generate.scala index c428167..b6d5847 100644 --- a/src/main/scala/seed/cli/Generate.scala +++ b/src/main/scala/seed/cli/Generate.scala @@ -6,13 +6,14 @@ import seed.{Log, model} import seed.Cli.Command import seed.generation.{Bloop, Idea} import seed.artefact.ArtefactResolution +import seed.config.BuildConfig.Build object Generate { def ui( seedConfig: model.Config, projectPath: Path, outputPath: Path, - build: model.Build, + build: Build, command: Command.Generate, log: Log ): Unit = { @@ -31,6 +32,7 @@ object Generate { val (_, platformResolution, compilerResolution) = ArtefactResolution.resolution( seedConfig, + ???, // TODO resolvers build, command.packageConfig, optionalArtefacts, diff --git a/src/main/scala/seed/cli/Link.scala b/src/main/scala/seed/cli/Link.scala index 61f15be..762c626 100644 --- a/src/main/scala/seed/cli/Link.scala +++ b/src/main/scala/seed/cli/Link.scala @@ -9,6 +9,7 @@ import seed.config.BuildConfig import seed.model import seed.model.Config import seed.Cli.Command +import seed.config.BuildConfig.Build import zio._ object Link { @@ -62,18 +63,17 @@ object Link { watch: Boolean, tmpfs: Boolean, log: Log, - onStdOut: model.Build => String => Unit + onStdOut: Build => String => Unit ): Either[List[String], UIO[Unit]] = BuildConfig.load(buildPath, log) match { case None => Left(List()) - case Some(BuildConfig.Result(build, projectPath, moduleProjectPaths)) => + case Some(BuildConfig.Result(projectPath, build)) => val parsedModules = modules.map(util.Target.parseModuleString(build)) util.Validation.unpack(parsedModules).right.map { allModules => val processes = BuildTarget.buildTargets( build, allModules, projectPath, - moduleProjectPaths, watch, tmpfs, log diff --git a/src/main/scala/seed/cli/Package.scala b/src/main/scala/seed/cli/Package.scala index 4f4b37f..c5900bb 100644 --- a/src/main/scala/seed/cli/Package.scala +++ b/src/main/scala/seed/cli/Package.scala @@ -6,10 +6,10 @@ import scala.collection.JavaConverters._ import seed.artefact.{ArtefactResolution, Coursier} import seed.cli.util.Ansi import seed.config.BuildConfig +import seed.config.BuildConfig.Build import seed.generation.util.PathUtil -import seed.model import seed.model.Build.{JavaDep, Module} -import seed.model.{Build, Config} +import seed.model.Config import seed.model.Platform.JVM import seed.{Cli, Log} @@ -17,7 +17,7 @@ object Package { def ui( seedConfig: Config, projectPath: Path, - build: model.Build, + build: Build, module: String, output: Option[Path], libs: Boolean, @@ -30,16 +30,16 @@ object Package { val platform = JVM val outputPath = output.getOrElse(buildPath.resolve("dist")) - build.module.get(module) match { + build.get(module) match { case None => log.error(s"Module ${Ansi.italic(module)} does not exist") case Some(resolvedModule) => val paths = ( List(module) ++ BuildConfig.collectJvmModuleDeps( build, - resolvedModule + resolvedModule.module ) ).map { name => - if (BuildConfig.isCrossBuild(build.module(name))) + if (BuildConfig.isCrossBuild(build(name).module)) bloopBuildPath.resolve(name + "-" + platform.id) else bloopBuildPath.resolve(name) @@ -53,8 +53,9 @@ object Package { else if (paths.isEmpty) log.error(s"No build paths were found") else { - val files = collectFiles(paths) - val jvmModule = resolvedModule.jvm.getOrElse(resolvedModule) + val files = collectFiles(paths) + val jvmModule = + resolvedModule.module.jvm.getOrElse(resolvedModule.module) val classPath = if (!libs) List() @@ -110,17 +111,18 @@ object Package { outputPath: Path, log: Log ): List[String] = { - val scalaVersion = BuildConfig.scalaVersion(build.project, List(jvmModule)) + val scalaVersion = jvmModule.scalaVersion.get val scalaLibraryDep = - JavaDep(build.project.scalaOrganisation, "scala-library", scalaVersion) + JavaDep(jvmModule.scalaOrganisation.get, "scala-library", scalaVersion) val scalaReflectDep = - JavaDep(build.project.scalaOrganisation, "scala-reflect", scalaVersion) + JavaDep(jvmModule.scalaOrganisation.get, "scala-reflect", scalaVersion) val platformDeps = Set(scalaLibraryDep, scalaReflectDep) val libraryDeps = ArtefactResolution.allLibraryDeps(build, Set(JVM)) val (resolvedDepPath, libraryResolution, platformResolution) = ArtefactResolution.resolution( seedConfig, + ???, // TODO resolvers build, packageConfig, optionalArtefacts = false, diff --git a/src/main/scala/seed/cli/Server.scala b/src/main/scala/seed/cli/Server.scala index 4a81fd7..e163120 100644 --- a/src/main/scala/seed/cli/Server.scala +++ b/src/main/scala/seed/cli/Server.scala @@ -8,8 +8,8 @@ import io.circe.{Decoder, DecodingFailure, Encoder, Json} import org.java_websocket.WebSocket import seed.Log import seed.cli.util.{BloopCli, RTS, WsServer} -import seed.model import seed.Cli.Command +import seed.config.BuildConfig.Build import seed.model.Config import scala.collection.JavaConverters._ @@ -87,7 +87,7 @@ object Server { def onStdOut( wsServer: WsServer, wsClient: WebSocket, - build: model.Build, + build: Build, serverLog: Log )(message: String): Unit = { wsClient.send(message) diff --git a/src/main/scala/seed/cli/Update.scala b/src/main/scala/seed/cli/Update.scala index 8bb3854..343b2ef 100644 --- a/src/main/scala/seed/cli/Update.scala +++ b/src/main/scala/seed/cli/Update.scala @@ -64,7 +64,7 @@ object Update { } def ui(path: Path, stable: Boolean, log: Log): Unit = { - val BuildConfig.Result(build, projectPath, _) = BuildConfig + val BuildConfig.Result(projectPath, build) = BuildConfig .load(path, log) .getOrElse(sys.exit(1)) @@ -72,7 +72,7 @@ object Update { val (compilerVersions, platformVersions, libraryArtefacts) = new Scaffold(log).checkVersions( - build.project.scalaOrganisation, + ???, // TODO build.project.scalaOrganisation, BuildConfig.buildTargets(build), buildArtefacts.mapValues(_.map(Artefact.fromDep)), stable @@ -83,12 +83,11 @@ object Update { BuildConfig.buildTargets(build).toList.sorted(Platform.Ordering).foreach { platform => val oldCompilerVersion = - build.module.values - .flatMap(BuildConfig.platformModule(_, platform)) + build.values + .flatMap(m => BuildConfig.platformModule(m.module, platform)) .view .flatMap(_.scalaVersion) - .headOption - .getOrElse(build.project.scalaVersion) + .head val newCompilerVersion = compilerVersions.get(platform) compareVersion( @@ -99,7 +98,7 @@ object Update { ) if (platform == JavaScript) { - val oldPlatformVersion = build.project.scalaJsVersion.get + val oldPlatformVersion = ??? // TODO build.project.scalaJsVersion.get val newPlatformVersion = platformVersions.get(platform) compareVersion( @@ -109,7 +108,7 @@ object Update { log ) } else if (platform == Native) { - val oldPlatformVersion = build.project.scalaNativeVersion.get + val oldPlatformVersion = ??? // TODO build.project.scalaNativeVersion.get val newPlatformVersion = platformVersions.get(platform) compareVersion( diff --git a/src/main/scala/seed/cli/util/BloopCli.scala b/src/main/scala/seed/cli/util/BloopCli.scala index c2ddb5b..20071ef 100644 --- a/src/main/scala/seed/cli/util/BloopCli.scala +++ b/src/main/scala/seed/cli/util/BloopCli.scala @@ -3,10 +3,8 @@ package seed.cli.util import java.nio.file.Path import seed.Log -import seed.model.Build +import seed.config.BuildConfig.Build import seed.process.ProcessHelper - -import seed.model import seed.model.BuildEvent import seed.model.Platform.{JVM, JavaScript, Native} import seed.model.Platform @@ -21,7 +19,7 @@ object BloopCli { def skipOutput(output: String): Boolean = output.contains("\u001b[H\u001b[2J") def parseBloopModule( - build: model.Build, + build: Build, bloopName: String ): (String, Platform) = if (bloopName.endsWith("-js")) @@ -32,13 +30,13 @@ object BloopCli { (bloopName.dropRight("-native".length), Native) else { require( - build.module(bloopName).targets.length == 1, + build(bloopName).module.targets.length == 1, "Only one target expected" ) - (bloopName, build.module(bloopName).targets.head) + (bloopName, build(bloopName).module.targets.head) } - def parseStdOut(build: model.Build)(message: String): Option[BuildEvent] = { + def parseStdOut(build: Build)(message: String): Option[BuildEvent] = { val parts = message.split(" ") if (parts(0) == "Compiling") { val (module, platform) = parseBloopModule(build, parts(1)) diff --git a/src/main/scala/seed/cli/util/Target.scala b/src/main/scala/seed/cli/util/Target.scala index ed0d310..9f6be4d 100644 --- a/src/main/scala/seed/cli/util/Target.scala +++ b/src/main/scala/seed/cli/util/Target.scala @@ -1,5 +1,6 @@ package seed.cli.util +import seed.config.BuildConfig.Build import seed.model.Build.Module import seed.model.{Build, Platform} @@ -17,11 +18,11 @@ object Target { else { def invalidName(name: String) = Left(s"Invalid module name: ${Ansi - .italic(name)}. Valid names: ${build.module.keys.mkString(", ")}") + .italic(name)}. Valid names: ${build.keys.mkString(", ")}") if (!module.contains(":")) { - if (!build.module.contains(module)) invalidName(module) - else Right(Parsed(ModuleRef(module, build.module(module)), None)) + if (!build.contains(module)) invalidName(module) + else Right(Parsed(ModuleRef(module, build(module).module), None)) } else { val parts = module.split(":") if (parts.length != 2) { @@ -29,24 +30,20 @@ object Target { } else { val (name, target) = (parts(0), parts(1)) - if (!build.module.contains(name)) invalidName(name) + if (!build.contains(name)) invalidName(name) else { - build - .module(name) - .targets + build(name).module.targets .find(_.id == target) .map(Left(_)) .orElse( - build - .module(name) - .target + build(name).module.target .get(target) .map(tgt => Right(TargetRef(target, tgt))) ) match { case None => Left(s"Invalid build target ${Ansi.italic(target)} provided") case Some(tgt) => - Right(Parsed(ModuleRef(name, build.module(name)), Some(tgt))) + Right(Parsed(ModuleRef(name, build(name).module), Some(tgt))) } } } diff --git a/src/main/scala/seed/config/BuildConfig.scala b/src/main/scala/seed/config/BuildConfig.scala index d619dbd..e82c0c4 100644 --- a/src/main/scala/seed/config/BuildConfig.scala +++ b/src/main/scala/seed/config/BuildConfig.scala @@ -1,31 +1,29 @@ package seed.config -import java.nio.file.{Files, Path, Paths} +import java.nio.file.{Files, Path} import seed.cli.util.{Ansi, ColourScheme} -import seed.model.Build.{JavaDep, Module, Project, ScalaDep} +import seed.model.Build.{JavaDep, Module, ScalaDep} import seed.model.Platform.{JVM, JavaScript, Native} -import seed.model.{Build, Platform} +import seed.model.{Build, Organisation, Platform, TomlBuild} import seed.Log +import seed.artefact.ArtefactResolution import seed.config.util.TomlUtils -import scala.collection.mutable - object BuildConfig { import TomlUtils.parseBuildToml - case class Result( - build: Build, - projectPath: Path, - moduleProjectPaths: Map[String, Path] - ) + case class ModuleConfig(module: Module, path: Path) + type Build = Map[String, ModuleConfig] + + case class Result(projectPath: Path, build: Build) def load(path: Path, log: Log): Option[Result] = loadInternal(path, log).filter( result => - result.build.module.toList.forall { + result.build.toList.forall { case (name, module) => - checkModule(result.build, name, module, log) + checkModule(result, name, module.module, log) } ) @@ -63,114 +61,100 @@ object BuildConfig { log ) .map { parsed => - val (build, moduleProjectPaths) = processBuild( + val modules = processBuild( parsed, - projectPath, { path => - loadInternal(path, log).map { - case Result(build, projectPath, moduleProjectPaths) => - parsed.module.keySet - .intersect(build.module.keySet) - .foreach( - name => - log.error( - s"Module name ${Ansi.italic(name)} is not unique" - ) - ) - (build, moduleProjectPaths) - } - } + projectPath, + path => loadInternal(path, log), + log ) - - Result(build, projectPath.normalize(), moduleProjectPaths) + Result(projectPath.normalize(), modules) } } } def processBuild( - build: Build, + build: TomlBuild, projectPath: Path, - parse: Path => Option[(Build, Map[String, Path])] - ): (Build, Map[String, Path]) = { - val parsed = build.copy( - module = build.module.mapValues { module => - val parentTargets = moduleTargets(module, module.targets) - module.copy( - targets = parentTargets, - test = module.test.map { module => - module.copy( - targets = moduleTargets( - module, - if (module.targets.isEmpty) parentTargets - else module.targets - ) - ) - } - ) - } - ) - - val imported = parsed.`import`.flatMap(parse(_)) + parse: Path => Option[Result], + log: Log + ): Build = { + val modules = + build.module.mapValues(inheritSettings(build.project.toModule)) + val imported = build.`import`.flatMap(parse(_)) + + modules.keySet + .intersect(imported.flatMap(_.build).map(_._1).toSet) + .foreach( + name => log.error(s"Module name ${Ansi.italic(name)} is not unique") + ) - val parsedModules = - parsed.module.mapValues(inheritCompilerDeps(parsed.project)) + (imported.flatMap(_.build) ++ modules.mapValues( + ModuleConfig(_, projectPath) + )).toMap + } - val importedModules = imported.foldLeft(Map.empty[String, Module]) { - case (acc, (importedBuild, importedPaths)) => - acc ++ importedBuild.module.mapValues( - inheritCompilerDeps(importedBuild.project) - ) + def inheritSettings(parent: Module)(module: Module): Module = { + def merge(m: Module): Module = { + val parentTargets = moduleTargets(module, module.targets) + + m.copy( + targets = parentTargets, + scalaVersion = m.scalaVersion.orElse(parent.scalaVersion), + scalaJsVersion = m.scalaJsVersion.orElse(parent.scalaJsVersion), + scalaNativeVersion = + m.scalaNativeVersion.orElse(parent.scalaNativeVersion), + scalaOptions = parent.scalaOptions ++ m.scalaOptions, + scalaOrganisation = m.scalaOrganisation + .orElse(parent.scalaOrganisation) + .orElse(Some(Organisation.Lightbend.packageName)), + compilerDeps = + ArtefactResolution.mergeDeps(parent.compilerDeps ++ m.compilerDeps), + testFrameworks = (parent.testFrameworks ++ m.testFrameworks).distinct, + mainClass = m.mainClass.orElse(parent.mainClass), + sources = parent.sources ++ m.sources, + moduleDeps = (parent.moduleDeps ++ m.moduleDeps).distinct, + + scalaDeps = + ArtefactResolution.mergeDeps(parent.scalaDeps ++ m.scalaDeps), + javaDeps = ArtefactResolution.mergeDeps(parent.javaDeps ++ m.javaDeps), + test = module.test.map { module => + // TODO inherit from base module? + module.copy( + targets = moduleTargets( + module, + if (module.targets.isEmpty) parentTargets else module.targets + ) + ) + } + ) } - val combinedBuild = parsed.copy( - project = parsed.project.copy( - testFrameworks = (parsed.project.testFrameworks ++ imported.flatMap( - _._1.project.testFrameworks - )).distinct - ), - module = parsedModules ++ importedModules + val mergedModule = merge(module) + + mergedModule.copy( + jvm = module.jvm + .map(inheritSettings(mergedModule)) + .orElse( + if (!module.targets.contains(Platform.JVM)) None + else Some(merge(Module())) + ), + js = module.js + .map(inheritSettings(mergedModule)) + .orElse( + if (!module.targets.contains(Platform.JavaScript)) None + else Some(merge(Module())) + ), + native = module.native + .map(inheritSettings(mergedModule)) + .orElse( + if (!module.targets.contains(Platform.Native)) None + else Some(merge(Module())) + ) ) - - val moduleProjectPaths = - imported.flatMap(_._2).toMap ++ - parsed.module.keys.map(m => m -> projectPath).toMap - - (combinedBuild, moduleProjectPaths) } - def inheritCompilerDeps(project: Project)(module: Module): Module = - module.copy( - compilerDeps = (project.compilerDeps ++ module.compilerDeps).distinct, - jvm = module.jvm.map(inheritCompilerDeps(project)), - js = module.js.map(inheritCompilerDeps(project)), - native = module.native.map(inheritCompilerDeps(project)) - ) - - def moduleTargets( - module: Build.Module, - otherTargets: List[Platform] - ): List[Platform] = - ( - otherTargets ++ - (if (module.jvm.nonEmpty) List(JVM) else List()) ++ - (if (module.js.nonEmpty) List(JavaScript) else List()) ++ - (if (module.native.nonEmpty) List(Native) else List()) - ).distinct - - def platformModule( - module: Build.Module, - platform: Platform - ): Option[Build.Module] = - platform match { - case JVM => module.jvm - case JavaScript => module.js - case Native => module.native - } - - def buildTargets(build: Build): Set[Platform] = - build.module.flatMap { case (_, module) => module.targets }.toSet - def checkModule( - build: Build, + result: Result, name: String, module: Build.Module, log: Log @@ -181,12 +165,12 @@ object BuildConfig { } val invalidModuleDeps = - module.moduleDeps.filter(!build.module.isDefinedAt(_)) + module.moduleDeps.filter(!result.build.isDefinedAt(_)) val invalidTargetModules = module.target.toList .flatMap(_._2.`class`) .map(_.module.module) - .filter(!build.module.isDefinedAt(_)) + .filter(!result.build.isDefinedAt(_)) val invalidTargetModules2 = module.target.keys .filter(id => Platform.All.keys.exists(_.id == id)) @@ -205,11 +189,15 @@ object BuildConfig { error(s"Source paths must be set on root or JVM module $moduleName") else if (module.sources.isEmpty && module.native.exists(_.sources.isEmpty)) error(s"Source paths must be set on root or native module $moduleName") - else if (module.targets.contains(JavaScript) && build.project.scalaJsVersion.isEmpty) + else if (module.targets.contains(JavaScript) && !module.js.exists( + _.scalaJsVersion.isDefined + )) error( s"Module $moduleName has JavaScript target, but Scala.js version not set" ) - else if (module.targets.contains(Native) && build.project.scalaNativeVersion.isEmpty) + else if (module.targets.contains(Native) && !module.native.exists( + _.scalaNativeVersion.isDefined + )) error( s"Module $moduleName has native target, but Scala Native version not set" ) @@ -256,60 +244,64 @@ object BuildConfig { else true } - def scalaVersion(project: Project, stack: List[Module]): String = - stack - .find(_.scalaVersion.isDefined) - .flatMap(_.scalaVersion) - .getOrElse(project.scalaVersion) - - def platformVersion( - build: Build, - module: Module, - platform: Platform - ): String = + def platformVersion(module: Module, platform: Platform): String = platform match { - case JVM => BuildConfig.scalaVersion(build.project, List(module)) - case JavaScript => build.project.scalaJsVersion.get - case Native => build.project.scalaNativeVersion.get + case JVM => module.scalaVersion.get + case JavaScript => module.scalaJsVersion.get + case Native => module.scalaNativeVersion.get } def isCrossBuild(module: Module): Boolean = module.targets.toSet.size > 1 - def hasTarget(build: Build, name: String, platform: Platform): Boolean = - build.module(name).targets.contains(platform) + def hasTarget(modules: Build, name: String, platform: Platform): Boolean = + modules(name).module.targets.contains(platform) def targetName(build: Build, name: String, platform: Platform): String = - if (!isCrossBuild(build.module(name))) name else name + "-" + platform.id + if (!isCrossBuild(build(name).module)) name else name + "-" + platform.id def buildTargets(build: Build, module: String): List[String] = { - val m = build.module(module) + val m = build(module).module val p = m.targets p.map(p => targetName(build, module, p)) } def linkTargets(build: Build, module: String): List[String] = { - val m = build.module(module) + val m = build(module).module val p = m.targets.diff(List(JVM)) p.map(p => targetName(build, module, p)) } + def moduleTargets( + module: Build.Module, + otherTargets: List[Platform] + ): List[Platform] = + ( + otherTargets ++ + (if (module.jvm.nonEmpty) List(JVM) else List()) ++ + (if (module.js.nonEmpty) List(JavaScript) else List()) ++ + (if (module.native.nonEmpty) List(Native) else List()) + ).distinct + + def buildTargets(build: Build): Set[Platform] = + build.flatMap { case (_, module) => module.module.targets }.toSet + def platformModule( - build: Build, - name: String, + module: Build.Module, platform: Platform - ): Option[Module] = - if (platform == JavaScript) build.module(name).js - else if (platform == JVM) build.module(name).jvm - else if (platform == Native) build.module(name).native - else throw new IllegalArgumentException() + ): Option[Build.Module] = + platform match { + case JVM => module.jvm + case JavaScript => module.js + case Native => module.native + } def targetNames( - build: Build, + modules: Build, name: String, platform: Platform ): List[String] = - if (!isCrossBuild(build.module(name))) List(name) - else if (platformModule(build, name, platform).isEmpty) List(name) + if (!isCrossBuild(modules(name).module)) List(name) + else if (platformModule(modules(name).module, platform).isEmpty) List(name) else List(name, name + "-" + platform.id) def jsModuleDeps(module: Module): List[String] = @@ -321,19 +313,19 @@ object BuildConfig { def jvmModuleDeps(module: Module): List[String] = module.moduleDeps ++ module.jvm.map(_.moduleDeps).getOrElse(List()) - def collectJsModuleDeps(build: Build, module: Module): List[String] = + def collectJsModuleDeps(modules: Build, module: Module): List[String] = jsModuleDeps(module).flatMap( - m => List(m) ++ collectJsModuleDeps(build, build.module(m)) + m => List(m) ++ collectJsModuleDeps(modules, modules(m).module) ) def collectNativeModuleDeps(build: Build, module: Module): List[String] = nativeModuleDeps(module).flatMap( - m => List(m) ++ collectNativeModuleDeps(build, build.module(m)) + m => List(m) ++ collectNativeModuleDeps(build, build(m).module) ) def collectJvmModuleDeps(build: Build, module: Module): List[String] = jvmModuleDeps(module).flatMap( - m => List(m) ++ collectJvmModuleDeps(build, build.module(m)) + m => List(m) ++ collectJvmModuleDeps(build, build(m).module) ) def collectModuleDeps( @@ -365,7 +357,7 @@ object BuildConfig { .resolve(targetName(build, name, JavaScript)) +: collectJsClassPath( buildPath, build, - build.module(name) + build(name).module ) ) @@ -382,7 +374,7 @@ object BuildConfig { .resolve(targetName(build, name, Native)) +: collectNativeClassPath( buildPath, build, - build.module(name) + build(name).module ) ) @@ -395,33 +387,33 @@ object BuildConfig { .filter(name => hasTarget(build, name, Platform.JVM)) .flatMap( name => - buildPath - .resolve(targetName(build, name, JVM)) +: collectJvmClassPath( - buildPath, - build, - build.module(name) - ) + buildPath.resolve(targetName(build, name, JVM)) +: + collectJvmClassPath( + buildPath, + build, + build(name).module + ) ) def collectJsDeps(build: Build, module: Module): List[ScalaDep] = - module.scalaDeps ++ module.js.map(_.scalaDeps).getOrElse(List()) ++ - jsModuleDeps(module).flatMap(m => collectJsDeps(build, build.module(m))) + module.js.map(_.scalaDeps).getOrElse(List()) ++ + jsModuleDeps(module).flatMap(m => collectJsDeps(build, build(m).module)) def collectNativeDeps(build: Build, module: Module): List[ScalaDep] = - module.scalaDeps ++ module.native.map(_.scalaDeps).getOrElse(List()) ++ + module.native.map(_.scalaDeps).getOrElse(List()) ++ nativeModuleDeps(module).flatMap( - m => collectNativeDeps(build, build.module(m)) + m => collectNativeDeps(build, build(m).module) ) def collectJvmScalaDeps(build: Build, module: Module): List[ScalaDep] = - module.scalaDeps ++ module.jvm.map(_.scalaDeps).getOrElse(List()) ++ + module.jvm.map(_.scalaDeps).getOrElse(List()) ++ jvmModuleDeps(module).flatMap( - m => collectJvmScalaDeps(build, build.module(m)) + m => collectJvmScalaDeps(build, build(m).module) ) def collectJvmJavaDeps(build: Build, module: Module): List[JavaDep] = - module.javaDeps ++ module.jvm.map(_.javaDeps).getOrElse(List()) ++ + module.jvm.map(_.javaDeps).getOrElse(List()) ++ jvmModuleDeps(module).flatMap( - m => collectJvmJavaDeps(build, build.module(m)) + m => collectJvmJavaDeps(build, build(m).module) ) } diff --git a/src/main/scala/seed/config/util/TomlUtils.scala b/src/main/scala/seed/config/util/TomlUtils.scala index 1fd8c00..f0cb17f 100644 --- a/src/main/scala/seed/config/util/TomlUtils.scala +++ b/src/main/scala/seed/config/util/TomlUtils.scala @@ -6,7 +6,7 @@ import org.apache.commons.io.FileUtils import seed.{Log, LogLevel} import seed.cli.util.Ansi import seed.model.Build.{PlatformModule, VersionTag} -import seed.model.{Build, Platform} +import seed.model.{Platform, TomlBuild} import toml.{Codec, Value} import scala.util.Try @@ -134,13 +134,13 @@ object TomlUtils { def parseBuildToml( projectPath: Path - )(content: String): Either[Codec.Error, Build] = { + )(content: String): Either[Codec.Error, TomlBuild] = { import toml._ import toml.Codecs._ import seed.config.util.TomlUtils.Codecs._ implicit val pCodec = pathCodec(fixPath(projectPath, _)) - Toml.parseAs[Build](content) + Toml.parseAs[TomlBuild](content) } } diff --git a/src/main/scala/seed/generation/Bloop.scala b/src/main/scala/seed/generation/Bloop.scala index af9a234..7938fa0 100644 --- a/src/main/scala/seed/generation/Bloop.scala +++ b/src/main/scala/seed/generation/Bloop.scala @@ -3,6 +3,7 @@ package seed.generation import java.nio.file.{Files, Path, Paths} import seed.config.BuildConfig.{ + Build, collectJsClassPath, collectJsDeps, collectJvmClassPath, @@ -13,9 +14,9 @@ import seed.config.BuildConfig.{ } import seed.artefact.{ArtefactResolution, Coursier} import seed.cli.util.Ansi -import seed.model.Build.{Module, Project} +import seed.model.Build.Module import seed.model.Platform.{JVM, JavaScript, Native} -import seed.model.{Build, Resolution} +import seed.model.Resolution import seed.Log import seed.config.BuildConfig import seed.generation.util.PathUtil @@ -138,68 +139,50 @@ object Bloop { bloopPath: Path, buildPath: Path, jsOutputPath: Option[Path], - parentModule: Module, - parentClassPaths: List[Path], jsModule: Option[Module], - project: Project, + parentClassPaths: List[Path], resolution: Coursier.ResolutionResult, compilerResolution: List[Coursier.ResolutionResult], - jsdom: Boolean, - emitSourceMaps: Boolean, test: Boolean, optionalArtefacts: Boolean, log: Log - ): Unit = { - import parentModule.{moduleDeps, scalaDeps, sources, targets} - import project.{ - scalaJsVersion, - scalaOptions, - scalaOrganisation, - testFrameworks - } - - val mainClass = jsModule - .flatMap(_.mainClass) - .orElse(parentModule.mainClass) - + ): Unit = jsModule - .orElse(if (!targets.contains(JavaScript)) None else Some(Module())) .foreach { js => + val jsdom = js.jsdom + val emitSourceMaps = js.emitSourceMaps + val mainClass = js.mainClass + val bloopName = if (!test) name else name + "-test" log.info(s"Writing JavaScript module ${Ansi.italic(bloopName)}...") - val scalaVersion = BuildConfig.scalaVersion( - project, - List(js, parentModule.js.getOrElse(Module()), parentModule) - ) - val plugIns = util.ScalaCompiler.compilerPlugIns( build, - parentModule, + js, compilerResolution, JavaScript, - scalaVersion + js.scalaVersion.get ) val resolvedDeps = Coursier.localArtefacts( resolution, - (scalaDeps ++ js.scalaDeps) + collectJsDeps(build, js) .map( dep => ArtefactResolution.javaDepFromScalaDep( dep, JavaScript, - scalaJsVersion.get, - scalaVersion + js.scalaJsVersion.get, + js.scalaVersion.get ) ) - .toSet ++ ArtefactResolution.jsPlatformDeps(build, js), + .toSet ++ ArtefactResolution.jsPlatformDeps(js), optionalArtefacts ) val dependencies = if (test) List(name) else - (moduleDeps ++ js.moduleDeps) + js.moduleDeps .filter(name => BuildConfig.hasTarget(build, name, JavaScript)) .map(name => BuildConfig.targetName(build, name, JavaScript)) @@ -210,8 +193,8 @@ object Bloop { val scalaCompiler = ArtefactResolution.resolveScalaCompiler( compilerResolution, - scalaOrganisation, - scalaVersion, + js.scalaOrganisation.get, + js.scalaVersion.get, resolvedDeps, classPath, optionalArtefacts @@ -223,14 +206,14 @@ object Bloop { bloopPath = bloopPath, dependencies = dependencies, classesDir = classesDir, - sources = sources ++ js.sources, + sources = js.sources, scalaCompiler = Some(scalaCompiler), - scalaOptions = scalaOptions ++ plugIns, - testFrameworks = if (test) testFrameworks else List(), + scalaOptions = js.scalaOptions ++ plugIns, + testFrameworks = if (test) js.testFrameworks else List(), platform = Some( Config.Platform.Js( Config.JsConfig( - version = majorMinorVersion(scalaJsVersion.get), + version = majorMinorVersion(js.scalaJsVersion.get), mode = Config.LinkerMode.Debug, kind = Config.ModuleKindJS.NoModule, emitSourceMaps = emitSourceMaps, @@ -244,7 +227,6 @@ object Bloop { ) ) } - } def writeNativeModule( build: Build, @@ -253,91 +235,54 @@ object Bloop { bloopPath: Path, buildPath: Path, outputPathBinary: Option[Path], - parentModule: Module, - parentClassPaths: List[Path], nativeModule: Option[Module], - project: Project, + parentClassPaths: List[Path], resolution: Coursier.ResolutionResult, compilerResolution: List[Coursier.ResolutionResult], test: Boolean, optionalArtefacts: Boolean, log: Log - ): Unit = { - import parentModule.{moduleDeps, scalaDeps, sources, targets} - import project.{ - scalaNativeVersion, - scalaOptions, - scalaOrganisation, - testFrameworks - } - - val mainClass = nativeModule - .flatMap(_.mainClass) - .orElse(parentModule.mainClass) - - val gc = nativeModule - .flatMap(_.gc) - .orElse(parentModule.gc) - .getOrElse("immix") - val targetTriple = nativeModule - .flatMap(_.targetTriple) - .orElse(parentModule.targetTriple) - .getOrElse("") - val clang = nativeModule - .flatMap(_.clang) - .orElse(parentModule.clang) - .getOrElse(Paths.get("/usr/bin/clang")) - val clangpp = nativeModule - .flatMap(_.clangpp) - .orElse(parentModule.clangpp) - .getOrElse(Paths.get("/usr/bin/clang++")) - val linkStubs = nativeModule.exists(_.linkStubs) || parentModule.linkStubs - val linkerOptions = nativeModule - .flatMap(_.linkerOptions) - .orElse(parentModule.linkerOptions) - .getOrElse(List()) - val compilerOptions = nativeModule - .flatMap(_.compilerOptions) - .orElse(parentModule.compilerOptions) - .getOrElse(List()) - + ): Unit = nativeModule - .orElse(if (!targets.contains(Native)) None else Some(Module())) .foreach { native => + val mainClass = native.mainClass + val gc = native.gc.getOrElse("immix") + val targetTriple = native.targetTriple.getOrElse("") + val clang = native.clang.getOrElse(Paths.get("/usr/bin/clang")) + val clangpp = native.clangpp.getOrElse(Paths.get("/usr/bin/clang++")) + val linkStubs = native.linkStubs + val linkerOptions = native.linkerOptions.getOrElse(List()) + val compilerOptions = native.compilerOptions.getOrElse(List()) + val bloopName = if (!test) name else name + "-test" log.info(s"Writing native module ${Ansi.italic(bloopName)}...") - val modules = - List(native, parentModule.native.getOrElse(Module()), parentModule) - - val scalaVersion = BuildConfig.scalaVersion(project, modules) - val plugIns = util.ScalaCompiler.compilerPlugIns( build, - parentModule, + native, compilerResolution, Native, - scalaVersion + native.scalaVersion.get ) val resolvedDeps = Coursier.localArtefacts( resolution, - (scalaDeps ++ native.scalaDeps) + collectNativeDeps(build, native) .map( dep => ArtefactResolution.javaDepFromScalaDep( dep, Native, - scalaNativeVersion.get, - scalaVersion + native.scalaNativeVersion.get, + native.scalaVersion.get ) ) - .toSet ++ ArtefactResolution.nativePlatformDeps(build, modules), + .toSet ++ ArtefactResolution.nativePlatformDeps(native), optionalArtefacts ) - val nativeLibDep = ArtefactResolution.nativeLibraryDep(build, modules) + val nativeLibDep = ArtefactResolution.nativeLibraryDep(native) val scalaNativelib = resolvedDeps .find(_.javaDep == nativeLibDep) .map(_.libraryJar) @@ -346,7 +291,7 @@ object Bloop { val dependencies = if (test) List(name) else - (moduleDeps ++ native.moduleDeps) + native.moduleDeps .filter(name => BuildConfig.hasTarget(build, name, Native)) .map(name => BuildConfig.targetName(build, name, Native)) @@ -357,8 +302,8 @@ object Bloop { val scalaCompiler = ArtefactResolution.resolveScalaCompiler( compilerResolution, - scalaOrganisation, - scalaVersion, + native.scalaOrganisation.get, + native.scalaVersion.get, resolvedDeps, classPath, optionalArtefacts @@ -370,14 +315,14 @@ object Bloop { bloopPath = bloopPath, dependencies = dependencies, classesDir = classesDir, - sources = sources ++ native.sources, + sources = native.sources, scalaCompiler = Some(scalaCompiler), - scalaOptions = scalaOptions ++ plugIns, - testFrameworks = if (test) testFrameworks else List(), + scalaOptions = native.scalaOptions ++ plugIns, + testFrameworks = if (test) native.testFrameworks else List(), platform = Some( Config.Platform.Native( Config.NativeConfig( - version = scalaNativeVersion.get, + version = native.scalaNativeVersion.get, mode = Config.LinkerMode.Debug, gc = gc, targetTriple = targetTriple, @@ -397,7 +342,6 @@ object Bloop { ) ) } - } def writeJvmModule( build: Build, @@ -405,40 +349,27 @@ object Bloop { projectPath: Path, bloopPath: Path, buildPath: Path, - parentModule: Module, - parentClassPaths: List[Path], jvmModule: Option[Module], - project: Project, + parentClassPaths: List[Path], resolution: Coursier.ResolutionResult, compilerResolution: List[Coursier.ResolutionResult], test: Boolean, optionalArtefacts: Boolean, log: Log - ): Unit = { - import parentModule.{moduleDeps, sources, targets} - import project.{scalaOptions, scalaOrganisation, testFrameworks} - - val mainClass = jvmModule - .flatMap(_.mainClass) - .orElse(parentModule.mainClass) - + ): Unit = jvmModule - .orElse(if (!targets.contains(JVM)) None else Some(Module())) .foreach { jvm => val bloopName = if (!test) name else name + "-test" log.info(s"Writing JVM module ${Ansi.italic(bloopName)}...") - val scalaVersion = BuildConfig.scalaVersion( - project, - List(jvm, parentModule.jvm.getOrElse(Module()), parentModule) - ) - - val javaDeps = parentModule.javaDeps ++ jvm.javaDeps - val scalaDeps = (parentModule.scalaDeps ++ jvm.scalaDeps).map( + val scalaVersion = jvm.scalaVersion.get + val javaDeps = collectJvmJavaDeps(build, jvm) + val scalaDeps = collectJvmScalaDeps(build, jvm).map( dep => ArtefactResolution .javaDepFromScalaDep(dep, JVM, scalaVersion, scalaVersion) ) + val resolvedDeps = Coursier.localArtefacts( resolution, (javaDeps ++ scalaDeps).toSet, @@ -447,7 +378,7 @@ object Bloop { val plugIns = util.ScalaCompiler.compilerPlugIns( build, - parentModule, + jvm, compilerResolution, JVM, scalaVersion @@ -456,7 +387,7 @@ object Bloop { val dependencies = if (test) List(name) else - (moduleDeps ++ jvm.moduleDeps) + jvm.moduleDeps .filter(name => BuildConfig.hasTarget(build, name, JVM)) .map(name => BuildConfig.targetName(build, name, JVM)) @@ -467,7 +398,7 @@ object Bloop { val scalaCompiler = ArtefactResolution.resolveScalaCompiler( compilerResolution, - scalaOrganisation, + jvm.scalaOrganisation.get, scalaVersion, resolvedDeps, classPath, @@ -480,18 +411,17 @@ object Bloop { bloopPath = bloopPath, dependencies = dependencies, classesDir = classesDir, - sources = sources ++ jvm.sources, + sources = jvm.sources, resources = jvm.resources, scalaCompiler = Some(scalaCompiler), - scalaOptions = scalaOptions ++ plugIns, - testFrameworks = if (test) testFrameworks else List(), + scalaOptions = jvm.scalaOptions ++ plugIns, + testFrameworks = if (test) jvm.testFrameworks else List(), platform = Some( Config.Platform - .Jvm(Config.JvmConfig(None, List()), mainClass = mainClass) + .Jvm(Config.JvmConfig(None, List()), mainClass = jvm.mainClass) ) ) } - } def moduleOutputPath( buildPath: Path, @@ -521,17 +451,11 @@ object Bloop { ): Unit = { val isCrossBuild = module.targets.toSet.size > 1 - val jsOutputPath = module.js - .orElse( - if (!module.targets.contains(JavaScript)) None - else Some(Module()) - ) - .map(js => moduleOutputPath(buildPath, js, name + ".js")) - - val nativeOutputPath = - module.native - .orElse(if (!module.targets.contains(Native)) None else Some(Module())) - .map(native => moduleOutputPath(buildPath, native, name + ".run")) + val jsOutputPath = + module.js.map(js => moduleOutputPath(buildPath, js, name + ".js")) + val nativeOutputPath = module.native.map( + native => moduleOutputPath(buildPath, native, name + ".run") + ) jsOutputPath.foreach { path => if (!Files.exists(path.getParent)) Files.createDirectories(path.getParent) @@ -548,14 +472,10 @@ object Bloop { bloopPath, bloopBuildPath, jsOutputPath, - module.copy(scalaDeps = collectJsDeps(build, module)), - collectJsClassPath(bloopBuildPath, build, module), module.js, - build.project, + collectJsClassPath(bloopBuildPath, build, module), resolution, compilerResolution, - jsdom = module.js.exists(_.jsdom), - emitSourceMaps = module.js.exists(_.emitSourceMaps), test = false, optionalArtefacts, log @@ -566,13 +486,8 @@ object Bloop { projectPath, bloopPath, bloopBuildPath, - module.copy( - scalaDeps = collectJvmScalaDeps(build, module), - javaDeps = collectJvmJavaDeps(build, module) - ), - collectJvmClassPath(bloopBuildPath, build, module), module.jvm, - build.project, + collectJvmClassPath(bloopBuildPath, build, module), resolution, compilerResolution, test = false, @@ -586,10 +501,8 @@ object Bloop { bloopPath, bloopBuildPath, nativeOutputPath, - module.copy(scalaDeps = collectNativeDeps(build, module)), - collectJvmClassPath(bloopBuildPath, build, module), module.native, - build.project, + collectJvmClassPath(bloopBuildPath, build, module), resolution, compilerResolution, test = false, @@ -598,10 +511,6 @@ object Bloop { ) module.test.foreach { test => - val targets = if (test.targets.nonEmpty) test.targets else module.targets - val jsdom = test.js.exists(_.jsdom) - val emitSourceMaps = test.js.exists(_.emitSourceMaps) - writeJsModule( build, if (!isCrossBuild) name else name + "-js", @@ -609,18 +518,18 @@ object Bloop { bloopPath, bloopBuildPath, None, - module.copy( - sources = test.sources, - scalaDeps = collectJsDeps(build, module) ++ test.scalaDeps, - targets = targets + // TODO Write helper function for inheriting from base module; must use mergeDeps + test.js.map( + js => + js.copy( + sources = module.js.get.sources ++ js.sources, + scalaDeps = + (collectJsDeps(build, module.js.get) ++ js.scalaDeps).distinct + ) ), collectJsClassPath(bloopBuildPath, build, module), - test.js, - build.project, resolution, compilerResolution, - jsdom, - emitSourceMaps, test = true, optionalArtefacts, log @@ -633,14 +542,15 @@ object Bloop { bloopPath, bloopBuildPath, None, - module.copy( - sources = test.sources, - scalaDeps = collectNativeDeps(build, module) ++ test.scalaDeps, - targets = targets + test.native.map( + native => + native.copy( + sources = module.native.get.sources ++ native.sources, + scalaDeps = + (collectNativeDeps(build, module.native.get) ++ native.scalaDeps).distinct + ) ), collectNativeClassPath(bloopBuildPath, build, module), - test.native, - build.project, resolution, compilerResolution, test = true, @@ -654,15 +564,17 @@ object Bloop { projectPath, bloopPath, bloopBuildPath, - module.copy( - sources = test.sources, - scalaDeps = collectJvmScalaDeps(build, module) ++ test.scalaDeps, - javaDeps = collectJvmJavaDeps(build, module) ++ test.javaDeps, - targets = targets + test.jvm.map( + jvm => + jvm.copy( + sources = module.sources ++ jvm.sources, + scalaDeps = + (collectJvmScalaDeps(build, module.jvm.get) ++ jvm.scalaDeps).distinct, + javaDeps = + (collectJvmJavaDeps(build, module.jvm.get) ++ jvm.javaDeps).distinct + ) ), collectJvmClassPath(bloopBuildPath, build, module), - test.jvm, - build.project, resolution, compilerResolution, test = true, @@ -675,7 +587,7 @@ object Bloop { projectPath = projectPath, name = name + "-test", bloopPath = bloopPath, - dependencies = targets.map(t => name + "-" + t.id + "-test"), + dependencies = test.targets.map(t => name + "-" + t.id + "-test"), classesDir = bloopBuildPath, sources = List(), scalaCompiler = None, @@ -725,7 +637,7 @@ object Bloop { .asScala .foreach(Files.delete) - build.module.foreach { + build.foreach { case (name, module) => log.info(s"Building module ${Ansi.italic(name)}...") buildModule( @@ -737,7 +649,7 @@ object Bloop { resolution, compilerResolution, name, - module, + module.module, optionalArtefacts, log ) diff --git a/src/main/scala/seed/generation/Idea.scala b/src/main/scala/seed/generation/Idea.scala index 05578d4..36cde1d 100644 --- a/src/main/scala/seed/generation/Idea.scala +++ b/src/main/scala/seed/generation/Idea.scala @@ -5,6 +5,7 @@ import java.nio.file.{Files, Path} import scala.collection.JavaConverters._ import org.apache.commons.io.FileUtils import seed.config.BuildConfig.{ + Build, collectJsDeps, collectJsModuleDeps, collectJvmJavaDeps, @@ -59,7 +60,6 @@ object Idea { } def createModule( - build: Build, root: Path, name: String, sources: List[Path], @@ -71,6 +71,7 @@ object Idea { buildPath: Path, modulesPath: Path, librariesPath: Path, + scalaOrganisation: String, scalaVersion: String ): Unit = { val filteredResolvedDeps = @@ -89,7 +90,7 @@ object Idea { ) ) - val scalaDep = build.project.scalaOrganisation + "-" + scalaVersion + val scalaDep = scalaOrganisation + "-" + scalaVersion val classPathOut = buildPath.resolve(name).resolve("main") val testClassPathOut = buildPath.resolve(name).resolve("test") @@ -123,46 +124,49 @@ object Idea { } def createCompilerLibraries( - build: Build, + modules: Build, resolution: List[Coursier.ResolutionResult], librariesPath: Path ): Unit = { - val scalaVersions = (build.module.values.toList.flatMap( - module => - module.jvm.flatMap(_.scalaVersion).toList ++ - module.js.flatMap(_.scalaVersion).toList ++ - module.native.flatMap(_.scalaVersion).toList ++ - module.scalaVersion.toList - ) ++ List(build.project.scalaVersion)).distinct - - scalaVersions.foreach { scalaVersion => - val scalaCompiler = ArtefactResolution.resolveScalaCompiler( - resolution, - build.project.scalaOrganisation, - scalaVersion, - List(), - List(), - optionalArtefacts = false + val scalaVersions = modules.values.toList + .map(_.module) + .flatMap( + module => + (module.jvm.toList ++ module.js.toList ++ module.native.toList) + .map(s => s.scalaOrganisation.get -> s.scalaVersion.get) ) + .distinct - val xml = IdeaFile.createLibrary( - IdeaFile.Library( - name = build.project.scalaOrganisation + "-" + scalaVersion, - compilerInfo = Some( - IdeaFile.CompilerInfo( - scalaVersion, - scalaCompiler.compilerJars.map(_.toString) - ) - ), - classes = scalaCompiler.libraries.map(_.libraryJar.toString), - javaDoc = List(), - sources = List() + scalaVersions.foreach { + case (scalaOrganisation, scalaVersion) => + val scalaCompiler = ArtefactResolution.resolveScalaCompiler( + resolution, + scalaOrganisation, + scalaVersion, + List(), + List(), + optionalArtefacts = false + ) + + val xml = IdeaFile.createLibrary( + IdeaFile.Library( + name = scalaOrganisation + "-" + scalaVersion, + compilerInfo = Some( + IdeaFile.CompilerInfo( + scalaVersion, + scalaCompiler.compilerJars.map(_.toString) + ) + ), + classes = scalaCompiler.libraries.map(_.libraryJar.toString), + javaDoc = List(), + sources = List() + ) ) - ) - val fileName = ideaName(build.project.scalaOrganisation) + "_" + - ideaName(scalaVersion) + ".xml" - FileUtils.write(librariesPath.resolve(fileName).toFile, xml, "UTF-8") + val fileName = ideaName(scalaOrganisation) + "_" + ideaName( + scalaVersion + ) + ".xml" + FileUtils.write(librariesPath.resolve(fileName).toFile, xml, "UTF-8") } } @@ -174,16 +178,14 @@ object Idea { ): Unit = { // Group all modules by additional settings; create compiler configuration // for each unique set of parameters - val modulePlugIns = modules.filter(build.module.contains).map { m => - val module = build.module(m) - val scalaVersion = BuildConfig - .scalaVersion(build.project, module.jvm.toList ++ List(module)) + val modulePlugIns = modules.filter(build.contains).map { m => + val module = build(m).module m -> util.ScalaCompiler.compilerPlugIns( build, - build.module(m), + build(m).module, compilerResolution, JVM, - scalaVersion + module.jvm.getOrElse(module).scalaVersion.get ) } val compilerSettings = @@ -191,13 +193,13 @@ object Idea { case (settings, modules) => val allModules = modules.flatMap { module => val targets = - BuildConfig.moduleTargets(build.module(module), List()) + BuildConfig.moduleTargets(build(module).module, List()) val all = module +: targets .map(target => BuildConfig.targetName(build, module, target)) all.distinct } - (build.project.scalaOptions ++ settings, allModules) + (settings, allModules) } val xml = IdeaFile.createScalaCompiler(compilerSettings) @@ -212,12 +214,12 @@ object Idea { * project will use JVM. */ def buildModule( + build: Build, projectPath: Path, buildPath: Path, ideaPath: Path, modulesPath: Path, librariesPath: Path, - build: Build, compilerResolution: List[Coursier.ResolutionResult], resolution: Coursier.ResolutionResult, name: String, @@ -241,11 +243,7 @@ object Idea { ) List() } else { - val scalaVersion = - BuildConfig.scalaVersion(build.project, List(jsModule, module)) - createModule( - build = build, root = jsModule.root.get, name = moduleName, sources = jsSources, @@ -258,8 +256,8 @@ object Idea { ArtefactResolution.javaDepFromScalaDep( dep, JavaScript, - build.project.scalaJsVersion.get, - scalaVersion + jsModule.scalaJsVersion.get, + jsModule.scalaVersion.get ) ) .toSet, @@ -275,8 +273,8 @@ object Idea { ArtefactResolution.javaDepFromScalaDep( dep, JavaScript, - build.project.scalaJsVersion.get, - scalaVersion + test.scalaJsVersion.get, + test.scalaVersion.get ) ) .toSet, @@ -292,7 +290,8 @@ object Idea { buildPath = buildPath, modulesPath = modulesPath, librariesPath = librariesPath, - scalaVersion = scalaVersion + scalaOrganisation = jsModule.scalaOrganisation.get, + scalaVersion = jsModule.scalaVersion.get ) List(moduleName) @@ -314,13 +313,7 @@ object Idea { ) List() } else { - val scalaVersion = BuildConfig.scalaVersion( - build.project, - List(jvmModule, module) - ) - createModule( - build = build, root = jvmModule.root.get, name = moduleName, sources = jvmSources, @@ -334,8 +327,8 @@ object Idea { ArtefactResolution.javaDepFromScalaDep( dep, JVM, - scalaVersion, - scalaVersion + jvmModule.scalaVersion.get, + jvmModule.scalaVersion.get ) ) .toSet, @@ -352,8 +345,8 @@ object Idea { ArtefactResolution.javaDepFromScalaDep( dep, JVM, - scalaVersion, - scalaVersion + test.scalaVersion.get, + test.scalaVersion.get ) ) .toSet, @@ -369,7 +362,8 @@ object Idea { buildPath = buildPath, modulesPath = modulesPath, librariesPath = librariesPath, - scalaVersion = scalaVersion + scalaOrganisation = jvmModule.scalaOrganisation.get, + scalaVersion = jvmModule.scalaVersion.get ) List(moduleName) @@ -392,25 +386,21 @@ object Idea { ) List() } else { - val scalaVersion = - BuildConfig.scalaVersion(build.project, List(nativeModule, module)) - createModule( - build = build, root = nativeModule.root.get, name = moduleName, sources = nativeSources, tests = nativeTests, resolvedDeps = Coursier.localArtefacts( resolution, - collectNativeDeps(build, module) + collectNativeDeps(null, module) .map( dep => ArtefactResolution.javaDepFromScalaDep( dep, Native, - build.project.scalaNativeVersion.get, - scalaVersion + nativeModule.scalaNativeVersion.get, + nativeModule.scalaVersion.get ) ) .toSet, @@ -420,14 +410,14 @@ object Idea { test => Coursier.localArtefacts( resolution, - collectNativeDeps(build, test) + collectNativeDeps(null, test) .map( dep => ArtefactResolution.javaDepFromScalaDep( dep, Native, - build.project.scalaNativeVersion.get, - scalaVersion + nativeModule.scalaNativeVersion.get, + nativeModule.scalaVersion.get ) ) .toSet, @@ -443,7 +433,8 @@ object Idea { buildPath = buildPath, modulesPath = modulesPath, librariesPath = librariesPath, - scalaVersion = scalaVersion + scalaOrganisation = nativeModule.scalaOrganisation.get, + scalaVersion = nativeModule.scalaVersion.get ) List(moduleName) @@ -463,26 +454,22 @@ object Idea { ) List() } else { - val scalaVersion = - BuildConfig.scalaVersion(build.project, List(module)) - createModule( - build = build, root = module.root.get, name = name, sources = sharedSources, tests = sharedTests, resolvedDeps = Coursier.localArtefacts( resolution, - collectJvmJavaDeps(build, module).toSet ++ - collectJvmScalaDeps(build, module) + collectJvmJavaDeps(null, module).toSet ++ + collectJvmScalaDeps(null, module) .map( dep => ArtefactResolution.javaDepFromScalaDep( dep, JVM, - scalaVersion, - scalaVersion + module.scalaVersion.get, + module.scalaVersion.get ) ) .toSet, @@ -499,8 +486,8 @@ object Idea { ArtefactResolution.javaDepFromScalaDep( dep, JVM, - scalaVersion, - scalaVersion + module.scalaVersion.get, + module.scalaVersion.get ) ) .toSet, @@ -515,7 +502,8 @@ object Idea { buildPath = buildPath, modulesPath = modulesPath, librariesPath = librariesPath, - scalaVersion = scalaVersion + scalaOrganisation = module.scalaOrganisation.get, + scalaVersion = module.scalaVersion.get ) List(name) @@ -534,12 +522,9 @@ object Idea { ) List() } else { - val scalaVersion = - BuildConfig.scalaVersion(build.project, List(module)) val moduleName = name + "-" + targetName createModule( - build = build, root = target.root.get, name = moduleName, sources = List(), @@ -551,7 +536,8 @@ object Idea { buildPath = buildPath, modulesPath = modulesPath, librariesPath = librariesPath, - scalaVersion = scalaVersion + scalaOrganisation = module.scalaOrganisation.get, + scalaVersion = module.scalaVersion.get ) List(moduleName) @@ -583,7 +569,7 @@ object Idea { def build( projectPath: Path, outputPath: Path, - build: Build, + modules: Build, resolution: Coursier.ResolutionResult, compilerResolution: List[Coursier.ResolutionResult], tmpfs: Boolean, @@ -616,32 +602,32 @@ object Idea { .asScala .foreach(Files.delete) - createCompilerLibraries(build, compilerResolution, librariesPath) + createCompilerLibraries(modules, compilerResolution, librariesPath) FileUtils.write( ideaPath.resolve("misc.xml").toFile, IdeaFile.createJdk(jdkVersion = "1.8"), "UTF-8" ) - val modules = build.module.toList.flatMap { + val ideaModules = modules.toList.flatMap { case (name, module) => buildModule( + modules, projectPath, ideaBuildPath, ideaPath, modulesPath, librariesPath, - build, compilerResolution, resolution, name, - module, + module.module, log ) } - createCompilerSettings(build, compilerResolution, ideaPath, modules) - writeModules(projectPath, ideaPath, modulesPath, modules) + createCompilerSettings(modules, compilerResolution, ideaPath, ideaModules) + writeModules(projectPath, ideaPath, modulesPath, ideaModules) log.info("IDEA project has been created") } diff --git a/src/main/scala/seed/generation/util/ScalaCompiler.scala b/src/main/scala/seed/generation/util/ScalaCompiler.scala index e47579d..4d8f389 100644 --- a/src/main/scala/seed/generation/util/ScalaCompiler.scala +++ b/src/main/scala/seed/generation/util/ScalaCompiler.scala @@ -5,6 +5,7 @@ import java.nio.file.Path import seed.artefact.Coursier import seed.config.BuildConfig import seed.artefact.ArtefactResolution +import seed.config.BuildConfig.Build import seed.model.Build.Module import seed.model.Platform.{JavaScript, Native} import seed.model.{Artefact, Build, Platform} @@ -43,9 +44,9 @@ object ScalaCompiler { ): List[String] = { import ArtefactResolution.mergeDeps - val platformVer = BuildConfig.platformVersion(build, module, platform) + val platformVer = BuildConfig.platformVersion(module, platform) val moduleDeps = BuildConfig.collectModuleDeps(build, module, platform) - val modules = moduleDeps.map(build.module) :+ module + val modules = moduleDeps.map(build(_).module) :+ module val artefacts = (if (platform == JavaScript) List(Artefact.ScalaJsCompiler -> platformVer) else if (platform == Native) diff --git a/src/main/scala/seed/model/Build.scala b/src/main/scala/seed/model/Build.scala index 8c1dc3d..57182df 100644 --- a/src/main/scala/seed/model/Build.scala +++ b/src/main/scala/seed/model/Build.scala @@ -4,9 +4,10 @@ import java.nio.file.Path import seed.artefact.MavenCentral -case class Build( +case class TomlBuild( `import`: List[Path] = List(), project: Build.Project, + // TODO currently unused; write test case resolvers: Build.Resolvers = Build.Resolvers(), module: Map[String, Build.Module] ) @@ -58,17 +59,35 @@ object Build { ) case class Project( - scalaVersion: String, + scalaVersion: Option[String], scalaJsVersion: Option[String] = None, scalaNativeVersion: Option[String] = None, scalaOptions: List[String] = List(), - scalaOrganisation: String = Organisation.Lightbend.packageName, + scalaOrganisation: Option[String] = None, testFrameworks: List[String] = List(), compilerDeps: List[ScalaDep] = List() - ) + ) { + def toModule = + Module( + scalaVersion = scalaVersion, + scalaJsVersion = scalaJsVersion, + scalaNativeVersion = scalaNativeVersion, + scalaOptions = scalaOptions, + scalaOrganisation = scalaOrganisation, + testFrameworks = testFrameworks, + compilerDeps = compilerDeps + ) + } + // TODO Instead of using this `case class` directly, create a polymorphic + // version for different platform types case class Module( scalaVersion: Option[String] = None, + scalaJsVersion: Option[String] = None, + scalaNativeVersion: Option[String] = None, + scalaOptions: List[String] = List(), + scalaOrganisation: Option[String] = None, + testFrameworks: List[String] = List(), root: Option[Path] = None, sources: List[Path] = List(), resources: List[Path] = List(), @@ -81,10 +100,10 @@ object Build { // If this was a Path, it would include the directory // relative to the build file. output: Option[String] = None, - // JavaScript + // --- JavaScript jsdom: Boolean = false, emitSourceMaps: Boolean = true, - // Native + // --- Native gc: Option[String] = None, targetTriple: Option[String] = None, clang: Option[Path] = None, @@ -92,6 +111,7 @@ object Build { linkerOptions: Option[List[String]] = None, compilerOptions: Option[List[String]] = None, linkStubs: Boolean = false, + // --- test: Option[Module] = None, js: Option[Module] = None, jvm: Option[Module] = None, diff --git a/src/test/scala/seed/artefact/ArtefactResolutionSpec.scala b/src/test/scala/seed/artefact/ArtefactResolutionSpec.scala index b9bc762..4a8c1c4 100644 --- a/src/test/scala/seed/artefact/ArtefactResolutionSpec.scala +++ b/src/test/scala/seed/artefact/ArtefactResolutionSpec.scala @@ -3,10 +3,10 @@ package seed.artefact import java.nio.file.Paths import minitest.SimpleTestSuite -import seed.model.Build.{JavaDep, Module, Project, ScalaDep, VersionTag} +import seed.config.BuildConfig.ModuleConfig +import seed.model.Build.{JavaDep, Module, ScalaDep, VersionTag} import seed.model.Platform.JavaScript import seed.model.Platform.JVM -import seed.model.Build object ArtefactResolutionSpec extends SimpleTestSuite { test("dependencyFromScalaDep() with Scala.js dependency") { @@ -37,21 +37,22 @@ object ArtefactResolutionSpec extends SimpleTestSuite { } test("Extract platform dependencies of test module in libraryDeps()") { - val build = - Build( - project = Project("2.12.8", scalaJsVersion = Some("0.6.26")), - module = Map( - "a" -> Module( - targets = List(JVM, JavaScript), - test = Some( - Module( - sources = List(Paths.get("a/test")), - scalaDeps = List(ScalaDep("io.monix", "minitest", "2.3.2")) - ) + val build = Map( + "a" -> ModuleConfig( + Module( + scalaVersion = Some("2.12.8"), + scalaJsVersion = Some("0.6.26"), + targets = List(JVM, JavaScript), + test = Some( + Module( + sources = List(Paths.get("a/test")), + scalaDeps = List(ScalaDep("io.monix", "minitest", "2.3.2")) ) ) - ) + ), + Paths.get(".") ) + ) val libraryDeps = ArtefactResolution.allLibraryDeps(build) assertEquals( @@ -64,12 +65,11 @@ object ArtefactResolutionSpec extends SimpleTestSuite { } test("jvmDeps()") { - val build = Build(project = Project("2.12.8"), module = Map()) val module = Module( scalaDeps = List(ScalaDep("io.monix", "minitest", "2.3.2")), javaDeps = List(JavaDep("net.java.dev.jna", "jna", "4.5.1")) ) - val deps = ArtefactResolution.jvmDeps(build, List(module)) + val deps = ArtefactResolution.jvmDeps(module) assertEquals( deps, Set( @@ -80,11 +80,9 @@ object ArtefactResolutionSpec extends SimpleTestSuite { } test("Inherit compiler dependencies") { - val build = Build( - project = Project("2.12.8", scalaJsVersion = Some("0.6.26")), - module = Map() - ) val module = Module( + scalaVersion = Some("2.12.8"), + scalaJsVersion = Some("0.6.26"), targets = List(JVM, JavaScript), compilerDeps = List(ScalaDep("org.scalamacros", "paradise", "2.1.1", VersionTag.Full)), @@ -102,7 +100,7 @@ object ArtefactResolutionSpec extends SimpleTestSuite { ) ) ) - val deps = ArtefactResolution.compilerDeps(build, module) + val deps = ArtefactResolution.compilerDeps(module) assertEquals( deps, @@ -126,11 +124,9 @@ object ArtefactResolutionSpec extends SimpleTestSuite { } test("Compiler dependency with overridden version in platform module") { - val build = Build( - project = Project("2.12.8", scalaJsVersion = Some("0.6.26")), - module = Map() - ) val module = Module( + scalaVersion = Some("2.12.8"), + scalaJsVersion = Some("0.6.26"), targets = List(JVM, JavaScript), compilerDeps = List(ScalaDep("org.scalamacros", "paradise", "2.1.0", VersionTag.Full)), @@ -142,7 +138,7 @@ object ArtefactResolutionSpec extends SimpleTestSuite { ) ) ) - val deps = ArtefactResolution.compilerDeps(build, module) + val deps = ArtefactResolution.compilerDeps(module) assertEquals( deps, diff --git a/src/test/scala/seed/cli/util/TargetSpec.scala b/src/test/scala/seed/cli/util/TargetSpec.scala index 5a9b9d6..c5fce03 100644 --- a/src/test/scala/seed/cli/util/TargetSpec.scala +++ b/src/test/scala/seed/cli/util/TargetSpec.scala @@ -1,28 +1,27 @@ package seed.cli.util +import java.nio.file.Paths + import minitest.SimpleTestSuite +import seed.config.BuildConfig.ModuleConfig import seed.model.{Build, Platform} import seed.model.Build.Module object TargetSpec extends SimpleTestSuite { test("Parse module string") { assertEquals( - Target.parseModuleString( - Build(project = Build.Project(""), module = Map()) - )(""), + Target.parseModuleString(Map())(""), Left("Module name cannot be empty") ) assertEquals( - Target.parseModuleString( - Build(project = Build.Project(""), module = Map()) - )("test"), + Target.parseModuleString(Map())("test"), Left(s"Invalid module name: ${Ansi.italic("test")}. Valid names: ") ) assertEquals( Target.parseModuleString( - Build(project = Build.Project(""), module = Map("test" -> Module())) + Map("test" -> ModuleConfig(Module(), Paths.get("."))) )("test:jvm"), Left(s"Invalid build target ${Ansi.italic("jvm")} provided") ) @@ -30,9 +29,11 @@ object TargetSpec extends SimpleTestSuite { assertEquals( Target .parseModuleString( - Build( - project = Build.Project(""), - module = Map("test" -> Module(targets = List(Platform.JVM))) + Map( + "test" -> ModuleConfig( + Module(targets = List(Platform.JVM)), + Paths.get(".") + ) ) )("test:jvm") .isRight, @@ -41,7 +42,7 @@ object TargetSpec extends SimpleTestSuite { assertEquals( Target.parseModuleString( - Build(project = Build.Project(""), module = Map("test" -> Module())) + Map("test" -> ModuleConfig(Module(), Paths.get("."))) )("test:custom"), Left(s"Invalid build target ${Ansi.italic("custom")} provided") ) @@ -49,10 +50,11 @@ object TargetSpec extends SimpleTestSuite { assertEquals( Target .parseModuleString( - Build( - project = Build.Project(""), - module = - Map("test" -> Module(target = Map("custom" -> Build.Target()))) + Map( + "test" -> ModuleConfig( + Module(target = Map("custom" -> Build.Target())), + Paths.get(".") + ) ) )("test:custom") .isRight, diff --git a/src/test/scala/seed/config/BuildConfigSpec.scala b/src/test/scala/seed/config/BuildConfigSpec.scala index 76a1f45..e2d3b6a 100644 --- a/src/test/scala/seed/config/BuildConfigSpec.scala +++ b/src/test/scala/seed/config/BuildConfigSpec.scala @@ -12,8 +12,8 @@ import seed.generation.util.BuildUtil import seed.model.Build import seed.model.Build.{Project, ScalaDep, VersionTag} import seed.model.Platform.{JVM, JavaScript} - import BuildUtil.tempPath +import seed.config.BuildConfig.{ModuleConfig, Result} object BuildConfigSpec extends SimpleTestSuite { test("Resolve absolute project path") { @@ -29,10 +29,10 @@ object BuildConfigSpec extends SimpleTestSuite { "UTF-8" ) - val BuildConfig.Result(_, projectPath, moduleProjectPaths) = + val BuildConfig.Result(projectPath, modules) = BuildConfig.load(tempPath.resolve("a.toml"), Log.urgent).get assertEquals(projectPath, tempPath) - assertEquals(moduleProjectPaths, Map("example" -> tempPath)) + assertEquals(modules, Map("example" -> tempPath)) } test("Resolve relative project path") { @@ -48,10 +48,10 @@ object BuildConfigSpec extends SimpleTestSuite { "UTF-8" ) - val BuildConfig.Result(_, projectPath, moduleProjectPaths) = + val BuildConfig.Result(projectPath, modules) = BuildConfig.load(Paths.get("test/a.toml"), Log.urgent).get assertEquals(projectPath, Paths.get("test")) - assertEquals(moduleProjectPaths, Map("example" -> Paths.get("test"))) + assertEquals(modules, Map("example" -> Paths.get("test"))) Files.delete(Paths.get("test/a.toml")) } @@ -88,10 +88,10 @@ object BuildConfigSpec extends SimpleTestSuite { "UTF-8" ) - val BuildConfig.Result(_, projectPath, moduleProjectPaths) = + val BuildConfig.Result(projectPath, modules) = BuildConfig.load(tempPath.resolve("seed-root"), Log.urgent).get assertEquals( - moduleProjectPaths, + modules, Map( "root" -> tempPath.resolve("seed-root"), "child" -> tempPath.resolve("seed-root").resolve("child") @@ -123,20 +123,15 @@ object BuildConfigSpec extends SimpleTestSuite { """.stripMargin val buildRaw = TomlUtils.parseBuildToml(Paths.get("."))(toml) - val (build, _) = BuildConfig.processBuild( + val build = BuildConfig.processBuild( buildRaw.right.get, Paths.get("."), - _ => - Some( - ( - Build(project = Project(scalaVersion = "2.12.8"), module = Map()), - Map() - ) - ) + _ => Some(Result(Paths.get("."), Map())), + Log.urgent ) assertEquals( - build.module("example").test.get.targets, + build("example").module.test.get.targets, List(JavaScript, JVM) ) } @@ -154,23 +149,20 @@ object BuildConfigSpec extends SimpleTestSuite { """.stripMargin val buildRaw = TomlUtils.parseBuildToml(Paths.get("."))(toml) - val (build, _) = BuildConfig.processBuild( + val build = BuildConfig.processBuild( buildRaw.right.get, Paths.get("."), - _ => - Some( - Build(project = Project(scalaVersion = "2.12.8"), module = Map()), - Map() - ) + _ => Some(Result(Paths.get("."), Map())), + Log.urgent ) assertEquals( - build.module("example").jvm.get.scalaDeps, + build("example").module.jvm.get.scalaDeps, List(ScalaDep("org.scalameta", "interactive", "4.1.0", VersionTag.Full)) ) } - test("Copy compilerDeps from project definitions to modules") { + test("Copy settings from project definitions to modules") { val fooToml = """ |import = ["bar"] | @@ -182,6 +174,7 @@ object BuildConfigSpec extends SimpleTestSuite { | |[module.foo] |sources = ["foo-jvm/src"] + | |[module.foo.js] |sources = ["foo-js/src"] |compilerDeps = [ @@ -201,23 +194,32 @@ object BuildConfigSpec extends SimpleTestSuite { """.stripMargin val buildRaw = TomlUtils.parseBuildToml(Paths.get("."))(fooToml) - val (build, _) = BuildConfig.processBuild( + val build = BuildConfig.processBuild( buildRaw.right.get, Paths.get("."), _ => TomlUtils .parseBuildToml(Paths.get("."))(barToml) .toOption - .map(build => build -> Map.empty) + .map( + x => + Result( + Paths.get("."), + x.module.mapValues(m => ModuleConfig(m, Paths.get("."))) + ) + ), + Log.urgent ) + assertEquals(build("foo").module.scalaVersion, Some("2.12.8")) + assertEquals( - build.module("foo").compilerDeps, + build("foo").module.compilerDeps, List(ScalaDep("foo", "foo", "1.0", VersionTag.Full)) ) assertEquals( - build.module("foo").js.get.compilerDeps, + build("foo").module.js.get.compilerDeps, List( ScalaDep("foo", "foo", "1.0", VersionTag.Full), ScalaDep("foo-js", "foo-js", "1.0", VersionTag.Full) @@ -225,8 +227,49 @@ object BuildConfigSpec extends SimpleTestSuite { ) assertEquals( - build.module("bar").compilerDeps, + build("bar").module.compilerDeps, List(ScalaDep("bar", "bar", "1.0", VersionTag.Full)) ) } + + test("Inheritance of settings") { + val fooToml = """ + |[project] + |scalaVersion = "2.12.8" + |testFrameworks = ["a.b"] + | + |[module.foo] + |scalaVersion = "2.11.11" + |sources = ["foo-jvm/src"] + | + |[module.foo.js] + |sources = ["foo-js/src"] + |testFrameworks = ["c.d"] + |compilerDeps = [ + | ["foo-js", "foo-js", "1.0", "full"] + |] + | + |[module.bar] + |testFrameworks = ["a.b"] + |sources = ["foo-jvm/src"] + """.stripMargin + + val buildRaw = TomlUtils.parseBuildToml(Paths.get("."))(fooToml) + val build = BuildConfig.processBuild( + buildRaw.right.get, + Paths.get("."), + _ => None, + Log.urgent + ) + + assertEquals(build("foo").module.scalaVersion, Some("2.11.11")) + assertEquals(build("foo").module.js.get.scalaVersion, Some("2.11.11")) + assertEquals(build("bar").module.scalaVersion, Some("2.12.8")) + + assertEquals(build("foo").module.testFrameworks, List("a.b")) + assertEquals(build("foo").module.js.get.testFrameworks, List("a.b", "c.d")) + } + + // TODO Test case for inheritance of settings across files + // TODO Test case for inheritance of Scala options } diff --git a/src/test/scala/seed/generation/BloopIntegrationSpec.scala b/src/test/scala/seed/generation/BloopIntegrationSpec.scala index e4d8bb0..9a85ea7 100644 --- a/src/test/scala/seed/generation/BloopIntegrationSpec.scala +++ b/src/test/scala/seed/generation/BloopIntegrationSpec.scala @@ -58,7 +58,7 @@ object BloopIntegrationSpec extends TestSuite[Unit] { testAsync( "Build project with compiler plug-in defined on cross-platform module" ) { _ => - val BuildConfig.Result(build, projectPath, _) = + val BuildConfig.Result(projectPath, build) = BuildConfig.load(Paths.get("test/example-paradise"), Log.urgent).get val buildPath = tempPath.resolve("example-paradise") Files.createDirectory(buildPath) @@ -81,7 +81,7 @@ object BloopIntegrationSpec extends TestSuite[Unit] { testAsync("Build project with compiler plug-in defined on platform modules") { _ => - val BuildConfig.Result(build, projectPath, _) = BuildConfig + val BuildConfig.Result(projectPath, build) = BuildConfig .load(Paths.get("test/example-paradise-platform"), Log.urgent) .get val buildPath = tempPath.resolve("example-paradise-platform") @@ -104,7 +104,7 @@ object BloopIntegrationSpec extends TestSuite[Unit] { } testAsync("Link JavaScript modules with custom target path") { _ => - val BuildConfig.Result(build, projectPath, _) = + val BuildConfig.Result(projectPath, build) = BuildConfig.load(Paths.get("test/submodule-output-path"), Log.urgent).get val buildPath = tempPath.resolve("submodule-output-path") Files.createDirectory(buildPath) @@ -140,7 +140,7 @@ object BloopIntegrationSpec extends TestSuite[Unit] { testAsync("Build project with overridden compiler plug-in version") { _ => val projectPath = Paths.get("test/example-paradise-versions") - val BuildConfig.Result(build, _, _) = + val BuildConfig.Result(_, build) = BuildConfig.load(projectPath, Log.urgent).get val buildPath = tempPath.resolve("example-paradise-versions") Files.createDirectory(buildPath) @@ -221,7 +221,7 @@ object BloopIntegrationSpec extends TestSuite[Unit] { } testAsync("Build modules with different Scala versions") { _ => - val BuildConfig.Result(build, projectPath, _) = BuildConfig + val BuildConfig.Result(projectPath, build) = BuildConfig .load(Paths.get("test/multiple-scala-versions"), Log.urgent) .get val buildPath = tempPath.resolve("multiple-scala-versions-bloop") @@ -255,7 +255,7 @@ object BloopIntegrationSpec extends TestSuite[Unit] { ): Future[Unit] = { val path = Paths.get(s"test/$name") - val BuildConfig.Result(build, projectPath, _) = + val BuildConfig.Result(projectPath, build) = BuildConfig.load(path, Log.urgent).get val buildPath = tempPath.resolve(name) Files.createDirectory(buildPath) diff --git a/src/test/scala/seed/generation/IdeaSpec.scala b/src/test/scala/seed/generation/IdeaSpec.scala index 0feef77..0a3180a 100644 --- a/src/test/scala/seed/generation/IdeaSpec.scala +++ b/src/test/scala/seed/generation/IdeaSpec.scala @@ -8,11 +8,11 @@ import seed.Cli.{Command, PackageConfig} import seed.{Log, cli} import seed.artefact.ArtefactResolution import seed.config.BuildConfig +import seed.config.BuildConfig.ModuleConfig import seed.generation.util.PathUtil -import seed.model.Build.{Module, Project} +import seed.model.Build.{Module, Project, Resolvers} import seed.model.Platform.JVM import seed.model.{Build, Config} - import seed.generation.util.BuildUtil.tempPath object IdeaSpec extends SimpleTestSuite { @@ -53,39 +53,37 @@ object IdeaSpec extends SimpleTestSuite { test("Generate modules") { val build = - Build( - project = Project("2.12.8"), - module = Map( - "a" -> Module( - targets = List(JVM), - jvm = Some( - Module( - root = Some(Paths.get("a")), - sources = List(Paths.get("a/src")) - ) - ), - target = Map("assets" -> Build.Target()) - ), - "b" -> Module( - targets = List(JVM), - jvm = Some( - Module( - root = Some(Paths.get("b")), - sources = List(Paths.get("b/src")) - ) - ), - target = Map("assets" -> Build.Target(Some(Paths.get("b/assets")))) + Map( + "a" -> Module( + scalaVersion = Some("2.12.8"), + targets = List(JVM), + jvm = Some( + Module( + root = Some(Paths.get("a")), + sources = List(Paths.get("a/src")) + ) ), - "c" -> Module( - // Module that only has test sources - targets = List(JVM), - jvm = Some(Module(root = Some(Paths.get("c")))), - test = Some( - Module(jvm = Some(Module(sources = List(Paths.get("c/test"))))) + target = Map("assets" -> Build.Target()) + ), + "b" -> Module( + targets = List(JVM), + jvm = Some( + Module( + root = Some(Paths.get("b")), + sources = List(Paths.get("b/src")) ) + ), + target = Map("assets" -> Build.Target(Some(Paths.get("b/assets")))) + ), + "c" -> Module( + // Module that only has test sources + targets = List(JVM), + jvm = Some(Module(root = Some(Paths.get("c")))), + test = Some( + Module(jvm = Some(Module(sources = List(Paths.get("c/test"))))) ) ) - ) + ).mapValues(m => ModuleConfig(m, Paths.get("."))) val projectPath = Paths.get(".") val outputPath = Paths.get("/tmp") @@ -94,6 +92,7 @@ object IdeaSpec extends SimpleTestSuite { val (_, platformResolution, compilerResolution) = ArtefactResolution.resolution( seed.model.Config(), + Resolvers(), build, packageConfig, optionalArtefacts = false, @@ -122,7 +121,7 @@ object IdeaSpec extends SimpleTestSuite { } test("Generate project with custom compiler options") { - val BuildConfig.Result(build, projectPath, _) = + val BuildConfig.Result(projectPath, build) = BuildConfig.load(Paths.get("test/compiler-options"), Log.urgent).get val packageConfig = PackageConfig( tmpfs = false, @@ -164,7 +163,7 @@ object IdeaSpec extends SimpleTestSuite { } test("Generate project with different Scala versions") { - val BuildConfig.Result(build, projectPath, _) = BuildConfig + val BuildConfig.Result(projectPath, build) = BuildConfig .load(Paths.get("test/multiple-scala-versions"), Log.urgent) .get val packageConfig = PackageConfig( diff --git a/src/test/scala/seed/generation/PackageSpec.scala b/src/test/scala/seed/generation/PackageSpec.scala index d33aade..e0c3fa5 100644 --- a/src/test/scala/seed/generation/PackageSpec.scala +++ b/src/test/scala/seed/generation/PackageSpec.scala @@ -22,7 +22,7 @@ object PackageSpec extends TestSuite[Unit] { testAsync("Package modules with same package") { _ => val path = Paths.get("test/package-modules") - val BuildConfig.Result(build, projectPath, _) = + val BuildConfig.Result(projectPath, build) = BuildConfig.load(path, Log.urgent).get val outputPath = tempPath.resolve("package-modules") Files.createDirectory(outputPath) diff --git a/src/test/scala/seed/generation/util/ProjectGeneration.scala b/src/test/scala/seed/generation/util/ProjectGeneration.scala index 035b53a..06b6686 100644 --- a/src/test/scala/seed/generation/util/ProjectGeneration.scala +++ b/src/test/scala/seed/generation/util/ProjectGeneration.scala @@ -1,12 +1,13 @@ package seed.generation.util -import java.nio.file.{Files, Path} +import java.nio.file.{Files, Path, Paths} import org.apache.commons.io.FileUtils import seed.Log import seed.artefact.{ArtefactResolution, Coursier} +import seed.config.BuildConfig.{Build, ModuleConfig} import seed.generation.Bloop -import seed.model.Build.JavaDep +import seed.model.Build.{JavaDep, Resolvers} import seed.model.{Build, Platform} object ProjectGeneration { @@ -28,7 +29,7 @@ object ProjectGeneration { val resolution = Coursier.resolveAndDownload( platformDeps ++ libraryDeps, - build.resolvers, + Resolvers(), resolvedIvyPath, resolvedCachePath, optionalArtefacts = false, @@ -40,7 +41,7 @@ object ProjectGeneration { d => Coursier.resolveAndDownload( d, - build.resolvers, + Resolvers(), resolvedIvyPath, resolvedCachePath, optionalArtefacts = false, @@ -49,7 +50,7 @@ object ProjectGeneration { ) ) - build.module.foreach { + build.foreach { case (id, module) => Bloop.buildModule( projectPath, @@ -60,7 +61,7 @@ object ProjectGeneration { resolution, compilerResolution, id, - module, + module.module, optionalArtefacts = false, Log.urgent ) @@ -68,19 +69,24 @@ object ProjectGeneration { } def generateJavaDepBloopProject(projectPath: Path): Unit = { - val build = Build( - project = Build.Project("2.12.8"), - module = Map( - "base" -> Build.Module( + val build = Map( + "base" -> ModuleConfig( + Build.Module( + scalaVersion = Some("2.12.8"), targets = List(Platform.JVM), javaDeps = List(JavaDep("org.postgresql", "postgresql", "42.2.5")) ), - "example" -> Build.Module( + Paths.get(".") + ), + "example" -> ModuleConfig( + Build.Module( + scalaVersion = Some("2.12.8"), moduleDeps = List("base"), targets = List(Platform.JVM), jvm = Some(Build.Module()), test = Some(Build.Module(jvm = Some(Build.Module()))) - ) + ), + Paths.get(".") ) ) @@ -92,13 +98,15 @@ object ProjectGeneration { val sourcePath = projectPath.resolve("src") Files.createDirectories(sourcePath) - val build = Build( - project = Build.Project("2.12.8", scalaJsVersion = Some("0.6.26")), - module = Map( - "example" -> Build.Module( + val build = Map( + "example" -> ModuleConfig( + Build.Module( + scalaVersion = Some("2.12.8"), + scalaJsVersion = Some("0.6.26"), sources = List(sourcePath), targets = List(Platform.JVM, Platform.JavaScript) - ) + ), + Paths.get(".") ) )