diff --git a/modules/cli/src/main/scala/scala/cli/exportCmd/JsonProject.scala b/modules/cli/src/main/scala/scala/cli/exportCmd/JsonProject.scala index c63bff1c77..9b118ad5c1 100644 --- a/modules/cli/src/main/scala/scala/cli/exportCmd/JsonProject.scala +++ b/modules/cli/src/main/scala/scala/cli/exportCmd/JsonProject.scala @@ -5,13 +5,14 @@ import com.github.plokhotnyuk.jsoniter_scala.macros.JsonCodecMaker import java.io.PrintStream -import scala.build.info.{BuildInfo, ExportDependencyFormat, ScopedBuildInfo} +import scala.build.info.{BuildInfo, ExportDependencyFormat, NativeOptionsInfo, ScopedBuildInfo} import scala.util.Using final case class JsonProject(buildInfo: BuildInfo) extends Project { def sorted = this.copy( buildInfo = buildInfo.copy( - scopes = buildInfo.scopes.map { case (k, v) => k -> v.sorted } + scopes = buildInfo.scopes.map { case (k, v) => k -> v.sorted }, + nativeOptions = buildInfo.nativeOptions.map(_.sorted) ) ) @@ -49,6 +50,14 @@ final case class JsonProject(buildInfo: BuildInfo) extends Project { } } +extension (n: NativeOptionsInfo) { + def sorted(using ord: Ordering[String]) = n.copy( + compilerPlugins = n.compilerPlugins.sorted(using JsonProject.ordering), + runtimeDependencies = n.runtimeDependencies.sorted(using JsonProject.ordering), + toolingDependencies = n.toolingDependencies.sorted(using JsonProject.ordering) + ) +} + extension (s: ScopedBuildInfo) { def sorted(using ord: Ordering[String]) = s.copy( s.sources.sorted, diff --git a/modules/integration/src/test/scala/scala/cli/integration/ExportJsonTestDefinitions.scala b/modules/integration/src/test/scala/scala/cli/integration/ExportJsonTestDefinitions.scala index 3ff2499767..5496dd8e57 100644 --- a/modules/integration/src/test/scala/scala/cli/integration/ExportJsonTestDefinitions.scala +++ b/modules/integration/src/test/scala/scala/cli/integration/ExportJsonTestDefinitions.scala @@ -107,11 +107,41 @@ abstract class ExportJsonTestDefinitions extends ScalaCliSuite with TestScalaVer val jsonContents = readJson(exportJsonProc.out.text()) + val nativeVersion = Constants.scalaNativeVersion val expectedJsonContents = s"""{ |"scalaVersion":"3.2.2", |"platform":"Native", - |"scalaNativeVersion":"${Constants.scalaNativeVersion}", + |"scalaNativeVersion":"$nativeVersion", + |"nativeOptions": { + | "scalaNativeVersion":"$nativeVersion", + | "compilerPlugins": [ + | { + | "groupId":"org.scala-native", + | "artifactId":{"name":"nscplugin","fullName":"nscplugin_3.2.2"}, + | "version":"$nativeVersion" + | } + | ], + | "runtimeDependencies": [ + | { + | "groupId":"org.scala-native", + | "artifactId":{"name":"javalib_native0.5","fullName":"javalib_native0.5_3"}, + | "version":"$nativeVersion" + | }, + | { + | "groupId":"org.scala-native", + | "artifactId":{"name":"scala3lib_native0.5","fullName":"scala3lib_native0.5_3"}, + | "version":"3.2.2+$nativeVersion" + | } + | ], + | "toolingDependencies": [ + | { + | "groupId":"org.scala-native", + | "artifactId":{"name":"scala-native-cli","fullName":"scala-native-cli_2.12"}, + | "version":"$nativeVersion" + | } + | ] + |}, |"scopes": { | "main": { | "sources": ["${withEscapedBackslashes(root / "Main.scala")}"], diff --git a/modules/options/src/main/scala/scala/build/info/BuildInfo.scala b/modules/options/src/main/scala/scala/build/info/BuildInfo.scala index 482621b751..e430f1ce6b 100644 --- a/modules/options/src/main/scala/scala/build/info/BuildInfo.scala +++ b/modules/options/src/main/scala/scala/build/info/BuildInfo.scala @@ -6,6 +6,13 @@ import scala.build.info.BuildInfo.escapeBackslashes import scala.build.internal.Constants import scala.build.options.* +final case class NativeOptionsInfo( + scalaNativeVersion: String, + compilerPlugins: Seq[ExportDependencyFormat] = Nil, + runtimeDependencies: Seq[ExportDependencyFormat] = Nil, + toolingDependencies: Seq[ExportDependencyFormat] = Nil +) + final case class BuildInfo( projectVersion: Option[String] = None, scalaVersion: Option[String] = None, @@ -14,6 +21,7 @@ final case class BuildInfo( scalaJsVersion: Option[String] = None, jsEsVersion: Option[String] = None, scalaNativeVersion: Option[String] = None, + nativeOptions: Option[NativeOptionsInfo] = None, mainClass: Option[String] = None, scopes: Map[String, ScopedBuildInfo] = Map.empty, scalaCliVersion: Option[String] = None @@ -152,11 +160,35 @@ object BuildInfo { ) } - private def scalaNativeSettings(options: ScalaNativeOptions): BuildInfo = + private def scalaNativeSettings(options: BuildOptions): BuildInfo = { + val nativeOptions = options.scalaNativeOptions + val nativeVersion = nativeOptions.finalVersion + val scalaParamsOpt = options.scalaParams.getOrElse(None) + val sv = scalaParamsOpt.map(_.scalaVersion) + .orElse(options.scalaOptions.defaultScalaVersion) + .getOrElse(Constants.defaultScalaVersion) + + val runtimeDeps = nativeOptions.nativeDependencies(sv) + .map(ExportDependencyFormat(_, scalaParamsOpt)) + val compilerPluginDeps = nativeOptions.compilerPlugins + .map(ExportDependencyFormat(_, scalaParamsOpt)) + val toolingDeps = Seq(ExportDependencyFormat( + "org.scala-native", + ArtifactId("scala-native-cli", "scala-native-cli_2.12"), + nativeVersion + )) + BuildInfo( platform = Some(Platform.Native.repr), - scalaNativeVersion = Some(options.finalVersion) + scalaNativeVersion = Some(nativeVersion), + nativeOptions = Some(NativeOptionsInfo( + scalaNativeVersion = nativeVersion, + compilerPlugins = compilerPluginDeps, + runtimeDependencies = runtimeDeps, + toolingDependencies = toolingDeps + )) ) + } private def jvmSettings(options: BuildOptions): BuildInfo = BuildInfo( @@ -173,7 +205,7 @@ object BuildInfo { case Some(Platform.JS) => scalaJsSettings(options.scalaJsOptions) case Some(Platform.Native) => - scalaNativeSettings(options.scalaNativeOptions) + scalaNativeSettings(options) case _ => jvmSettings(options) }