From 0b5d97d480be23612d5ddfc3b9a3d55425257c6a Mon Sep 17 00:00:00 2001 From: Romain Reuillon Date: Thu, 9 Nov 2023 13:50:25 +0100 Subject: [PATCH] Implement altenative caching stategies --- .../scala/com/typesafe/sbt/osgi/Osgi.scala | 52 ++++++++++--------- .../com/typesafe/sbt/osgi/OsgiKeys.scala | 11 +++- .../scala/com/typesafe/sbt/osgi/SbtOsgi.scala | 4 +- 3 files changed, 39 insertions(+), 28 deletions(-) diff --git a/src/main/scala/com/typesafe/sbt/osgi/Osgi.scala b/src/main/scala/com/typesafe/sbt/osgi/Osgi.scala index 318a832..294ef7e 100644 --- a/src/main/scala/com/typesafe/sbt/osgi/Osgi.scala +++ b/src/main/scala/com/typesafe/sbt/osgi/Osgi.scala @@ -16,19 +16,19 @@ package com.typesafe.sbt.osgi -import java.nio.file.{ FileVisitOption, Files, Path } - +import java.nio.file.{FileVisitOption, Files, Path} import aQute.bnd.osgi.Builder -import aQute.bnd.osgi.Constants._ +import aQute.bnd.osgi.Constants.* +import com.typesafe.sbt.osgi.OsgiKeys.CacheStrategy + import java.util.Properties import java.util.function.Predicate import java.util.stream.Collectors - -import sbt._ -import sbt.Keys._ +import sbt.* +import sbt.Keys.* import sbt.Package.ManifestAttributes -import scala.collection.JavaConverters._ +import scala.collection.JavaConverters.* import scala.language.implicitConversions private object Osgi { @@ -45,12 +45,19 @@ private object Osgi { sourceDirectories: Seq[File], packageOptions: scala.Seq[sbt.PackageOption], useJVMJar: Boolean, - cacheBundle: Boolean): Option[File] = { + 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) + } - def fileFootprint(file: File) = if (!file.exists()) Seq() - else if (file.isDirectory) Files.walk(file.toPath).iterator().asScala.map(f => f.toAbsolutePath.toString -> Hash.toHex(FileInfo.hash(f.toFile).hash.toArray)).toSeq - else Seq(file.absolutePath -> Hash.toHex(FileInfo.hash(file).hash.toArray)) + 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} @@ -68,16 +75,13 @@ private object Osgi { def footprint = Hash.apply(serialized).mkString("") - if (!cacheBundle) None - else { - val footprintValue = footprint - val bundleCacheFootprint = file(artifactPath.absolutePath + "_footprint") + val footprintValue = footprint + val bundleCacheFootprint = file(artifactPath.absolutePath + "_footprint") - if (!bundleCacheFootprint.exists() || IO.read(bundleCacheFootprint) != footprintValue) { - IO.write(bundleCacheFootprint, footprintValue) - None - } else if (artifactPath.exists()) Some(artifactPath) else None - } + if (!bundleCacheFootprint.exists() || IO.read(bundleCacheFootprint) != footprintValue) { + IO.write(bundleCacheFootprint, footprintValue) + None + } else if (artifactPath.exists()) Some(artifactPath) else None } def withCache( headers: OsgiManifestHeaders, @@ -91,7 +95,7 @@ private object Osgi { sourceDirectories: Seq[File], packageOptions: scala.Seq[sbt.PackageOption], useJVMJar: Boolean, - cacheBundle: Boolean)(produce: => File): File = + cacheStrategy: Option[CacheStrategy])(produce: => File): File = cachedBundle( headers, additionalHeaders, @@ -104,7 +108,7 @@ private object Osgi { sourceDirectories, packageOptions, useJVMJar, - cacheBundle + cacheStrategy ).getOrElse(produce) def bundleTask( @@ -119,7 +123,7 @@ private object Osgi { sourceDirectories: Seq[File], packageOptions: scala.Seq[sbt.PackageOption], useJVMJar: Boolean, - cacheBundle: Boolean, + cacheStrategy: Option[CacheStrategy], streams: TaskStreams): File = withCache(headers, additionalHeaders, @@ -132,7 +136,7 @@ private object Osgi { sourceDirectories, packageOptions, useJVMJar, - cacheBundle) { + cacheStrategy) { val builder = new Builder if (failOnUndecidedPackage) { diff --git a/src/main/scala/com/typesafe/sbt/osgi/OsgiKeys.scala b/src/main/scala/com/typesafe/sbt/osgi/OsgiKeys.scala index 7e096f2..c5d8fb6 100644 --- a/src/main/scala/com/typesafe/sbt/osgi/OsgiKeys.scala +++ b/src/main/scala/com/typesafe/sbt/osgi/OsgiKeys.scala @@ -107,10 +107,17 @@ object OsgiKeys { SettingKey[Boolean](prefix("PackageWithJVMJar"), "Use the JVM jar tools to craft the bundle instead of the one from BND." + "Without this setting the produced bundle are detected as corrupted by recent JVMs") - val cacheBundle: SettingKey[Boolean] = - SettingKey[Boolean](prefix("CacheBundle"), "Do not build a new bundle if a bundle already exists and has been crafted from identical inputs") + val cacheStrategy: SettingKey[Option[CacheStrategy]] = + SettingKey[Option[CacheStrategy]](prefix("CacheBundle"), "Do not build a new bundle if a bundle already exists and has been crafted from identical inputs") private def prefix(key: String) = "osgi" + key + + sealed trait CacheStrategy + + object CacheStrategy { + object Hash extends CacheStrategy + object LastModified extends CacheStrategy + } } diff --git a/src/main/scala/com/typesafe/sbt/osgi/SbtOsgi.scala b/src/main/scala/com/typesafe/sbt/osgi/SbtOsgi.scala index 2d0f2db..e0aa655 100644 --- a/src/main/scala/com/typesafe/sbt/osgi/SbtOsgi.scala +++ b/src/main/scala/com/typesafe/sbt/osgi/SbtOsgi.scala @@ -53,7 +53,7 @@ object SbtOsgi extends AutoPlugin { (sourceDirectories in Compile).value, (packageOptions in (Compile, packageBin)).value, packageWithJVMJar.value, - cacheBundle.value, + cacheStrategy.value, streams.value), Compile / sbt.Keys.packageBin := bundle.value, manifestHeaders := OsgiManifestHeaders( @@ -89,6 +89,6 @@ object SbtOsgi extends AutoPlugin { embeddedJars := Nil, explodedJars := Nil, packageWithJVMJar := false, - cacheBundle := false) + cacheStrategy := None) } }