Updates to Ivy component and getting launcher component working.

This commit is contained in:
Mark Harrah 2009-09-08 23:13:30 -04:00
parent 1fedab85be
commit b6b7fe2f9b
3 changed files with 87 additions and 54 deletions

View File

@ -80,21 +80,24 @@ final class IvySbt(configuration: IvyConfiguration)
def withModule[T](f: (Ivy,DefaultModuleDescriptor,String) => T): T =
withIvy[T] { ivy => f(ivy, moduleDescriptor, defaultConfig) }
import moduleConfiguration._
private lazy val (moduleDescriptor: DefaultModuleDescriptor, defaultConfig: String) =
{
val (baseModule, baseConfiguration) =
if(isUnconfigured)
autodetectDependencies(IvySbt.toID(module))
else
configureModule
ivyScala.foreach(IvyScala.checkModule(baseModule, baseConfiguration))
baseModule.getExtraAttributesNamespaces.asInstanceOf[java.util.Map[String,String]].put("m", "m")
moduleConfiguration match
{
case ic: InlineConfiguration => configureInline(ic)
case ec: EmptyConfiguration => configureEmpty(ec.module)
case pc: PomConfiguration => readPom(pc.file, pc.validate)
case ifc: IvyFileConfiguration => readIvyFile(ifc.file, ifc.validate)
}
moduleConfiguration.ivyScala.foreach(IvyScala.checkModule(baseModule, baseConfiguration))
baseModule.getExtraAttributesNamespaces.asInstanceOf[java.util.Map[String,String]].put("e", "http://ant.apache.org/ivy/extra")
(baseModule, baseConfiguration)
}
private def configureModule =
private def configureInline(ic: InlineConfiguration) =
{
val moduleID = newConfiguredModuleID
import ic._
val moduleID = newConfiguredModuleID(module, configurations)
val defaultConf = defaultConfiguration getOrElse Configurations.config(ModuleDescriptor.DEFAULT_CONFIGURATION)
log.debug("Using inline dependencies specified in Scala" + (if(ivyXML.isEmpty) "." else " and XML."))
@ -105,7 +108,7 @@ final class IvySbt(configuration: IvyConfiguration)
IvySbt.addMainArtifact(moduleID)
(moduleID, parser.getDefaultConf)
}
private def newConfiguredModuleID =
private def newConfiguredModuleID(module: ModuleID, configurations: Iterable[Configuration]) =
{
val mod = new DefaultModuleDescriptor(IvySbt.toID(module), "release", null, false)
mod.setLastModified(System.currentTimeMillis)
@ -114,13 +117,13 @@ final class IvySbt(configuration: IvyConfiguration)
}
/** Parses the given Maven pom 'pomFile'.*/
private def readPom(pomFile: File) =
private def readPom(pomFile: File, validate: Boolean) =
{
val md = PomModuleDescriptorParser.getInstance.parseDescriptor(settings, toURL(pomFile), validate)
(IvySbt.toDefaultModuleDescriptor(md), "compile")
}
/** Parses the given Ivy file 'ivyFile'.*/
private def readIvyFile(ivyFile: File) =
private def readIvyFile(ivyFile: File, validate: Boolean) =
{
val url = toURL(ivyFile)
val parser = new CustomXmlParser.CustomParser(settings)
@ -131,30 +134,14 @@ final class IvySbt(configuration: IvyConfiguration)
(IvySbt.toDefaultModuleDescriptor(md), parser.getDefaultConf)
}
private def toURL(file: File) = file.toURI.toURL
/** Called to determine dependencies when the dependency manager is SbtManager and no inline dependencies (Scala or XML)
* are defined. It will try to read from pom.xml first and then ivy.xml if pom.xml is not found. If neither is found,
* Ivy is configured with defaults.*/
private def autodetectDependencies(module: ModuleRevisionId) =
private def configureEmpty(module: ModuleID) =
{
log.debug("Autodetecting dependencies.")
val defaultPOMFile = IvySbt.defaultPOM(paths.baseDirectory)
if(defaultPOMFile.canRead)
readPom(defaultPOMFile)
else
{
val defaultIvy = IvySbt.defaultIvyFile(paths.baseDirectory)
if(defaultIvy.canRead)
readIvyFile(defaultIvy)
else
{
val defaultConf = ModuleDescriptor.DEFAULT_CONFIGURATION
log.warn("No dependency configuration found, using defaults.")
val moduleID = DefaultModuleDescriptor.newDefaultInstance(module)
IvySbt.addMainArtifact(moduleID)
IvySbt.addDefaultArtifact(defaultConf, moduleID)
(moduleID, defaultConf)
}
}
val defaultConf = ModuleDescriptor.DEFAULT_CONFIGURATION
val moduleID = new DefaultModuleDescriptor(IvySbt.toID(module), "release", null, false)
moduleID.setLastModified(System.currentTimeMillis)
moduleID.addConfiguration(IvySbt.toIvyConfiguration(Configurations.Default))
IvySbt.addMainArtifact(moduleID)
(moduleID, defaultConf)
}
}
}
@ -165,9 +152,9 @@ private object IvySbt
val DefaultIvyFilename = "ivy.xml"
val DefaultMavenFilename = "pom.xml"
private def defaultIvyFile(project: File) = new File(project, DefaultIvyFilename)
private def defaultIvyConfiguration(project: File) = new File(project, DefaultIvyConfigFilename)
private def defaultPOM(project: File) = new File(project, DefaultMavenFilename)
def defaultIvyFile(project: File) = new File(project, DefaultIvyFilename)
def defaultIvyConfiguration(project: File) = new File(project, DefaultIvyConfigFilename)
def defaultPOM(project: File) = new File(project, DefaultMavenFilename)
/** Sets the resolvers for 'settings' to 'resolvers'. This is done by creating a new chain and making it the default. */
private def setResolvers(settings: IvySettings, resolvers: Seq[Resolver], log: IvyLogger)
@ -190,7 +177,7 @@ private object IvySbt
manager.setChangingPattern(".*-SNAPSHOT");
settings.setDefaultRepositoryCacheManager(manager)
}
private def toIvyConfiguration(configuration: Configuration) =
def toIvyConfiguration(configuration: Configuration) =
{
import org.apache.ivy.core.module.descriptor.{Configuration => IvyConfig}
import IvyConfig.Visibility._
@ -207,10 +194,10 @@ private object IvySbt
moduleID.check()
}
/** Converts the given sbt module id into an Ivy ModuleRevisionId.*/
private[xsbt] def toID(m: ModuleID) =
def toID(m: ModuleID) =
{
import m._
ModuleRevisionId.newInstance(organization, name, revision)
ModuleRevisionId.newInstance(organization, name, revision, javaMap(extraAttributes))
}
private def toIvyArtifact(moduleID: ModuleDescriptor, a: Artifact, configurations: Iterable[String]): MDArtifact =
{
@ -218,7 +205,19 @@ private object IvySbt
configurations.foreach(artifact.addConfiguration)
artifact
}
private def extra(artifact: Artifact) = artifact.classifier.map(c => javaMap("m:classifier" -> c)).getOrElse(null)
private def extra(artifact: Artifact) =
{
val ea = artifact.classifier match { case Some(c) => artifact.extra("e:classifier" -> c); case None => artifact }
javaMap(artifact.extraAttributes)
}
private def javaMap(map: Map[String,String]) =
if(map.isEmpty) null
else
{
val wrap = scala.collection.jcl.Map(new java.util.HashMap[String,String])
wrap ++= map
wrap.underlying
}
private object javaMap
{

View File

@ -9,17 +9,21 @@ import scala.xml.NodeSeq
final class IvyPaths(val baseDirectory: File, val cacheDirectory: Option[File]) extends NotNull
final class IvyConfiguration(val paths: IvyPaths, val resolvers: Seq[Resolver], val log: IvyLogger) extends NotNull
final class ModuleConfiguration(val module: ModuleID, val dependencies: Iterable[ModuleID], val ivyXML: NodeSeq,
val configurations: Iterable[Configuration], val defaultConfiguration: Option[Configuration], val ivyScala: Option[IvyScala],
val artifacts: Iterable[Artifact], val validate: Boolean) extends NotNull
sealed trait ModuleConfiguration extends NotNull
{
def isUnconfigured = dependencies.isEmpty && ivyXML.isEmpty && configurations.isEmpty &&
defaultConfiguration.isEmpty && artifacts.isEmpty
def validate: Boolean
def ivyScala: Option[IvyScala]
}
object ModuleConfiguration
final class IvyFileConfiguration(val file: File, val ivyScala: Option[IvyScala], val validate: Boolean) extends ModuleConfiguration
final class PomConfiguration(val file: File, val ivyScala: Option[IvyScala], val validate: Boolean) extends ModuleConfiguration
final class InlineConfiguration(val module: ModuleID, val dependencies: Iterable[ModuleID], val ivyXML: NodeSeq,
val configurations: Iterable[Configuration], val defaultConfiguration: Option[Configuration], val ivyScala: Option[IvyScala],
val artifacts: Iterable[Artifact], val validate: Boolean) extends ModuleConfiguration
final class EmptyConfiguration(val module: ModuleID, val ivyScala: Option[IvyScala], val validate: Boolean) extends ModuleConfiguration
object InlineConfiguration
{
def apply(module: ModuleID, dependencies: Iterable[ModuleID], artifacts: Iterable[Artifact]) =
new ModuleConfiguration(module, dependencies, NodeSeq.Empty, Nil, None, None, artifacts, false)
new InlineConfiguration(module, dependencies, NodeSeq.Empty, Nil, None, None, artifacts, false)
def configurations(explicitConfigurations: Iterable[Configuration], defaultConfiguration: Option[Configuration]) =
if(explicitConfigurations.isEmpty)
{
@ -32,4 +36,25 @@ object ModuleConfiguration
}
else
explicitConfigurations
}
object ModuleConfiguration
{
def apply(ivyScala: Option[IvyScala], validate: Boolean, module: => ModuleID)(baseDirectory: File, log: IvyLogger) =
{
log.debug("Autodetecting dependencies.")
val defaultPOMFile = IvySbt.defaultPOM(baseDirectory)
if(defaultPOMFile.canRead)
new PomConfiguration(defaultPOMFile, ivyScala, validate)
else
{
val defaultIvy = IvySbt.defaultIvyFile(baseDirectory)
if(defaultIvy.canRead)
new IvyFileConfiguration(defaultIvy, ivyScala, validate)
else
{
log.warn("No dependency configuration found, using defaults.")
new EmptyConfiguration(module, ivyScala, validate)
}
}
}
}

View File

@ -9,16 +9,17 @@ import scala.xml.NodeSeq
import org.apache.ivy.plugins.resolver.IBiblioResolver
import org.apache.ivy.util.url.CredentialsStore
final case class ModuleID(organization: String, name: String, revision: String, configurations: Option[String], isChanging: Boolean, isTransitive: Boolean, explicitArtifacts: Seq[Artifact]) extends NotNull
final case class ModuleID(organization: String, name: String, revision: String, configurations: Option[String], isChanging: Boolean, isTransitive: Boolean, explicitArtifacts: Seq[Artifact], extraAttributes: Map[String,String]) extends NotNull
{
override def toString = organization + ":" + name + ":" + revision
// () required for chaining
def notTransitive() = intransitive()
def intransitive() = ModuleID(organization, name, revision, configurations, isChanging, false, explicitArtifacts)
def changing() = ModuleID(organization, name, revision, configurations, true, isTransitive, explicitArtifacts)
def intransitive() = ModuleID(organization, name, revision, configurations, isChanging, false, explicitArtifacts, extraAttributes)
def changing() = ModuleID(organization, name, revision, configurations, true, isTransitive, explicitArtifacts, extraAttributes)
def from(url: String) = artifacts(Artifact(name, new URL(url)))
def classifier(c: String) = artifacts(Artifact(name, c))
def artifacts(newArtifacts: Artifact*) = ModuleID(organization, name, revision, configurations, isChanging, isTransitive, newArtifacts ++ explicitArtifacts)
def artifacts(newArtifacts: Artifact*) = ModuleID(organization, name, revision, configurations, isChanging, isTransitive, newArtifacts ++ explicitArtifacts, extraAttributes)
def extra(attributes: (String,String)*) = ModuleID(organization, name, revision, configurations, isChanging, isTransitive, explicitArtifacts, extraAttributes ++ attributes)
}
object ModuleID
{
@ -27,6 +28,8 @@ object ModuleID
ModuleID(organization, name, revision, configurations, false, true)
def apply(organization: String, name: String, revision: String, configurations: Option[String], isChanging: Boolean, isTransitive: Boolean): ModuleID =
ModuleID(organization, name, revision, configurations, isChanging, isTransitive, Nil)
def apply(organization: String, name: String, revision: String, configurations: Option[String], isChanging: Boolean, isTransitive: Boolean, explicitArtifacts: Seq[Artifact]): ModuleID =
ModuleID(organization, name, revision, configurations, isChanging, isTransitive, explicitArtifacts, Map.empty)
}
sealed trait Resolver extends NotNull
{
@ -302,13 +305,19 @@ final case class Configuration(name: String, description: String, isPublic: Bool
override def toString = name
}
final case class Artifact(name: String, `type`: String, extension: String, classifier: Option[String], configurations: Iterable[Configuration], url: Option[URL]) extends NotNull
final case class Artifact(name: String, `type`: String, extension: String, classifier: Option[String], configurations: Iterable[Configuration], url: Option[URL], extraAttributes: Map[String,String]) extends NotNull
{
def extra(attributes: (String,String)*) = Artifact(name, `type`, extension, classifier, configurations, url, extraAttributes ++ attributes)
}
object Artifact
{
def apply(name: String): Artifact = Artifact(name, defaultType, defaultExtension, None, Nil, None)
def apply(name: String, extra: Map[String,String]): Artifact = Artifact(name, defaultType, defaultExtension, None, Nil, None, extra)
def apply(name: String, classifier: String): Artifact = Artifact(name, defaultType, defaultExtension, Some(classifier), Nil, None)
def apply(name: String, `type`: String, extension: String): Artifact = Artifact(name, `type`, extension, None, Nil, None)
def apply(name: String, url: URL): Artifact =Artifact(name, extract(url, defaultType), extract(url, defaultExtension), None, Nil, Some(url))
def apply(name: String, `type`: String, extension: String, classifier: Option[String], configurations: Iterable[Configuration], url: Option[URL]): Artifact =
Artifact(name, `type`, extension, classifier, configurations, url, Map.empty)
val defaultExtension = "jar"
val defaultType = "jar"
def extract(url: URL, default: String): String = extract(url.toString, default)