Created
June 23, 2021 07:12
-
-
Save danslapman/aa42b1a95895b2f08f8aa47b6589ce55 to your computer and use it in GitHub Desktop.
ManagedSourcesCachePlugin
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package sbt | |
import sbt.Keys._ | |
import sbt.internal.inc.HashUtil | |
import sbt.internal.remotecache.CustomRemoteCacheArtifact | |
import sbt.nio.FileStamp | |
import sbt.nio.file.FileAttributes | |
import sbt.plugins.JvmPlugin | |
import sbt.util.InterfaceUtil.toOption | |
//Adopted from https://github.com/iRevive/sbt-twirl-remote-cache | |
object ManagedSourcesCachePlugin extends AutoPlugin { | |
override def requires: Plugins = JvmPlugin | |
override def trigger: PluginTrigger = allRequirements | |
object autoImport { | |
lazy val ManagedSourcesCache = config("managedSourcesCache") | |
lazy val sourceGeneratorInputs = settingKey[Seq[File]]("Source generator inputs") | |
lazy val managedSourcesRemoteCacheArtifactName = settingKey[String]("The artifact name") | |
lazy val managedSourcesRemoteCacheDir = settingKey[File]("Managed sources remote cache directory") | |
lazy val pullManagedSourcesRemoteCache = taskKey[Unit]("Pull managed sources from remote cache") | |
lazy val pushManagedSourcesRemoteCache = taskKey[Unit]("Push managed sources to remote cache") | |
} | |
import autoImport._ | |
override lazy val projectConfigurations: Seq[Configuration] = Seq(ManagedSourcesCache) | |
override lazy val projectSettings: Seq[Setting[_]] = | |
Seq( | |
sourceGeneratorInputs := Seq() | |
) ++ | |
inConfig(ManagedSourcesCache)( | |
Seq( | |
packageOptions := { | |
val n = name.value + "-" + managedSourcesRemoteCacheArtifactName.value | |
val ver = version.value | |
val org = organization.value | |
val orgName = organizationName.value | |
val hp = homepage.value | |
List( | |
Package.addSpecManifestAttributes(n, ver, orgName), | |
Package.addImplManifestAttributes(n, ver, hp, org, orgName) | |
) | |
}, | |
mappings := { | |
val sourcesDir = sourceManaged.value | |
val sources = sourcesDir.globRecursive("*.scala").pair(Path.relativeTo(sourcesDir)) | |
sources | |
}, | |
packageConfiguration := Defaults.packageConfigurationTask.value, | |
packageCache := Defaults.packageTask.value, | |
artifact := Artifact(moduleName.value, managedSourcesRemoteCacheArtifactName.value), | |
packagedArtifact := (artifact.value -> packageCache.value), | |
artifactPath := Defaults.artifactPathSetting(artifact).value, | |
artifactName := Artifact.artifactName, | |
managedSourcesRemoteCacheArtifactName := "managed-sources", | |
pushRemoteCacheConfiguration / remoteCacheArtifacts += { | |
val art = (ManagedSourcesCache / artifact).value | |
val packaged = ManagedSourcesCache / packageCache | |
val extractDirectory = sourceManaged.value | |
CustomRemoteCacheArtifact(art, packaged, extractDirectory, preserveLastModified = false) | |
}, | |
managedSourcesRemoteCacheDir := { | |
val remote = pushRemoteCacheTo.value | |
val module = moduleName.value | |
val scalaBinVersion = scalaBinaryVersion.value | |
val base = remote match { | |
case Some(cache: MavenCache) => cache.rootFile | |
case _ => baseDirectory.value | |
} | |
base / module / scalaBinVersion | |
}, | |
pushManagedSourcesRemoteCache := { | |
val log = streams.value.log | |
val cacheDir = managedSourcesRemoteCacheDir.value | |
val baseDir = sourceManaged.value | |
val cacheId = { | |
val inputs = sourceGeneratorInputs.value.flatMap { dir => | |
dir | |
.globRecursive("*") | |
.get() | |
.map(_.toPath) | |
.map(path => path -> FileAttributes(path).toOption.flatMap(FileStamp(path, _))) | |
.collect { case (path, Some(stamp)) => path -> stamp } | |
} | |
combineHash(extractHash(inputs)) | |
} | |
val templates = baseDir.globRecursive("*.scala").pair(Path.relativeTo(baseDir)) | |
val output = cacheDir / s"$cacheId.zip" | |
if (sourceGeneratorInputs.value.nonEmpty && templates.nonEmpty) { | |
IO.zip(templates, output, None) | |
log.info(s"Published managed sources cache to $output") | |
} | |
}, | |
pullManagedSourcesRemoteCache := { | |
if (sourceGeneratorInputs.value.nonEmpty) { | |
val log = streams.value.log | |
val baseDir = sourceManaged.value | |
val cacheDir = managedSourcesRemoteCacheDir.value | |
val candidateIds = { | |
val inputs = sourceGeneratorInputs.value.flatMap { dir => | |
dir | |
.globRecursive("*") | |
.get() | |
.map(_.toPath) | |
.map(path => path -> FileAttributes(path).toOption.flatMap(FileStamp(path, _))) | |
.collect { case (path, Some(stamp)) => path -> stamp } | |
} | |
combineHash(extractHash(inputs)) | |
} :: Nil | |
candidateIds.map(id => cacheDir / s"$id.zip").find(_.exists) match { | |
case Some(archive) => | |
log.info(s"Found managed sources cache $archive") | |
IO.unzip(archive, baseDir, preserveLastModified = false) | |
case None => | |
log.info("Managed sources cache does not exist") | |
} | |
} | |
} | |
) | |
) | |
def extractHash(inputs: Seq[(java.nio.file.Path, FileStamp)]): Vector[String] = | |
inputs.toVector map { case (_, stamp0) => | |
toOption(stamp0.stamp.getHash).getOrElse("cafe") | |
} | |
def combineHash(vs: Vector[String]): String = { | |
val hashValue = HashUtil.farmHash(vs.sorted.mkString("").getBytes("UTF-8")) | |
java.lang.Long.toHexString(hashValue) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment