Skip to content

Commit

Permalink
Merge pull request #165 from tgodzik/another-update
Browse files Browse the repository at this point in the history
Another update
  • Loading branch information
tgodzik committed Apr 23, 2024
2 parents 8f65ccc + 456fa24 commit cf0e8bd
Show file tree
Hide file tree
Showing 16 changed files with 154 additions and 44 deletions.
2 changes: 2 additions & 0 deletions .github/workflows/ci.yml
Expand Up @@ -38,6 +38,7 @@ jobs:
- uses: coursier/setup-action@v1.3.0
with:
jvm: "temurin:17"
apps: sbt
- name: Tests
run: |
.github/setup-test-projects.sh &&\
Expand All @@ -64,6 +65,7 @@ jobs:
- uses: coursier/setup-action@v1.3.0
with:
jvm: "temurin:17"
apps: sbt
- name: Compile and test main projects
# Only running the tests in 2.12 for now. Many test fixtures need
# to be updated for 2.13.
Expand Down
2 changes: 1 addition & 1 deletion backend/src/main/scala/bloop/Compiler.scala
Expand Up @@ -8,7 +8,7 @@ import java.util.concurrent.Executor

import scala.collection.mutable
import scala.concurrent.Promise
import scala.util.control.NonFatal
import scala.util.Try

import bloop.io.AbsolutePath
import bloop.io.ParallelOps
Expand Down
23 changes: 20 additions & 3 deletions backend/src/main/scala/bloop/ScalaInstance.scala
Expand Up @@ -23,7 +23,8 @@ final class ScalaInstance private (
val organization: String,
val name: String,
override val version: String,
override val allJars: Array[File]
override val allJars: Array[File],
val bridgeJarsOpt: Option[Seq[File]] = None
) extends xsbti.compile.ScalaInstance {

override lazy val loaderCompilerOnly: ClassLoader =
Expand Down Expand Up @@ -153,6 +154,15 @@ object ScalaInstance {

private[ScalaInstance] final val ScalacCompilerName = "scala-compiler"

def apply(
scalaOrg: String,
scalaName: String,
scalaVersion: String,
allJars: Seq[AbsolutePath],
logger: Logger
): ScalaInstance =
apply(scalaOrg, scalaName, scalaVersion, allJars, logger, None)

/**
* Reuses all jars to create an Scala instance if and only if all of them exist.
*
Expand All @@ -170,7 +180,8 @@ object ScalaInstance {
scalaName: String,
scalaVersion: String,
allJars: Seq[AbsolutePath],
logger: Logger
logger: Logger,
bridgeJarsOpt: Option[Seq[AbsolutePath]]
): ScalaInstance = {
val jarsKey = allJars.map(_.underlying).sortBy(_.toString).toList
if (allJars.nonEmpty) {
Expand All @@ -179,7 +190,13 @@ object ScalaInstance {
DebugFilter.Compilation
)
jarsKey.foreach(p => logger.debug(s" => $p")(DebugFilter.Compilation))
new ScalaInstance(scalaOrg, scalaName, scalaVersion, allJars.map(_.toFile).toArray)
new ScalaInstance(
scalaOrg,
scalaName,
scalaVersion,
allJars.map(_.toFile).toArray,
bridgeJarsOpt.map(_.map(_.toFile))
)
}

val nonExistingJars = allJars.filter(j => !Files.exists(j.underlying))
Expand Down
Expand Up @@ -116,7 +116,11 @@ object BloopComponentCompiler {
*/
private def compiledBridge(bridgeSources: ModuleID, scalaInstance: ScalaInstance): File = {
val raw = new RawCompiler(scalaInstance, ClasspathOptionsUtil.auto, logger)
val zinc = new BloopComponentCompiler(raw, manager, bridgeSources, logger)
val bridgeJarsOpt = scalaInstance match {
case b: _root_.bloop.ScalaInstance => b.bridgeJarsOpt
case _ => None
}
val zinc = new BloopComponentCompiler(raw, manager, bridgeSources, bridgeJarsOpt, logger)
logger.debug(s"Getting $bridgeSources for Scala ${scalaInstance.version}")(
DebugFilter.Compilation
)
Expand Down Expand Up @@ -229,6 +233,7 @@ private[inc] class BloopComponentCompiler(
compiler: RawCompiler,
manager: BloopComponentManager,
bridgeSources: ModuleID,
bridgeJarsOpt: Option[Seq[File]],
logger: BloopLogger
) {
implicit val debugFilter: DebugFilter.Compilation.type = DebugFilter.Compilation
Expand Down Expand Up @@ -257,23 +262,25 @@ private[inc] class BloopComponentCompiler(
IO.withTemporaryDirectory { _ =>
val shouldResolveSources =
bridgeSources.explicitArtifacts.exists(_.`type` == "src")
val allArtifacts = BloopDependencyResolution.resolveWithErrors(
List(
BloopDependencyResolution
.Artifact(bridgeSources.organization, bridgeSources.name, bridgeSources.revision)
),
logger,
resolveSources = shouldResolveSources,
List(
coursierapi.MavenRepository.of(
"https://scala-ci.typesafe.com/artifactory/scala-integration/"
val allArtifacts = bridgeJarsOpt.map(_.map(_.toPath)).getOrElse {
BloopDependencyResolution.resolveWithErrors(
List(
BloopDependencyResolution
.Artifact(bridgeSources.organization, bridgeSources.name, bridgeSources.revision)
),
logger,
resolveSources = shouldResolveSources,
List(
coursierapi.MavenRepository.of(
"https://scala-ci.typesafe.com/artifactory/scala-integration/"
)
)
)
) match {
case Right(paths) => paths.map(_.underlying).toVector
case Left(t) =>
val msg = s"Couldn't retrieve module $bridgeSources"
throw new InvalidComponent(msg, t)
) match {
case Right(paths) => paths.map(_.underlying).toVector
case Left(t) =>
val msg = s"Couldn't retrieve module $bridgeSources"
throw new InvalidComponent(msg, t)
}
}

if (!shouldResolveSources) {
Expand All @@ -286,7 +293,7 @@ private[inc] class BloopComponentCompiler(
if (!HydraSupport.isEnabled(compiler.scalaInstance)) (bridgeSources.name, sources)
else {
val hydraBridgeModule = HydraSupport.getModuleForBridgeSources(compiler.scalaInstance)
mergeBloopAndHydraBridges(sources, hydraBridgeModule) match {
mergeBloopAndHydraBridges(sources.toVector, hydraBridgeModule) match {
case Right(mergedHydraBridgeSourceJar) =>
(hydraBridgeModule.name, mergedHydraBridgeSourceJar)
case Left(error) =>
Expand Down
10 changes: 5 additions & 5 deletions build.sc
Expand Up @@ -32,7 +32,7 @@ object Dependencies {

def asm = ivy"org.ow2.asm:asm:$asmVersion"
def asmUtil = ivy"org.ow2.asm:asm-util:$asmVersion"
def bloopConfig = ivy"ch.epfl.scala::bloop-config:1.5.5"
def bloopConfig = ivy"ch.epfl.scala::bloop-config:2.0.0"
def brave = ivy"io.zipkin.brave:brave:5.18.1"
def bsp4j = ivy"ch.epfl.scala:bsp4j:2.1.1"
def bsp4s = ivy"ch.epfl.scala::bsp4s:2.1.1"
Expand Down Expand Up @@ -61,7 +61,7 @@ object Dependencies {
def munit = ivy"org.scalameta::munit:0.7.29"
def nailgun = ivy"io.github.alexarchambault.bleep:nailgun-server:1.0.7"
def osLib = ivy"com.lihaoyi::os-lib:0.9.0"
def pprint = ivy"com.lihaoyi::pprint:0.8.1"
def pprint = ivy"com.lihaoyi::pprint:0.9.0"
def sbtTestAgent = ivy"org.scala-sbt:test-agent:1.9.9"
def sbtTestInterface = ivy"org.scala-sbt:test-interface:1.0"
def scalaDebugAdapter = ivy"ch.epfl.scala::scala-debug-adapter:4.0.3"
Expand All @@ -72,12 +72,12 @@ object Dependencies {
def scalaJsSbtTestAdapter1 = ivy"org.scala-js::scalajs-sbt-test-adapter:$scalaJs1Version"
def scalaJsLogging1 = ivy"org.scala-js::scalajs-logging:1.1.1"
def scalaNativeTools04 = ivy"org.scala-native::tools:0.4.17"
def scalaNativeTools05 = ivy"org.scala-native::tools:0.5.0-RC2"
def scalaNativeTools05 = ivy"org.scala-native::tools:0.5.1"
def scalazCore = ivy"org.scalaz::scalaz-core:7.3.8"
def snailgun = ivy"io.github.alexarchambault.scala-cli.snailgun::snailgun-core:0.4.1-sc2"
def sourcecode = ivy"com.lihaoyi::sourcecode:0.3.1"
def sourcecode = ivy"com.lihaoyi::sourcecode:0.4.1"
def svm = ivy"org.graalvm.nativeimage:svm:$graalvmVersion"
def utest = ivy"com.lihaoyi::utest:0.8.2"
def utest = ivy"com.lihaoyi::utest:0.8.3"
def xxHashLibrary = ivy"net.jpountz.lz4:lz4:1.3.0"
def zinc = ivy"org.scala-sbt::zinc:1.9.5"
def zipkinSender = ivy"io.zipkin.reporter2:zipkin-sender-urlconnection:2.17.2"
Expand Down
36 changes: 35 additions & 1 deletion frontend/src/main/scala/bloop/bsp/BloopBspServices.scala
Expand Up @@ -130,6 +130,7 @@ final class BloopBspServices(
.requestAsync(endpoints.BuildTarget.sources)(p => schedule(sources(p)))
.requestAsync(endpoints.BuildTarget.inverseSources)(p => schedule(inverseSources(p)))
.requestAsync(endpoints.BuildTarget.resources)(p => schedule(resources(p)))
.requestAsync(endpoints.BuildTarget.outputPaths)(p => schedule(outputPaths(p)))
.requestAsync(endpoints.BuildTarget.scalacOptions)(p => schedule(scalacOptions(p)))
.requestAsync(endpoints.BuildTarget.javacOptions)(p => schedule(javacOptions(p)))
.requestAsync(endpoints.BuildTarget.compile)(p => schedule(compile(p)))
Expand Down Expand Up @@ -311,7 +312,7 @@ final class BloopBspServices(
dependencySourcesProvider = Some(true),
dependencyModulesProvider = Some(true),
resourcesProvider = Some(true),
outputPathsProvider = None,
outputPathsProvider = Some(true),
buildTargetChangedProvider = Some(false),
jvmTestEnvironmentProvider = Some(true),
jvmRunEnvironmentProvider = Some(true),
Expand Down Expand Up @@ -1204,6 +1205,39 @@ final class BloopBspServices(
}
}

def outputPaths(
request: bsp.OutputPathsParams
): BspEndpointResponse[bsp.OutputPathsResult] = {
def outputPaths(
projects: Seq[ProjectMapping],
state: State
): BspResult[bsp.OutputPathsResult] = {

val response = bsp.OutputPathsResult(
projects.iterator.map {
case (target, project) =>
val outputPathItems =
List(
bsp.OutputPathItem(bsp.Uri(project.out.toBspUri), bsp.OutputPathItemKind.Directory)
)
bsp.OutputPathsItem(target, outputPathItems)
}.toList
)

Task.now((state, Right(response)))
}

ifInitialized(None) { (state: State, logger: BspServerLogger) =>
mapToProjects(request.targets, state) match {
case Left(error) =>
// Log the mapping error to the user via a log event + an error status code
logger.error(error)
Task.now((state, Right(bsp.OutputPathsResult(Nil))))
case Right(mappings) => outputPaths(mappings, state)
}
}
}

def dependencyModules(
request: bsp.DependencyModulesParams
): BspEndpointResponse[bsp.DependencyModulesResult] = {
Expand Down
17 changes: 7 additions & 10 deletions frontend/src/main/scala/bloop/bsp/ProjectUris.scala
Expand Up @@ -12,19 +12,16 @@ import bloop.engine.State
import bloop.io.AbsolutePath

object ProjectUris {
private val queryPrefix = "id="
def getProjectDagFromUri(projectUri: String, state: State): Either[String, Option[Project]] = {
if (projectUri.isEmpty) Left("URI cannot be empty.")
else {
val query = Try(new URI(projectUri).getRawQuery().split("&").map(_.split("="))).toEither
query match {
case Left(_) =>
Try(new URI(projectUri).getQuery()).toEither match {
case Right(query) if query.startsWith(queryPrefix) =>
val projectName = query.stripPrefix(queryPrefix)
Right(state.build.getProjectFor(projectName))
case _ =>
Left(s"URI '${projectUri}' has invalid format. Example: ${ProjectUris.Example}")
case Right(parsed) =>
parsed.headOption match {
case Some(Array("id", projectName)) => Right(state.build.getProjectFor(projectName))
case _ =>
Left(s"URI '${projectUri}' has invalid format. Example: ${ProjectUris.Example}")
}
}
}
}
Expand All @@ -39,7 +36,7 @@ object ProjectUris {
existingUri.getHost,
existingUri.getPort,
existingUri.getPath,
s"id=${id}",
s"$queryPrefix${id}",
existingUri.getFragment
)
}
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/main/scala/bloop/data/ClientInfo.scala
Expand Up @@ -11,11 +11,11 @@ import scala.collection.mutable
import scala.util.control.NonFatal
import scala.util.matching.Regex

import bloop.ClientClassesObserver
import bloop.io.AbsolutePath
import bloop.io.Filenames
import bloop.io.Paths
import bloop.util.UUIDUtil
import bloop.ClientClassesObserver

sealed trait ClientInfo {

Expand Down
9 changes: 8 additions & 1 deletion frontend/src/main/scala/bloop/data/Project.scala
Expand Up @@ -290,7 +290,14 @@ object Project {
else {
val scalaJars = scala.jars.map(AbsolutePath.apply)
Some(
ScalaInstance(scala.organization, scala.name, scala.version, scalaJars, logger)
ScalaInstance(
scala.organization,
scala.name,
scala.version,
scalaJars,
logger,
scala.bridgeJars.map(_.map(AbsolutePath(_)))
)
)
}
}
Expand Down
Expand Up @@ -2,6 +2,7 @@ package bloop.engine.tasks.compilation

import scala.concurrent.Promise

import bloop.ClientClassesObserver
import bloop.CompileOutPaths
import bloop.Compiler
import bloop.ScalaInstance
Expand All @@ -23,7 +24,6 @@ import bloop.tracing.BraveTracer

import monix.reactive.Observable
import sbt.internal.inc.PlainVirtualFileConverter
import bloop.ClientClassesObserver

sealed trait CompileBundle

Expand Down
Expand Up @@ -3,6 +3,7 @@ package bloop.engine.tasks.toolchains
import java.lang.reflect.InvocationTargetException
import java.nio.file.Path

import scala.concurrent.Future
import scala.util.Try

import bloop.DependencyResolution
Expand All @@ -14,7 +15,6 @@ import bloop.internal.build.BuildInfo
import bloop.io.AbsolutePath
import bloop.logging.Logger
import bloop.task.Task
import scala.concurrent.Future

final class ScalaNativeToolchain private (classLoader: ClassLoader) {

Expand Down
@@ -1,5 +1,5 @@
addSbtPlugin("org.portable-scala" % "sbt-scala-native-crossproject" % "1.0.0")
addSbtPlugin("org.scala-native" % "sbt-scala-native" % "0.5.0-RC2")
addSbtPlugin("org.scala-native" % "sbt-scala-native" % "0.5.1")

val pluginVersion = sys.props.getOrElse(
"bloopVersion",
Expand Down
13 changes: 13 additions & 0 deletions frontend/src/test/scala/bloop/bsp/BspBaseSuite.scala
Expand Up @@ -349,6 +349,19 @@ abstract class BspBaseSuite extends BaseSuite with BspClientTest {
TestUtil.await(FiniteDuration(5, "s"))(resourcesTask)
}

def requestOutputPaths(project: TestProject): bsp.OutputPathsResult = {
val outputPathsTask = {
client0
.request(endpoints.BuildTarget.outputPaths, bsp.OutputPathsParams(List(project.bspId)))
.map {
case RpcFailure(_, error) => fail(s"Received error ${error}")
case RpcSuccess(resources, _) => resources
}
}

TestUtil.await(FiniteDuration(5, "s"))(outputPathsTask)
}

def requestDependencyModules(project: TestProject): bsp.DependencyModulesResult = {
val dependencyModulesTask = {
client0
Expand Down
31 changes: 31 additions & 0 deletions frontend/src/test/scala/bloop/bsp/BspProtocolSpec.scala
Expand Up @@ -516,6 +516,37 @@ class BspProtocolSpec(
}
}

test("outputPaths request works") {
TestUtil.withinWorkspace { workspace =>
val logger = new RecordingLogger(ansiCodesSupported = false)
loadBspBuildFromResources("cross-test-build-scalajs-0.6", workspace, logger) { build =>
val mainProject = build.projectFor("test-project")
val testProject = build.projectFor("test-project-test")
val mainJsProject = build.projectFor("test-projectJS")
val testJsProject = build.projectFor("test-projectJS-test")
val rootMain = build.projectFor("cross-test-build-scalajs-0-6")
val rootTest = build.projectFor("cross-test-build-scalajs-0-6-test")

def checkOutputPaths(project: TestProject): Unit = {
val outputPathsResult = build.state.requestOutputPaths(project)
assert(outputPathsResult.items.size == 1)
val outputPathsItem = outputPathsResult.items.head
assert(outputPathsItem.target == project.bspId)
val outputPaths = outputPathsItem.outputPaths.map(_.uri.toPath)
val expectedOutputPaths = List(project.config.out.toAbsolutePath())
assert(outputPaths == expectedOutputPaths)
}

checkOutputPaths(mainProject)
checkOutputPaths(testProject)
checkOutputPaths(mainJsProject)
checkOutputPaths(testJsProject)
checkOutputPaths(rootMain)
checkOutputPaths(rootTest)
}
}
}

test("dependency modules request works") {
TestUtil.withinWorkspace { workspace =>
val logger = new RecordingLogger(ansiCodesSupported = false)
Expand Down

0 comments on commit cf0e8bd

Please sign in to comment.