mirror of https://github.com/sbt/sbt.git
Merge pull request #304 from alexarchambault/topic/develop
Various fixes
This commit is contained in:
commit
3c7d3b8443
|
|
@ -48,7 +48,7 @@ if echo "$TRAVIS_SCALA_VERSION" | grep -q "^2\.10"; then
|
|||
SBT_COMMANDS="$SBT_COMMANDS plugin/scripted"
|
||||
fi
|
||||
|
||||
SBT_COMMANDS="$SBT_COMMANDS coreJVM/mimaReportBinaryIssues cache/mimaReportBinaryIssues"
|
||||
SBT_COMMANDS="$SBT_COMMANDS tut coreJVM/mimaReportBinaryIssues cache/mimaReportBinaryIssues"
|
||||
|
||||
if isNotPr && publish && isMaster; then
|
||||
SBT_COMMANDS="$SBT_COMMANDS publish"
|
||||
|
|
|
|||
|
|
@ -447,7 +447,7 @@ scala> val repositories = Seq(
|
|||
| Cache.ivy2Local,
|
||||
| MavenRepository("https://repo1.maven.org/maven2")
|
||||
| )
|
||||
repositories: Seq[coursier.core.Repository] = List(IvyRepository(file://${user.home}/.ivy2/local/[organisation]/[module]/(scala_[scalaVersion]/)(sbt_[sbtVersion]/)[revision]/[type]s/[artifact](-[classifier]).[ext],None,None,Map(),true,true,true,true,None), MavenRepository(https://repo1.maven.org/maven2,None,false,None))
|
||||
repositories: Seq[coursier.core.Repository] = List(IvyRepository(Pattern(List(Const(file://), Var(user.home), Const(/local/), Var(organisation), Const(/), Var(module), Const(/), Opt(WrappedArray(Const(scala_), Var(scalaVersion), Const(/))), Opt(WrappedArray(Const(sbt_), Var(sbtVersion), Const(/))), Var(revision), Const(/), Var(type), Const(s/), Var(artifact), Opt(WrappedArray(Const(-), Var(classifier))), Const(.), Var(ext))),None,None,true,true,true,true,None), MavenRepository(https://repo1.maven.org/maven2,None,false,None))
|
||||
```
|
||||
The first one, `Cache.ivy2Local`, is defined in `coursier.Cache`, itself from the `coursier-cache` module that
|
||||
we added above. As we can see, it is an `IvyRepository`, picking things under `~/.ivy2/local`. An `IvyRepository`
|
||||
|
|
@ -554,6 +554,8 @@ We're using the `Cache.file` method, that can also be given a `Logger` (for more
|
|||
|
||||
#### Inter-project repository in the SBT plugin is a bit naive
|
||||
|
||||
**Fixed in 1.0.0-M13**
|
||||
|
||||
The inter-project repository is the pseudo-repository, nesting the metadata
|
||||
of sub-projects. It gets confused in at least these two cases:
|
||||
|
||||
|
|
|
|||
|
|
@ -148,6 +148,14 @@ lazy val core = crossProject
|
|||
|
||||
Seq(
|
||||
// Since 1.0.0-M13
|
||||
// reworked VersionConstraint
|
||||
ProblemFilters.exclude[MissingClassProblem]("coursier.core.VersionConstraint$Interval"),
|
||||
ProblemFilters.exclude[MissingClassProblem]("coursier.core.VersionConstraint$Preferred"),
|
||||
ProblemFilters.exclude[MissingClassProblem]("coursier.core.VersionConstraint$Preferred$"),
|
||||
ProblemFilters.exclude[MissingClassProblem]("coursier.core.VersionConstraint$Interval$"),
|
||||
ProblemFilters.exclude[FinalClassProblem]("coursier.core.VersionConstraint"),
|
||||
ProblemFilters.exclude[IncompatibleResultTypeProblem]("coursier.core.VersionConstraint.repr"),
|
||||
ProblemFilters.exclude[IncompatibleMethTypeProblem]("coursier.core.VersionConstraint.this"),
|
||||
// Extra `actualVersion` field in `Project`
|
||||
ProblemFilters.exclude[MissingTypesProblem]("coursier.core.Project$"),
|
||||
ProblemFilters.exclude[MissingMethodProblem]("coursier.core.Project.apply"),
|
||||
|
|
|
|||
|
|
@ -75,10 +75,12 @@ case class Bootstrap(
|
|||
|
||||
val helper = new Helper(options.common, remainingArgs)
|
||||
|
||||
val isolatedDeps = options.isolated.isolatedDeps(options.common.defaultArtifactType)
|
||||
|
||||
val (_, isolatedArtifactFiles) =
|
||||
options.isolated.targets.foldLeft((Vector.empty[String], Map.empty[String, (Seq[String], Seq[File])])) {
|
||||
case ((done, acc), target) =>
|
||||
val subRes = helper.res.subset(options.isolated.isolatedDeps.getOrElse(target, Nil).toSet)
|
||||
val subRes = helper.res.subset(isolatedDeps.getOrElse(target, Nil).toSet)
|
||||
val subArtifacts = subRes.artifacts.map(_.url)
|
||||
|
||||
val filteredSubArtifacts = subArtifacts.diff(done)
|
||||
|
|
@ -86,7 +88,7 @@ case class Bootstrap(
|
|||
def subFiles0 = helper.fetch(
|
||||
sources = false,
|
||||
javadoc = false,
|
||||
subset = options.isolated.isolatedDeps.getOrElse(target, Seq.empty).toSet
|
||||
subset = isolatedDeps.getOrElse(target, Seq.empty).toSet
|
||||
)
|
||||
|
||||
val (subUrls, subFiles) =
|
||||
|
|
|
|||
|
|
@ -244,6 +244,7 @@ class Helper(
|
|||
Dependency(
|
||||
module,
|
||||
version,
|
||||
attributes = Attributes(defaultArtifactType, ""),
|
||||
configuration = configOpt.getOrElse(defaultConfiguration),
|
||||
exclusions = excludes
|
||||
)
|
||||
|
|
@ -254,6 +255,7 @@ class Helper(
|
|||
Dependency(
|
||||
module,
|
||||
version,
|
||||
attributes = Attributes(defaultArtifactType, ""),
|
||||
configuration = configOpt.getOrElse(defaultConfiguration),
|
||||
exclusions = excludes,
|
||||
transitive = false
|
||||
|
|
|
|||
|
|
@ -104,6 +104,9 @@ case class Launch(
|
|||
if (options.isolated.isolated.isEmpty)
|
||||
(parentLoader0, files0)
|
||||
else {
|
||||
|
||||
val isolatedDeps = options.isolated.isolatedDeps(options.common.defaultArtifactType)
|
||||
|
||||
val (isolatedLoader, filteredFiles0) = options.isolated.targets.foldLeft((parentLoader0, files0)) {
|
||||
case ((parent, files0), target) =>
|
||||
|
||||
|
|
@ -111,7 +114,7 @@ case class Launch(
|
|||
val isolatedFiles = helper.fetch(
|
||||
sources = false,
|
||||
javadoc = false,
|
||||
subset = options.isolated.isolatedDeps.getOrElse(target, Seq.empty).toSet
|
||||
subset = isolatedDeps.getOrElse(target, Seq.empty).toSet
|
||||
)
|
||||
|
||||
if (options.common.verbosityLevel >= 2) {
|
||||
|
|
@ -199,6 +202,7 @@ case class Launch(
|
|||
Helper.errPrintln(s"Error: method main not found in $mainClass0")
|
||||
sys.exit(255)
|
||||
}
|
||||
method.setAccessible(true)
|
||||
|
||||
if (options.common.verbosityLevel >= 2)
|
||||
Helper.errPrintln(s"Launching $mainClass0 ${userArgs.mkString(" ")}")
|
||||
|
|
@ -206,5 +210,9 @@ case class Launch(
|
|||
Helper.errPrintln(s"Launching")
|
||||
|
||||
Thread.currentThread().setContextClassLoader(loader)
|
||||
method.invoke(null, userArgs.toArray)
|
||||
try method.invoke(null, userArgs.toArray)
|
||||
catch {
|
||||
case e: java.lang.reflect.InvocationTargetException =>
|
||||
throw Option(e.getCause).getOrElse(e)
|
||||
}
|
||||
}
|
||||
|
|
@ -58,6 +58,10 @@ case class CommonOptions(
|
|||
@Value("configuration")
|
||||
@Short("c")
|
||||
defaultConfiguration: String = "default(compile)",
|
||||
@Help("Default artifact type (make it empty to follow POM packaging - default: jar)")
|
||||
@Value("type")
|
||||
@Short("a")
|
||||
defaultArtifactType: String = "jar",
|
||||
@Help("Maximum number of parallel downloads (default: 6)")
|
||||
@Short("n")
|
||||
parallel: Int = 6,
|
||||
|
|
@ -145,13 +149,19 @@ case class IsolatedLoaderOptions(
|
|||
t -> modVers
|
||||
}
|
||||
|
||||
lazy val isolatedDeps = isolatedModuleVersions.map {
|
||||
case (t, l) =>
|
||||
t -> l.map {
|
||||
case (mod, ver) =>
|
||||
Dependency(mod, ver, configuration = "runtime")
|
||||
}
|
||||
}
|
||||
def isolatedDeps(defaultArtifactType: String) =
|
||||
isolatedModuleVersions.map {
|
||||
case (t, l) =>
|
||||
t -> l.map {
|
||||
case (mod, ver) =>
|
||||
Dependency(
|
||||
mod,
|
||||
ver,
|
||||
configuration = "runtime",
|
||||
attributes = Attributes(defaultArtifactType, "")
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -43,12 +43,12 @@ object Parse {
|
|||
}
|
||||
|
||||
def versionConstraint(s: String): Option[VersionConstraint] = {
|
||||
def noConstraint = if (s.isEmpty) Some(VersionConstraint.None) else None
|
||||
def noConstraint = if (s.isEmpty) Some(VersionConstraint.all) else None
|
||||
|
||||
noConstraint
|
||||
.orElse(ivyLatestSubRevisionInterval(s).map(VersionConstraint.Interval))
|
||||
.orElse(version(s).map(VersionConstraint.Preferred))
|
||||
.orElse(versionInterval(s).map(VersionConstraint.Interval))
|
||||
.orElse(ivyLatestSubRevisionInterval(s).map(VersionConstraint.interval))
|
||||
.orElse(version(s).map(VersionConstraint.preferred))
|
||||
.orElse(versionInterval(s).map(VersionConstraint.interval))
|
||||
}
|
||||
|
||||
val fallbackConfigRegex = {
|
||||
|
|
|
|||
|
|
@ -140,25 +140,26 @@ object Resolution {
|
|||
* Returns `None` in case of conflict.
|
||||
*/
|
||||
def mergeVersions(versions: Seq[String]): Option[String] = {
|
||||
val (nonParsedConstraints, parsedConstraints) =
|
||||
versions
|
||||
.map(v => v -> Parse.versionConstraint(v))
|
||||
.partition(_._2.isEmpty)
|
||||
|
||||
val parseResults = versions.map(v => v -> Parse.versionConstraint(v))
|
||||
|
||||
val nonParsedConstraints = parseResults.collect {
|
||||
case (repr, None) => repr
|
||||
}
|
||||
|
||||
// FIXME Report this in return type, not this way
|
||||
if (nonParsedConstraints.nonEmpty)
|
||||
Console.err.println(
|
||||
s"Ignoring unparsed versions: ${nonParsedConstraints.map(_._1)}"
|
||||
s"Ignoring unparsed versions: $nonParsedConstraints"
|
||||
)
|
||||
|
||||
val intervalOpt =
|
||||
(Option(VersionInterval.zero) /: parsedConstraints) {
|
||||
case (acc, (_, someCstr)) =>
|
||||
acc.flatMap(_.merge(someCstr.get.interval))
|
||||
}
|
||||
val parsedConstraints = parseResults.collect {
|
||||
case (_, Some(c)) => c
|
||||
}
|
||||
|
||||
intervalOpt
|
||||
.map(_.constraint.repr)
|
||||
VersionConstraint
|
||||
.merge(parsedConstraints: _*)
|
||||
.flatMap(_.repr)
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -1,5 +1,8 @@
|
|||
package coursier.core
|
||||
|
||||
import scalaz.{ -\/, \/, \/- }
|
||||
import scalaz.Scalaz.ToEitherOps
|
||||
|
||||
case class VersionInterval(from: Option[Version],
|
||||
to: Option[Version],
|
||||
fromIncluded: Boolean,
|
||||
|
|
@ -64,9 +67,9 @@ case class VersionInterval(from: Option[Version],
|
|||
|
||||
def constraint: VersionConstraint =
|
||||
this match {
|
||||
case VersionInterval.zero => VersionConstraint.None
|
||||
case VersionInterval(Some(version), None, true, false) => VersionConstraint.Preferred(version)
|
||||
case itv => VersionConstraint.Interval(itv)
|
||||
case VersionInterval.zero => VersionConstraint.all
|
||||
case VersionInterval(Some(version), None, true, false) => VersionConstraint.preferred(version)
|
||||
case itv => VersionConstraint.interval(itv)
|
||||
}
|
||||
|
||||
def repr: String = Seq(
|
||||
|
|
@ -82,23 +85,54 @@ object VersionInterval {
|
|||
val zero = VersionInterval(None, None, fromIncluded = false, toIncluded = false)
|
||||
}
|
||||
|
||||
sealed abstract class VersionConstraint(
|
||||
val interval: VersionInterval,
|
||||
val repr: String
|
||||
)
|
||||
final case class VersionConstraint(
|
||||
interval: VersionInterval,
|
||||
preferred: Seq[Version]
|
||||
) {
|
||||
def blend: Option[VersionInterval \/ Version] =
|
||||
if (interval.isValid) {
|
||||
val preferredInInterval = preferred.filter(interval.contains)
|
||||
|
||||
if (preferredInInterval.isEmpty)
|
||||
Some(interval.left)
|
||||
else
|
||||
Some(preferredInInterval.max.right)
|
||||
} else
|
||||
None
|
||||
|
||||
def repr: Option[String] =
|
||||
blend.map {
|
||||
case -\/(itv) =>
|
||||
if (itv == VersionInterval.zero)
|
||||
""
|
||||
else
|
||||
itv.repr
|
||||
case \/-(v) => v.repr
|
||||
}
|
||||
}
|
||||
|
||||
object VersionConstraint {
|
||||
/** Currently treated as minimum... */
|
||||
final case class Preferred(version: Version) extends VersionConstraint(
|
||||
VersionInterval(Some(version), Option.empty, fromIncluded = true, toIncluded = false),
|
||||
version.repr
|
||||
)
|
||||
final case class Interval(interval0: VersionInterval) extends VersionConstraint(
|
||||
interval0,
|
||||
interval0.repr
|
||||
)
|
||||
case object None extends VersionConstraint(
|
||||
VersionInterval.zero,
|
||||
"" // Once parsed, "(,)" becomes "" because of this
|
||||
)
|
||||
|
||||
def preferred(version: Version): VersionConstraint =
|
||||
VersionConstraint(VersionInterval.zero, Seq(version))
|
||||
def interval(interval: VersionInterval): VersionConstraint =
|
||||
VersionConstraint(interval, Nil)
|
||||
|
||||
val all = VersionConstraint(VersionInterval.zero, Nil)
|
||||
|
||||
def merge(constraints: VersionConstraint*): Option[VersionConstraint] = {
|
||||
|
||||
val intervals = constraints.map(_.interval)
|
||||
|
||||
val intervalOpt =
|
||||
(Option(VersionInterval.zero) /: intervals) {
|
||||
case (acc, itv) =>
|
||||
acc.flatMap(_.merge(itv))
|
||||
}
|
||||
|
||||
for (interval <- intervalOpt) yield {
|
||||
val preferreds = constraints.flatMap(_.preferred).distinct
|
||||
VersionConstraint(interval, preferreds)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -48,7 +48,12 @@ object MavenRepository {
|
|||
val defaultPackaging = "jar"
|
||||
|
||||
def defaultPublications(moduleName: String, packaging: String) = Seq(
|
||||
"compile" -> Publication(moduleName, packaging, MavenSource.typeExtension(packaging), ""),
|
||||
"compile" -> Publication(
|
||||
moduleName,
|
||||
packaging,
|
||||
MavenSource.typeExtension(packaging),
|
||||
MavenSource.typeDefaultClassifier(packaging)
|
||||
),
|
||||
"docs" -> Publication(moduleName, "doc", "jar", "javadoc"),
|
||||
"sources" -> Publication(moduleName, "src", "jar", "sources")
|
||||
)
|
||||
|
|
|
|||
|
|
@ -136,12 +136,20 @@ case class MavenSource(
|
|||
if (publications.isEmpty) {
|
||||
val type0 = if (dependency.attributes.`type`.isEmpty) "jar" else dependency.attributes.`type`
|
||||
|
||||
val extension = MavenSource.typeExtension(type0)
|
||||
|
||||
val classifier =
|
||||
if (dependency.attributes.classifier.isEmpty)
|
||||
MavenSource.typeDefaultClassifier(type0)
|
||||
else
|
||||
dependency.attributes.classifier
|
||||
|
||||
Seq(
|
||||
Publication(
|
||||
dependency.module.name,
|
||||
type0,
|
||||
MavenSource.typeExtension(type0),
|
||||
dependency.attributes.classifier
|
||||
extension,
|
||||
classifier
|
||||
)
|
||||
)
|
||||
} else
|
||||
|
|
@ -163,10 +171,27 @@ object MavenSource {
|
|||
"jar" -> "jar",
|
||||
"bundle" -> "jar",
|
||||
"doc" -> "jar",
|
||||
"src" -> "jar"
|
||||
"src" -> "jar",
|
||||
"test-jar" -> "jar",
|
||||
"ejb-client" -> "jar"
|
||||
)
|
||||
|
||||
def typeExtension(`type`: String): String =
|
||||
typeExtensions.getOrElse(`type`, `type`)
|
||||
|
||||
// see https://github.com/apache/maven/blob/c023e58104b71e27def0caa034d39ab0fa0373b6/maven-core/src/main/resources/META-INF/plexus/artifact-handlers.xml
|
||||
// discussed in https://github.com/alexarchambault/coursier/issues/298
|
||||
val typeDefaultClassifiers: Map[String, String] = Map(
|
||||
"test-jar" -> "tests",
|
||||
"javadoc" -> "javadoc",
|
||||
"java-source" -> "sources",
|
||||
"ejb-client" -> "client"
|
||||
)
|
||||
|
||||
def typeDefaultClassifierOpt(`type`: String): Option[String] =
|
||||
typeDefaultClassifiers.get(`type`)
|
||||
|
||||
def typeDefaultClassifier(`type`: String): String =
|
||||
typeDefaultClassifierOpt(`type`).getOrElse("")
|
||||
|
||||
}
|
||||
|
|
@ -11,7 +11,7 @@ package object coursier {
|
|||
version: String,
|
||||
// Substituted by Resolver with its own default configuration (compile)
|
||||
configuration: String = "",
|
||||
attributes: Attributes = Attributes(),
|
||||
attributes: Attributes = Attributes("jar"),
|
||||
exclusions: Set[(String, String)] = Set.empty,
|
||||
optional: Boolean = false,
|
||||
transitive: Boolean = true
|
||||
|
|
|
|||
|
|
@ -136,7 +136,7 @@ object Parse {
|
|||
else if (s.startsWith("sonatype:"))
|
||||
MavenRepository(s"https://oss.sonatype.org/content/repositories/${s.stripPrefix("sonatype:")}").right
|
||||
else if (s.startsWith("bintray:"))
|
||||
MavenRepository(s"https://dl.bintray.com/${s.stripPrefix("bintray:")}/maven").right
|
||||
MavenRepository(s"https://dl.bintray.com/${s.stripPrefix("bintray:")}").right
|
||||
else if (s.startsWith("typesafe:ivy-"))
|
||||
IvyRepository.fromPattern(
|
||||
(s"https://repo.typesafe.com/typesafe/ivy-" + s.stripPrefix("typesafe:ivy-") + "/") +:
|
||||
|
|
|
|||
|
|
@ -135,8 +135,13 @@ object Cache {
|
|||
// but it would then have required properties, which would have cluttered
|
||||
// output here.
|
||||
|
||||
val ivy2Local = coursier.Cache.ivy2Local.copy(
|
||||
pattern = coursier.Cache.ivy2Local.pattern.replace("file:" + sys.props("user.home"), "file://${user.home}")
|
||||
import coursier.ivy.Pattern.Chunk, Chunk._
|
||||
|
||||
val ivy2Local = coursier.ivy.IvyRepository.fromPattern(
|
||||
coursier.ivy.Pattern(
|
||||
Seq[Chunk]("file://", Var("user.home"), "/local/") ++ coursier.ivy.Pattern.default.chunks
|
||||
),
|
||||
dropInfoAttributes = true
|
||||
)
|
||||
|
||||
def fetch() = coursier.Cache.fetch()
|
||||
|
|
@ -576,6 +581,8 @@ We're using the `Cache.file` method, that can also be given a `Logger` (for more
|
|||
|
||||
#### Inter-project repository in the SBT plugin is a bit naive
|
||||
|
||||
**Fixed in 1.0.0-M13**
|
||||
|
||||
The inter-project repository is the pseudo-repository, nesting the metadata
|
||||
of sub-projects. It gets confused in at least these two cases:
|
||||
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ object CoursierPlugin extends AutoPlugin {
|
|||
val coursierFallbackDependencies = Keys.coursierFallbackDependencies
|
||||
val coursierCache = Keys.coursierCache
|
||||
val coursierProject = Keys.coursierProject
|
||||
val coursierProjects = Keys.coursierProjects
|
||||
val coursierInterProjectDependencies = Keys.coursierInterProjectDependencies
|
||||
val coursierPublications = Keys.coursierPublications
|
||||
val coursierSbtClassifiersModule = Keys.coursierSbtClassifiersModule
|
||||
|
||||
|
|
@ -67,7 +67,7 @@ object CoursierPlugin extends AutoPlugin {
|
|||
coursierSourceRepositories := Nil,
|
||||
coursierResolvers <<= Tasks.coursierResolversTask,
|
||||
coursierSbtResolvers <<= externalResolvers in updateSbtClassifiers,
|
||||
coursierUseSbtCredentials := true,
|
||||
coursierUseSbtCredentials := false,
|
||||
coursierCredentials := Map.empty,
|
||||
coursierFallbackDependencies <<= Tasks.coursierFallbackDependenciesTask,
|
||||
coursierCache := Cache.default,
|
||||
|
|
@ -82,7 +82,7 @@ object CoursierPlugin extends AutoPlugin {
|
|||
ignoreArtifactErrors = true
|
||||
),
|
||||
coursierProject <<= Tasks.coursierProjectTask,
|
||||
coursierProjects <<= Tasks.coursierProjectsTask,
|
||||
coursierInterProjectDependencies <<= Tasks.coursierInterProjectDependenciesTask,
|
||||
coursierPublications <<= Tasks.coursierPublicationsTask,
|
||||
coursierSbtClassifiersModule <<= classifiersModule in updateSbtClassifiers,
|
||||
coursierConfigurations <<= Tasks.coursierConfigurationsTask,
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ object Keys {
|
|||
val coursierFallbackDependencies = TaskKey[Seq[(Module, String, URL, Boolean)]]("coursier-fallback-dependencies")
|
||||
|
||||
val coursierProject = TaskKey[Project]("coursier-project")
|
||||
val coursierProjects = TaskKey[Seq[Project]]("coursier-projects")
|
||||
val coursierInterProjectDependencies = TaskKey[Seq[Project]]("coursier-inter-project-dependencies", "Projects the current project depends on, possibly transitively")
|
||||
val coursierPublications = TaskKey[Seq[(String, Publication)]]("coursier-publications")
|
||||
|
||||
val coursierSbtClassifiersModule = TaskKey[GetClassifiersModule]("coursier-sbt-classifiers-module")
|
||||
|
|
|
|||
|
|
@ -96,9 +96,32 @@ object Tasks {
|
|||
}
|
||||
}
|
||||
|
||||
def coursierProjectsTask: Def.Initialize[sbt.Task[Seq[Project]]] =
|
||||
sbt.Keys.state.flatMap { state =>
|
||||
val projects = structure(state).allProjectRefs
|
||||
def coursierInterProjectDependenciesTask: Def.Initialize[sbt.Task[Seq[Project]]] =
|
||||
(
|
||||
sbt.Keys.state,
|
||||
sbt.Keys.thisProjectRef
|
||||
).flatMap { (state, projectRef) =>
|
||||
|
||||
def dependencies(map: Map[String, Seq[String]], id: String): Set[String] = {
|
||||
|
||||
def helper(map: Map[String, Seq[String]], acc: Set[String]): Set[String] =
|
||||
if (acc.exists(map.contains)) {
|
||||
val (kept, rem) = map.partition { case (k, _) => acc(k) }
|
||||
helper(rem, acc ++ kept.valuesIterator.flatten)
|
||||
} else
|
||||
acc
|
||||
|
||||
helper(map - id, map.getOrElse(id, Nil).toSet)
|
||||
}
|
||||
|
||||
val allProjectsDeps =
|
||||
for (p <- structure(state).allProjects)
|
||||
yield p.id -> p.dependencies.map(_.project.project)
|
||||
|
||||
val deps = dependencies(allProjectsDeps.toMap, projectRef.project)
|
||||
|
||||
val projects = structure(state).allProjectRefs.filter(p => deps(p.project))
|
||||
|
||||
coursierProject.forAllProjects(state, projects).map(_.values.toVector)
|
||||
}
|
||||
|
||||
|
|
@ -271,7 +294,7 @@ object Tasks {
|
|||
(proj.copy(publications = publications), fallbackDeps)
|
||||
}
|
||||
|
||||
val projects = coursierProjects.value
|
||||
val interProjectDependencies = coursierInterProjectDependencies.value
|
||||
|
||||
val parallelDownloads = coursierParallelDownloads.value
|
||||
val checksums = coursierChecksums.value
|
||||
|
|
@ -363,12 +386,12 @@ object Tasks {
|
|||
userForceVersions ++
|
||||
sourceRepositoriesForcedDependencies ++
|
||||
forcedScalaModules(so, sv) ++
|
||||
projects.map(_.moduleVersion)
|
||||
interProjectDependencies.map(_.moduleVersion)
|
||||
)
|
||||
|
||||
if (verbosityLevel >= 2) {
|
||||
log.info("InterProjectRepository")
|
||||
for (p <- projects)
|
||||
for (p <- interProjectDependencies)
|
||||
log.info(s" ${p.module}:${p.version}")
|
||||
}
|
||||
|
||||
|
|
@ -380,7 +403,7 @@ object Tasks {
|
|||
withArtifacts = false
|
||||
)
|
||||
|
||||
val interProjectRepo = InterProjectRepository(projects)
|
||||
val interProjectRepo = InterProjectRepository(interProjectDependencies)
|
||||
|
||||
val ivyProperties = Map(
|
||||
"ivy.home" -> (new File(sys.props("user.home")).toURI.getPath + ".ivy2")
|
||||
|
|
|
|||
|
|
@ -23,7 +23,9 @@ object ToSbt {
|
|||
// FIXME Get these two from publications
|
||||
artifact.attributes.`type`,
|
||||
MavenSource.typeExtension(artifact.attributes.`type`),
|
||||
Some(artifact.attributes.classifier).filter(_.nonEmpty),
|
||||
Some(artifact.attributes.classifier)
|
||||
.filter(_.nonEmpty)
|
||||
.orElse(MavenSource.typeDefaultClassifierOpt(artifact.attributes.`type`)),
|
||||
Nil,
|
||||
Some(url(artifact.url)),
|
||||
Map.empty
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ scalaVersion := "2.11.8"
|
|||
|
||||
resolvers += "authenticated" at "http://localhost:8080"
|
||||
|
||||
coursierUseSbtCredentials := true
|
||||
credentials += Credentials("", "localhost", "user", "pass")
|
||||
|
||||
coursierCachePolicies := {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,10 @@
|
|||
scalaVersion := "2.11.8"
|
||||
|
||||
libraryDependencies += "org.apache.hadoop" % "hadoop-yarn-server-resourcemanager" % "2.7.1"
|
||||
|
||||
coursierCachePolicies := {
|
||||
if (sys.props("os.name").startsWith("Windows"))
|
||||
coursierCachePolicies.value
|
||||
else
|
||||
Seq(coursier.CachePolicy.ForceDownload)
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
{
|
||||
val pluginVersion = sys.props.getOrElse(
|
||||
"plugin.version",
|
||||
throw new RuntimeException(
|
||||
"""|The system property 'plugin.version' is not defined.
|
||||
|Specify this property using the scriptedLaunchOpts -D.""".stripMargin
|
||||
)
|
||||
)
|
||||
|
||||
addSbtPlugin("io.get-coursier" % "sbt-coursier" % pluginVersion)
|
||||
}
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
import java.io.File
|
||||
import java.nio.file.Files
|
||||
|
||||
import org.apache.zookeeper.ZooKeeper
|
||||
|
||||
object Main extends App {
|
||||
Files.write(new File("output").toPath, classOf[ZooKeeper].getSimpleName.getBytes("UTF-8"))
|
||||
}
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
$ delete output
|
||||
> run
|
||||
$ exists output
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
|
||||
object A {
|
||||
|
||||
def msg = "OK"
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
import java.io.File
|
||||
import java.nio.file.Files
|
||||
|
||||
import argonaut._, Argonaut._, ArgonautShapeless._
|
||||
|
||||
object Main extends App {
|
||||
|
||||
case class CC(i: Int, s: String)
|
||||
|
||||
val msg = CC(2, A.msg).asJson.spaces2
|
||||
|
||||
Files.write(new File("output").toPath, msg.getBytes("UTF-8"))
|
||||
}
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
|
||||
lazy val sharedSettings = Seq(
|
||||
scalaVersion := "2.11.8",
|
||||
coursierCachePolicies := {
|
||||
if (sys.props("os.name").startsWith("Windows"))
|
||||
coursierCachePolicies.value
|
||||
else
|
||||
Seq(coursier.CachePolicy.ForceDownload)
|
||||
}
|
||||
)
|
||||
|
||||
/** Module with the same Maven coordinates as shapeless 2.3.1 */
|
||||
lazy val `shapeless-mock` = project
|
||||
.settings(sharedSettings)
|
||||
.settings(
|
||||
organization := "com.chuusai",
|
||||
name := "shapeless",
|
||||
version := "2.3.1"
|
||||
)
|
||||
|
||||
lazy val a = project
|
||||
.settings(sharedSettings)
|
||||
.settings(
|
||||
organization := "com.pany",
|
||||
name := "a",
|
||||
version := "0.0.1"
|
||||
)
|
||||
|
||||
/** Transitively depends on the - real - shapeless 2.3.1 */
|
||||
lazy val b = project
|
||||
.dependsOn(a)
|
||||
.settings(sharedSettings)
|
||||
.settings(
|
||||
organization := "com.pany",
|
||||
name := "b",
|
||||
version := "0.0.1",
|
||||
libraryDependencies += "com.github.alexarchambault" %% "argonaut-shapeless_6.2" % "1.2.0-M1"
|
||||
)
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
{
|
||||
val pluginVersion = sys.props.getOrElse(
|
||||
"plugin.version",
|
||||
throw new RuntimeException(
|
||||
"""|The system property 'plugin.version' is not defined.
|
||||
|Specify this property using the scriptedLaunchOpts -D.""".stripMargin
|
||||
)
|
||||
)
|
||||
|
||||
addSbtPlugin("io.get-coursier" % "sbt-coursier" % pluginVersion)
|
||||
}
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
$ delete output
|
||||
> b/run
|
||||
$ exists output
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
org.webjars.bower:jquery:3.1.0:compile
|
||||
org.webjars.bower:jquery-mousewheel:3.1.13:compile
|
||||
org.webjars.bower:malihu-custom-scrollbar-plugin:3.1.5:compile
|
||||
|
|
@ -104,7 +104,7 @@ object CentralTests extends TestSuite {
|
|||
)(
|
||||
f: Artifact => T
|
||||
): Future[T] = async {
|
||||
val dep = Dependency(module, version, transitive = false)
|
||||
val dep = Dependency(module, version, transitive = false, attributes = Attributes())
|
||||
val res = await(resolve(Set(dep), extraRepo = extraRepo))
|
||||
|
||||
res.artifacts match {
|
||||
|
|
@ -237,6 +237,15 @@ object CentralTests extends TestSuite {
|
|||
)
|
||||
}
|
||||
|
||||
'versionInterval - {
|
||||
// Warning: needs to be updated when new versions of org.webjars.bower:jquery and
|
||||
// org.webjars.bower:jquery-mousewheel are published :-|
|
||||
resolutionCheck(
|
||||
Module("org.webjars.bower", "malihu-custom-scrollbar-plugin"),
|
||||
"3.1.5"
|
||||
)
|
||||
}
|
||||
|
||||
'latestRevision - {
|
||||
* - resolutionCheck(
|
||||
Module("com.chuusai", "shapeless_2.11"),
|
||||
|
|
@ -346,6 +355,42 @@ object CentralTests extends TestSuite {
|
|||
assert(nonUnique.isEmpty)
|
||||
}
|
||||
}
|
||||
|
||||
'testJarType - {
|
||||
// dependencies with type "test-jar" should be given the classifier "tests" by default
|
||||
|
||||
async {
|
||||
val deps = Set(
|
||||
Dependency(
|
||||
Module("org.apache.hadoop", "hadoop-yarn-server-resourcemanager"),
|
||||
"2.7.1"
|
||||
)
|
||||
)
|
||||
|
||||
val res = await(resolve(deps))
|
||||
|
||||
assert(res.errors.isEmpty)
|
||||
assert(res.conflicts.isEmpty)
|
||||
assert(res.isDone)
|
||||
|
||||
val dependencyArtifacts = res.dependencyArtifacts
|
||||
|
||||
val zookeeperTestArtifacts = dependencyArtifacts.collect {
|
||||
case (dep, artifact)
|
||||
if dep.module == Module("org.apache.zookeeper", "zookeeper") &&
|
||||
dep.attributes.`type` == "test-jar" =>
|
||||
artifact
|
||||
}
|
||||
|
||||
assert(zookeeperTestArtifacts.length == 1)
|
||||
|
||||
val zookeeperTestArtifact = zookeeperTestArtifacts.head
|
||||
|
||||
assert(zookeeperTestArtifact.attributes.`type` == "test-jar")
|
||||
assert(zookeeperTestArtifact.attributes.classifier == "tests")
|
||||
zookeeperTestArtifact.url.endsWith("-tests.jar")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -10,45 +10,30 @@ object VersionConstraintTests extends TestSuite {
|
|||
'parse{
|
||||
'empty{
|
||||
val c0 = Parse.versionConstraint("")
|
||||
assert(c0 == Some(VersionConstraint.None))
|
||||
assert(c0 == Some(VersionConstraint.all))
|
||||
}
|
||||
'basicVersion{
|
||||
val c0 = Parse.versionConstraint("1.2")
|
||||
assert(c0 == Some(VersionConstraint.Preferred(Version("1.2"))))
|
||||
assert(c0 == Some(VersionConstraint.preferred(Version("1.2"))))
|
||||
}
|
||||
'basicVersionInterval{
|
||||
val c0 = Parse.versionConstraint("(,1.2]")
|
||||
assert(c0 == Some(VersionConstraint.Interval(VersionInterval(None, Some(Version("1.2")), false, true))))
|
||||
assert(c0 == Some(VersionConstraint.interval(VersionInterval(None, Some(Version("1.2")), false, true))))
|
||||
}
|
||||
}
|
||||
|
||||
'repr{
|
||||
'empty{
|
||||
val s0 = VersionConstraint.None.repr
|
||||
assert(s0 == "")
|
||||
val s0 = VersionConstraint.all.repr
|
||||
assert(s0 == Some(""))
|
||||
}
|
||||
'preferred{
|
||||
val s0 = VersionConstraint.Preferred(Version("2.1")).repr
|
||||
assert(s0 == "2.1")
|
||||
val s0 = VersionConstraint.preferred(Version("2.1")).repr
|
||||
assert(s0 == Some("2.1"))
|
||||
}
|
||||
'interval{
|
||||
val s0 = VersionConstraint.Interval(VersionInterval(None, Some(Version("2.1")), false, true)).repr
|
||||
assert(s0 == "(,2.1]")
|
||||
}
|
||||
}
|
||||
|
||||
'interval{
|
||||
'empty{
|
||||
val s0 = VersionConstraint.None.interval
|
||||
assert(s0 == VersionInterval.zero)
|
||||
}
|
||||
'preferred{
|
||||
val s0 = VersionConstraint.Preferred(Version("2.1")).interval
|
||||
assert(s0 == VersionInterval(Some(Version("2.1")), None, true, false))
|
||||
}
|
||||
'interval{
|
||||
val s0 = VersionConstraint.Interval(VersionInterval(None, Some(Version("2.1")), false, true)).interval
|
||||
assert(s0 == VersionInterval(None, Some(Version("2.1")), false, true))
|
||||
val s0 = VersionConstraint.interval(VersionInterval(None, Some(Version("2.1")), false, true)).repr
|
||||
assert(s0 == Some("(,2.1]"))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -269,17 +269,17 @@ object VersionIntervalTests extends TestSuite {
|
|||
'none{
|
||||
val s1 = "(,)"
|
||||
val c1 = Parse.versionInterval(s1).map(_.constraint)
|
||||
assert(c1 == Some(VersionConstraint.None))
|
||||
assert(c1 == Some(VersionConstraint.all))
|
||||
}
|
||||
'preferred{
|
||||
val s1 = "[1.3,)"
|
||||
val c1 = Parse.versionInterval(s1).map(_.constraint)
|
||||
assert(c1 == Some(VersionConstraint.Preferred(Parse.version("1.3").get)))
|
||||
assert(c1 == Some(VersionConstraint.preferred(Parse.version("1.3").get)))
|
||||
}
|
||||
'interval{
|
||||
val s1 = "[1.3,2.4)"
|
||||
val c1 = Parse.versionInterval(s1).map(_.constraint)
|
||||
assert(c1 == Some(VersionConstraint.Interval(VersionInterval(Parse.version("1.3"), Parse.version("2.4"), true, false))))
|
||||
assert(c1 == Some(VersionConstraint.interval(VersionInterval(Parse.version("1.3"), Parse.version("2.4"), true, false))))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue