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

Skip to content

Commit 0691f0f

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

File tree

9 files changed

+119
-88
lines changed

9 files changed

+119
-88
lines changed

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

Lines changed: 24 additions & 24 deletions
< 10000 td data-grid-cell-id="diff-bb6456fdf5e49034033997d9e9a5048f35859798afd7f695b1fcaaec45b2c85c-1084-1085-0" data-selected="false" role="gridcell" style="background-color:var(--diffBlob-additionNum-bgColor, var(--diffBlob-addition-bgColor-num));text-align:center" tabindex="-1" valign="top" class="focusable-grid-cell diff-line-number position-relative left-side">
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 & 20 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,21 +31,20 @@ 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

4547
test(s"should build native app at first time ($additionalMessage)") {< 10000 /div>
46-
4748
inputs.withLoadedBuild(defaultOptions, buildThreads, Some(bloopConfig), fromDirectory) {
4849
(_, _, maybeBuild) =>
4950
val build = maybeBuild.successfulOpt.get
@@ -55,7 +56,7 @@ class CachedBinaryTests extends munit.FunSuite {
5556
os.write(destPath, Random.alphanumeric.take(10).mkString(""), createFolders = true)
5657

5758
val cacheData =
58-
CachedBinary.getCacheData(build, config, destPath, nativeWorkDir)
59+
CachedBinary.getCacheData(Seq(build), config, destPath, nativeWorkDir)
5960
expect(cacheData.changed)
6061
}
6162
}
@@ -72,7 +73,7 @@ class CachedBinaryTests extends munit.FunSuite {
7273
os.write(destPath, Random.alphanumeric.take(10).mkString(""), createFolders = true)
7374

7475
val cacheData =
75-
CachedBinary.getCacheData(build, config, destPath, nativeWorkDir)
76+
CachedBinary.getCacheData(Seq(build), config, destPath, nativeWorkDir)
7677
CachedBinary.updateProjectAndOutputSha(
7778
destPath,
7879
nativeWorkDir,
@@ -81,7 +82,7 @@ class CachedBinaryTests extends munit.FunSuite {
8182
expect(cacheData.changed)
8283

8384
val sameBuildCache =
84-
CachedBinary.getCacheData(build, config, destPath, nativeWorkDir)
85+
CachedBinary.getCacheData(Seq(build), config, destPath, nativeWorkDir)
8586
expect(!sameBuildCache.changed)
8687
}
8788
}
@@ -98,7 +99,7 @@ class CachedBinaryTests extends munit.FunSuite {
9899
os.write(destPath, Random.alphanumeric.take(10).mkString(""), createFolders = true)
99100

100101
val cacheData =
101-
CachedBinary.getCacheData(build, config, destPath, nativeWorkDir)
102+
CachedBinary.getCacheData(Seq(build), config, destPath, nativeWorkDir)
102103
CachedBinary.updateProjectAndOutputSha(
103104
destPath,
104105
nativeWorkDir,
@@ -108,7 +109,7 @@ class CachedBinaryTests extends munit.FunSuite {
108109

109110
os.remove(destPath)
110111
val afterDeleteCache =
111-
CachedBinary.getCacheData(build, config, destPath, nativeWorkDir)
112+
CachedBinary.getCacheData(Seq(build), config, destPath, nativeWorkDir)
112113
10000 expect(afterDeleteCache.changed)
113114
}
114115
}
@@ -125,7 +126,7 @@ class CachedBinaryTests extends munit.FunSuite {
125126
os.write(destPath, Random.alphanumeric.take(10).mkString(""), createFolders = true)
126127

127128
val cacheData =
128-
CachedBinary.getCacheData(build, config, destPath, nativeWorkDir)
129+
CachedBinary.getCacheData(Seq(build), config, destPath, nativeWorkDir)
129130
CachedBinary.updateProjectAndOutputSha(
130131
destPath,
131132
nativeWorkDir,
@@ -135,7 +136,7 @@ class CachedBinaryTests extends munit.FunSuite {
135136

136137
os.write.over(destPath, Random.alphanumeric.take(10).mkString(""))
137138
val cacheAfterFileUpdate =
138-
CachedBinary.getCacheData(build, config, destPath, nativeWorkDir)
139+
CachedBinary.getCacheData(Seq(build), config, destPath, nativeWorkDir)
139140
expect(cacheAfterFileUpdate.changed)
140141
}
141142
}
@@ -151,7 +152,7 @@ class CachedBinaryTests extends munit.FunSuite {
151152
os.write(destPath, Random.alphanumeric.take(10).mkString(""), createFolders = true)
152153

153154
val cacheData =
154-
CachedBinary.getCacheData(build, config, destPath, nativeWorkDir)
155+
CachedBinary.getCacheData(Seq(build), config, destPath, nativeWorkDir)
155156
CachedBinary.updateProjectAndOutputSha(
156157
destPath,
157158
nativeWorkDir,
@@ -161,7 +162,7 @@ class CachedBinaryTests extends munit.FunSuite {
161162

162163
os.write.append(root / helloFileName, Random.alphanumeric.take(10).mkString(""))
163164
val cacheAfterFileUpdate =
164-
CachedBinary.getCacheData(build, config, destPath, nativeWorkDir)
165+
CachedBinary.getCacheData(Seq(build), config, destPath, nativeWorkDir)
165166
expect(cacheAfterFileUpdate.changed)
166167
}
167168
}
@@ -177,7 +178,7 @@ class CachedBinaryTests extends munit.FunSuite {
177178
os.write(destPath, Random.alphanumeric.take(10).mkString(""), createFolders = true)
178179

179180
val cacheData =
180-
CachedBinary.getCacheData(build, config, destPath, nativeWorkDir)
181+
CachedBinary.getCacheData(Seq(build), config, destPath, nativeWorkDir)
181182
CachedBinary.updateProjectAndOutputSha(
182183
destPath,
183184
nativeWorkDir,
@@ -197,7 +198,7 @@ class CachedBinaryTests extends munit.FunSuite {
197198

198199
val cacheAfterConfigUpdate =
199200
CachedBinary.getCacheData(
200-
updatedBuild,
201+
Seq(updatedBuild),
201202
updatedConfig,
202203
destPath,
203204
nativeWorkDir

0 commit comments

Comments
 (0)
0