mirror of https://github.com/sbt/sbt.git
Reformat
This commit is contained in:
parent
a4ce8db55b
commit
a8f2b1f636
|
|
@ -34,34 +34,33 @@ private[sbt] object JsonUtil {
|
|||
UpdateReportLite(ur.configurations map { cr =>
|
||||
ConfigurationReportLite(
|
||||
cr.configuration.name,
|
||||
cr.details map {
|
||||
oar =>
|
||||
OrganizationArtifactReport(
|
||||
oar.organization,
|
||||
oar.name,
|
||||
oar.modules map { mr =>
|
||||
ModuleReport(
|
||||
mr.module,
|
||||
mr.artifacts,
|
||||
mr.missingArtifacts,
|
||||
mr.status,
|
||||
mr.publicationDate,
|
||||
mr.resolver,
|
||||
mr.artifactResolver,
|
||||
mr.evicted,
|
||||
mr.evictedData,
|
||||
mr.evictedReason,
|
||||
mr.problem,
|
||||
mr.homepage,
|
||||
mr.extraAttributes,
|
||||
mr.isDefault,
|
||||
mr.branch,
|
||||
mr.configurations,
|
||||
mr.licenses,
|
||||
filterOutArtificialCallers(mr.callers)
|
||||
)
|
||||
}
|
||||
)
|
||||
cr.details map { oar =>
|
||||
OrganizationArtifactReport(
|
||||
oar.organization,
|
||||
oar.name,
|
||||
oar.modules map { mr =>
|
||||
ModuleReport(
|
||||
mr.module,
|
||||
mr.artifacts,
|
||||
mr.missingArtifacts,
|
||||
mr.status,
|
||||
mr.publicationDate,
|
||||
mr.resolver,
|
||||
mr.artifactResolver,
|
||||
mr.evicted,
|
||||
mr.evictedData,
|
||||
mr.evictedReason,
|
||||
mr.problem,
|
||||
mr.homepage,
|
||||
mr.extraAttributes,
|
||||
mr.isDefault,
|
||||
mr.branch,
|
||||
mr.configurations,
|
||||
mr.licenses,
|
||||
filterOutArtificialCallers(mr.callers)
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
)
|
||||
})
|
||||
|
|
|
|||
|
|
@ -58,8 +58,8 @@ private[librarymanagement] abstract class SemComparatorExtra {
|
|||
|
||||
protected def toStringImpl: String = {
|
||||
val versionStr = Seq(major, minor, patch)
|
||||
.collect {
|
||||
case Some(v) => v.toString
|
||||
.collect { case Some(v) =>
|
||||
v.toString
|
||||
}
|
||||
.mkString(".")
|
||||
val tagsStr = if (tags.nonEmpty) s"-${tags.mkString("-")}" else ""
|
||||
|
|
@ -177,8 +177,8 @@ private[librarymanagement] abstract class SemComparatorFunctions {
|
|||
}
|
||||
parse(
|
||||
numbers
|
||||
.collect {
|
||||
case Some(v) => v.toString
|
||||
.collect { case Some(v) =>
|
||||
v.toString
|
||||
}
|
||||
.mkString(".")
|
||||
)
|
||||
|
|
|
|||
|
|
@ -71,7 +71,7 @@ object VersionRange {
|
|||
case _: NumberFormatException =>
|
||||
// TODO - if the version doesn't meet our expectations, maybe we just issue a hard
|
||||
// error instead of softly ignoring the attempt to rewrite.
|
||||
//sys.error(s"Could not fix version [$revision] into maven style version")
|
||||
// sys.error(s"Could not fix version [$revision] into maven style version")
|
||||
revision
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,7 +36,8 @@ private[sbt] object VersionSchemes {
|
|||
case x => sys.error(s"unknown version scheme: $x")
|
||||
}
|
||||
|
||||
/** info.versionScheme property will be included into POM after sbt 1.4.0.
|
||||
/**
|
||||
* info.versionScheme property will be included into POM after sbt 1.4.0.
|
||||
*/
|
||||
def extractFromId(mid: ModuleID): Option[String] = extractFromExtraAttributes(mid.extraAttributes)
|
||||
|
||||
|
|
|
|||
|
|
@ -27,7 +27,8 @@ object CrossVersionUtil {
|
|||
private[sbt] val BinCompatV = raw"""$basicVersion(-$tagPattern)?-bin(-.*)?""".r
|
||||
private val CandidateV = raw"""$basicVersion(-RC\d+)""".r
|
||||
private val MilestonV = raw"""$basicVersion(-M$tagPattern)""".r
|
||||
private val NonReleaseV_n = raw"""$basicVersion((?:-$tagPattern)*)""".r // 0-n word suffixes, with leading dashes
|
||||
private val NonReleaseV_n =
|
||||
raw"""$basicVersion((?:-$tagPattern)*)""".r // 0-n word suffixes, with leading dashes
|
||||
private val NonReleaseV_1 = raw"""$basicVersion(-$tagPattern)""".r // 1 word suffix, after a dash
|
||||
private[sbt] val PartialVersion = raw"""($longPattern)\.($longPattern)(?:\..+)?""".r
|
||||
|
||||
|
|
|
|||
|
|
@ -37,13 +37,13 @@ private[librarymanagement] abstract class CrossVersionFunctions {
|
|||
*/
|
||||
def fullWith(prefix: String, suffix: String): CrossVersion = Full(prefix, suffix)
|
||||
|
||||
/** Cross-versions a module with the binary version (typically the binary Scala version). */
|
||||
/** Cross-versions a module with the binary version (typically the binary Scala version). */
|
||||
def binary: CrossVersion = Binary()
|
||||
|
||||
/** Disables cross versioning for a module. */
|
||||
def disabled: CrossVersion = sbt.librarymanagement.Disabled
|
||||
|
||||
/** Cross-versions a module with a constant string (typically the binary Scala version). */
|
||||
/** Cross-versions a module with a constant string (typically the binary Scala version). */
|
||||
def constant(value: String): CrossVersion = Constant(value)
|
||||
|
||||
/**
|
||||
|
|
@ -218,7 +218,7 @@ private[librarymanagement] abstract class CrossVersionFunctions {
|
|||
*/
|
||||
def scalaApiVersion(v: String): Option[(Long, Long)] = CrossVersionUtil.scalaApiVersion(v)
|
||||
|
||||
/** Regular expression that extracts the major and minor components of a version into matched groups 1 and 2.*/
|
||||
/** Regular expression that extracts the major and minor components of a version into matched groups 1 and 2. */
|
||||
val PartialVersion = CrossVersionUtil.PartialVersion
|
||||
|
||||
/** Extracts the major and minor components of a version string `s` or returns `None` if the version is improperly formatted. */
|
||||
|
|
|
|||
|
|
@ -29,7 +29,9 @@ trait DependencyFilterExtra {
|
|||
): ArtifactFilter =
|
||||
new ArtifactFilter {
|
||||
def apply(a: Artifact): Boolean =
|
||||
name.accept(a.name) && `type`.accept(a.`type`) && extension.accept(a.extension) && classifier
|
||||
name.accept(a.name) && `type`.accept(a.`type`) && extension.accept(
|
||||
a.extension
|
||||
) && classifier
|
||||
.accept(a.classifier getOrElse "")
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -189,10 +189,9 @@ class DependencyResolution private[sbt] (lmEngine: DependencyResolutionInterface
|
|||
((sourceArtifactTypes.toIterable map (_ -> Artifact.SourceClassifier))
|
||||
:: (docArtifactTypes.toIterable map (_ -> Artifact.DocClassifier)) :: Nil).flatten.toMap
|
||||
Right(r.substitute { (conf, mid, artFileSeq) =>
|
||||
artFileSeq map {
|
||||
case (art, f) =>
|
||||
// Deduce the classifier from the type if no classifier is present already
|
||||
art.withClassifier(art.classifier orElse typeClassifierMap.get(art.`type`)) -> f
|
||||
artFileSeq map { case (art, f) =>
|
||||
// Deduce the classifier from the type if no classifier is present already
|
||||
art.withClassifier(art.classifier orElse typeClassifierMap.get(art.`type`)) -> f
|
||||
}
|
||||
})
|
||||
case Left(w) => Left(w)
|
||||
|
|
@ -200,10 +199,9 @@ class DependencyResolution private[sbt] (lmEngine: DependencyResolutionInterface
|
|||
}
|
||||
|
||||
protected def directDependenciesNames(module: ModuleDescriptor): String =
|
||||
(module.directDependencies map {
|
||||
case mID: ModuleID =>
|
||||
import mID._
|
||||
s"$organization % $name % $revision"
|
||||
(module.directDependencies map { case mID: ModuleID =>
|
||||
import mID._
|
||||
s"$organization % $name % $revision"
|
||||
}).mkString(", ")
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -106,11 +106,16 @@ object EvictionError {
|
|||
if (isNameScalaSuffixed(p.name)) assumedVersionScheme
|
||||
else assumedVersionSchemeJava
|
||||
val guess = VersionSchemes.evalFunc(scheme)
|
||||
(p.evicteds forall { r =>
|
||||
f((r.module, winnerOpt, module.scalaModuleInfo))
|
||||
}, schemeOpt.getOrElse("?"), p.evicteds forall { r =>
|
||||
guess((r.module, winnerOpt, module.scalaModuleInfo))
|
||||
}, scheme)
|
||||
(
|
||||
p.evicteds forall { r =>
|
||||
f((r.module, winnerOpt, module.scalaModuleInfo))
|
||||
},
|
||||
schemeOpt.getOrElse("?"),
|
||||
p.evicteds forall { r =>
|
||||
guess((r.module, winnerOpt, module.scalaModuleInfo))
|
||||
},
|
||||
scheme
|
||||
)
|
||||
}
|
||||
pairs foreach {
|
||||
// don't report on a transitive eviction that does not have a winner
|
||||
|
|
@ -152,30 +157,29 @@ final class EvictionError private[sbt] (
|
|||
val out: mutable.ListBuffer[String] = mutable.ListBuffer()
|
||||
out += "found version conflict(s) in library dependencies; some are suspected to be binary incompatible:"
|
||||
out += ""
|
||||
evictions.foreach({
|
||||
case (a, scheme) =>
|
||||
val revs = a.evicteds map { _.module.revision }
|
||||
val revsStr =
|
||||
if (revs.size <= 1) revs.mkString else "{" + revs.distinct.mkString(", ") + "}"
|
||||
val seen: mutable.Set[ModuleID] = mutable.Set()
|
||||
val callers: List[String] = (a.evicteds.toList ::: a.winner.toList) flatMap { r =>
|
||||
val rev = r.module.revision
|
||||
r.callers.toList flatMap { caller =>
|
||||
if (seen(caller.caller)) Nil
|
||||
else {
|
||||
seen += caller.caller
|
||||
List(f"\t +- ${caller}%-50s (depends on $rev)")
|
||||
}
|
||||
evictions.foreach({ case (a, scheme) =>
|
||||
val revs = a.evicteds map { _.module.revision }
|
||||
val revsStr =
|
||||
if (revs.size <= 1) revs.mkString else "{" + revs.distinct.mkString(", ") + "}"
|
||||
val seen: mutable.Set[ModuleID] = mutable.Set()
|
||||
val callers: List[String] = (a.evicteds.toList ::: a.winner.toList) flatMap { r =>
|
||||
val rev = r.module.revision
|
||||
r.callers.toList flatMap { caller =>
|
||||
if (seen(caller.caller)) Nil
|
||||
else {
|
||||
seen += caller.caller
|
||||
List(f"\t +- ${caller}%-50s (depends on $rev)")
|
||||
}
|
||||
}
|
||||
val que = if (assumed) "?" else ""
|
||||
val winnerRev = a.winner match {
|
||||
case Some(r) => s":${r.module.revision} ($scheme$que) is selected over ${revsStr}"
|
||||
case _ => " is evicted for all versions"
|
||||
}
|
||||
val title = s"\t* ${a.organization}:${a.name}$winnerRev"
|
||||
val lines = title :: (if (a.showCallers) callers.reverse else Nil) ::: List("")
|
||||
out ++= lines
|
||||
}
|
||||
val que = if (assumed) "?" else ""
|
||||
val winnerRev = a.winner match {
|
||||
case Some(r) => s":${r.module.revision} ($scheme$que) is selected over ${revsStr}"
|
||||
case _ => " is evicted for all versions"
|
||||
}
|
||||
val title = s"\t* ${a.organization}:${a.name}$winnerRev"
|
||||
val lines = title :: (if (a.showCallers) callers.reverse else Nil) ::: List("")
|
||||
out ++= lines
|
||||
})
|
||||
out.toList
|
||||
}
|
||||
|
|
|
|||
|
|
@ -279,10 +279,12 @@ object EvictionWarning {
|
|||
}
|
||||
confs flatMap { confReport =>
|
||||
confReport.details map { detail =>
|
||||
if ((detail.modules exists { _.evicted }) &&
|
||||
!(buffer exists { x =>
|
||||
(x.organization == detail.organization) && (x.name == detail.name)
|
||||
})) {
|
||||
if (
|
||||
(detail.modules exists { _.evicted }) &&
|
||||
!(buffer exists { x =>
|
||||
(x.organization == detail.organization) && (x.name == detail.name)
|
||||
})
|
||||
) {
|
||||
buffer += detail
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -37,10 +37,10 @@ private[librarymanagement] abstract class ModuleIDExtra {
|
|||
protected def toStringImpl: String =
|
||||
s"""$organization:$name:$revision""" +
|
||||
(configurations match { case Some(s) => ":" + s; case None => "" }) + {
|
||||
val attr = attributeString
|
||||
if (attr == "") ""
|
||||
else " " + attr
|
||||
} +
|
||||
val attr = attributeString
|
||||
if (attr == "") ""
|
||||
else " " + attr
|
||||
} +
|
||||
(if (extraAttributes.isEmpty) "" else " " + extraString)
|
||||
|
||||
protected def attributeString: String = {
|
||||
|
|
@ -95,10 +95,10 @@ private[librarymanagement] abstract class ModuleIDExtra {
|
|||
})
|
||||
|
||||
// () required for chaining
|
||||
/** Do not follow dependencies of this module. Synonym for `intransitive`.*/
|
||||
/** Do not follow dependencies of this module. Synonym for `intransitive`. */
|
||||
def notTransitive(): ModuleID = intransitive()
|
||||
|
||||
/** Do not follow dependencies of this module. Synonym for `notTransitive`.*/
|
||||
/** Do not follow dependencies of this module. Synonym for `notTransitive`. */
|
||||
def intransitive(): ModuleID = withIsTransitive(false)
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -167,7 +167,7 @@ private[librarymanagement] abstract class ResolverFunctions {
|
|||
)
|
||||
def jcenterRepo = JCenterRepository
|
||||
|
||||
/** Add the local and Maven Central repositories to the user repositories. */
|
||||
/** Add the local and Maven Central repositories to the user repositories. */
|
||||
def combineDefaultResolvers(userResolvers: Vector[Resolver]): Vector[Resolver] =
|
||||
combineDefaultResolvers(userResolvers, mavenCentral = true)
|
||||
|
||||
|
|
@ -214,7 +214,10 @@ private[librarymanagement] abstract class ResolverFunctions {
|
|||
single(JCenterRepository, jcenter) ++
|
||||
(xs.partition(_ == DefaultMavenRepository) match {
|
||||
case (_, xs) =>
|
||||
single(DefaultMavenRepository, mavenCentral) ++ xs // TODO - Do we need to filter out duplicates?
|
||||
single(
|
||||
DefaultMavenRepository,
|
||||
mavenCentral
|
||||
) ++ xs // TODO - Do we need to filter out duplicates?
|
||||
})
|
||||
})
|
||||
}
|
||||
|
|
@ -222,7 +225,7 @@ private[librarymanagement] abstract class ResolverFunctions {
|
|||
private def single[T](value: T, nonEmpty: Boolean): Vector[T] =
|
||||
if (nonEmpty) Vector(value) else Vector.empty
|
||||
|
||||
/** A base class for defining factories for interfaces to Ivy repositories that require a hostname , port, and patterns. */
|
||||
/** A base class for defining factories for interfaces to Ivy repositories that require a hostname , port, and patterns. */
|
||||
sealed abstract class Define[RepositoryType <: SshBasedRepository] {
|
||||
|
||||
/** Subclasses should implement this method to */
|
||||
|
|
@ -251,8 +254,8 @@ private[librarymanagement] abstract class ResolverFunctions {
|
|||
* patterns will be resolved. `basePatterns` are the initial patterns to use.
|
||||
* A ManagedProject has an implicit defining these initial patterns based on a setting for either Maven or Ivy style patterns.
|
||||
*/
|
||||
def apply(name: String, hostname: String, basePath: String)(
|
||||
implicit basePatterns: Patterns
|
||||
def apply(name: String, hostname: String, basePath: String)(implicit
|
||||
basePatterns: Patterns
|
||||
): RepositoryType =
|
||||
apply(name, Some(hostname), None, Some(basePath))
|
||||
|
||||
|
|
@ -260,8 +263,8 @@ private[librarymanagement] abstract class ResolverFunctions {
|
|||
* Constructs this repository type with the given `name`, `hostname`, and `port`. `basePatterns` are the initial patterns to use.
|
||||
* A ManagedProject has an implicit defining these initial patterns based on a setting for either Maven or Ivy style patterns.
|
||||
*/
|
||||
def apply(name: String, hostname: String, port: Int)(
|
||||
implicit basePatterns: Patterns
|
||||
def apply(name: String, hostname: String, port: Int)(implicit
|
||||
basePatterns: Patterns
|
||||
): RepositoryType =
|
||||
apply(name, Some(hostname), Some(port), None)
|
||||
|
||||
|
|
@ -270,8 +273,8 @@ private[librarymanagement] abstract class ResolverFunctions {
|
|||
* patterns will be resolved. `basePatterns` are the initial patterns to use.
|
||||
* A ManagedProject has an implicit defining these initial patterns based on a setting for either Maven or Ivy style patterns.
|
||||
*/
|
||||
def apply(name: String, hostname: String, port: Int, basePath: String)(
|
||||
implicit basePatterns: Patterns
|
||||
def apply(name: String, hostname: String, port: Int, basePath: String)(implicit
|
||||
basePatterns: Patterns
|
||||
): RepositoryType =
|
||||
apply(name, Some(hostname), Some(port), Some(basePath))
|
||||
|
||||
|
|
@ -286,13 +289,13 @@ private[librarymanagement] abstract class ResolverFunctions {
|
|||
construct(name, SshConnection(None, hostname, port), resolvePatterns(basePath, basePatterns))
|
||||
}
|
||||
|
||||
/** A factory to construct an interface to an Ivy SSH resolver.*/
|
||||
/** A factory to construct an interface to an Ivy SSH resolver. */
|
||||
object ssh extends Define[SshRepository] {
|
||||
protected def construct(name: String, connection: SshConnection, patterns: Patterns) =
|
||||
SshRepository(name, connection, patterns, None)
|
||||
}
|
||||
|
||||
/** A factory to construct an interface to an Ivy SFTP resolver.*/
|
||||
/** A factory to construct an interface to an Ivy SFTP resolver. */
|
||||
object sftp extends Define[SftpRepository] {
|
||||
protected def construct(name: String, connection: SshConnection, patterns: Patterns) =
|
||||
SftpRepository(name, connection, patterns)
|
||||
|
|
@ -330,8 +333,8 @@ private[librarymanagement] abstract class ResolverFunctions {
|
|||
def apply(name: String, baseURL: URL)(implicit basePatterns: Patterns): URLRepository =
|
||||
baseRepository(baseURL.toURI.normalize.toString)(URLRepository(name, _))
|
||||
}
|
||||
private def baseRepository[T](base: String)(construct: Patterns => T)(
|
||||
implicit basePatterns: Patterns
|
||||
private def baseRepository[T](base: String)(construct: Patterns => T)(implicit
|
||||
basePatterns: Patterns
|
||||
): T =
|
||||
construct(resolvePatterns(base, basePatterns))
|
||||
|
||||
|
|
@ -363,7 +366,7 @@ private[librarymanagement] abstract class ResolverFunctions {
|
|||
}
|
||||
def defaultFileConfiguration = FileConfiguration(true, None)
|
||||
def mavenStylePatterns = Patterns().withArtifactPatterns(Vector(mavenStyleBasePattern))
|
||||
def ivyStylePatterns = defaultIvyPatterns //Patterns(Nil, Nil, false)
|
||||
def ivyStylePatterns = defaultIvyPatterns // Patterns(Nil, Nil, false)
|
||||
|
||||
def defaultPatterns = mavenStylePatterns
|
||||
def mavenStyleBasePattern =
|
||||
|
|
@ -394,7 +397,9 @@ private[librarymanagement] abstract class ResolverFunctions {
|
|||
}
|
||||
sys.props.get("maven.repo.local").map(new File(_)) orElse
|
||||
loadHomeFromSettings(() => new File(sbt.io.Path.userHome, ".m2/settings.xml")) orElse
|
||||
loadHomeFromSettings(() => new File(new File(System.getenv("M2_HOME")), "conf/settings.xml")) getOrElse
|
||||
loadHomeFromSettings(() =>
|
||||
new File(new File(System.getenv("M2_HOME")), "conf/settings.xml")
|
||||
) getOrElse
|
||||
new File(sbt.io.Path.userHome, ".m2/repository")
|
||||
}
|
||||
// TODO - should this just be the *exact* same as mavenLocal? probably...
|
||||
|
|
|
|||
|
|
@ -12,16 +12,15 @@ final class RichUpdateReport(report: UpdateReport) {
|
|||
private[sbt] def recomputeStamps(): UpdateReport = {
|
||||
val files = report.cachedDescriptor +: allFiles
|
||||
val stamps = files
|
||||
.map(
|
||||
f =>
|
||||
(
|
||||
f,
|
||||
// TODO: The list of files may also contain some odd files that do not actually exist like:
|
||||
// "./target/ivyhome/resolution-cache/com.example/foo/0.4.0/resolved.xml.xml".
|
||||
// IO.getModifiedTimeOrZero() will just return zero, but the list of files should not contain such
|
||||
// files to begin with, in principle.
|
||||
IO.getModifiedTimeOrZero(f)
|
||||
)
|
||||
.map(f =>
|
||||
(
|
||||
f,
|
||||
// TODO: The list of files may also contain some odd files that do not actually exist like:
|
||||
// "./target/ivyhome/resolution-cache/com.example/foo/0.4.0/resolved.xml.xml".
|
||||
// IO.getModifiedTimeOrZero() will just return zero, but the list of files should not contain such
|
||||
// files to begin with, in principle.
|
||||
IO.getModifiedTimeOrZero(f)
|
||||
)
|
||||
)
|
||||
.toMap
|
||||
UpdateReport(report.cachedDescriptor, report.configurations, report.stats, stamps)
|
||||
|
|
@ -65,13 +64,13 @@ final class RichUpdateReport(report: UpdateReport) {
|
|||
file
|
||||
}
|
||||
|
||||
/** Constructs a new report that only contains files matching the specified filter.*/
|
||||
/** Constructs a new report that only contains files matching the specified filter. */
|
||||
def filter(f: DependencyFilter): UpdateReport =
|
||||
moduleReportMap { (configuration, modReport) =>
|
||||
modReport
|
||||
.withArtifacts(
|
||||
modReport.artifacts filter {
|
||||
case (art, _) => f(configuration, modReport.module, art)
|
||||
modReport.artifacts filter { case (art, _) =>
|
||||
f(configuration, modReport.module, art)
|
||||
}
|
||||
)
|
||||
.withMissingArtifacts(
|
||||
|
|
|
|||
|
|
@ -10,9 +10,13 @@ final class ResolveException(
|
|||
val failedPaths: Map[ModuleID, Seq[ModuleID]]
|
||||
) extends RuntimeException(messages.mkString("\n")) {
|
||||
def this(messages: Seq[String], failed: Seq[ModuleID]) =
|
||||
this(messages, failed, Map(failed map { m =>
|
||||
m -> Nil
|
||||
}: _*))
|
||||
this(
|
||||
messages,
|
||||
failed,
|
||||
Map(failed map { m =>
|
||||
m -> Nil
|
||||
}: _*)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -30,13 +34,12 @@ object UnresolvedWarning {
|
|||
config: UnresolvedWarningConfiguration
|
||||
): UnresolvedWarning = {
|
||||
def modulePosition(m0: ModuleID): Option[SourcePosition] =
|
||||
config.modulePositions.find {
|
||||
case (m, _) =>
|
||||
(m.organization == m0.organization) &&
|
||||
(m0.name startsWith m.name) &&
|
||||
(m.revision == m0.revision)
|
||||
} map {
|
||||
case (_, p) => p
|
||||
config.modulePositions.find { case (m, _) =>
|
||||
(m.organization == m0.organization) &&
|
||||
(m0.name startsWith m.name) &&
|
||||
(m.revision == m0.revision)
|
||||
} map { case (_, p) =>
|
||||
p
|
||||
}
|
||||
val failedPaths = err.failed map { (x: ModuleID) =>
|
||||
err.failedPaths(x).toList.reverse map { id =>
|
||||
|
|
@ -67,9 +70,8 @@ object UnresolvedWarning {
|
|||
if (path.nonEmpty) {
|
||||
val head = path.head
|
||||
buffer += "\t\t" + head._1.toString + sourcePosStr(head._2)
|
||||
path.tail foreach {
|
||||
case (m, pos) =>
|
||||
buffer += "\t\t +- " + m.toString + sourcePosStr(pos)
|
||||
path.tail foreach { case (m, pos) =>
|
||||
buffer += "\t\t +- " + m.toString + sourcePosStr(pos)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,9 +29,13 @@ private[librarymanagement] abstract class ConfigurationReportExtra {
|
|||
}
|
||||
|
||||
def retrieve(f: (ConfigRef, ModuleID, Artifact, File) => File): ConfigurationReport =
|
||||
ConfigurationReport(configuration, modules map {
|
||||
_.retrieve((mid, art, file) => f(configuration, mid, art, file))
|
||||
}, details)
|
||||
ConfigurationReport(
|
||||
configuration,
|
||||
modules map {
|
||||
_.retrieve((mid, art, file) => f(configuration, mid, art, file))
|
||||
},
|
||||
details
|
||||
)
|
||||
}
|
||||
|
||||
private[librarymanagement] abstract class ModuleReportExtra {
|
||||
|
|
@ -124,24 +128,23 @@ private[librarymanagement] abstract class UpdateReportExtra {
|
|||
/** All resolved modules in all configurations. */
|
||||
def allModules: Vector[ModuleID] = {
|
||||
val key = (m: ModuleID) => (m.organization, m.name, m.revision)
|
||||
configurations.flatMap(_.allModules).groupBy(key).toVector map {
|
||||
case (_, v) =>
|
||||
v reduceLeft { (agg, x) =>
|
||||
agg.withConfigurations(
|
||||
(agg.configurations, x.configurations) match {
|
||||
case (None, _) => x.configurations
|
||||
case (Some(ac), None) => Some(ac)
|
||||
case (Some(ac), Some(xc)) => Some(s"$ac;$xc")
|
||||
}
|
||||
)
|
||||
}
|
||||
configurations.flatMap(_.allModules).groupBy(key).toVector map { case (_, v) =>
|
||||
v reduceLeft { (agg, x) =>
|
||||
agg.withConfigurations(
|
||||
(agg.configurations, x.configurations) match {
|
||||
case (None, _) => x.configurations
|
||||
case (Some(ac), None) => Some(ac)
|
||||
case (Some(ac), Some(xc)) => Some(s"$ac;$xc")
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
def retrieve(f: (ConfigRef, ModuleID, Artifact, File) => File): UpdateReport =
|
||||
UpdateReport(cachedDescriptor, configurations map { _ retrieve f }, stats, stamps)
|
||||
|
||||
/** Gets the report for the given configuration, or `None` if the configuration was not resolved.*/
|
||||
/** Gets the report for the given configuration, or `None` if the configuration was not resolved. */
|
||||
def configuration(s: ConfigRef) = configurations.find(_.configuration == s)
|
||||
|
||||
/** Gets the names of all resolved configurations. This `UpdateReport` contains one `ConfigurationReport` for each configuration in this list. */
|
||||
|
|
|
|||
|
|
@ -162,7 +162,8 @@ object VersionNumber {
|
|||
}
|
||||
}
|
||||
|
||||
/** A variant of SemVar that seems to be common among the Scala libraries.
|
||||
/**
|
||||
* A variant of SemVar that seems to be common among the Scala libraries.
|
||||
* The second segment (y in x.y.z) increments breaks the binary compatibility even when x > 0.
|
||||
* Also API compatibility is expected even when the first segment is zero.
|
||||
*/
|
||||
|
|
@ -172,7 +173,8 @@ object VersionNumber {
|
|||
PackVer.isCompatible(v1, v2)
|
||||
}
|
||||
|
||||
/** A variant of SemVar that seems to be common among the Scala libraries.
|
||||
/**
|
||||
* A variant of SemVar that seems to be common among the Scala libraries.
|
||||
* The second segment (y in x.y.z) increments breaks the binary compatibility even when x > 0.
|
||||
* Also API compatibility is expected even when the first segment is zero.
|
||||
*/
|
||||
|
|
@ -193,7 +195,8 @@ object VersionNumber {
|
|||
}
|
||||
}
|
||||
|
||||
/** A variant of SemVar that enforces API compatibility when the first segment is zero.
|
||||
/**
|
||||
* A variant of SemVar that enforces API compatibility when the first segment is zero.
|
||||
*/
|
||||
object EarlySemVer extends VersionNumberCompatibility {
|
||||
import SemVer._
|
||||
|
|
|
|||
|
|
@ -21,8 +21,6 @@ import org.apache.ivy.core.module.descriptor.DefaultDependencyDescriptor;
|
|||
*
|
||||
* Also see: http://ant.apache.org/ivy/history/2.3.0/ivyfile/dependency.html
|
||||
* and: http://svn.apache.org/repos/asf/ant/ivy/core/tags/2.3.0/src/java/org/apache/ivy/plugins/parser/m2/PomModuleDescriptorBuilder.java
|
||||
*
|
||||
*
|
||||
*/
|
||||
object ReplaceMavenConfigurationMappings {
|
||||
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ class ComponentManager(
|
|||
/** This is used to lock the local cache in project/boot/. By checking the local cache first, we can avoid grabbing a global lock. */
|
||||
private def lockLocalCache[T](action: => T): T = lock(provider.lockFile)(action)
|
||||
|
||||
/** This is used to ensure atomic access to components in the global Ivy cache.*/
|
||||
/** This is used to ensure atomic access to components in the global Ivy cache. */
|
||||
private def lockGlobalCache[T](action: => T): T = lock(ivyCache.lockFile)(action)
|
||||
private def lock[T](file: File)(action: => T): T =
|
||||
globalLock(file, new Callable[T] { def call = action })
|
||||
|
|
|
|||
|
|
@ -151,83 +151,82 @@ private[sbt] object ConvertResolver {
|
|||
(updateOptions.resolverConverter orElse defaultConvert)((r, settings, log))
|
||||
|
||||
/** The default implementation of converter. */
|
||||
lazy val defaultConvert: ResolverConverter = {
|
||||
case (r, settings, log) =>
|
||||
val managedChecksums = Option(settings.getVariable(ManagedChecksums)) match {
|
||||
case Some(x) => x.toBoolean
|
||||
case _ => false
|
||||
lazy val defaultConvert: ResolverConverter = { case (r, settings, log) =>
|
||||
val managedChecksums = Option(settings.getVariable(ManagedChecksums)) match {
|
||||
case Some(x) => x.toBoolean
|
||||
case _ => false
|
||||
}
|
||||
r match {
|
||||
case repo: MavenRepository => {
|
||||
val pattern = Collections.singletonList(
|
||||
Resolver.resolvePattern(repo.root, Resolver.mavenStyleBasePattern)
|
||||
)
|
||||
final class PluginCapableResolver
|
||||
extends IBiblioResolver
|
||||
with ChecksumFriendlyURLResolver
|
||||
with DescriptorRequired {
|
||||
override val managedChecksumsEnabled: Boolean = managedChecksums
|
||||
override def getResource(resource: Resource, dest: File): Long = get(resource, dest)
|
||||
def setPatterns(): Unit = {
|
||||
// done this way for access to protected methods.
|
||||
setArtifactPatterns(pattern)
|
||||
setIvyPatterns(pattern)
|
||||
}
|
||||
}
|
||||
val resolver = new PluginCapableResolver
|
||||
if (repo.localIfFile) resolver.setRepository(new LocalIfFileRepo)
|
||||
initializeMavenStyle(resolver, repo.name, repo.root)
|
||||
resolver
|
||||
.setPatterns() // has to be done after initializeMavenStyle, which calls methods that overwrite the patterns
|
||||
resolver
|
||||
}
|
||||
r match {
|
||||
case repo: MavenRepository => {
|
||||
val pattern = Collections.singletonList(
|
||||
Resolver.resolvePattern(repo.root, Resolver.mavenStyleBasePattern)
|
||||
)
|
||||
final class PluginCapableResolver
|
||||
extends IBiblioResolver
|
||||
with ChecksumFriendlyURLResolver
|
||||
with DescriptorRequired {
|
||||
override val managedChecksumsEnabled: Boolean = managedChecksums
|
||||
override def getResource(resource: Resource, dest: File): Long = get(resource, dest)
|
||||
def setPatterns(): Unit = {
|
||||
// done this way for access to protected methods.
|
||||
setArtifactPatterns(pattern)
|
||||
setIvyPatterns(pattern)
|
||||
}
|
||||
}
|
||||
val resolver = new PluginCapableResolver
|
||||
if (repo.localIfFile) resolver.setRepository(new LocalIfFileRepo)
|
||||
initializeMavenStyle(resolver, repo.name, repo.root)
|
||||
resolver
|
||||
.setPatterns() // has to be done after initializeMavenStyle, which calls methods that overwrite the patterns
|
||||
resolver
|
||||
case repo: SshRepository => {
|
||||
val resolver = new SshResolver with DescriptorRequired with ThreadSafeSshBasedResolver {
|
||||
override val managedChecksumsEnabled: Boolean = managedChecksums
|
||||
override def getResource(resource: Resource, dest: File): Long = get(resource, dest)
|
||||
}
|
||||
case repo: SshRepository => {
|
||||
val resolver = new SshResolver with DescriptorRequired with ThreadSafeSshBasedResolver {
|
||||
override val managedChecksumsEnabled: Boolean = managedChecksums
|
||||
override def getResource(resource: Resource, dest: File): Long = get(resource, dest)
|
||||
}
|
||||
initializeSSHResolver(resolver, repo, settings)
|
||||
repo.publishPermissions.foreach(perm => resolver.setPublishPermissions(perm))
|
||||
resolver
|
||||
}
|
||||
case repo: SftpRepository => {
|
||||
val resolver = new SFTPResolver with ThreadSafeSshBasedResolver
|
||||
initializeSSHResolver(resolver, repo, settings)
|
||||
resolver
|
||||
}
|
||||
case repo: FileRepository => {
|
||||
val resolver = new FileSystemResolver with DescriptorRequired {
|
||||
// Workaround for #1156
|
||||
// Temporarily in sbt 0.13.x we deprecate overwriting
|
||||
// in local files for non-changing revisions.
|
||||
// This will be fully enforced in sbt 1.0.
|
||||
setRepository(new WarnOnOverwriteFileRepo())
|
||||
override val managedChecksumsEnabled: Boolean = managedChecksums
|
||||
override def getResource(resource: Resource, dest: File): Long = get(resource, dest)
|
||||
}
|
||||
resolver.setName(repo.name)
|
||||
initializePatterns(resolver, repo.patterns, settings)
|
||||
import repo.configuration.{ isLocal, isTransactional }
|
||||
resolver.setLocal(isLocal)
|
||||
isTransactional.foreach(value => resolver.setTransactional(value.toString))
|
||||
resolver
|
||||
}
|
||||
case repo: URLRepository => {
|
||||
val resolver = new URLResolver with ChecksumFriendlyURLResolver with DescriptorRequired {
|
||||
override val managedChecksumsEnabled: Boolean = managedChecksums
|
||||
override def getResource(resource: Resource, dest: File): Long = get(resource, dest)
|
||||
}
|
||||
resolver.setName(repo.name)
|
||||
initializePatterns(resolver, repo.patterns, settings)
|
||||
resolver
|
||||
}
|
||||
case repo: ChainedResolver =>
|
||||
IvySbt.resolverChain(repo.name, repo.resolvers, settings, log)
|
||||
case repo: RawRepository =>
|
||||
repo.resolver match {
|
||||
case r: DependencyResolver => r
|
||||
}
|
||||
initializeSSHResolver(resolver, repo, settings)
|
||||
repo.publishPermissions.foreach(perm => resolver.setPublishPermissions(perm))
|
||||
resolver
|
||||
}
|
||||
case repo: SftpRepository => {
|
||||
val resolver = new SFTPResolver with ThreadSafeSshBasedResolver
|
||||
initializeSSHResolver(resolver, repo, settings)
|
||||
resolver
|
||||
}
|
||||
case repo: FileRepository => {
|
||||
val resolver = new FileSystemResolver with DescriptorRequired {
|
||||
// Workaround for #1156
|
||||
// Temporarily in sbt 0.13.x we deprecate overwriting
|
||||
// in local files for non-changing revisions.
|
||||
// This will be fully enforced in sbt 1.0.
|
||||
setRepository(new WarnOnOverwriteFileRepo())
|
||||
override val managedChecksumsEnabled: Boolean = managedChecksums
|
||||
override def getResource(resource: Resource, dest: File): Long = get(resource, dest)
|
||||
}
|
||||
resolver.setName(repo.name)
|
||||
initializePatterns(resolver, repo.patterns, settings)
|
||||
import repo.configuration.{ isLocal, isTransactional }
|
||||
resolver.setLocal(isLocal)
|
||||
isTransactional.foreach(value => resolver.setTransactional(value.toString))
|
||||
resolver
|
||||
}
|
||||
case repo: URLRepository => {
|
||||
val resolver = new URLResolver with ChecksumFriendlyURLResolver with DescriptorRequired {
|
||||
override val managedChecksumsEnabled: Boolean = managedChecksums
|
||||
override def getResource(resource: Resource, dest: File): Long = get(resource, dest)
|
||||
}
|
||||
resolver.setName(repo.name)
|
||||
initializePatterns(resolver, repo.patterns, settings)
|
||||
resolver
|
||||
}
|
||||
case repo: ChainedResolver =>
|
||||
IvySbt.resolverChain(repo.name, repo.resolvers, settings, log)
|
||||
case repo: RawRepository =>
|
||||
repo.resolver match {
|
||||
case r: DependencyResolver => r
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private sealed trait DescriptorRequired extends BasicResolver {
|
||||
|
|
@ -290,8 +289,9 @@ private[sbt] object ConvertResolver {
|
|||
override def getDependency(dd: DependencyDescriptor, data: ResolveData) = {
|
||||
val prev = descriptorString(isAllownomd)
|
||||
setDescriptor(descriptorString(hasExplicitURL(dd)))
|
||||
val t = try super.getDependency(dd, data)
|
||||
finally setDescriptor(prev)
|
||||
val t =
|
||||
try super.getDependency(dd, data)
|
||||
finally setDescriptor(prev)
|
||||
t
|
||||
}
|
||||
def descriptorString(optional: Boolean) =
|
||||
|
|
|
|||
|
|
@ -64,7 +64,7 @@ object CustomPomParser {
|
|||
// Evil hackery to override the default maven pom mappings.
|
||||
ReplaceMavenConfigurationMappings.init()
|
||||
|
||||
/** The key prefix that indicates that this is used only to store extra information and is not intended for dependency resolution.*/
|
||||
/** The key prefix that indicates that this is used only to store extra information and is not intended for dependency resolution. */
|
||||
val InfoKeyPrefix = SbtPomExtraProperties.POM_INFO_KEY_PREFIX
|
||||
val ApiURLKey = SbtPomExtraProperties.POM_API_KEY
|
||||
val VersionSchemeKey = SbtPomExtraProperties.VERSION_SCHEME_KEY
|
||||
|
|
@ -109,7 +109,9 @@ object CustomPomParser {
|
|||
val MyHash = MakeTransformHash(md)
|
||||
// sbt 0.13.1 used "sbtTransformHash" instead of "e:sbtTransformHash" until #1192 so read both
|
||||
Option(extraInfo).isDefined &&
|
||||
((Option(extraInfo get TransformedHashKey) orElse Option(extraInfo get oldTransformedHashKey)) match {
|
||||
((Option(extraInfo get TransformedHashKey) orElse Option(
|
||||
extraInfo get oldTransformedHashKey
|
||||
)) match {
|
||||
case Some(MyHash) => true
|
||||
case _ => false
|
||||
})
|
||||
|
|
@ -269,17 +271,23 @@ object CustomPomParser {
|
|||
for (l <- md.getLicenses) dmd.addLicense(l)
|
||||
for ((key, value) <- md.getExtraInfo.asInstanceOf[java.util.Map[String, String]].asScala)
|
||||
dmd.addExtraInfo(key, value)
|
||||
dmd.addExtraInfo(TransformedHashKey, MakeTransformHash(md)) // mark as transformed by this version, so we don't need to do it again
|
||||
for ((key, value) <- md.getExtraAttributesNamespaces
|
||||
.asInstanceOf[java.util.Map[String, String]]
|
||||
.asScala) dmd.addExtraAttributeNamespace(key, value)
|
||||
dmd.addExtraInfo(
|
||||
TransformedHashKey,
|
||||
MakeTransformHash(md)
|
||||
) // mark as transformed by this version, so we don't need to do it again
|
||||
for (
|
||||
(key, value) <- md.getExtraAttributesNamespaces
|
||||
.asInstanceOf[java.util.Map[String, String]]
|
||||
.asScala
|
||||
) dmd.addExtraAttributeNamespace(key, value)
|
||||
IvySbt.addExtraNamespace(dmd)
|
||||
|
||||
val withExtra = md.getDependencies map { dd =>
|
||||
addExtra(dd, dependencyExtra)
|
||||
}
|
||||
val withVersionRangeMod: Seq[DependencyDescriptor] =
|
||||
if (LMSysProp.modifyVersionRange) withExtra map { stripVersionRange } else withExtra
|
||||
if (LMSysProp.modifyVersionRange) withExtra map { stripVersionRange }
|
||||
else withExtra
|
||||
val unique = IvySbt.mergeDuplicateDefinitions(withVersionRangeMod)
|
||||
unique foreach dmd.addDependency
|
||||
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ import org.apache.ivy.plugins.parser.xml.XmlModuleDescriptorParser
|
|||
import org.apache.ivy.plugins.repository.Resource
|
||||
import org.apache.ivy.plugins.repository.url.URLResource
|
||||
|
||||
/** Subclasses the default Ivy file parser in order to provide access to protected methods.*/
|
||||
/** Subclasses the default Ivy file parser in order to provide access to protected methods. */
|
||||
private[sbt] object CustomXmlParser extends XmlModuleDescriptorParser {
|
||||
import XmlModuleDescriptorParser.Parser
|
||||
class CustomParser(settings: IvySettings, defaultConfig: Option[String])
|
||||
|
|
@ -26,7 +26,7 @@ private[sbt] object CustomXmlParser extends XmlModuleDescriptorParser {
|
|||
}
|
||||
def setInput(bytes: Array[Byte]): Unit = setInput(new ByteArrayInputStream(bytes))
|
||||
|
||||
/** Overridden because the super implementation overwrites the module descriptor.*/
|
||||
/** Overridden because the super implementation overwrites the module descriptor. */
|
||||
override def setResource(res: Resource): Unit = ()
|
||||
override def setMd(md: DefaultModuleDescriptor) = {
|
||||
super.setMd(md)
|
||||
|
|
|
|||
|
|
@ -178,8 +178,8 @@ private[sbt] class FakeResolver(private var name: String, cacheDir: File, module
|
|||
val artifact =
|
||||
for {
|
||||
artifacts <- modules get ((moduleOrganisation, moduleName, moduleRevision))
|
||||
artifact <- artifacts find (
|
||||
a => a.name == art.getName && a.tpe == art.getType && a.ext == art.getExt
|
||||
artifact <- artifacts find (a =>
|
||||
a.name == art.getName && a.tpe == art.getType && a.ext == art.getExt
|
||||
)
|
||||
} yield new ArtifactOrigin(art, /* isLocal = */ true, artifact.file.toURI.toURL.toString)
|
||||
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ import sbt.internal.librarymanagement.IvyUtil.TransientNetworkException
|
|||
|
||||
object IvyActions {
|
||||
|
||||
/** Installs the dependencies of the given 'module' from the resolver named 'from' to the resolver named 'to'.*/
|
||||
/** Installs the dependencies of the given 'module' from the resolver named 'from' to the resolver named 'to'. */
|
||||
def install(module: IvySbt#Module, from: String, to: String, log: Logger): Unit = {
|
||||
module.withModule(log) { (ivy, md, _) =>
|
||||
for (dependency <- md.getDependencies) {
|
||||
|
|
@ -57,7 +57,7 @@ object IvyActions {
|
|||
module.owner.cleanCachedResolutionCache()
|
||||
}
|
||||
|
||||
/** Creates a Maven pom from the given Ivy configuration*/
|
||||
/** Creates a Maven pom from the given Ivy configuration */
|
||||
def makePomFile(module: IvySbt#Module, configuration: MakePomConfiguration, log: Logger): File = {
|
||||
import configuration.{
|
||||
allRepositories,
|
||||
|
|
@ -91,13 +91,12 @@ object IvyActions {
|
|||
val deliverIvyPattern = configuration.deliverIvyPattern
|
||||
.getOrElse(sys.error("deliverIvyPattern must be specified."))
|
||||
val status = getDeliverStatus(configuration.status)
|
||||
module.withModule(log) {
|
||||
case (ivy, md, _) =>
|
||||
val revID = md.getModuleRevisionId
|
||||
val options = DeliverOptions.newInstance(ivy.getSettings).setStatus(status)
|
||||
options.setConfs(getConfigurations(md, configuration.configurations))
|
||||
ivy.deliver(revID, revID.getRevision, deliverIvyPattern, options)
|
||||
deliveredFile(ivy, deliverIvyPattern, md)
|
||||
module.withModule(log) { case (ivy, md, _) =>
|
||||
val revID = md.getModuleRevisionId
|
||||
val options = DeliverOptions.newInstance(ivy.getSettings).setStatus(status)
|
||||
options.setConfs(getConfigurations(md, configuration.configurations))
|
||||
ivy.deliver(revID, revID.getRevision, deliverIvyPattern, options)
|
||||
deliveredFile(ivy, deliverIvyPattern, md)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -130,18 +129,17 @@ object IvyActions {
|
|||
|
||||
val artifacts = Map(configuration.artifacts: _*)
|
||||
val checksums = configuration.checksums
|
||||
module.withModule(log) {
|
||||
case (ivy, md, _) =>
|
||||
val resolver = ivy.getSettings.getResolver(resolverName)
|
||||
if (resolver eq null) sys.error("Undefined resolver '" + resolverName + "'")
|
||||
val ivyArtifact = ivyFile map { file =>
|
||||
(MDArtifact.newIvyArtifact(md), file)
|
||||
}
|
||||
val cross = crossVersionMap(module.moduleSettings)
|
||||
val as = mapArtifacts(md, cross, artifacts) ++ ivyArtifact.toList
|
||||
withChecksums(resolver, checksums) {
|
||||
publish(md, as, resolver, overwrite = configuration.overwrite)
|
||||
}
|
||||
module.withModule(log) { case (ivy, md, _) =>
|
||||
val resolver = ivy.getSettings.getResolver(resolverName)
|
||||
if (resolver eq null) sys.error("Undefined resolver '" + resolverName + "'")
|
||||
val ivyArtifact = ivyFile map { file =>
|
||||
(MDArtifact.newIvyArtifact(md), file)
|
||||
}
|
||||
val cross = crossVersionMap(module.moduleSettings)
|
||||
val as = mapArtifacts(md, cross, artifacts) ++ ivyArtifact.toList
|
||||
withChecksums(resolver, checksums) {
|
||||
publish(md, as, resolver, overwrite = configuration.overwrite)
|
||||
}
|
||||
}
|
||||
}
|
||||
private[this] def withChecksums[T](resolver: DependencyResolver, checksums: Vector[String])(
|
||||
|
|
@ -193,35 +191,36 @@ object IvyActions {
|
|||
uwconfig: UnresolvedWarningConfiguration,
|
||||
log: Logger
|
||||
): Either[UnresolvedWarning, UpdateReport] = {
|
||||
module.withModule(log) {
|
||||
case (ivy, moduleDescriptor, _) =>
|
||||
// Warn about duplicated and inconsistent dependencies
|
||||
val iw = IvySbt.inconsistentDuplicateWarning(moduleDescriptor)
|
||||
iw.foreach(log.warn(_))
|
||||
module.withModule(log) { case (ivy, moduleDescriptor, _) =>
|
||||
// Warn about duplicated and inconsistent dependencies
|
||||
val iw = IvySbt.inconsistentDuplicateWarning(moduleDescriptor)
|
||||
iw.foreach(log.warn(_))
|
||||
|
||||
val metadataDirectory = configuration.metadataDirectory
|
||||
val metadataDirectory = configuration.metadataDirectory
|
||||
|
||||
// Create inputs, resolve and retrieve the module descriptor
|
||||
val inputs = ResolutionInputs(ivy, moduleDescriptor, configuration, log)
|
||||
val resolutionResult: Either[ResolveException, UpdateReport] = {
|
||||
if (module.owner.configuration.updateOptions.cachedResolution && metadataDirectory.isDefined) {
|
||||
val cache =
|
||||
metadataDirectory.getOrElse(sys.error("Missing directory for cached resolution."))
|
||||
cachedResolveAndRetrieve(inputs, cache)
|
||||
} else resolveAndRetrieve(inputs)
|
||||
}
|
||||
// Create inputs, resolve and retrieve the module descriptor
|
||||
val inputs = ResolutionInputs(ivy, moduleDescriptor, configuration, log)
|
||||
val resolutionResult: Either[ResolveException, UpdateReport] = {
|
||||
if (
|
||||
module.owner.configuration.updateOptions.cachedResolution && metadataDirectory.isDefined
|
||||
) {
|
||||
val cache =
|
||||
metadataDirectory.getOrElse(sys.error("Missing directory for cached resolution."))
|
||||
cachedResolveAndRetrieve(inputs, cache)
|
||||
} else resolveAndRetrieve(inputs)
|
||||
}
|
||||
|
||||
// Convert to unresolved warning or retrieve update report
|
||||
resolutionResult.fold(
|
||||
exception => Left(UnresolvedWarning(exception, uwconfig)),
|
||||
ur0 => {
|
||||
val ur = configuration.retrieveManaged match {
|
||||
case Some(retrieveConf) => retrieve(log, ivy, ur0, retrieveConf)
|
||||
case _ => ur0
|
||||
}
|
||||
Right(ur)
|
||||
// Convert to unresolved warning or retrieve update report
|
||||
resolutionResult.fold(
|
||||
exception => Left(UnresolvedWarning(exception, uwconfig)),
|
||||
ur0 => {
|
||||
val ur = configuration.retrieveManaged match {
|
||||
case Some(retrieveConf) => retrieve(log, ivy, ur0, retrieveConf)
|
||||
case _ => ur0
|
||||
}
|
||||
)
|
||||
Right(ur)
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -252,11 +251,10 @@ object IvyActions {
|
|||
exclude.getOrElse(restrictedCopy(id, false), Set.empty[String])
|
||||
|
||||
def extractExcludes(report: UpdateReport): Map[ModuleID, Set[String]] =
|
||||
report.allMissing flatMap {
|
||||
case (_, mod, art) =>
|
||||
art.classifier.map { c =>
|
||||
(restrictedCopy(mod, false), c)
|
||||
}
|
||||
report.allMissing flatMap { case (_, mod, art) =>
|
||||
art.classifier.map { c =>
|
||||
(restrictedCopy(mod, false), c)
|
||||
}
|
||||
} groupBy (_._1) map { case (mod, pairs) => (mod, pairs.map(_._2).toSet) }
|
||||
|
||||
/**
|
||||
|
|
@ -275,8 +273,8 @@ object IvyActions {
|
|||
)
|
||||
|
||||
implicit def toIvyFilter(f: ArtifactTypeFilter): IvyFilter = new IvyFilter {
|
||||
override def accept(o: Object): Boolean = Option(o) exists {
|
||||
case a: IArtifact => applyFilter(a)
|
||||
override def accept(o: Object): Boolean = Option(o) exists { case a: IArtifact =>
|
||||
applyFilter(a)
|
||||
}
|
||||
|
||||
def applyFilter(a: IArtifact): Boolean =
|
||||
|
|
@ -498,13 +496,12 @@ object IvyActions {
|
|||
checkFilesPresent(artifacts)
|
||||
try {
|
||||
resolver.beginPublishTransaction(module.getModuleRevisionId(), overwrite);
|
||||
artifacts.foreach {
|
||||
case (artifact, file) =>
|
||||
IvyUtil.retryWithBackoff(
|
||||
resolver.publish(artifact, file, overwrite),
|
||||
TransientNetworkException.apply,
|
||||
maxAttempts = LMSysProp.maxPublishAttempts
|
||||
)
|
||||
artifacts.foreach { case (artifact, file) =>
|
||||
IvyUtil.retryWithBackoff(
|
||||
resolver.publish(artifact, file, overwrite),
|
||||
TransientNetworkException.apply,
|
||||
maxAttempts = LMSysProp.maxPublishAttempts
|
||||
)
|
||||
}
|
||||
resolver.commitPublishTransaction()
|
||||
} catch {
|
||||
|
|
|
|||
|
|
@ -31,11 +31,11 @@ private object NotInCache {
|
|||
}
|
||||
}
|
||||
|
||||
/** Provides methods for working at the level of a single jar file with the default Ivy cache.*/
|
||||
/** Provides methods for working at the level of a single jar file with the default Ivy cache. */
|
||||
class IvyCache(val ivyHome: Option[File]) {
|
||||
def lockFile = new File(ivyHome getOrElse Path.userHome, ".sbt.cache.lock")
|
||||
|
||||
/** Caches the given 'file' with the given ID. It may be retrieved or cleared using this ID.*/
|
||||
/** Caches the given 'file' with the given ID. It may be retrieved or cleared using this ID. */
|
||||
def cacheJar(
|
||||
moduleID: ModuleID,
|
||||
file: File,
|
||||
|
|
@ -52,7 +52,7 @@ class IvyCache(val ivyHome: Option[File]) {
|
|||
}
|
||||
}
|
||||
|
||||
/** Clears the cache of the jar for the given ID.*/
|
||||
/** Clears the cache of the jar for the given ID. */
|
||||
def clearCachedJar(id: ModuleID, lock: Option[xsbti.GlobalLock], log: Logger): Unit = {
|
||||
try {
|
||||
withCachedJar(id, lock, log)(_.delete); ()
|
||||
|
|
@ -61,7 +61,7 @@ class IvyCache(val ivyHome: Option[File]) {
|
|||
}
|
||||
}
|
||||
|
||||
/** Copies the cached jar for the given ID to the directory 'toDirectory'. If the jar is not in the cache, NotInCache is thrown.*/
|
||||
/** Copies the cached jar for the given ID to the directory 'toDirectory'. If the jar is not in the cache, NotInCache is thrown. */
|
||||
def retrieveCachedJar(
|
||||
id: ModuleID,
|
||||
toDirectory: File,
|
||||
|
|
@ -74,7 +74,7 @@ class IvyCache(val ivyHome: Option[File]) {
|
|||
copyTo
|
||||
}
|
||||
|
||||
/** Get the location of the cached jar for the given ID in the Ivy cache. If the jar is not in the cache, NotInCache is thrown .*/
|
||||
/** Get the location of the cached jar for the given ID in the Ivy cache. If the jar is not in the cache, NotInCache is thrown . */
|
||||
def withCachedJar[T](id: ModuleID, lock: Option[xsbti.GlobalLock], log: Logger)(
|
||||
f: File => T
|
||||
): T = {
|
||||
|
|
@ -89,7 +89,7 @@ class IvyCache(val ivyHome: Option[File]) {
|
|||
if (cachedFile.exists) f(cachedFile) else throw new NotInCache(id)
|
||||
}
|
||||
|
||||
/** Calls the given function with the default Ivy cache.*/
|
||||
/** Calls the given function with the default Ivy cache. */
|
||||
def withDefaultCache[T](lock: Option[xsbti.GlobalLock], log: Logger)(
|
||||
f: DefaultRepositoryCacheManager => T
|
||||
): T = {
|
||||
|
|
@ -103,7 +103,7 @@ class IvyCache(val ivyHome: Option[File]) {
|
|||
}
|
||||
private def unknownOrigin(artifact: IvyArtifact) = ArtifactOrigin.unkwnown(artifact)
|
||||
|
||||
/** A minimal Ivy setup with only a local resolver and the current directory as the base directory.*/
|
||||
/** 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: Logger) = {
|
||||
val local = Resolver.defaultLocal
|
||||
val paths = IvyPaths(new File("."), ivyHome)
|
||||
|
|
@ -115,12 +115,12 @@ class IvyCache(val ivyHome: Option[File]) {
|
|||
(new IvySbt(conf, CustomHttp.defaultHttpClient), local)
|
||||
}
|
||||
|
||||
/** Creates a default jar artifact based on the given ID.*/
|
||||
/** Creates a default jar artifact based on the given ID. */
|
||||
private def defaultArtifact(moduleID: ModuleID): IvyArtifact =
|
||||
new DefaultArtifact(IvySbt.toID(moduleID), null, moduleID.name, "jar", "jar")
|
||||
}
|
||||
|
||||
/** Required by Ivy for copying to the cache.*/
|
||||
/** Required by Ivy for copying to the cache. */
|
||||
private class FileDownloader extends ResourceDownloader {
|
||||
def download(artifact: IvyArtifact, resource: Resource, dest: File): Unit = {
|
||||
if (dest.exists()) dest.delete()
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ private[sbt] final class IvyLoggerInterface(logger: Logger) extends MessageLogge
|
|||
case MSG_ERR => error(msg)
|
||||
}
|
||||
}
|
||||
//DEBUG level messages are very verbose and rarely useful to users.
|
||||
// DEBUG level messages are very verbose and rarely useful to users.
|
||||
// TODO: provide access to this information some other way
|
||||
def debug(msg: String): Unit = ()
|
||||
def verbose(msg: String): Unit = logger.verbose(msg)
|
||||
|
|
|
|||
|
|
@ -67,9 +67,11 @@ object IvyScalaUtil {
|
|||
new NamespaceTransformer {
|
||||
def transform(mrid: ModuleRevisionId): ModuleRevisionId = {
|
||||
if (mrid == null) mrid
|
||||
else if ((isScala2Artifact(mrid.getName) || isScala3Artifact(mrid.getName)) &&
|
||||
configQualifies &&
|
||||
dependeeQualifies) {
|
||||
else if (
|
||||
(isScala2Artifact(mrid.getName) || isScala3Artifact(mrid.getName)) &&
|
||||
configQualifies &&
|
||||
dependeeQualifies
|
||||
) {
|
||||
// do not override the binary incompatible Scala version because:
|
||||
// - the artifacts compiled with Scala 3 depends on the Scala 2.13 scala-library
|
||||
// - the Scala 2 TASTy reader can consume the Scala 3 artifacts
|
||||
|
|
@ -152,7 +154,8 @@ object IvyScalaUtil {
|
|||
.forall(bv => bv.startsWith("3") || bv.startsWith("2.13"))
|
||||
|
||||
def matchesOneOfTheConfigs = dep.getModuleConfigurations exists { scalaVersionConfigs }
|
||||
val mismatched = isScalaLangOrg && isScalaArtifact && hasBinVerMismatch && matchesOneOfTheConfigs
|
||||
val mismatched =
|
||||
isScalaLangOrg && isScalaArtifact && hasBinVerMismatch && matchesOneOfTheConfigs
|
||||
if (mismatched)
|
||||
Some(
|
||||
"Binary version (" + depBinaryVersion + ") for dependency " + id +
|
||||
|
|
@ -180,8 +183,7 @@ object IvyScalaUtil {
|
|||
): Unit = {
|
||||
val configurationNames = {
|
||||
val names = module.getConfigurationsNames
|
||||
if (configurations.isEmpty)
|
||||
names
|
||||
if (configurations.isEmpty) names
|
||||
else {
|
||||
val configSet = configurationSet(configurations)
|
||||
configSet.intersect(HashSet(names: _*))
|
||||
|
|
|
|||
|
|
@ -102,5 +102,6 @@ private[sbt] object ResolutionCache {
|
|||
private val Name = "sbt-resolution-cache"
|
||||
|
||||
// use sbt-specific extra attributes so that resolved xml files do not get overwritten when using different Scala/sbt versions
|
||||
private val ResolvedPattern = "[organisation]/[module]/" + Resolver.PluginPattern + "([branch]/)[revision]/[artifact].[ext]"
|
||||
private val ResolvedPattern =
|
||||
"[organisation]/[module]/" + Resolver.PluginPattern + "([branch]/)[revision]/[artifact].[ext]"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -127,8 +127,12 @@ private[sbt] class CachedResolutionResolveCache {
|
|||
val mesStr = (mes map excludeRuleString).mkString(",")
|
||||
val os = extractOverrides(parent)
|
||||
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(",")};explicitArtifacts=${explicitArtifacts
|
||||
val depsString = s"""$mrid;${confMap.mkString(
|
||||
","
|
||||
)};isForce=${dd.isForce};isChanging=${dd.isChanging};isTransitive=${dd.isTransitive};""" +
|
||||
s"""exclusions=${exclusions.mkString(",")};inclusions=${inclusions.mkString(
|
||||
","
|
||||
)};explicitArtifacts=${explicitArtifacts
|
||||
.mkString(",")};$moduleLevel;"""
|
||||
val sha1 = Hash.toHex(
|
||||
Hash(s"""graphVersion=${CachedResolutionResolveCache.graphVersion};$depsString""")
|
||||
|
|
@ -158,15 +162,14 @@ private[sbt] class CachedResolutionResolveCache {
|
|||
md0.getAllDependencyDescriptorMediators.getAllRules.asScala.toSeq.toVector sortBy {
|
||||
case (k, _) =>
|
||||
k.toString
|
||||
} collect {
|
||||
case (k: MapMatcher, v: OverrideDependencyDescriptorMediator) =>
|
||||
val attr: Map[Any, Any] = k.getAttributes.asScala.toMap
|
||||
val module = IvyModuleId.newInstance(
|
||||
attr(IvyPatternHelper.ORGANISATION_KEY).toString,
|
||||
attr(IvyPatternHelper.MODULE_KEY).toString
|
||||
)
|
||||
val pm = k.getPatternMatcher
|
||||
IvyOverride(module, pm, v)
|
||||
} collect { case (k: MapMatcher, v: OverrideDependencyDescriptorMediator) =>
|
||||
val attr: Map[Any, Any] = k.getAttributes.asScala.toMap
|
||||
val module = IvyModuleId.newInstance(
|
||||
attr(IvyPatternHelper.ORGANISATION_KEY).toString,
|
||||
attr(IvyPatternHelper.MODULE_KEY).toString
|
||||
)
|
||||
val pm = k.getPatternMatcher
|
||||
IvyOverride(module, pm, v)
|
||||
}
|
||||
}
|
||||
def getOrElseUpdateMiniGraph(
|
||||
|
|
@ -200,8 +203,10 @@ private[sbt] class CachedResolutionResolveCache {
|
|||
}
|
||||
val staticGraphDirectory = miniGraphPath / "static"
|
||||
val dynamicGraphDirectory = miniGraphPath / "dynamic"
|
||||
val staticGraphPath = staticGraphDirectory / pathScalaVersion / pathSbtVersion / pathOrg / pathName / pathRevision / "graphs" / "graph.json"
|
||||
val dynamicGraphPath = dynamicGraphDirectory / todayStr / logicalClock.toString / pathScalaVersion / pathSbtVersion / pathOrg / pathName / pathRevision / "graphs" / "graph.json"
|
||||
val staticGraphPath =
|
||||
staticGraphDirectory / pathScalaVersion / pathSbtVersion / pathOrg / pathName / pathRevision / "graphs" / "graph.json"
|
||||
val dynamicGraphPath =
|
||||
dynamicGraphDirectory / todayStr / logicalClock.toString / pathScalaVersion / pathSbtVersion / pathOrg / pathName / pathRevision / "graphs" / "graph.json"
|
||||
def cleanDynamicGraph(): Unit = {
|
||||
val list = IO.listFiles(dynamicGraphDirectory, DirectoryFilter).toList
|
||||
list filterNot { d =>
|
||||
|
|
@ -282,9 +287,12 @@ private[sbt] class CachedResolutionResolveCache {
|
|||
val moduleIdMap = Map(conflicts map { x =>
|
||||
x.module -> x
|
||||
}: _*)
|
||||
(surviving map moduleIdMap, evicted map moduleIdMap map {
|
||||
_.withEvicted(true).withEvictedReason(Some(mgr.toString))
|
||||
})
|
||||
(
|
||||
surviving map moduleIdMap,
|
||||
evicted map moduleIdMap map {
|
||||
_.withEvicted(true).withEvictedReason(Some(mgr.toString))
|
||||
}
|
||||
)
|
||||
}
|
||||
(conflictCache get ((cf0, cf1))) match {
|
||||
case Some((surviving, evicted, mgr)) => reconstructReports(surviving, evicted, mgr)
|
||||
|
|
@ -304,8 +312,7 @@ private[sbt] class CachedResolutionResolveCache {
|
|||
def getOrElseUpdateProjectReport(mrid: ModuleRevisionId, logicalClock: LogicalClock)(
|
||||
f: => Either[ResolveException, UpdateReport]
|
||||
): Either[ResolveException, UpdateReport] =
|
||||
if (projectReportCache contains (mrid -> logicalClock))
|
||||
projectReportCache((mrid, logicalClock))
|
||||
if (projectReportCache contains (mrid -> logicalClock)) projectReportCache((mrid, logicalClock))
|
||||
else {
|
||||
val oldKeys = projectReportCache.keys filter { case (_, clk) => clk != logicalClock }
|
||||
projectReportCache --= oldKeys
|
||||
|
|
@ -410,59 +417,58 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine {
|
|||
Left(new ResolveException(messages, failed, failedPaths))
|
||||
}
|
||||
}
|
||||
val (internal, external) = mds.partition {
|
||||
case (_, _, dd) => cache.internalDependency(dd, projectResolver).isDefined
|
||||
val (internal, external) = mds.partition { case (_, _, dd) =>
|
||||
cache.internalDependency(dd, projectResolver).isDefined
|
||||
}
|
||||
val internalResults = internal map {
|
||||
case (md, changing, dd) =>
|
||||
cache.getOrElseUpdateMiniGraph(
|
||||
md,
|
||||
changing,
|
||||
logicalClock,
|
||||
miniGraphPath,
|
||||
cachedDescriptor,
|
||||
log
|
||||
) {
|
||||
doWork(md, dd)
|
||||
}
|
||||
val internalResults = internal map { case (md, changing, dd) =>
|
||||
cache.getOrElseUpdateMiniGraph(
|
||||
md,
|
||||
changing,
|
||||
logicalClock,
|
||||
miniGraphPath,
|
||||
cachedDescriptor,
|
||||
log
|
||||
) {
|
||||
doWork(md, dd)
|
||||
}
|
||||
}
|
||||
val externalResults = external map {
|
||||
case (md0, changing, dd) =>
|
||||
val configurationsInInternal = internalResults flatMap {
|
||||
case Right(ur) =>
|
||||
ur.allModules.flatMap {
|
||||
case md =>
|
||||
val sameName = md.name == dd.getDependencyId.getName
|
||||
val sameOrg = md.organization == dd.getDependencyId.getOrganisation
|
||||
if (sameName && sameOrg) md.configurations
|
||||
else None
|
||||
val externalResults = external map { case (md0, changing, dd) =>
|
||||
val configurationsInInternal = internalResults flatMap {
|
||||
case Right(ur) =>
|
||||
ur.allModules.flatMap { case md =>
|
||||
val sameName = md.name == dd.getDependencyId.getName
|
||||
val sameOrg = md.organization == dd.getDependencyId.getOrganisation
|
||||
if (sameName && sameOrg) md.configurations
|
||||
else None
|
||||
}
|
||||
case _ => Nil
|
||||
}
|
||||
|
||||
dd match {
|
||||
case d: DefaultDependencyDescriptor =>
|
||||
configurationsInInternal foreach { c =>
|
||||
val configurations = c.split(";").map(_.split("->"))
|
||||
configurations foreach { conf =>
|
||||
try d.addDependencyConfiguration(conf(0), conf(1))
|
||||
catch {
|
||||
case _: Throwable => ()
|
||||
} // An exception will be thrown if `conf(0)` doesn't exist.
|
||||
}
|
||||
case _ => Nil
|
||||
}
|
||||
}
|
||||
|
||||
dd match {
|
||||
case d: DefaultDependencyDescriptor =>
|
||||
configurationsInInternal foreach { c =>
|
||||
val configurations = c.split(";").map(_.split("->"))
|
||||
configurations foreach { conf =>
|
||||
try d.addDependencyConfiguration(conf(0), conf(1))
|
||||
catch { case _: Throwable => () } // An exception will be thrown if `conf(0)` doesn't exist.
|
||||
}
|
||||
}
|
||||
case _ => ()
|
||||
}
|
||||
|
||||
case _ => ()
|
||||
}
|
||||
|
||||
cache.getOrElseUpdateMiniGraph(
|
||||
md0,
|
||||
changing,
|
||||
logicalClock,
|
||||
miniGraphPath,
|
||||
cachedDescriptor,
|
||||
log
|
||||
) {
|
||||
doWork(md0, dd)
|
||||
}
|
||||
cache.getOrElseUpdateMiniGraph(
|
||||
md0,
|
||||
changing,
|
||||
logicalClock,
|
||||
miniGraphPath,
|
||||
cachedDescriptor,
|
||||
log
|
||||
) {
|
||||
doWork(md0, dd)
|
||||
}
|
||||
}
|
||||
val results = internalResults ++ externalResults
|
||||
val uReport =
|
||||
|
|
@ -485,21 +491,20 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine {
|
|||
log: Logger
|
||||
): Either[ResolveException, UpdateReport] =
|
||||
if (!missingOk && (results exists { _.isLeft }))
|
||||
Left(mergeErrors(md0, results collect { case Left(re) => re }))
|
||||
Left(mergeErrors(md0, results collect { case Left(re) => re }))
|
||||
else Right(mergeReports(md0, results collect { case Right(ur) => ur }, resolveTime, os, log))
|
||||
|
||||
def mergeErrors(md0: ModuleDescriptor, errors: Vector[ResolveException]): ResolveException = {
|
||||
val messages = errors flatMap { _.messages }
|
||||
val failed = errors flatMap { _.failed }
|
||||
val failedPaths = errors flatMap {
|
||||
_.failedPaths.toList map {
|
||||
case (failed, paths) =>
|
||||
if (paths.isEmpty) (failed, paths)
|
||||
else
|
||||
(
|
||||
failed,
|
||||
List(IvyRetrieve.toModuleID(md0.getResolvedModuleRevisionId)) ::: paths.toList.tail
|
||||
)
|
||||
_.failedPaths.toList map { case (failed, paths) =>
|
||||
if (paths.isEmpty) (failed, paths)
|
||||
else
|
||||
(
|
||||
failed,
|
||||
List(IvyRetrieve.toModuleID(md0.getResolvedModuleRevisionId)) ::: paths.toList.tail
|
||||
)
|
||||
}
|
||||
}
|
||||
new ResolveException(messages, failed, ListMap(failedPaths: _*))
|
||||
|
|
@ -579,12 +584,11 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine {
|
|||
// this might take up some memory, but it's limited to a single
|
||||
val reports1 = reports0 flatMap { filterReports }
|
||||
val allModules0: Map[(String, String), Vector[OrganizationArtifactReport]] =
|
||||
Map(orgNamePairs map {
|
||||
case (organization, name) =>
|
||||
val xs = reports1 filter { oar =>
|
||||
oar.organization == organization && oar.name == name
|
||||
}
|
||||
((organization, name), xs)
|
||||
Map(orgNamePairs map { case (organization, name) =>
|
||||
val xs = reports1 filter { oar =>
|
||||
oar.organization == organization && oar.name == name
|
||||
}
|
||||
((organization, name), xs)
|
||||
}: _*)
|
||||
// this returns a List of Lists of (org, name). should be deterministic
|
||||
def detectLoops(
|
||||
|
|
@ -766,8 +770,8 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine {
|
|||
val completelyEvicted = xs forall { _.evicted }
|
||||
val allCallers = xs flatMap { _.callers }
|
||||
// Caller info is often repeated across the subprojects. We only need ModuleID info for later, so xs.head is ok.
|
||||
val distinctByModuleId = allCallers.groupBy({ _.caller }).toVector map {
|
||||
case (_, xs) => xs.head
|
||||
val distinctByModuleId = allCallers.groupBy({ _.caller }).toVector map { case (_, xs) =>
|
||||
xs.head
|
||||
}
|
||||
val allArtifacts = (xs flatMap { _.artifacts }).distinct
|
||||
xs.head
|
||||
|
|
@ -777,10 +781,9 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine {
|
|||
}
|
||||
val merged = (modules groupBy { m =>
|
||||
(m.module.organization, m.module.name, m.module.revision)
|
||||
}).toSeq.toVector flatMap {
|
||||
case (_, xs) =>
|
||||
if (xs.size < 2) xs
|
||||
else Vector(mergeModuleReports(xs))
|
||||
}).toSeq.toVector flatMap { case (_, xs) =>
|
||||
if (xs.size < 2) xs
|
||||
else Vector(mergeModuleReports(xs))
|
||||
}
|
||||
val conflicts = merged filter { m =>
|
||||
!m.evicted && m.problem.isEmpty
|
||||
|
|
@ -789,9 +792,12 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine {
|
|||
else
|
||||
resolveConflict(rootModuleConf, conflicts, os, log) match {
|
||||
case (survivor, evicted) =>
|
||||
(survivor ++ (merged filter { m =>
|
||||
m.evicted || m.problem.isDefined
|
||||
}), evicted)
|
||||
(
|
||||
survivor ++ (merged filter { m =>
|
||||
m.evicted || m.problem.isDefined
|
||||
}),
|
||||
evicted
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -869,9 +875,13 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine {
|
|||
}) match {
|
||||
case Some(m) =>
|
||||
log.debug(s"- directly forced dependency: $m ${m.callers}")
|
||||
(Vector(m), conflicts filterNot { _ == m } map {
|
||||
_.withEvicted(true).withEvictedReason(Some("direct-force"))
|
||||
}, "direct-force")
|
||||
(
|
||||
Vector(m),
|
||||
conflicts filterNot { _ == m } map {
|
||||
_.withEvicted(true).withEvictedReason(Some("direct-force"))
|
||||
},
|
||||
"direct-force"
|
||||
)
|
||||
case None =>
|
||||
(conflicts find { m =>
|
||||
m.callers.exists { _.isForceDependency }
|
||||
|
|
@ -879,18 +889,26 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine {
|
|||
// Ivy translates pom.xml dependencies to forced="true", so transitive force is broken.
|
||||
case Some(m) if !ignoreTransitiveForce =>
|
||||
log.debug(s"- transitively forced dependency: $m ${m.callers}")
|
||||
(Vector(m), conflicts filterNot { _ == m } map {
|
||||
_.withEvicted(true).withEvictedReason(Some("transitive-force"))
|
||||
}, "transitive-force")
|
||||
(
|
||||
Vector(m),
|
||||
conflicts filterNot { _ == m } map {
|
||||
_.withEvicted(true).withEvictedReason(Some("transitive-force"))
|
||||
},
|
||||
"transitive-force"
|
||||
)
|
||||
case _ =>
|
||||
val strategy = lcm.getStrategy
|
||||
val infos = conflicts map { ModuleReportArtifactInfo(_) }
|
||||
log.debug(s"- Using $strategy with $infos")
|
||||
Option(strategy.findLatest(infos.toArray, None.orNull)) match {
|
||||
case Some(ModuleReportArtifactInfo(m)) =>
|
||||
(Vector(m), conflicts filterNot { _ == m } map {
|
||||
_.withEvicted(true).withEvictedReason(Some(lcm.toString))
|
||||
}, lcm.toString)
|
||||
(
|
||||
Vector(m),
|
||||
conflicts filterNot { _ == m } map {
|
||||
_.withEvicted(true).withEvictedReason(Some(lcm.toString))
|
||||
},
|
||||
lcm.toString
|
||||
)
|
||||
case _ => (conflicts, Vector(), lcm.toString)
|
||||
}
|
||||
}
|
||||
|
|
@ -905,9 +923,13 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine {
|
|||
mr.module.revision == ovrVersion
|
||||
} match {
|
||||
case Some(m) =>
|
||||
(Vector(m), conflicts filterNot { _ == m } map {
|
||||
_.withEvicted(true).withEvictedReason(Some("override"))
|
||||
}, "override")
|
||||
(
|
||||
Vector(m),
|
||||
conflicts filterNot { _ == m } map {
|
||||
_.withEvicted(true).withEvictedReason(Some("override"))
|
||||
},
|
||||
"override"
|
||||
)
|
||||
case None =>
|
||||
sys.error(
|
||||
s"override dependency specifies $ovrVersion but no candidates were found: " + (conflicts map {
|
||||
|
|
@ -925,7 +947,7 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine {
|
|||
}).mkString("(", ", ", ")"))
|
||||
)
|
||||
case lcm: LatestConflictManager => useLatest(lcm)
|
||||
case conflictManager => sys.error(s"Unsupported conflict manager $conflictManager")
|
||||
case conflictManager => sys.error(s"Unsupported conflict manager $conflictManager")
|
||||
}
|
||||
}
|
||||
if (conflicts.size == 2 && os.isEmpty) {
|
||||
|
|
|
|||
|
|
@ -65,8 +65,10 @@ object ErrorMessageAuthenticator {
|
|||
}
|
||||
|
||||
try Option(ivyOriginalField.get(ivy).asInstanceOf[Authenticator]) match {
|
||||
case Some(_: ErrorMessageAuthenticator) => // We're already installed, no need to do the work again.
|
||||
case originalOpt => installIntoIvyImpl(originalOpt)
|
||||
case Some(
|
||||
_: ErrorMessageAuthenticator
|
||||
) => // We're already installed, no need to do the work again.
|
||||
case originalOpt => installIntoIvyImpl(originalOpt)
|
||||
} catch {
|
||||
case t: Throwable =>
|
||||
Message.debug(
|
||||
|
|
|
|||
|
|
@ -47,52 +47,53 @@ class GigahorseUrlHandler(http: OkHttpClient) extends AbstractURLHandler {
|
|||
|
||||
val response = http.newCall(request.build()).execute()
|
||||
try {
|
||||
val infoOption = try {
|
||||
val infoOption =
|
||||
try {
|
||||
|
||||
if (checkStatusCode(url, response)) {
|
||||
val bodyCharset =
|
||||
BasicURLHandler.getCharSetFromContentType(
|
||||
Option(response.body().contentType()).map(_.toString).orNull
|
||||
if (checkStatusCode(url, response)) {
|
||||
val bodyCharset =
|
||||
BasicURLHandler.getCharSetFromContentType(
|
||||
Option(response.body().contentType()).map(_.toString).orNull
|
||||
)
|
||||
Some(
|
||||
new SbtUrlInfo(
|
||||
true,
|
||||
response.body().contentLength(),
|
||||
lastModifiedTimestamp(response),
|
||||
bodyCharset
|
||||
)
|
||||
)
|
||||
Some(
|
||||
new SbtUrlInfo(
|
||||
true,
|
||||
response.body().contentLength(),
|
||||
lastModifiedTimestamp(response),
|
||||
bodyCharset
|
||||
)
|
||||
)
|
||||
} else None
|
||||
//
|
||||
// Commented out for now - can potentially be used for non HTTP urls
|
||||
//
|
||||
// val contentLength: Long = con.getContentLengthLong
|
||||
// if (contentLength <= 0) None
|
||||
// else {
|
||||
// // TODO: not HTTP... maybe we *don't* want to default to ISO-8559-1 here?
|
||||
// val bodyCharset = BasicURLHandler.getCharSetFromContentType(con.getContentType)
|
||||
// Some(new SbtUrlInfo(true, contentLength, con.getLastModified(), bodyCharset))
|
||||
// }
|
||||
} else None
|
||||
//
|
||||
// Commented out for now - can potentially be used for non HTTP urls
|
||||
//
|
||||
// val contentLength: Long = con.getContentLengthLong
|
||||
// if (contentLength <= 0) None
|
||||
// else {
|
||||
// // TODO: not HTTP... maybe we *don't* want to default to ISO-8559-1 here?
|
||||
// val bodyCharset = BasicURLHandler.getCharSetFromContentType(con.getContentType)
|
||||
// Some(new SbtUrlInfo(true, contentLength, con.getLastModified(), bodyCharset))
|
||||
// }
|
||||
|
||||
} catch {
|
||||
case e: UnknownHostException =>
|
||||
Message.warn("Host " + e.getMessage + " not found. url=" + url)
|
||||
Message.info(
|
||||
"You probably access the destination server through "
|
||||
+ "a proxy server that is not well configured."
|
||||
)
|
||||
None
|
||||
case e: IOException =>
|
||||
Message.error("Server access Error: " + e.getMessage + " url=" + url)
|
||||
None
|
||||
}
|
||||
} catch {
|
||||
case e: UnknownHostException =>
|
||||
Message.warn("Host " + e.getMessage + " not found. url=" + url)
|
||||
Message.info(
|
||||
"You probably access the destination server through "
|
||||
+ "a proxy server that is not well configured."
|
||||
)
|
||||
None
|
||||
case e: IOException =>
|
||||
Message.error("Server access Error: " + e.getMessage + " url=" + url)
|
||||
None
|
||||
}
|
||||
infoOption.getOrElse(UNAVAILABLE)
|
||||
} finally {
|
||||
response.close()
|
||||
}
|
||||
}
|
||||
|
||||
//The caller of this *MUST* call Response.close()
|
||||
// The caller of this *MUST* call Response.close()
|
||||
private def getUrl(url0: URL): okhttp3.Response = {
|
||||
// Install the ErrorMessageAuthenticator
|
||||
if ("http" == url0.getProtocol || "https" == url0.getProtocol) {
|
||||
|
|
@ -117,7 +118,7 @@ class GigahorseUrlHandler(http: OkHttpClient) extends AbstractURLHandler {
|
|||
response
|
||||
} catch {
|
||||
case NonFatal(e) =>
|
||||
//ensure the response gets closed if there's an error
|
||||
// ensure the response gets closed if there's an error
|
||||
response.close()
|
||||
throw e
|
||||
}
|
||||
|
|
@ -125,7 +126,7 @@ class GigahorseUrlHandler(http: OkHttpClient) extends AbstractURLHandler {
|
|||
}
|
||||
|
||||
def openStream(url: URL): InputStream = {
|
||||
//It's assumed that the caller of this will call close() on the supplied inputstream,
|
||||
// It's assumed that the caller of this will call close() on the supplied inputstream,
|
||||
// thus closing the OkHTTP request
|
||||
getUrl(url).body().byteStream()
|
||||
}
|
||||
|
|
@ -201,7 +202,8 @@ class GigahorseUrlHandler(http: OkHttpClient) extends AbstractURLHandler {
|
|||
}
|
||||
}
|
||||
|
||||
private val ErrorBodyTruncateLen = 512 // in case some bad service returns files rather than messages in error bodies
|
||||
private val ErrorBodyTruncateLen =
|
||||
512 // in case some bad service returns files rather than messages in error bodies
|
||||
private val DefaultErrorCharset = java.nio.charset.StandardCharsets.UTF_8
|
||||
|
||||
// neurotic resource managemement...
|
||||
|
|
|
|||
|
|
@ -56,8 +56,8 @@ private[sbt] object IvyCredentialsLookup {
|
|||
* A mapping of host -> realms in the ivy credentials store.
|
||||
*/
|
||||
def realmsForHost: Map[String, Set[String]] =
|
||||
(keyringKeys collect {
|
||||
case x: Realm => x
|
||||
(keyringKeys collect { case x: Realm =>
|
||||
x
|
||||
} groupBy { realm =>
|
||||
realm.host
|
||||
} mapValues { realms =>
|
||||
|
|
|
|||
|
|
@ -13,14 +13,14 @@ private[sbt] object MergeDescriptors {
|
|||
a.isTransitive == b.isTransitive &&
|
||||
a.getParentRevisionId == b.getParentRevisionId &&
|
||||
a.getNamespace == b.getNamespace && {
|
||||
val amrid = a.getDependencyRevisionId
|
||||
val bmrid = b.getDependencyRevisionId
|
||||
amrid == bmrid
|
||||
} && {
|
||||
val adyn = a.getDynamicConstraintDependencyRevisionId
|
||||
val bdyn = b.getDynamicConstraintDependencyRevisionId
|
||||
adyn == bdyn
|
||||
}
|
||||
val amrid = a.getDependencyRevisionId
|
||||
val bmrid = b.getDependencyRevisionId
|
||||
amrid == bmrid
|
||||
} && {
|
||||
val adyn = a.getDynamicConstraintDependencyRevisionId
|
||||
val bdyn = b.getDynamicConstraintDependencyRevisionId
|
||||
adyn == bdyn
|
||||
}
|
||||
|
||||
def apply(a: DependencyDescriptor, b: DependencyDescriptor): DependencyDescriptor = {
|
||||
assert(mergeable(a, b))
|
||||
|
|
|
|||
|
|
@ -48,17 +48,18 @@ private[sbt] class ParallelResolveEngine(
|
|||
}
|
||||
// Farm out the dependencies for parallel download
|
||||
implicit val ec = ParallelResolveEngine.resolveExecutionContext
|
||||
val allDownloadsFuture = Future.traverse(report.getDependencies.asScala) {
|
||||
case dep: IvyNode =>
|
||||
Future {
|
||||
if (!(dep.isCompletelyEvicted || dep.hasProblem) &&
|
||||
dep.getModuleRevision != null) {
|
||||
Some(downloadNodeArtifacts(dep, artifactFilter, options))
|
||||
} else None
|
||||
}
|
||||
val allDownloadsFuture = Future.traverse(report.getDependencies.asScala) { case dep: IvyNode =>
|
||||
Future {
|
||||
if (
|
||||
!(dep.isCompletelyEvicted || dep.hasProblem) &&
|
||||
dep.getModuleRevision != null
|
||||
) {
|
||||
Some(downloadNodeArtifacts(dep, artifactFilter, options))
|
||||
} else None
|
||||
}
|
||||
}
|
||||
val allDownloads = Await.result(allDownloadsFuture, Duration.Inf)
|
||||
//compute total downloaded size
|
||||
// compute total downloaded size
|
||||
val totalSize = allDownloads.foldLeft(0L) {
|
||||
case (size, Some(download)) =>
|
||||
val dependency = download.dep
|
||||
|
|
@ -67,8 +68,10 @@ private[sbt] class ParallelResolveEngine(
|
|||
val configurationReport = report.getConfigurationReport(configuration)
|
||||
|
||||
// Take into account artifacts required by the given configuration
|
||||
if (dependency.isEvicted(configuration) ||
|
||||
dependency.isBlacklisted(configuration)) {
|
||||
if (
|
||||
dependency.isEvicted(configuration) ||
|
||||
dependency.isBlacklisted(configuration)
|
||||
) {
|
||||
configurationReport.addDependency(dependency)
|
||||
} else configurationReport.addDependency(dependency, download.report)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -124,7 +124,8 @@ private[sbt] case class SbtChainResolver(
|
|||
/** If None, module was not found. Otherwise, hit. */
|
||||
type TriedResolution = Option[(ResolvedModuleRevision, DependencyResolver)]
|
||||
|
||||
/** Attempts to resolve the artifact from each of the resolvers in the chain.
|
||||
/**
|
||||
* Attempts to resolve the artifact from each of the resolvers in the chain.
|
||||
*
|
||||
* Contract:
|
||||
* 1. It doesn't resolve anything when there is a resolved module, `isReturnFirst` is
|
||||
|
|
@ -155,8 +156,8 @@ private[sbt] case class SbtChainResolver(
|
|||
currentlyResolved = Option(resolver.getDependency(descriptor, data))
|
||||
if (currentlyResolved eq previouslyResolved) None
|
||||
else if (useLatest) {
|
||||
currentlyResolved.map(
|
||||
x => (reparseModuleDescriptor(descriptor, data, resolver, x), resolver)
|
||||
currentlyResolved.map(x =>
|
||||
(reparseModuleDescriptor(descriptor, data, resolver, x), resolver)
|
||||
)
|
||||
} else currentlyResolved.map(x => (forcedRevision(x), resolver))
|
||||
}
|
||||
|
|
@ -174,7 +175,8 @@ private[sbt] case class SbtChainResolver(
|
|||
val oldLatest: Option[LatestStrategy] =
|
||||
setLatestIfRequired(resolver, Option(getLatestStrategy))
|
||||
try Right(performResolution(resolver))
|
||||
catch { case NonFatal(t) => reportError(t, resolver); Left(t) } finally {
|
||||
catch { case NonFatal(t) => reportError(t, resolver); Left(t) }
|
||||
finally {
|
||||
oldLatest.foreach(_ => doSetLatestStrategy(resolver, oldLatest))
|
||||
checkInterrupted()
|
||||
}
|
||||
|
|
@ -189,34 +191,33 @@ private[sbt] case class SbtChainResolver(
|
|||
data: ResolveData
|
||||
): Option[ResolvedModuleRevision] = {
|
||||
|
||||
val sortedRevisions = foundRevisions.sortBy {
|
||||
case (rmr, resolver) =>
|
||||
val publicationDate = rmr.getPublicationDate
|
||||
val descriptorDate = rmr.getDescriptor.getPublicationDate
|
||||
Message.warn(s"Sorting results from $rmr, using $publicationDate and $descriptorDate.")
|
||||
// Just issue warning about issues with publication date, and fake one on it for now
|
||||
val chosenPublicationDate = Option(publicationDate).orElse(Option(descriptorDate))
|
||||
chosenPublicationDate match {
|
||||
case Some(date) => date.getTime
|
||||
case None =>
|
||||
val id = rmr.getId
|
||||
val resolvedResource = (resolver.findIvyFileRef(descriptor, data), rmr.getDescriptor)
|
||||
resolvedResource match {
|
||||
case (res: ResolvedResource, dmd: DefaultModuleDescriptor) =>
|
||||
val resolvedPublicationDate = new java.util.Date(res.getLastModified)
|
||||
Message.debug(s"No publication date from resolver $resolver for $id.")
|
||||
Message.debug(s"Setting publication date to: $resolvedPublicationDate.")
|
||||
dmd.setPublicationDate(resolvedPublicationDate)
|
||||
res.getLastModified
|
||||
case (ivf, dmd) =>
|
||||
// The dependency is specified by a direct URL or some sort of non-ivy file
|
||||
if (ivf == null && descriptor.isChanging)
|
||||
Message.warn(s"$prefix: changing dependency $id with no ivy/pom file!")
|
||||
if (dmd == null)
|
||||
Message.warn(s"$prefix: no publication date from resolver $resolver for $id")
|
||||
0L
|
||||
}
|
||||
}
|
||||
val sortedRevisions = foundRevisions.sortBy { case (rmr, resolver) =>
|
||||
val publicationDate = rmr.getPublicationDate
|
||||
val descriptorDate = rmr.getDescriptor.getPublicationDate
|
||||
Message.warn(s"Sorting results from $rmr, using $publicationDate and $descriptorDate.")
|
||||
// Just issue warning about issues with publication date, and fake one on it for now
|
||||
val chosenPublicationDate = Option(publicationDate).orElse(Option(descriptorDate))
|
||||
chosenPublicationDate match {
|
||||
case Some(date) => date.getTime
|
||||
case None =>
|
||||
val id = rmr.getId
|
||||
val resolvedResource = (resolver.findIvyFileRef(descriptor, data), rmr.getDescriptor)
|
||||
resolvedResource match {
|
||||
case (res: ResolvedResource, dmd: DefaultModuleDescriptor) =>
|
||||
val resolvedPublicationDate = new java.util.Date(res.getLastModified)
|
||||
Message.debug(s"No publication date from resolver $resolver for $id.")
|
||||
Message.debug(s"Setting publication date to: $resolvedPublicationDate.")
|
||||
dmd.setPublicationDate(resolvedPublicationDate)
|
||||
res.getLastModified
|
||||
case (ivf, dmd) =>
|
||||
// The dependency is specified by a direct URL or some sort of non-ivy file
|
||||
if (ivf == null && descriptor.isChanging)
|
||||
Message.warn(s"$prefix: changing dependency $id with no ivy/pom file!")
|
||||
if (dmd == null)
|
||||
Message.warn(s"$prefix: no publication date from resolver $resolver for $id")
|
||||
0L
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val firstHit = sortedRevisions.reverse.headOption
|
||||
|
|
@ -277,12 +278,11 @@ private[sbt] case class SbtChainResolver(
|
|||
}
|
||||
|
||||
/** Cleans unnecessary module id information not provided by [[IvyRetrieve.toModuleID()]]. */
|
||||
private final val moduleResolvers = updateOptions.moduleResolvers.map {
|
||||
case (key, value) =>
|
||||
val cleanKey = ModuleID(key.organization, key.name, key.revision)
|
||||
.withExtraAttributes(key.extraAttributes)
|
||||
.withBranchName(key.branchName)
|
||||
cleanKey -> value
|
||||
private final val moduleResolvers = updateOptions.moduleResolvers.map { case (key, value) =>
|
||||
val cleanKey = ModuleID(key.organization, key.name, key.revision)
|
||||
.withExtraAttributes(key.extraAttributes)
|
||||
.withBranchName(key.branchName)
|
||||
cleanKey -> value
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -309,7 +309,8 @@ private[sbt] case class SbtChainResolver(
|
|||
def findInterProjectResolver(resolvers: Seq[DependencyResolver]): Option[DependencyResolver] =
|
||||
resolvers.find(_.getName == ProjectResolver.InterProject)
|
||||
|
||||
/** Gets the dependency for a given descriptor with the pertinent resolve data.
|
||||
/**
|
||||
* Gets the dependency for a given descriptor with the pertinent resolve data.
|
||||
*
|
||||
* This is a custom sbt chain operation that produces better error output and deals with
|
||||
* cases that the conventional ivy resolver does not. It accumulates the resolution of
|
||||
|
|
|
|||
Loading…
Reference in New Issue