mirror of https://github.com/sbt/sbt.git
merge 0.13.7 manually
This commit is contained in:
commit
416ffa76d1
|
|
@ -11,8 +11,8 @@ import org.apache.ivy.core
|
|||
import core.resolve._
|
||||
import core.module.id.{ ModuleRevisionId, ModuleId => IvyModuleId }
|
||||
import core.report.{ ResolveReport, ConfigurationResolveReport, DownloadReport }
|
||||
import core.module.descriptor.{ DefaultModuleDescriptor, ModuleDescriptor, DependencyDescriptor, Configuration => IvyConfiguration, ExcludeRule, IncludeRule }
|
||||
import core.module.descriptor.OverrideDependencyDescriptorMediator
|
||||
import core.module.descriptor.{ DefaultModuleDescriptor, ModuleDescriptor, DefaultDependencyDescriptor, DependencyDescriptor, Configuration => IvyConfiguration, ExcludeRule, IncludeRule }
|
||||
import core.module.descriptor.{ OverrideDependencyDescriptorMediator, DependencyArtifactDescriptor, DefaultDependencyArtifactDescriptor }
|
||||
import core.{ IvyPatternHelper, LogOptions }
|
||||
import org.apache.ivy.util.Message
|
||||
import org.apache.ivy.plugins.latest.{ ArtifactInfo => IvyArtifactInfo }
|
||||
|
|
@ -29,46 +29,119 @@ private[sbt] class CachedResolutionResolveCache() {
|
|||
val updateReportCache: concurrent.Map[ModuleRevisionId, Either[ResolveException, UpdateReport]] = concurrent.TrieMap()
|
||||
val resolveReportCache: concurrent.Map[ModuleRevisionId, ResolveReport] = concurrent.TrieMap()
|
||||
val resolvePropertiesCache: concurrent.Map[ModuleRevisionId, String] = concurrent.TrieMap()
|
||||
val directDependencyCache: concurrent.Map[ModuleRevisionId, Vector[DependencyDescriptor]] = concurrent.TrieMap()
|
||||
val conflictCache: concurrent.Map[(ModuleID, ModuleID), (Vector[ModuleID], Vector[ModuleID], String)] = concurrent.TrieMap()
|
||||
val maxConflictCacheSize: Int = 10000
|
||||
|
||||
def clean(md0: ModuleDescriptor, prOpt: Option[ProjectResolver]): Unit = {
|
||||
val mrid0 = md0.getModuleRevisionId
|
||||
val mds =
|
||||
if (mrid0.getOrganisation == sbtOrgTemp) Vector(md0)
|
||||
else buildArtificialModuleDescriptors(md0, prOpt) map { _._1 }
|
||||
|
||||
updateReportCache.remove(md0.getModuleRevisionId)
|
||||
directDependencyCache.remove(md0.getModuleRevisionId)
|
||||
mds foreach { md =>
|
||||
updateReportCache.remove(md.getModuleRevisionId)
|
||||
directDependencyCache.remove(md.getModuleRevisionId)
|
||||
}
|
||||
updateReportCache.clear
|
||||
}
|
||||
def directDependencies(md0: ModuleDescriptor): Vector[DependencyDescriptor] =
|
||||
directDependencyCache.getOrElseUpdate(md0.getModuleRevisionId, md0.getDependencies.toVector)
|
||||
|
||||
def buildArtificialModuleDescriptors(md0: ModuleDescriptor, prOpt: Option[ProjectResolver]): Vector[(DefaultModuleDescriptor, Boolean)] =
|
||||
md0.getDependencies.toVector
|
||||
def buildArtificialModuleDescriptors(md0: ModuleDescriptor, data: ResolveData, prOpt: Option[ProjectResolver], log: Logger): Vector[(DefaultModuleDescriptor, Boolean)] =
|
||||
{
|
||||
def expandInternalDeps(dep: DependencyDescriptor): Vector[DependencyDescriptor] =
|
||||
prOpt map {
|
||||
_.getModuleDescriptor(dep.getDependencyRevisionId) match {
|
||||
case Some(internal) => directDependencies(internal) flatMap expandInternalDeps
|
||||
case _ => Vector(dep)
|
||||
}
|
||||
} getOrElse Vector(dep)
|
||||
val expanded = directDependencies(md0) flatMap expandInternalDeps
|
||||
val rootModuleConfigs = md0.getConfigurations.toVector
|
||||
expanded map { buildArtificialModuleDescriptor(_, rootModuleConfigs, md0, prOpt) }
|
||||
log.debug(s":: building artificial module descriptors from ${md0.getModuleRevisionId}")
|
||||
val expanded = expandInternalDependencies(md0, data, prOpt, log)
|
||||
val rootModuleConfigs = md0.getConfigurations.toArray.toVector
|
||||
expanded map { dd =>
|
||||
val arts = dd.getAllDependencyArtifacts.toVector map { x => s"""${x.getName}:${x.getType}:${x.getExt}:${x.getExtraAttributes}""" }
|
||||
log.debug(s"::: expanded dd: $dd (artifacts: ${arts.mkString(",")})")
|
||||
buildArtificialModuleDescriptor(dd, rootModuleConfigs, md0, prOpt, log)
|
||||
}
|
||||
}
|
||||
|
||||
def buildArtificialModuleDescriptor(dd: DependencyDescriptor, rootModuleConfigs: Vector[IvyConfiguration], parent: ModuleDescriptor, prOpt: Option[ProjectResolver]): (DefaultModuleDescriptor, Boolean) =
|
||||
// This expands out all internal dependencies and merge them into a single graph that consists
|
||||
// only of external dependencies.
|
||||
// The tricky part is the merger of configurations, even though in most cases we will only see compile->compile when it comes to internal deps.
|
||||
// Theoretically, there could be a potential for test->test->runtime kind of situation. nextConfMap and remapConfigurations track
|
||||
// the configuration chains transitively.
|
||||
def expandInternalDependencies(md0: ModuleDescriptor, data: ResolveData, prOpt: Option[ProjectResolver], log: Logger): Vector[DependencyDescriptor] =
|
||||
{
|
||||
log.debug(s"::: expanding internal dependencies of module descriptor ${md0.getModuleRevisionId}")
|
||||
val rootModuleConfigs = md0.getConfigurations.toArray.toVector
|
||||
val rootNode = new IvyNode(data, md0)
|
||||
def expandInternalDeps(dep: DependencyDescriptor, confMap: Map[String, Array[String]]): Vector[DependencyDescriptor] =
|
||||
internalDependency(dep) match {
|
||||
case Some(internal) =>
|
||||
log.debug(s""":::: found internal dependency ${internal.getResolvedModuleRevisionId}""")
|
||||
val allConfigurations: Vector[String] = confMap.values.flatten.toVector.distinct
|
||||
val next = nextConfMap(dep, confMap)
|
||||
// direct dependencies of an internal dependency
|
||||
val directs0 = directDependencies(internal)
|
||||
val directs = directs0 filter { dd =>
|
||||
allConfigurations exists { conf => !dd.getDependencyConfigurations(conf).isEmpty }
|
||||
}
|
||||
directs flatMap { dd => expandInternalDeps(dd, next) }
|
||||
case _ =>
|
||||
Vector(remapConfigurations(dep, confMap, log))
|
||||
}
|
||||
def internalDependency(dep: DependencyDescriptor): Option[ModuleDescriptor] =
|
||||
prOpt match {
|
||||
case Some(pr) => pr.getModuleDescriptor(dep.getDependencyRevisionId)
|
||||
case _ => None
|
||||
}
|
||||
// This creates confMap. The key of the map is rootModuleConf for md0, the value is the dependency configs for dd.
|
||||
def nextConfMap(dd: DependencyDescriptor, previous: Map[String, Array[String]]): Map[String, Array[String]] =
|
||||
previous map {
|
||||
case (rootModuleConf, vs) =>
|
||||
rootModuleConf -> (vs flatMap { conf =>
|
||||
dd.getDependencyConfigurations(conf) flatMap { confName =>
|
||||
if (confName == "*") Array(confName)
|
||||
else rootNode.getRealConfs(confName)
|
||||
}
|
||||
})
|
||||
}
|
||||
// The key of the confMap is rootModuleConf for md0, and the values are modules configuratons of dd0.
|
||||
// For example if project Root depends on project B % "test", and project B depends on junit,
|
||||
// confMap should contain Map("test", Array("compile")).
|
||||
// This remaps junit dependency as junit % "test".
|
||||
def remapConfigurations(dd0: DependencyDescriptor, confMap: Map[String, Array[String]], log: Logger): DependencyDescriptor =
|
||||
{
|
||||
log.debug(s""":::: remapping configuration of ${dd0} with ${confMap.toList map { case (k, v) => (k, v.toList) }}""")
|
||||
val dd = new DefaultDependencyDescriptor(md0, dd0.getDependencyRevisionId, dd0.getDynamicConstraintDependencyRevisionId,
|
||||
dd0.isForce, dd0.isChanging, dd0.isTransitive)
|
||||
val moduleConfigurations = dd0.getModuleConfigurations.toVector
|
||||
for {
|
||||
moduleConf <- moduleConfigurations
|
||||
(rootModuleConf, vs) <- confMap.toSeq
|
||||
} if (vs contains moduleConf) {
|
||||
log.debug(s""":::: ${dd0}: $moduleConf maps to $rootModuleConf""")
|
||||
dd0.getDependencyConfigurations(moduleConf) foreach { conf =>
|
||||
dd.addDependencyConfiguration(rootModuleConf, conf)
|
||||
}
|
||||
dd0.getIncludeRules(moduleConf) foreach { rule =>
|
||||
dd.addIncludeRule(rootModuleConf, rule)
|
||||
}
|
||||
dd0.getExcludeRules(moduleConf) foreach { rule =>
|
||||
dd.addExcludeRule(rootModuleConf, rule)
|
||||
}
|
||||
dd0.getAllDependencyArtifacts foreach { dad0 =>
|
||||
(Option(dad0.getConfigurations) map { confs => confs.isEmpty || confs.contains(moduleConf) || confs.contains("*") }) match {
|
||||
case Some(false) => // do nothing
|
||||
case _ =>
|
||||
val dad = new DefaultDependencyArtifactDescriptor(dd, dad0.getName, dad0.getType, dad0.getExt, dad0.getUrl, dad0.getExtraAttributes)
|
||||
dad.addConfiguration(rootModuleConf)
|
||||
dd.addDependencyArtifact(rootModuleConf, dad)
|
||||
}
|
||||
}
|
||||
}
|
||||
log.debug(s""":::: remapped dd: $dd""")
|
||||
dd
|
||||
}
|
||||
directDependencies(md0) flatMap { dep =>
|
||||
val initialMap = Map(dep.getModuleConfigurations map { rootModuleConf =>
|
||||
(rootModuleConf -> Array(rootModuleConf))
|
||||
}: _*)
|
||||
expandInternalDeps(dep, initialMap)
|
||||
}
|
||||
}
|
||||
def buildArtificialModuleDescriptor(dd: DependencyDescriptor, rootModuleConfigs: Vector[IvyConfiguration],
|
||||
parent: ModuleDescriptor, prOpt: Option[ProjectResolver], log: Logger): (DefaultModuleDescriptor, Boolean) =
|
||||
{
|
||||
def excludeRuleString(rule: ExcludeRule): String =
|
||||
s"""Exclude(${rule.getId},${rule.getConfigurations.mkString(",")},${rule.getMatcher})"""
|
||||
def includeRuleString(rule: IncludeRule): String =
|
||||
s"""Include(${rule.getId},${rule.getConfigurations.mkString(",")},${rule.getMatcher})"""
|
||||
def artifactString(dad: DependencyArtifactDescriptor): String =
|
||||
s"""Artifact(${dad.getName},${dad.getType},${dad.getExt},${dad.getUrl},${dad.getConfigurations.mkString(",")},${dad.getExtraAttributes})"""
|
||||
val mrid = dd.getDependencyRevisionId
|
||||
val confMap = (dd.getModuleConfigurations map { conf =>
|
||||
conf + "->(" + dd.getDependencyConfigurations(conf).mkString(",") + ")"
|
||||
|
|
@ -85,10 +158,13 @@ private[sbt] class CachedResolutionResolveCache() {
|
|||
case rules => Some(conf + "->(" + (rules map includeRuleString).mkString(",") + ")")
|
||||
}
|
||||
})
|
||||
val explicitArtifacts = dd.getAllDependencyArtifacts.toVector map { artifactString }
|
||||
val mes = parent.getAllExcludeRules.toVector
|
||||
val mesStr = (mes map excludeRuleString).mkString(",")
|
||||
val os = extractOverrides(parent)
|
||||
val moduleLevel = s"""dependencyOverrides=${os.mkString(",")}"""
|
||||
val moduleLevel = s"""dependencyOverrides=${os.mkString(",")};moduleExclusions=$mesStr"""
|
||||
val depsString = s"""$mrid;${confMap.mkString(",")};isForce=${dd.isForce};isChanging=${dd.isChanging};isTransitive=${dd.isTransitive};""" +
|
||||
s"""exclusions=${exclusions.mkString(",")};inclusions=${inclusions.mkString(",")};$moduleLevel;"""
|
||||
s"""exclusions=${exclusions.mkString(",")};inclusions=${inclusions.mkString(",")};explicitArtifacts=${explicitArtifacts.mkString(",")};$moduleLevel;"""
|
||||
val sha1 = Hash.toHex(Hash(depsString))
|
||||
val md1 = new DefaultModuleDescriptor(createID(sbtOrgTemp, "temp-resolve-" + sha1, "1.0"), "release", null, false) with ArtificialModuleDescriptor {
|
||||
def targetModuleRevisionId: ModuleRevisionId = mrid
|
||||
|
|
@ -100,6 +176,9 @@ private[sbt] class CachedResolutionResolveCache() {
|
|||
os foreach { ovr =>
|
||||
md1.addDependencyDescriptorMediator(ovr.moduleId, ovr.pm, ovr.ddm)
|
||||
}
|
||||
mes foreach { exclude =>
|
||||
md1.addExcludeRule(exclude)
|
||||
}
|
||||
(md1, IvySbt.isChanging(dd))
|
||||
}
|
||||
def extractOverrides(md0: ModuleDescriptor): Vector[IvyOverride] =
|
||||
|
|
@ -228,9 +307,10 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine {
|
|||
val miniGraphPath = depDir / "module"
|
||||
val cachedDescriptor = getSettings.getResolutionCacheManager.getResolvedIvyFileInCache(md0.getModuleRevisionId)
|
||||
val cache = cachedResolutionResolveCache
|
||||
cache.directDependencyCache.remove(md0.getModuleRevisionId)
|
||||
val os = cache.extractOverrides(md0)
|
||||
val mds = cache.buildArtificialModuleDescriptors(md0, projectResolver)
|
||||
val options1 = new ResolveOptions(options0)
|
||||
val data = new ResolveData(this, options1)
|
||||
val mds = cache.buildArtificialModuleDescriptors(md0, data, projectResolver, log)
|
||||
def doWork(md: ModuleDescriptor): Either[ResolveException, UpdateReport] =
|
||||
{
|
||||
val options1 = new ResolveOptions(options0)
|
||||
|
|
@ -318,10 +398,17 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine {
|
|||
}
|
||||
def mergeModuleReports(rootModuleConf: String, modules: Vector[ModuleReport], os: Vector[IvyOverride], log: Logger): Vector[ModuleReport] =
|
||||
{
|
||||
def mergeModuleReports(org: String, name: String, version: String, xs: Vector[ModuleReport]): ModuleReport = {
|
||||
val completelyEvicted = xs forall { _.evicted }
|
||||
val allCallers = xs flatMap { _.callers }
|
||||
val allArtifacts = (xs flatMap { _.artifacts }).distinct
|
||||
log.debug(s":: merging module report for $org:$name:$version - $allArtifacts")
|
||||
xs.head.copy(artifacts = allArtifacts, evicted = completelyEvicted, callers = allCallers)
|
||||
}
|
||||
val merged = (modules groupBy { m => (m.module.organization, m.module.name, m.module.revision) }).toSeq.toVector flatMap {
|
||||
case ((org, name, version), xs) =>
|
||||
if (xs.size < 2) xs
|
||||
else Vector(xs.head.copy(evicted = xs exists { _.evicted }, callers = xs flatMap { _.callers }))
|
||||
else Vector(mergeModuleReports(org, name, version, xs))
|
||||
}
|
||||
val conflicts = merged filter { m => !m.evicted && m.problem.isEmpty }
|
||||
if (conflicts.size < 2) merged
|
||||
|
|
|
|||
|
|
@ -1,10 +1,11 @@
|
|||
|
||||
[Cached-Resolution]: http://www.scala-sbt.org/0.13/docs/Cached-Resolution.html
|
||||
[@cunei]: https://github.com/cunei
|
||||
[@eed3si9n]: https://github.com/eed3si9n
|
||||
[@gkossakowski]: https://github.com/gkossakowski
|
||||
[@jsuereth]: https://github.com/jsuereth
|
||||
[@ajozwik]: https://github.com/ajozwik
|
||||
[@cocumpkin]: https://github.com/copumpkin
|
||||
[@copumpkin]: https://github.com/copumpkin
|
||||
[@Duhemm]: https://github.com/Duhemm
|
||||
[@jedesah]: https://github.com/jedesah
|
||||
[@rkrzewski]: https://github.com/rkrzewski
|
||||
|
|
@ -15,12 +16,14 @@
|
|||
[1237]: https://github.com/sbt/sbt/issues/1237
|
||||
[1430]: https://github.com/sbt/sbt/issues/1430
|
||||
[1544]: https://github.com/sbt/sbt/issues/1544
|
||||
[1563]: https://github.com/sbt/sbt/pull/1563
|
||||
[1572]: https://github.com/sbt/sbt/pull/1572
|
||||
[1573]: https://github.com/sbt/sbt/pull/1573
|
||||
[1579]: https://github.com/sbt/sbt/pull/1579
|
||||
[1584]: https://github.com/sbt/sbt/pull/1584
|
||||
[1586]: https://github.com/sbt/sbt/pull/1586
|
||||
[1589]: https://github.com/sbt/sbt/issues/1589
|
||||
[1590]: https://github.com/sbt/sbt/pull/1590
|
||||
[1591]: https://github.com/sbt/sbt/pull/1591
|
||||
[1598]: https://github.com/sbt/sbt/issues/1598
|
||||
[1600]: https://github.com/sbt/sbt/pull/1600
|
||||
|
|
@ -39,13 +42,13 @@
|
|||
### Fixes with compatibility implications
|
||||
|
||||
- Maven artifact dependencies will limit their transitive dependencies to `Compile` rather than *every configuration* if no `master` configuration is found. [#1586][1586] by [@jsuereth][@jsuereth]
|
||||
- The new natural whitspace handling parser is unable to cope with certain classes of Scala syntax. In particular, top-level pattern matches, or multi-value defintions are no longer supported:
|
||||
- The new natural whitspace handling parser is unable to cope with certain classes of Scala syntax. In particular, top-level pattern matches, or multi-value defintions are no longer supported.
|
||||
|
||||
Here are examples:
|
||||
|
||||
```scala
|
||||
val x, y = project // BAD
|
||||
val x = project //
|
||||
val y = project // GOOD
|
||||
```
|
||||
val x = project //
|
||||
val y = project // GOOD
|
||||
|
||||
### Improvements
|
||||
|
||||
|
|
@ -72,7 +75,7 @@
|
|||
[#1611][1611]/[#1618][1618] by [@jsuereth][@jsuereth]
|
||||
- Fixes NullPointerException when using `ChainResolver` and Maven repositories. [#1611][1611]/[#1618][1618] by [@jsuereth][@jsuereth]
|
||||
- Fixes `Resolver`'s `url` method dropping `descriptorOptional` and `skipConsistencyCheck`. [#1621][1621] by [@tmandke][@tmandke]
|
||||
- Revert `useLatestSnapshot` on `updateOptions` to default to `false`. Reverts chain resolver to previous behavior. [#1683]/[1683] by [@jsuereth][@jsuereth]
|
||||
- Revert `useLatestSnapshot` on `updateOptions` to default to `false`. Reverts chain resolver to previous behavior. [#1683][1683] by [@jsuereth][@jsuereth]
|
||||
|
||||
### Natural whitespace handling
|
||||
|
||||
|
|
@ -104,7 +107,7 @@ By default circular dependencies are warned, but they do not halt the dependency
|
|||
|
||||
### Cached resolution (minigraph caching)
|
||||
|
||||
sbt 0.13.7 adds a new update option called *cached resolution*, which replaces consolidated resolution:
|
||||
sbt 0.13.7 adds a new **experimental** update option called *cached resolution*, which replaces consolidated resolution:
|
||||
|
||||
updateOptions := updateOptions.value.withCachedResolution(true)
|
||||
|
||||
|
|
@ -112,6 +115,6 @@ Unlike consolidated resolution, which only consolidated subprojects with identic
|
|||
|
||||
Once the minigraphs are resolved and saved as files, dependency resolution turns into a matter of loading json file from the second run onwards, which should complete in a matter of seconds even for large projects. Also, because the files are saved under a global `~/.sbt/0.13/dependency` (or what's specified by `sbt.dependency.base` flag), the resolution result is shared across all builds.
|
||||
|
||||
Breaking graphs into minigraphs allows partial resolution results to be shared, which scales better for subprojects with similar but slightly different dependencies, and also for making small changes to the dependencies graph over time.
|
||||
Breaking graphs into minigraphs allows partial resolution results to be shared, which scales better for subprojects with similar but slightly different dependencies, and also for making small changes to the dependencies graph over time. See [documentation on cached resolution][Cached-Resolution] for more details.
|
||||
|
||||
[#1631][1631] by [@eed3si9n][@eed3si9n]
|
||||
|
|
|
|||
|
|
@ -0,0 +1,98 @@
|
|||
lazy val check = taskKey[Unit]("Runs the check")
|
||||
|
||||
def commonSettings: Seq[Def.Setting[_]] =
|
||||
Seq(
|
||||
ivyPaths := new IvyPaths( (baseDirectory in ThisBuild).value, Some((baseDirectory in LocalRootProject).value / "ivy-cache")),
|
||||
dependencyCacheDirectory := (baseDirectory in LocalRootProject).value / "dependency",
|
||||
scalaVersion := "2.10.4",
|
||||
resolvers += Resolver.sonatypeRepo("snapshots")
|
||||
)
|
||||
|
||||
lazy val classifierTest = project.
|
||||
settings(commonSettings: _*).
|
||||
settings(
|
||||
libraryDependencies := Seq(
|
||||
"net.sf.json-lib" % "json-lib" % "2.4" classifier "jdk15" intransitive(),
|
||||
"commons-io" % "commons-io" % "1.4"
|
||||
)
|
||||
)
|
||||
|
||||
lazy val transitiveTest = project.
|
||||
settings(commonSettings: _*).
|
||||
settings(
|
||||
libraryDependencies := Seq(
|
||||
"junit" % "junit" % "4.11" % "test"
|
||||
)
|
||||
)
|
||||
|
||||
lazy val a = project.
|
||||
dependsOn(classifierTest, transitiveTest % "test->test").
|
||||
settings(commonSettings: _*).
|
||||
settings(
|
||||
updateOptions := updateOptions.value.withCachedResolution(true),
|
||||
artifact in (Compile, packageBin) := Artifact("demo"),
|
||||
libraryDependencies := Seq(
|
||||
"com.typesafe.akka" %% "akka-remote" % "2.3.4" exclude("com.typesafe.akka", "akka-actor_2.10"),
|
||||
"net.databinder" %% "unfiltered-uploads" % "0.8.0",
|
||||
"commons-io" % "commons-io" % "1.4" classifier "sources",
|
||||
"com.typesafe" % "config" % "0.4.9-SNAPSHOT"
|
||||
)
|
||||
)
|
||||
|
||||
lazy val b = project.
|
||||
dependsOn(classifierTest, transitiveTest % "test->test").
|
||||
settings(commonSettings: _*).
|
||||
settings(
|
||||
libraryDependencies := Seq(
|
||||
"com.typesafe.akka" %% "akka-remote" % "2.3.4" exclude("com.typesafe.akka", "akka-actor_2.10"),
|
||||
"net.databinder" %% "unfiltered-uploads" % "0.8.0",
|
||||
"commons-io" % "commons-io" % "1.4" classifier "sources",
|
||||
"com.typesafe" % "config" % "0.4.9-SNAPSHOT"
|
||||
)
|
||||
)
|
||||
|
||||
lazy val c = project.
|
||||
dependsOn(a).
|
||||
settings(commonSettings: _*).
|
||||
settings(
|
||||
updateOptions := updateOptions.value.withCachedResolution(true)
|
||||
)
|
||||
|
||||
lazy val root = (project in file(".")).
|
||||
settings(
|
||||
organization in ThisBuild := "org.example",
|
||||
version in ThisBuild := "1.0",
|
||||
check := {
|
||||
val acp = (externalDependencyClasspath in Compile in a).value.sortBy {_.data.getName}
|
||||
val bcp = (externalDependencyClasspath in Compile in b).value.sortBy {_.data.getName}
|
||||
val ccp = (externalDependencyClasspath in Compile in c).value.sortBy {_.data.getName} filterNot { _.data.getName == "demo_2.10.jar"}
|
||||
if (!(acp exists { _.data.getName contains "commons-io-1.4-sources.jar" })) {
|
||||
sys.error("commons-io-1.4-sources not found when it should be included: " + acp.toString)
|
||||
}
|
||||
if (!(acp exists { _.data.getName contains "commons-io-1.4.jar" })) {
|
||||
sys.error("commons-io-1.4 not found when it should be included: " + acp.toString)
|
||||
}
|
||||
|
||||
// stock Ivy implementation doesn't contain regular (non-source) jar, which probably is a bug
|
||||
val acpWithoutSource = acp filterNot { _.data.getName contains "commons-io-1.4"}
|
||||
val bcpWithoutSource = bcp filterNot { _.data.getName contains "commons-io-1.4"}
|
||||
val ccpWithoutSource = ccp filterNot { _.data.getName contains "commons-io-1.4"}
|
||||
if (acpWithoutSource == bcpWithoutSource && acpWithoutSource == ccpWithoutSource) ()
|
||||
else sys.error("Different classpaths are found:" +
|
||||
"\n - a (cached) " + acpWithoutSource.toString +
|
||||
"\n - b (plain) " + bcpWithoutSource.toString +
|
||||
"\n - c (inter-project) " + ccpWithoutSource.toString)
|
||||
|
||||
val atestcp = (externalDependencyClasspath in Test in a).value.sortBy {_.data.getName} filterNot { _.data.getName contains "commons-io-1.4"}
|
||||
val btestcp = (externalDependencyClasspath in Test in b).value.sortBy {_.data.getName} filterNot { _.data.getName contains "commons-io-1.4"}
|
||||
val ctestcp = (externalDependencyClasspath in Test in c).value.sortBy {_.data.getName} filterNot { _.data.getName == "demo_2.10.jar"} filterNot { _.data.getName contains "commons-io-1.4"}
|
||||
if (ctestcp exists { _.data.getName contains "junit-4.11.jar" }) {
|
||||
sys.error("junit found when it should be excluded: " + ctestcp.toString)
|
||||
}
|
||||
|
||||
if (atestcp == btestcp) ()
|
||||
else sys.error("Different classpaths are found:" +
|
||||
"\n - a test (cached) " + atestcp.toString +
|
||||
"\n - b test (plain) " + btestcp.toString)
|
||||
}
|
||||
)
|
||||
|
|
@ -1,3 +1,5 @@
|
|||
> a/update
|
||||
|
||||
> a/updateClassifiers
|
||||
|
||||
> a/publishLocal
|
||||
|
|
@ -0,0 +1,62 @@
|
|||
// https://github.com/sbt/sbt/issues/1710
|
||||
lazy val check = taskKey[Unit]("Runs the check")
|
||||
|
||||
def commonSettings: Seq[Def.Setting[_]] =
|
||||
Seq(
|
||||
organization := "com.example",
|
||||
version := "0.1.0",
|
||||
ivyPaths := new IvyPaths( (baseDirectory in ThisBuild).value, Some((baseDirectory in LocalRootProject).value / "ivy-cache")),
|
||||
dependencyCacheDirectory := (baseDirectory in LocalRootProject).value / "dependency",
|
||||
scalaVersion := "2.10.4",
|
||||
fullResolvers := fullResolvers.value.filterNot(_.name == "inter-project")
|
||||
)
|
||||
|
||||
def cachedResolutionSettings: Seq[Def.Setting[_]] =
|
||||
commonSettings ++ Seq(
|
||||
updateOptions := updateOptions.value.withCachedResolution(true)
|
||||
)
|
||||
|
||||
lazy val X1 = project.
|
||||
settings(commonSettings: _*).
|
||||
settings(
|
||||
libraryDependencies ++= Seq(
|
||||
"com.example" %% "y1" % "0.1.0" % "compile->compile;runtime->runtime",
|
||||
"com.example" %% "y2" % "0.1.0" % "compile->compile;runtime->runtime")
|
||||
)
|
||||
|
||||
lazy val Y1 = project.
|
||||
settings(commonSettings: _*).
|
||||
settings(
|
||||
name := "y1",
|
||||
libraryDependencies ++= Seq(
|
||||
// this includes slf4j 1.7.5
|
||||
"com.ning" % "async-http-client" % "1.8.14",
|
||||
// this includes slf4j 1.6.6
|
||||
"com.twitter" % "summingbird-core_2.10" % "0.5.0",
|
||||
"org.slf4j" % "slf4j-api" % "1.6.6" force()
|
||||
)
|
||||
)
|
||||
|
||||
lazy val Y2 = project.
|
||||
settings(commonSettings: _*).
|
||||
settings(
|
||||
name := "y2",
|
||||
libraryDependencies ++= Seq(
|
||||
// this includes slf4j 1.6.6
|
||||
"com.twitter" % "summingbird-core_2.10" % "0.5.0",
|
||||
// this includes slf4j 1.7.5
|
||||
"com.ning" % "async-http-client" % "1.8.14")
|
||||
)
|
||||
|
||||
lazy val root = (project in file(".")).
|
||||
settings(
|
||||
organization in ThisBuild := "org.example",
|
||||
version in ThisBuild := "1.0",
|
||||
check := {
|
||||
val x1cp = (externalDependencyClasspath in Compile in X1).value.sortBy {_.data.getName}
|
||||
// sys.error("slf4j-api is not found on X1" + x1cp)
|
||||
if (!(x1cp exists {_.data.getName contains "slf4j-api"})) {
|
||||
sys.error("slf4j-api is not found on X1" + x1cp)
|
||||
}
|
||||
}
|
||||
)
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
> debug
|
||||
|
||||
> Y1/publishLocal
|
||||
|
||||
> Y2/publishLocal
|
||||
|
||||
> check
|
||||
|
|
@ -17,7 +17,11 @@ def cachedResolutionSettings: Seq[Def.Setting[_]] =
|
|||
lazy val a = project.
|
||||
settings(cachedResolutionSettings: _*).
|
||||
settings(
|
||||
libraryDependencies += "net.databinder" %% "unfiltered-uploads" % "0.8.0" exclude("commons-io", "commons-io")
|
||||
libraryDependencies += "net.databinder" %% "unfiltered-uploads" % "0.8.0" exclude("commons-io", "commons-io"),
|
||||
ivyXML :=
|
||||
<dependencies>
|
||||
<exclude module="commons-codec"/>
|
||||
</dependencies>
|
||||
)
|
||||
|
||||
lazy val b = project.
|
||||
|
|
@ -32,12 +36,15 @@ lazy val root = (project in file(".")).
|
|||
organization in ThisBuild := "org.example",
|
||||
version in ThisBuild := "1.0",
|
||||
check := {
|
||||
// sys.error(dependencyCacheDirectory.value.toString)
|
||||
val acp = (externalDependencyClasspath in Compile in a).value.sortBy {_.data.getName}
|
||||
val bcp = (externalDependencyClasspath in Compile in b).value.sortBy {_.data.getName}
|
||||
if (acp exists { _.data.getName contains "commons-io" }) {
|
||||
sys.error("commons-io found when it should be excluded")
|
||||
}
|
||||
if (acp exists { _.data.getName contains "commons-codec" }) {
|
||||
sys.error("commons-codec found when it should be excluded")
|
||||
}
|
||||
// This is checking to make sure excluded graph is not getting picked up
|
||||
if (!(bcp exists { _.data.getName contains "commons-io" })) {
|
||||
sys.error("commons-io NOT found when it should NOT be excluded")
|
||||
}
|
||||
|
|
@ -1,53 +0,0 @@
|
|||
lazy val check = taskKey[Unit]("Runs the check")
|
||||
|
||||
def commonSettings: Seq[Def.Setting[_]] =
|
||||
Seq(
|
||||
ivyPaths := new IvyPaths( (baseDirectory in ThisBuild).value, Some((baseDirectory in LocalRootProject).value / "ivy-cache")),
|
||||
dependencyCacheDirectory := (baseDirectory in LocalRootProject).value / "dependency",
|
||||
libraryDependencies := Seq(
|
||||
"net.sf.json-lib" % "json-lib" % "2.4" classifier "jdk15" intransitive(),
|
||||
"com.typesafe.akka" %% "akka-remote" % "2.3.4" exclude("com.typesafe.akka", "akka-actor_2.10"),
|
||||
"net.databinder" %% "unfiltered-uploads" % "0.8.0",
|
||||
"commons-io" % "commons-io" % "1.3",
|
||||
"com.typesafe" % "config" % "0.4.9-SNAPSHOT"
|
||||
),
|
||||
scalaVersion := "2.10.4",
|
||||
resolvers += Resolver.sonatypeRepo("snapshots")
|
||||
)
|
||||
|
||||
def consolidatedResolutionSettings: Seq[Def.Setting[_]] =
|
||||
commonSettings ++ Seq(
|
||||
updateOptions := updateOptions.value.withConsolidatedResolution(true)
|
||||
)
|
||||
|
||||
lazy val a = project.
|
||||
settings(consolidatedResolutionSettings: _*).
|
||||
settings(
|
||||
artifact in (Compile, packageBin) := Artifact("demo")
|
||||
)
|
||||
|
||||
lazy val b = project.
|
||||
settings(commonSettings: _*)
|
||||
|
||||
lazy val c = project.
|
||||
dependsOn(a).
|
||||
settings(consolidatedResolutionSettings: _*).
|
||||
settings(
|
||||
// libraryDependencies := Seq(organization.value %% "a" % version.value)
|
||||
)
|
||||
|
||||
lazy val root = (project in file(".")).
|
||||
settings(
|
||||
organization in ThisBuild := "org.example",
|
||||
version in ThisBuild := "1.0",
|
||||
check := {
|
||||
val acp = (externalDependencyClasspath in Compile in a).value.sortBy {_.data.getName}
|
||||
val bcp = (externalDependencyClasspath in Compile in b).value.sortBy {_.data.getName}
|
||||
val ccp = (externalDependencyClasspath in Compile in c).value.sortBy {_.data.getName} filterNot {_.data.getName == "demo_2.10.jar"}
|
||||
if (acp == bcp && acp == ccp) ()
|
||||
else sys.error("Different classpaths are found:" +
|
||||
"\n - a (cached) " + acp.toString +
|
||||
"\n - b (plain) " + bcp.toString +
|
||||
"\n - c (inter-project) " + ccp.toString)
|
||||
}
|
||||
)
|
||||
|
|
@ -4,7 +4,7 @@
|
|||
[app]
|
||||
org: ${sbt.organization-org.scala-sbt}
|
||||
name: sbt
|
||||
version: ${sbt.version-read(sbt.version)[0.13.5]}
|
||||
version: ${sbt.version-read(sbt.version)[0.13.7]}
|
||||
class: sbt.xMain
|
||||
components: xsbti,extra
|
||||
cross-versioned: ${sbt.cross.versioned-false}
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
[app]
|
||||
org: ${sbt.organization-org.scala-sbt}
|
||||
name: sbt
|
||||
version: ${sbt.version-read(sbt.version)[0.13.5]}
|
||||
version: ${sbt.version-read(sbt.version)[0.13.7]}
|
||||
class: sbt.ScriptMain
|
||||
components: xsbti,extra
|
||||
cross-versioned: ${sbt.cross.versioned-false}
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
[app]
|
||||
org: ${sbt.organization-org.scala-sbt}
|
||||
name: sbt
|
||||
version: ${sbt.version-read(sbt.version)[0.13.5]}
|
||||
version: ${sbt.version-read(sbt.version)[0.13.7]}
|
||||
class: sbt.ConsoleMain
|
||||
components: xsbti,extra
|
||||
cross-versioned: ${sbt.cross.versioned-false}
|
||||
|
|
|
|||
|
|
@ -85,7 +85,6 @@ trait Init[Scope] {
|
|||
*/
|
||||
private[sbt] final def validated[T](key: ScopedKey[T], selfRefOk: Boolean): ValidationCapture[T] = new ValidationCapture(key, selfRefOk)
|
||||
|
||||
|
||||
@deprecated("0.13.7", "Use the version with default arguments and default paramter.")
|
||||
final def derive[T](s: Setting[T], allowDynamic: Boolean, filter: Scope => Boolean, trigger: AttributeKey[_] => Boolean): Setting[T] =
|
||||
derive(s, allowDynamic, filter, trigger, false)
|
||||
|
|
|
|||
Loading…
Reference in New Issue