Merge pull request #129 from alexarchambault/topic/optim

Small fix in standalone launcher, build it from SBT, various optimizations
This commit is contained in:
Alexandre Archambault 2016-02-07 20:41:15 +01:00
commit 7f188340c5
18 changed files with 196 additions and 134 deletions

View File

@ -219,6 +219,7 @@ lazy val cli = project
.settings(commonSettings) .settings(commonSettings)
.settings(noPublish210Settings) .settings(noPublish210Settings)
.settings(packAutoSettings) .settings(packAutoSettings)
.settings(proguardSettings)
.settings( .settings(
name := "coursier-cli", name := "coursier-cli",
libraryDependencies ++= { libraryDependencies ++= {
@ -229,7 +230,15 @@ lazy val cli = project
}, },
resourceGenerators in Compile += packageBin.in(bootstrap).in(Compile).map { jar => resourceGenerators in Compile += packageBin.in(bootstrap).in(Compile).map { jar =>
Seq(jar) Seq(jar)
}.taskValue }.taskValue,
ProguardKeys.proguardVersion in Proguard := "5.2.1",
ProguardKeys.options in Proguard ++= Seq(
"-dontwarn",
"-keep class coursier.cli.Coursier {\n public static void main(java.lang.String[]);\n}",
"-keep class coursier.cli.IsolatedClassLoader {\n public java.lang.String[] getIsolationTargets();\n}"
),
javaOptions in (Proguard, ProguardKeys.proguard) := Seq("-Xmx3172M"),
artifactPath in Proguard := (ProguardKeys.proguardDirectory in Proguard).value / "coursier-standalone.jar"
) )
lazy val web = project lazy val web = project

View File

@ -357,8 +357,8 @@ object Cache {
artifact0.checksumUrls.get(sumType) match { artifact0.checksumUrls.get(sumType) match {
case Some(sumFile) => case Some(sumFile) =>
Task { Task {
val sum = scala.io.Source.fromFile(sumFile) val sum = new String(NioFiles.readAllBytes(new File(sumFile).toPath), "UTF-8")
.getLines() .linesIterator
.toStream .toStream
.headOption .headOption
.mkString .mkString
@ -471,7 +471,7 @@ object Cache {
pool = pool pool = pool
).leftMap(_.message).map { f => ).leftMap(_.message).map { f =>
// FIXME Catch error here? // FIXME Catch error here?
scala.io.Source.fromFile(f)("UTF-8").mkString new String(NioFiles.readAllBytes(f.toPath), "UTF-8")
} }
} }
@ -571,31 +571,29 @@ object Cache {
} }
sealed trait FileError extends Product with Serializable { sealed abstract class FileError(val message: String) extends Product with Serializable
def message: String
}
object FileError { object FileError {
case class DownloadError(message0: String) extends FileError { final case class DownloadError(reason: String) extends FileError(s"Download error: $reason")
def message = s"Download error: $message0"
}
case class NotFound(file: String) extends FileError {
def message = s"Not found: $file"
}
case class ChecksumNotFound(sumType: String, file: String) extends FileError {
def message = s"$sumType checksum not found: $file"
}
case class WrongChecksum(sumType: String, got: String, expected: String, file: String, sumFile: String) extends FileError {
def message = s"$sumType checksum validation failed: $file"
}
sealed trait Recoverable extends FileError final case class NotFound(file: String) extends FileError(s"Not found: $file")
case class Locked(file: File) extends Recoverable {
def message = s"Locked: $file" final case class ChecksumNotFound(
} sumType: String,
case class ConcurrentDownload(url: String) extends Recoverable { file: String
def message = s"Concurrent download: $url" ) extends FileError(s"$sumType checksum not found: $file")
}
final case class WrongChecksum(
sumType: String,
got: String,
expected: String,
file: String,
sumFile: String
) extends FileError(s"$sumType checksum validation failed: $file")
sealed abstract class Recoverable(message: String) extends FileError(message)
final case class Locked(file: File) extends Recoverable(s"Locked: $file")
final case class ConcurrentDownload(url: String) extends Recoverable(s"Concurrent download: $url")
} }

View File

@ -1,6 +1,6 @@
package coursier package coursier
sealed trait CachePolicy extends Product with Serializable sealed abstract class CachePolicy extends Product with Serializable
object CachePolicy { object CachePolicy {
case object LocalOnly extends CachePolicy case object LocalOnly extends CachePolicy

View File

@ -62,7 +62,7 @@ case class CacheOptions(
cache: String = Cache.defaultBase.toString cache: String = Cache.defaultBase.toString
) )
sealed trait CoursierCommand extends Command sealed abstract class CoursierCommand extends Command
case class Resolve( case class Resolve(
@Recurse @Recurse

View File

@ -9,7 +9,7 @@ package coursier.core
* *
* Using the same terminology as Ivy. * Using the same terminology as Ivy.
*/ */
case class Module( final case class Module(
organization: String, organization: String,
name: String, name: String,
attributes: Map[String, String] attributes: Map[String, String]
@ -28,6 +28,8 @@ case class Module(
override def toString = override def toString =
s"$organization:$name" + s"$organization:$name" +
(if (attributes.nonEmpty) s";$attributesStr" else "") (if (attributes.nonEmpty) s";$attributesStr" else "")
override final lazy val hashCode = Module.unapply(this).get.hashCode()
} }
/** /**
@ -36,7 +38,7 @@ case class Module(
* The remaining fields are left untouched, some being transitively * The remaining fields are left untouched, some being transitively
* propagated (exclusions, optional, in particular). * propagated (exclusions, optional, in particular).
*/ */
case class Dependency( final case class Dependency(
module: Module, module: Module,
version: String, version: String,
configuration: String, configuration: String,
@ -48,11 +50,13 @@ case class Dependency(
transitive: Boolean transitive: Boolean
) { ) {
def moduleVersion = (module, version) lazy val moduleVersion = (module, version)
override lazy val hashCode = Dependency.unapply(this).get.hashCode()
} }
// Maven-specific // Maven-specific
case class Attributes( final case class Attributes(
`type`: String, `type`: String,
classifier: String classifier: String
) { ) {
@ -60,7 +64,7 @@ case class Attributes(
Publication(name, `type`, ext, classifier) Publication(name, `type`, ext, classifier)
} }
case class Project( final case class Project(
module: Module, module: Module,
version: String, version: String,
// First String is configuration (scope for Maven) // First String is configuration (scope for Maven)
@ -83,7 +87,7 @@ case class Project(
// Extra infos, not used during resolution // Extra infos, not used during resolution
info: Info info: Info
) { ) {
def moduleVersion = (module, version) lazy val moduleVersion = (module, version)
/** All configurations that each configuration extends, including the ones it extends transitively */ /** All configurations that each configuration extends, including the ones it extends transitively */
lazy val allConfigurations: Map[String, Set[String]] = lazy val allConfigurations: Map[String, Set[String]] =
@ -91,7 +95,7 @@ case class Project(
} }
/** Extra project info, not used during resolution */ /** Extra project info, not used during resolution */
case class Info( final case class Info(
description: String, description: String,
homePage: String, homePage: String,
licenses: Seq[(String, Option[String])], licenses: Seq[(String, Option[String])],
@ -100,7 +104,7 @@ case class Info(
) )
object Info { object Info {
case class Developer( final case class Developer(
id: String, id: String,
name: String, name: String,
url: String url: String
@ -110,10 +114,10 @@ object Info {
} }
// Maven-specific // Maven-specific
case class Activation(properties: Seq[(String, Option[String])]) final case class Activation(properties: Seq[(String, Option[String])])
// Maven-specific // Maven-specific
case class Profile( final case class Profile(
id: String, id: String,
activeByDefault: Option[Boolean], activeByDefault: Option[Boolean],
activation: Activation, activation: Activation,
@ -123,7 +127,7 @@ case class Profile(
) )
// Maven-specific // Maven-specific
case class Versions( final case class Versions(
latest: String, latest: String,
release: String, release: String,
available: List[String], available: List[String],
@ -131,7 +135,7 @@ case class Versions(
) )
object Versions { object Versions {
case class DateTime( final case class DateTime(
year: Int, year: Int,
month: Int, month: Int,
day: Int, day: Int,
@ -142,7 +146,7 @@ object Versions {
} }
// Maven-specific // Maven-specific
case class SnapshotVersion( final case class SnapshotVersion(
classifier: String, classifier: String,
extension: String, extension: String,
value: String, value: String,
@ -150,7 +154,7 @@ case class SnapshotVersion(
) )
// Maven-specific // Maven-specific
case class SnapshotVersioning( final case class SnapshotVersioning(
module: Module, module: Module,
version: String, version: String,
latest: String, latest: String,
@ -163,7 +167,7 @@ case class SnapshotVersioning(
) )
// Ivy-specific // Ivy-specific
case class Publication( final case class Publication(
name: String, name: String,
`type`: String, `type`: String,
ext: String, ext: String,
@ -172,7 +176,7 @@ case class Publication(
def attributes: Attributes = Attributes(`type`, classifier) def attributes: Attributes = Attributes(`type`, classifier)
} }
case class Artifact( final case class Artifact(
url: String, url: String,
checksumUrls: Map[String, String], checksumUrls: Map[String, String],
extra: Map[String, Artifact], extra: Map[String, Artifact],

View File

@ -1,9 +1,10 @@
package coursier.core package coursier.core
import java.util.concurrent.ConcurrentHashMap
import java.util.regex.Pattern.quote import java.util.regex.Pattern.quote
import scala.annotation.tailrec import scala.annotation.tailrec
import scala.collection.mutable import scala.collection.JavaConverters._
import scalaz.{ \/-, -\/ } import scalaz.{ \/-, -\/ }
object Resolution { object Resolution {
@ -76,7 +77,7 @@ object Resolution {
def substituteProps(s: String, properties: Map[String, String]) = { def substituteProps(s: String, properties: Map[String, String]) = {
val matches = propRegex val matches = propRegex
.findAllMatchIn(s) .findAllMatchIn(s)
.toList .toVector
.reverse .reverse
if (matches.isEmpty) s if (matches.isEmpty) s
@ -172,7 +173,7 @@ object Resolution {
): (Seq[Dependency], Seq[Dependency], Map[Module, String]) = { ): (Seq[Dependency], Seq[Dependency], Map[Module, String]) = {
val mergedByModVer = dependencies val mergedByModVer = dependencies
.toList .toVector
.groupBy(dep => dep.module) .groupBy(dep => dep.module)
.map { case (module, deps) => .map { case (module, deps) =>
module -> { module -> {
@ -203,7 +204,7 @@ object Resolution {
val merged = mergedByModVer val merged = mergedByModVer
.values .values
.toList .toVector
( (
merged merged
@ -424,35 +425,60 @@ object Resolution {
* @param projectCache: cache of known projects * @param projectCache: cache of known projects
* @param errorCache: keeps track of the modules whose project definition could not be found * @param errorCache: keeps track of the modules whose project definition could not be found
*/ */
case class Resolution( final case class Resolution(
rootDependencies: Set[Dependency], rootDependencies: Set[Dependency],
dependencies: Set[Dependency], dependencies: Set[Dependency],
forceVersions: Map[Module, String], forceVersions: Map[Module, String],
conflicts: Set[Dependency], conflicts: Set[Dependency],
projectCache: Map[Resolution.ModuleVersion, (Artifact.Source, Project)], projectCache: Map[Resolution.ModuleVersion, (Artifact.Source, Project)],
errorCache: Map[Resolution.ModuleVersion, Seq[String]], errorCache: Map[Resolution.ModuleVersion, Seq[String]],
finalDependenciesCache: Map[Dependency, Seq[Dependency]],
filter: Option[Dependency => Boolean], filter: Option[Dependency => Boolean],
profileActivation: Option[(String, Activation, Map[String, String]) => Boolean] profileActivation: Option[(String, Activation, Map[String, String]) => Boolean]
) { ) {
def copyWithCache(
rootDependencies: Set[Dependency] = rootDependencies,
dependencies: Set[Dependency] = dependencies,
forceVersions: Map[Module, String] = forceVersions,
conflicts: Set[Dependency] = conflicts,
projectCache: Map[Resolution.ModuleVersion, (Artifact.Source, Project)] = projectCache,
errorCache: Map[Resolution.ModuleVersion, Seq[String]] = errorCache,
filter: Option[Dependency => Boolean] = filter,
profileActivation: Option[(String, Activation, Map[String, String]) => Boolean] = profileActivation
): Resolution =
copy(
rootDependencies,
dependencies,
forceVersions,
conflicts,
projectCache,
errorCache,
finalDependenciesCache ++ finalDependenciesCache0.asScala,
filter,
profileActivation
)
import Resolution._ import Resolution._
private val finalDependenciesCache = private[core] val finalDependenciesCache0 = new ConcurrentHashMap[Dependency, Seq[Dependency]]
new mutable.HashMap[Dependency, Seq[Dependency]]()
private def finalDependencies0(dep: Dependency) = private def finalDependencies0(dep: Dependency): Seq[Dependency] =
finalDependenciesCache.synchronized { if (dep.transitive) {
finalDependenciesCache.getOrElseUpdate(dep, { val deps = finalDependenciesCache.getOrElse(dep, finalDependenciesCache0.get(dep))
if (dep.transitive)
projectCache.get(dep.moduleVersion) match { if (deps == null)
case Some((_, proj)) => projectCache.get(dep.moduleVersion) match {
finalDependencies(dep, proj) case Some((_, proj)) =>
.filter(filter getOrElse defaultFilter) val res = finalDependencies(dep, proj).filter(filter getOrElse defaultFilter)
case None => Nil finalDependenciesCache0.put(dep, res)
} res
else case None => Nil
Nil }
}) else
} deps
} else
Nil
/** /**
* Transitive dependencies of the current dependencies, according to * Transitive dependencies of the current dependencies, according to
@ -460,9 +486,9 @@ case class Resolution(
* *
* No attempt is made to solve version conflicts here. * No attempt is made to solve version conflicts here.
*/ */
def transitiveDependencies: Seq[Dependency] = lazy val transitiveDependencies: Seq[Dependency] =
(dependencies -- conflicts) (dependencies -- conflicts)
.toList .toVector
.flatMap(finalDependencies0) .flatMap(finalDependencies0)
/** /**
@ -476,7 +502,7 @@ case class Resolution(
* Returns a tuple made of the conflicting dependencies, all * Returns a tuple made of the conflicting dependencies, all
* the dependencies, and the retained version of each module. * the dependencies, and the retained version of each module.
*/ */
def nextDependenciesAndConflicts: (Seq[Dependency], Seq[Dependency], Map[Module, String]) = lazy val nextDependenciesAndConflicts: (Seq[Dependency], Seq[Dependency], Map[Module, String]) =
// TODO Provide the modules whose version was forced by dependency overrides too // TODO Provide the modules whose version was forced by dependency overrides too
merge( merge(
rootDependencies.map(withDefaultConfig) ++ dependencies ++ transitiveDependencies, rootDependencies.map(withDefaultConfig) ++ dependencies ++ transitiveDependencies,
@ -486,7 +512,7 @@ case class Resolution(
/** /**
* The modules we miss some info about. * The modules we miss some info about.
*/ */
def missingFromCache: Set[ModuleVersion] = { lazy val missingFromCache: Set[ModuleVersion] = {
val modules = dependencies val modules = dependencies
.map(_.moduleVersion) .map(_.moduleVersion)
val nextModules = nextDependenciesAndConflicts._2 val nextModules = nextDependenciesAndConflicts._2
@ -500,7 +526,7 @@ case class Resolution(
/** /**
* Whether the resolution is done. * Whether the resolution is done.
*/ */
def isDone: Boolean = { lazy val isDone: Boolean = {
def isFixPoint = { def isFixPoint = {
val (nextConflicts, _, _) = nextDependenciesAndConflicts val (nextConflicts, _, _) = nextDependenciesAndConflicts
@ -520,7 +546,7 @@ case class Resolution(
* *
* The versions of all the dependencies returned are erased (emptied). * The versions of all the dependencies returned are erased (emptied).
*/ */
def reverseDependencies: Map[Dependency, Vector[Dependency]] = { lazy val reverseDependencies: Map[Dependency, Vector[Dependency]] = {
val (updatedConflicts, updatedDeps, _) = nextDependenciesAndConflicts val (updatedConflicts, updatedDeps, _) = nextDependenciesAndConflicts
val trDepsSeq = val trDepsSeq =
@ -546,7 +572,7 @@ case class Resolution(
* *
* The versions of all the dependencies returned are erased (emptied). * The versions of all the dependencies returned are erased (emptied).
*/ */
def remainingDependencies: Set[Dependency] = { lazy val remainingDependencies: Set[Dependency] = {
val rootDependencies0 = rootDependencies val rootDependencies0 = rootDependencies
.map(withDefaultConfig) .map(withDefaultConfig)
.map(eraseVersion) .map(eraseVersion)
@ -568,7 +594,7 @@ case class Resolution(
broughtBy broughtBy
.filter(x => remaining.contains(x) || rootDependencies0(x)) .filter(x => remaining.contains(x) || rootDependencies0(x))
) )
.toList .toVector
.toMap .toMap
) )
} }
@ -581,7 +607,7 @@ case class Resolution(
/** /**
* The final next dependency set, stripped of no more required ones. * The final next dependency set, stripped of no more required ones.
*/ */
def newDependencies: Set[Dependency] = { lazy val newDependencies: Set[Dependency] = {
val remainingDependencies0 = remainingDependencies val remainingDependencies0 = remainingDependencies
nextDependenciesAndConflicts._2 nextDependenciesAndConflicts._2
@ -589,10 +615,10 @@ case class Resolution(
.toSet .toSet
} }
private def nextNoMissingUnsafe: Resolution = { private lazy val nextNoMissingUnsafe: Resolution = {
val (newConflicts, _, _) = nextDependenciesAndConflicts val (newConflicts, _, _) = nextDependenciesAndConflicts
copy( copyWithCache(
dependencies = newDependencies ++ newConflicts, dependencies = newDependencies ++ newConflicts,
conflicts = newConflicts.toSet conflicts = newConflicts.toSet
) )
@ -856,7 +882,7 @@ case class Resolution(
newDeps newDeps
} }
copy( copyWithCache(
rootDependencies = dependencies, rootDependencies = dependencies,
dependencies = helper(dependencies.map(updateVersion)) dependencies = helper(dependencies.map(updateVersion))
// don't know if something should be done about conflicts // don't know if something should be done about conflicts

View File

@ -5,7 +5,7 @@ import scalaz._
import scala.annotation.tailrec import scala.annotation.tailrec
sealed trait ResolutionProcess { sealed abstract class ResolutionProcess {
def run[F[_]]( def run[F[_]](
fetch: Fetch.Metadata[F], fetch: Fetch.Metadata[F],
maxIterations: Int = 50 maxIterations: Int = 50
@ -52,7 +52,7 @@ sealed trait ResolutionProcess {
def current: Resolution def current: Resolution
} }
case class Missing( final case class Missing(
missing: Seq[(Module, String)], missing: Seq[(Module, String)],
current: Resolution, current: Resolution,
cont: Resolution => ResolutionProcess cont: Resolution => ResolutionProcess
@ -74,7 +74,7 @@ case class Missing(
def cont0(res: Resolution) = { def cont0(res: Resolution) = {
val res0 = val res0 =
successes.foldLeft(res){case (acc, (modVer, (source, proj))) => successes.foldLeft(res){case (acc, (modVer, (source, proj))) =>
acc.copy(projectCache = acc.projectCache + ( acc.copyWithCache(projectCache = acc.projectCache + (
modVer -> (source, acc.withDependencyManagement(proj)) modVer -> (source, acc.withDependencyManagement(proj))
)) ))
} }
@ -83,7 +83,7 @@ case class Missing(
} }
val current0 = current val current0 = current
.copy(errorCache = current.errorCache ++ errors) .copyWithCache(errorCache = current.errorCache ++ errors)
if (depMgmtMissing.isEmpty) if (depMgmtMissing.isEmpty)
cont0(current0) cont0(current0)
@ -93,7 +93,7 @@ case class Missing(
} }
case class Continue( final case class Continue(
current: Resolution, current: Resolution,
cont: Resolution => ResolutionProcess cont: Resolution => ResolutionProcess
) extends ResolutionProcess { ) extends ResolutionProcess {
@ -108,7 +108,7 @@ case class Continue(
} }
case class Done(resolution: Resolution) extends ResolutionProcess { final case class Done(resolution: Resolution) extends ResolutionProcess {
def current: Resolution = resolution def current: Resolution = resolution
} }

View File

@ -20,7 +20,7 @@ case class Version(repr: String) extends Ordered[Version] {
object Version { object Version {
sealed trait Item extends Ordered[Item] { sealed abstract class Item extends Ordered[Item] {
def compare(other: Item): Int = def compare(other: Item): Int =
(this, other) match { (this, other) match {
case (Number(a), Number(b)) => a.compare(b) case (Number(a), Number(b)) => a.compare(b)
@ -43,27 +43,27 @@ object Version {
def compareToEmpty: Int = 1 def compareToEmpty: Int = 1
} }
sealed trait Numeric extends Item { sealed abstract class Numeric extends Item {
def repr: String def repr: String
def next: Numeric def next: Numeric
} }
case class Number(value: Int) extends Numeric { final case class Number(value: Int) extends Numeric {
val order = 0 val order = 0
def next: Number = Number(value + 1) def next: Number = Number(value + 1)
def repr: String = value.toString def repr: String = value.toString
override def compareToEmpty = value.compare(0) override def compareToEmpty = value.compare(0)
} }
case class BigNumber(value: BigInt) extends Numeric { final case class BigNumber(value: BigInt) extends Numeric {
val order = 0 val order = 0
def next: BigNumber = BigNumber(value + 1) def next: BigNumber = BigNumber(value + 1)
def repr: String = value.toString def repr: String = value.toString
override def compareToEmpty = value.compare(0) override def compareToEmpty = value.compare(0)
} }
case class Qualifier(value: String, level: Int) extends Item { final case class Qualifier(value: String, level: Int) extends Item {
val order = -2 val order = -2
override def compareToEmpty = level.compare(0) override def compareToEmpty = level.compare(0)
} }
case class Literal(value: String) extends Item { final case class Literal(value: String) extends Item {
val order = -1 val order = -1
override def compareToEmpty = if (value.isEmpty) 0 else 1 override def compareToEmpty = if (value.isEmpty) 0 else 1
} }
@ -93,7 +93,7 @@ object Version {
val qualifiersMap = qualifiers.map(q => q.value -> q).toMap val qualifiersMap = qualifiers.map(q => q.value -> q).toMap
object Tokenizer { object Tokenizer {
sealed trait Separator sealed abstract class Separator
case object Dot extends Separator case object Dot extends Separator
case object Hyphen extends Separator case object Hyphen extends Separator
case object Underscore extends Separator case object Underscore extends Separator

View File

@ -82,21 +82,23 @@ object VersionInterval {
val zero = VersionInterval(None, None, fromIncluded = false, toIncluded = false) val zero = VersionInterval(None, None, fromIncluded = false, toIncluded = false)
} }
sealed trait VersionConstraint { sealed abstract class VersionConstraint(
def interval: VersionInterval val interval: VersionInterval,
def repr: String val repr: String
} )
object VersionConstraint { object VersionConstraint {
/** Currently treated as minimum... */ /** Currently treated as minimum... */
case class Preferred(version: Version) extends VersionConstraint { final case class Preferred(version: Version) extends VersionConstraint(
def interval: VersionInterval = VersionInterval(Some(version), Option.empty, fromIncluded = true, toIncluded = false) VersionInterval(Some(version), Option.empty, fromIncluded = true, toIncluded = false),
def repr: String = version.repr version.repr
} )
case class Interval(interval: VersionInterval) extends VersionConstraint { final case class Interval(interval0: VersionInterval) extends VersionConstraint(
def repr: String = interval.repr interval0,
} interval0.repr
case object None extends VersionConstraint { )
val interval = VersionInterval.zero case object None extends VersionConstraint(
def repr: String = "" // Once parsed, "(,)" becomes "" because of this VersionInterval.zero,
} "" // Once parsed, "(,)" becomes "" because of this
} )
}

View File

@ -23,7 +23,7 @@ object Pattern {
def apply(content: String): Map[String, String] => String \/ String def apply(content: String): Map[String, String] => String \/ String
} }
object PatternPart { object PatternPart {
case class Literal(override val effectiveStart: Int, override val effectiveEnd: Int) extends PatternPart(effectiveStart, effectiveEnd) { final case class Literal(override val effectiveStart: Int, override val effectiveEnd: Int) extends PatternPart(effectiveStart, effectiveEnd) {
def apply(content: String): Map[String, String] => String \/ String = { def apply(content: String): Map[String, String] => String \/ String = {
assert(content.length == effectiveEnd - effectiveStart) assert(content.length == effectiveEnd - effectiveStart)
val matches = variableRegex.findAllMatchIn(content).toList val matches = variableRegex.findAllMatchIn(content).toList
@ -54,7 +54,7 @@ object Pattern {
helper(0, matches, new StringBuilder) helper(0, matches, new StringBuilder)
} }
} }
case class Optional(start0: Int, end0: Int) extends PatternPart(start0 + 1, end0 - 1) { final case class Optional(start0: Int, end0: Int) extends PatternPart(start0 + 1, end0 - 1) {
override def start = start0 override def start = start0
override def end = end0 override def end = end0
@ -78,7 +78,7 @@ object Pattern {
} }
case class Pattern( final case class Pattern(
pattern: String, pattern: String,
properties: Map[String, String] properties: Map[String, String]
) { ) {

View File

@ -70,6 +70,7 @@ package object coursier {
conflicts: Set[Dependency] = Set.empty, conflicts: Set[Dependency] = Set.empty,
projectCache: Map[ModuleVersion, (Artifact.Source, Project)] = Map.empty, projectCache: Map[ModuleVersion, (Artifact.Source, Project)] = Map.empty,
errorCache: Map[ModuleVersion, Seq[String]] = Map.empty, errorCache: Map[ModuleVersion, Seq[String]] = Map.empty,
finalDependencies: Map[Dependency, Seq[Dependency]] = Map.empty,
filter: Option[Dependency => Boolean] = None, filter: Option[Dependency => Boolean] = None,
profileActivation: Option[(String, core.Activation, Map[String, String]) => Boolean] = None profileActivation: Option[(String, core.Activation, Map[String, String]) => Boolean] = None
): Resolution = ): Resolution =
@ -80,6 +81,7 @@ package object coursier {
conflicts, conflicts,
projectCache, projectCache,
errorCache, errorCache,
finalDependencies,
filter, filter,
profileActivation profileActivation
) )

View File

@ -1,11 +1,11 @@
package coursier.util package coursier.util
import java.util.Properties import java.util.{ Properties => JProperties }
object Properties { object Properties {
private lazy val props = { private lazy val props = {
val p = new Properties() val p = new JProperties()
p.load( p.load(
getClass getClass
.getClassLoader .getClassLoader

Binary file not shown.

View File

@ -23,6 +23,10 @@ cat >> coursier.pro << EOF
-keep class coursier.cli.Coursier { -keep class coursier.cli.Coursier {
public static void main(java.lang.String[]); public static void main(java.lang.String[]);
} }
-keep class coursier.cli.IsolatedClassLoader {
public java.lang.String[] getIsolationTargets();
}
EOF EOF
# -noverify added in launcher below because of errors like # -noverify added in launcher below because of errors like

View File

@ -4,3 +4,4 @@ addSbtPlugin("com.jsuereth" % "sbt-pgp" % "1.0.0")
addSbtPlugin("org.scoverage" % "sbt-scoverage" % "1.1.0") addSbtPlugin("org.scoverage" % "sbt-scoverage" % "1.1.0")
addSbtPlugin("org.tpolecat" % "tut-plugin" % "0.4.0") addSbtPlugin("org.tpolecat" % "tut-plugin" % "0.4.0")
addSbtPlugin("com.github.alexarchambault" % "coursier-sbt-plugin" % "1.0.0-M4") addSbtPlugin("com.github.alexarchambault" % "coursier-sbt-plugin" % "1.0.0-M4")
addSbtPlugin("com.typesafe.sbt" % "sbt-proguard" % "0.2.2")

View File

@ -90,8 +90,7 @@ object CentralTests extends TestSuite {
'logback{ 'logback{
async { async {
val dep = Dependency(Module("ch.qos.logback", "logback-classic"), "1.1.3") val dep = Dependency(Module("ch.qos.logback", "logback-classic"), "1.1.3")
val res = await(resolve(Set(dep))) val res = await(resolve(Set(dep))).clearCaches
.copy(projectCache = Map.empty, errorCache = Map.empty) // No validating these here
val expected = Resolution( val expected = Resolution(
rootDependencies = Set(dep), rootDependencies = Set(dep),
@ -106,8 +105,7 @@ object CentralTests extends TestSuite {
'asm{ 'asm{
async { async {
val dep = Dependency(Module("org.ow2.asm", "asm-commons"), "5.0.2") val dep = Dependency(Module("org.ow2.asm", "asm-commons"), "5.0.2")
val res = await(resolve(Set(dep))) val res = await(resolve(Set(dep))).clearCaches
.copy(projectCache = Map.empty, errorCache = Map.empty) // No validating these here
val expected = Resolution( val expected = Resolution(
rootDependencies = Set(dep), rootDependencies = Set(dep),
@ -123,7 +121,7 @@ object CentralTests extends TestSuite {
async { async {
val dep = Dependency(Module("joda-time", "joda-time"), "[2.2,2.8]") val dep = Dependency(Module("joda-time", "joda-time"), "[2.2,2.8]")
val res0 = await(resolve(Set(dep))) val res0 = await(resolve(Set(dep)))
val res = res0.copy(projectCache = Map.empty, errorCache = Map.empty) val res = res0.clearCaches
val expected = Resolution( val expected = Resolution(
rootDependencies = Set(dep), rootDependencies = Set(dep),

View File

@ -203,7 +203,7 @@ object ResolutionTests extends TestSuite {
val dep = Dependency(Module("acme", "config"), "1.3.0") val dep = Dependency(Module("acme", "config"), "1.3.0")
val res = await(resolve0( val res = await(resolve0(
Set(dep) Set(dep)
)) )).clearFinalDependenciesCache
val expected = Resolution( val expected = Resolution(
rootDependencies = Set(dep), rootDependencies = Set(dep),
@ -220,7 +220,7 @@ object ResolutionTests extends TestSuite {
val trDep = Dependency(Module("acme", "play-json"), "2.4.0") val trDep = Dependency(Module("acme", "play-json"), "2.4.0")
val res = await(resolve0( val res = await(resolve0(
Set(dep) Set(dep)
)) )).clearFinalDependenciesCache
val expected = Resolution( val expected = Resolution(
rootDependencies = Set(dep), rootDependencies = Set(dep),
@ -243,7 +243,7 @@ object ResolutionTests extends TestSuite {
) )
val res = await(resolve0( val res = await(resolve0(
Set(dep) Set(dep)
)).copy(filter = None, projectCache = Map.empty) )).clearCaches
val expected = Resolution( val expected = Resolution(
rootDependencies = Set(dep), rootDependencies = Set(dep),
@ -264,7 +264,7 @@ object ResolutionTests extends TestSuite {
) )
val res = await(resolve0( val res = await(resolve0(
Set(dep) Set(dep)
)).copy(filter = None, projectCache = Map.empty) )).clearCaches
val expected = Resolution( val expected = Resolution(
rootDependencies = Set(dep), rootDependencies = Set(dep),
@ -285,7 +285,7 @@ object ResolutionTests extends TestSuite {
) )
val res = await(resolve0( val res = await(resolve0(
Set(dep) Set(dep)
)).copy(filter = None, projectCache = Map.empty) )).clearCaches
val expected = Resolution( val expected = Resolution(
rootDependencies = Set(dep), rootDependencies = Set(dep),
@ -300,7 +300,7 @@ object ResolutionTests extends TestSuite {
val dep = Dependency(Module("hudsucker", "mail"), "10.0") val dep = Dependency(Module("hudsucker", "mail"), "10.0")
val res = await(resolve0( val res = await(resolve0(
Set(dep) Set(dep)
)).copy(filter = None, projectCache = Map.empty) )).clearCaches
val expected = Resolution( val expected = Resolution(
rootDependencies = Set(dep), rootDependencies = Set(dep),
@ -319,7 +319,7 @@ object ResolutionTests extends TestSuite {
) )
val res = await(resolve0( val res = await(resolve0(
Set(dep) Set(dep)
)).copy(filter = None, projectCache = Map.empty) )).clearCaches
val expected = Resolution( val expected = Resolution(
rootDependencies = Set(dep), rootDependencies = Set(dep),
@ -337,7 +337,7 @@ object ResolutionTests extends TestSuite {
Dependency(Module("org.gnome", "desktop"), "7.0")) Dependency(Module("org.gnome", "desktop"), "7.0"))
val res = await(resolve0( val res = await(resolve0(
Set(dep) Set(dep)
)).copy(filter = None, projectCache = Map.empty, errorCache = Map.empty) )).clearCaches
val expected = Resolution( val expected = Resolution(
rootDependencies = Set(dep), rootDependencies = Set(dep),
@ -354,7 +354,7 @@ object ResolutionTests extends TestSuite {
Dependency(Module("gov.nsa", "secure-pgp"), "10.0", exclusions = Set(("*", "crypto")))) Dependency(Module("gov.nsa", "secure-pgp"), "10.0", exclusions = Set(("*", "crypto"))))
val res = await(resolve0( val res = await(resolve0(
Set(dep) Set(dep)
)).copy(filter = None, projectCache = Map.empty, errorCache = Map.empty) )).clearCaches
val expected = Resolution( val expected = Resolution(
rootDependencies = Set(dep), rootDependencies = Set(dep),
@ -369,7 +369,7 @@ object ResolutionTests extends TestSuite {
val dep = Dependency(Module("com.thoughtworks.paranamer", "paranamer"), "2.6") val dep = Dependency(Module("com.thoughtworks.paranamer", "paranamer"), "2.6")
val res = await(resolve0( val res = await(resolve0(
Set(dep) Set(dep)
)).copy(filter = None, projectCache = Map.empty, errorCache = Map.empty) )).clearCaches
val expected = Resolution( val expected = Resolution(
rootDependencies = Set(dep), rootDependencies = Set(dep),
@ -386,7 +386,7 @@ object ResolutionTests extends TestSuite {
Dependency(Module("org.escalier", "librairie-standard"), "2.11.6")) Dependency(Module("org.escalier", "librairie-standard"), "2.11.6"))
val res = await(resolve0( val res = await(resolve0(
Set(dep) Set(dep)
)).copy(filter = None, projectCache = Map.empty, errorCache = Map.empty) )).clearCaches
val expected = Resolution( val expected = Resolution(
rootDependencies = Set(dep), rootDependencies = Set(dep),
@ -405,7 +405,7 @@ object ResolutionTests extends TestSuite {
Dependency(Module("org.escalier", "librairie-standard"), "2.11.6")) Dependency(Module("org.escalier", "librairie-standard"), "2.11.6"))
val res = await(resolve0( val res = await(resolve0(
Set(dep) Set(dep)
)).copy(filter = None, projectCache = Map.empty, errorCache = Map.empty) )).clearCaches
val expected = Resolution( val expected = Resolution(
rootDependencies = Set(dep), rootDependencies = Set(dep),
@ -426,7 +426,7 @@ object ResolutionTests extends TestSuite {
Dependency(Module("org.escalier", "librairie-standard"), "2.11.6")) Dependency(Module("org.escalier", "librairie-standard"), "2.11.6"))
val res = await(resolve0( val res = await(resolve0(
Set(dep) Set(dep)
)).copy(filter = None, projectCache = Map.empty, errorCache = Map.empty) )).clearCaches
val expected = Resolution( val expected = Resolution(
rootDependencies = Set(dep), rootDependencies = Set(dep),
@ -447,7 +447,7 @@ object ResolutionTests extends TestSuite {
val res = await(resolve0( val res = await(resolve0(
Set(dep), Set(dep),
filter = Some(_ => true) filter = Some(_ => true)
)).copy(filter = None, projectCache = Map.empty, errorCache = Map.empty) )).clearCaches.clearFilter
val expected = Resolution( val expected = Resolution(
rootDependencies = Set(dep), rootDependencies = Set(dep),
@ -470,7 +470,7 @@ object ResolutionTests extends TestSuite {
val res = await(resolve0( val res = await(resolve0(
deps, deps,
filter = Some(_ => true) filter = Some(_ => true)
)).copy(filter = None, projectCache = Map.empty, errorCache = Map.empty) )).clearCaches.clearFilter
val expected = Resolution( val expected = Resolution(
rootDependencies = deps, rootDependencies = deps,
@ -492,7 +492,7 @@ object ResolutionTests extends TestSuite {
val res = await(resolve0( val res = await(resolve0(
deps, deps,
forceVersions = depOverrides forceVersions = depOverrides
)).copy(filter = None, projectCache = Map.empty, errorCache = Map.empty) )).clearCaches
val expected = Resolution( val expected = Resolution(
rootDependencies = deps, rootDependencies = deps,
@ -516,7 +516,7 @@ object ResolutionTests extends TestSuite {
val res = await(resolve0( val res = await(resolve0(
deps, deps,
forceVersions = depOverrides forceVersions = depOverrides
)).copy(filter = None, projectCache = Map.empty, errorCache = Map.empty) )).clearCaches
val expected = Resolution( val expected = Resolution(
rootDependencies = deps, rootDependencies = deps,
@ -542,7 +542,7 @@ object ResolutionTests extends TestSuite {
val res = await(resolve0( val res = await(resolve0(
deps, deps,
forceVersions = depOverrides forceVersions = depOverrides
)).copy(filter = None, projectCache = Map.empty, errorCache = Map.empty) )).clearCaches
val expected = Resolution( val expected = Resolution(
rootDependencies = deps, rootDependencies = deps,

View File

@ -6,6 +6,24 @@ package object test {
def withCompileScope: Dependency = underlying.copy(configuration = "compile") def withCompileScope: Dependency = underlying.copy(configuration = "compile")
} }
implicit class ResolutionOps(val underlying: Resolution) extends AnyVal {
// The content of these fields is typically not validated in the tests.
// It can be cleared with these method to it easier to compare `underlying`
// to an expected value.
def clearFinalDependenciesCache: Resolution =
underlying.copy(finalDependenciesCache = Map.empty)
def clearCaches: Resolution =
underlying.copy(
projectCache = Map.empty,
errorCache = Map.empty,
finalDependenciesCache = Map.empty
)
def clearFilter: Resolution =
underlying.copy(filter = None)
}
object Profile { object Profile {
type Activation = core.Activation type Activation = core.Activation
object Activation { object Activation {