Skip to content

Commit

Permalink
Include scope test in export to sbt (#523)
Browse files Browse the repository at this point in the history
* Include scope test in export to sbt and mill
  • Loading branch information
lwronski committed Jan 11, 2022
1 parent 5644277 commit da7ce53
Show file tree
Hide file tree
Showing 10 changed files with 239 additions and 88 deletions.
49 changes: 39 additions & 10 deletions modules/cli/src/main/scala/scala/cli/commands/Export.scala
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ object Export extends ScalaCommand[ExportOptions] {
inputs: Inputs,
buildOptions: BuildOptions,
logger: Logger,
verbosity: Int
verbosity: Int,
scope: Scope
): Either[BuildException, (Sources, BuildOptions)] = either {

logger.log("Preparing build")
Expand All @@ -33,7 +34,7 @@ object Export extends ScalaCommand[ExportOptions] {
)
}
val scopedSources = value(crossSources.scopedSources(buildOptions))
val sources = scopedSources.sources(Scope.Main, crossSources.sharedOptions(buildOptions))
val sources = scopedSources.sources(scope, crossSources.sharedOptions(buildOptions))

if (verbosity >= 3)
pprint.stderr.log(sources)
Expand All @@ -44,8 +45,9 @@ object Export extends ScalaCommand[ExportOptions] {
}

// FIXME Auto-update those
def sbtBuildTool(extraSettings: Seq[String]) = Sbt("1.5.5", extraSettings)
def millBuildTool(cache: FileCache[Task]) = {
def sbtBuildTool(extraSettings: Seq[String], sbtVersion: String, logger: Logger) =
Sbt(sbtVersion, extraSettings, logger)
def millBuildTool(cache: FileCache[Task], logger: Logger) = {
val launcherArtifacts = Seq(
os.rel / "mill" -> "https://github.com/lefou/millw/raw/main/millw",
os.rel / "mill.bat" -> "https://github.com/lefou/millw/raw/main/millw.bat"
Expand All @@ -65,7 +67,8 @@ object Export extends ScalaCommand[ExportOptions] {
val launchers = launchersTask.unsafeRun()(cache.ec)
Mill(
"0.9.8",
launchers
launchers,
logger
)
}

Expand All @@ -76,21 +79,47 @@ object Export extends ScalaCommand[ExportOptions] {
CurrentParams.workspaceOpt = Some(inputs.workspace)
val baseOptions = options.buildOptions

val (sources, options0) =
prepareBuild(inputs, baseOptions, logger, options.shared.logging.verbosity)
val (sourcesMain, optionsMain0) =
prepareBuild(inputs, baseOptions, logger, options.shared.logging.verbosity, Scope.Main)
.orExit(logger)
val (sourcesTest, optionsTest0) =
prepareBuild(inputs, baseOptions, logger, options.shared.logging.verbosity, Scope.Test)
.orExit(logger)

for {
svMain <- optionsMain0.scalaOptions.scalaVersion
svTest <- optionsTest0.scalaOptions.scalaVersion
} if (svMain != svTest) {
System.err.println(
s"""Detected different Scala versions in main and test scopes.
|Please set the Scala version explicitly in the main and test scope with using directives or pass -S, --scala-version as parameter""".stripMargin
)
sys.exit(1)
}

if (
optionsMain0.scalaOptions.scalaVersion.isEmpty && optionsTest0.scalaOptions.scalaVersion.nonEmpty
) {
System.err.println(
s"""Detected that the Scala version is only set in test scope.
|Please set the Scala version explicitly in the main and test scopes with using directives or pass -S, --scala-version as parameter""".stripMargin
)
sys.exit(1)
}

def sbtBuildTool0 = sbtBuildTool(options.sbtSetting.map(_.trim).filter(_.nonEmpty))
val sbtVersion = options.sbtVersion.getOrElse("1.6.1")
def sbtBuildTool0 =
sbtBuildTool(options.sbtSetting.map(_.trim).filter(_.nonEmpty), sbtVersion, logger)

val buildTool =
if (options.sbt.getOrElse(false))
sbtBuildTool0
else if (options.mill.getOrElse(false))
millBuildTool(options.shared.coursierCache)
millBuildTool(options.shared.coursierCache, logger)
else
sbtBuildTool0

val project = buildTool.export(options0, sources)
val project = buildTool.export(optionsMain0, optionsTest0, sourcesMain, sourcesTest)

val output = options.output.getOrElse("dest")
val dest = os.Path(output, os.pwd)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ final case class ExportOptions(
@Name("setting")
@Group("Build Tool export options")
sbtSetting: List[String] = Nil,

@Group("Build Tool export options")
sbtVersion: Option[String] = None,
@Name("o")
@Group("Build Tool export options")
output: Option[String] = None
Expand Down
7 changes: 6 additions & 1 deletion modules/cli/src/main/scala/scala/cli/export/BuildTool.scala
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,12 @@ import scala.build.Sources
import scala.build.options.{BuildOptions, ScalaJsOptions}

abstract class BuildTool extends Product with Serializable {
def export(options: BuildOptions, sources: Sources): Project
def export(
optionsMain: BuildOptions,
optionsTest: BuildOptions,
sourcesMain: Sources,
sourcesTest: Sources
): Project
}

object BuildTool {
Expand Down
82 changes: 63 additions & 19 deletions modules/cli/src/main/scala/scala/cli/export/Mill.scala
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,26 @@ import coursier.parse.RepositoryParser
import dependency.NoAttributes

import java.nio.charset.StandardCharsets
import java.nio.file.Path

import scala.build.Sources
import scala.build.internal.Constants
import scala.build.internal.Runner.frameworkName
import scala.build.options.{BuildOptions, Platform, ScalaJsOptions, ScalaNativeOptions}
import scala.build.testrunner.AsmTestRunner
import scala.build.{Logger, Sources}

final case class Mill(
millVersion: String,
launchers: Seq[(os.RelPath, Array[Byte])]
launchers: Seq[(os.RelPath, Array[Byte])],
logger: Logger
) extends BuildTool {

private val charSet = StandardCharsets.UTF_8

private def sourcesSettings(sources: Sources): MillProject = {
val allSources = BuildTool.sources(sources, charSet)
MillProject(mainSources = allSources)
private def sourcesSettings(mainSources: Sources, testSources: Sources): MillProject = {
val mainSources0 = BuildTool.sources(mainSources, charSet)
val testSources0 = BuildTool.sources(testSources, charSet)
MillProject(mainSources = mainSources0, testSources = testSources0)
}

private def scalaVersionSettings(options: BuildOptions, sources: Sources): MillProject = {
Expand Down Expand Up @@ -57,9 +62,13 @@ final case class Mill(
MillProject(scalaNativeVersion = scalaNativeVersion)
}

private def dependencySettings(options: BuildOptions): MillProject = {
val deps = options.classPathOptions.extraDependencies.map(_.value.render)
MillProject(deps = deps)
private def dependencySettings(
mainOptions: BuildOptions,
testOptions: BuildOptions
): MillProject = {
val mainDeps = mainOptions.classPathOptions.extraDependencies.map(_.value.render)
val testDeps = testOptions.classPathOptions.extraDependencies.map(_.value.render)
MillProject(mainDeps = mainDeps, testDeps = testDeps)
}

private def repositorySettings(options: BuildOptions): MillProject = {
Expand All @@ -85,6 +94,23 @@ final case class Mill(
)
}

private def customResourcesSettings(options: BuildOptions): MillProject = {

val customResourcesDecls =
if (options.classPathOptions.resourcesDir.isEmpty) Nil
else {
val resources =
options.classPathOptions.resourcesDir.map(p => s"""PathRef(os.Path("$p"))""")
Seq(
s"""def runClasspath = super.runClasspath() ++ Seq(${resources.mkString(", ")})"""
)
}

MillProject(
extraDecls = customResourcesDecls
)
}

private def customJarsSettings(options: BuildOptions): MillProject = {

val customCompileOnlyJarsDecls =
Expand All @@ -111,7 +137,18 @@ final case class Mill(

private def testFrameworkSettings(options: BuildOptions): MillProject = {

val testFrameworkDecls = options.testOptions.frameworkOpt match {
val testClassPath: Seq[Path] = options.artifacts(logger) match {
case Right(artifacts) => artifacts.classPath
case Left(exception) =>
logger.debug(exception.message)
Seq.empty
}
val parentInspector = new AsmTestRunner.ParentInspector(testClassPath)
val frameworkName0 = options.testOptions.frameworkOpt.orElse {
frameworkName(testClassPath, parentInspector).toOption
}

val testFrameworkDecls = frameworkName0 match {
case None => Nil
case Some(fw) =>
Seq(s"""def testFramework = "$fw"""")
Expand All @@ -122,28 +159,35 @@ final case class Mill(
)
}

def export(options: BuildOptions, sources: Sources): MillProject = {
def export(
optionsMain: BuildOptions,
optionsTest: BuildOptions,
sourcesMain: Sources,
sourcesTest: Sources
): MillProject = {

// FIXME Put a sensible value in MillProject.nameOpt

val baseSettings = MillProject(
millVersion = Some(millVersion),
launchers = launchers,
mainClass = options.mainClass
mainClass = optionsMain.mainClass
)

val settings = Seq(
baseSettings,
sourcesSettings(sources),
scalaVersionSettings(options, sources),
dependencySettings(options),
repositorySettings(options),
if (options.platform.value == Platform.JS) scalaJsSettings(options.scalaJsOptions)
sourcesSettings(sourcesMain, sourcesTest),
scalaVersionSettings(optionsMain, sourcesMain),
dependencySettings(optionsMain, optionsTest),
repositorySettings(optionsMain),
if (optionsMain.platform.value == Platform.JS) scalaJsSettings(optionsMain.scalaJsOptions)
else MillProject(),
if (options.platform.value == Platform.Native) scalaNativeSettings(options.scalaNativeOptions)
if (optionsMain.platform.value == Platform.Native)
scalaNativeSettings(optionsMain.scalaNativeOptions)
else MillProject(),
customJarsSettings(options),
testFrameworkSettings(options)
customResourcesSettings(optionsMain),
customJarsSettings(optionsMain),
testFrameworkSettings(optionsTest)
)

settings.foldLeft(MillProject())(_ + _)
Expand Down
14 changes: 7 additions & 7 deletions modules/cli/src/main/scala/scala/cli/export/MillProject.scala
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ import scala.util.Properties

final case class MillProject(
millVersion: Option[String] = None,
deps: Seq[String] = Nil,
mainDeps: Seq[String] = Nil,
testDeps: Seq[String] = Nil,
scalaVersion: Option[String] = None,
scalaJsVersion: Option[String] = None,
scalaNativeVersion: Option[String] = None,
Expand Down Expand Up @@ -62,7 +63,7 @@ final case class MillProject(
val maybeScalaVer = scalaVersion.fold("") { sv =>
s"""def scalaVersion = "$sv"""" + nl
}
val maybeDeps =
def maybeDeps(deps: Seq[String]) =
if (deps.isEmpty) ""
else {
val depLen = deps.length
Expand Down Expand Up @@ -91,24 +92,23 @@ final case class MillProject(
|object $escapedName extends $parentModule {
| $maybeScalaVer
| $extraDecs
| $maybeDeps
| ${maybeDeps(mainDeps)}
| $maybeMain
| ${extraDecls.map(" " + _ + nl).mkString}
|
| object test extends Tests {
| // Scala CLI doesn't distinguish main and test sources for now.
| def sources = T.sources(super.sources() ++ $escapedName.sources())
| ${maybeDeps(testDeps)}
| ${extraTestDecls.map(" " + _ + nl).mkString}
| }
|}
|""".stripMargin

for ((path, language, content) <- mainSources) {
val path0 = dir / name / "src" / path
val path0 = dir / name / "src" / "main" / "scala" / path
os.write(path0, content, createFolders = true)
}
for ((path, language, content) <- testSources) {
val path0 = dir / name / "src" / "test" / path
val path0 = dir / name / "test" / "src" / "test" / path
os.write(path0, content, createFolders = true)
}

Expand Down
Loading

0 comments on commit da7ce53

Please sign in to comment.