Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,14 @@ import java.util.Locale

import scala.build.{Inputs, Os, Sources}
import scala.build.internal.AmmUtil
import scala.build.options.{BuildOptions, BuildRequirements, ClassPathOptions, ScalaOptions}
import scala.build.options.{
BuildOptions,
BuildRequirements,
ClassPathOptions,
ScalaJsOptions,
ScalaNativeOptions,
ScalaOptions
}
import scala.collection.JavaConverters._

case object ScalaPreprocessor extends Preprocessor {
Expand Down Expand Up @@ -105,8 +112,33 @@ case object ScalaPreprocessor extends Preprocessor {
scalaVersion = Some(scalaVer)
)
)
case _ =>
sys.error(s"Unrecognized using directive: ${dir.values.mkString(" ")}")
case Seq("repository", repo) if repo.nonEmpty =>
BuildOptions(
classPathOptions = ClassPathOptions(
extraRepositories = Seq(repo)
)
)
case other =>
val maybeOptions =
// TODO Accept several platforms for cross-compilation
if (other.lengthCompare(1) == 0)
isPlatform(normalizePlatform(other.head)).map {
case BuildRequirements.Platform.JVM =>
BuildOptions()
case BuildRequirements.Platform.JS =>
BuildOptions(
scalaJsOptions = ScalaJsOptions(enable = true)
)
case BuildRequirements.Platform.Native =>
BuildOptions(
scalaNativeOptions = ScalaNativeOptions(enable = true)
)
}
else
None
maybeOptions.getOrElse {
sys.error(s"Unrecognized using directive: ${other.mkString(" ")}")
}
}
}
.foldLeft(BuildOptions())(_ orElse _)
Expand Down
1 change: 1 addition & 0 deletions modules/cli/src/main/scala/scala/cli/ScalaCli.scala
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ object ScalaCli extends CommandsEntryPoint {
Clean,
Compile,
Directories,
Export,
InstallCompletions,
Metabrowse,
Repl,
Expand Down
69 changes: 69 additions & 0 deletions modules/cli/src/main/scala/scala/cli/commands/Export.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package scala.cli.commands

import caseapp._

import scala.build.{BloopBuildClient, Build, CrossSources, Inputs, Logger, Sources}
import scala.build.internal.CustomCodeWrapper
import scala.build.options.BuildOptions
import scala.build.GeneratedSource

import scala.cli.export._

object Export extends ScalaCommand[ExportOptions] {

private def prepareBuild(
inputs: Inputs,
buildOptions: BuildOptions,
logger: Logger,
verbosity: Int
): (Sources, BuildOptions) = {

logger.log("Preparing build")

val crossSources = CrossSources.forInputs(
inputs,
Sources.defaultPreprocessors(
buildOptions.scriptOptions.codeWrapper.getOrElse(CustomCodeWrapper)
)
)
val sources = crossSources.sources(buildOptions)

if (verbosity >= 3)
pprint.better.log(sources)

val options0 = buildOptions.orElse(sources.buildOptions)

(sources, options0)
}

def sbtBuildTool = Sbt("1.5.5")
def defaultBuildTool = sbtBuildTool

def run(options: ExportOptions, args: RemainingArgs): Unit = {

val logger = options.shared.logger
val inputs = options.shared.inputsOrExit(args)
val baseOptions = options.buildOptions

val (sources, options0) =
prepareBuild(inputs, baseOptions, logger, options.shared.logging.verbosity)

val buildTool =
if (options.sbt.getOrElse(true))
sbtBuildTool
else
defaultBuildTool

val project = buildTool.export(options0, sources)

val output = options.output.getOrElse("dest")
val dest = os.Path(output, os.pwd)
if (os.exists(dest)) {
System.err.println(s"Error: $output already exists.")
sys.exit(1)
}

os.makeDir.all(dest)
project.writeTo(dest)
}
}
28 changes: 28 additions & 0 deletions modules/cli/src/main/scala/scala/cli/commands/ExportOptions.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package scala.cli.commands

import caseapp._

import scala.build.options.BuildOptions

// format: off
final case class ExportOptions(
// FIXME There might be too many options for 'scala-cli export' there
@Recurse
shared: SharedOptions = SharedOptions(),
@Recurse
mainClass: MainClassOptions = MainClassOptions(),

sbt: Option[Boolean] = None,

@Name("o")
output: Option[String] = None
) {
// format: on

def buildOptions: BuildOptions = {
val baseOptions = shared.buildOptions(enableJmh = false, None, ignoreErrors = false)
baseOptions.copy(
mainClass = mainClass.mainClass.filter(_.nonEmpty)
)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package scala.cli.commands

import caseapp._

// format: off
final case class MainClassOptions(
@Group("Entrypoint")
@HelpMessage("Specify which main class to run")
@ValueDescription("main-class")
@Name("M")
mainClass: Option[String] = None
)
// format: on

object MainClassOptions {
implicit val parser = Parser[MainClassOptions]
implicit val help = Help[MainClassOptions]
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ final case class PackageOptions(
watch: SharedWatchOptions = SharedWatchOptions(),
@Recurse
compileCross: CompileCrossOptions = CompileCrossOptions(),
@Recurse
mainClass: MainClassOptions = MainClassOptions(),

@Group("Package")
@HelpMessage("Set destination path")
Expand All @@ -32,11 +34,6 @@ final case class PackageOptions(
@HelpMessage("Generate an assembly JAR")
assembly: Boolean = false,

@Group("Package")
@HelpMessage("Specify which main class to run")
@ValueDescription("main-class")
@Name("M")
mainClass: Option[String] = None,
@Recurse
packager: PackagerOptions = PackagerOptions(),
@Group("Package")
Expand Down Expand Up @@ -72,7 +69,7 @@ final case class PackageOptions(
def buildOptions: BuildOptions = {
val baseOptions = shared.buildOptions(enableJmh = false, jmhVersion = None)
baseOptions.copy(
mainClass = mainClass.filter(_.nonEmpty),
mainClass = mainClass.mainClass.filter(_.nonEmpty),
packageOptions = baseOptions.packageOptions.copy(
version = Some(packager.version),
launcherApp = packager.launcherApp,
Expand Down
10 changes: 3 additions & 7 deletions modules/cli/src/main/scala/scala/cli/commands/RunOptions.scala
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,8 @@ final case class RunOptions(
watch: SharedWatchOptions = SharedWatchOptions(),
@Recurse
compileCross: CompileCrossOptions = CompileCrossOptions(),

@Group("Runner")
@HelpMessage("Specify which main class to run")
@ValueDescription("main-class")
@Name("M")
mainClass: Option[String] = None
@Recurse
mainClass: MainClassOptions = MainClassOptions()
) {
// format: on

Expand All @@ -37,7 +33,7 @@ final case class RunOptions(
jmhVersion = benchmarking.jmhVersion
)
baseOptions.copy(
mainClass = mainClass,
mainClass = mainClass.mainClass,
javaOptions = baseOptions.javaOptions.copy(
javaOpts = baseOptions.javaOptions.javaOpts ++ sharedJava.allJavaOpts
)
Expand Down
8 changes: 8 additions & 0 deletions modules/cli/src/main/scala/scala/cli/export/BuildTool.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package scala.cli.export

import scala.build.options.BuildOptions
import scala.build.Sources

sealed abstract class BuildTool extends Product with Serializable {
def export(options: BuildOptions, sources: Sources): Project
}
5 changes: 5 additions & 0 deletions modules/cli/src/main/scala/scala/cli/export/Project.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package scala.cli.export

abstract class Project extends Product with Serializable {
def writeTo(dir: os.Path): Unit
}
Loading