8000 Add Scala Native support for running a main method from the test scope · VirtusLab/scala-cli@e584caf · GitHub
[go: up one dir, main page]

Skip to content

Commit e584caf

Browse files
committed
Add Scala Native support for running a main method from the test scope
1 parent 73254ee commit e584caf

File tree

8 files changed

+77
-66
lines changed

8 files changed

+77
-66
lines changed

modules/cli/src/main/scala/scala/cli/commands/package0/Package.scala

Lines changed: 24 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -393,7 +393,7 @@ object Package extends ScalaCommand[PackageOptions] with BuildCommandHelpers {
393393
case _ => None
394394

395395
val cachedDest = value(buildNative(
396-
build = build,
396+
builds = Seq(build),
397397
mainClass = mainClassO,
398398
targetType = tpe,
399399
destPath = Some(destPath),
@@ -535,10 +535,10 @@ object Package extends ScalaCommand[PackageOptions] with BuildCommandHelpers {
535535
val dest = workDir / "doc.jar"
536536
val cacheData =
537537
CachedBinary.getCacheData(
538-
build,
539-
extraArgs.toList,
540-
dest,
541-
workDir
538+
builds = Seq(build),
539+
config = extraArgs.toList,
540+
dest = dest,
541+
workDir = workDir
542542
)
543543

544544
if (cacheData.changed) {
@@ -667,7 +667,7 @@ object Package extends ScalaCommand[PackageOptions] with BuildCommandHelpers {
667667
case Platform.Native =>
668668
val dest =
669669
value(buildNative(
670-
build = build,
670+
builds = Seq(build),
671671
mainClass = Some(mainClass),
672672
targetType = PackageType.Native.Application,
673673
destPath = None,
@@ -1031,28 +1031,29 @@ object Package extends ScalaCommand[PackageOptions] with BuildCommandHelpers {
10311031
}
10321032

10331033
def buildNative(
1034-
build: Build.Successful,
1034+
builds: Seq[Build.Successful],
10351035
mainClass: Option[String], // when building a static/dynamic library, we don't need a main class
10361036
targetType: PackageType.Native,
10371037
destPath: Option[os.Path],
10381038
logger: Logger
10391039
): Either[BuildException, os.Path] = either {
1040-
val dest = build.inputs.nativeWorkDir / s"main${if (Properties.isWin) ".exe" else ""}"
1040+
val dest = builds.head.inputs.nativeWorkDir / s"main${if (Properties.isWin) ".exe" else ""}"
10411041

10421042
val cliOptions =
1043-
build.options.scalaNativeOptions.configCliOptions(build.sources.resourceDirs.nonEmpty)
1043+
builds.head.options.scalaNativeOptions.configCliOptions(builds.exists(
1044+
_.sources.resourceDirs.nonEmpty
1045+
))
10441046

1045-
val setupPython = build.options.notForBloopOptions.doSetupPython.getOrElse(false)
1047+
val setupPython = builds.head.options.notForBloopOptions.doSetupPython.getOrElse(false)
10461048
val pythonLdFlags =
1047-
if (setupPython)
1049+
if setupPython then
10481050
value {
10491051
val python = Python()
10501052
val flagsOrError = python.ldflags
10511053
logger.debug(s"Python ldflags: $flagsOrError")
10521054
flagsOrError.orPythonDetectionError
10531055
}
1054-
else
1055-
Nil
1056+
else Nil
10561057
val pythonCliOptions = pythonLdFlags.flatMap(f => Seq("--linking-option", f)).toList
10571058

10581059
val libraryLinkingOptions: Seq[String] =
@@ -1076,21 +1077,21 @@ object Package extends ScalaCommand[PackageOptions] with BuildCommandHelpers {
10761077
libraryLinkingOptions ++
10771078
mainClass.toSeq.flatMap(m => Seq("--main", m))
10781079

1079-
val nativeWorkDir = build.inputs.nativeWorkDir
1080+
val nativeWorkDir = builds.head.inputs.nativeWorkDir
10801081
os.makeDir.all(nativeWorkDir)
10811082

10821083
val cacheData =
10831084
CachedBinary.getCacheData(
1084-
build,
1085+
builds,
10851086
allCliOptions,
10861087
dest,
10871088
nativeWorkDir
10881089
)
10891090

10901091
if (cacheData.changed) {
1091-
NativeResourceMapper.copyCFilesToScalaNativeDir(build, nativeWorkDir)
1092-
val mainJar = Library.libraryJar(build)
1093-
val classpath = mainJar.toString +: build.artifacts.classPath.map(_.toString)
1092+
builds.foreach(build => NativeResourceMapper.copyCFilesToScalaNativeDir(build, nativeWorkDir))
1093+
val jars = builds.map(Library.libraryJar(_))
1094+
val classpath = (jars ++ builds.flatMap(_.artifacts.classPath)).map(_.toString).distinct
10941095
val args =
10951096
allCliOptions ++
10961097
logger.scalaNativeCliInternalLoggerOptions ++
@@ -1101,25 +1102,24 @@ object Package extends ScalaCommand[PackageOptions] with BuildCommandHelpers {
11011102
nativeWorkDir.toString()
11021103
) ++ classpath
11031104

1104-
val scalaNativeCli = build.artifacts.scalaOpt
1105+
val scalaNativeCli = builds.flatMap(_.artifacts.scalaOpt).headOption
11051106
.getOrElse {
11061107
sys.error("Expected Scala artifacts to be fetched")
11071108
}
11081109
.scalaNativeCli
11091110

11101111
val exitCode =
11111112
Runner.runJvm(
1112-
build.options.javaHome().value.javaCommand,
1113-
build.options.javaOptions.javaOpts.toSeq.map(_.value.value),
1113+
builds.head.options.javaHome().value.javaCommand,
1114+
builds.head.options.javaOptions.javaOpts.toSeq.map(_.value.value),
11141115
scalaNativeCli,
11151116
"scala.scalanative.cli.ScalaNativeLd",
11161117
args,
11171118
logger
11181119
).waitFor()
1119-
if (exitCode == 0)
1120+
if exitCode == 0 then
11201121
CachedBinary.updateProjectAndOutputSha(dest, nativeWorkDir, cacheData.projectSha)
1121-
else
1122-
throw new ScalaNativeBuildError
1122+
else throw new ScalaNativeBuildError
11231123
}
11241124

11251125
dest

modules/cli/src/main/scala/scala/cli/commands/run/Run.scala

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -543,7 +543,7 @@ object Run extends ScalaCommand[RunOptions] with BuildCommandHelpers {
543543
pythonExecutable.fold(Map.empty)(py => Map("SCALAPY_PYTHON_PROGRAMNAME" -> py))
544544
val extraEnv = libraryPathsEnv ++ programNameEnv ++ pythonExtraEnv
545545
val maybeResult = withNativeLauncher(
546-
builds.head, // TODO: support multiple builds
546+
builds,
547547
mainClass,
548548
logger
549549
) { launcher =>
@@ -686,12 +686,12 @@ object Run extends ScalaCommand[RunOptions] with BuildCommandHelpers {
686686
}
687687

688688
def withNativeLauncher[T](
689-
build: Build.Successful,
689+
builds: Seq[Build.Successful],
690690
mainClass: String,
691691
logger: Logger
692692
)(f: os.Path => T): Either[BuildException, T] =
693693
Package.buildNative(
694-
build = build,
694+
builds = builds,
695695
mainClass = Some(mainClass),
696696
targetType = PackageType.Native.Application,
697697
destPath = None,

modules/cli/src/main/scala/scala/cli/commands/test/Test.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -225,7 +225,7 @@ object Test extends ScalaCommand[TestOptions] {
225225
case Platform.Native =>
226226
value {
227227
Run.withNativeLauncher(
228-
build,
228+
Seq(build),
229229
"scala.scalanative.testinterface.TestMain",
230230
logger
231231
) { launcher =>

modules/cli/src/main/scala/scala/cli/internal/CachedBinary.scala

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -58,13 +58,13 @@ object CachedBinary {
5858
.map(_.getBytes(StandardCharsets.UTF_8))
5959
}
6060

61-
private def projectSha(build: Build.Successful, config: List[String]) = {
61+
private def projectSha(builds: Seq[Build.Successful], config: List[String]): String = {
6262
val md = MessageDigest.getInstance("SHA-1")
6363
val charset = StandardCharsets.UTF_8
64-
md.update(build.inputs.sourceHash().getBytes(charset))
64+
md.update(builds.map(_.inputs.sourceHash()).reduce(_ + _).getBytes(charset))
6565
md.update("<resources>".getBytes())
6666
// Resource changes for SN require relinking, so they should also be hashed
67-
hashResources(build).foreach(md.update)
67+
builds.foreach(build => hashResources(build).foreach(md.update))
6868
md.update("</resources>".getBytes())
6969
md.update(0: Byte)
7070
md.update("<config>".getBytes(charset))
@@ -75,7 +75,7 @@ object CachedBinary {
7575
md.update("</config>".getBytes(charset))
7676
md.update(Constants.version.getBytes)
7777
md.update(0: Byte)
78-
for (h <- build.options.hash) {
78+
for (h <- builds.map(_.options).reduce(_ orElse _).hash) {
7979
md.update(h.getBytes(charset))
8080
md.update(0: Byte)
8181
}
@@ -99,19 +99,20 @@ object CachedBinary {
9999
}
100100

101101
def getCacheData(
102-
build: Build.Successful,
102+
builds: Seq[Build.Successful],
103103
config: List[String],
104104
dest: os.Path,
105105
workDir: os.Path
106106
): CacheData = {
107107
val projectShaPath = resolveProjectShaPath(workDir)
108108
val outputShaPath = resolveOutputShaPath(workDir)
109109

110-
val currentProjectSha = projectSha(build, config)
111-
val currentOutputSha = if (os.exists(dest)) Some(fileSha(dest)) else None
110+
val currentProjectSha = projectSha(builds, config)
111+
val currentOutputSha = if os.exists(dest) then Some(fileSha(dest)) else None
112112

113-
val previousProjectSha = if (os.exists(projectShaPath)) Some(os.read(projectShaPath)) else None
114-
val previousOutputSha = if (os.exists(outputShaPath)) Some(os.read(outputShaPath)) else None
113+
val previousProjectSha =
114+
if os.exists(projectShaPath) then Some(os.read(projectShaPath)) else None
115+
val previousOutputSha = if os.exists(outputShaPath) then Some(os.read(outputShaPath)) else None
115116

116117
val changed =
117118
!previousProjectSha.contains(currentProjectSha) ||

modules/cli/src/main/scala/scala/cli/packaging/Library.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ object Library {
2020
val dest = workDir / "library.jar"
2121
val cacheData =
2222
CachedBinary.getCacheData(
23-
build,
23+
Seq(build),
2424
mainClassOpt.toList.flatMap(c => List("--main-class", c)),
2525
dest,
2626
workDir

modules/cli/src/main/scala/scala/cli/packaging/NativeImage.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -190,7 +190,7 @@ object NativeImage {
190190
options.notForBloopOptions.packageOptions.nativeImageOptions.graalvmArgs.map(_.value)
191191

192192
val cacheData = CachedBinary.getCacheData(
193-
build,
193+
Seq(build),
194194
s"--java-home=${javaHome.javaHome.toString}" :: "--" :: extraOptions.toList ++ nativeImageArgs,
195195
dest,
196196
nativeImageWorkDir

modules/cli/src/test/scala/cli/tests/CachedBinaryTests.scala

Lines changed: 21 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package scala.cli.tests
22

3-
import com.eed3si9n.expecty.Expecty.{assert => expect}
3+
import bloop.rifle.BloopRifleConfig
4+
import com.eed3si9n.expecty.Expecty.assert as expect
5+
import os.Path
46

57
import scala.build.options.{BuildOptions, InternalOptions}
68
import scala.build.tests.util.BloopServer
@@ -11,12 +13,12 @@ import scala.util.{Properties, Random}
1113

1214
class CachedBinaryTests extends munit.FunSuite {
1315

14-
val buildThreads = BuildThreads.create()
15-
def bloopConfig = BloopServer.bloopConfig
16+
val buildThreads: BuildThreads = BuildThreads.create()
17+
def bloopConfig: BloopRifleConfig = BloopServer.bloopConfig
1618

1719
val helloFileName = "Hello.scala"
1820

19-
val inputs = TestInputs(
21+
val inputs: TestInputs = TestInputs(
2022
os.rel / helloFileName ->
2123
s"""object Hello extends App {
2224
| println("Hello")
@@ -29,16 +31,16 @@ class CachedBinaryTests extends munit.FunSuite {
2931
|""".stripMargin
3032
)
3133

32-
val extraRepoTmpDir = os.temp.dir(prefix = "scala-cli-tests-extra-repo-")
33-
val directories = Directories.under(extraRepoTmpDir)
34+
val extraRepoTmpDir: Path = os.temp.dir(prefix = "scala-cli-tests-extra-repo-")
35+
val directories: Directories = Directories.under(extraRepoTmpDir)
3436

35-
val defaultOptions = BuildOptions(
37+
val defaultOptions: BuildOptions = BuildOptions(
3638
internal = InternalOptions(
3739
localRepository = LocalRepo.localRepo(directories.localRepoDir, TestLogger())
3840
)
3941
)
4042

41-
private def helperTests(fromDirectory: Boolean) = {
43+
private def helperTests(fromDirectory: Boolean): Unit = {
4244
val additionalMessage =
4345
if (fromDirectory) "built from a directory" else "built from a set of files"
4446

@@ -55,7 +57,7 @@ class CachedBinaryTests extends munit.FunSuite {
5557
os.write(destPath, Random.alphanumeric.take(10).mkString(""), createFolders = true)
5658

5759
val cacheData =
58-
CachedBinary.getCacheData(build, config, destPath, nativeWorkDir)
60+
CachedBinary.getCacheData(Seq(build), config, destPath, nativeWorkDir)
5961
expect(cacheData.changed)
6062
}
6163
}
@@ -72,7 +74,7 @@ class CachedBinaryTests extends munit.FunSuite {
7274
os.write(destPath, Random.alphanumeric.take(10).mkString(""), createFolders = true)
7375

7476
val cacheData =
75-
CachedBinary.getCacheData(build, config, destPath, nativeWorkDir)
77+
CachedBinary.getCacheData(Seq(build), config, destPath, nativeWorkDir)
7678
CachedBinary.updateProjectAndOutputSha(
7779
destPath,
7880
nativeWorkDir,
@@ -81,7 +83,7 @@ class CachedBinaryTests extends munit.FunSuite {
8183
expect(cacheData.changed)
8284

8385
val sameBuildCache =
84-
CachedBinary.getCacheData(build, config, destPath, nativeWorkDir)
86+
CachedBinary.getCacheData(Seq(build), config, destPath, nativeWorkDir)
8587
expect(!sameBuildCache.changed)
8688
}
8789
}
@@ -98,7 +100,7 @@ class CachedBinaryTests extends munit.FunSuite {
98100
os.write(destPath, Random.alphanumeric.take(10).mkString(""), createFolders = true)
99101

100102
val cacheData =
101-
CachedBinary.getCacheData(build, config, destPath, nativeWorkDir)
103+
CachedBinary.getCacheData(Seq(build), config, destPath, nativeWorkDir)
102104
CachedBinary.updateProjectAndOutputSha(
103105
destPath,
104106
nativeWorkDir,
@@ -108,7 +110,7 @@ class CachedBinaryTests extends munit.FunSuite {
108110

109111
os.remove(destPath)
110112
val afterDeleteCache =
111-
CachedBinary.getCacheData(build, config, destPath, nativeWorkDir)
113+
CachedBinary.getCacheData(Seq(build), config, destPath, nativeWorkDir)
112114
expect(afterDeleteCache.changed)
113115
}
114116
}
@@ -125,7 +127,7 @@ class CachedBinaryTests extends munit.FunSuite {
125127
os.write(destPath, Random.alphanumeric.take(10).mkString(""), createFolders = true)
126128

127129
val cacheData =
128-
CachedBinary.getCacheData(build, config, destPath, nativeWorkDir)
130+
CachedBinary.getCacheData(Seq(build), config, destPath, nativeWorkDir)
129131
CachedBinary.updateProjectAndOutputSha(
130132
destPath,
131133
nativeWorkDir,
@@ -135,7 +137,7 @@ class CachedBinaryTests extends munit.FunSuite {
135137

136138
os.write.over(destPath, Random.alphanumeric.take(10).mkString(""))
137139
val cacheAfterFileUpdate =
138-
CachedBinary.getCacheData(build, config, destPath, nativeWorkDir)
140+
CachedBinary.getCacheData(Seq(build), config, destPath, nativeWorkDir)
139141
expect(cacheAfterFileUpdate.changed)
140142
}
141143
}
@@ -151,7 +153,7 @@ class CachedBinaryTests extends munit.FunSuite {
151153
os.write(destPath, Random.alphanumeric.take(10).mkString(""), createFolders = true)
152154

153155
val cacheData =
154-
CachedBinary.getCacheData(build, config, destPath, nativeWorkDir)
156+
CachedBinary.getCacheData(Seq(build), config, destPath, nativeWorkDir)
155157
CachedBinary.updateProjectAndOutputSha(
156158
destPath,
157159
nativeWorkDir,
@@ -161,7 +163,7 @@ class CachedBinaryTests extends munit.FunSuite {
161163

162164
os.write.append(root / helloFileName, Random.alphanumeric.take(10).mkString(""))
163165
val cacheAfterFileUpdate =
164-
CachedBinary.getCacheData(build, config, destPath, nativeWorkDir)
166+
CachedBinary.getCacheData(Seq(build), config, destPath, nativeWorkDir)
165167
expect(cacheAfterFileUpdate.changed)
166168
}
167169
}
@@ -177,7 +179,7 @@ class CachedBinaryTests extends munit.FunSuite {
177179
os.write(destPath, Random.alphanumeric.take(10).mkString(""), createFolders = true)
178180

179181
val cacheData =
180-
CachedBinary.getCacheData(build, config, destPath, nativeWorkDir)
182+
CachedBinary.getCacheData(Seq(build), config, destPath, nativeWorkDir)
181183
CachedBinary.updateProjectAndOutputSha(
182184
destPath,
183185
nativeWorkDir,
@@ -197,7 +199,7 @@ class CachedBinaryTests extends munit.FunSuite {
197199

198200
val cacheAfterConfigUpdate =
199201
CachedBinary.getCacheData(
200-
updatedBuild,
202+
Seq(updatedBuild),
201203
updatedConfig,
202204
destPath,
203205
nativeWorkDir

0 commit comments

Comments
 (0)
0