Merge pull request #5639 from iRevive/customizable-remote-cache-artifacts

Allow customization of remote cache artifacts
This commit is contained in:
eugene yokota 2020-06-23 15:34:21 -04:00 committed by GitHub
commit 406330b3fe
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 524 additions and 50 deletions

View File

@ -0,0 +1,44 @@
/**
* This code is generated using [[https://www.scala-sbt.org/contraband/ sbt-contraband]].
*/
// DO NOT EDIT MANUALLY
package sbt.internal.remotecache
final class CompileRemoteCacheArtifact private (
artifact: sbt.librarymanagement.Artifact,
packaged: sbt.TaskKey[java.io.File],
val extractDirectory: java.io.File,
val analysisFile: java.io.File) extends sbt.internal.remotecache.RemoteCacheArtifact(artifact, packaged) with Serializable {
override def equals(o: Any): Boolean = o match {
case x: CompileRemoteCacheArtifact => (this.artifact == x.artifact) && (this.packaged == x.packaged) && (this.extractDirectory == x.extractDirectory) && (this.analysisFile == x.analysisFile)
case _ => false
}
override def hashCode: Int = {
37 * (37 * (37 * (37 * (37 * (17 + "sbt.internal.remotecache.CompileRemoteCacheArtifact".##) + artifact.##) + packaged.##) + extractDirectory.##) + analysisFile.##)
}
override def toString: String = {
"CompileRemoteCacheArtifact(" + artifact + ", " + packaged + ", " + extractDirectory + ", " + analysisFile + ")"
}
private[this] def copy(artifact: sbt.librarymanagement.Artifact = artifact, packaged: sbt.TaskKey[java.io.File] = packaged, extractDirectory: java.io.File = extractDirectory, analysisFile: java.io.File = analysisFile): CompileRemoteCacheArtifact = {
new CompileRemoteCacheArtifact(artifact, packaged, extractDirectory, analysisFile)
}
def withArtifact(artifact: sbt.librarymanagement.Artifact): CompileRemoteCacheArtifact = {
copy(artifact = artifact)
}
def withPackaged(packaged: sbt.TaskKey[java.io.File]): CompileRemoteCacheArtifact = {
copy(packaged = packaged)
}
def withExtractDirectory(extractDirectory: java.io.File): CompileRemoteCacheArtifact = {
copy(extractDirectory = extractDirectory)
}
def withAnalysisFile(analysisFile: java.io.File): CompileRemoteCacheArtifact = {
copy(analysisFile = analysisFile)
}
}
object CompileRemoteCacheArtifact {
def apply(artifact: sbt.librarymanagement.Artifact, packaged: sbt.TaskKey[java.io.File], extractDirectory: java.io.File, analysisFile: java.io.File): CompileRemoteCacheArtifact = new CompileRemoteCacheArtifact(artifact, packaged, extractDirectory, analysisFile)
}

View File

@ -0,0 +1,44 @@
/**
* This code is generated using [[https://www.scala-sbt.org/contraband/ sbt-contraband]].
*/
// DO NOT EDIT MANUALLY
package sbt.internal.remotecache
final class CustomRemoteCacheArtifact private (
artifact: sbt.librarymanagement.Artifact,
packaged: sbt.TaskKey[java.io.File],
val extractDirectory: java.io.File,
val preserveLastModified: Boolean) extends sbt.internal.remotecache.RemoteCacheArtifact(artifact, packaged) with Serializable {
override def equals(o: Any): Boolean = o match {
case x: CustomRemoteCacheArtifact => (this.artifact == x.artifact) && (this.packaged == x.packaged) && (this.extractDirectory == x.extractDirectory) && (this.preserveLastModified == x.preserveLastModified)
case _ => false
}
override def hashCode: Int = {
37 * (37 * (37 * (37 * (37 * (17 + "sbt.internal.remotecache.CustomRemoteCacheArtifact".##) + artifact.##) + packaged.##) + extractDirectory.##) + preserveLastModified.##)
}
override def toString: String = {
"CustomRemoteCacheArtifact(" + artifact + ", " + packaged + ", " + extractDirectory + ", " + preserveLastModified + ")"
}
private[this] def copy(artifact: sbt.librarymanagement.Artifact = artifact, packaged: sbt.TaskKey[java.io.File] = packaged, extractDirectory: java.io.File = extractDirectory, preserveLastModified: Boolean = preserveLastModified): CustomRemoteCacheArtifact = {
new CustomRemoteCacheArtifact(artifact, packaged, extractDirectory, preserveLastModified)
}
def withArtifact(artifact: sbt.librarymanagement.Artifact): CustomRemoteCacheArtifact = {
copy(artifact = artifact)
}
def withPackaged(packaged: sbt.TaskKey[java.io.File]): CustomRemoteCacheArtifact = {
copy(packaged = packaged)
}
def withExtractDirectory(extractDirectory: java.io.File): CustomRemoteCacheArtifact = {
copy(extractDirectory = extractDirectory)
}
def withPreserveLastModified(preserveLastModified: Boolean): CustomRemoteCacheArtifact = {
copy(preserveLastModified = preserveLastModified)
}
}
object CustomRemoteCacheArtifact {
def apply(artifact: sbt.librarymanagement.Artifact, packaged: sbt.TaskKey[java.io.File], extractDirectory: java.io.File, preserveLastModified: Boolean): CustomRemoteCacheArtifact = new CustomRemoteCacheArtifact(artifact, packaged, extractDirectory, preserveLastModified)
}

View File

@ -0,0 +1,36 @@
/**
* This code is generated using [[https://www.scala-sbt.org/contraband/ sbt-contraband]].
*/
// DO NOT EDIT MANUALLY
package sbt.internal.remotecache
final class PomRemoteCacheArtifact private (
artifact: sbt.librarymanagement.Artifact,
packaged: sbt.TaskKey[java.io.File]) extends sbt.internal.remotecache.RemoteCacheArtifact(artifact, packaged) with Serializable {
override def equals(o: Any): Boolean = o match {
case x: PomRemoteCacheArtifact => (this.artifact == x.artifact) && (this.packaged == x.packaged)
case _ => false
}
override def hashCode: Int = {
37 * (37 * (37 * (17 + "sbt.internal.remotecache.PomRemoteCacheArtifact".##) + artifact.##) + packaged.##)
}
override def toString: String = {
"PomRemoteCacheArtifact(" + artifact + ", " + packaged + ")"
}
private[this] def copy(artifact: sbt.librarymanagement.Artifact = artifact, packaged: sbt.TaskKey[java.io.File] = packaged): PomRemoteCacheArtifact = {
new PomRemoteCacheArtifact(artifact, packaged)
}
def withArtifact(artifact: sbt.librarymanagement.Artifact): PomRemoteCacheArtifact = {
copy(artifact = artifact)
}
def withPackaged(packaged: sbt.TaskKey[java.io.File]): PomRemoteCacheArtifact = {
copy(packaged = packaged)
}
}
object PomRemoteCacheArtifact {
def apply(artifact: sbt.librarymanagement.Artifact, packaged: sbt.TaskKey[java.io.File]): PomRemoteCacheArtifact = new PomRemoteCacheArtifact(artifact, packaged)
}

View File

@ -0,0 +1,27 @@
/**
* This code is generated using [[https://www.scala-sbt.org/contraband/ sbt-contraband]].
*/
// DO NOT EDIT MANUALLY
package sbt.internal.remotecache
abstract class RemoteCacheArtifact(
val artifact: sbt.librarymanagement.Artifact,
val packaged: sbt.TaskKey[java.io.File]) extends Serializable {
override def equals(o: Any): Boolean = o match {
case x: RemoteCacheArtifact => (this.artifact == x.artifact) && (this.packaged == x.packaged)
case _ => false
}
override def hashCode: Int = {
37 * (37 * (37 * (17 + "sbt.internal.remotecache.RemoteCacheArtifact".##) + artifact.##) + packaged.##)
}
override def toString: String = {
"RemoteCacheArtifact(" + artifact + ", " + packaged + ")"
}
}
object RemoteCacheArtifact {
}

View File

@ -0,0 +1,48 @@
/**
* This code is generated using [[https://www.scala-sbt.org/contraband/ sbt-contraband]].
*/
// DO NOT EDIT MANUALLY
package sbt.internal.remotecache
final class TestRemoteCacheArtifact private (
artifact: sbt.librarymanagement.Artifact,
packaged: sbt.TaskKey[java.io.File],
val extractDirectory: java.io.File,
val analysisFile: java.io.File,
val testResult: java.io.File) extends sbt.internal.remotecache.RemoteCacheArtifact(artifact, packaged) with Serializable {
override def equals(o: Any): Boolean = o match {
case x: TestRemoteCacheArtifact => (this.artifact == x.artifact) && (this.packaged == x.packaged) && (this.extractDirectory == x.extractDirectory) && (this.analysisFile == x.analysisFile) && (this.testResult == x.testResult)
case _ => false
}
override def hashCode: Int = {
37 * (37 * (37 * (37 * (37 * (37 * (17 + "sbt.internal.remotecache.TestRemoteCacheArtifact".##) + artifact.##) + packaged.##) + extractDirectory.##) + analysisFile.##) + testResult.##)
}
override def toString: String = {
"TestRemoteCacheArtifact(" + artifact + ", " + packaged + ", " + extractDirectory + ", " + analysisFile + ", " + testResult + ")"
}
private[this] def copy(artifact: sbt.librarymanagement.Artifact = artifact, packaged: sbt.TaskKey[java.io.File] = packaged, extractDirectory: java.io.File = extractDirectory, analysisFile: java.io.File = analysisFile, testResult: java.io.File = testResult): TestRemoteCacheArtifact = {
new TestRemoteCacheArtifact(artifact, packaged, extractDirectory, analysisFile, testResult)
}
def withArtifact(artifact: sbt.librarymanagement.Artifact): TestRemoteCacheArtifact = {
copy(artifact = artifact)
}
def withPackaged(packaged: sbt.TaskKey[java.io.File]): TestRemoteCacheArtifact = {
copy(packaged = packaged)
}
def withExtractDirectory(extractDirectory: java.io.File): TestRemoteCacheArtifact = {
copy(extractDirectory = extractDirectory)
}
def withAnalysisFile(analysisFile: java.io.File): TestRemoteCacheArtifact = {
copy(analysisFile = analysisFile)
}
def withTestResult(testResult: java.io.File): TestRemoteCacheArtifact = {
copy(testResult = testResult)
}
}
object TestRemoteCacheArtifact {
def apply(artifact: sbt.librarymanagement.Artifact, packaged: sbt.TaskKey[java.io.File], extractDirectory: java.io.File, analysisFile: java.io.File, testResult: java.io.File): TestRemoteCacheArtifact = new TestRemoteCacheArtifact(artifact, packaged, extractDirectory, analysisFile, testResult)
}

View File

@ -0,0 +1,83 @@
{
"codecNamespace": "sbt.internal.remotecache",
"fullCodec": "RemoteCacheArtifactCodec",
"types": [
{
"name": "RemoteCacheArtifact",
"namespace": "sbt.internal.remotecache",
"target": "Scala",
"type": "interface",
"fields": [
{
"name": "artifact",
"type": "sbt.librarymanagement.Artifact"
},
{
"name": "packaged",
"type": "sbt.TaskKey[java.io.File]"
}
],
"types": [
{
"name": "PomRemoteCacheArtifact",
"namespace": "sbt.internal.remotecache",
"target": "Scala",
"type": "record",
"fields": []
},
{
"name": "CompileRemoteCacheArtifact",
"namespace": "sbt.internal.remotecache",
"target": "Scala",
"type": "record",
"fields": [
{
"name": "extractDirectory",
"type": "java.io.File"
},
{
"name": "analysisFile",
"type": "java.io.File"
}
]
},
{
"name": "TestRemoteCacheArtifact",
"namespace": "sbt.internal.remotecache",
"target": "Scala",
"type": "record",
"fields": [
{
"name": "extractDirectory",
"type": "java.io.File"
},
{
"name": "analysisFile",
"type": "java.io.File"
},
{
"name": "testResult",
"type": "java.io.File"
}
]
},
{
"name": "CustomRemoteCacheArtifact",
"namespace": "sbt.internal.remotecache",
"target": "Scala",
"type": "record",
"fields": [
{
"name": "extractDirectory",
"type": "java.io.File"
},
{
"name": "preserveLastModified",
"type": "Boolean"
}
]
}
]
}
]
}

View File

@ -25,6 +25,7 @@ import sbt.internal.bsp._
import sbt.internal.inc.ScalaInstance
import sbt.internal.io.WatchState
import sbt.internal.librarymanagement.{ CompatibilityWarningOptions, IvySbt }
import sbt.internal.remotecache.RemoteCacheArtifact
import sbt.internal.server.ServerHandler
import sbt.internal.util.{ AttributeKey, ProgressState, SourcePosition }
import sbt.io._
@ -345,6 +346,8 @@ object Keys {
val remoteCacheId = taskKey[String]("Unique identifier for the remote cache.")
val remoteCacheProjectId = taskKey[ModuleID]("ModuleID used for remote cache JARs.")
val remoteCacheIdCandidates = taskKey[Seq[String]]("Remote cache ids to pull.")
val remoteCacheArtifacts = taskKey[Seq[RemoteCacheArtifact]]("Remote cache artifact definitions.")
val remoteCacheArtifact = taskKey[RemoteCacheArtifact]("The remote cache artifact definition.")
val pullRemoteCache = taskKey[Unit]("Retrieve remote cache.")
val pushRemoteCache = taskKey[Unit]("Push remote cache to the cache server.")
val pushRemoteCacheArtifact = settingKey[Boolean]("Enables publishing an artifact to remote cache.")

View File

@ -20,16 +20,18 @@ import sbt.librarymanagement.syntax._
import sbt.internal.librarymanagement._
import sbt.io.IO
import sbt.io.syntax._
import sbt.internal.remotecache._
import sbt.internal.inc.JarUtils
import sbt.util.Logger
object RemoteCache {
final val cachedCompileClassifier = "cached-compile"
final val cachedTestClasifier = "cached-test"
final val cachedTestClassifier = "cached-test"
final val commitLength = 10
def gitCommitId: String =
scala.sys.process.Process("git rev-parse HEAD").!!.trim.take(commitLength)
def gitCommitIds(n: Int): List[String] =
scala.sys.process
.Process("git log -n " + n.toString + " --format=%H")
@ -41,7 +43,7 @@ object RemoteCache {
lazy val globalSettings: Seq[Def.Setting[_]] = Seq(
remoteCacheId := gitCommitId,
remoteCacheIdCandidates := gitCommitIds(5),
pushRemoteCacheTo :== None,
pushRemoteCacheTo :== None
)
lazy val projectSettings: Seq[Def.Setting[_]] = (Seq(
@ -54,12 +56,21 @@ object RemoteCache {
ModuleID(o, m, v).cross(c)
},
pushRemoteCacheConfiguration / publishMavenStyle := true,
pushRemoteCacheConfiguration / artifacts := artifactDefs(defaultArtifactTasks).value,
pushRemoteCacheConfiguration / packagedArtifacts := packaged(defaultArtifactTasks).value,
pushRemoteCacheConfiguration / packagedArtifacts := Def.taskDyn {
val artifacts = (pushRemoteCacheConfiguration / remoteCacheArtifacts).value
artifacts
.map(a => a.packaged.map(file => (a.artifact, file)))
.join
.apply(_.join.map(_.toMap))
}.value,
pushRemoteCacheConfiguration / remoteCacheArtifacts := {
enabledOnly(remoteCacheArtifact.toSettingKey, defaultArtifactTasks).apply(_.join).value
},
Compile / packageCache / pushRemoteCacheArtifact := true,
Test / packageCache / pushRemoteCacheArtifact := true,
Compile / packageCache / artifact := Artifact(moduleName.value, cachedCompileClassifier),
Test / packageCache / artifact := Artifact(moduleName.value, cachedTestClasifier),
Test / packageCache / artifact := Artifact(moduleName.value, cachedTestClassifier),
remoteCachePom / pushRemoteCacheArtifact := true,
pushRemoteCacheConfiguration := {
Classpaths.publishConfig(
@ -75,19 +86,17 @@ object RemoteCache {
)
},
pullRemoteCache := {
val s = streams.value
val log = streams.value.log
val smi = scalaModuleInfo.value
val dr = (pullRemoteCache / dependencyResolution).value
val is = (pushRemoteCache / ivySbt).value
val t = crossTarget.value / "cache-download"
val p = remoteCacheProjectId.value
val ids = remoteCacheIdCandidates.value
val compileAf = (Compile / compileAnalysisFile).value
val compileOutput = (Compile / classDirectory).value
val testAf = (Test / compileAnalysisFile).value
val testOutput = (Test / classDirectory).value
val testStreams = (Test / test / streams).value
val testResult = Defaults.succeededFile(testStreams.cacheDirectory)
val artifacts = (pushRemoteCacheConfiguration / remoteCacheArtifacts).value
val applicable = artifacts.filterNot(isPomArtifact)
val classifiers = applicable.flatMap(_.artifact.classifier).toVector
var found = false
ids foreach {
id: String =>
@ -95,19 +104,25 @@ object RemoteCache {
val modId = p.withRevision(v)
if (found) ()
else
pullFromMavenRepo0(modId, smi, is, dr, t, s.log) match {
pullFromMavenRepo0(modId, classifiers, smi, is, dr, t, log) match {
case Right(xs0) =>
val xs = xs0.distinct
xs.find(_.toString.endsWith(s"$v-$cachedCompileClassifier.jar")) foreach {
jar: File =>
extractCache(jar, compileOutput, compileAf, None)
}
xs.find(_.toString.endsWith(s"$v-$cachedTestClasifier.jar")) foreach { jar: File =>
extractCache(jar, testOutput, testAf, Some(testResult))
val jars = xs0.distinct
applicable.foreach { art =>
val classifier = art.artifact.classifier
findJar(classifier, v, jars) match {
case Some(jar) =>
extractJar(art, jar)
log.info(s"remote cache artifact extracted for $classifier")
case None =>
log.info(s"remote cache artifact not found for $classifier")
}
}
found = true
case Left(unresolvedWarning) =>
s.log.info(s"remote cache not found for ${v}")
log.info(s"remote cache not found for ${v}")
}
}
},
@ -118,7 +133,9 @@ object RemoteCache {
publisher.makePomFile((pushRemoteCache / ivyModule).value, config, s.log)
config.file.get
},
remoteCachePom / packagedArtifact := ((makePom / artifact).value -> remoteCachePom.value),
remoteCachePom / remoteCacheArtifact := {
PomRemoteCacheArtifact((makePom / artifact).value, remoteCachePom)
}
) ++ inTask(pushRemoteCache)(
Seq(
ivyConfiguration := {
@ -146,7 +163,7 @@ object RemoteCache {
val s = streams.value
val config = pushRemoteCacheConfiguration.value
IvyActions.publish(ivyModule.value, config, s.log)
} tag (Tags.Publish, Tags.Network)).value,
} tag (Tags.Publish, Tags.Network)).value
)
) ++ inTask(pullRemoteCache)(
Seq(
@ -157,10 +174,12 @@ object RemoteCache {
.withResolvers(rs)
}
)
) ++ inConfig(Compile)(packageCacheSettings)
++ inConfig(Test)(packageCacheSettings))
) ++ inConfig(Compile)(packageCacheSettings(compileArtifact(Compile, cachedCompileClassifier)))
++ inConfig(Test)(packageCacheSettings(testArtifact(Test, cachedTestClassifier))))
def packageCacheSettings: Seq[Def.Setting[_]] =
private def packageCacheSettings[A <: RemoteCacheArtifact](
cacheArtifact: Def.Initialize[Task[A]]
): Seq[Def.Setting[_]] =
inTask(packageCache)(
Seq(
packageCache.in(Defaults.TaskZero) := {
@ -180,15 +199,48 @@ object RemoteCache {
// }
artp
},
remoteCacheArtifact := cacheArtifact.value,
packagedArtifact := (artifact.value -> packageCache.value),
artifactPath := Defaults.artifactPathSetting(artifact).value,
artifactPath := Defaults.artifactPathSetting(artifact).value
)
)
def isPomArtifact(artifact: RemoteCacheArtifact): Boolean =
artifact match {
case _: PomRemoteCacheArtifact => true
case _ => false
}
def compileArtifact(
configuration: Configuration,
classifier: String
): Def.Initialize[Task[CompileRemoteCacheArtifact]] = Def.task {
CompileRemoteCacheArtifact(
Artifact(moduleName.value, classifier),
configuration / packageCache,
(configuration / classDirectory).value,
(configuration / compileAnalysisFile).value
)
}
def testArtifact(
configuration: Configuration,
classifier: String
): Def.Initialize[Task[TestRemoteCacheArtifact]] = Def.task {
TestRemoteCacheArtifact(
Artifact(moduleName.value, classifier),
configuration / packageCache,
(configuration / classDirectory).value,
(configuration / compileAnalysisFile).value,
Defaults.succeededFile((configuration / test / streams).value.cacheDirectory)
)
}
private def toVersion(v: String): String = s"0.0.0-$v"
private def pullFromMavenRepo0(
modId: ModuleID,
classifiers: Vector[String],
smi: Option[ScalaModuleInfo],
is: IvySbt,
dr: DependencyResolution,
@ -202,47 +254,65 @@ object RemoteCache {
.withScalaModuleInfo(smi)
.withDependencies(deps)
}
val deps =
Vector(modId.classifier(cachedCompileClassifier), modId.classifier(cachedTestClasifier))
val deps = classifiers.map(modId.classifier)
val mconfig = dummyModule(deps)
val m = new is.Module(mconfig)
dr.retrieve(m, cacheDir, log)
}
private def extractCache(
jar: File,
output: File,
analysisFile: File,
testResult: Option[File]
private def findJar(classifier: Option[String], ver: String, jars: Vector[File]): Option[File] = {
val suffix = classifier.fold(ver)(c => s"$ver-$c.jar")
jars.find(_.toString.endsWith(suffix))
}
private def extractJar(cacheArtifact: RemoteCacheArtifact, jar: File): Unit =
cacheArtifact match {
case a: CompileRemoteCacheArtifact =>
extractCache(jar, a.extractDirectory, preserveLastModified = true) { output =>
extractAnalysis(output, a.analysisFile)
}
case a: TestRemoteCacheArtifact =>
extractCache(jar, a.extractDirectory, preserveLastModified = true) { output =>
extractAnalysis(output, a.analysisFile)
extractTestResult(output, a.testResult)
}
case a: CustomRemoteCacheArtifact =>
extractCache(jar, a.extractDirectory, a.preserveLastModified)(_ => ())
case _ =>
()
}
private def extractCache(jar: File, output: File, preserveLastModified: Boolean)(
processOutput: File => Unit
): Unit = {
IO.delete(output)
IO.unzip(jar, output)
IO.unzip(jar, output, preserveLastModified = preserveLastModified)
processOutput(output)
IO.delete(output / "META-INF")
}
private def extractAnalysis(output: File, analysisFile: File): Unit = {
val metaDir = output / "META-INF"
val expandedAnalysis = metaDir / "inc_compile.zip"
if (expandedAnalysis.exists) {
IO.move(expandedAnalysis, analysisFile)
}
IO.delete(metaDir)
// testResult match {
// case Some(r) =>
// val expandedTestResult = output / "META-INF" / "succeeded_tests"
// if (expandedTestResult.exists) {
// IO.move(expandedTestResult, r)
// }
// case _ => ()
// }
()
}
private def extractTestResult(output: File, testResult: File): Unit = {
//val expandedTestResult = output / "META-INF" / "succeeded_tests"
//if (expandedTestResult.exists) {
// IO.move(expandedTestResult, testResult)
//}
}
private def defaultArtifactTasks: Seq[TaskKey[File]] =
Seq(remoteCachePom, Compile / packageCache, Test / packageCache)
private def packaged(pkgTasks: Seq[TaskKey[File]]): Def.Initialize[Task[Map[Artifact, File]]] =
enabledOnly(packagedArtifact.toSettingKey, pkgTasks) apply (_.join.map(_.toMap))
private def artifactDefs(pkgTasks: Seq[TaskKey[File]]): Def.Initialize[Seq[Artifact]] =
enabledOnly(artifact, pkgTasks)
private def enabledOnly[A](
key: SettingKey[A],
pkgTasks: Seq[TaskKey[File]]

View File

@ -0,0 +1,59 @@
import sbt.internal.remotecache.CustomRemoteCacheArtifact
lazy val root = (project in file("."))
.configs(CustomArtifact)
.settings(
name := "my-project",
scalaVersion := "2.12.11",
pushRemoteCacheTo := Some(
MavenCache("local-cache", (ThisBuild / baseDirectory).value / "remote-cache")
),
remoteCacheId := "fixed-id",
remoteCacheIdCandidates := Seq("fixed-id"),
pushRemoteCacheConfiguration := pushRemoteCacheConfiguration.value.withOverwrite(true),
pushRemoteCacheConfiguration / remoteCacheArtifacts += {
val art = (CustomArtifact / artifact).value
val packaged = CustomArtifact / packageCache
val extractDirectory = (CustomArtifact / sourceManaged).value
CustomRemoteCacheArtifact(art, packaged, extractDirectory, preserveLastModified = false)
},
Compile / sourceGenerators += Def.task {
val extractDirectory = (CustomArtifact / sourceManaged).value
val output = extractDirectory / "HelloWorld.scala"
IO.write(output, "class HelloWorld")
Seq(output)
}.taskValue
)
.settings(customArtifactSettings)
lazy val CustomArtifact = config("custom-artifact")
def customArtifactSettings: Seq[Def.Setting[_]] = {
val classifier = "custom-artifact"
inConfig(CustomArtifact)(
Seq(
packageOptions := {
val n = name.value + "-" + classifier
val ver = version.value
val orgName = organizationName.value
List(Package.addSpecManifestAttributes(n, ver, orgName))
},
sourceManaged := (Compile / target).value / "custom-artifact-gen",
mappings := {
val sourcesDir = sourceManaged.value
val sources = sourcesDir.allPaths.pair(Path.relativeTo(sourcesDir))
sources
},
packageConfiguration := Defaults.packageConfigurationTask.value,
packageCache := Defaults.packageTask.value,
artifact := Artifact(moduleName.value, classifier),
packagedArtifact := (artifact.value -> packageCache.value),
artifactPath := Defaults.artifactPathSetting(artifact).value,
artifactName := Artifact.artifactName
)
)
}

View File

@ -0,0 +1 @@
object MyClass

View File

@ -0,0 +1 @@
object MyTest

View File

@ -0,0 +1,58 @@
> compile
> pushRemoteCache
# Generated sources, compiled classes
$ exists target/custom-artifact-gen/HelloWorld.scala
$ exists target/scala-2.12/classes/HelloWorld.class
$ exists target/scala-2.12/classes/MyClass.class
$ exists target/scala-2.12/classes/MyClass$.class
$ exists target/scala-2.12/zinc/inc_compile_2.12.zip
$ exists target/scala-2.12/test-classes/MyTest.class
$ exists target/scala-2.12/test-classes/MyTest$.class
$ exists target/scala-2.12/test-zinc/inc_compile_2.12.zip
# Pom file
$ exists remote-cache/my-project/my-project_2.12/0.0.0-fixed-id/my-project_2.12-0.0.0-fixed-id.pom
$ exists remote-cache/my-project/my-project_2.12/0.0.0-fixed-id/my-project_2.12-0.0.0-fixed-id.pom.md5
$ exists remote-cache/my-project/my-project_2.12/0.0.0-fixed-id/my-project_2.12-0.0.0-fixed-id.pom.sha1
# Compile
$ exists remote-cache/my-project/my-project_2.12/0.0.0-fixed-id/my-project_2.12-0.0.0-fixed-id-cached-compile.jar
$ exists remote-cache/my-project/my-project_2.12/0.0.0-fixed-id/my-project_2.12-0.0.0-fixed-id-cached-compile.jar.md5
$ exists remote-cache/my-project/my-project_2.12/0.0.0-fixed-id/my-project_2.12-0.0.0-fixed-id-cached-compile.jar.sha1
# Test
$ exists remote-cache/my-project/my-project_2.12/0.0.0-fixed-id/my-project_2.12-0.0.0-fixed-id-cached-test.jar
$ exists remote-cache/my-project/my-project_2.12/0.0.0-fixed-id/my-project_2.12-0.0.0-fixed-id-cached-test.jar.md5
$ exists remote-cache/my-project/my-project_2.12/0.0.0-fixed-id/my-project_2.12-0.0.0-fixed-id-cached-test.jar.sha1
# Custom artifact
$ exists remote-cache/my-project/my-project_2.12/0.0.0-fixed-id/my-project_2.12-0.0.0-fixed-id-custom-artifact.jar
$ exists remote-cache/my-project/my-project_2.12/0.0.0-fixed-id/my-project_2.12-0.0.0-fixed-id-custom-artifact.jar.md5
$ exists remote-cache/my-project/my-project_2.12/0.0.0-fixed-id/my-project_2.12-0.0.0-fixed-id-custom-artifact.jar.sha1
> clean
$ absent target/custom-artifact-gen/HelloWorld.scala
$ absent target/scala-2.12/classes/HelloWorld.class
$ absent target/scala-2.12/classes/MyClass.class
$ absent target/scala-2.12/classes/MyClass$.class
$ absent target/scala-2.12/zinc/inc_compile_2.12.zip
$ absent target/scala-2.12/test-classes/MyTest.class
$ absent target/scala-2.12/test-classes/MyTest$.class
$ absent target/scala-2.12/test-zinc/inc_compile_2.12.zip
> pullRemoteCache
# Files extracted from the cache artifacts
$ exists target/custom-artifact-gen/HelloWorld.scala
$ exists target/scala-2.12/classes/HelloWorld.class
$ exists target/scala-2.12/classes/MyClass.class
$ exists target/scala-2.12/classes/MyClass$.class
$ exists target/scala-2.12/zinc/inc_compile_2.12.zip
$ exists target/scala-2.12/test-classes/MyTest.class
$ exists target/scala-2.12/test-classes/MyTest$.class
$ exists target/scala-2.12/test-zinc/inc_compile_2.12.zip
# Artifacts can be pushed twice (enabled overriding)
> pushRemoteCache