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

WIP use sbt 2.0.0-M4 & cross-build against it #440

Draft
wants to merge 2 commits into
base: main
Choose a base branch
from
Draft
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
80 changes: 24 additions & 56 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,65 +5,31 @@ on:
- main
pull_request:
jobs:
jdk8:
name: JDK8 tests
ubuntu:
strategy:
fail-fast: false
matrix:
jvm: ["8", "11", "17", "21", "23"]
scala: ["2.12.x", "3.x"]
name: Ubuntu / JDK${{ matrix.jvm }} / Scala ${{ matrix.scala }}
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: coursier/setup-action@v1
with:
apps: sbt
jvm: temurin:8
- run: rm -rf src/sbt-test/skip-sbt1.4
- run: sbt test scripted
jdk11:
name: JDK11 tests
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: coursier/setup-action@v1
with:
apps: sbt
jvm: temurin:11
- run: rm -rf src/sbt-test/skip-sbt1.4
- run: sbt test scripted
jdk17:
name: JDK17 tests
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: coursier/setup-action@v1
with:
apps: sbt
jvm: temurin:17
- run: rm -rf src/sbt-test/skip-java17+
- run: rm -rf src/sbt-test/skip-sbt1.4
- run: sbt test scripted

jdk21:
name: JDK21 tests
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: coursier/setup-action@v1
with:
apps: sbt
jvm: temurin:21
- run: rm -rf src/sbt-test/skip-java17+
- run: sbt test scripted
jdk23:
name: JDK23 tests
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: coursier/setup-action@v1
with:
apps: sbt
jvm: temurin:23
- run: rm -rf src/sbt-test/skip-java17+
- run: sbt test scripted
jvm: temurin:${{ matrix.jvm }}
- if: matrix.jvm == '8' || matrix.jvm == '11' || matrix.jvm == '17'
run: rm -rf src/sbt-test/skip-sbt1.4
- if: matrix.jvm == '17' || matrix.jvm == '21' || matrix.jvm == '23'
run: rm -rf src/sbt-test/skip-java17+
- run: sbt ++${{ matrix.scala }} test scripted
windows:
name: Windows tests
strategy:
fail-fast: false
matrix:
scala: ["2.12.x", "3.x"]
name: Windows / Scala ${{ matrix.scala }}
runs-on: windows-latest
steps:
- uses: actions/checkout@v4
Expand All @@ -72,12 +38,14 @@ jobs:
apps: sbt
- run: rm -r -fo src\sbt-test\skip-sbt1.4
- run: rm -r -fo src\sbt-test\skip-windows
- run: sbt test-skip-windows scripted
shell: bash
Copy link
Collaborator Author

@bjaglin bjaglin Mar 13, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The presence of this was triggering sbtn usage, which does not seem to work on any github action

before

Run sbt -v '++2.12.x test-skip-windows scripted'
  sbt -v '++2.12.x test-skip-windows scripted'
  shell: C:\Program Files\Git\bin\bash.EXE --noprofile --norc -e -o pipefail {0}
  env:
    COURSIER_BIN_DIR: C:\Users\runneradmin\cs\bin
[sbt_options] declare -a sbt_options=()
[debug] running native client
# Executing command line:
"/c/Program Files (x86)/sbt/bin/sbtn-x86_64-pc-win32.exe"
"--sbt-script=/c/Program%20Files (x86)/sbt/bin/sbt"
-v
"++2.12.x test-skip-windows scripted"

[info] entering *experimental* thin client - BEEP WHIRR
[info] server was not detected. starting an instance
[error] Failed to start server : java.io.IOException: Cannot run program "C:/Program Files" (in directory "D:\a\sbt-scalafix\sbt-scalafix"): CreateProcess error=5, Access is denied
[error] failed to connect to server

after


Started at 1741908079000
Run sbt ++2.12.x test-skip-windows scripted
  sbt ++2.12.x test-skip-windows scripted
  shell: C:\Program Files\PowerShell\7\pwsh.EXE -command ". '{0}'"
  env:
    COURSIER_BIN_DIR: C:\Users\runneradmin\cs\bin
[info] [launcher] getting org.scala-sbt sbt 2.0.0-M4  (this may take some time)...
[info] [launcher] getting Scala 3.6.4 (for sbt)...
[info] welcome to sbt 2.0.0-M4 (Temurin Java 1.8.0_442)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

checks:
name: Scalafmt
- run: sbt ++${{ matrix.scala }} test-skip-windows scripted
formatting:
name: Scalafmt and Scalafix
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: coursier/setup-action@v1
with:
apps: sbt
- run: ./bin/scalafmt --test
- run: sbt "scalafixAll --check"
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

enforcing scalafix in this PR mostly for ExplicitResultTypes, to have deterministic types from the beginning for the sbt 2.x artifact

22 changes: 17 additions & 5 deletions .scalafix.conf
Original file line number Diff line number Diff line change
@@ -1,7 +1,19 @@
rules = [
DisableSyntax
]
DisableSyntax.keywords = [
var
null
ExplicitResultTypes,
OrganizeImports,
RemoveUnused
]

OrganizeImports {
groups = [
"re:javax?\\."
"scala."
"sbt."
"*"
]
targetDialect = Scala3
Copy link
Collaborator Author

@bjaglin bjaglin Mar 9, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks to -Xsource:3 (which was added by default for sbt1 but was removed in sbt2, needing an explicit addition in this PR), Scala 3 import syntax can be used sbt1 metabuilds (and thus sb1 plugins) .

So we might as well start using OrganizeImports with Scala 3 syntax for all files (not just the Scala 3 ones), as we start enforcing scalafix for ExplicitResultTypes

}

RemoveUnused {
imports = false
}
4 changes: 4 additions & 0 deletions bin/test-release.sh
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,7 @@ version=$1
cs resolve \
--sbt-version 1.0 \
--sbt-plugin "ch.epfl.scala:sbt-scalafix:$version"

cs resolve \
--sbt-version 2.0.0-M4 \
--sbt-plugin "ch.epfl.scala:sbt-scalafix:$version"
61 changes: 40 additions & 21 deletions build.sbt
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
inThisBuild(
List(
Test / parallelExecution := false,
scalafixDependencies := List(
// Custom rule published to Maven Central https://github.com/scalacenter/example-scalafix-rule
"ch.epfl.scala" %% "example-scalafix-rule" % "1.4.0"
)
)
// dogfooding
semanticdbEnabled := true
scalafixDependencies := List(
// Custom rule published to Maven Central https://github.com/scalacenter/example-scalafix-rule
"ch.epfl.scala" %% "example-scalafix-rule" % "1.4.0"
)
onLoadMessage := s"Welcome to sbt-scalafix ${version.value}"

onLoadMessage := s"Welcome to sbt-scalafix ${version.value} built with Scala ${scalaVersion.value}"
moduleName := "sbt-scalafix"

// Publish settings
Expand Down Expand Up @@ -44,29 +42,50 @@ libraryDependencies ++= List(
"org.scalatest" %% "scalatest" % "3.2.19" % Test
)

scalaVersion := "2.12.20"
lazy val scala212 = "2.12.20" // bin/test-release.sh
lazy val scala3 = "3.6.4" // bin/test-release.sh

scalaVersion := scala3
crossScalaVersions := Seq(scala212, scala3)

// keep this as low as possible to avoid running into binary incompatibility such as https://github.com/sbt/sbt/issues/5049
pluginCrossBuild / sbtVersion := "1.4.0"
pluginCrossBuild / sbtVersion := {
scalaBinaryVersion.value match {
case "2.12" =>
"1.4.0"
case _ =>
"2.0.0-M4" // bin/test-release.sh
}
}

scriptedSbt := {
val jdk = System.getProperty("java.specification.version").toDouble

if (jdk >= 21)
"1.9.0" // first release that supports JDK21
Ordering[String].max(
(pluginCrossBuild / sbtVersion).value,
"1.9.0" // first release that supports JDK21
)
else
(pluginCrossBuild / sbtVersion).value
}

libraryDependencies += compilerPlugin(scalafixSemanticdb)

scalacOptions ++= List("-Ywarn-unused", "-Yrangepos")

scalacOptions ++= List(
"-target:jvm-1.8",
"-Xfatal-warnings",
"-Xlint"
)
scalacOptions ++= {
scalaBinaryVersion.value match {
case "2.12" =>
List(
"-Xsource:3",
"-Ywarn-unused",
"-Xlint",
"-Xfatal-warnings"
)
case _ =>
List(
"-Wunused:all",
"-Werror"
)
}
}

// Scripted
enablePlugins(ScriptedPlugin)
Expand Down
3 changes: 2 additions & 1 deletion project/Dependencies.scala
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ object Dependencies {
val all = List(
"org.eclipse.jgit" % "org.eclipse.jgit" % "5.13.3.202401111512-r",
"ch.epfl.scala" % "scalafix-interfaces" % scalafixVersion,
"io.get-coursier" % "interface" % "1.0.28"
"io.get-coursier" % "interface" % "1.0.28",
"org.scala-lang.modules" %% "scala-collection-compat" % "2.13.0"
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

helps getting rid of import scala.collection.JavaConverters.* mostly

)
}
2 changes: 1 addition & 1 deletion project/build.properties
Original file line number Diff line number Diff line change
@@ -1 +1 @@
sbt.version=1.10.7
sbt.version=2.0.0-M4
6 changes: 3 additions & 3 deletions project/plugins.sbt
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
resolvers ++= Resolver.sonatypeOssRepos("public")
addSbtPlugin("com.github.sbt" % "sbt-ci-release" % "1.9.2")
//addSbtPlugin("com.github.sbt" % "sbt-ci-release" % "1.9.2")
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ pending cross-publishing to 2.0.0-M4


libraryDependencies += "org.scala-sbt" %% "scripted-plugin" % sbtVersion.value
// dogfooding
Compile / unmanagedSourceDirectories ++= {
val root = (ThisBuild / baseDirectory).value.getParentFile / "src" / "main"
List(
root / "scala",
root / "scala-sbt-1.0"
root / "scala-3"
)
}
libraryDependencies ++= Dependencies.all
30 changes: 30 additions & 0 deletions src/main/scala-2.12/scalafix/internal/sbt/Compat.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package scalafix.internal.sbt

import java.io.File
import java.nio.file.Path

import sbt.Attributed
import sbt.Keys
import sbt.ModuleID

import xsbti.FileConverter

object Compat {

def toPath(
attributed: Attributed[File]
)(implicit conv: FileConverter): Path =
toFile(attributed).toPath()

def toFile(
attributed: Attributed[File]
)(implicit conv: FileConverter): File = {
val _ = conv // avoid unused warning
attributed.data
}

def extractModuleID(
attributed: Attributed[File]
): Option[ModuleID] =
attributed.get(Keys.moduleID.key)
}
32 changes: 32 additions & 0 deletions src/main/scala-3/scalafix/internal/sbt/Compat.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package scalafix.internal.sbt

import java.io.File
import java.nio.file.Path

import sbt.Attributed
import sbt.Classpaths
import sbt.Keys
import sbt.ModuleID

import xsbti.FileConverter
import xsbti.HashedVirtualFileRef

object Compat {

def toPath(
attributed: Attributed[HashedVirtualFileRef]
)(using conv: FileConverter): Path =
conv.toPath(attributed.data)

def toFile(
attributed: Attributed[HashedVirtualFileRef]
)(using conv: FileConverter): File =
toPath(attributed).toFile()
Comment on lines +16 to +24
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.


def extractModuleID(
attributed: Attributed[HashedVirtualFileRef]
): Option[ModuleID] =
attributed
.get(Keys.moduleIDStr)
.map(Classpaths.moduleIdJsonKeyFormat.read)
Comment on lines +30 to +31
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

}
3 changes: 1 addition & 2 deletions src/main/scala/scalafix/internal/sbt/BlockingCache.scala
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
package scalafix.internal.sbt

import java.{util => ju}

import java.lang.ref.SoftReference
import java.util as ju

/** A basic thread-safe cache with arbitrary eviction on GC pressure. */
class BlockingCache[K, V] {
Expand Down
17 changes: 11 additions & 6 deletions src/main/scala/scalafix/internal/sbt/CoursierRepoResolvers.scala
Original file line number Diff line number Diff line change
@@ -1,13 +1,18 @@
package scalafix.internal.sbt

import coursierapi.{Credentials, IvyRepository, MavenRepository, Repository}
import org.apache.ivy.plugins.resolver.IBiblioResolver
import java.net.MalformedURLException
import java.nio.file.Paths

import scala.jdk.CollectionConverters.*

import sbt.librarymanagement.{Configuration as _, MavenRepository as _, *}
import sbt.util.Logger

import java.net.MalformedURLException
import java.nio.file.Paths
import scala.collection.JavaConverters.*
import coursierapi.Credentials
import coursierapi.IvyRepository
import coursierapi.MavenRepository
import coursierapi.Repository
import org.apache.ivy.plugins.resolver.IBiblioResolver

// vendor from sbt-coursier/lmcoursier.internal.Resolvers
object CoursierRepoResolvers {
Expand Down Expand Up @@ -122,7 +127,7 @@ object CoursierRepoResolvers {

private object IBiblioRepository {

private def stringVector(v: java.util.List[_]): Vector[String] =
private def stringVector(v: java.util.List[?]): Vector[String] =
Option(v).map(_.asScala.toVector).getOrElse(Vector.empty).collect {
case s: String => s
}
Expand Down
3 changes: 2 additions & 1 deletion src/main/scala/scalafix/internal/sbt/DependencyRule.scala
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
package scalafix.internal.sbt

import sbt.ModuleID
import scala.util.matching.Regex

import sbt.ModuleID

case class DependencyRule(
ruleName: String,
dependency: ModuleID
Expand Down
3 changes: 2 additions & 1 deletion src/main/scala/scalafix/internal/sbt/Implicits.scala
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package scalafix.internal.sbt

import sbt.librarymanagement._
import sbt.librarymanagement.*

import scalafix.sbt.InvalidArgument

trait Implicits {
Expand Down
9 changes: 5 additions & 4 deletions src/main/scala/scalafix/internal/sbt/JGitCompletions.scala
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
package scalafix.internal.sbt

import java.nio.file.Path

import scala.jdk.CollectionConverters.*
import scala.util.Try

import org.eclipse.jgit.api.Git
import org.eclipse.jgit.lib.Constants.DOT_GIT
import org.eclipse.jgit.lib.RefDatabase
Expand All @@ -9,10 +14,6 @@ import org.eclipse.jgit.storage.file.FileRepositoryBuilder
import org.eclipse.jgit.util.FS
import org.eclipse.jgit.util.GitDateFormatter

import java.nio.file.Path
import scala.collection.JavaConverters._
import scala.util.Try

class JGitCompletion(cwd: Path) {
private val isGitRepository =
RepositoryCache.FileKey
Expand Down
Loading
Loading