Move ivy.xml generation stuff to lm-coursier

So that it can be re-used from sbt
This commit is contained in:
Alexandre Archambault 2020-05-18 19:42:37 +02:00
parent 6cebc8fe7a
commit 8aa40d1f21
5 changed files with 129 additions and 122 deletions

View File

@ -1,21 +1,13 @@
package coursier.sbtcoursiershared
import java.nio.charset.StandardCharsets.UTF_8
import java.nio.file.Files
package lmcoursier
import lmcoursier.Inputs
import lmcoursier.definitions.{Configuration, Project}
import org.apache.ivy.core.module.id.ModuleRevisionId
import sbt.{Def, Setting, Task, TaskKey}
import sbt.internal.librarymanagement.IvySbt
import sbt.librarymanagement.{CrossVersion, PublishConfiguration}
import scala.collection.JavaConverters._
import scala.xml.{Node, PrefixedAttribute}
object IvyXml {
private[sbtcoursiershared] def rawContent(
def apply(
currentProject: Project,
exclusions: Seq[(String, String)],
shadedConfigOpt: Option[Configuration]
@ -34,38 +26,6 @@ object IvyXml {
}
// These are required for publish to be fine, later on.
private def writeFiles(
currentProject: Project,
exclusions: Seq[(String, String)],
shadedConfigOpt: Option[Configuration],
ivySbt: IvySbt,
log: sbt.util.Logger
): Unit = {
val ivyCacheManager = ivySbt.withIvy(log)(ivy =>
ivy.getResolutionCacheManager
)
val ivyModule = ModuleRevisionId.newInstance(
currentProject.module.organization.value,
currentProject.module.name.value,
currentProject.version,
currentProject.module.attributes.asJava
)
val cacheIvyFile = ivyCacheManager.getResolvedIvyFileInCache(ivyModule)
val cacheIvyPropertiesFile = ivyCacheManager.getResolvedIvyPropertiesInCache(ivyModule)
val content0 = rawContent(currentProject, exclusions, shadedConfigOpt)
cacheIvyFile.getParentFile.mkdirs()
log.info(s"Writing Ivy file $cacheIvyFile")
Files.write(cacheIvyFile.toPath, content0.getBytes(UTF_8))
// Just writing an empty file here... Are these only used?
cacheIvyPropertiesFile.getParentFile.mkdirs()
Files.write(cacheIvyPropertiesFile.toPath, Array.emptyByteArray)
}
private def content(
project0: Project,
exclusions: Seq[(String, String)],
@ -168,53 +128,4 @@ object IvyXml {
</ivy-module>
}
private def makeIvyXmlBefore[T](
task: TaskKey[T],
shadedConfigOpt: Option[Configuration]
): Setting[Task[T]] =
task := task.dependsOn {
Def.taskDyn {
import SbtCoursierShared.autoImport._
val doGen = coursierGenerateIvyXml.value
if (doGen)
Def.task {
val sv = sbt.Keys.scalaVersion.value
val sbv = sbt.Keys.scalaBinaryVersion.value
val log = sbt.Keys.streams.value.log
val currentProject = {
val proj = coursierProject.value
val publications = coursierPublications.value
proj.withPublications(publications)
}
val excludeDeps = Inputs.exclusionsSeq(InputsTasks.actualExcludeDependencies.value, sv, sbv, log)
.map {
case (org, name) =>
(org.value, name.value)
}
writeFiles(currentProject, excludeDeps, shadedConfigOpt, sbt.Keys.ivySbt.value, log)
}
else
Def.task(())
}
}.value
private lazy val needsIvyXmlLocal = Seq(sbt.Keys.publishLocalConfiguration) ++ getPubConf("makeIvyXmlLocalConfiguration")
private lazy val needsIvyXml = Seq(sbt.Keys.publishConfiguration) ++ getPubConf("makeIvyXmlConfiguration")
private[this] def getPubConf(method: String): List[TaskKey[PublishConfiguration]] =
try {
val cls = sbt.Keys.getClass
val m = cls.getMethod(method)
val task = m.invoke(sbt.Keys).asInstanceOf[TaskKey[PublishConfiguration]]
List(task)
} catch {
case _: Throwable => // FIXME Too wide
Nil
}
def generateIvyXmlSettings(
shadedConfigOpt: Option[Configuration] = None
): Seq[Setting[_]] =
(needsIvyXml ++ needsIvyXmlLocal).map(makeIvyXmlBefore(_, shadedConfigOpt))
}

View File

@ -0,0 +1,27 @@
package lmcoursier
import lmcoursier.definitions.{Configuration, Info, Module, ModuleName, Organization, Project}
import org.scalatest.{Matchers, PropSpec}
object IvyXmlTests extends PropSpec with Matchers {
property("no truncation") {
val project = Project(
Module(Organization("org"), ModuleName("name"), Map()),
"ver",
Nil,
Map(
Configuration("foo") -> (1 to 80).map(n => Configuration("bar" + n)) // long list of configurations -> no truncation any way
),
Nil,
None,
Nil,
Info("", "", Nil, Nil, None)
)
val content = IvyXml(project, Nil, None)
assert(!content.contains("</conf>"))
}
}

View File

@ -0,0 +1,99 @@
package coursier.sbtcoursiershared
import java.nio.charset.StandardCharsets.UTF_8
import java.nio.file.Files
import lmcoursier.{Inputs, IvyXml}
import lmcoursier.definitions.{Configuration, Project}
import org.apache.ivy.core.module.id.ModuleRevisionId
import sbt.{Def, Setting, Task, TaskKey}
import sbt.internal.librarymanagement.IvySbt
import sbt.librarymanagement.{CrossVersion, PublishConfiguration}
import scala.collection.JavaConverters._
object IvyXmlGeneration {
// These are required for publish to be fine, later on.
private def writeFiles(
currentProject: Project,
exclusions: Seq[(String, String)],
shadedConfigOpt: Option[Configuration],
ivySbt: IvySbt,
log: sbt.util.Logger
): Unit = {
val ivyCacheManager = ivySbt.withIvy(log)(ivy =>
ivy.getResolutionCacheManager
)
val ivyModule = ModuleRevisionId.newInstance(
currentProject.module.organization.value,
currentProject.module.name.value,
currentProject.version,
currentProject.module.attributes.asJava
)
val cacheIvyFile = ivyCacheManager.getResolvedIvyFileInCache(ivyModule)
val cacheIvyPropertiesFile = ivyCacheManager.getResolvedIvyPropertiesInCache(ivyModule)
val content0 = IvyXml(currentProject, exclusions, shadedConfigOpt)
cacheIvyFile.getParentFile.mkdirs()
log.info(s"Writing Ivy file $cacheIvyFile")
Files.write(cacheIvyFile.toPath, content0.getBytes(UTF_8))
// Just writing an empty file here... Are these only used?
cacheIvyPropertiesFile.getParentFile.mkdirs()
Files.write(cacheIvyPropertiesFile.toPath, Array.emptyByteArray)
}
private def makeIvyXmlBefore[T](
task: TaskKey[T],
shadedConfigOpt: Option[Configuration]
): Setting[Task[T]] =
task := task.dependsOn {
Def.taskDyn {
import SbtCoursierShared.autoImport._
val doGen = coursierGenerateIvyXml.value
if (doGen)
Def.task {
val sv = sbt.Keys.scalaVersion.value
val sbv = sbt.Keys.scalaBinaryVersion.value
val log = sbt.Keys.streams.value.log
val currentProject = {
val proj = coursierProject.value
val publications = coursierPublications.value
proj.withPublications(publications)
}
val excludeDeps = Inputs.exclusionsSeq(InputsTasks.actualExcludeDependencies.value, sv, sbv, log)
.map {
case (org, name) =>
(org.value, name.value)
}
writeFiles(currentProject, excludeDeps, shadedConfigOpt, sbt.Keys.ivySbt.value, log)
}
else
Def.task(())
}
}.value
private lazy val needsIvyXmlLocal = Seq(sbt.Keys.publishLocalConfiguration) ++ getPubConf("makeIvyXmlLocalConfiguration")
private lazy val needsIvyXml = Seq(sbt.Keys.publishConfiguration) ++ getPubConf("makeIvyXmlConfiguration")
private[this] def getPubConf(method: String): List[TaskKey[PublishConfiguration]] =
try {
val cls = sbt.Keys.getClass
val m = cls.getMethod(method)
val task = m.invoke(sbt.Keys).asInstanceOf[TaskKey[PublishConfiguration]]
List(task)
} catch {
case _: Throwable => // FIXME Too wide
Nil
}
def generateIvyXmlSettings(
shadedConfigOpt: Option[Configuration] = None
): Seq[Setting[_]] =
(needsIvyXml ++ needsIvyXmlLocal).map(makeIvyXmlBefore(_, shadedConfigOpt))
}

View File

@ -174,7 +174,7 @@ object SbtCoursierShared extends AutoPlugin {
versionReconciliation := Seq.empty
) ++ {
if (pubSettings)
IvyXml.generateIvyXmlSettings()
IvyXmlGeneration.generateIvyXmlSettings()
else
Nil
}

View File

@ -1,30 +0,0 @@
package coursier.sbtcoursiershared
import lmcoursier.definitions.{Configuration, Info, Module, ModuleName, Organization, Project}
import utest._
object IvyXmlTests extends TestSuite {
val tests = Tests {
"no truncation" - {
val project = Project(
Module(Organization("org"), ModuleName("name"), Map()),
"ver",
Nil,
Map(
Configuration("foo") -> (1 to 80).map(n => Configuration("bar" + n)) // long list of configurations -> no truncation any way
),
Nil,
None,
Nil,
Info("", "", Nil, Nil, None)
)
val content = IvyXml.rawContent(project, Nil, None)
assert(!content.contains("</conf>"))
}
}
}