mirror of https://github.com/sbt/sbt.git
Added support for providing basic SCM info
Sonatype OSS repo (where many libraries are expected to migrate) requires
populating SCM info in additional to what is already provisioned for
populating in SBT.
We now support populating the basic SCM info as thus:
```
// Usual <scm><url/><connection/></scm>
scmInfo := Some(ScmInfo(url("https://github.com/foo/project"), "scm
https://github.com/foo/project.git"))
// Also add <developerConnection/>
scmInfo := Some(ScmInfo(url("https://github.com/foo/project"), "scm
https://github.com/foo/project.git", Some("dev_connection")))
```
For anything more esoteric than the basic info, there is always `pomPostProcess` :)
This commit is contained in:
parent
45eacbad4c
commit
ea08f86520
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -44,6 +44,7 @@ class MakePom(val log: Logger)
|
|||
<name>{moduleInfo.nameFormal}</name>
|
||||
{ makeStartYear(moduleInfo) }
|
||||
{ makeOrganization(moduleInfo) }
|
||||
{ makeScmInfo(moduleInfo) }
|
||||
{ extra }
|
||||
{
|
||||
val deps = depsInConfs(module, configurations)
|
||||
|
|
@ -83,6 +84,21 @@ class MakePom(val log: Logger)
|
|||
}}
|
||||
</organization>
|
||||
}
|
||||
def makeScmInfo(moduleInfo: ModuleInfo): NodeSeq =
|
||||
{
|
||||
moduleInfo.scmInfo match {
|
||||
case Some(s) =>
|
||||
<scm>
|
||||
<url>{s.browseUrl}</url>
|
||||
<connection>{s.connection}</connection>
|
||||
{s.devConnection match {
|
||||
case Some(d) => <developerConnection>{d}</developerConnection>
|
||||
case _ => NodeSeq.Empty
|
||||
}}
|
||||
</scm>
|
||||
case _ => NodeSeq.Empty
|
||||
}
|
||||
}
|
||||
def makeProperties(module: ModuleDescriptor, dependencies: Seq[DependencyDescriptor]): NodeSeq =
|
||||
{
|
||||
val extra = IvySbt.getExtraAttributes(module)
|
||||
|
|
|
|||
|
|
@ -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) }
|
||||
|
|
|
|||
|
|
@ -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.")
|
||||
|
|
|
|||
Loading…
Reference in New Issue