Skip to content

Commit

Permalink
Apply scalafmt
Browse files Browse the repository at this point in the history
  • Loading branch information
mdedetrich committed Jan 25, 2024
1 parent 809fb46 commit b496e71
Show file tree
Hide file tree
Showing 31 changed files with 285 additions and 272 deletions.
9 changes: 5 additions & 4 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ ThisBuild / dynverSonatypeSnapshots := true

// So that publishLocal doesn't continuously create new versions
def versionFmt(out: sbtdynver.GitDescribeOutput): String = {
val snapshotSuffix = if
(out.isSnapshot()) "-SNAPSHOT"
else ""
val snapshotSuffix =
if (out.isSnapshot()) "-SNAPSHOT"
else ""
out.ref.dropPrefix + snapshotSuffix
}

Expand Down Expand Up @@ -55,7 +55,8 @@ scalacOptions ++= Seq(
"-unchecked",
"-deprecation",
"-Xlint",
"-encoding", "UTF-8"
"-encoding",
"UTF-8"
)
scriptedLaunchOpts += "-Xmx1024m"
scriptedLaunchOpts ++= Seq("-Dplugin.version=" + version.value)
Expand Down
7 changes: 2 additions & 5 deletions project/Dependencies.scala
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,11 @@ object Library {

// Libraries
val bndLib = "biz.aQute.bnd" % "biz.aQute.bndlib" % bndVersion
val specs2 = "org.specs2" %% "specs2-core" % specs2Version
val specs2 = "org.specs2" %% "specs2-core" % specs2Version
}

object Dependencies {

import Library._

val sbtOsgi = List(
bndLib,
specs2 % Test)
val sbtOsgi = List(bndLib, specs2 % Test)
}
4 changes: 2 additions & 2 deletions project/plugins.sbt
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
addSbtPlugin("com.github.sbt" % "sbt-ci-release" % "1.5.12")
addSbtPlugin("org.scalameta" % "sbt-scalafmt" % "2.5.2")
addSbtPlugin("com.github.sbt" % "sbt-ci-release" % "1.5.12")
addSbtPlugin("org.scalameta" % "sbt-scalafmt" % "2.5.2")
addSbtPlugin("com.github.sbt" % "sbt-github-actions" % "0.22.0")
249 changes: 138 additions & 111 deletions src/main/scala/com/typesafe/sbt/osgi/Osgi.scala
Original file line number Diff line number Diff line change
Expand Up @@ -35,42 +35,43 @@ import scala.language.implicitConversions
private object Osgi {

def cachedBundle(
headers: OsgiManifestHeaders,
additionalHeaders: Map[String, String],
fullClasspath: Seq[File],
artifactPath: File,
resourceDirectories: Seq[File],
embeddedJars: Seq[File],
explodedJars: Seq[File],
failOnUndecidedPackage: Boolean,
sourceDirectories: Seq[File],
packageOptions: scala.Seq[sbt.PackageOption],
useJVMJar: Boolean,
cacheStrategy: Option[CacheStrategy]): Option[File] = cacheStrategy.flatMap { strategy =>

headers: OsgiManifestHeaders,
additionalHeaders: Map[String, String],
fullClasspath: Seq[File],
artifactPath: File,
resourceDirectories: Seq[File],
embeddedJars: Seq[File],
explodedJars: Seq[File],
failOnUndecidedPackage: Boolean,
sourceDirectories: Seq[File],
packageOptions: scala.Seq[sbt.PackageOption],
useJVMJar: Boolean,
cacheStrategy: Option[CacheStrategy]
): Option[File] = cacheStrategy.flatMap { strategy =>
def fileFootprint(file: File) = {
def footprint(f: File) =
strategy match {
case CacheStrategy.LastModified => FileInfo.lastModified(f).lastModified.toString
case CacheStrategy.Hash => Hash.toHex(FileInfo.hash(f).hash.toArray)
case CacheStrategy.Hash => Hash.toHex(FileInfo.hash(f).hash.toArray)
}

if (!file.exists()) Seq()
else if (file.isDirectory) Files.walk(file.toPath).iterator().asScala.map(f => f.toAbsolutePath.toString -> footprint(f.toFile).toSeq)
else if (file.isDirectory)
Files.walk(file.toPath).iterator().asScala.map(f => f.toAbsolutePath.toString -> footprint(f.toFile).toSeq)
else Seq(file.absolutePath -> footprint(file))
}

def serialized =
s"""${headers}
|${additionalHeaders}
s"""$headers
|$additionalHeaders
|${fullClasspath.flatMap(fileFootprint)}
|${artifactPath}
|$artifactPath
|${resourceDirectories.flatMap(fileFootprint)}
|${embeddedJars.flatMap(fileFootprint)}
|${explodedJars.flatMap(fileFootprint)}
|$failOnUndecidedPackage
|${sourceDirectories.flatMap(fileFootprint)}
|${packageOptions}
|$packageOptions
|$useJVMJar
|""".stripMargin

Expand All @@ -82,21 +83,23 @@ private object Osgi {
if (!bundleCacheFootprint.exists() || IO.read(bundleCacheFootprint) != footprintValue) {
IO.write(bundleCacheFootprint, footprintValue)
None
} else if (artifactPath.exists()) Some(artifactPath) else None
} else if (artifactPath.exists()) Some(artifactPath)
else None
}
def withCache(
headers: OsgiManifestHeaders,
additionalHeaders: Map[String, String],
fullClasspath: Seq[File],
artifactPath: File,
resourceDirectories: Seq[File],
embeddedJars: Seq[File],
explodedJars: Seq[File],
failOnUndecidedPackage: Boolean,
sourceDirectories: Seq[File],
packageOptions: scala.Seq[sbt.PackageOption],
useJVMJar: Boolean,
cacheStrategy: Option[CacheStrategy])(produce: => File): File =
headers: OsgiManifestHeaders,
additionalHeaders: Map[String, String],
fullClasspath: Seq[File],
artifactPath: File,
resourceDirectories: Seq[File],
embeddedJars: Seq[File],
explodedJars: Seq[File],
failOnUndecidedPackage: Boolean,
sourceDirectories: Seq[File],
packageOptions: scala.Seq[sbt.PackageOption],
useJVMJar: Boolean,
cacheStrategy: Option[CacheStrategy]
)(produce: => File): File =
cachedBundle(
headers,
additionalHeaders,
Expand All @@ -113,20 +116,22 @@ private object Osgi {
).getOrElse(produce)

def bundleTask(
headers: OsgiManifestHeaders,
additionalHeaders: Map[String, String],
fullClasspath: Seq[File],
artifactPath: File,
resourceDirectories: Seq[File],
embeddedJars: Seq[File],
explodedJars: Seq[File],
failOnUndecidedPackage: Boolean,
sourceDirectories: Seq[File],
packageOptions: scala.Seq[sbt.PackageOption],
useJVMJar: Boolean,
cacheStrategy: Option[CacheStrategy],
streams: TaskStreams): File =
withCache(headers,
headers: OsgiManifestHeaders,
additionalHeaders: Map[String, String],
fullClasspath: Seq[File],
artifactPath: File,
resourceDirectories: Seq[File],
embeddedJars: Seq[File],
explodedJars: Seq[File],
failOnUndecidedPackage: Boolean,
sourceDirectories: Seq[File],
packageOptions: scala.Seq[sbt.PackageOption],
useJVMJar: Boolean,
cacheStrategy: Option[CacheStrategy],
streams: TaskStreams
): File =
withCache(
headers,
additionalHeaders,
fullClasspath,
artifactPath,
Expand All @@ -137,62 +142,67 @@ private object Osgi {
sourceDirectories,
packageOptions,
useJVMJar,
cacheStrategy) {
val builder = new Builder

if (failOnUndecidedPackage) {
streams.log.info("Validating all packages are set private or exported for OSGi explicitly...")
val internal = headers.privatePackage
val exported = headers.exportPackage
validateAllPackagesDecidedAbout(internal, exported, sourceDirectories)
}
cacheStrategy
) {
val builder = new Builder

if (failOnUndecidedPackage) {
streams.log.info("Validating all packages are set private or exported for OSGi explicitly...")
val internal = headers.privatePackage
val exported = headers.exportPackage
validateAllPackagesDecidedAbout(internal, exported, sourceDirectories)
}

builder.setClasspath(fullClasspath.toArray)

val props = headersToProperties(headers, additionalHeaders)
addPackageOptions(props, packageOptions)
builder.setProperties(props)

includeResourceProperty(resourceDirectories.filter(_.exists), embeddedJars, explodedJars) foreach (dirs =>
builder.setProperty(INCLUDERESOURCE, dirs))
bundleClasspathProperty(embeddedJars) foreach (jars =>
builder.setProperty(BUNDLE_CLASSPATH, jars))
// Write to a temporary file to prevent trying to simultaneously read from and write to the
// same jar file in exportJars mode (which causes a NullPointerException).
val tmpArtifactPath = file(artifactPath.absolutePath + ".tmp")
// builder.build is not thread-safe because it uses a static SimpleDateFormat. This ensures
// that all calls to builder.build are serialized.
val jar = synchronized {
builder.build
}
val log = streams.log
builder.getWarnings.asScala.foreach(s => log.warn(s"bnd: $s"))
builder.getErrors.asScala.foreach(s => log.error(s"bnd: $s"))

if (!useJVMJar) jar.write(tmpArtifactPath)
else {
val tmpArtifactDirectoryPath = file(artifactPath.absolutePath + "_tmpdir")
IO.delete(tmpArtifactDirectoryPath)
tmpArtifactDirectoryPath.mkdirs()

val manifest = jar.getManifest
jar.writeFolder(tmpArtifactDirectoryPath)

def content = {
import _root_.java.nio.file._
import _root_.scala.collection.JavaConverters._
val path = tmpArtifactDirectoryPath.toPath
Files.walk(path).iterator.asScala.map(f => f.toFile -> path.relativize(f))
.collect { case (f, p) if p != (file("META-INF") / "MANIFEST.MF").toPath => (f, p.toString) }
.toTraversable
}
builder.setClasspath(fullClasspath.toArray)

val props = headersToProperties(headers, additionalHeaders)
addPackageOptions(props, packageOptions)
builder.setProperties(props)

includeResourceProperty(resourceDirectories.filter(_.exists), embeddedJars, explodedJars) foreach (dirs =>
builder.setProperty(INCLUDERESOURCE, dirs)
)
bundleClasspathProperty(embeddedJars) foreach (jars => builder.setProperty(BUNDLE_CLASSPATH, jars))
// Write to a temporary file to prevent trying to simultaneously read from and write to the
// same jar file in exportJars mode (which causes a NullPointerException).
val tmpArtifactPath = file(artifactPath.absolutePath + ".tmp")
// builder.build is not thread-safe because it uses a static SimpleDateFormat. This ensures
// that all calls to builder.build are serialized.
val jar = synchronized {
builder.build
}
val log = streams.log
builder.getWarnings.asScala.foreach(s => log.warn(s"bnd: $s"))
builder.getErrors.asScala.foreach(s => log.error(s"bnd: $s"))

IO.jar(content, tmpArtifactPath, manifest)
IO.delete(tmpArtifactDirectoryPath)
if (!useJVMJar) jar.write(tmpArtifactPath)
else {
val tmpArtifactDirectoryPath = file(artifactPath.absolutePath + "_tmpdir")
IO.delete(tmpArtifactDirectoryPath)
tmpArtifactDirectoryPath.mkdirs()

val manifest = jar.getManifest
jar.writeFolder(tmpArtifactDirectoryPath)

def content = {
import _root_.java.nio.file._
import _root_.scala.collection.JavaConverters._
val path = tmpArtifactDirectoryPath.toPath
Files
.walk(path)
.iterator
.asScala
.map(f => f.toFile -> path.relativize(f))
.collect { case (f, p) if p != (file("META-INF") / "MANIFEST.MF").toPath => (f, p.toString) }
.toTraversable
}

IO.move(tmpArtifactPath, artifactPath)
artifactPath
IO.jar(content, tmpArtifactPath, manifest)
IO.delete(tmpArtifactDirectoryPath)
}

IO.move(tmpArtifactPath, artifactPath)
artifactPath
}

private def addPackageOptions(props: Properties, packageOptions: Seq[PackageOption]) = {
Expand All @@ -203,14 +213,21 @@ private object Osgi {
props
}

def validateAllPackagesDecidedAbout(internal: Seq[String], exported: Seq[String], sourceDirectories: Seq[File]): Unit = {
def validateAllPackagesDecidedAbout(
internal: Seq[String],
exported: Seq[String],
sourceDirectories: Seq[File]
): Unit = {
val allPackages = sourceDirectories.flatMap { baseFile =>
if (!baseFile.exists()) Nil
else {
val packages =
Files.walk(baseFile.toPath, FileVisitOption.FOLLOW_LINKS)
Files
.walk(baseFile.toPath, FileVisitOption.FOLLOW_LINKS)
.filter((p: Path) => p.toFile.isDirectory) // uses conversions defined below to not look horrible
.filter((p: Path) => p.toFile.listFiles().exists(f => f.isFile)) // uses conversions defined below to not look horrible
.filter((p: Path) =>
p.toFile.listFiles().exists(f => f.isFile)
) // uses conversions defined below to not look horrible
.map[String]((p: Path) => {
val pack = p.toString.replace(baseFile.toString, "").replaceAll("/", ".")
if (pack.startsWith(".")) pack.substring(1) else pack
Expand All @@ -222,9 +239,15 @@ private object Osgi {
}
}.toSet

def validateAllPackagesDecidedAbout(internal: Seq[String], exported: Seq[String], realPackages: List[String]): Unit =
def validateAllPackagesDecidedAbout(
internal: Seq[String],
exported: Seq[String],
realPackages: List[String]
): Unit =
if (internal.isEmpty && exported.isEmpty && realPackages.nonEmpty) {
throw new RuntimeException(s"Remaining packages are undecided about (private or exported) for OSGi (this is rather dangerous!): ${realPackages}")
throw new RuntimeException(
s"Remaining packages are undecided about (private or exported) for OSGi (this is rather dangerous!): ${realPackages}"
)
} else
realPackages match {
case Nil => // OK!
Expand All @@ -234,11 +257,14 @@ private object Osgi {

if (startsWith(pack, internal) || startsWith(pack, exported)) {
validateAllPackagesDecidedAbout(internal, exported, remainingPackages)
} else throw new RuntimeException(s"Unable to determine if [$pack] package is meant to be private or exported! " +
s"Please define what to do with this package for OSGi explicitly! \n" +
s" Private packages : $internal\n" +
s" Exported packages: $exported\n" +
s" Offending package: $pack\n")
} else
throw new RuntimeException(
s"Unable to determine if [$pack] package is meant to be private or exported! " +
s"Please define what to do with this package for OSGi explicitly! \n" +
s" Private packages : $internal\n" +
s" Exported packages: $exported\n" +
s" Offending package: $pack\n"
)
}

val i = internal.map(_.replaceAll(".*", ""))
Expand All @@ -261,8 +287,9 @@ private object Osgi {
bundleActivator foreach (properties.put(BUNDLE_ACTIVATOR, _))
strToStrOpt(bundleDescription) foreach (properties.put(BUNDLE_DESCRIPTION, _))
bundleDocURL foreach (u => properties.put(BUNDLE_DOCURL, u.toString))
bundleLicense.headOption foreach {case (license, url) =>
properties.put(BUNDLE_LICENSE, s"${url.toString};description=$license")}
bundleLicense.headOption foreach { case (license, url) =>
properties.put(BUNDLE_LICENSE, s"${url.toString};description=$license")
}
strToStrOpt(bundleName) foreach (properties.put(BUNDLE_NAME, _))
seqToStrOpt(bundleRequiredExecutionEnvironment)(id) foreach (properties.put(BUNDLE_REQUIREDEXECUTIONENVIRONMENT, _))
strToStrOpt(bundleVendor) foreach (properties.put(BUNDLE_VENDOR, _))
Expand Down Expand Up @@ -296,7 +323,7 @@ private object Osgi {
val nameParts = parts(name)
val partsWithoutOverlap = (organizationParts.lastOption, nameParts.headOption) match {
case (Some(last), Some(head)) if last == head => organizationParts ++ nameParts.tail
case _ => organizationParts ++ nameParts
case _ => organizationParts ++ nameParts
}
partsWithoutOverlap mkString "."
}
Expand Down
Loading

0 comments on commit b496e71

Please sign in to comment.