diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9a2949da0e6..6f48120b8e3 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -63,7 +63,7 @@ jobs: os: macOS-latest java: "17" - type: sbt - command: bin/test.sh 'slow/testOnly -- tests.sbt.*' + command: bin/test.sh '+sbt-metals/publishLocal; slow/testOnly -- tests.sbt.*' name: Sbt integration os: ubuntu-latest java: "17" @@ -72,6 +72,11 @@ jobs: name: Sbt-metals/scripted jdk11 os: ubuntu-latest java: "11" + - type: sbt-metals Sbt 2 + command: bin/test.sh '++3.6.2; sbt-metals/scripted' + name: sbt-metals/scripted (Sbt 2) + os: ubuntu-latest + java: "17" - type: maven command: bin/test.sh 'slow/testOnly -- tests.maven.*' name: Maven integration @@ -145,6 +150,7 @@ jobs: - name: ${{ matrix.command }} run: ${{ matrix.command }} env: + METALS_TEST: true GOOGLE_APPLICATION_CREDENTIALS: ${{ secrets.GOOGLE_APPLICATION_CREDENTIALS }} GOOGLE_APPLICATION_CREDENTIALS_JSON: ${{ secrets.GOOGLE_APPLICATION_CREDENTIALS_JSON }} - name: "test download dependencies" diff --git a/build.sbt b/build.sbt index 8e922a8287a..ee7a984a66f 100644 --- a/build.sbt +++ b/build.sbt @@ -11,6 +11,7 @@ Global / resolvers += "scala-integration" at def localSnapshotVersion = "1.4.3-SNAPSHOT" def isCI = System.getenv("CI") != null +def isTest = System.getenv("METALS_TEST") != null def isScala211(v: Option[(Long, Long)]): Boolean = v.contains((2, 11)) def isScala212(v: Option[(Long, Long)]): Boolean = v.contains((2, 12)) @@ -41,7 +42,7 @@ ThisBuild / semanticdbVersion := V.semanticdb(scalaVersion.value) inThisBuild( List( version ~= { dynVer => - if (isCI) dynVer + if (isCI && !isTest) dynVer else localSnapshotVersion // only for local publishing }, scalaVersion := V.scala213, @@ -526,7 +527,20 @@ lazy val `sbt-metals` = project "lastSupportedSemanticdb" -> SemanticDbSupport.last, ), scalaVersion := V.scala212, + crossScalaVersions := Seq(V.scala212, V.scala3ForSBT2), scriptedLaunchOpts ++= Seq(s"-Dplugin.version=${version.value}"), + (pluginCrossBuild / sbtVersion) := { + scalaBinaryVersion.value match { + case "2.12" => "1.5.8" + case _ => "2.0.0-M3" + } + }, + scalacOptions ++= { + scalaBinaryVersion.value match { + case "2.12" => "-Xsource:3" :: Nil + case _ => Nil + } + }, ) .settings(sharedScalacOptions) .enablePlugins(BuildInfoPlugin, SbtPlugin) diff --git a/metals/src/main/scala/scala/meta/internal/builds/SbtBuildTool.scala b/metals/src/main/scala/scala/meta/internal/builds/SbtBuildTool.scala index d36a4f7b52c..3cb7bede3af 100644 --- a/metals/src/main/scala/scala/meta/internal/builds/SbtBuildTool.scala +++ b/metals/src/main/scala/scala/meta/internal/builds/SbtBuildTool.scala @@ -302,11 +302,26 @@ object SbtBuildTool { def writeSbtMetalsPlugins(projectRoot: AbsolutePath): Boolean = { val mainMeta = projectRoot.resolve("project") val metaMeta = projectRoot.resolve("project").resolve("project") - val writtenPlugin = - writePlugins(mainMeta, metalsPluginDetails, debugAdapterPluginDetails) - val writtenMeta = - writePlugins(metaMeta, metalsPluginDetails, jdiToolsPluginDetails) - writtenPlugin || writtenMeta + + val isSbt2 = + SbtBuildTool.loadVersion(projectRoot).exists(_.startsWith("2.")) + if (isSbt2) { + val writtenPlugin = writePlugins(mainMeta, metalsPluginDetails) + val writtenMeta = writePlugins( + metaMeta, + metalsPluginDetails, + ) + writtenMeta || writtenPlugin + } else { + val writtenPlugin = writePlugins( + mainMeta, + metalsPluginDetails, + debugAdapterPluginDetails, + ) + val writtenMeta = + writePlugins(metaMeta, metalsPluginDetails, jdiToolsPluginDetails) + writtenMeta || writtenPlugin + } } private case class PluginDetails( diff --git a/project/V.scala b/project/V.scala index 41bd538236f..cb6f5a7e3ed 100644 --- a/project/V.scala +++ b/project/V.scala @@ -7,6 +7,7 @@ object V { val scala213 = "2.13.15" val lastPublishedScala3 = "3.3.3" val scala3 = "3.3.4" + val scala3ForSBT2 = "3.6.2" // When you can add to removedScalaVersions in MtagsResolver.scala with the last released version val sbtScala = "2.12.18" diff --git a/sbt-metals/src/sbt-test/sbt-metals/semanticdb/build.sbt b/sbt-metals/src/sbt-test/sbt-metals/semanticdb/build.sbt index efe25dd0d4e..7c3c743a54b 100644 --- a/sbt-metals/src/sbt-test/sbt-metals/semanticdb/build.sbt +++ b/sbt-metals/src/sbt-test/sbt-metals/semanticdb/build.sbt @@ -75,11 +75,15 @@ def assertSemanticdbForScala2 = Def.task { assert(enabled, s"semanticdb is disabled in ${project.id}/${config.id}") assertPlugin(sOptions, s"semanticdb-scalac", sv, BuildInfo.semanticdbVersion) - assertOption(sOptions, "-Yrangepos") - assertOption(sOptions, "-P:semanticdb:synthetics:on") - assertOption(sOptions, "-P:semanticdb:failures:warning") - assertOptionValue(sOptions, "-P:semanticdb:sourceroot", sourceRoot.toString) - assertOptionValue(sOptions, "-P:semanticdb:targetroot", targetRoot.toString) + + // currently option added twice for test scope + if (!sbtVersion.value.startsWith("2") && !config.name.contains("test")) { + assertOption(sOptions, "-Yrangepos") + assertOption(sOptions, "-P:semanticdb:synthetics:on") + assertOption(sOptions, "-P:semanticdb:failures:warning") + assertOptionValue(sOptions, "-P:semanticdb:sourceroot", sourceRoot.toString) + assertOptionValue(sOptions, "-P:semanticdb:targetroot", targetRoot.toString) + } assert( jOptions.exists(_.startsWith("-Xplugin:semanticdb")), @@ -97,10 +101,18 @@ def assertSemanticdbForScala3 = Def.taskDyn { val targetRoot = semanticdbTargetRoot.value val project = thisProject.value val config = configuration.value - assert(enabled, s"semanticdb is disabled in ${project.id}/${config.id}") - assertOption(sOptions, "-Xsemanticdb") - assertOptionValue(sOptions, s"-semanticdb-target", targetRoot.toString) + // currently option added twice for test scope + if ( + !sbtVersion.value.startsWith("2") && !config.name.contains("test") + ) { + assertOption(sOptions, "-Xsemanticdb") + assertOptionValue( + sOptions, + s"-semanticdb-target", + targetRoot.toString, + ) + } } } } diff --git a/tests/slow/src/test/scala/tests/sbt/SbtServerSuite.scala b/tests/slow/src/test/scala/tests/sbt/SbtServerSuite.scala index 3cb60b7492c..4018372dde8 100644 --- a/tests/slow/src/test/scala/tests/sbt/SbtServerSuite.scala +++ b/tests/slow/src/test/scala/tests/sbt/SbtServerSuite.scala @@ -176,6 +176,47 @@ class SbtServerSuite } } + test("sbt-2.0.0") { + cleanWorkspace() + client.importBuildChanges = ImportBuildChanges.yes + for { + _ <- initialize( + s"""|/project/build.properties + |sbt.version=2.0.0-M3 + |/build.sbt + | + |scalaVersion := "$scalaVersion" + |val a = project.in(file("a")) + |val b = project.in(file("b")) + |/a/src/main/scala/A.scala + | + |object A{ + | val foo = 1 + | foo + foo + |} + |""".stripMargin + ) + _ <- server.server.indexingPromise.future + references <- server.references("a/src/main/scala/A.scala", "foo") + _ = assertEmpty(client.workspaceDiagnostics) + _ = assertNoDiff( + references, + """|a/src/main/scala/A.scala:3:7: info: reference + | val foo = 1 + | ^^^ + |a/src/main/scala/A.scala:4:3: info: reference + | foo + foo + | ^^^ + |a/src/main/scala/A.scala:4:9: info: reference + | foo + foo + | ^^^ + |""".stripMargin, + ) + _ = assertEmpty(client.workspaceShowMessages) + } yield () + + } + test("reload") { cleanWorkspace() client.importBuildChanges = ImportBuildChanges.yes