From eb25d0aa639ffcd9b640e0e0f819c3f7b1514d62 Mon Sep 17 00:00:00 2001 From: Anatolii Kmetiuk Date: Thu, 9 Apr 2026 12:09:05 +0900 Subject: [PATCH 01/17] Port sbt-osgi to sbt 2 cross-build --- .github/workflows/ci.yml | 12 +- build.sbt | 18 ++- .../com/github/sbt/osgi/PluginCompat.scala | 9 ++ .../com/github/sbt/osgi/PluginCompat.scala | 13 +++ src/main/scala/com/github/sbt/osgi/Osgi.scala | 11 +- .../scala/com/github/sbt/osgi/OsgiKeys.scala | 8 +- .../scala/com/github/sbt/osgi/SbtOsgi.scala | 105 +++++++++++------- .../sbt-osgi/test-00-defaults/build.sbt | 5 + src/sbt-test/sbt-osgi/test-00-defaults/test | 2 +- .../sbt-osgi/test-01-contents/build.sbt | 2 +- .../test-02-includeresource/build.sbt | 2 +- .../test-03-arbitraryHeaders/build.sbt | 2 +- .../sbt-osgi/test-04-embeddedJars/build.sbt | 13 ++- .../sbt-osgi/test-06-explodedJars/build.sbt | 10 +- .../build.sbt | 2 +- .../test-08-packageWithJVMJar/build.sbt | 5 + .../sbt-osgi/test-08-packageWithJVMJar/test | 2 +- .../build.sbt | 4 +- .../build.sbt | 10 +- .../scala/com/github/sbt/osgi/OsgiSpec.scala | 7 +- 20 files changed, 166 insertions(+), 76 deletions(-) create mode 100644 src/main/scala-2.12/com/github/sbt/osgi/PluginCompat.scala create mode 100644 src/main/scala-3/com/github/sbt/osgi/PluginCompat.scala diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6de2baf..df17975 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -23,7 +23,7 @@ jobs: strategy: matrix: os: [ubuntu-latest, macos-latest, windows-latest] - scala: [2.12.21] + scala: [2.12.21, 3.8.2] java: [temurin@8, temurin@11, temurin@17, temurin@21] exclude: - java: temurin@8 @@ -173,6 +173,16 @@ jobs: tar xf targets.tar rm targets.tar + - name: Download target directories (3.8.2) + uses: actions/download-artifact@v6 + with: + name: target-${{ matrix.os }}-3.8.2-${{ matrix.java }} + + - name: Inflate target directories (3.8.2) + run: | + tar xf targets.tar + rm targets.tar + - name: Publish project env: PGP_PASSPHRASE: ${{ secrets.PGP_PASSPHRASE }} diff --git a/build.sbt b/build.sbt index 0ecbc52..6dffbec 100644 --- a/build.sbt +++ b/build.sbt @@ -1,5 +1,6 @@ lazy val scala212 = "2.12.21" -ThisBuild / crossScalaVersions := Seq(scala212) +lazy val scala3 = "3.8.2" +ThisBuild / crossScalaVersions := Seq(scala212, scala3) ThisBuild / scalaVersion := scala212 // So that publishLocal doesn't continuously create new versions @@ -52,17 +53,26 @@ ThisBuild / githubWorkflowBuildMatrixExclusions += MatrixExclude(Map("java" -> " name := "sbt-osgi" enablePlugins(SbtPlugin) +addSbtPlugin("com.github.sbt" % "sbt2-compat" % "0.1.0") +pluginCrossBuild / sbtVersion := { + scalaBinaryVersion.value match { + case "2.12" => "1.12.9" + case _ => "2.0.0-RC11" + } +} libraryDependencies ++= Dependencies.sbtOsgi scalacOptions ++= Seq( "-unchecked", "-deprecation", - "-Xlint", "-encoding", "UTF-8" -) +) ++ (CrossVersion.partialVersion(scalaVersion.value) match { + case Some((2, 12)) => Seq("-Xlint") + case _ => Nil +}) scalacOptions ++= { - if (insideCI.value) { + if (insideCI.value && scalaBinaryVersion.value == "2.12") { val log = sLog.value log.info("Running in CI, enabling Scala2 optimizer") Seq( diff --git a/src/main/scala-2.12/com/github/sbt/osgi/PluginCompat.scala b/src/main/scala-2.12/com/github/sbt/osgi/PluginCompat.scala new file mode 100644 index 0000000..b048dff --- /dev/null +++ b/src/main/scala-2.12/com/github/sbt/osgi/PluginCompat.scala @@ -0,0 +1,9 @@ +package com.github.sbt.osgi + +import java.net.URL + +private[osgi] object PluginCompat { + def licenses(v: Seq[(String, URL)]): Seq[(String, URL)] = v + def apiUrl(v: Option[URL]): Option[URL] = v + type ManifestAttributes = sbt.Package.ManifestAttributes +} diff --git a/src/main/scala-3/com/github/sbt/osgi/PluginCompat.scala b/src/main/scala-3/com/github/sbt/osgi/PluginCompat.scala new file mode 100644 index 0000000..8ef38a7 --- /dev/null +++ b/src/main/scala-3/com/github/sbt/osgi/PluginCompat.scala @@ -0,0 +1,13 @@ +package com.github.sbt.osgi + +import java.net.{ URI, URL } + +import sbt.librarymanagement.License + +private[osgi] object PluginCompat { + def licenses(v: Seq[License]): Seq[(String, URL)] = + v.map(l => l.spdxId -> new URL(l.uri.toString)) + def apiUrl(v: Option[URI]): Option[URL] = + v.map(u => new URL(u.toString)) + type ManifestAttributes = sbt.PackageOption.ManifestAttributes +} diff --git a/src/main/scala/com/github/sbt/osgi/Osgi.scala b/src/main/scala/com/github/sbt/osgi/Osgi.scala index 7072d43..1bd0901 100644 --- a/src/main/scala/com/github/sbt/osgi/Osgi.scala +++ b/src/main/scala/com/github/sbt/osgi/Osgi.scala @@ -27,7 +27,8 @@ import java.util.stream.Collectors import sbt._ import sbt.Keys._ -import sbt.Package.ManifestAttributes + +import PluginCompat.ManifestAttributes import scala.collection.JavaConverters._ import scala.language.implicitConversions @@ -207,9 +208,9 @@ private object Osgi { private def addPackageOptions(props: Properties, packageOptions: Seq[PackageOption]) = { packageOptions - .collect({ case attr: ManifestAttributes ⇒ attr.attributes }) + .collect({ case attr: ManifestAttributes => attr.attributes }) .flatten - .foreach { case (name, value) ⇒ props.put(name.toString, value) } + .foreach { case (name, value) => props.put(name.toString, value) } props } @@ -307,7 +308,7 @@ private object Osgi { def seqToStrOpt[A](seq: Seq[A])(f: A => String): Option[String] = if (seq.isEmpty) None else Some(seq map f mkString ",") - def strToStrOpt(s: String): Option[String] = Option(s).filter(_.trim nonEmpty) + def strToStrOpt(s: String): Option[String] = Option(s).filter(_.trim.nonEmpty) def includeResourceProperty(resourceDirectories: Seq[File], embeddedJars: Seq[File], explodedJars: Seq[File]) = { val paths: Seq[String] = @@ -330,7 +331,7 @@ private object Osgi { def id(s: String) = s - def parts(s: String) = s split "[.-]" filterNot (_.isEmpty) + def parts(s: String) = s.split("[.-]").filterNot(_.isEmpty) // ------------ Poor Man's Java 8 make-it-look-nice inter-op ---------------- implicit def asPredicate[T](f: T => Boolean): Predicate[T] = diff --git a/src/main/scala/com/github/sbt/osgi/OsgiKeys.scala b/src/main/scala/com/github/sbt/osgi/OsgiKeys.scala index 60d1e44..a0c9d10 100644 --- a/src/main/scala/com/github/sbt/osgi/OsgiKeys.scala +++ b/src/main/scala/com/github/sbt/osgi/OsgiKeys.scala @@ -17,11 +17,15 @@ package com.github.sbt.osgi import sbt._ +import sbtcompat.PluginCompat.FileRef trait OsgiKeys { - lazy val bundle: TaskKey[File] = - TaskKey[File](prefix("Bundle"), "Create an OSGi bundle.") + lazy val bundle: TaskKey[FileRef] = + TaskKey[FileRef](prefix("Bundle"), "Create an OSGi bundle.") + + lazy val bundleFile: TaskKey[File] = + TaskKey[File](prefix("BundleFile"), "The OSGi bundle as a java.io.File.") lazy val manifestHeaders: TaskKey[OsgiManifestHeaders] = TaskKey[OsgiManifestHeaders](prefix("ManifestHeaders"), "The aggregated manifest headers.") diff --git a/src/main/scala/com/github/sbt/osgi/SbtOsgi.scala b/src/main/scala/com/github/sbt/osgi/SbtOsgi.scala index 24da9de..b9b4caf 100644 --- a/src/main/scala/com/github/sbt/osgi/SbtOsgi.scala +++ b/src/main/scala/com/github/sbt/osgi/SbtOsgi.scala @@ -16,9 +16,13 @@ package com.github.sbt.osgi +import java.io.File + import sbt._ import sbt.Keys._ import sbt.plugins.JvmPlugin +import sbtcompat.PluginCompat._ +import xsbti.FileConverter object SbtOsgi extends AutoPlugin { @@ -36,8 +40,12 @@ object SbtOsgi extends AutoPlugin { val OsgiKeys = com.github.sbt.osgi.OsgiKeys lazy val osgiSettings: Seq[Setting[_]] = Seq( - Compile / packageBin / packagedArtifact := Scoped - .mkTuple2((Compile / packageBin / artifact).value, OsgiKeys.bundle.value), + Compile / packageBin / packagedArtifact := Def.uncached { + Scoped.mkTuple2( + (Compile / packageBin / artifact).value, + OsgiKeys.bundle.value + ) + }, Compile / packageBin / artifact ~= (_.withType("bundle")) ) } @@ -45,40 +53,52 @@ object SbtOsgi extends AutoPlugin { lazy val defaultOsgiSettings: Seq[Setting[_]] = { import OsgiKeys._ Seq( - bundle := Osgi.bundleTask( - manifestHeaders.value, - additionalHeaders.value, - (Compile / dependencyClasspathAsJars).value.map(_.data) ++ (Compile / products).value, - (Compile / packageBin / artifactPath).value, - (Compile / resourceDirectories).value, - embeddedJars.value, - explodedJars.value, - failOnUndecidedPackage.value, - (Compile / sourceDirectories).value, - (Compile / packageBin / packageOptions).value, - packageWithJVMJar.value, - cacheStrategy.value, - streams.value - ), - manifestHeaders := OsgiManifestHeaders( - bundleActivator.value, - description.value, - apiURL.value, - licenses.value, - name.value, - bundleRequiredExecutionEnvironment.value, - organizationName.value, - bundleSymbolicName.value, - bundleVersion.value, - dynamicImportPackage.value, - exportPackage.value, - importPackage.value, - fragmentHost.value, - privatePackage.value, - requireBundle.value, - requireCapability.value - ), - Compile / sbt.Keys.packageBin := bundle.value, + bundle := Def.uncached { + implicit val conv: FileConverter = fileConverter.value + val cpJars = toFiles((Compile / dependencyClasspathAsJars).value) + val prods = (Compile / products).value + val out = Osgi.bundleTask( + manifestHeaders.value, + additionalHeaders.value, + cpJars ++ prods, + artifactPathToFile((Compile / packageBin / artifactPath).value), + (Compile / resourceDirectories).value, + embeddedJars.value, + explodedJars.value, + failOnUndecidedPackage.value, + (Compile / sourceDirectories).value, + (Compile / packageBin / packageOptions).value, + packageWithJVMJar.value, + cacheStrategy.value, + streams.value + ) + toFileRef(out) + }, + bundleFile := Def.uncached { + implicit val conv: FileConverter = fileConverter.value + toFile(bundle.value) + }, + manifestHeaders := Def.uncached { + OsgiManifestHeaders( + bundleActivator.value, + description.value, + PluginCompat.apiUrl(apiURL.value), + PluginCompat.licenses(licenses.value), + name.value, + bundleRequiredExecutionEnvironment.value, + organizationName.value, + bundleSymbolicName.value, + bundleVersion.value, + dynamicImportPackage.value, + exportPackage.value, + importPackage.value, + fragmentHost.value, + privatePackage.value, + requireBundle.value, + requireCapability.value + ) + }, + Compile / sbt.Keys.packageBin := Def.uncached(OsgiKeys.bundle.value), bundleSymbolicName := Osgi.defaultBundleSymbolicName(organization.value, normalizedName.value), privatePackage := bundleSymbolicName(name => List(name + ".*")).value, bundleVersion := version.value @@ -88,7 +108,14 @@ object SbtOsgi extends AutoPlugin { lazy val defaultGlobalSettings: Seq[Setting[_]] = { import OsgiKeys._ Seq( - bundle := file(""), + bundle := Def.uncached { + implicit val conv: FileConverter = (ThisBuild / fileConverter).value + toFileRef(file("")) + }, + bundleFile := Def.uncached { + implicit val conv: FileConverter = (ThisBuild / fileConverter).value + toFile(bundle.value) + }, bundleActivator := None, bundleSymbolicName := "", bundleVersion := "", @@ -102,8 +129,8 @@ object SbtOsgi extends AutoPlugin { failOnUndecidedPackage := false, requireCapability := Osgi.requireCapabilityTask, additionalHeaders := Map.empty, - embeddedJars := Nil, - explodedJars := Nil, + embeddedJars := Def.uncached(Seq.empty[File]), + explodedJars := Def.uncached(Seq.empty[File]), packageWithJVMJar := false, cacheStrategy := None ) diff --git a/src/sbt-test/sbt-osgi/test-00-defaults/build.sbt b/src/sbt-test/sbt-osgi/test-00-defaults/build.sbt index f39bb2c..f7a259b 100644 --- a/src/sbt-test/sbt-osgi/test-00-defaults/build.sbt +++ b/src/sbt-test/sbt-osgi/test-00-defaults/build.sbt @@ -69,3 +69,8 @@ TaskKey[Unit]("verifyRequireBundle") := { if (!bundle.isEmpty) sys.error("Expected require-bundle to be empty, but was %s!" format bundle) } + +TaskKey[Unit]("verifyOsgiBundleJar") := { + val jar = OsgiKeys.bundleFile.value + if (!jar.exists()) sys.error(s"Expected OSGi bundle jar on disk: $jar") +} diff --git a/src/sbt-test/sbt-osgi/test-00-defaults/test b/src/sbt-test/sbt-osgi/test-00-defaults/test index c63cd37..1735b2e 100644 --- a/src/sbt-test/sbt-osgi/test-00-defaults/test +++ b/src/sbt-test/sbt-osgi/test-00-defaults/test @@ -12,4 +12,4 @@ # Existence of JAR file > osgiBundle -$ exists target/scala-2.12/sbt-osgi-test_2.12-1.2.3.jar +> verifyOsgiBundleJar diff --git a/src/sbt-test/sbt-osgi/test-01-contents/build.sbt b/src/sbt-test/sbt-osgi/test-01-contents/build.sbt index e776b9d..359ead5 100644 --- a/src/sbt-test/sbt-osgi/test-01-contents/build.sbt +++ b/src/sbt-test/sbt-osgi/test-01-contents/build.sbt @@ -26,7 +26,7 @@ TaskKey[Unit]("verifyBundle") := { import java.io.IOException import java.util.zip.ZipFile import scala.io.Source - val file = OsgiKeys.bundle.value + val file = OsgiKeys.bundleFile.value val newLine = System.getProperty("line.separator") val zipFile = new ZipFile(file) // Verify manifest diff --git a/src/sbt-test/sbt-osgi/test-02-includeresource/build.sbt b/src/sbt-test/sbt-osgi/test-02-includeresource/build.sbt index 34c1c64..d2a58ac 100644 --- a/src/sbt-test/sbt-osgi/test-02-includeresource/build.sbt +++ b/src/sbt-test/sbt-osgi/test-02-includeresource/build.sbt @@ -21,7 +21,7 @@ TaskKey[Unit]("verifyBundle") := { import java.util.jar.JarFile import scala.io.Source val newLine = System.getProperty("line.separator") - val jarFile = new JarFile(OsgiKeys.bundle.value) + val jarFile = new JarFile(OsgiKeys.bundleFile.value) // Verify manifest try { val manifest = jarFile.getManifest diff --git a/src/sbt-test/sbt-osgi/test-03-arbitraryHeaders/build.sbt b/src/sbt-test/sbt-osgi/test-03-arbitraryHeaders/build.sbt index db4c576..93b0f6e 100644 --- a/src/sbt-test/sbt-osgi/test-03-arbitraryHeaders/build.sbt +++ b/src/sbt-test/sbt-osgi/test-03-arbitraryHeaders/build.sbt @@ -16,7 +16,7 @@ TaskKey[Unit]("verifyBundle") := { import java.io.IOException import java.util.zip.ZipFile import scala.io.Source - val file = OsgiKeys.bundle.value + val file = OsgiKeys.bundleFile.value val newLine = System.getProperty("line.separator") val zipFile = new ZipFile(file) // Verify manifest diff --git a/src/sbt-test/sbt-osgi/test-04-embeddedJars/build.sbt b/src/sbt-test/sbt-osgi/test-04-embeddedJars/build.sbt index 0cf2f4f..d932408 100644 --- a/src/sbt-test/sbt-osgi/test-04-embeddedJars/build.sbt +++ b/src/sbt-test/sbt-osgi/test-04-embeddedJars/build.sbt @@ -1,4 +1,11 @@ -lazy val test04 = (project in file("")).enablePlugins(SbtOsgi) +import sbtcompat.PluginCompat._ + +lazy val test04 = (project in file("")).enablePlugins(SbtOsgi).settings( + OsgiKeys.embeddedJars := Def.uncached { + implicit val conv: xsbti.FileConverter = fileConverter.value + toFiles((Compile / externalDependencyClasspath).value).filter(_.getName.startsWith("junit")) + } +) organization := "com.github.sbt" @@ -8,15 +15,13 @@ version := "1.2.3" osgiSettings -OsgiKeys.embeddedJars := (Keys.externalDependencyClasspath in Compile).value map (_.data) filter (_.getName startsWith "junit") - libraryDependencies += "junit" % "junit" % "4.11" // Not in test scope here! TaskKey[Unit]("verifyBundle") := { import java.io.IOException import java.util.zip.ZipFile import scala.io.Source - val file = OsgiKeys.bundle.value + val file = OsgiKeys.bundleFile.value val newLine = System.getProperty("line.separator") val zipFile = new ZipFile(file) // Verify bundle content diff --git a/src/sbt-test/sbt-osgi/test-06-explodedJars/build.sbt b/src/sbt-test/sbt-osgi/test-06-explodedJars/build.sbt index 853c188..7af19ae 100644 --- a/src/sbt-test/sbt-osgi/test-06-explodedJars/build.sbt +++ b/src/sbt-test/sbt-osgi/test-06-explodedJars/build.sbt @@ -1,4 +1,6 @@ -lazy val test06 = (project in file("")).enablePlugins(SbtOsgi) +import sbtcompat.PluginCompat._ + +lazy val test06 = (project in file("")).enablePlugins(SbtOsgi).settings(OsgiKeys.explodedJars := Def.uncached(Seq(file("tiny.jar")))) organization := "com.github.sbt" @@ -8,16 +10,14 @@ version := "1.2.3" osgiSettings -OsgiKeys.explodedJars += file("tiny.jar") - TaskKey[Unit]("verifyBundle") := { import scala.collection.JavaConverters._ import java.util.jar.JarFile - val file = OsgiKeys.bundle.value + val file = OsgiKeys.bundleFile.value val (tiny, bundle) = (new JarFile("tiny.jar"), new JarFile(file)) // Everything in tiny other than its manifest should exist in bundle val entries = tiny.entries.asScala.toList.map(e => (e, Option(bundle.getEntry(e.getName)))) - entries.filterNot(_._1.getName.startsWith("META-INF/")).foreach { + entries.filterNot(e => e._1.getName.startsWith("META-INF/")).foreach { case (te, None) => sys.error("Expected entry " + te + " not found.") case (te, Some(be)) => if (te.getSize != be.getSize) sys.error("Unequal sizes for " + te) } diff --git a/src/sbt-test/sbt-osgi/test-07-failOnClassesExcludedFromJar/build.sbt b/src/sbt-test/sbt-osgi/test-07-failOnClassesExcludedFromJar/build.sbt index f6ba4f0..833938d 100644 --- a/src/sbt-test/sbt-osgi/test-07-failOnClassesExcludedFromJar/build.sbt +++ b/src/sbt-test/sbt-osgi/test-07-failOnClassesExcludedFromJar/build.sbt @@ -34,7 +34,7 @@ TaskKey[Unit]("verifyBundle") := { import java.io.IOException import java.util.zip.ZipFile import scala.io.Source - val file = OsgiKeys.bundle.value + val file = OsgiKeys.bundleFile.value val newLine = System.getProperty("line.separator") val zipFile = new ZipFile(file) // Verify manifest diff --git a/src/sbt-test/sbt-osgi/test-08-packageWithJVMJar/build.sbt b/src/sbt-test/sbt-osgi/test-08-packageWithJVMJar/build.sbt index 66f3453..335a3ed 100644 --- a/src/sbt-test/sbt-osgi/test-08-packageWithJVMJar/build.sbt +++ b/src/sbt-test/sbt-osgi/test-08-packageWithJVMJar/build.sbt @@ -71,3 +71,8 @@ TaskKey[Unit]("verifyRequireBundle") := { if (!bundle.isEmpty) sys.error("Expected require-bundle to be empty, but was %s!" format bundle) } + +TaskKey[Unit]("verifyOsgiBundleJar") := { + val jar = OsgiKeys.bundleFile.value + if (!jar.exists()) sys.error(s"Expected OSGi bundle jar on disk: $jar") +} diff --git a/src/sbt-test/sbt-osgi/test-08-packageWithJVMJar/test b/src/sbt-test/sbt-osgi/test-08-packageWithJVMJar/test index c63cd37..1735b2e 100644 --- a/src/sbt-test/sbt-osgi/test-08-packageWithJVMJar/test +++ b/src/sbt-test/sbt-osgi/test-08-packageWithJVMJar/test @@ -12,4 +12,4 @@ # Existence of JAR file > osgiBundle -$ exists target/scala-2.12/sbt-osgi-test_2.12-1.2.3.jar +> verifyOsgiBundleJar diff --git a/src/sbt-test/sbt-osgi/test-09-automatic-module-name-in-opts/build.sbt b/src/sbt-test/sbt-osgi/test-09-automatic-module-name-in-opts/build.sbt index 8f93ae6..e746675 100644 --- a/src/sbt-test/sbt-osgi/test-09-automatic-module-name-in-opts/build.sbt +++ b/src/sbt-test/sbt-osgi/test-09-automatic-module-name-in-opts/build.sbt @@ -20,7 +20,7 @@ OsgiKeys.bundleRequiredExecutionEnvironment := Seq("JavaSE-1.7", "JavaSE-1.8") val myModuleName = "my.nice.module.name" val AutomaticModuleName = "Automatic-Module-Name" -packageOptions in (Compile, packageBin) += Package.ManifestAttributes(AutomaticModuleName → myModuleName) +Compile / packageBin / packageOptions += Package.ManifestAttributes(AutomaticModuleName -> myModuleName) apiURL := Some(url("https://github.com/sbt/sbt-osgi")) @@ -30,7 +30,7 @@ TaskKey[Unit]("verifyBundle") := { import java.io.IOException import java.util.zip.ZipFile import scala.io.Source - val file = OsgiKeys.bundle.value + val file = OsgiKeys.bundleFile.value val newLine = System.getProperty("line.separator") val zipFile = new ZipFile(file) // Verify manifest diff --git a/src/sbt-test/sbt-osgi/test-10-multi-project-dependsOn-includePackage-versions/build.sbt b/src/sbt-test/sbt-osgi/test-10-multi-project-dependsOn-includePackage-versions/build.sbt index b9ad0c3..f00d755 100644 --- a/src/sbt-test/sbt-osgi/test-10-multi-project-dependsOn-includePackage-versions/build.sbt +++ b/src/sbt-test/sbt-osgi/test-10-multi-project-dependsOn-includePackage-versions/build.sbt @@ -44,7 +44,7 @@ TaskKey[Unit]("verifyBundle") := { val newLine = System.getProperty("line.separator") { - val file = OsgiKeys.bundle.in(proj1).value + val file = (proj1 / OsgiKeys.bundleFile).value val zipFile = new ZipFile(file) // Verify manifest @@ -55,10 +55,10 @@ TaskKey[Unit]("verifyBundle") := { val allLines = lines.mkString(newLine) val butWas = newLine + "But was:" + newLine + allLines - val export = Seq("Export-Package: ", "proj1;", s"""version="${version.value}"""") + val expectedExportFragments = Seq("Export-Package: ", "proj1;", s"""version="${version.value}"""") - if (!(lines.exists(l => export.forall(s => l.containsSlice(s))))) { - sys.error(s"""Expected ${export.mkString("'", "' and '", "'")} in manifest!""" + butWas) + if (!(lines.exists(l => expectedExportFragments.forall(s => l.containsSlice(s))))) { + sys.error(s"""Expected ${expectedExportFragments.mkString("'", "' and '", "'")} in manifest!""" + butWas) } } catch { case e: IOException => sys.error("Expected to be able to read the manifest, but got exception!" + newLine + e) @@ -66,7 +66,7 @@ TaskKey[Unit]("verifyBundle") := { } { - val file = OsgiKeys.bundle.in(proj2).value + val file = (proj2 / OsgiKeys.bundleFile).value val zipFile = new ZipFile(file) // Verify manifest diff --git a/src/test/scala/com/github/sbt/osgi/OsgiSpec.scala b/src/test/scala/com/github/sbt/osgi/OsgiSpec.scala index 571996d..f81fc6e 100644 --- a/src/test/scala/com/github/sbt/osgi/OsgiSpec.scala +++ b/src/test/scala/com/github/sbt/osgi/OsgiSpec.scala @@ -19,6 +19,7 @@ package com.github.sbt.osgi import aQute.bnd.osgi.Constants._ import java.io.File import org.specs2.mutable.Specification +import java.net.URL import scala.collection.JavaConverters._ class OsgiSpec extends Specification { @@ -40,8 +41,8 @@ class OsgiSpec extends Specification { val headers = OsgiManifestHeaders( Some("bundleActivator"), "bundleDescription", - Some(sbt.url("http://example.example")), - Seq(("License", sbt.url("http://license.license"))), + Some(new URL("http://example.example")), + Seq(("License", new URL("http://license.license"))), "bundleName", Seq("req1", "req2"), "bundleVendor", @@ -60,7 +61,7 @@ class OsgiSpec extends Specification { BUNDLE_ACTIVATOR -> "bundleActivator", BUNDLE_SYMBOLICNAME -> "bundleSymbolicName", BUNDLE_DESCRIPTION -> "bundleDescription", - BUNDLE_DOCURL -> sbt.url("http://example.example").toString, + BUNDLE_DOCURL -> new URL("http://example.example").toString, BUNDLE_LICENSE -> "http://license.license;description=License", BUNDLE_NAME -> "bundleName", BUNDLE_REQUIREDEXECUTIONENVIRONMENT -> "req1,req2", From bcdf86217f80806e48d6faa311ad457aedf87157 Mon Sep 17 00:00:00 2001 From: Anatolii Kmetiuk Date: Thu, 9 Apr 2026 12:12:42 +0900 Subject: [PATCH 02/17] style: apply scalafmt --- build.sbt | 2 +- .../sbt-osgi/test-04-embeddedJars/build.sbt | 14 ++++++++------ .../sbt-osgi/test-06-explodedJars/build.sbt | 3 ++- 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/build.sbt b/build.sbt index 6dffbec..fdc1e68 100644 --- a/build.sbt +++ b/build.sbt @@ -68,7 +68,7 @@ scalacOptions ++= Seq( "UTF-8" ) ++ (CrossVersion.partialVersion(scalaVersion.value) match { case Some((2, 12)) => Seq("-Xlint") - case _ => Nil + case _ => Nil }) scalacOptions ++= { diff --git a/src/sbt-test/sbt-osgi/test-04-embeddedJars/build.sbt b/src/sbt-test/sbt-osgi/test-04-embeddedJars/build.sbt index d932408..81bd763 100644 --- a/src/sbt-test/sbt-osgi/test-04-embeddedJars/build.sbt +++ b/src/sbt-test/sbt-osgi/test-04-embeddedJars/build.sbt @@ -1,11 +1,13 @@ import sbtcompat.PluginCompat._ -lazy val test04 = (project in file("")).enablePlugins(SbtOsgi).settings( - OsgiKeys.embeddedJars := Def.uncached { - implicit val conv: xsbti.FileConverter = fileConverter.value - toFiles((Compile / externalDependencyClasspath).value).filter(_.getName.startsWith("junit")) - } -) +lazy val test04 = (project in file("")) + .enablePlugins(SbtOsgi) + .settings( + OsgiKeys.embeddedJars := Def.uncached { + implicit val conv: xsbti.FileConverter = fileConverter.value + toFiles((Compile / externalDependencyClasspath).value).filter(_.getName.startsWith("junit")) + } + ) organization := "com.github.sbt" diff --git a/src/sbt-test/sbt-osgi/test-06-explodedJars/build.sbt b/src/sbt-test/sbt-osgi/test-06-explodedJars/build.sbt index 7af19ae..2b8e6ea 100644 --- a/src/sbt-test/sbt-osgi/test-06-explodedJars/build.sbt +++ b/src/sbt-test/sbt-osgi/test-06-explodedJars/build.sbt @@ -1,6 +1,7 @@ import sbtcompat.PluginCompat._ -lazy val test06 = (project in file("")).enablePlugins(SbtOsgi).settings(OsgiKeys.explodedJars := Def.uncached(Seq(file("tiny.jar")))) +lazy val test06 = + (project in file("")).enablePlugins(SbtOsgi).settings(OsgiKeys.explodedJars := Def.uncached(Seq(file("tiny.jar")))) organization := "com.github.sbt" From 812a1a0f6c995820d47a0633c6805af969e7a3fe Mon Sep 17 00:00:00 2001 From: Anatolii Kmetiuk Date: Thu, 9 Apr 2026 12:18:15 +0900 Subject: [PATCH 03/17] ci: exclude JDK 8/11 for Scala 3.8.2; use JDK 17 for publish Scala 3.8+ requires JDK 17+ for the compiler bridge. Drop invalid matrix pairs and put temurin@17 first so the publish job downloads artifacts that the build job actually produces. --- .github/workflows/ci.yml | 56 +++++++++++++++++++++------------------- build.sbt | 8 +++--- 2 files changed, 35 insertions(+), 29 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index df17975..88ae504 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -24,10 +24,14 @@ jobs: matrix: os: [ubuntu-latest, macos-latest, windows-latest] scala: [2.12.21, 3.8.2] - java: [temurin@8, temurin@11, temurin@17, temurin@21] + java: [temurin@17, temurin@21, temurin@8, temurin@11] exclude: - java: temurin@8 os: macos-latest + - java: temurin@8 + scala: 3.8.2 + - java: temurin@11 + scala: 3.8.2 runs-on: ${{ matrix.os }} steps: - name: Ignore line ending differences in git @@ -48,36 +52,36 @@ jobs: with: fetch-depth: 0 - - name: Setup Java (temurin@8) - if: matrix.java == 'temurin@8' + - name: Setup Java (temurin@17) + if: matrix.java == 'temurin@17' uses: actions/setup-java@v5 with: distribution: temurin - java-version: 8 + java-version: 17 cache: sbt - - name: Setup Java (temurin@11) - if: matrix.java == 'temurin@11' + - name: Setup Java (temurin@21) + if: matrix.java == 'temurin@21' uses: actions/setup-java@v5 with: distribution: temurin - java-version: 11 + java-version: 21 cache: sbt - - name: Setup Java (temurin@17) - if: matrix.java == 'temurin@17' + - name: Setup Java (temurin@8) + if: matrix.java == 'temurin@8' uses: actions/setup-java@v5 with: distribution: temurin - java-version: 17 + java-version: 8 cache: sbt - - name: Setup Java (temurin@21) - if: matrix.java == 'temurin@21' + - name: Setup Java (temurin@11) + if: matrix.java == 'temurin@11' uses: actions/setup-java@v5 with: distribution: temurin - java-version: 21 + java-version: 11 cache: sbt - name: Setup sbt @@ -108,7 +112,7 @@ jobs: matrix: os: [ubuntu-latest] scala: [2.12.21] - java: [temurin@8] + java: [temurin@17] runs-on: ${{ matrix.os }} steps: - name: Ignore line ending differences in git @@ -128,36 +132,36 @@ jobs: with: fetch-depth: 0 - - name: Setup Java (temurin@8) - if: matrix.java == 'temurin@8' + - name: Setup Java (temurin@17) + if: matrix.java == 'temurin@17' uses: actions/setup-java@v5 with: distribution: temurin - java-version: 8 + java-version: 17 cache: sbt - - name: Setup Java (temurin@11) - if: matrix.java == 'temurin@11' + - name: Setup Java (temurin@21) + if: matrix.java == 'temurin@21' uses: actions/setup-java@v5 with: distribution: temurin - java-version: 11 + java-version: 21 cache: sbt - - name: Setup Java (temurin@17) - if: matrix.java == 'temurin@17' + - name: Setup Java (temurin@8) + if: matrix.java == 'temurin@8' uses: actions/setup-java@v5 with: distribution: temurin - java-version: 17 + java-version: 8 cache: sbt - - name: Setup Java (temurin@21) - if: matrix.java == 'temurin@21' + - name: Setup Java (temurin@11) + if: matrix.java == 'temurin@11' uses: actions/setup-java@v5 with: distribution: temurin - java-version: 21 + java-version: 11 cache: sbt - name: Setup sbt diff --git a/build.sbt b/build.sbt index fdc1e68..2bde9e1 100644 --- a/build.sbt +++ b/build.sbt @@ -43,13 +43,15 @@ ThisBuild / githubWorkflowPublish := Seq( ThisBuild / githubWorkflowOSes := Seq("ubuntu-latest", "macos-latest", "windows-latest") ThisBuild / githubWorkflowJavaVersions := Seq( - JavaSpec.temurin("8"), - JavaSpec.temurin("11"), JavaSpec.temurin("17"), - JavaSpec.temurin("21") + JavaSpec.temurin("21"), + JavaSpec.temurin("8"), + JavaSpec.temurin("11") ) ThisBuild / githubWorkflowBuildMatrixExclusions += MatrixExclude(Map("java" -> "temurin@8", "os" -> "macos-latest")) +ThisBuild / githubWorkflowBuildMatrixExclusions += MatrixExclude(Map("java" -> "temurin@8", "scala" -> scala3)) +ThisBuild / githubWorkflowBuildMatrixExclusions += MatrixExclude(Map("java" -> "temurin@11", "scala" -> scala3)) name := "sbt-osgi" enablePlugins(SbtPlugin) From ca82c6e622e25ca0cdc7005cbde9e2328a57bfb1 Mon Sep 17 00:00:00 2001 From: Matthias Kurz Date: Thu, 9 Apr 2026 07:29:53 +0200 Subject: [PATCH 04/17] URL to URI Co-authored-by: kenji yoshida <6b656e6a69@gmail.com> --- src/main/scala-3/com/github/sbt/osgi/PluginCompat.scala | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/scala-3/com/github/sbt/osgi/PluginCompat.scala b/src/main/scala-3/com/github/sbt/osgi/PluginCompat.scala index 8ef38a7..f118dcb 100644 --- a/src/main/scala-3/com/github/sbt/osgi/PluginCompat.scala +++ b/src/main/scala-3/com/github/sbt/osgi/PluginCompat.scala @@ -8,6 +8,8 @@ private[osgi] object PluginCompat { def licenses(v: Seq[License]): Seq[(String, URL)] = v.map(l => l.spdxId -> new URL(l.uri.toString)) def apiUrl(v: Option[URI]): Option[URL] = - v.map(u => new URL(u.toString)) + v.map(l => l.spdxId -> new URI(l.uri.toString).toURL) + def apiUrl(v: Option[URI]): Option[URL] = + v.map(u => new URI(u.toString).toURL) type ManifestAttributes = sbt.PackageOption.ManifestAttributes } From 69abb9f2d765f50e41a45597d4870fe44acf862c Mon Sep 17 00:00:00 2001 From: Matthias Kurz Date: Thu, 9 Apr 2026 07:30:08 +0200 Subject: [PATCH 05/17] URL to URI Co-authored-by: kenji yoshida <6b656e6a69@gmail.com> --- src/test/scala/com/github/sbt/osgi/OsgiSpec.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/scala/com/github/sbt/osgi/OsgiSpec.scala b/src/test/scala/com/github/sbt/osgi/OsgiSpec.scala index f81fc6e..64b7a76 100644 --- a/src/test/scala/com/github/sbt/osgi/OsgiSpec.scala +++ b/src/test/scala/com/github/sbt/osgi/OsgiSpec.scala @@ -41,8 +41,8 @@ class OsgiSpec extends Specification { val headers = OsgiManifestHeaders( Some("bundleActivator"), "bundleDescription", - Some(new URL("http://example.example")), - Seq(("License", new URL("http://license.license"))), + Some(new URI("http://example.example").toURL), + Seq(("License", new URI("http://license.license").toURL)), "bundleName", Seq("req1", "req2"), "bundleVendor", From 95fd2b3adfc174aee79d2ae0a1e26894561a9ff8 Mon Sep 17 00:00:00 2001 From: Matthias Kurz Date: Thu, 9 Apr 2026 07:30:20 +0200 Subject: [PATCH 06/17] URL to URI Co-authored-by: kenji yoshida <6b656e6a69@gmail.com> --- src/test/scala/com/github/sbt/osgi/OsgiSpec.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/scala/com/github/sbt/osgi/OsgiSpec.scala b/src/test/scala/com/github/sbt/osgi/OsgiSpec.scala index 64b7a76..d705fba 100644 --- a/src/test/scala/com/github/sbt/osgi/OsgiSpec.scala +++ b/src/test/scala/com/github/sbt/osgi/OsgiSpec.scala @@ -61,7 +61,7 @@ class OsgiSpec extends Specification { BUNDLE_ACTIVATOR -> "bundleActivator", BUNDLE_SYMBOLICNAME -> "bundleSymbolicName", BUNDLE_DESCRIPTION -> "bundleDescription", - BUNDLE_DOCURL -> new URL("http://example.example").toString, + BUNDLE_DOCURL -> new URI("http://example.example").toURL.toString, BUNDLE_LICENSE -> "http://license.license;description=License", BUNDLE_NAME -> "bundleName", BUNDLE_REQUIREDEXECUTIONENVIRONMENT -> "req1,req2", From a2531c69af13480e6d3f0a639298a6cb716422c9 Mon Sep 17 00:00:00 2001 From: Anatolii Kmetiuk Date: Thu, 9 Apr 2026 17:22:35 +0900 Subject: [PATCH 07/17] Update build.sbt Co-authored-by: Matthias Kurz --- build.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sbt b/build.sbt index 2bde9e1..f43ff93 100644 --- a/build.sbt +++ b/build.sbt @@ -1,5 +1,5 @@ lazy val scala212 = "2.12.21" -lazy val scala3 = "3.8.2" +lazy val scala3 = "3.8.3" ThisBuild / crossScalaVersions := Seq(scala212, scala3) ThisBuild / scalaVersion := scala212 From 20586b1adf2e229b07576eb8e47b07289a9bf0f5 Mon Sep 17 00:00:00 2001 From: Anatolii Kmetiuk Date: Thu, 9 Apr 2026 17:22:41 +0900 Subject: [PATCH 08/17] Update .github/workflows/ci.yml Co-authored-by: Matthias Kurz --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 88ae504..3bd235d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -23,7 +23,7 @@ jobs: strategy: matrix: os: [ubuntu-latest, macos-latest, windows-latest] - scala: [2.12.21, 3.8.2] + scala: [2.12.21, 3.8.3] java: [temurin@17, temurin@21, temurin@8, temurin@11] exclude: - java: temurin@8 From 4855e5753ec60c2582324a0e72e59bf6dfdb2f80 Mon Sep 17 00:00:00 2001 From: Anatolii Kmetiuk Date: Thu, 9 Apr 2026 17:24:03 +0900 Subject: [PATCH 09/17] Fix test import --- src/test/scala/com/github/sbt/osgi/OsgiSpec.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/scala/com/github/sbt/osgi/OsgiSpec.scala b/src/test/scala/com/github/sbt/osgi/OsgiSpec.scala index d705fba..1bb8b70 100644 --- a/src/test/scala/com/github/sbt/osgi/OsgiSpec.scala +++ b/src/test/scala/com/github/sbt/osgi/OsgiSpec.scala @@ -19,7 +19,7 @@ package com.github.sbt.osgi import aQute.bnd.osgi.Constants._ import java.io.File import org.specs2.mutable.Specification -import java.net.URL +import java.net.URI import scala.collection.JavaConverters._ class OsgiSpec extends Specification { From 3145f552ac104c8bbc4c46a5292d3a99dbd036d5 Mon Sep 17 00:00:00 2001 From: Anatolii Kmetiuk Date: Thu, 9 Apr 2026 17:27:14 +0900 Subject: [PATCH 10/17] Regenerate ci.yml for Scala 3.8.3 (githubWorkflowGenerate) --- .github/workflows/ci.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3bd235d..3acbdab 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -29,9 +29,9 @@ jobs: - java: temurin@8 os: macos-latest - java: temurin@8 - scala: 3.8.2 + scala: 3.8.3 - java: temurin@11 - scala: 3.8.2 + scala: 3.8.3 runs-on: ${{ matrix.os }} steps: - name: Ignore line ending differences in git @@ -177,12 +177,12 @@ jobs: tar xf targets.tar rm targets.tar - - name: Download target directories (3.8.2) + - name: Download target directories (3.8.3) uses: actions/download-artifact@v6 with: - name: target-${{ matrix.os }}-3.8.2-${{ matrix.java }} + name: target-${{ matrix.os }}-3.8.3-${{ matrix.java }} - - name: Inflate target directories (3.8.2) + - name: Inflate target directories (3.8.3) run: | tar xf targets.tar rm targets.tar From 76fadab05b9c0f6d712634b0be4c8b1b84e9c376 Mon Sep 17 00:00:00 2001 From: Anatolii Kmetiuk Date: Thu, 9 Apr 2026 17:32:24 +0900 Subject: [PATCH 11/17] Fix plugin compat --- src/main/scala-3/com/github/sbt/osgi/PluginCompat.scala | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/main/scala-3/com/github/sbt/osgi/PluginCompat.scala b/src/main/scala-3/com/github/sbt/osgi/PluginCompat.scala index f118dcb..6ed0785 100644 --- a/src/main/scala-3/com/github/sbt/osgi/PluginCompat.scala +++ b/src/main/scala-3/com/github/sbt/osgi/PluginCompat.scala @@ -7,8 +7,6 @@ import sbt.librarymanagement.License private[osgi] object PluginCompat { def licenses(v: Seq[License]): Seq[(String, URL)] = v.map(l => l.spdxId -> new URL(l.uri.toString)) - def apiUrl(v: Option[URI]): Option[URL] = - v.map(l => l.spdxId -> new URI(l.uri.toString).toURL) def apiUrl(v: Option[URI]): Option[URL] = v.map(u => new URI(u.toString).toURL) type ManifestAttributes = sbt.PackageOption.ManifestAttributes From 5172fa8acdc5246505294690f2a0aa819540a221 Mon Sep 17 00:00:00 2001 From: Matthias Kurz Date: Sat, 16 May 2026 16:20:55 +0200 Subject: [PATCH 12/17] Bump sbt versions --- build.sbt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build.sbt b/build.sbt index f43ff93..8ed47d5 100644 --- a/build.sbt +++ b/build.sbt @@ -58,8 +58,8 @@ enablePlugins(SbtPlugin) addSbtPlugin("com.github.sbt" % "sbt2-compat" % "0.1.0") pluginCrossBuild / sbtVersion := { scalaBinaryVersion.value match { - case "2.12" => "1.12.9" - case _ => "2.0.0-RC11" + case "2.12" => "1.12.11" + case _ => "2.0.0-RC12" } } libraryDependencies ++= Dependencies.sbtOsgi From 17a87fcff43dd2be0e54bbdb21e4b61fc3d60b0c Mon Sep 17 00:00:00 2001 From: Matthias Kurz Date: Sat, 16 May 2026 16:22:36 +0200 Subject: [PATCH 13/17] Fix workflow --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3acbdab..5ec69b9 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -178,7 +178,7 @@ jobs: rm targets.tar - name: Download target directories (3.8.3) - uses: actions/download-artifact@v6 + uses: actions/download-artifact@v8 with: name: target-${{ matrix.os }}-3.8.3-${{ matrix.java }} From 73dbca666e06a7a1ce3beb6f85b688067c81aa86 Mon Sep 17 00:00:00 2001 From: Matthias Kurz Date: Sat, 16 May 2026 23:32:52 +0200 Subject: [PATCH 14/17] Test with java 25 --- .github/workflows/ci.yml | 23 ++++++++++++++++++++++- build.sbt | 1 + 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5ec69b9..2fe20da 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -24,7 +24,12 @@ jobs: matrix: os: [ubuntu-latest, macos-latest, windows-latest] scala: [2.12.21, 3.8.3] - java: [temurin@17, temurin@21, temurin@8, temurin@11] + java: + - temurin@17 + - temurin@25 + - temurin@21 + - temurin@8 + - temurin@11 exclude: - java: temurin@8 os: macos-latest @@ -60,6 +65,14 @@ jobs: java-version: 17 cache: sbt + - name: Setup Java (temurin@25) + if: matrix.java == 'temurin@25' + uses: actions/setup-java@v5 + with: + distribution: temurin + java-version: 25 + cache: sbt + - name: Setup Java (temurin@21) if: matrix.java == 'temurin@21' uses: actions/setup-java@v5 @@ -140,6 +153,14 @@ jobs: java-version: 17 cache: sbt + - name: Setup Java (temurin@25) + if: matrix.java == 'temurin@25' + uses: actions/setup-java@v5 + with: + distribution: temurin + java-version: 25 + cache: sbt + - name: Setup Java (temurin@21) if: matrix.java == 'temurin@21' uses: actions/setup-java@v5 diff --git a/build.sbt b/build.sbt index 8ed47d5..7c12cf2 100644 --- a/build.sbt +++ b/build.sbt @@ -44,6 +44,7 @@ ThisBuild / githubWorkflowOSes := Seq("ubuntu-latest", "macos-latest", "windows- ThisBuild / githubWorkflowJavaVersions := Seq( JavaSpec.temurin("17"), + JavaSpec.temurin("25"), JavaSpec.temurin("21"), JavaSpec.temurin("8"), JavaSpec.temurin("11") From 26141398d291888def6dacc8f3b694749e5fe7af Mon Sep 17 00:00:00 2001 From: Matthias Kurz Date: Sat, 16 May 2026 23:33:04 +0200 Subject: [PATCH 15/17] sbt 1 should build for Java 8 --- build.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sbt b/build.sbt index 7c12cf2..9f79c9c 100644 --- a/build.sbt +++ b/build.sbt @@ -70,7 +70,7 @@ scalacOptions ++= Seq( "-encoding", "UTF-8" ) ++ (CrossVersion.partialVersion(scalaVersion.value) match { - case Some((2, 12)) => Seq("-Xlint") + case Some((2, 12)) => Seq("-Xlint", "-Xsource:3", "-release:8") case _ => Nil }) From 66b5d1a302d8754e9a23d1909d27f371017fbad7 Mon Sep 17 00:00:00 2001 From: Matthias Kurz Date: Sat, 16 May 2026 23:33:53 +0200 Subject: [PATCH 16/17] fix Scala 3 warning --- src/main/scala/com/github/sbt/osgi/Osgi.scala | 8 ++++---- src/main/scala/com/github/sbt/osgi/SbtOsgi.scala | 10 +++++----- src/test/scala/com/github/sbt/osgi/OsgiSpec.scala | 2 +- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/main/scala/com/github/sbt/osgi/Osgi.scala b/src/main/scala/com/github/sbt/osgi/Osgi.scala index 1bd0901..e3cca6b 100644 --- a/src/main/scala/com/github/sbt/osgi/Osgi.scala +++ b/src/main/scala/com/github/sbt/osgi/Osgi.scala @@ -30,7 +30,7 @@ import sbt.Keys._ import PluginCompat.ManifestAttributes -import scala.collection.JavaConverters._ +import scala.jdk.CollectionConverters._ import scala.language.implicitConversions private object Osgi { @@ -187,7 +187,7 @@ private object Osgi { def content = { import _root_.java.nio.file._ - import _root_.scala.collection.JavaConverters._ + import _root_.scala.jdk.CollectionConverters._ val path = tmpArtifactDirectoryPath.toPath Files .walk(path) @@ -195,7 +195,7 @@ private object Osgi { .asScala .map(f => f.toFile -> path.relativize(f)) .collect { case (f, p) if p != (file("META-INF") / "MANIFEST.MF").toPath => (f, p.toString) } - .toTraversable + .toList } IO.jar(content, tmpArtifactPath, manifest) @@ -235,7 +235,7 @@ private object Osgi { }) .collect(Collectors.toSet()) - import scala.collection.JavaConverters._ + import scala.jdk.CollectionConverters._ packages.asScala } }.toSet diff --git a/src/main/scala/com/github/sbt/osgi/SbtOsgi.scala b/src/main/scala/com/github/sbt/osgi/SbtOsgi.scala index b9b4caf..e9ef4f4 100644 --- a/src/main/scala/com/github/sbt/osgi/SbtOsgi.scala +++ b/src/main/scala/com/github/sbt/osgi/SbtOsgi.scala @@ -30,16 +30,16 @@ object SbtOsgi extends AutoPlugin { override lazy val requires: Plugins = JvmPlugin - override lazy val projectSettings: Seq[Def.Setting[_]] = defaultOsgiSettings + override lazy val projectSettings: Seq[Def.Setting[?]] = defaultOsgiSettings - override lazy val globalSettings: Seq[Def.Setting[_]] = defaultGlobalSettings + override lazy val globalSettings: Seq[Def.Setting[?]] = defaultGlobalSettings object autoImport { type OsgiManifestHeaders = com.github.sbt.osgi.OsgiManifestHeaders val OsgiKeys = com.github.sbt.osgi.OsgiKeys - lazy val osgiSettings: Seq[Setting[_]] = Seq( + lazy val osgiSettings: Seq[Setting[?]] = Seq( Compile / packageBin / packagedArtifact := Def.uncached { Scoped.mkTuple2( (Compile / packageBin / artifact).value, @@ -50,7 +50,7 @@ object SbtOsgi extends AutoPlugin { ) } - lazy val defaultOsgiSettings: Seq[Setting[_]] = { + lazy val defaultOsgiSettings: Seq[Setting[?]] = { import OsgiKeys._ Seq( bundle := Def.uncached { @@ -105,7 +105,7 @@ object SbtOsgi extends AutoPlugin { ) } - lazy val defaultGlobalSettings: Seq[Setting[_]] = { + lazy val defaultGlobalSettings: Seq[Setting[?]] = { import OsgiKeys._ Seq( bundle := Def.uncached { diff --git a/src/test/scala/com/github/sbt/osgi/OsgiSpec.scala b/src/test/scala/com/github/sbt/osgi/OsgiSpec.scala index 1bb8b70..a184a21 100644 --- a/src/test/scala/com/github/sbt/osgi/OsgiSpec.scala +++ b/src/test/scala/com/github/sbt/osgi/OsgiSpec.scala @@ -20,7 +20,7 @@ import aQute.bnd.osgi.Constants._ import java.io.File import org.specs2.mutable.Specification import java.net.URI -import scala.collection.JavaConverters._ +import scala.jdk.CollectionConverters._ class OsgiSpec extends Specification { From e30f873dfbc820896b9642bd67e487309dbdee9d Mon Sep 17 00:00:00 2001 From: Matthias Kurz Date: Sat, 16 May 2026 23:34:26 +0200 Subject: [PATCH 17/17] activate dependabot --- .github/dependabot.yml | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 .github/dependabot.yml diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..5ace460 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,6 @@ +version: 2 +updates: + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "weekly"