Merge pull request #122 from dwijnand/detangle

Detangle the dependencies
This commit is contained in:
Dale Wijnand 2017-07-06 14:59:12 +01:00 committed by GitHub
commit 74d8a3835d
14 changed files with 44 additions and 352 deletions

View File

@ -37,8 +37,9 @@ lazy val lmRoot = (project in file("."))
Seq(
homepage := Some(url("https://github.com/sbt/librarymanagement")),
description := "Library management module for sbt",
scmInfo := Some(ScmInfo(url("https://github.com/sbt/librarymanagement"),
"git@github.com:sbt/librarymanagement.git")),
scmInfo := Some(ScmInfo(
url("https://github.com/sbt/librarymanagement"), "git@github.com:sbt/librarymanagement.git"
)),
bintrayPackage := "librarymanagement",
scalafmtOnCompile := true,
// scalafmtVersion 1.0.0-RC3 has regression
@ -63,21 +64,17 @@ lazy val lm = (project in file("librarymanagement"))
.settings(
commonSettings,
name := "librarymanagement",
libraryDependencies ++= Seq(ivy,
jsch,
scalaReflect.value,
launcherInterface,
gigahorseOkhttp,
okhttpUrlconnection,
sjsonnewScalaJson.value % Optional),
libraryDependencies ++= Seq(
ivy, jsch, scalaReflect.value, launcherInterface, gigahorseOkhttp, okhttpUrlconnection,
sjsonnewScalaJson.value % Optional,
scalaTest
),
libraryDependencies ++= scalaXml.value,
resourceGenerators in Compile += Def
.task(
Util.generateVersionFile(version.value,
resourceManaged.value,
streams.value,
(compile in Compile).value))
.taskValue,
resourceGenerators in Compile += Def.task(
Util.generateVersionFile(
version.value, resourceManaged.value, streams.value, (compile in Compile).value
)
).taskValue,
// mimaBinaryIssueFilters ++= Seq(),
managedSourceDirectories in Compile +=
baseDirectory.value / "src" / "main" / "contraband-scala",
@ -91,19 +88,14 @@ lazy val lm = (project in file("librarymanagement"))
(((srcs --- sdirs --- base) pair (relativeTo(sdirs) | relativeTo(base) | flat)) toSeq)
}
)
.configure(addSbtIO,
addSbtUtilLogging,
addSbtUtilTesting,
addSbtUtilCollection,
addSbtUtilCompletion,
addSbtUtilCache)
.configure(addSbtIO, addSbtUtilLogging, addSbtUtilPosition, addSbtUtilCache)
.enablePlugins(ContrabandPlugin, JsonCodecPlugin)
def customCommands: Seq[Setting[_]] = Seq(
commands += Command.command("release") { state =>
// "clean" ::
"so compile" ::
"so publishSigned" ::
"+compile" ::
"+publishSigned" ::
"reload" ::
state
}

View File

@ -1,11 +1,10 @@
package sbt.internal.librarymanagement
import java.io.File
import org.apache.ivy.core
import core.module.descriptor.ModuleDescriptor
import org.apache.ivy.core.module.descriptor.ModuleDescriptor
import sbt.io.IO
import sbt.util.{ CacheStore, Logger }
import sbt.librarymanagement._
import sbt.librarymanagement.LibraryManagementCodec._
import sbt.librarymanagement._, LibraryManagementCodec._
private[sbt] object JsonUtil {
def sbtOrgTemp = "org.scala-sbt.temp"
@ -22,14 +21,17 @@ private[sbt] object JsonUtil {
fromLite(lite, cachedDescriptor)
} catch {
case e: Throwable =>
log.error("Unable to parse mini graph: " + path.toString)
log.error(s"Unable to parse mini graph: $path")
throw e
}
}
def writeUpdateReport(ur: UpdateReport, graphPath: File): Unit = {
sbt.io.IO.createDirectory(graphPath.getParentFile)
CacheStore(graphPath).write(toLite(ur))
val updateReportLite = toLite(ur)
IO.createDirectory(graphPath.getParentFile)
CacheStore(graphPath).write(updateReportLite)
}
def toLite(ur: UpdateReport): UpdateReportLite =
UpdateReportLite(ur.configurations map { cr =>
ConfigurationReportLite(
@ -65,6 +67,7 @@ private[sbt] object JsonUtil {
}
)
})
// #1763/#2030. Caller takes up 97% of space, so we need to shrink it down,
// but there are semantics associated with some of them.
def filterOutArtificialCallers(callers: Vector[Caller]): Vector[Caller] =

View File

@ -1,117 +0,0 @@
package sbt
package internal
package librarymanagement
import java.io.File
import java.net.URL
import scala.io.Source
import sbt.internal.util.complete.Parser
import sbt.internal.util.complete.DefaultParsers._
private[sbt] object RepositoriesParser {
private case class AfterPattern(artifactPattern: Option[String], flags: Int)
final case class PredefinedRepository(override val id: xsbti.Predefined)
extends xsbti.PredefinedRepository
final case class MavenRepository(override val id: String, override val url: URL)
extends xsbti.MavenRepository
final case class IvyRepository(
override val id: String,
override val url: URL,
override val ivyPattern: String,
override val artifactPattern: String,
override val mavenCompatible: Boolean,
override val skipConsistencyCheck: Boolean,
override val descriptorOptional: Boolean,
val bootOnly: Boolean
) extends xsbti.IvyRepository
// Predefined repositories
def local: Parser[xsbti.Repository] =
"local" ^^^ new PredefinedRepository(xsbti.Predefined.Local)
def mavenLocal: Parser[xsbti.Repository] =
"maven-local" ^^^ new PredefinedRepository(xsbti.Predefined.MavenLocal)
def mavenCentral: Parser[xsbti.Repository] =
"maven-central" ^^^ new PredefinedRepository(xsbti.Predefined.MavenCentral)
def predefinedResolver: Parser[xsbti.Repository] = local | mavenLocal | mavenCentral
// Options
def descriptorOptional: Parser[Int] = "descriptorOptional" ^^^ Flags.descriptorOptionalFlag
def skipConsistencyCheck: Parser[Int] = "skipConsistencyCheck" ^^^ Flags.skipConsistencyCheckFlag
def bootOnly: Parser[Int] = "bootOnly" ^^^ Flags.bootOnlyFlag
def mavenCompatible: Parser[Int] = "mavenCompatible" ^^^ Flags.mavenCompatibleFlag
def option: Parser[Int] = descriptorOptional | skipConsistencyCheck | bootOnly | mavenCompatible
def options: Parser[Int] = rep1sep(option, separator) map (_ reduce (_ | _))
def name: Parser[String] = ID
def separator: Parser[String] = "," ~> charClass(c => c == ' ' || c == '\t').*.string
def nonComma: Parser[String] = charClass(_ != ',').*.string
def ivyPattern: Parser[String] = nonComma
def artifactPattern: Parser[String] = nonComma
private def afterPattern: Parser[AfterPattern] = {
def onlyOptions = options map (AfterPattern(None, _))
def both = artifactPattern ~ (separator ~> options).? map {
case ap ~ opts => AfterPattern(Some(ap), opts getOrElse 0)
}
onlyOptions | both
}
def customResolver: Parser[xsbti.Repository] =
name ~ ": " ~ basicUri ~ (separator ~> ivyPattern).? ~ (separator ~> afterPattern).? map {
case name ~ ": " ~ uri ~ None ~ _ =>
new MavenRepository(name, uri.toURL)
case name ~ ": " ~ uri ~ Some(ivy) ~ ap =>
// scalac complains about the recursion depth if we pattern match over `ap` directly.
ap match {
case Some(AfterPattern(artifactPattern, Flags(dOpt, sc, bo, mc))) =>
new IvyRepository(
name,
uri.toURL,
ivy,
artifactPattern getOrElse ivy,
mc,
sc,
dOpt,
bo
)
case None =>
new IvyRepository(name, uri.toURL, ivy, ivy, false, false, false, false)
}
}
def resolver: Parser[xsbti.Repository] =
predefinedResolver | customResolver
def getResolver[T](in: String)(parser: Parser[T]): Option[T] =
Parser.parse(in.trim, parser).right.toOption
def apply(lines: Iterator[String]): Seq[xsbti.Repository] =
if (lines.isEmpty) Nil
else {
if (lines.next != "[repositories]")
throw new Exception("Repositories file must start with '[repositories]'")
lines.flatMap(getResolver(_)(resolver)).toList
}
def apply(str: String): Seq[xsbti.Repository] = apply(str.lines)
def apply(file: File): Seq[xsbti.Repository] = {
if (!file.exists) Nil
else apply(Source.fromFile(file).getLines)
}
object Flags {
val descriptorOptionalFlag = 1 << 0
val skipConsistencyCheckFlag = 1 << 1
val bootOnlyFlag = 1 << 2
val mavenCompatibleFlag = 1 << 3
def unapply(flags: Int): Some[(Boolean, Boolean, Boolean, Boolean)] = {
val dOpt = (flags & descriptorOptionalFlag) != 0
val sc = (flags & skipConsistencyCheckFlag) != 0
val bo = (flags & bootOnlyFlag) != 0
val mc = (flags & mavenCompatibleFlag) != 0
Some((dOpt, sc, bo, mc))
}
}
}

View File

@ -1,6 +1,6 @@
package sbt.librarymanagement
import sbt.internal.util.UnitSpec
import sbt.internal.librarymanagement.UnitSpec
import CrossVersion._
class CrossVersionTest extends UnitSpec {

View File

@ -3,7 +3,7 @@ package sbt.librarymanagement
import java.net.URL
import java.io.File
import sbt.internal._, librarymanagement._, util.UnitSpec
import sbt.internal._, librarymanagement._
import scalajson.ast.unsafe._
import sjsonnew._, support.scalajson.unsafe._
import org.scalatest.Assertion

View File

@ -1,6 +1,6 @@
package sbt.internal.librarymanagement
import org.apache.ivy.core.module.descriptor.{ DependencyArtifactDescriptor }
import org.apache.ivy.core.module.descriptor.DependencyArtifactDescriptor
import sbt.librarymanagement._
import sbt.internal.librarymanagement.ivyint._

View File

@ -1,6 +1,6 @@
package sbt.librarymanagement
import sbt.internal.util.UnitSpec
import sbt.internal.librarymanagement.UnitSpec
class ModuleIdTest extends UnitSpec {
"Module Id" should "return cross-disabled module id as equal to a copy" in {

View File

@ -3,7 +3,7 @@ package sbt.librarymanagement
import org.scalatest.Assertion
import sbt.internal.librarymanagement._
import sbt.internal.librarymanagement.impl.DependencyBuilders
import sbt.io.{ FileFilter, IO, Path }
import sbt.io.IO
class OfflineModeSpec extends BaseIvySpecification with DependencyBuilders {
private final def targetDir = Some(currentDependency)
@ -40,7 +40,7 @@ class OfflineModeSpec extends BaseIvySpecification with DependencyBuilders {
// Compute an estimate to ensure that the second resolution does indeed use the cache
val originalResolveTime = onlineResolution.right.get.stats.resolveTime
val estimatedCachedTime = originalResolveTime * 0.15
val estimatedCachedTime = originalResolveTime * 0.3
val offlineResolution =
IvyActions.updateEither(toResolve, offlineConf, warningConf, noClock, targetDir, log)

View File

@ -2,7 +2,7 @@ package sbt.librarymanagement
import java.net.URL
import sbt.internal.util.UnitSpec
import sbt.internal.librarymanagement.UnitSpec
object ResolverTest extends UnitSpec {

View File

@ -3,7 +3,7 @@ package sbt.librarymanagement
import org.apache.ivy.core.module.id.ModuleRevisionId
import org.apache.ivy.core.module.descriptor.DefaultDependencyDescriptor
import sbt.internal.util.UnitSpec
import sbt.internal.librarymanagement.UnitSpec
import IvyScala.OverrideScalaMediator
import ScalaArtifacts._

View File

@ -1,6 +1,6 @@
package sbt.librarymanagement
import sbt.internal.util.UnitSpec
import sbt.internal.librarymanagement.UnitSpec
class UpdateOptionsSpec extends UnitSpec {

View File

@ -1,6 +1,6 @@
package sbt.librarymanagement
import sbt.internal.util.UnitSpec
import sbt.internal.librarymanagement.UnitSpec
// This is a specification to check the version number parsing.
class VersionNumberSpec extends UnitSpec {

View File

@ -1,175 +0,0 @@
package sbt
package internal
package librarymanagement
import java.net.URL
/**
* Tests that we can correctly parse repositories definitions.
*/
class RepositoriesParserSpecification extends UnitSpec {
import RepositoriesParser._
"The RepositoriesParser" should "check that repositories file starts with [repositories]" in {
val file = """local
|maven-central""".stripMargin
a[Exception] should be thrownBy RepositoriesParser(file)
}
it should "parse the local repository" in {
val file = """[repositories]
| local""".stripMargin
val repos = RepositoriesParser(file)
repos.size shouldBe 1
repos(0) shouldBe PredefinedRepository(xsbti.Predefined.Local)
}
it should "parse the local maven repository" in {
val file = """[repositories]
| maven-local""".stripMargin
val repos = RepositoriesParser(file)
repos.size shouldBe 1
repos(0) shouldBe PredefinedRepository(xsbti.Predefined.MavenLocal)
}
it should "parse Maven Central repository" in {
val file = """[repositories]
| maven-central""".stripMargin
val repos = RepositoriesParser(file)
repos.size shouldBe 1
repos(0) shouldBe PredefinedRepository(xsbti.Predefined.MavenCentral)
}
it should "parse simple Maven repository" in {
val file = """[repositories]
| mavenRepo: https://repo1.maven.org""".stripMargin
val repos = RepositoriesParser(file)
repos.size shouldBe 1
repos(0) shouldBe MavenRepository("mavenRepo", new URL("https://repo1.maven.org"))
}
it should "parse `bootOnly` option" in {
val file = """[repositories]
| ivyRepo: https://repo1.maven.org, [orgPath], bootOnly""".stripMargin
val repos = RepositoriesParser(file)
val expected =
IvyRepository(
"ivyRepo",
new URL("https://repo1.maven.org"),
"[orgPath]",
"[orgPath]",
mavenCompatible = false,
skipConsistencyCheck = false,
descriptorOptional = false,
bootOnly = true
)
repos.size shouldBe 1
repos(0) shouldBe expected
}
it should "parse `mavenCompatible` option" in {
val file = """[repositories]
| ivyRepo: https://repo1.maven.org, [orgPath], mavenCompatible""".stripMargin
val repos = RepositoriesParser(file)
val expected =
IvyRepository(
"ivyRepo",
new URL("https://repo1.maven.org"),
"[orgPath]",
"[orgPath]",
mavenCompatible = true,
skipConsistencyCheck = false,
descriptorOptional = false,
bootOnly = false
)
repos.size shouldBe 1
repos(0) shouldBe expected
}
it should "parse `skipConsistencyCheck` option" in {
val file = """[repositories]
| ivyRepo: https://repo1.maven.org, [orgPath], skipConsistencyCheck""".stripMargin
val repos = RepositoriesParser(file)
val expected =
IvyRepository(
"ivyRepo",
new URL("https://repo1.maven.org"),
"[orgPath]",
"[orgPath]",
mavenCompatible = false,
skipConsistencyCheck = true,
descriptorOptional = false,
bootOnly = false
)
repos.size shouldBe 1
repos(0) shouldBe expected
}
it should "parse `descriptorOptional` option" in {
val file = """[repositories]
| ivyRepo: https://repo1.maven.org, [orgPath], descriptorOptional""".stripMargin
val repos = RepositoriesParser(file)
val expected =
IvyRepository(
"ivyRepo",
new URL("https://repo1.maven.org"),
"[orgPath]",
"[orgPath]",
mavenCompatible = false,
skipConsistencyCheck = false,
descriptorOptional = true,
bootOnly = false
)
repos.size shouldBe 1
repos(0) shouldBe expected
}
it should "parse complex ivy repository definition" in {
val file =
"""[repositories]
| ivyRepo: https://repo1.maven.org, [orgPath], [artPath], descriptorOptional, skipConsistencyCheck""".stripMargin
val repos = RepositoriesParser(file)
val expected =
IvyRepository(
"ivyRepo",
new URL("https://repo1.maven.org"),
"[orgPath]",
"[artPath]",
mavenCompatible = false,
skipConsistencyCheck = true,
descriptorOptional = true,
bootOnly = false
)
repos.size shouldBe 1
repos(0) shouldBe expected
}
it should "parse multiple repositories defined together" in {
val file =
"""[repositories]
| local
| ivyRepo: https://repo1.maven.org, [orgPath], [artPath], descriptorOptional, skipConsistencyCheck
| mavenRepo: https://repo1.maven.org""".stripMargin
val expected0 = PredefinedRepository(xsbti.Predefined.Local)
val expected1 =
IvyRepository(
"ivyRepo",
new URL("https://repo1.maven.org"),
"[orgPath]",
"[artPath]",
mavenCompatible = false,
skipConsistencyCheck = true,
descriptorOptional = true,
bootOnly = false
)
val expected2 = MavenRepository("mavenRepo", new URL("https://repo1.maven.org"))
val repos = RepositoriesParser(file)
repos.size shouldBe 3
repos(0) shouldBe expected0
repos(1) shouldBe expected1
repos(2) shouldBe expected2
}
}

View File

@ -7,14 +7,12 @@ object Dependencies {
val scala212 = "2.12.2"
private val ioVersion = "1.0.0-M12"
private val utilVersion = "1.0.0-M25"
private val utilVersion = "1.0.0-M26"
private val sbtIO = "org.scala-sbt" %% "io" % ioVersion
private val utilCollection = "org.scala-sbt" %% "util-collection" % utilVersion
private val utilPosition = "org.scala-sbt" %% "util-position" % utilVersion
private val utilLogging = "org.scala-sbt" %% "util-logging" % utilVersion
private val utilTesting = "org.scala-sbt" %% "util-testing" % utilVersion
private val utilCompletion = "org.scala-sbt" %% "util-completion" % utilVersion
private val utilCache = "org.scala-sbt" %% "util-cache" % utilVersion
def getSbtModulePath(key: String, name: String) = {
@ -28,27 +26,17 @@ object Dependencies {
lazy val sbtIoPath = getSbtModulePath("sbtio.path", "sbt/io")
lazy val sbtUtilPath = getSbtModulePath("sbtutil.path", "sbt/util")
def addSbtModule(p: Project,
path: Option[String],
projectName: String,
m: ModuleID,
c: Option[Configuration] = None) =
def addSbtModule(p: Project, path: Option[String], projectName: String, m: ModuleID) =
path match {
case Some(f) =>
p dependsOn c.fold[ClasspathDep[ProjectReference]](ProjectRef(file(f), projectName))(
ProjectRef(file(f), projectName) % _)
case None => p settings (libraryDependencies += c.fold(m)(m % _))
case Some(f) => p dependsOn ProjectRef(file(f), projectName)
case None => p settings (libraryDependencies += m)
}
def addSbtIO(p: Project): Project = addSbtModule(p, sbtIoPath, "io", sbtIO)
def addSbtUtilCollection(p: Project): Project =
addSbtModule(p, sbtUtilPath, "utilCollection", utilCollection)
def addSbtUtilPosition(p: Project): Project =
addSbtModule(p, sbtUtilPath, "utilPosition", utilPosition)
def addSbtUtilLogging(p: Project): Project =
addSbtModule(p, sbtUtilPath, "utilLogging", utilLogging)
def addSbtUtilTesting(p: Project): Project =
addSbtModule(p, sbtUtilPath, "utilTesting", utilTesting, Some(Test))
def addSbtUtilCompletion(p: Project): Project =
addSbtModule(p, sbtUtilPath, "utilComplete", utilCompletion)
def addSbtUtilCache(p: Project): Project = addSbtModule(p, sbtUtilPath, "utilCache", utilCache)
val launcherInterface = "org.scala-sbt" % "launcher-interface" % "1.0.0"
@ -56,6 +44,7 @@ object Dependencies {
val jsch = "com.jcraft" % "jsch" % "0.1.46" intransitive ()
val scalaReflect = Def.setting { "org.scala-lang" % "scala-reflect" % scalaVersion.value }
val scalaXml = scala211Module("scala-xml", "1.0.5")
val scalaTest = "org.scalatest" %% "scalatest" % "3.0.1" % Test
val sjsonnew = Def.setting { "com.eed3si9n" %% "sjson-new-core" % contrabandSjsonNewVersion.value }
val sjsonnewScalaJson = Def.setting { "com.eed3si9n" %% "sjson-new-scalajson" % contrabandSjsonNewVersion.value }
val gigahorseOkhttp = "com.eed3si9n" %% "gigahorse-okhttp" % "0.3.0"