Skip to content

Commit

Permalink
Merge pull request #100 from eed3si9n/wip/scala3
Browse files Browse the repository at this point in the history
Add support for auto detecting Scala 3 apps
  • Loading branch information
eed3si9n authored Sep 21, 2022
2 parents 605b678 + 99e17aa commit 289a618
Show file tree
Hide file tree
Showing 8 changed files with 121 additions and 55 deletions.
17 changes: 6 additions & 11 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,20 +18,15 @@ jobs:
JVM_OPTS: -Xms2048M -Xmx2048M -Xss6M -XX:ReservedCodeCacheSize=256M -Dfile.encoding=UTF-8
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Setup
uses: olafurpg/setup-scala@v10
uses: actions/checkout@v3
- name: Setup JDK
uses: actions/setup-java@v3
with:
java-version: "adopt@1.${{ matrix.java }}"
- name: Coursier cache
uses: coursier/cache-action@v6
distribution: temurin
java-version: "${{ matrix.java }}"
cache: sbt
- name: Build and test
run: |
sbt -v "mimaReportBinaryIssues; scalafmtCheckAll; shadedPackageBin; test;"
ci-test/test.sh
rm -rf "$HOME/.ivy2/local" || true
find $HOME/Library/Caches/Coursier/v1 -name "ivydata-*.properties" -delete || true
find $HOME/.ivy2/cache -name "ivydata-*.properties" -delete || true
find $HOME/.cache/coursier/v1 -name "ivydata-*.properties" -delete || true
find $HOME/.sbt -name "*.lock" -delete || true
shell: bash
2 changes: 1 addition & 1 deletion build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ Global / onChangedBuildSource := ReloadOnSourceChanges
ThisBuild / dynverSonatypeSnapshots := true
ThisBuild / version := {
val orig = (ThisBuild / version).value
if (orig.endsWith("-SNAPSHOT")) "1.2.0-SNAPSHOT"
if (orig.endsWith("-SNAPSHOT")) "1.4.0-SNAPSHOT"
else orig
}
ThisBuild / description := "Standalone launcher for maven/ivy deployed projects"
Expand Down
2 changes: 1 addition & 1 deletion ci-test/test.sh
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#!/bin/bash -e

LAUNCHER="../../launcher-implementation/target/proguard/launcher-implementation-1.2.0-SNAPSHOT-shading.jar"
LAUNCHER="../../launcher-implementation/target/proguard/launcher-implementation-1.4.0-SNAPSHOT-shading.jar"

pushd ci-test/app0
COURSIER_CACHE=/tmp/cache/ java -jar $LAUNCHER @sbt.1.3.13.boot.properties exit
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@ private[boot] object BootConfiguration {
// these are the Scala module identifiers to resolve/retrieve
val ScalaOrg = "org.scala-lang"
val CompilerModuleName = "scala-compiler"
val Compiler3ModuleName = "scala3-compiler_3"
val LibraryModuleName = "scala-library"
val Library3ModuleName = "scala3-library_3"

val JUnitName = "junit"
val JAnsiVersion = "1.18"
Expand Down Expand Up @@ -56,7 +58,8 @@ private[boot] object BootConfiguration {
* The loader will check that these classes can be loaded and will assume that their presence indicates
* the Scala compiler and library have been downloaded.
*/
val TestLoadScalaClasses = "scala.Option" :: "scala.tools.nsc.Global" :: Nil
val TestLoadScala2Classes = "scala.Option" :: "scala.tools.nsc.Global" :: Nil
val TestLoadScala3Classes = "scala.Option" :: "dotty.tools.dotc.Driver" :: Nil

val ScalaHomeProperty = "scala.home"
val UpdateLogName = "update.log"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,20 +56,40 @@ class CousierUpdate(config: UpdateConfiguration) {
Console.err.println(
s"[info] [launcher] getting ${scalaOrgString}Scala $scalaVersion ${reason}..."
)
withPublication(
Dependency(
Module(Organization(scalaOrg), ModuleName(CompilerModuleName)),
scalaVersion
),
u.classifiers
) :::
withPublication(
Dependency(
Module(Organization(scalaOrg), ModuleName(LibraryModuleName)),
scalaVersion
),
u.classifiers
)
scalaVersion match {
case sv if sv.startsWith("2.") =>
withPublication(
Dependency(
Module(Organization(scalaOrg), ModuleName(CompilerModuleName)),
scalaVersion
),
u.classifiers
) :::
withPublication(
Dependency(
Module(Organization(scalaOrg), ModuleName(LibraryModuleName)),
scalaVersion
),
u.classifiers
)
case sv if sv.startsWith("3.") =>
withPublication(
Dependency(
Module(Organization(scalaOrg), ModuleName(Compiler3ModuleName)),
scalaVersion
),
u.classifiers
) :::
withPublication(
Dependency(
Module(Organization(scalaOrg), ModuleName(Library3ModuleName)),
scalaVersion
),
u.classifiers
)
case _ =>
sys.error("unsupported Scala version " + scalaVersion)
}
case u: UpdateApp =>
val app = u.id
val resolvedName = (app.crossVersioned, scalaVersion) match {
Expand Down Expand Up @@ -103,6 +123,22 @@ class CousierUpdate(config: UpdateConfiguration) {
update(target, deps)
}

private def detectScalaVersion(dependencySet: Set[Dependency]): Option[String] = {
def detectScalaVersion3: Option[String] =
(dependencySet collect {
case d: Dependency
if d.module == Module(Organization(scalaOrg), ModuleName(Library3ModuleName)) =>
d.version
}).headOption
def detectScalaVersion2: Option[String] =
(dependencySet collect {
case d: Dependency
if d.module == Module(Organization(scalaOrg), ModuleName(LibraryModuleName)) =>
d.version
}).headOption
detectScalaVersion3.orElse(detectScalaVersion2)
}

/** Runs the resolve and retrieve for the given moduleID, which has had its dependencies added already. */
private def update(
target: UpdateTarget,
Expand All @@ -115,20 +151,22 @@ class CousierUpdate(config: UpdateConfiguration) {
.withScalaVersion(sv)
.withForceScalaVersion(true)
case _ =>
ResolutionParams()
detectScalaVersion(deps.toSet) match {
case Some(sv) =>
ResolutionParams()
.withScalaVersion(sv)
.withForceScalaVersion(true)
case _ =>
ResolutionParams()
}
}
val r: Resolution = Resolve()
.withCache(coursierCache)
.addDependencies(deps: _*)
.withRepositories(repos)
.withResolutionParams(params)
.run()
val actualScalaVersion =
(r.dependencySet.set collect {
case d: Dependency
if d.module == Module(Organization(scalaOrg), ModuleName(LibraryModuleName)) =>
d.version
}).headOption
val actualScalaVersion = detectScalaVersion(r.dependencySet.set)
val retrieveDir = target match {
case u: UpdateScala =>
new File(new File(bootDirectory, baseDirectoryName(scalaOrg, scalaVersion)), "lib")
Expand Down
8 changes: 6 additions & 2 deletions launcher-implementation/src/main/scala/xsbt/boot/Launch.scala
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,8 @@ import BootConfiguration.{
baseDirectoryName,
extractScalaVersion,
ScalaDirectoryName,
TestLoadScalaClasses,
TestLoadScala2Classes,
TestLoadScala3Classes,
ScalaOrg
}
class Launch private[xsbt] (
Expand Down Expand Up @@ -409,9 +410,12 @@ class Launch private[xsbt] (
val scalaM = scalaModule(scalaOrg, scalaVersion)
val (scalaHome, lib) = scalaDirs(scalaM, scalaOrg, scalaVersion)
val baseDirs = lib :: Nil
def testLoadScalaClasses =
if (scalaVersion.startsWith("2.")) TestLoadScala2Classes
else TestLoadScala3Classes
def provider(retrieved: RetrievedModule): xsbti.ScalaProvider = {
val p = scalaProvider(scalaVersion, retrieved, classLoader, lib)
checkLoader(p.loader, retrieved.definition, TestLoadScalaClasses, p)
checkLoader(p.loader, retrieved.definition, testLoadScalaClasses, p)
}
existing(scalaM, scalaOrg, Some(scalaVersion), _ => baseDirs) flatMap { mod =>
try Some(provider(mod))
Expand Down
60 changes: 43 additions & 17 deletions launcher-implementation/src/main/scala/xsbt/boot/Update.scala
Original file line number Diff line number Diff line change
Expand Up @@ -201,22 +201,44 @@ final class Update(config: UpdateConfiguration) {
val dep = target match {
case u: UpdateScala =>
val scalaVersion = getScalaVersion
addDependency(
moduleID,
scalaOrg,
CompilerModuleName,
scalaVersion,
"default;optional(default)",
u.classifiers
)
val ddesc = addDependency(
moduleID,
scalaOrg,
LibraryModuleName,
scalaVersion,
"default",
u.classifiers
)
val ddesc = scalaVersion match {
case sv if sv.startsWith("2.") =>
addDependency(
moduleID,
scalaOrg,
CompilerModuleName,
scalaVersion,
"default;optional(default)",
u.classifiers
)
addDependency(
moduleID,
scalaOrg,
LibraryModuleName,
scalaVersion,
"default",
u.classifiers
)
case sv if sv.startsWith("3.") =>
addDependency(
moduleID,
scalaOrg,
Compiler3ModuleName,
scalaVersion,
"default;optional(default)",
u.classifiers
)
addDependency(
moduleID,
scalaOrg,
Library3ModuleName,
scalaVersion,
"default",
u.classifiers
)
case _ =>
error("unsupported Scala version " + scalaVersion)
}
excludeJUnit(moduleID)
val scalaOrgString = if (scalaOrg != ScalaOrg) scalaOrg + " " else ""
Console.err.println(
Expand Down Expand Up @@ -324,6 +346,7 @@ final class Update(config: UpdateConfiguration) {
rule
}
val scalaLibraryId = ModuleId.newInstance(ScalaOrg, LibraryModuleName)
val scala3Library3Id = ModuleId.newInstance(ScalaOrg, Library3ModuleName)
// Returns the version of the scala library, as well as `dep` (a dependency of `module`) after it's been resolved
private def resolve(
eventManager: EventManager,
Expand All @@ -348,8 +371,11 @@ final class Update(config: UpdateConfiguration) {
error("error retrieving required libraries")
}
val modules = moduleRevisionIDs(resolveReport)
extractVersion(modules, scalaLibraryId) -> extractVersion(modules, dep)
val autoScala =
extractVersion(modules, scala3Library3Id).orElse(extractVersion(modules, scalaLibraryId))
autoScala -> extractVersion(modules, dep)
}

private[this] def extractVersion(
modules: Seq[ModuleRevisionId],
dep: ModuleId
Expand Down
2 changes: 1 addition & 1 deletion project/Deps.scala
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,6 @@ object Deps {

// TODO - these should be like the above, just ModuleIDs
lazy val ivy = "org.scala-sbt.ivy" % "ivy" % "2.3.0-sbt-839fad1cdc07cf6fc81364d74c323867230432ad"
lazy val coursier = "io.get-coursier" %% "coursier" % "2.0.13"
lazy val coursier = "io.get-coursier" %% "coursier" % "2.0.16"
lazy val scalaCompiler = Def.setting("org.scala-lang" % "scala-compiler" % scalaVersion.value)
}

0 comments on commit 289a618

Please sign in to comment.