diff --git a/ivy/IvyInterface.scala b/ivy/IvyInterface.scala index 5b90fd141..be3d2cd3d 100644 --- a/ivy/IvyInterface.scala +++ b/ivy/IvyInterface.scala @@ -17,9 +17,9 @@ final case class ModuleID(organization: String, name: String, revision: String, (if(extraAttributes.isEmpty) "" else " " + extraString) def extraString = extraAttributes.map { case (k,v) => k + "=" + v } mkString("(",", ",")") - @deprecated("Use the variant accepting a CrossVersion value constructed by a member of the CrossVersion object.", "0.12.0") + @deprecated("Use `cross(CrossVersion)`, the variant accepting a CrossVersion value constructed by a member of the CrossVersion object instead.", "0.12.0") def cross(v: Boolean): ModuleID = cross(if(v) CrossVersion.binary else CrossVersion.Disabled) - @deprecated("Use the variant accepting a CrossVersion value constructed by a member of the CrossVersion object.", "0.12.0") + @deprecated("Use `cross(CrossVersion)`, the variant accepting a CrossVersion value constructed by a member of the CrossVersion object instead.", "0.12.0") def cross(v: Boolean, verRemap: String => String): ModuleID = cross(if(v) CrossVersion.binaryMapped(verRemap) else CrossVersion.Disabled) def cross(v: CrossVersion): ModuleID = copy(crossVersion = v) @@ -49,13 +49,15 @@ object ModuleID if(key.startsWith("e:")) (key, value) else ("e:" + key, value) } /** Additional information about a project module */ -case class ModuleInfo(nameFormal: String, description: String = "", homepage: Option[URL] = None, startYear: Option[Int] = None, licenses: Seq[(String, URL)] = Nil, organizationName: String = "", organizationHomepage: Option[URL] = None) +case class ModuleInfo(nameFormal: String, description: String = "", homepage: Option[URL] = None, startYear: Option[Int] = None, licenses: Seq[(String, URL)] = Nil, organizationName: String = "", organizationHomepage: Option[URL] = None, scmInfo: Option[ScmInfo] = None) { def formally(name: String) = copy(nameFormal = name) def describing(desc: String, home: Option[URL]) = copy(description = desc, homepage = home) def licensed(lics: (String, URL)*) = copy(licenses = lics) def organization(name: String, home: Option[URL]) = copy(organizationName = name, organizationHomepage = home) } +/** Basic SCM information for a project module */ +case class ScmInfo(browseUrl: URL, connection: String, devConnection: Option[String] = None) /** Rule to exclude unwanted dependencies pulled in transitively by a module. */ case class ExclusionRule(organization: String = "*", name: String = "*", artifact: String = "*", configurations: Seq[String] = Nil) sealed trait Resolver @@ -428,7 +430,7 @@ object Artifact } def artifactName(scalaVersion: ScalaVersion, module: ModuleID, artifact: Artifact): String = { - import artifact._ + import artifact._ val classifierStr = classifier match { case None => ""; case Some(c) => "-" + c } val cross = CrossVersion(module.crossVersion, scalaVersion.full, scalaVersion.binary) val base = CrossVersion.applyCross(artifact.name, cross) diff --git a/ivy/MakePom.scala b/ivy/MakePom.scala index e2b5f1778..31a83a705 100644 --- a/ivy/MakePom.scala +++ b/ivy/MakePom.scala @@ -44,6 +44,7 @@ class MakePom(val log: Logger) {moduleInfo.nameFormal} { makeStartYear(moduleInfo) } { makeOrganization(moduleInfo) } + { makeScmInfo(moduleInfo) } { extra } { val deps = depsInConfs(module, configurations) @@ -83,6 +84,21 @@ class MakePom(val log: Logger) }} } + def makeScmInfo(moduleInfo: ModuleInfo): NodeSeq = + { + moduleInfo.scmInfo match { + case Some(s) => + + {s.browseUrl} + {s.connection} + {s.devConnection match { + case Some(d) => {d} + case _ => NodeSeq.Empty + }} + + case _ => NodeSeq.Empty + } + } def makeProperties(module: ModuleDescriptor, dependencies: Seq[DependencyDescriptor]): NodeSeq = { val extra = IvySbt.getExtraAttributes(module) diff --git a/main/Defaults.scala b/main/Defaults.scala index 6e07ed6e9..656bfd0b3 100644 --- a/main/Defaults.scala +++ b/main/Defaults.scala @@ -715,7 +715,8 @@ object Classpaths organization <<= organization or normalizedName, organizationName <<= organizationName or organization, organizationHomepage <<= organizationHomepage or homepage, - projectInfo <<= (name, description, homepage, startYear, licenses, organizationName, organizationHomepage) apply ModuleInfo, + scmInfo in GlobalScope :== None, + projectInfo <<= (name, description, homepage, startYear, licenses, organizationName, organizationHomepage, scmInfo) apply ModuleInfo, externalResolvers <<= (externalResolvers.task.?, resolvers) { case (Some(delegated), Seq()) => delegated case (_, rs) => task { Resolver.withDefaultResolvers(rs) } diff --git a/main/Keys.scala b/main/Keys.scala index a0fe26a11..eeed6e3a9 100644 --- a/main/Keys.scala +++ b/main/Keys.scala @@ -197,10 +197,10 @@ object Keys val testListeners = TaskKey[Seq[TestReportListener]]("test-listeners", "Defines test listeners.") val testExecution = TaskKey[Tests.Execution]("test-execution", "Settings controlling test execution") val isModule = AttributeKey[Boolean]("is-module", "True if the target is a module.") - + // Classpath/Dependency Management Keys type Classpath = Seq[Attributed[File]] - + val name = SettingKey[String]("name", "Project name.") val normalizedName = SettingKey[String]("normalized-name", "Project name transformed from mixed case and spaces to lowercase and dash-separated.") val description = SettingKey[String]("description", "Project description.") @@ -210,6 +210,7 @@ object Keys val organization = SettingKey[String]("organization", "Organization/group ID.") val organizationName = SettingKey[String]("organization-name", "Organization full/formal name.") val organizationHomepage = SettingKey[Option[URL]]("organization-homepage", "Organization homepage.") + val scmInfo = SettingKey[Option[ScmInfo]]("scm-info", "Basic SCM information for the project.") val projectInfo = SettingKey[ModuleInfo]("project-info", "Addition project information like formal name, homepage, licenses etc.") val defaultConfiguration = SettingKey[Option[Configuration]]("default-configuration", "Defines the configuration used when none is specified for a dependency.") val defaultConfigurationMapping = SettingKey[String]("default-configuration-mapping", "Defines the mapping used for a simple, unmapped configuration definition.") @@ -225,7 +226,7 @@ object Keys val externalDependencyClasspath = TaskKey[Classpath]("external-dependency-classpath", "The classpath consisting of library dependencies, both managed and unmanaged.") val dependencyClasspath = TaskKey[Classpath]("dependency-classpath", "The classpath consisting of internal and external, managed and unmanaged dependencies.") val fullClasspath = TaskKey[Classpath]("full-classpath", "The exported classpath, consisting of build products and unmanaged and managed, internal and external dependencies.") - + val internalConfigurationMap = SettingKey[Configuration => Configuration]("internal-configuration-map", "Maps configurations to the actual configuration used to define the classpath.") val classpathConfiguration = TaskKey[Configuration]("classpath-configuration", "The configuration used to define the classpath.") val ivyConfiguration = TaskKey[IvyConfiguration]("ivy-configuration", "General dependency management (Ivy) settings, such as the resolvers and paths to use.") @@ -240,7 +241,7 @@ object Keys val updateClassifiers = TaskKey[UpdateReport]("update-classifiers", "Resolves and optionally retrieves classified artifacts, such as javadocs and sources, for dependency definitions, transitively.", update) val transitiveClassifiers = SettingKey[Seq[String]]("transitive-classifiers", "List of classifiers used for transitively obtaining extra artifacts for sbt or declared dependencies.") val updateSbtClassifiers = TaskKey[UpdateReport]("update-sbt-classifiers", "Resolves and optionally retrieves classifiers, such as javadocs and sources, for sbt, transitively.", updateClassifiers) - + val publishConfiguration = TaskKey[PublishConfiguration]("publish-configuration", "Configuration for publishing to a repository.") val publishLocalConfiguration = TaskKey[PublishConfiguration]("publish-local-configuration", "Configuration for publishing to the local repository.") val deliverConfiguration = TaskKey[DeliverConfiguration]("deliver-configuration", "Configuration for generating the finished Ivy file for publishing.")