mirror of https://github.com/sbt/sbt.git
Use custom pom generation instead of Ivy's built-in generation in order to support extra information like licenses.
This commit is contained in:
parent
e747bb2b1c
commit
3b67efa0d4
|
|
@ -1,6 +1,7 @@
|
|||
package sbt
|
||||
|
||||
import java.io.File
|
||||
import scala.xml.NodeSeq
|
||||
|
||||
import org.apache.ivy.{core, plugins, util, Ivy}
|
||||
import core.cache.DefaultRepositoryCacheManager
|
||||
|
|
@ -35,15 +36,18 @@ object IvyActions
|
|||
}
|
||||
|
||||
/** Clears the Ivy cache, as configured by 'config'. */
|
||||
def cleanCache(ivy: IvySbt) = ivy.withIvy { _.getSettings.getRepositoryCacheManagers.foreach(_.clean()) }
|
||||
def cleanCache(ivy: IvySbt) = ivy.withIvy { iv =>
|
||||
iv.getSettings.getResolutionCacheManager.clean()
|
||||
iv.getSettings.getRepositoryCacheManagers.foreach(_.clean())
|
||||
}
|
||||
|
||||
/** Creates a Maven pom from the given Ivy configuration*/
|
||||
def makePom(module: IvySbt#Module, extraDependencies: Iterable[ModuleID], configurations: Option[Iterable[Configuration]], output: File)
|
||||
def makePom(module: IvySbt#Module, extraDependencies: Iterable[ModuleID], configurations: Option[Iterable[Configuration]], extra: NodeSeq, output: File)
|
||||
{
|
||||
module.withModule { (ivy, md, default) =>
|
||||
addLateDependencies(ivy, md, default, extraDependencies)
|
||||
val pomModule = keepConfigurations(md, configurations)
|
||||
PomModuleDescriptorWriter.write(pomModule, DefaultConfigurationMapping, output)
|
||||
(new PomWriter).write(pomModule, extra, output)
|
||||
module.logger.info("Wrote " + output.getAbsolutePath)
|
||||
}
|
||||
}
|
||||
|
|
@ -132,21 +136,4 @@ object IvyActions
|
|||
if(resolveReport.hasError)
|
||||
error(Set(resolveReport.getAllProblemMessages.toArray: _*).mkString("\n"))
|
||||
}
|
||||
}
|
||||
|
||||
private object DefaultConfigurationMapping extends PomModuleDescriptorWriter.ConfigurationScopeMapping(new java.util.HashMap)
|
||||
{
|
||||
override def getScope(confs: Array[String]) =
|
||||
{
|
||||
Configurations.defaultMavenConfigurations.find(conf => confs.contains(conf.name)) match
|
||||
{
|
||||
case Some(conf) => conf.name
|
||||
case None =>
|
||||
if(confs.isEmpty || confs(0) == Configurations.Default.name)
|
||||
null
|
||||
else
|
||||
confs(0)
|
||||
}
|
||||
}
|
||||
override def isOptional(confs: Array[String]) = confs.isEmpty || (confs.length == 1 && confs(0) == Configurations.Optional.name)
|
||||
}
|
||||
|
|
@ -81,7 +81,7 @@ object IvyCache
|
|||
/** A minimal Ivy setup with only a local resolver and the current directory as the base directory.*/
|
||||
private def basicLocalIvy(lock: Option[xsbti.GlobalLock], log: IvyLogger) =
|
||||
{
|
||||
val local = Resolver.defaultLocal
|
||||
val local = Resolver.defaultLocal(None)
|
||||
val paths = new IvyPaths(new File("."), None)
|
||||
val conf = new InlineIvyConfiguration(paths, Seq(local), Nil, lock, log)
|
||||
(new IvySbt(conf), local)
|
||||
|
|
|
|||
|
|
@ -7,19 +7,29 @@ import java.io.File
|
|||
import scala.xml.NodeSeq
|
||||
|
||||
final class IvyPaths(val baseDirectory: File, val cacheDirectory: Option[File]) extends NotNull
|
||||
|
||||
{
|
||||
def withBase(newBaseDirectory: File) = new IvyPaths(newBaseDirectory, cacheDirectory)
|
||||
}
|
||||
sealed trait IvyConfiguration extends NotNull
|
||||
{
|
||||
type This <: IvyConfiguration
|
||||
def lock: Option[xsbti.GlobalLock]
|
||||
def baseDirectory: File
|
||||
def log: IvyLogger
|
||||
def withBase(newBaseDirectory: File): This
|
||||
}
|
||||
final class InlineIvyConfiguration(val paths: IvyPaths, val resolvers: Seq[Resolver],
|
||||
val moduleConfigurations: Seq[ModuleConfiguration], val lock: Option[xsbti.GlobalLock], val log: IvyLogger) extends IvyConfiguration
|
||||
{
|
||||
type This = InlineIvyConfiguration
|
||||
def baseDirectory = paths.baseDirectory
|
||||
def withBase(newBase: File) = new InlineIvyConfiguration(paths.withBase(newBase), resolvers, moduleConfigurations, lock, log)
|
||||
}
|
||||
final class ExternalIvyConfiguration(val baseDirectory: File, val file: File, val lock: Option[xsbti.GlobalLock], val log: IvyLogger) extends IvyConfiguration
|
||||
{
|
||||
type This = ExternalIvyConfiguration
|
||||
def withBase(newBase: File) = new ExternalIvyConfiguration(newBase, file, lock, log)
|
||||
}
|
||||
|
||||
object IvyConfiguration
|
||||
{
|
||||
|
|
|
|||
|
|
@ -167,7 +167,7 @@ object Resolver
|
|||
def withDefaultResolvers(userResolvers: Seq[Resolver], scalaTools: Boolean): Seq[Resolver] =
|
||||
withDefaultResolvers(userResolvers, true, scalaTools)
|
||||
def withDefaultResolvers(userResolvers: Seq[Resolver], mavenCentral: Boolean, scalaTools: Boolean): Seq[Resolver] =
|
||||
Seq(Resolver.defaultLocal) ++
|
||||
Seq(Resolver.defaultLocal(None)) ++
|
||||
userResolvers ++
|
||||
single(DefaultMavenRepository, mavenCentral)++
|
||||
single(ScalaToolsReleases, scalaTools)
|
||||
|
|
@ -266,10 +266,11 @@ object Resolver
|
|||
def userRoot = System.getProperty("user.home")
|
||||
def userMavenRoot = userRoot + "/.m2/repository/"
|
||||
def userIvyRoot = userRoot + "/.ivy2/"
|
||||
private def userIvyRootFile = new File(userIvyRoot)
|
||||
|
||||
def defaultLocal = defaultUserFileRepository("local")
|
||||
def defaultShared = defaultUserFileRepository("shared")
|
||||
def defaultUserFileRepository(id: String) = file(id, new File(userIvyRoot, id))(defaultIvyPatterns)
|
||||
def defaultLocal(ivyHome: Option[File]) = defaultUserFileRepository(ivyHome, "local")
|
||||
def defaultShared(ivyHome: Option[File]) = defaultUserFileRepository(ivyHome, "shared")
|
||||
def defaultUserFileRepository(ivyHome: Option[File], id: String) = file(id, new File(ivyHome.getOrElse(userIvyRootFile), id))(defaultIvyPatterns)
|
||||
def defaultIvyPatterns =
|
||||
{
|
||||
val pList = List(localBasePattern)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,104 @@
|
|||
// based on Ivy's PomModuleDescriptorWriter, which is Apache Licensed, Version 2.0
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
package sbt;
|
||||
|
||||
import java.io.{BufferedWriter, File, OutputStreamWriter, FileOutputStream}
|
||||
import scala.xml.{Node, NodeSeq, XML}
|
||||
|
||||
import org.apache.ivy.{core, Ivy}
|
||||
import core.module.{descriptor, id}
|
||||
import descriptor.{DependencyDescriptor, License, ModuleDescriptor}
|
||||
import id.ModuleRevisionId
|
||||
|
||||
class PomWriter
|
||||
{
|
||||
def encoding = "UTF-8"
|
||||
def write(module: ModuleDescriptor, extra: NodeSeq, output: File): Unit = write(toPom(module, extra), output)
|
||||
def write(node: Node, output: File)
|
||||
{
|
||||
output.getParentFile.mkdirs()
|
||||
val out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(output), encoding))
|
||||
try { XML.write(out, node, encoding, true, null) }
|
||||
finally { out.close() }
|
||||
}
|
||||
|
||||
def toPom(module: ModuleDescriptor, extra: NodeSeq): Node =
|
||||
(<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
{ makeModuleID(module) }
|
||||
{ extra }
|
||||
{ makeDependencies(module) }
|
||||
<!--{ makeRepositories(module.ivy) }-->
|
||||
</project>)
|
||||
|
||||
def makeModuleID(module: ModuleDescriptor): NodeSeq =
|
||||
{
|
||||
val mrid = moduleDescriptor(module)
|
||||
val a: NodeSeq =
|
||||
(<groupId>{ mrid.getOrganisation }</groupId>
|
||||
<artifactId>{ mrid.getName }</artifactId>
|
||||
<packaging> { packaging(mrid) }</packaging>)
|
||||
val b: NodeSeq =
|
||||
( (description(module.getDescription) ++
|
||||
homePage(module.getHomePage) ++
|
||||
revision(mrid.getRevision) ++
|
||||
licenses(module.getLicenses)) : NodeSeq )
|
||||
a ++ b
|
||||
}
|
||||
|
||||
def description(d: String) = if((d eq null) || d.isEmpty) NodeSeq.Empty else <description>{d}</description>
|
||||
def licenses(ls: Array[License]) = if(ls == null || ls.isEmpty) NodeSeq.Empty else <licenses>{ls.map(license)}</licenses>
|
||||
def license(l: License) =
|
||||
<license>
|
||||
<name>{l.getName}</name>
|
||||
<url>{l.getUrl}</url>
|
||||
<distribution>jar</distribution>
|
||||
</license>
|
||||
def homePage(homePage: String) = if(homePage eq null) NodeSeq.Empty else <url>{homePage}</url>
|
||||
def revision(version: String) = if(version ne null) <version>{version}</version> else NodeSeq.Empty
|
||||
def packaging(module: ModuleRevisionId) = "jar"//module.getDefaultArtifact.getExt
|
||||
|
||||
def makeDependencies(module: ModuleDescriptor): NodeSeq =
|
||||
{
|
||||
val dependencies = module.getDependencies
|
||||
if(dependencies.isEmpty) NodeSeq.Empty
|
||||
else
|
||||
<dependencies>
|
||||
{ dependencies.map(makeDependency) }
|
||||
</dependencies>
|
||||
}
|
||||
|
||||
def makeDependency(dependency: DependencyDescriptor): NodeSeq =
|
||||
{
|
||||
val mrid = dependency.getDependencyRevisionId
|
||||
<dependency>
|
||||
<groupId>{mrid.getOrganisation}</groupId>
|
||||
<artifactId>{mrid.getName}</artifactId>
|
||||
<version>{mrid.getRevision}</version>
|
||||
{ scope(dependency)}
|
||||
{ optional(dependency) }
|
||||
</dependency>
|
||||
}
|
||||
|
||||
def scope(dependency: DependencyDescriptor): NodeSeq =
|
||||
scope(getScope(dependency.getModuleConfigurations))
|
||||
def scope(scope: String): NodeSeq = if(scope ne null) <scope>{scope}</scope> else NodeSeq.Empty
|
||||
def optional(dependency: DependencyDescriptor) =
|
||||
if(isOptional(dependency.getModuleConfigurations)) <optional>true</optional> else NodeSeq.Empty
|
||||
def moduleDescriptor(module: ModuleDescriptor) = module.getModuleRevisionId
|
||||
|
||||
def getScope(confs: Array[String]) =
|
||||
{
|
||||
Configurations.defaultMavenConfigurations.find(conf => confs.contains(conf.name)) match
|
||||
{
|
||||
case Some(conf) => conf.name
|
||||
case None =>
|
||||
if(confs.isEmpty || confs(0) == Configurations.Default.name)
|
||||
null
|
||||
else
|
||||
confs(0)
|
||||
}
|
||||
}
|
||||
def isOptional(confs: Array[String]) = confs.isEmpty || (confs.length == 1 && confs(0) == Configurations.Optional.name)
|
||||
}
|
||||
Loading…
Reference in New Issue