Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix incorrect module traversal for BSP classpath retrieval #1793

Merged
merged 5 commits into from
Mar 25, 2022
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
49 changes: 7 additions & 42 deletions bsp/test/resources/bsp-install/build.sc
Original file line number Diff line number Diff line change
@@ -1,49 +1,14 @@
import mill._
import mill.api.PathRef
import mill.scalalib
import mill.define.Command
import mill.scalalib.GenIdeaModule._
import mill.scalalib._

trait HelloWorldModule extends scalalib.ScalaModule {
def scalaVersion = "2.12.4"
object test extends super.Tests {
def testFrameworks = Seq("utest.runner.Framework")
}
trait HelloBspModule extends ScalaModule {
def scalaVersion = sys.props.getOrElse("TEST_SCALA_2_13_VERSION", ???)
object test extends super.Tests with TestModule.Utest

def generatedSources = T {
override def generatedSources = T {
Seq(PathRef(T.ctx().dest / "classes"))
}

def ideaJavaModuleFacets(ideaConfigVersion: Int): Command[Seq[JavaFacet]] = T.command {
ideaConfigVersion match {
case 4 =>
Seq(
JavaFacet("AspectJ", "AspectJ",
Element("configuration", childs = Seq(
Element("projectLibrary", childs = Seq(
Element("option", Map("name" -> "name", "value" -> "/tmp"))
))
))
)
)
}
}

override def ideaConfigFiles(ideaConfigVersion: Int): Command[Seq[IdeaConfigFile]] = T.command {
ideaConfigVersion match {
case 4 =>
Seq(
IdeaConfigFile(
name = "compiler.xml",
component = "AjcSettings",
config = Seq(Element("option", Map("name" -> "ajcPath", "value" -> "/tmp/aspectjtools.jar")))),
IdeaConfigFile(
name = "compiler.xml",
component = "CompilerConfiguration",
config = Seq(Element("option", Map("name" -> "DEFAULT_COMPILER", "value" -> "ajc")))
)
)
}
}
}

object HelloWorld extends HelloWorldModule
object HelloBsp extends HelloBspModule
7 changes: 3 additions & 4 deletions bsp/test/src/BspInstallTests.scala
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,10 @@ object BspInstallTests extends ScriptTestSuite(false) {
override def scriptSourcePath: Path = os.pwd / "bsp" / "test" / "resources" / workspaceSlug

def tests: Tests = Tests {
"BSP install" - {
test("BSP install") {
val workspacePath = initWorkspace()
eval("mill.bsp.BSP/install")

assert(exists(workspacePath / ".bsp" / s"${BSP.serverName}.json"))
eval("mill.bsp.BSP/install") ==> true
exists(workspacePath / ".bsp" / s"${BSP.serverName}.json") ==> true
}
}
}
3 changes: 2 additions & 1 deletion main/test/src/util/ScriptTestSuite.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package mill.util

import java.io.{ByteArrayInputStream, ByteArrayOutputStream, PrintStream}
import mainargs.Flag
import mill.define.SelectMode

import scala.util.Try
import os.Path
Expand Down Expand Up @@ -100,7 +101,7 @@ abstract class ScriptTestSuite(fork: Boolean) extends TestSuite {
} catch { case e: Throwable => false }
}
def meta(s: String): String = {
val (List(selector), args) = mill.define.ParseArgs.apply(Seq(s), multiSelect = false).right.get
val Seq((List(selector), _)) = mill.define.ParseArgs.apply(Seq(s), SelectMode.Single).getOrElse(???)

val segments = selector._2.value.flatMap(_.pathSegments)
os.read(wd / "out" / segments.init / s"${segments.last}.json")
Expand Down
4 changes: 2 additions & 2 deletions scalalib/src/JavaModule.scala
Original file line number Diff line number Diff line change
Expand Up @@ -318,9 +318,9 @@ trait JavaModule
j: JavaModule,
pathsResolver: Task[EvaluatorPathsResolver]
): Task[Seq[PathRef]] = {
val cl = bspCompileClassesPath(pathsResolver)
val cl = j.bspCompileClassesPath(pathsResolver)
T.task {
resources() ++ Seq(cl())
j.resources() ++ Seq(cl())
}
}

Expand Down
3 changes: 2 additions & 1 deletion scalalib/src/ScalaModule.scala
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ trait ScalaModule extends JavaModule { outer =>
)()
}

// Keep in sync with [[bspCompileClassesInfo]]
// Keep in sync with [[bspCompileClassesPath]]
override def compile: T[CompilationResult] = T.persistent {
val sv = scalaVersion()
if (sv == "2.12.4") T.log.error(
Expand Down Expand Up @@ -244,6 +244,7 @@ trait ScalaModule extends JavaModule { outer =>
val compileCp = Seq(
"-classpath",
compileClasspath()
.iterator
.filter(_.path.ext != "pom")
.map(_.path)
.mkString(java.io.File.pathSeparator)
Expand Down
91 changes: 91 additions & 0 deletions scalalib/test/src/mill/scalalib/bsp/BspModuleTests.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
package mill.scalalib.bsp

import mill.eval.EvaluatorPaths
import mill.{Agg, T}
import mill.scalalib.{DepSyntax, ScalaModule, TestModule}
import mill.util.{TestEvaluator, TestUtil}
import os.{BasePathImpl, FilePath}
import utest.framework.TestPath
import utest.{TestSuite, Tests, test, _}

object BspModuleTests extends TestSuite {

val testScalaVersion = sys.props.getOrElse("TEST_SCALA_2_13_VERSION", ???)

trait BspBase extends TestUtil.BaseModule {
override def millSourcePath: os.Path =
TestUtil.getSrcPathBase() / millOuterCtx.enclosing.split('.')
}

object MultiBase extends BspBase {
object HelloBsp extends ScalaModule {
def scalaVersion = testScalaVersion
override def ivyDeps = Agg(ivy"org.slf4j:slf4j-api:1.7.34")
}
object HelloBsp2 extends ScalaModule {
def scalaVersion = testScalaVersion
override def moduleDeps = Seq(HelloBsp)
override def ivyDeps = Agg(ivy"ch.qos.logback:logback-classic:1.1.10")
}
}

def workspaceTest[T](m: TestUtil.BaseModule)(t: TestEvaluator => T)(implicit tp: TestPath): T = {
val eval = new TestEvaluator(m)
os.remove.all(m.millSourcePath)
os.remove.all(eval.outPath)
os.makeDir.all(m.millSourcePath / os.up)
t(eval)
}

override def tests: Tests = Tests {
test("bspCompileClasspath") {
test("single module") {
workspaceTest(MultiBase) { eval =>
val Right((result, evalCount)) = eval.apply(
MultiBase.HelloBsp.bspCompileClasspath(T.task(eval.evaluator.pathsResolver))
)

assert(
result.size == 3,
result.map(_.path.last).toSet == Set(
"resources",
"slf4j-api-1.7.34.jar",
s"scala-library-${testScalaVersion}.jar"
),
evalCount > 0
)
}
test("dependent module") {
workspaceTest(MultiBase) { eval =>
val Right((result, evalCount)) = eval.apply(
MultiBase.HelloBsp2.bspCompileClasspath(T.task(eval.evaluator.pathsResolver))
)

val relResults: Seq[FilePath] = result.map { p =>
val name = p.path.last
if (name.endsWith(".jar")) os.rel / name
else p.path
}.sortBy(_.toString)

val expected: Seq[FilePath] = Seq(
MultiBase.HelloBsp.millSourcePath / "resources",
MultiBase.HelloBsp2.millSourcePath / "resources",
EvaluatorPaths.resolveDestPaths(eval.outPath, MultiBase.HelloBsp.compile)
.dest / "classes",
os.rel / "slf4j-api-1.7.34.jar",
os.rel / "logback-core-1.1.10.jar",
os.rel / "logback-classic-1.1.10.jar",
os.rel / s"scala-library-${testScalaVersion}.jar"
).sortBy(_.toString)

assert(
result.size == 7,
relResults == expected,
evalCount > 0
)
}
}
}
}
}
}