Skip to content

Commit

Permalink
?
Browse files Browse the repository at this point in the history
  • Loading branch information
alexarchambault committed Feb 15, 2024
1 parent 53a475d commit ee06f51
Show file tree
Hide file tree
Showing 4 changed files with 124 additions and 35 deletions.
4 changes: 2 additions & 2 deletions build.sc
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,8 @@ trait ScalaInterpreter extends Cross.Module[String] with AlmondModule with Bloop
Deps.directiveHandler,
Deps.jansi,
Deps.ammoniteCompiler(crossScalaVersion).exclude(("net.java.dev.jna", "jna")),
Deps.ammoniteRepl(crossScalaVersion).exclude(("net.java.dev.jna", "jna"))
Deps.ammoniteRepl(crossScalaVersion).exclude(("net.java.dev.jna", "jna")),
ivy"io.github.alexarchambault::class-path-inspector:0.1.1"
)
}
def scalacOptions = super.scalacOptions() ++ {
Expand All @@ -247,7 +248,6 @@ trait ScalaInterpreter extends Cross.Module[String] with AlmondModule with Bloop
scala213Options
}
object test extends CrossSbtModuleTests with AlmondTestModule {
override def testUseArgsFile = false
def moduleDeps = {
val rx =
if (crossScalaVersion.startsWith("2.12.")) Seq(scala.`almond-rx`())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,6 @@ import coursier.util.ModuleMatcher

import scala.jdk.CollectionConverters._
import scala.language.reflectiveCalls
import java.net.URLClassLoader
import scala.annotation.tailrec

object AmmInterpreter {

Expand Down Expand Up @@ -113,21 +111,12 @@ object AmmInterpreter {

val log = logCtx(getClass)

@tailrec
def printCl(cl: ClassLoader): Unit =
if (cl != null) {
System.err.println(s"Loader $cl")
cl match {
case u: URLClassLoader =>
for (url <- u.getURLs)
System.err.println(s" $url")
case _ =>
}
System.err.println()
printCl(cl.getParent)
}

printCl(frames0().head.classloader)
for ((cl, cp) <- classpath.Inspector.classPath(frames0().head.classloader).toVector) {
System.err.println(s"$cp")
for (elem <- cp)
System.err.println(s" $elem")
System.err.println()
}

try {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ import utest._

import scala.collection.JavaConverters._
import scala.collection.compat._
import scala.annotation.tailrec

object ScalaKernelTests extends TestSuite {

Expand Down Expand Up @@ -76,21 +75,12 @@ object ScalaKernelTests extends TestSuite {

test("stdin") {

@tailrec
def printCl(cl: ClassLoader): Unit =
if (cl != null) {
System.err.println(s"Loader $cl")
cl match {
case u: URLClassLoader =>
for (url <- u.getURLs)
System.err.println(s" $url")
case _ =>
}
System.err.println()
printCl(cl.getParent)
}

printCl(Thread.currentThread().getContextClassLoader)
for ((cl, cp) <- classpath.Inspector.classPath().toVector) {
System.err.println(s"$cp")
for (elem <- cp)
System.err.println(s" $elem")
System.err.println()
}

val interpreter = new ScalaInterpreter(
params = ScalaInterpreterParams(
Expand Down
110 changes: 110 additions & 0 deletions project/settings.sc
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,116 @@ trait AlmondTestModule
with AlmondScalacOptions {
// with AlmondScala2Or3Module {

// originally based on https://github.com/com-lihaoyi/mill/blob/3335d2a2f7f33766a680e30df6a7d0dc0fbe08b3/scalalib/src/mill/scalalib/TestModule.scala#L80-L146
// goal here is to use a coursier bootstrap rather than a manifest JAR when testUseArgsFile is true
protected def testTask(
args: Task[Seq[String]],
globSelectors: Task[Seq[String]]
): Task[(String, Seq[mill.testrunner.TestResult])] =
T.task {
val outputPath = T.dest / "out.json"
val useArgsFile = testUseArgsFile()

val (jvmArgs, props: Map[String, String]) =
if (useArgsFile) {
val (props, jvmArgs) = forkArgs().partition(_.startsWith("-D"))
val sysProps =
props
.map(_.drop(2).split("[=]", 2))
.map {
case Array(k, v) => k -> v
case Array(k) => k -> ""
}
.toMap

jvmArgs -> sysProps
} else {
forkArgs() -> Map()
}

val testArgs = mill.testrunner.TestArgs(
framework = testFramework(),
classpath = runClasspath().map(_.path),
arguments = args(),
sysProps = props,
outputPath = outputPath,
colored = T.log.colored,
testCp = compile().classes.path,
home = T.home,
globSelectors = globSelectors()
)

val testRunnerClasspathArg = zincWorker().scalalibClasspath()
.map(_.path.toNIO.toUri.toURL)
.mkString(",")

val argsFile = T.dest / "testargs"
os.write(argsFile, upickle.default.write(testArgs))
val mainArgs = Seq(testRunnerClasspathArg, argsFile.toString)

runSubprocess(
mainClass = "mill.testrunner.entrypoint.TestRunnerMain",
classPath = (runClasspath() ++ zincWorker().testrunnerEntrypointClasspath()).map(_.path),
jvmArgs = jvmArgs,
envArgs = forkEnv(),
mainArgs = mainArgs,
workingDir = forkWorkingDir(),
useCpPassingJar = useArgsFile
)

if (!os.exists(outputPath)) mill.api.Result.Failure("Test execution failed.")
else
try {
val jsonOutput = ujson.read(outputPath.toIO)
val (doneMsg, results) =
upickle.default.read[(String, Seq[mill.testrunner.TestResult])](jsonOutput)
TestModule.handleResults(doneMsg, results, Some(T.ctx()))
} catch {
case e: Throwable =>
mill.api.Result.Failure("Test reporting failed: " + e)
}
}

private def createBootstrapJar(dest: os.Path, classPath: Agg[os.Path], mainClass: String): Unit = {
import coursier.launcher._
val content = Seq(ClassLoaderContent.fromUrls(classPath.toSeq.map(_.toNIO.toUri.toASCIIString)))
val params = Parameters.Bootstrap(content, mainClass)
BootstrapGenerator.generate(params, dest.toNIO)
}

// originally based on https://github.com/com-lihaoyi/mill/blob/3335d2a2f7f33766a680e30df6a7d0dc0fbe08b3/main/util/src/mill/util/Jvm.scala#L117-L154
// goal is to use coursier bootstraps rather than manifest JARs
// the former load JARs via standard URLClassLoader-s, which is better dealt with in Ammonite and almond
private def runSubprocess(
mainClass: String,
classPath: Agg[os.Path],
jvmArgs: Seq[String] = Seq.empty,
envArgs: Map[String, String] = Map.empty,
mainArgs: Seq[String] = Seq.empty,
workingDir: os.Path = null,
useCpPassingJar: Boolean = false
)(implicit ctx: mill.api.Ctx): Unit = {

val (cp, mainClass0) =
if (useCpPassingJar && !classPath.iterator.isEmpty) {
val passingJar = os.temp(prefix = "run-", suffix = ".jar", deleteOnExit = false)
ctx.log.debug(s"Creating classpath passing jar '$passingJar' with Class-Path: ${classPath.iterator.map(_.toNIO.toUri.toURL.toExternalForm).mkString(" ")}")
createBootstrapJar(passingJar, classPath, mainClass)
(Agg(passingJar), "coursier.bootstrap.launcher.Launcher")
} else
(classPath, mainClass)

val args =
Vector(mill.util.Jvm.javaExe) ++
jvmArgs ++
Vector("-cp", cp.iterator.mkString(java.io.File.pathSeparator), mainClass0) ++
mainArgs

ctx.log.debug(s"Run subprocess with args: ${args.map(a => s"'$a'").mkString(" ")}")

mill.util.Jvm.runSubprocess(args, envArgs, workingDir)
}

def ivyDeps = Agg(Deps.utest)
def testFramework = "utest.runner.Framework"

Expand Down

0 comments on commit ee06f51

Please sign in to comment.