mirror of https://github.com/sbt/sbt.git
Merge pull request #58 from dwijnand/contraband
Switch to sbt-datatype, sjson-new & Vectors
This commit is contained in:
commit
e90b167b4e
12
build.sbt
12
build.sbt
|
|
@ -17,7 +17,6 @@ def commonSettings: Seq[Setting[_]] = Seq(
|
|||
crossScalaVersions := Seq(scala211),
|
||||
resolvers += Resolver.sonatypeRepo("public"),
|
||||
scalacOptions += "-Ywarn-unused",
|
||||
scalacOptions += "-Ywarn-unused-import",
|
||||
previousArtifact := None, // Some(organization.value %% moduleName.value % "1.0.0"),
|
||||
publishArtifact in Compile := true,
|
||||
publishArtifact in Test := false
|
||||
|
|
@ -47,11 +46,14 @@ lazy val lm = (project in file("librarymanagement")).
|
|||
commonSettings,
|
||||
name := "librarymanagement",
|
||||
libraryDependencies ++= Seq(
|
||||
ivy, jsch, sbtSerialization, scalaReflect.value, launcherInterface),
|
||||
resourceGenerators in Compile <+= (version, resourceManaged, streams, compile in Compile) map Util.generateVersionFile,
|
||||
binaryIssueFilters ++= Seq()
|
||||
ivy, jsch, scalaReflect.value, launcherInterface, sjsonnewScalaJson % Optional),
|
||||
libraryDependencies ++= scalaXml.value,
|
||||
resourceGenerators in Compile += Def.task(Util.generateVersionFile(version.value, resourceManaged.value, streams.value, (compile in Compile).value)).taskValue,
|
||||
binaryIssueFilters ++= Seq(),
|
||||
datatypeFormatsForType in generateDatatypes in Compile := DatatypeConfig.getFormats
|
||||
).
|
||||
configure(addSbtIO, addSbtUtilLogging, addSbtUtilTesting, addSbtUtilCollection, addSbtUtilCompletion)
|
||||
configure(addSbtIO, addSbtUtilLogging, addSbtUtilTesting, addSbtUtilCollection, addSbtUtilCompletion, addSbtUtilCache).
|
||||
enablePlugins(DatatypePlugin, JsonCodecPlugin)
|
||||
|
||||
def customCommands: Seq[Setting[_]] = Seq(
|
||||
commands += Command.command("release") { state =>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,775 @@
|
|||
{
|
||||
"codecNamespace": "sbt.librarymanagement",
|
||||
"fullCodec": "LibraryManagementCodec",
|
||||
"types": [
|
||||
{
|
||||
"name": "Artifact",
|
||||
"namespace": "sbt.librarymanagement",
|
||||
"target": "Scala",
|
||||
"type": "record",
|
||||
"parents": "sbt.librarymanagement.ArtifactExtra",
|
||||
"fields": [
|
||||
{ "name": "name", "type": "String" },
|
||||
{ "name": "type", "type": "String", "default": "Artifact.DefaultType", "since": "0.0.1" },
|
||||
{ "name": "extension", "type": "String", "default": "Artifact.DefaultExtension", "since": "0.0.1" },
|
||||
{ "name": "classifier", "type": "String?", "default": "None", "since": "0.0.1" },
|
||||
{ "name": "configurations", "type": "sbt.librarymanagement.Configuration*", "default": "Vector.empty", "since": "0.0.1" },
|
||||
{ "name": "url", "type": "java.net.URL?", "default": "None", "since": "0.0.1" },
|
||||
{ "name": "extraAttributes", "type": "Map[String, String]", "default": "Map.empty", "since": "0.0.1" }
|
||||
],
|
||||
"parentsCompanion": "sbt.librarymanagement.ArtifactFunctions"
|
||||
},
|
||||
{
|
||||
"name": "ArtifactTypeFilter",
|
||||
"namespace": "sbt.librarymanagement",
|
||||
"target": "Scala",
|
||||
"type": "record",
|
||||
"doc": "Work around the inadequacy of Ivy's ArtifactTypeFilter (that it cannot reverse a filter)",
|
||||
"parents": "sbt.librarymanagement.ArtifactTypeFilterExtra",
|
||||
"fields": [
|
||||
{
|
||||
"name": "types",
|
||||
"doc": [
|
||||
"Represents the artifact types that we should try to resolve for (as in the allowed values of",
|
||||
"`artifact[type]` from a dependency `<publications>` section). One can use this to filter",
|
||||
"source / doc artifacts."
|
||||
],
|
||||
"type": "Set[String]"
|
||||
},
|
||||
{
|
||||
"name": "inverted",
|
||||
"doc": [ "Whether to invert the types filter (i.e. allow only types NOT in the set)" ],
|
||||
"type": "boolean"
|
||||
}
|
||||
],
|
||||
"parentsCompanion": "sbt.librarymanagement.ArtifactTypeFilterFunctions"
|
||||
},
|
||||
{
|
||||
"name": "Caller",
|
||||
"namespace": "sbt.librarymanagement",
|
||||
"target": "Scala",
|
||||
"type": "record",
|
||||
"fields": [
|
||||
{ "name": "caller", "type": "sbt.librarymanagement.ModuleID" },
|
||||
{ "name": "callerConfigurations", "type": "String*" },
|
||||
{ "name": "callerExtraAttributes", "type": "Map[String, String]" },
|
||||
{ "name": "isForceDependency", "type": "boolean" },
|
||||
{ "name": "isChangingDependency", "type": "boolean" },
|
||||
{ "name": "isTransitiveDependency", "type": "boolean" },
|
||||
{ "name": "isDirectlyForceDependency", "type": "boolean" }
|
||||
],
|
||||
"toString": "s\"$caller\""
|
||||
},
|
||||
{
|
||||
"name": "Configuration",
|
||||
"namespace": "sbt.librarymanagement",
|
||||
"target": "Scala",
|
||||
"type": "record",
|
||||
"doc": "Represents an Ivy configuration.",
|
||||
"parents": "sbt.librarymanagement.ConfigurationExtra",
|
||||
"fields": [
|
||||
{ "name": "name", "type": "String" },
|
||||
{ "name": "description", "type": "String", "default": "\"\"", "since": "0.0.1" },
|
||||
{ "name": "isPublic", "type": "boolean", "default": "true", "since": "0.0.1" },
|
||||
{ "name": "extendsConfigs", "type": "sbt.librarymanagement.Configuration*", "default": "Vector.empty", "since": "0.0.1" },
|
||||
{ "name": "transitive", "type": "boolean", "default": "true", "since": "0.0.1" }
|
||||
],
|
||||
"toString": "name"
|
||||
},
|
||||
{
|
||||
"name": "ConfigurationReport",
|
||||
"namespace": "sbt.librarymanagement",
|
||||
"target": "Scala",
|
||||
"type": "record",
|
||||
"doc": [
|
||||
"Provides information about resolution of a single configuration."
|
||||
],
|
||||
"parents": "sbt.librarymanagement.ConfigurationReportExtra",
|
||||
"fields": [
|
||||
{ "name": "configuration", "type": "String", "doc": [ "the configuration this report is for." ] },
|
||||
{
|
||||
"name": "modules",
|
||||
"type": "sbt.librarymanagement.ModuleReport*",
|
||||
"doc": [
|
||||
"a sequence containing one report for each module resolved for this configuration."
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "details",
|
||||
"type": "sbt.librarymanagement.OrganizationArtifactReport*",
|
||||
"doc": [ "a sequence containing one report for each org/name, which may or may not be part of the final resolution." ]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "ConflictManager",
|
||||
"namespace": "sbt.librarymanagement",
|
||||
"target": "Scala",
|
||||
"type": "record",
|
||||
"doc": "See http://ant.apache.org/ivy/history/latest-milestone/settings/conflict-managers.html for details of the different conflict managers.",
|
||||
"fields": [
|
||||
{ "name": "name", "type": "String" },
|
||||
{ "name": "organization", "type": "String", "default": "\"*\"", "since": "0.0.1" },
|
||||
{ "name": "module", "type": "String", "default": "\"*\"", "since": "0.0.1" }
|
||||
],
|
||||
"parentsCompanion": "sbt.librarymanagement.ConflictManagerFunctions"
|
||||
},
|
||||
{
|
||||
"name": "CrossVersion",
|
||||
"namespace": "sbt.librarymanagement",
|
||||
"target": "Scala",
|
||||
"type": "interface",
|
||||
"doc": "Configures how a module will be cross-versioned.",
|
||||
"types": [
|
||||
{
|
||||
"name": "Disabled",
|
||||
"namespace": "sbt.librarymanagement",
|
||||
"target": "Scala",
|
||||
"doc": "Disables cross versioning for a module.",
|
||||
"type": "record"
|
||||
},
|
||||
{
|
||||
"name": "Binary",
|
||||
"namespace": "sbt.librarymanagement",
|
||||
"target": "Scala",
|
||||
"doc": [
|
||||
"Cross-versions a module using the result of applying `remapVersion` to the binary version.",
|
||||
"For example, if `remapVersion = v => \"2.10\"` and the binary version is \"2.9.2\" or \"2.10\",",
|
||||
"the module is cross-versioned with \"2.10\"."
|
||||
],
|
||||
"type": "record"
|
||||
},
|
||||
{
|
||||
"name": "Full",
|
||||
"namespace": "sbt.librarymanagement",
|
||||
"target": "Scala",
|
||||
"type": "record",
|
||||
"doc": [
|
||||
"Cross-versions a module with the result of applying `remapVersion` to the full version.",
|
||||
"For example, if `remapVersion = v => \"2.10\"` and the full version is \"2.9.2\" or \"2.10.3\",",
|
||||
"the module is cross-versioned with \"2.10\"."
|
||||
]
|
||||
}
|
||||
],
|
||||
"parentsCompanion": "sbt.librarymanagement.CrossVersionFunctions"
|
||||
},
|
||||
{
|
||||
"name": "Developer",
|
||||
"namespace": "sbt.librarymanagement",
|
||||
"target": "Scala",
|
||||
"type": "record",
|
||||
"fields": [
|
||||
{ "name": "id", "type": "String" },
|
||||
{ "name": "name", "type": "String" },
|
||||
{ "name": "email", "type": "String" },
|
||||
{ "name": "url", "type": "java.net.URL" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "FileConfiguration",
|
||||
"namespace": "sbt.librarymanagement",
|
||||
"target": "Scala",
|
||||
"type": "record",
|
||||
"doc": "Configuration specific to an Ivy filesystem resolver.",
|
||||
"fields": [
|
||||
{ "name": "isLocal", "type": "boolean" },
|
||||
{ "name": "isTransactional", "type": "boolean?" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "InclExclRule",
|
||||
"namespace": "sbt.librarymanagement",
|
||||
"target": "Scala",
|
||||
"type": "record",
|
||||
"doc": [
|
||||
"Rule to either:",
|
||||
"<ul>",
|
||||
"<li> exclude unwanted dependencies pulled in transitively by a module, or to</li>",
|
||||
"<li> include and merge artifacts coming from the ModuleDescriptor if \"dependencyArtifacts\" are also provided.</li>",
|
||||
"</ul>",
|
||||
"Which one depends on the parameter name which it is passed to, but the filter has the same fields in both cases."
|
||||
],
|
||||
"fields": [
|
||||
{ "name": "organization", "type": "String", "default": "\"*\"", "since": "0.0.1" },
|
||||
{ "name": "name", "type": "String", "default": "\"*\"", "since": "0.0.1" },
|
||||
{ "name": "artifact", "type": "String", "default": "\"*\"", "since": "0.0.1" },
|
||||
{ "name": "configurations", "type": "String*", "default": "Vector.empty", "since": "0.0.1" }
|
||||
],
|
||||
"parentsCompanion": "sbt.librarymanagement.InclExclRuleFunctions"
|
||||
},
|
||||
{
|
||||
"name": "IvyScala",
|
||||
"namespace": "sbt.librarymanagement",
|
||||
"target": "Scala",
|
||||
"type": "record",
|
||||
"fields": [
|
||||
{ "name": "scalaFullVersion", "type": "String" },
|
||||
{ "name": "scalaBinaryVersion", "type": "String" },
|
||||
{ "name": "configurations", "type": "sbt.librarymanagement.Configuration*" },
|
||||
{ "name": "checkExplicit", "type": "boolean" },
|
||||
{ "name": "filterImplicit", "type": "boolean" },
|
||||
{ "name": "overrideScalaVersion", "type": "boolean" },
|
||||
{ "name": "scalaOrganization", "type": "String", "default": "sbt.librarymanagement.ScalaArtifacts.Organization", "since": "0.0.1" },
|
||||
{ "name": "scalaArtifacts", "type": "String*", "default": "sbt.librarymanagement.ScalaArtifacts.Artifacts", "since": "0.0.1" }
|
||||
],
|
||||
"parentsCompanion": "sbt.librarymanagement.IvyScalaFunctions"
|
||||
},
|
||||
{
|
||||
"name": "ModuleConfiguration",
|
||||
"namespace": "sbt.librarymanagement",
|
||||
"target": "Scala",
|
||||
"type": "record",
|
||||
"fields": [
|
||||
{ "name": "organization", "type": "String" },
|
||||
{ "name": "name", "type": "String" },
|
||||
{ "name": "revision", "type": "String" },
|
||||
{ "name": "resolver", "type": "sbt.librarymanagement.Resolver" }
|
||||
],
|
||||
"extraCompanion": [
|
||||
"def apply(org: String, resolver: sbt.librarymanagement.Resolver): ModuleConfiguration = apply(org, \"*\", \"*\", resolver)",
|
||||
"def apply(org: String, name: String, resolver: sbt.librarymanagement.Resolver): ModuleConfiguration = ModuleConfiguration(org, name, \"*\", resolver)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "ModuleID",
|
||||
"namespace": "sbt.librarymanagement",
|
||||
"target": "Scala",
|
||||
"type": "record",
|
||||
"parents": "sbt.librarymanagement.ModuleIDExtra",
|
||||
"fields": [
|
||||
{ "name": "organization", "type": "String" },
|
||||
{ "name": "name", "type": "String" },
|
||||
{ "name": "revision", "type": "String" },
|
||||
{ "name": "configurations", "type": "String?", "default": "None", "since": "0.0.1" },
|
||||
{ "name": "isChanging", "type": "boolean", "default": "false", "since": "0.0.1" },
|
||||
{ "name": "isTransitive", "type": "boolean", "default": "true", "since": "0.0.1" },
|
||||
{ "name": "isForce", "type": "boolean", "default": "false", "since": "0.0.1" },
|
||||
{ "name": "explicitArtifacts", "type": "sbt.librarymanagement.Artifact*", "default": "Vector.empty", "since": "0.0.1" },
|
||||
{ "name": "inclusions", "type": "sbt.librarymanagement.InclExclRule*", "default": "Vector.empty", "since": "0.0.1" },
|
||||
{ "name": "exclusions", "type": "sbt.librarymanagement.InclExclRule*", "default": "Vector.empty", "since": "0.0.1" },
|
||||
{ "name": "extraAttributes", "type": "Map[String, String]", "default": "Map.empty", "since": "0.0.1" },
|
||||
{ "name": "crossVersion", "type": "sbt.librarymanagement.CrossVersion", "default": "sbt.librarymanagement.Disabled()", "since": "0.0.1" },
|
||||
{ "name": "branchName", "type": "String?", "default": "None", "since": "0.0.1" }
|
||||
],
|
||||
"toString": [
|
||||
"organization + \":\" + name + \":\" + revision +",
|
||||
" (configurations match { case Some(s) => \":\" + s; case None => \"\" }) +",
|
||||
" (if (extraAttributes.isEmpty) \"\" else \" \" + extraString)"
|
||||
],
|
||||
"parentsCompanion": "sbt.librarymanagement.ModuleIDFunctions"
|
||||
},
|
||||
{
|
||||
"name": "ModuleInfo",
|
||||
"namespace": "sbt.librarymanagement",
|
||||
"target": "Scala",
|
||||
"type": "record",
|
||||
"doc": "Additional information about a project module",
|
||||
"fields": [
|
||||
{ "name": "nameFormal", "type": "String" },
|
||||
{ "name": "description", "type": "String", "default": "\"\"", "since": "0.0.1" },
|
||||
{ "name": "homepage", "type": "java.net.URL?", "default": "None", "since": "0.0.1" },
|
||||
{ "name": "startYear", "type": "int?", "default": "None", "since": "0.0.1" },
|
||||
{ "name": "licenses", "type": "scala.Tuple2[String, java.net.URL]*", "default": "Vector.empty", "since": "0.0.1" },
|
||||
{ "name": "organizationName", "type": "String", "default": "\"\"", "since": "0.0.1" },
|
||||
{ "name": "organizationHomepage", "type": "java.net.URL?", "default": "None", "since": "0.0.1" },
|
||||
{ "name": "scmInfo", "type": "sbt.librarymanagement.ScmInfo?", "default": "None", "since": "0.0.1" },
|
||||
{ "name": "developers", "type": "sbt.librarymanagement.Developer*", "default": "Vector.empty", "since": "0.0.1" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "ModuleReport",
|
||||
"namespace": "sbt.librarymanagement",
|
||||
"target": "Scala",
|
||||
"type": "record",
|
||||
"doc": [
|
||||
"Provides information about the resolution of a module.",
|
||||
"This information is in the context of a specific configuration."
|
||||
],
|
||||
"parents": "sbt.librarymanagement.ModuleReportExtra",
|
||||
"fields": [
|
||||
{ "name": "module", "type": "sbt.librarymanagement.ModuleID" },
|
||||
{ "name": "artifacts", "type": "scala.Tuple2[sbt.librarymanagement.Artifact, java.io.File]*" },
|
||||
{ "name": "missingArtifacts", "type": "sbt.librarymanagement.Artifact*" },
|
||||
{ "name": "status", "type": "String?", "default": "None", "since": "0.0.1" },
|
||||
{ "name": "publicationDate", "type": "java.util.Date?", "default": "None", "since": "0.0.1" },
|
||||
{ "name": "resolver", "type": "String?", "default": "None", "since": "0.0.1" },
|
||||
{ "name": "artifactResolver", "type": "String?", "default": "None", "since": "0.0.1" },
|
||||
{ "name": "evicted", "type": "boolean", "default": "false", "since": "0.0.1" },
|
||||
{ "name": "evictedData", "type": "String?", "default": "None", "since": "0.0.1" },
|
||||
{ "name": "evictedReason", "type": "String?", "default": "None", "since": "0.0.1" },
|
||||
{ "name": "problem", "type": "String?", "default": "None", "since": "0.0.1" },
|
||||
{ "name": "homepage", "type": "String?", "default": "None", "since": "0.0.1" },
|
||||
{ "name": "extraAttributes", "type": "Map[String, String]", "default": "Map.empty", "since": "0.0.1" },
|
||||
{ "name": "isDefault", "type": "boolean?", "default": "None", "since": "0.0.1" },
|
||||
{ "name": "branch", "type": "String?", "default": "None", "since": "0.0.1" },
|
||||
{ "name": "configurations", "type": "String*", "default": "Vector.empty", "since": "0.0.1" },
|
||||
{ "name": "licenses", "type": "scala.Tuple2[String, Option[String]]*", "default": "Vector.empty", "since": "0.0.1" },
|
||||
{ "name": "callers", "type": "sbt.librarymanagement.Caller*", "default": "Vector.empty", "since": "0.0.1" }
|
||||
],
|
||||
"toString": [
|
||||
"s\"\\t\\t$module: \" +",
|
||||
"(if (arts.size <= 1) \"\" else \"\\n\\t\\t\\t\") + arts.mkString(\"\\n\\t\\t\\t\") + \"\\n\""
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "ModuleSettings",
|
||||
"namespace": "sbt.librarymanagement",
|
||||
"target": "Scala",
|
||||
"type": "interface",
|
||||
"fields": [
|
||||
{ "name": "validate", "type": "boolean" },
|
||||
{ "name": "ivyScala", "type": "sbt.librarymanagement.IvyScala?" }
|
||||
],
|
||||
"types": [
|
||||
{
|
||||
"name": "IvyFileConfiguration",
|
||||
"namespace": "sbt.librarymanagement",
|
||||
"target": "Scala",
|
||||
"type": "record",
|
||||
"fields": [
|
||||
{ "name": "file", "type": "java.io.File" },
|
||||
{ "name": "autoScalaTools", "type": "boolean" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "PomConfiguration",
|
||||
"namespace": "sbt.librarymanagement",
|
||||
"target": "Scala",
|
||||
"type": "record",
|
||||
"fields": [
|
||||
{ "name": "file", "type": "java.io.File" },
|
||||
{ "name": "autoScalaTools", "type": "boolean" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "InlineConfiguration",
|
||||
"namespace": "sbt.internal.librarymanagement",
|
||||
"target": "Scala",
|
||||
"type": "record",
|
||||
"fields": [
|
||||
{ "name": "module", "type": "sbt.librarymanagement.ModuleID" },
|
||||
{ "name": "moduleInfo", "type": "sbt.librarymanagement.ModuleInfo" },
|
||||
{ "name": "dependencies", "type": "sbt.librarymanagement.ModuleID*" },
|
||||
{ "name": "overrides", "type": "Set[sbt.librarymanagement.ModuleID]", "default": "Set.empty", "since": "0.0.1" },
|
||||
{ "name": "excludes", "type": "sbt.internal.librarymanagement.SbtExclusionRule*", "default": "Vector.empty", "since": "0.0.1" },
|
||||
{ "name": "ivyXML", "type": "scala.xml.NodeSeq", "default": "scala.xml.NodeSeq.Empty", "since": "0.0.1" },
|
||||
{ "name": "configurations", "type": "sbt.librarymanagement.Configuration*", "default": "Vector.empty", "since": "0.0.1" },
|
||||
{ "name": "defaultConfiguration", "type": "sbt.librarymanagement.Configuration?", "default": "None", "since": "0.0.1" },
|
||||
{ "name": "conflictManager", "type": "sbt.librarymanagement.ConflictManager", "default": "sbt.librarymanagement.ConflictManager.default", "since": "0.0.1" }
|
||||
],
|
||||
"parentsCompanion": "sbt.internal.librarymanagement.InlineConfigurationFunctions"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "OrganizationArtifactReport",
|
||||
"namespace": "sbt.librarymanagement",
|
||||
"target": "Scala",
|
||||
"type": "record",
|
||||
"doc": [
|
||||
"OrganizationArtifactReport represents an organization+name entry in Ivy resolution report.",
|
||||
"In sbt's terminology, \"module\" consists of organization, name, and version.",
|
||||
"In Ivy's, \"module\" means just organization and name, and the one including version numbers",
|
||||
"are called revisions.",
|
||||
"",
|
||||
"A sequence of OrganizationArtifactReport called details is newly added to ConfigurationReport, replacing evicted.",
|
||||
"(Note old evicted was just a seq of ModuleIDs).",
|
||||
"OrganizationArtifactReport groups the ModuleReport of both winners and evicted reports by their organization and name,",
|
||||
"which can be used to calculate detailed eviction warning etc."
|
||||
],
|
||||
"fields": [
|
||||
{ "name": "organization", "type": "String" },
|
||||
{ "name": "name", "type": "String" },
|
||||
{ "name": "modules", "type": "sbt.librarymanagement.ModuleReport*" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Patterns",
|
||||
"namespace": "sbt.librarymanagement",
|
||||
"target": "Scala",
|
||||
"type": "record",
|
||||
"fields": [
|
||||
{ "name": "ivyPatterns", "type": "String*", "default": "Vector.empty", "since": "0.0.1" },
|
||||
{ "name": "artifactPatterns", "type": "String*", "default": "Vector.empty", "since": "0.0.1" },
|
||||
{ "name": "isMavenCompatible", "type": "boolean", "default": "true", "since": "0.0.1" },
|
||||
{ "name": "descriptorOptional", "type": "boolean", "default": "false", "since": "0.0.1" },
|
||||
{ "name": "skipConsistencyCheck", "type": "boolean", "default": "false", "since": "0.0.1" }
|
||||
],
|
||||
"toString": [
|
||||
"\"Patterns(ivyPatterns=%s, artifactPatterns=%s, isMavenCompatible=%s, descriptorOptional=%s, skipConsistencyCheck=%s)\".format(",
|
||||
" ivyPatterns, artifactPatterns, isMavenCompatible, descriptorOptional, skipConsistencyCheck)"
|
||||
],
|
||||
"parentsCompanion": "sbt.librarymanagement.PatternsFunctions"
|
||||
},
|
||||
{
|
||||
"name": "Resolver",
|
||||
"namespace": "sbt.librarymanagement",
|
||||
"target": "Scala",
|
||||
"type": "interface",
|
||||
"fields": [
|
||||
{ "name": "name", "type": "String" }
|
||||
],
|
||||
"types": [
|
||||
{
|
||||
"name": "ChainedResolver",
|
||||
"namespace": "sbt.librarymanagement",
|
||||
"target": "Scala",
|
||||
"type": "record",
|
||||
"fields": [
|
||||
{ "name": "resolvers", "type": "sbt.librarymanagement.Resolver*" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "IMavenRepository",
|
||||
"namespace": "sbt.librarymanagement",
|
||||
"target": "Scala",
|
||||
"type": "interface",
|
||||
"doc": "An instance of a remote maven repository. Note: This will use Aether/Maven to resolve artifacts.",
|
||||
"fields": [
|
||||
{ "name": "root", "type": "String" },
|
||||
{ "name": "localIfFile", "type": "boolean", "default": "true", "since": "0.0.1" }
|
||||
],
|
||||
"types": [
|
||||
{
|
||||
"name": "MavenRepository",
|
||||
"namespace": "sbt.librarymanagement",
|
||||
"target": "Scala",
|
||||
"type": "record",
|
||||
"toString": "s\"$name: $root\""
|
||||
},
|
||||
{
|
||||
"name": "MavenCache",
|
||||
"namespace": "sbt.librarymanagement",
|
||||
"target": "Scala",
|
||||
"type": "record",
|
||||
"doc": [
|
||||
"An instance of maven CACHE directory. You cannot treat a cache directory the same as a a remote repository because",
|
||||
"the metadata is different (see Aether ML discussion)."
|
||||
],
|
||||
"fields": [
|
||||
{ "name": "rootFile", "type": "java.io.File" }
|
||||
],
|
||||
"extra": "def this(name: String, rootFile: java.io.File) = this(name, rootFile.toURI.toURL.toString, true, rootFile)",
|
||||
"toString": "s\"cache:$name: ${rootFile.getAbsolutePath}\"",
|
||||
"extraCompanion": "def apply(name: String, rootFile: java.io.File): MavenCache = new MavenCache(name, rootFile)"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "PatternsBasedRepository",
|
||||
"namespace": "sbt.librarymanagement",
|
||||
"target": "Scala",
|
||||
"type": "interface",
|
||||
"fields": [
|
||||
{ "name": "patterns", "type": "sbt.librarymanagement.Patterns" }
|
||||
],
|
||||
"doc": "sbt interface to an Ivy repository based on patterns, which is most Ivy repositories.",
|
||||
"types": [
|
||||
{
|
||||
"name": "FileRepository",
|
||||
"namespace": "sbt.librarymanagement",
|
||||
"target": "Scala",
|
||||
"type": "record",
|
||||
"doc": "sbt interface for an Ivy filesystem repository. More convenient construction is done using Resolver.file.",
|
||||
"fields": [
|
||||
{ "name": "configuration", "type": "sbt.librarymanagement.FileConfiguration" }
|
||||
],
|
||||
"extra": [
|
||||
"def this(name: String, configuration: sbt.librarymanagement.FileConfiguration, patterns: sbt.librarymanagement.Patterns) = ",
|
||||
" this(name, patterns, configuration)"
|
||||
],
|
||||
"extraCompanion": [
|
||||
"def apply(name: String, configuration: sbt.librarymanagement.FileConfiguration, patterns: sbt.librarymanagement.Patterns) = ",
|
||||
" new FileRepository(name, patterns, configuration)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "URLRepository",
|
||||
"namespace": "sbt.librarymanagement",
|
||||
"target": "Scala",
|
||||
"type": "record"
|
||||
},
|
||||
{
|
||||
"name": "SshBasedRepository",
|
||||
"namespace": "sbt.librarymanagement",
|
||||
"target": "Scala",
|
||||
"type": "interface",
|
||||
"doc": "sbt interface for an Ivy ssh-based repository (ssh and sftp). Requires the Jsch library..",
|
||||
"fields": [
|
||||
{ "name": "connection", "type": "sbt.librarymanagement.SshConnection" }
|
||||
],
|
||||
"types": [
|
||||
{
|
||||
"name": "SshRepository",
|
||||
"namespace": "sbt.librarymanagement",
|
||||
"target": "Scala",
|
||||
"type": "record",
|
||||
"doc": "sbt interface for an Ivy repository over ssh. More convenient construction is done using Resolver.ssh.",
|
||||
"fields": [
|
||||
{ "name": "publishPermissions", "type": "String?" }
|
||||
],
|
||||
"extra": [
|
||||
"def this(name: String, connection: sbt.librarymanagement.SshConnection, patterns: sbt.librarymanagement.Patterns, publishPermissions: Option[String]) = ",
|
||||
" this(name, patterns, connection, publishPermissions)"
|
||||
],
|
||||
"extraCompanion": [
|
||||
"def apply(name: String, connection: sbt.librarymanagement.SshConnection, patterns: sbt.librarymanagement.Patterns, publishPermissions: Option[String]) = ",
|
||||
" new SshRepository(name, patterns, connection, publishPermissions)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "SftpRepository",
|
||||
"namespace": "sbt.librarymanagement",
|
||||
"target": "Scala",
|
||||
"type": "record",
|
||||
"doc": "sbt interface for an Ivy repository over sftp. More convenient construction is done using Resolver.sftp.",
|
||||
"extra": [
|
||||
"def this(name: String, connection: sbt.librarymanagement.SshConnection, patterns: sbt.librarymanagement.Patterns) = ",
|
||||
" this(name, patterns, connection)"
|
||||
],
|
||||
"extraCompanion": [
|
||||
"def apply(name: String, connection: sbt.librarymanagement.SshConnection, patterns: sbt.librarymanagement.Patterns) = ",
|
||||
" new SftpRepository(name, patterns, connection)"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"parentsCompanion": "sbt.librarymanagement.ResolverFunctions"
|
||||
},
|
||||
{
|
||||
"name": "ScmInfo",
|
||||
"namespace": "sbt.librarymanagement",
|
||||
"target": "Scala",
|
||||
"type": "record",
|
||||
"doc": "Basic SCM information for a project module",
|
||||
"fields": [
|
||||
{ "name": "browseUrl", "type": "java.net.URL" },
|
||||
{ "name": "connection", "type": "String" },
|
||||
{ "name": "devConnection", "type": "String?" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "SshAuthentication",
|
||||
"namespace": "sbt.librarymanagement",
|
||||
"target": "Scala",
|
||||
"type": "interface",
|
||||
"types": [
|
||||
{
|
||||
"name": "PasswordAuthentication",
|
||||
"namespace": "sbt.librarymanagement",
|
||||
"target": "Scala",
|
||||
"type": "record",
|
||||
"fields": [
|
||||
{ "name": "user", "type": "String" },
|
||||
{ "name": "password", "type": "String?" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "KeyFileAuthentication",
|
||||
"namespace": "sbt.librarymanagement",
|
||||
"target": "Scala",
|
||||
"type": "record",
|
||||
"fields": [
|
||||
{ "name": "user", "type": "String" },
|
||||
{ "name": "keyfile", "type": "java.io.File" },
|
||||
{ "name": "password", "type": "String?" }
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "SshConnection",
|
||||
"namespace": "sbt.librarymanagement",
|
||||
"target": "Scala",
|
||||
"type": "record",
|
||||
"fields": [
|
||||
{ "name": "authentication", "type": "sbt.librarymanagement.SshAuthentication?" },
|
||||
{ "name": "hostname", "type": "String?" },
|
||||
{ "name": "port", "type": "int?" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "UpdateConfiguration",
|
||||
"namespace": "sbt.librarymanagement",
|
||||
"target": "Scala",
|
||||
"type": "record",
|
||||
"fields": [
|
||||
{ "name": "retrieve", "type": "sbt.internal.librarymanagement.RetrieveConfiguration?" },
|
||||
{ "name": "missingOk", "type": "boolean" },
|
||||
{ "name": "logging", "type": "sbt.librarymanagement.UpdateLogging" },
|
||||
{ "name": "artifactFilter", "type": "sbt.librarymanagement.ArtifactTypeFilter" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "UpdateLogging",
|
||||
"namespace": "sbt.librarymanagement",
|
||||
"target": "Scala",
|
||||
"type": "enumeration",
|
||||
"doc": [
|
||||
"Configures logging during an 'update'. `level` determines the amount of other information logged.",
|
||||
"`Full` is the default and logs the most.",
|
||||
"`DownloadOnly` only logs what is downloaded.",
|
||||
"`Quiet` only displays errors.",
|
||||
"`Default` uses the current log level of `update` task."
|
||||
],
|
||||
"symbols": [ "Full", "DownloadOnly", "Quiet", "Default" ]
|
||||
},
|
||||
{
|
||||
"name": "UpdateReport",
|
||||
"namespace": "sbt.librarymanagement",
|
||||
"target": "Scala",
|
||||
"type": "record",
|
||||
"doc": [
|
||||
"Provides information about dependency resolution.",
|
||||
"It does not include information about evicted modules, only about the modules ultimately selected by the conflict manager.",
|
||||
"This means that for a given configuration, there should only be one revision for a given organization and module name."
|
||||
],
|
||||
"parents": "sbt.librarymanagement.UpdateReportExtra",
|
||||
"fields": [
|
||||
{
|
||||
"name": "cachedDescriptor",
|
||||
"type": "java.io.File",
|
||||
"doc": [ "the location of the resolved module descriptor in the cache" ]
|
||||
},
|
||||
{
|
||||
"name": "configurations",
|
||||
"type": "sbt.librarymanagement.ConfigurationReport*",
|
||||
"doc": [ "a sequence containing one report for each configuration resolved." ]
|
||||
},
|
||||
{
|
||||
"name": "stats",
|
||||
"type": "sbt.librarymanagement.UpdateStats",
|
||||
"doc": [ "stats information about the update that produced this report" ]
|
||||
},
|
||||
{ "name": "stamps", "type": "Map[java.io.File, Long]" }
|
||||
],
|
||||
"toString": "\"Update report:\\n\\t\" + stats + \"\\n\" + configurations.mkString"
|
||||
},
|
||||
{
|
||||
"name": "UpdateStats",
|
||||
"namespace": "sbt.librarymanagement",
|
||||
"target": "Scala",
|
||||
"type": "record",
|
||||
"fields": [
|
||||
{ "name": "resolveTime", "type": "long" },
|
||||
{ "name": "downloadTime", "type": "long" },
|
||||
{ "name": "downloadSize", "type": "long" },
|
||||
{ "name": "cached", "type": "boolean" }
|
||||
],
|
||||
"toString": "Seq(\"Resolve time: \" + resolveTime + \" ms\", \"Download time: \" + downloadTime + \" ms\", \"Download size: \" + downloadSize + \" bytes\").mkString(\", \")"
|
||||
},
|
||||
|
||||
{
|
||||
"name": "ConfigurationReportLite",
|
||||
"namespace": "sbt.internal.librarymanagement",
|
||||
"target": "Scala",
|
||||
"type": "record",
|
||||
"fields": [
|
||||
{ "name": "configuration", "type": "String" },
|
||||
{ "name": "details", "type": "sbt.librarymanagement.OrganizationArtifactReport*" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "IvyConfiguration",
|
||||
"namespace": "sbt.internal.librarymanagement",
|
||||
"target": "Scala",
|
||||
"type": "interface",
|
||||
"fields": [
|
||||
{ "name": "lock", "type": "xsbti.GlobalLock?" },
|
||||
{ "name": "baseDirectory", "type": "java.io.File" },
|
||||
{ "name": "log", "type": "xsbti.Logger" },
|
||||
{ "name": "updateOptions", "type": "sbt.librarymanagement.UpdateOptions" }
|
||||
],
|
||||
"types": [
|
||||
{
|
||||
"name": "InlineIvyConfiguration",
|
||||
"namespace": "sbt.internal.librarymanagement",
|
||||
"target": "Scala",
|
||||
"type": "record",
|
||||
"fields": [
|
||||
{ "name": "paths", "type": "sbt.internal.librarymanagement.IvyPaths" },
|
||||
{ "name": "resolvers", "type": "sbt.librarymanagement.Resolver*" },
|
||||
{ "name": "otherResolvers", "type": "sbt.librarymanagement.Resolver*" },
|
||||
{ "name": "moduleConfigurations", "type": "sbt.librarymanagement.ModuleConfiguration*" },
|
||||
{ "name": "localOnly", "type": "boolean" },
|
||||
{ "name": "checksums", "type": "String*" },
|
||||
{ "name": "resolutionCacheDir", "type": "java.io.File?" }
|
||||
],
|
||||
"extra": [
|
||||
"def this(",
|
||||
" paths: sbt.internal.librarymanagement.IvyPaths,",
|
||||
" resolvers: Vector[sbt.librarymanagement.Resolver],",
|
||||
" otherResolvers: Vector[sbt.librarymanagement.Resolver],",
|
||||
" moduleConfigurations: Vector[sbt.librarymanagement.ModuleConfiguration],",
|
||||
" localOnly: Boolean,",
|
||||
" lock: Option[xsbti.GlobalLock],",
|
||||
" checksums: Vector[String],",
|
||||
" resolutionCacheDir: Option[java.io.File],",
|
||||
" updateOptions: sbt.librarymanagement.UpdateOptions,",
|
||||
" log: xsbti.Logger",
|
||||
") =",
|
||||
" this(lock, paths.baseDirectory, log, updateOptions, paths, resolvers, otherResolvers,",
|
||||
" moduleConfigurations, localOnly, checksums, resolutionCacheDir)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "ExternalIvyConfiguration",
|
||||
"namespace": "sbt.internal.librarymanagement",
|
||||
"target": "Scala",
|
||||
"type": "record",
|
||||
"fields": [
|
||||
{ "name": "uri", "type": "java.net.URI" },
|
||||
{ "name": "extraResolvers", "type": "sbt.librarymanagement.Resolver*" }
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "IvyPaths",
|
||||
"namespace": "sbt.internal.librarymanagement",
|
||||
"target": "Scala",
|
||||
"type": "record",
|
||||
"fields": [
|
||||
{ "name": "baseDirectory", "type": "java.io.File" },
|
||||
{ "name": "ivyHome", "type": "java.io.File?" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "RetrieveConfiguration",
|
||||
"namespace": "sbt.internal.librarymanagement",
|
||||
"target": "Scala",
|
||||
"type": "record",
|
||||
"fields": [
|
||||
{ "name": "retrieveDirectory", "type": "java.io.File" },
|
||||
{ "name": "outputPattern", "type": "String" },
|
||||
{ "name": "sync", "type": "boolean", "default": "false", "since": "0.0.1" },
|
||||
{ "name": "configurationsToRetrieve", "type": "Set[sbt.librarymanagement.Configuration]?", "default": "None", "since": "0.0.1" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "SbtExclusionRule",
|
||||
"namespace": "sbt.internal.librarymanagement",
|
||||
"target": "Scala",
|
||||
"type": "record",
|
||||
"fields": [
|
||||
{ "name": "organization", "type": "String" },
|
||||
{ "name": "name", "type": "String" },
|
||||
{ "name": "artifact", "type": "String" },
|
||||
{ "name": "configurations", "type": "String*" },
|
||||
{ "name": "crossVersion", "type": "sbt.librarymanagement.CrossVersion" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "UpdateReportLite",
|
||||
"namespace": "sbt.internal.librarymanagement",
|
||||
"target": "Scala",
|
||||
"type": "record",
|
||||
"fields": [
|
||||
{ "name": "configurations", "type": "sbt.internal.librarymanagement.ConfigurationReportLite*" }
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -195,20 +195,20 @@ private[sbt] object ConvertResolver {
|
|||
initializePatterns(resolver, repo.patterns, settings)
|
||||
initializeConnection(resolver, repo.connection)
|
||||
}
|
||||
private def initializeConnection(resolver: AbstractSshBasedResolver, connection: RepositoryHelpers.SshConnection): Unit = {
|
||||
private def initializeConnection(resolver: AbstractSshBasedResolver, connection: SshConnection): Unit = {
|
||||
import resolver._
|
||||
import connection._
|
||||
hostname.foreach(setHost)
|
||||
port.foreach(setPort)
|
||||
authentication foreach
|
||||
{
|
||||
case RepositoryHelpers.PasswordAuthentication(user, password) =>
|
||||
setUser(user)
|
||||
password.foreach(setUserPassword)
|
||||
case RepositoryHelpers.KeyFileAuthentication(user, file, password) =>
|
||||
setKeyFile(file)
|
||||
password.foreach(setKeyFilePassword)
|
||||
setUser(user)
|
||||
case pa: PasswordAuthentication =>
|
||||
setUser(pa.user)
|
||||
pa.password.foreach(setUserPassword)
|
||||
case kfa: KeyFileAuthentication =>
|
||||
setKeyFile(kfa.keyfile)
|
||||
kfa.password.foreach(setKeyFilePassword)
|
||||
setUser(kfa.user)
|
||||
}
|
||||
}
|
||||
private def initializePatterns(resolver: AbstractPatternsBasedResolver, patterns: Patterns, settings: IvySettings): Unit = {
|
||||
|
|
|
|||
|
|
@ -30,8 +30,9 @@ import sbt.util.Logger
|
|||
import sbt.librarymanagement._
|
||||
import Resolver.PluginPattern
|
||||
import ivyint.{ CachedResolutionResolveEngine, CachedResolutionResolveCache, SbtDefaultDependencyDescriptor }
|
||||
import sbt.internal.util.CacheStore
|
||||
|
||||
final class IvySbt(val configuration: IvyConfiguration) {
|
||||
final class IvySbt(val configuration: IvyConfiguration, fileToStore: File => CacheStore) { self =>
|
||||
import configuration.baseDirectory
|
||||
|
||||
/*
|
||||
|
|
@ -92,7 +93,8 @@ final class IvySbt(val configuration: IvyConfiguration) {
|
|||
setEventManager(new EventManager())
|
||||
if (configuration.updateOptions.cachedResolution) {
|
||||
setResolveEngine(new ResolveEngine(getSettings, getEventManager, getSortEngine) with CachedResolutionResolveEngine {
|
||||
val cachedResolutionResolveCache = IvySbt.cachedResolutionResolveCache
|
||||
override private[sbt] val fileToStore: File => CacheStore = self.fileToStore
|
||||
val cachedResolutionResolveCache = IvySbt.cachedResolutionResolveCache(fileToStore)
|
||||
val projectResolver = prOpt
|
||||
def makeInstance = mkIvy
|
||||
})
|
||||
|
|
@ -139,7 +141,7 @@ final class IvySbt(val configuration: IvyConfiguration) {
|
|||
withIvy(log) { i =>
|
||||
val prOpt = Option(i.getSettings.getResolver(ProjectResolver.InterProject)) map { case pr: ProjectResolver => pr }
|
||||
if (configuration.updateOptions.cachedResolution) {
|
||||
IvySbt.cachedResolutionResolveCache.clean(md, prOpt)
|
||||
IvySbt.cachedResolutionResolveCache(fileToStore).clean(md, prOpt)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -236,8 +238,8 @@ private[sbt] object IvySbt {
|
|||
val DefaultIvyConfigFilename = "ivysettings.xml"
|
||||
val DefaultIvyFilename = "ivy.xml"
|
||||
val DefaultMavenFilename = "pom.xml"
|
||||
val DefaultChecksums = Seq("sha1", "md5")
|
||||
private[sbt] val cachedResolutionResolveCache: CachedResolutionResolveCache = new CachedResolutionResolveCache()
|
||||
val DefaultChecksums = Vector("sha1", "md5")
|
||||
private[sbt] def cachedResolutionResolveCache(fileToStore: File => CacheStore): CachedResolutionResolveCache = new CachedResolutionResolveCache(fileToStore)
|
||||
|
||||
def defaultIvyFile(project: File) = new File(project, DefaultIvyFilename)
|
||||
def defaultIvyConfiguration(project: File) = new File(project, DefaultIvyConfigFilename)
|
||||
|
|
@ -305,8 +307,8 @@ private[sbt] object IvySbt {
|
|||
*/
|
||||
def hasImplicitClassifier(artifact: IArtifact): Boolean =
|
||||
{
|
||||
import collection.JavaConversions._
|
||||
artifact.getQualifiedExtraAttributes.keys.exists(_.asInstanceOf[String] startsWith "m:")
|
||||
import scala.collection.JavaConverters._
|
||||
artifact.getQualifiedExtraAttributes.asScala.keys.exists(_.asInstanceOf[String] startsWith "m:")
|
||||
}
|
||||
private def setModuleConfigurations(settings: IvySettings, moduleConfigurations: Seq[ModuleConfiguration], log: Logger): Unit = {
|
||||
val existing = settings.getResolverNames
|
||||
|
|
@ -426,7 +428,7 @@ private[sbt] object IvySbt {
|
|||
{
|
||||
val sub = CrossVersion(scalaFullVersion, scalaBinaryVersion)
|
||||
m match {
|
||||
case ic: InlineConfiguration => ic.copy(module = sub(ic.module), dependencies = ic.dependencies map sub, overrides = ic.overrides map sub)
|
||||
case ic: InlineConfiguration => ic.withModule(sub(ic.module)).withDependencies(ic.dependencies map sub).withOverrides(ic.overrides map sub)
|
||||
case _ => m
|
||||
}
|
||||
}
|
||||
|
|
@ -439,7 +441,7 @@ private[sbt] object IvySbt {
|
|||
}
|
||||
def getExtraAttributes(revID: ExtendableItem): Map[String, String] =
|
||||
{
|
||||
import collection.JavaConverters._
|
||||
import scala.collection.JavaConverters._
|
||||
revID.getExtraAttributes.asInstanceOf[java.util.Map[String, String]].asScala.toMap
|
||||
}
|
||||
private[sbt] def extra(artifact: Artifact, unqualify: Boolean = false): java.util.Map[String, String] =
|
||||
|
|
@ -449,8 +451,9 @@ private[sbt] object IvySbt {
|
|||
}
|
||||
private[sbt] def javaMap(m: Map[String, String], unqualify: Boolean = false) =
|
||||
{
|
||||
import scala.collection.JavaConverters._
|
||||
val map = if (unqualify) m map { case (k, v) => (k.stripPrefix("e:"), v) } else m
|
||||
if (map.isEmpty) null else scala.collection.JavaConversions.mapAsJavaMap(map)
|
||||
if (map.isEmpty) null else map.asJava
|
||||
}
|
||||
|
||||
/** Creates a full ivy file for 'module' using the 'dependencies' XML as the part after the <info>...</info> section. */
|
||||
|
|
@ -514,7 +517,7 @@ private[sbt] object IvySbt {
|
|||
val dds = moduleID.getDependencies
|
||||
val deps = dds flatMap { dd =>
|
||||
val module = toModuleID(dd.getDependencyRevisionId)
|
||||
dd.getModuleConfigurations map (c => module.copy(configurations = Some(c)))
|
||||
dd.getModuleConfigurations map (c => module.withConfigurations(Some(c)))
|
||||
}
|
||||
inconsistentDuplicateWarning(deps)
|
||||
}
|
||||
|
|
@ -571,7 +574,7 @@ private[sbt] object IvySbt {
|
|||
deps.put(id, updated)
|
||||
}
|
||||
|
||||
import collection.JavaConverters._
|
||||
import scala.collection.JavaConverters._
|
||||
deps.values.asScala.toSeq.flatMap { dds =>
|
||||
val mergeable = (dds, dds.tail).zipped.forall(ivyint.MergeDescriptors.mergeable _)
|
||||
if (mergeable) dds.reverse.reduceLeft(ivyint.MergeDescriptors.apply _) :: Nil else dds
|
||||
|
|
@ -652,7 +655,7 @@ private[sbt] object IvySbt {
|
|||
val overridden = overrides.map(id => (key(id), id.revision)).toMap
|
||||
dependencies map { dep =>
|
||||
overridden get key(dep) match {
|
||||
case Some(rev) => dep.copy(revision = rev)
|
||||
case Some(rev) => dep.withRevision(rev)
|
||||
case None => dep
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,36 +21,19 @@ import sbt.util.Logger
|
|||
import sbt.internal.util.{ ShowLines, SourcePosition, LinePosition, RangePosition, LineRange }
|
||||
import sbt.librarymanagement._
|
||||
import sbt.internal.librarymanagement.syntax._
|
||||
import sbt.internal.librarymanagement._
|
||||
|
||||
final class DeliverConfiguration(val deliverIvyPattern: String, val status: String, val configurations: Option[Seq[Configuration]], val logging: UpdateLogging.Value)
|
||||
final class PublishConfiguration(val ivyFile: Option[File], val resolverName: String, val artifacts: Map[Artifact, File], val checksums: Seq[String], val logging: UpdateLogging.Value,
|
||||
final class DeliverConfiguration(val deliverIvyPattern: String, val status: String, val configurations: Option[Vector[Configuration]], val logging: UpdateLogging)
|
||||
final class PublishConfiguration(val ivyFile: Option[File], val resolverName: String, val artifacts: Map[Artifact, File], val checksums: Vector[String], val logging: UpdateLogging,
|
||||
val overwrite: Boolean) {
|
||||
def this(ivyFile: Option[File], resolverName: String, artifacts: Map[Artifact, File], checksums: Seq[String], logging: UpdateLogging.Value) =
|
||||
def this(ivyFile: Option[File], resolverName: String, artifacts: Map[Artifact, File], checksums: Vector[String], logging: UpdateLogging) =
|
||||
this(ivyFile, resolverName, artifacts, checksums, logging, false)
|
||||
}
|
||||
|
||||
final class UpdateConfiguration(val retrieve: Option[RetrieveConfiguration], val missingOk: Boolean, val logging: UpdateLogging.Value, val artifactFilter: ArtifactTypeFilter) {
|
||||
@deprecated("You should use the constructor that provides an artifactFilter", "1.0.x")
|
||||
def this(retrieve: Option[RetrieveConfiguration], missingOk: Boolean, logging: UpdateLogging.Value) {
|
||||
this(retrieve, missingOk, logging, ArtifactTypeFilter.forbid(Set("src", "doc"))) // allow everything but "src", "doc" by default
|
||||
}
|
||||
|
||||
private[sbt] def copy(
|
||||
retrieve: Option[RetrieveConfiguration] = this.retrieve,
|
||||
missingOk: Boolean = this.missingOk,
|
||||
logging: UpdateLogging.Value = this.logging,
|
||||
artifactFilter: ArtifactTypeFilter = this.artifactFilter
|
||||
): UpdateConfiguration =
|
||||
new UpdateConfiguration(retrieve, missingOk, logging, artifactFilter)
|
||||
}
|
||||
final class RetrieveConfiguration(val retrieveDirectory: File, val outputPattern: String, val sync: Boolean, val configurationsToRetrieve: Option[Set[Configuration]]) {
|
||||
def this(retrieveDirectory: File, outputPattern: String) = this(retrieveDirectory, outputPattern, false, None)
|
||||
def this(retrieveDirectory: File, outputPattern: String, sync: Boolean) = this(retrieveDirectory, outputPattern, sync, None)
|
||||
}
|
||||
final case class MakePomConfiguration(file: File, moduleInfo: ModuleInfo, configurations: Option[Seq[Configuration]] = None, extra: NodeSeq = NodeSeq.Empty, process: XNode => XNode = n => n, filterRepositories: MavenRepository => Boolean = _ => true, allRepositories: Boolean, includeTypes: Set[String] = Set(Artifact.DefaultType, Artifact.PomType))
|
||||
final case class MakePomConfiguration(file: File, moduleInfo: ModuleInfo, configurations: Option[Vector[Configuration]] = None, extra: NodeSeq = NodeSeq.Empty, process: XNode => XNode = n => n, filterRepositories: MavenRepository => Boolean = _ => true, allRepositories: Boolean, includeTypes: Set[String] = Set(Artifact.DefaultType, Artifact.PomType))
|
||||
/** @param exclude is a map from ModuleID to classifiers that were previously tried and failed, so should now be excluded */
|
||||
final case class GetClassifiersConfiguration(module: GetClassifiersModule, exclude: Map[ModuleID, Set[String]], configuration: UpdateConfiguration, ivyScala: Option[IvyScala], sourceArtifactTypes: Set[String], docArtifactTypes: Set[String])
|
||||
final case class GetClassifiersModule(id: ModuleID, modules: Seq[ModuleID], configurations: Seq[Configuration], classifiers: Seq[String])
|
||||
final case class GetClassifiersModule(id: ModuleID, modules: Vector[ModuleID], configurations: Vector[Configuration], classifiers: Vector[String])
|
||||
|
||||
final class UnresolvedWarningConfiguration private[sbt] (
|
||||
val modulePositions: Map[ModuleID, SourcePosition]
|
||||
|
|
@ -61,17 +44,6 @@ object UnresolvedWarningConfiguration {
|
|||
new UnresolvedWarningConfiguration(modulePositions)
|
||||
}
|
||||
|
||||
/**
|
||||
* Configures logging during an 'update'. `level` determines the amount of other information logged.
|
||||
* `Full` is the default and logs the most.
|
||||
* `DownloadOnly` only logs what is downloaded.
|
||||
* `Quiet` only displays errors.
|
||||
* `Default` uses the current log level of `update` task.
|
||||
*/
|
||||
object UpdateLogging extends Enumeration {
|
||||
val Full, DownloadOnly, Quiet, Default = Value
|
||||
}
|
||||
|
||||
object IvyActions {
|
||||
/** 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 = {
|
||||
|
|
@ -133,13 +105,13 @@ object IvyActions {
|
|||
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.toSeq
|
||||
val as = mapArtifacts(md, cross, artifacts) ++ ivyArtifact.toList
|
||||
withChecksums(resolver, checksums) { publish(md, as, resolver, overwrite = overwrite) }
|
||||
}
|
||||
}
|
||||
private[this] def withChecksums[T](resolver: DependencyResolver, checksums: Seq[String])(act: => T): T =
|
||||
private[this] def withChecksums[T](resolver: DependencyResolver, checksums: Vector[String])(act: => T): T =
|
||||
resolver match { case br: BasicResolver => withChecksums(br, checksums)(act); case _ => act }
|
||||
private[this] def withChecksums[T](resolver: BasicResolver, checksums: Seq[String])(act: => T): T =
|
||||
private[this] def withChecksums[T](resolver: BasicResolver, checksums: Vector[String])(act: => T): T =
|
||||
{
|
||||
val previous = resolver.getChecksumAlgorithms
|
||||
resolver.setChecksums(checksums mkString ",")
|
||||
|
|
@ -151,9 +123,9 @@ object IvyActions {
|
|||
case i: InlineConfiguration => CrossVersion(i.module, i.ivyScala)
|
||||
case _ => None
|
||||
}
|
||||
def mapArtifacts(module: ModuleDescriptor, cross: Option[String => String], artifacts: Map[Artifact, File]): Seq[(IArtifact, File)] =
|
||||
def mapArtifacts(module: ModuleDescriptor, cross: Option[String => String], artifacts: Map[Artifact, File]): Vector[(IArtifact, File)] =
|
||||
{
|
||||
val rawa = artifacts.keys.toSeq
|
||||
val rawa = artifacts.keys.toVector
|
||||
val seqa = CrossVersion.substituteCross(rawa, cross)
|
||||
val zipped = rawa zip IvySbt.mapArtifacts(module, seqa)
|
||||
zipped map { case (a, ivyA) => (ivyA, artifacts(a)) }
|
||||
|
|
@ -235,8 +207,8 @@ object IvyActions {
|
|||
{
|
||||
import config.{ configuration => c, ivyScala, module => mod }
|
||||
import mod.{ id, modules => deps }
|
||||
val base = restrictedCopy(id, true).copy(name = id.name + "$" + label)
|
||||
val module = new ivySbt.Module(InlineConfiguration(base, ModuleInfo(base.name), deps).copy(ivyScala = ivyScala))
|
||||
val base = restrictedCopy(id, true).withName(id.name + "$" + label)
|
||||
val module = new ivySbt.Module(InlineConfiguration(false, ivyScala, base, ModuleInfo(base.name), deps))
|
||||
val report = updateEither(module, c, uwconfig, logicalClock, depDir, log) match {
|
||||
case Right(r) => r
|
||||
case Left(w) =>
|
||||
|
|
@ -270,10 +242,10 @@ object IvyActions {
|
|||
val baseModules = modules map { m => restrictedCopy(m, true) }
|
||||
// Adding list of explicit artifacts here.
|
||||
val deps = baseModules.distinct flatMap classifiedArtifacts(classifiers, exclude, artifacts)
|
||||
val base = restrictedCopy(id, true).copy(name = id.name + classifiers.mkString("$", "_", ""))
|
||||
val module = new ivySbt.Module(InlineConfiguration(base, ModuleInfo(base.name), deps).copy(ivyScala = ivyScala, configurations = confs))
|
||||
val base = restrictedCopy(id, true).withName(id.name + classifiers.mkString("$", "_", ""))
|
||||
val module = new ivySbt.Module(InlineConfiguration(false, ivyScala, base, ModuleInfo(base.name), deps).withConfigurations(confs))
|
||||
// c.copy ensures c.types is preserved too
|
||||
val upConf = c.copy(missingOk = true)
|
||||
val upConf = c.withMissingOk(true)
|
||||
updateEither(module, upConf, uwconfig, logicalClock, depDir, log) match {
|
||||
case Right(r) =>
|
||||
// The artifacts that came from Ivy don't have their classifier set, let's set it according to
|
||||
|
|
@ -285,7 +257,7 @@ object IvyActions {
|
|||
artFileSeq map {
|
||||
case (art, f) =>
|
||||
// Deduce the classifier from the type if no classifier is present already
|
||||
art.copy(classifier = art.classifier orElse typeClassifierMap.get(art.`type`)) -> f
|
||||
art.withClassifier(art.classifier orElse typeClassifierMap.get(art.`type`)) -> f
|
||||
}
|
||||
}
|
||||
case Left(w) =>
|
||||
|
|
@ -294,7 +266,7 @@ object IvyActions {
|
|||
}
|
||||
// This version adds explicit artifact
|
||||
private[sbt] def classifiedArtifacts(
|
||||
classifiers: Seq[String],
|
||||
classifiers: Vector[String],
|
||||
exclude: Map[ModuleID, Set[String]],
|
||||
artifacts: Vector[(String, ModuleID, Artifact, File)]
|
||||
)(m: ModuleID): Option[ModuleID] = {
|
||||
|
|
@ -308,7 +280,7 @@ object IvyActions {
|
|||
def hardcodedArtifacts = classifiedArtifacts(classifiers, exclude)(m)
|
||||
explicitArtifacts orElse hardcodedArtifacts
|
||||
}
|
||||
private def classifiedArtifacts(classifiers: Seq[String], exclude: Map[ModuleID, Set[String]])(m: ModuleID): Option[ModuleID] =
|
||||
private def classifiedArtifacts(classifiers: Vector[String], exclude: Map[ModuleID, Set[String]])(m: ModuleID): Option[ModuleID] =
|
||||
{
|
||||
val excluded = exclude getOrElse (restrictedCopy(m, false), Set.empty)
|
||||
val included = classifiers filterNot excluded
|
||||
|
|
@ -330,12 +302,12 @@ object IvyActions {
|
|||
* }}}
|
||||
* `usage.getDependencyIncludesSet` returns null if there are no (explicit) include rules.
|
||||
*/
|
||||
private def intransitiveModuleWithExplicitArts(module: ModuleID, arts: Seq[Artifact]): ModuleID =
|
||||
module.copy(isTransitive = false, explicitArtifacts = arts, inclusions = InclExclRule.everything :: Nil)
|
||||
private def intransitiveModuleWithExplicitArts(module: ModuleID, arts: Vector[Artifact]): ModuleID =
|
||||
module.withIsTransitive(false).withExplicitArtifacts(arts).withInclusions(Vector(InclExclRule.everything))
|
||||
|
||||
def addExcluded(report: UpdateReport, classifiers: Seq[String], exclude: Map[ModuleID, Set[String]]): UpdateReport =
|
||||
def addExcluded(report: UpdateReport, classifiers: Vector[String], exclude: Map[ModuleID, Set[String]]): UpdateReport =
|
||||
report.addMissing { id => classifiedArtifacts(id.name, classifiers filter getExcluded(id, exclude)) }
|
||||
def classifiedArtifacts(name: String, classifiers: Seq[String]): Seq[Artifact] =
|
||||
def classifiedArtifacts(name: String, classifiers: Vector[String]): Vector[Artifact] =
|
||||
classifiers map { c => Artifact.classified(name, c) }
|
||||
private[this] def getExcluded(id: ModuleID, exclude: Map[ModuleID, Set[String]]): Set[String] =
|
||||
exclude.getOrElse(restrictedCopy(id, false), Set.empty[String])
|
||||
|
|
@ -344,10 +316,10 @@ object IvyActions {
|
|||
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) }
|
||||
|
||||
private[this] def restrictedCopy(m: ModuleID, confs: Boolean) =
|
||||
ModuleID(m.organization, m.name, m.revision, crossVersion = m.crossVersion, extraAttributes = m.extraAttributes, configurations = if (confs) m.configurations else None)
|
||||
ModuleID(m.organization, m.name, m.revision).withCrossVersion(m.crossVersion).withExtraAttributes(m.extraAttributes).withConfigurations(if (confs) m.configurations else None)
|
||||
.branch(m.branchName)
|
||||
|
||||
private[this] def resolve(logging: UpdateLogging.Value)(ivy: Ivy, module: DefaultModuleDescriptor, defaultConf: String, filter: ArtifactTypeFilter): (ResolveReport, Option[ResolveException]) =
|
||||
private[this] def resolve(logging: UpdateLogging)(ivy: Ivy, module: DefaultModuleDescriptor, defaultConf: String, filter: ArtifactTypeFilter): (ResolveReport, Option[ResolveException]) =
|
||||
{
|
||||
val resolveOptions = new ResolveOptions
|
||||
val resolveId = ResolveOptions.getDefaultResolveId(module)
|
||||
|
|
@ -420,7 +392,7 @@ object IvyActions {
|
|||
|
||||
import UpdateLogging.{ Quiet, Full, DownloadOnly, Default }
|
||||
import LogOptions.{ LOG_QUIET, LOG_DEFAULT, LOG_DOWNLOAD_ONLY }
|
||||
private def ivyLogLevel(level: UpdateLogging.Value) =
|
||||
private def ivyLogLevel(level: UpdateLogging) =
|
||||
level match {
|
||||
case Quiet => LOG_QUIET
|
||||
case DownloadOnly => LOG_DOWNLOAD_ONLY
|
||||
|
|
|
|||
|
|
@ -15,6 +15,14 @@ import sbt.io.Path
|
|||
import sbt.util.Logger
|
||||
import sbt.librarymanagement._
|
||||
|
||||
import sbt.internal.util.{ CacheStore, FileBasedStore }
|
||||
|
||||
import scala.json.ast.unsafe._
|
||||
import scala.collection.mutable
|
||||
import jawn.{ SupportParser, MutableFacade }
|
||||
import sjsonnew.IsoString
|
||||
import sjsonnew.support.scalajson.unsafe.{ CompactPrinter, Converter }
|
||||
|
||||
class NotInCache(val id: ModuleID, cause: Throwable)
|
||||
extends RuntimeException(NotInCache(id, cause), cause) {
|
||||
def this(id: ModuleID) = this(id, null)
|
||||
|
|
@ -27,7 +35,9 @@ private object NotInCache {
|
|||
}
|
||||
}
|
||||
/** Provides methods for working at the level of a single jar file with the default Ivy cache.*/
|
||||
class IvyCache(val ivyHome: Option[File]) {
|
||||
class IvyCache(val ivyHome: Option[File], fileToStore: File => CacheStore) {
|
||||
def this(ivyHome: Option[File]) = this(ivyHome, DefaultFileToStore)
|
||||
|
||||
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.*/
|
||||
def cacheJar(moduleID: ModuleID, file: File, lock: Option[xsbti.GlobalLock], log: Logger): Unit = {
|
||||
|
|
@ -81,8 +91,8 @@ class IvyCache(val ivyHome: Option[File]) {
|
|||
{
|
||||
val local = Resolver.defaultLocal
|
||||
val paths = new IvyPaths(new File("."), ivyHome)
|
||||
val conf = new InlineIvyConfiguration(paths, Seq(local), Nil, Nil, false, lock, IvySbt.DefaultChecksums, None, UpdateOptions(), log)
|
||||
(new IvySbt(conf), local)
|
||||
val conf = new InlineIvyConfiguration(paths, Vector(local), Vector.empty, Vector.empty, false, lock, IvySbt.DefaultChecksums, None, UpdateOptions(), log)
|
||||
(new IvySbt(conf, fileToStore), local)
|
||||
}
|
||||
/** Creates a default jar artifact based on the given ID.*/
|
||||
private def defaultArtifact(moduleID: ModuleID): IvyArtifact =
|
||||
|
|
@ -98,3 +108,31 @@ private class FileDownloader extends ResourceDownloader {
|
|||
sys.error("Could not move temporary file " + part + " to final location " + dest)
|
||||
}
|
||||
}
|
||||
|
||||
object FixedParser extends SupportParser[JValue] {
|
||||
implicit val facade: MutableFacade[JValue] =
|
||||
new MutableFacade[JValue] {
|
||||
def jnull() = JNull
|
||||
def jfalse() = JFalse
|
||||
def jtrue() = JTrue
|
||||
def jnum(s: String) = JNumber(s)
|
||||
def jint(s: String) = JNumber(s)
|
||||
def jstring(s: String) = JString(s)
|
||||
def jarray(vs: mutable.ArrayBuffer[JValue]) = JArray(vs.toArray)
|
||||
def jobject(vs: mutable.Map[String, JValue]) = {
|
||||
val array = new Array[JField](vs.size)
|
||||
var i = 0
|
||||
vs.foreach {
|
||||
case (key, value) =>
|
||||
array(i) = JField(key, value)
|
||||
i += 1
|
||||
}
|
||||
JObject(array)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
object DefaultFileToStore extends (File => CacheStore) {
|
||||
private implicit lazy val isoString: IsoString[JValue] = IsoString.iso(CompactPrinter.apply _, FixedParser.parseUnsafe _)
|
||||
override def apply(f: File): CacheStore = new FileBasedStore(f, Converter)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,206 +3,9 @@
|
|||
*/
|
||||
package sbt.internal.librarymanagement
|
||||
|
||||
import java.io.File
|
||||
import java.net.URI
|
||||
import scala.xml.NodeSeq
|
||||
import sbt.util.Logger
|
||||
import sbt.librarymanagement._
|
||||
|
||||
final class IvyPaths(val baseDirectory: File, val ivyHome: Option[File]) {
|
||||
def withBase(newBaseDirectory: File) = new IvyPaths(newBaseDirectory, ivyHome)
|
||||
override def toString = s"IvyPaths($baseDirectory, $ivyHome)"
|
||||
}
|
||||
sealed trait IvyConfiguration {
|
||||
type This <: IvyConfiguration
|
||||
def lock: Option[xsbti.GlobalLock]
|
||||
def baseDirectory: File
|
||||
def log: Logger
|
||||
def withBase(newBaseDirectory: File): This
|
||||
def updateOptions: UpdateOptions
|
||||
}
|
||||
final class InlineIvyConfiguration(val paths: IvyPaths, val resolvers: Seq[Resolver], val otherResolvers: Seq[Resolver],
|
||||
val moduleConfigurations: Seq[ModuleConfiguration], val localOnly: Boolean, val lock: Option[xsbti.GlobalLock],
|
||||
val checksums: Seq[String], val resolutionCacheDir: Option[File], val updateOptions: UpdateOptions,
|
||||
val log: Logger) extends IvyConfiguration {
|
||||
@deprecated("Use the variant that accepts resolutionCacheDir and updateOptions.", "0.13.0")
|
||||
def this(paths: IvyPaths, resolvers: Seq[Resolver], otherResolvers: Seq[Resolver],
|
||||
moduleConfigurations: Seq[ModuleConfiguration], localOnly: Boolean, lock: Option[xsbti.GlobalLock],
|
||||
checksums: Seq[String], log: Logger) =
|
||||
this(paths, resolvers, otherResolvers, moduleConfigurations, localOnly, lock, checksums, None, UpdateOptions(), log)
|
||||
|
||||
@deprecated("Use the variant that accepts updateOptions.", "0.13.6")
|
||||
def this(paths: IvyPaths, resolvers: Seq[Resolver], otherResolvers: Seq[Resolver],
|
||||
moduleConfigurations: Seq[ModuleConfiguration], localOnly: Boolean, lock: Option[xsbti.GlobalLock],
|
||||
checksums: Seq[String], resolutionCacheDir: Option[File], log: Logger) =
|
||||
this(paths, resolvers, otherResolvers, moduleConfigurations, localOnly, lock, checksums, resolutionCacheDir, UpdateOptions(), log)
|
||||
|
||||
override def toString: String = s"InlineIvyConfiguration($paths, $resolvers, $otherResolvers, " +
|
||||
s"$moduleConfigurations, $localOnly, $checksums, $resolutionCacheDir, $updateOptions)"
|
||||
|
||||
type This = InlineIvyConfiguration
|
||||
def baseDirectory = paths.baseDirectory
|
||||
def withBase(newBase: File) = new InlineIvyConfiguration(paths.withBase(newBase), resolvers, otherResolvers, moduleConfigurations, localOnly, lock, checksums,
|
||||
resolutionCacheDir, updateOptions, log)
|
||||
def changeResolvers(newResolvers: Seq[Resolver]) = new InlineIvyConfiguration(paths, newResolvers, otherResolvers, moduleConfigurations, localOnly, lock, checksums,
|
||||
resolutionCacheDir, updateOptions, log)
|
||||
|
||||
override def equals(o: Any): Boolean = o match {
|
||||
case o: InlineIvyConfiguration =>
|
||||
this.paths == o.paths &&
|
||||
this.resolvers == o.resolvers &&
|
||||
this.otherResolvers == o.otherResolvers &&
|
||||
this.moduleConfigurations == o.moduleConfigurations &&
|
||||
this.localOnly == o.localOnly &&
|
||||
this.checksums == o.checksums &&
|
||||
this.resolutionCacheDir == o.resolutionCacheDir &&
|
||||
this.updateOptions == o.updateOptions
|
||||
case _ => false
|
||||
}
|
||||
|
||||
override def hashCode: Int =
|
||||
{
|
||||
var hash = 1
|
||||
hash = hash * 31 + this.paths.##
|
||||
hash = hash * 31 + this.resolvers.##
|
||||
hash = hash * 31 + this.otherResolvers.##
|
||||
hash = hash * 31 + this.moduleConfigurations.##
|
||||
hash = hash * 31 + this.localOnly.##
|
||||
hash = hash * 31 + this.checksums.##
|
||||
hash = hash * 31 + this.resolutionCacheDir.##
|
||||
hash = hash * 31 + this.updateOptions.##
|
||||
hash
|
||||
}
|
||||
}
|
||||
final class ExternalIvyConfiguration(val baseDirectory: File, val uri: URI, val lock: Option[xsbti.GlobalLock],
|
||||
val extraResolvers: Seq[Resolver], val updateOptions: UpdateOptions, val log: Logger) extends IvyConfiguration {
|
||||
@deprecated("Use the variant that accepts updateOptions.", "0.13.6")
|
||||
def this(baseDirectory: File, uri: URI, lock: Option[xsbti.GlobalLock], extraResolvers: Seq[Resolver], log: Logger) =
|
||||
this(baseDirectory, uri, lock, extraResolvers, UpdateOptions(), log)
|
||||
|
||||
type This = ExternalIvyConfiguration
|
||||
def withBase(newBase: File) = new ExternalIvyConfiguration(newBase, uri, lock, extraResolvers, UpdateOptions(), log)
|
||||
}
|
||||
object ExternalIvyConfiguration {
|
||||
def apply(baseDirectory: File, file: File, lock: Option[xsbti.GlobalLock], log: Logger) = new ExternalIvyConfiguration(baseDirectory, file.toURI, lock, Nil, UpdateOptions(), log)
|
||||
}
|
||||
|
||||
object IvyConfiguration {
|
||||
/**
|
||||
* Called to configure Ivy when inline resolvers are not specified.
|
||||
* This will configure Ivy with an 'ivy-settings.xml' file if there is one or else use default resolvers.
|
||||
*/
|
||||
@deprecated("Explicitly use either external or inline configuration.", "0.12.0")
|
||||
def apply(paths: IvyPaths, lock: Option[xsbti.GlobalLock], localOnly: Boolean, checksums: Seq[String], log: Logger): IvyConfiguration =
|
||||
{
|
||||
log.debug("Autodetecting configuration.")
|
||||
val defaultIvyConfigFile = IvySbt.defaultIvyConfiguration(paths.baseDirectory)
|
||||
if (defaultIvyConfigFile.canRead)
|
||||
ExternalIvyConfiguration(paths.baseDirectory, defaultIvyConfigFile, lock, log)
|
||||
else
|
||||
new InlineIvyConfiguration(paths, Resolver.withDefaultResolvers(Nil), Nil, Nil, localOnly, lock, checksums, None, log)
|
||||
}
|
||||
}
|
||||
|
||||
sealed trait ModuleSettings {
|
||||
def validate: Boolean
|
||||
def ivyScala: Option[IvyScala]
|
||||
def noScala: ModuleSettings
|
||||
}
|
||||
final case class IvyFileConfiguration(file: File, ivyScala: Option[IvyScala], validate: Boolean, autoScalaTools: Boolean = true) extends ModuleSettings {
|
||||
def noScala = copy(ivyScala = None)
|
||||
}
|
||||
final case class PomConfiguration(file: File, ivyScala: Option[IvyScala], validate: Boolean, autoScalaTools: Boolean = true) extends ModuleSettings {
|
||||
def noScala = copy(ivyScala = None)
|
||||
}
|
||||
|
||||
final class InlineConfiguration private[sbt] (
|
||||
val module: ModuleID,
|
||||
val moduleInfo: ModuleInfo,
|
||||
val dependencies: Seq[ModuleID],
|
||||
val overrides: Set[ModuleID],
|
||||
val excludes: Seq[SbtExclusionRule],
|
||||
val ivyXML: NodeSeq,
|
||||
val configurations: Seq[Configuration],
|
||||
val defaultConfiguration: Option[Configuration],
|
||||
val ivyScala: Option[IvyScala],
|
||||
val validate: Boolean,
|
||||
val conflictManager: ConflictManager
|
||||
) extends ModuleSettings {
|
||||
def withConfigurations(configurations: Seq[Configuration]) = copy(configurations = configurations)
|
||||
def noScala = copy(ivyScala = None)
|
||||
def withOverrides(overrides: Set[ModuleID]): ModuleSettings =
|
||||
copy(overrides = overrides)
|
||||
|
||||
private[sbt] def copy(
|
||||
module: ModuleID = this.module,
|
||||
moduleInfo: ModuleInfo = this.moduleInfo,
|
||||
dependencies: Seq[ModuleID] = this.dependencies,
|
||||
overrides: Set[ModuleID] = this.overrides,
|
||||
excludes: Seq[SbtExclusionRule] = this.excludes,
|
||||
ivyXML: NodeSeq = this.ivyXML,
|
||||
configurations: Seq[Configuration] = this.configurations,
|
||||
defaultConfiguration: Option[Configuration] = this.defaultConfiguration,
|
||||
ivyScala: Option[IvyScala] = this.ivyScala,
|
||||
validate: Boolean = this.validate,
|
||||
conflictManager: ConflictManager = this.conflictManager
|
||||
): InlineConfiguration =
|
||||
InlineConfiguration(module, moduleInfo, dependencies, overrides, excludes, ivyXML,
|
||||
configurations, defaultConfiguration, ivyScala, validate, conflictManager)
|
||||
|
||||
override def toString: String =
|
||||
s"InlineConfiguration($module, $moduleInfo, $dependencies, $overrides, $excludes, " +
|
||||
s"$ivyXML, $configurations, $defaultConfiguration, $ivyScala, $validate, $conflictManager)"
|
||||
|
||||
override def equals(o: Any): Boolean = o match {
|
||||
case o: InlineConfiguration =>
|
||||
this.module == o.module &&
|
||||
this.moduleInfo == o.moduleInfo &&
|
||||
this.dependencies == o.dependencies &&
|
||||
this.overrides == o.overrides &&
|
||||
this.excludes == o.excludes &&
|
||||
this.ivyXML == o.ivyXML &&
|
||||
this.configurations == o.configurations &&
|
||||
this.defaultConfiguration == o.defaultConfiguration &&
|
||||
this.ivyScala == o.ivyScala &&
|
||||
this.validate == o.validate &&
|
||||
this.conflictManager == o.conflictManager
|
||||
case _ => false
|
||||
}
|
||||
|
||||
override def hashCode: Int =
|
||||
{
|
||||
var hash = 1
|
||||
hash = hash * 31 + this.module.##
|
||||
hash = hash * 31 + this.dependencies.##
|
||||
hash = hash * 31 + this.overrides.##
|
||||
hash = hash * 31 + this.excludes.##
|
||||
hash = hash * 31 + this.ivyXML.##
|
||||
hash = hash * 31 + this.configurations.##
|
||||
hash = hash * 31 + this.defaultConfiguration.##
|
||||
hash = hash * 31 + this.ivyScala.##
|
||||
hash = hash * 31 + this.validate.##
|
||||
hash = hash * 31 + this.conflictManager.##
|
||||
hash
|
||||
}
|
||||
}
|
||||
object InlineConfiguration {
|
||||
def apply(
|
||||
module: ModuleID,
|
||||
moduleInfo: ModuleInfo,
|
||||
dependencies: Seq[ModuleID],
|
||||
overrides: Set[ModuleID] = Set.empty,
|
||||
excludes: Seq[SbtExclusionRule] = Nil,
|
||||
ivyXML: NodeSeq = NodeSeq.Empty,
|
||||
configurations: Seq[Configuration] = Nil,
|
||||
defaultConfiguration: Option[Configuration] = None,
|
||||
ivyScala: Option[IvyScala] = None,
|
||||
validate: Boolean = false,
|
||||
conflictManager: ConflictManager = ConflictManager.default
|
||||
): InlineConfiguration =
|
||||
new InlineConfiguration(module, moduleInfo, dependencies, overrides, excludes, ivyXML,
|
||||
configurations, defaultConfiguration, ivyScala, validate, conflictManager)
|
||||
|
||||
abstract class InlineConfigurationFunctions {
|
||||
def configurations(explicitConfigurations: Iterable[Configuration], defaultConfiguration: Option[Configuration]) =
|
||||
if (explicitConfigurations.isEmpty) {
|
||||
defaultConfiguration match {
|
||||
|
|
|
|||
|
|
@ -17,10 +17,10 @@ import sbt.librarymanagement._
|
|||
import sbt.internal.librarymanagement.syntax._
|
||||
|
||||
object IvyRetrieve {
|
||||
def reports(report: ResolveReport): Seq[ConfigurationResolveReport] =
|
||||
report.getConfigurations map report.getConfigurationReport
|
||||
def reports(report: ResolveReport): Vector[ConfigurationResolveReport] =
|
||||
report.getConfigurations.toVector map report.getConfigurationReport
|
||||
|
||||
def moduleReports(confReport: ConfigurationResolveReport): Seq[ModuleReport] =
|
||||
def moduleReports(confReport: ConfigurationResolveReport): Vector[ModuleReport] =
|
||||
for {
|
||||
revId <- confReport.getModuleRevisionIds.toArray.toVector collect { case revId: ModuleRevisionId => revId }
|
||||
} yield moduleRevisionDetail(confReport, confReport.getDependency(revId))
|
||||
|
|
@ -32,7 +32,7 @@ object IvyRetrieve {
|
|||
ModuleReport(mid, resolved, missing)
|
||||
}
|
||||
|
||||
private[sbt] def artifacts(mid: ModuleID, artReport: Seq[ArtifactDownloadReport]): (Seq[(Artifact, File)], Seq[Artifact]) =
|
||||
private[sbt] def artifacts(mid: ModuleID, artReport: Seq[ArtifactDownloadReport]): (Vector[(Artifact, File)], Vector[Artifact]) =
|
||||
{
|
||||
val missing = new mutable.ListBuffer[Artifact]
|
||||
val resolved = new mutable.ListBuffer[(Artifact, File)]
|
||||
|
|
@ -44,13 +44,13 @@ object IvyRetrieve {
|
|||
case None => missing += art
|
||||
}
|
||||
}
|
||||
(resolved.toSeq, missing.toSeq)
|
||||
(resolved.toVector, missing.toVector)
|
||||
}
|
||||
|
||||
// We need this because current module report used as part of UpdateReport/ConfigurationReport contains
|
||||
// only the revolved modules.
|
||||
// Sometimes the entire module can be excluded via rules etc.
|
||||
private[sbt] def organizationArtifactReports(confReport: ConfigurationResolveReport): Seq[OrganizationArtifactReport] = {
|
||||
private[sbt] def organizationArtifactReports(confReport: ConfigurationResolveReport): Vector[OrganizationArtifactReport] = {
|
||||
val moduleIds = confReport.getModuleIds.toArray.toVector collect { case mId: IvyModuleId => mId }
|
||||
def organizationArtifact(mid: IvyModuleId): OrganizationArtifactReport = {
|
||||
val deps = confReport.getNodes(mid).toArray.toVector collect { case node: IvyNode => node }
|
||||
|
|
@ -130,14 +130,14 @@ object IvyRetrieve {
|
|||
case _ => dep.getResolvedId.getExtraAttributes
|
||||
})
|
||||
val isDefault = Option(dep.getDescriptor) map { _.isDefault }
|
||||
val configurations = dep.getConfigurations(confReport.getConfiguration).toList
|
||||
val licenses: Seq[(String, Option[String])] = mdOpt match {
|
||||
val configurations = dep.getConfigurations(confReport.getConfiguration).toVector
|
||||
val licenses: Vector[(String, Option[String])] = mdOpt match {
|
||||
case Some(md) => md.getLicenses.toVector collect {
|
||||
case lic: IvyLicense if Option(lic.getName).isDefined =>
|
||||
val temporaryURL = "http://localhost"
|
||||
(lic.getName, nonEmptyString(lic.getUrl) orElse { Some(temporaryURL) })
|
||||
}
|
||||
case _ => Nil
|
||||
case _ => Vector.empty
|
||||
}
|
||||
val callers = dep.getCallers(confReport.getConfiguration).toVector map { toCaller }
|
||||
val (resolved, missing) = artifacts(moduleId, confReport getDownloadReports revId)
|
||||
|
|
@ -151,13 +151,13 @@ object IvyRetrieve {
|
|||
confReport.getEvictedNodes.map(node => toModuleID(node.getId))
|
||||
|
||||
def toModuleID(revID: ModuleRevisionId): ModuleID =
|
||||
ModuleID(revID.getOrganisation, revID.getName, revID.getRevision, extraAttributes = IvySbt.getExtraAttributes(revID))
|
||||
ModuleID(revID.getOrganisation, revID.getName, revID.getRevision).withExtraAttributes(IvySbt.getExtraAttributes(revID))
|
||||
.branch(nonEmptyString(revID.getBranch))
|
||||
|
||||
def toArtifact(art: IvyArtifact): Artifact =
|
||||
{
|
||||
import art._
|
||||
Artifact(getName, getType, getExt, Option(getExtraAttribute("classifier")), getConfigurations map Configurations.config, Option(getUrl))
|
||||
Artifact(getName, getType, getExt, Option(getExtraAttribute("classifier")), getConfigurations.toVector map Configurations.config, Option(getUrl))
|
||||
}
|
||||
|
||||
def updateReport(report: ResolveReport, cachedDescriptor: File): UpdateReport =
|
||||
|
|
|
|||
|
|
@ -3,18 +3,22 @@ package sbt.internal.librarymanagement
|
|||
import java.io.File
|
||||
import org.apache.ivy.core
|
||||
import core.module.descriptor.ModuleDescriptor
|
||||
import sbt.serialization._
|
||||
import sbt.util.Logger
|
||||
import sbt.internal.util.CacheStore
|
||||
import sbt.librarymanagement._
|
||||
import sbt.librarymanagement.LibraryManagementCodec._
|
||||
import JsonUtil._
|
||||
|
||||
private[sbt] object JsonUtil {
|
||||
def sbtOrgTemp = "org.scala-sbt.temp"
|
||||
def fakeCallerOrganization = "org.scala-sbt.temp-callers"
|
||||
}
|
||||
|
||||
private[sbt] class JsonUtil(fileToStore: File => CacheStore) {
|
||||
def parseUpdateReport(md: ModuleDescriptor, path: File, cachedDescriptor: File, log: Logger): UpdateReport =
|
||||
{
|
||||
try {
|
||||
val lite = fromJsonFile[UpdateReportLite](path).get
|
||||
val lite = fileToStore(path).read[UpdateReportLite]
|
||||
fromLite(lite, cachedDescriptor)
|
||||
} catch {
|
||||
case e: Throwable =>
|
||||
|
|
@ -25,7 +29,7 @@ private[sbt] object JsonUtil {
|
|||
def writeUpdateReport(ur: UpdateReport, graphPath: File): Unit =
|
||||
{
|
||||
sbt.io.IO.createDirectory(graphPath.getParentFile)
|
||||
toJsonFile(toLite(ur), graphPath)
|
||||
fileToStore(graphPath).write(toLite(ur))
|
||||
}
|
||||
def toLite(ur: UpdateReport): UpdateReportLite =
|
||||
UpdateReportLite(ur.configurations map { cr =>
|
||||
|
|
@ -44,7 +48,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: Seq[Caller]): Seq[Caller] =
|
||||
def filterOutArtificialCallers(callers: Vector[Caller]): Vector[Caller] =
|
||||
if (callers.isEmpty) callers
|
||||
else {
|
||||
val nonArtificial = callers filter { c =>
|
||||
|
|
@ -53,8 +57,8 @@ private[sbt] object JsonUtil {
|
|||
}
|
||||
val interProj = (callers find { c =>
|
||||
c.caller.organization == sbtOrgTemp
|
||||
}).toList
|
||||
interProj ::: nonArtificial.toList
|
||||
}).toVector
|
||||
interProj ++ nonArtificial
|
||||
}
|
||||
|
||||
def fromLite(lite: UpdateReportLite, cachedDescriptor: File): UpdateReport =
|
||||
|
|
@ -72,13 +76,3 @@ private[sbt] object JsonUtil {
|
|||
new UpdateReport(cachedDescriptor, configReports, stats, Map.empty)
|
||||
}
|
||||
}
|
||||
|
||||
private[sbt] case class UpdateReportLite(configurations: Seq[ConfigurationReportLite])
|
||||
private[sbt] object UpdateReportLite {
|
||||
implicit val pickler: Pickler[UpdateReportLite] with Unpickler[UpdateReportLite] = PicklerUnpickler.generate[UpdateReportLite]
|
||||
}
|
||||
|
||||
private[sbt] case class ConfigurationReportLite(configuration: String, details: Seq[OrganizationArtifactReport])
|
||||
private[sbt] object ConfigurationReportLite {
|
||||
implicit val pickler: Pickler[ConfigurationReportLite] with Unpickler[ConfigurationReportLite] = PicklerUnpickler.generate[ConfigurationReportLite]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -35,18 +35,16 @@ final class RichUpdateReport(report: UpdateReport) {
|
|||
/** Constructs a new report that only contains files matching the specified filter.*/
|
||||
private[sbt] def filter(f: DependencyFilter): UpdateReport =
|
||||
moduleReportMap { (configuration, modReport) =>
|
||||
modReport.copy(
|
||||
artifacts = modReport.artifacts filter { case (art, file) => f(configuration, modReport.module, art) },
|
||||
missingArtifacts = modReport.missingArtifacts filter { art => f(configuration, modReport.module, art) }
|
||||
)
|
||||
modReport
|
||||
.withArtifacts(modReport.artifacts filter { case (art, file) => f(configuration, modReport.module, art) })
|
||||
.withMissingArtifacts(modReport.missingArtifacts filter { art => f(configuration, modReport.module, art) })
|
||||
}
|
||||
def substitute(f: (String, ModuleID, Seq[(Artifact, File)]) => Seq[(Artifact, File)]): UpdateReport =
|
||||
def substitute(f: (String, ModuleID, Vector[(Artifact, File)]) => Vector[(Artifact, File)]): UpdateReport =
|
||||
moduleReportMap { (configuration, modReport) =>
|
||||
val newArtifacts = f(configuration, modReport.module, modReport.artifacts)
|
||||
modReport.copy(
|
||||
artifacts = newArtifacts,
|
||||
missingArtifacts = modReport.missingArtifacts
|
||||
)
|
||||
modReport
|
||||
.withArtifacts(newArtifacts)
|
||||
.withMissingArtifacts(modReport.missingArtifacts)
|
||||
}
|
||||
|
||||
def toSeq: Seq[(String, ModuleID, Artifact, File)] =
|
||||
|
|
@ -57,9 +55,8 @@ final class RichUpdateReport(report: UpdateReport) {
|
|||
|
||||
def addMissing(f: ModuleID => Seq[Artifact]): UpdateReport =
|
||||
moduleReportMap { (configuration, modReport) =>
|
||||
modReport.copy(
|
||||
missingArtifacts = (modReport.missingArtifacts ++ f(modReport.module)).distinct
|
||||
)
|
||||
modReport
|
||||
.withMissingArtifacts((modReport.missingArtifacts ++ f(modReport.module)).distinct)
|
||||
}
|
||||
|
||||
def moduleReportMap(f: (String, ModuleReport) => ModuleReport): UpdateReport =
|
||||
|
|
|
|||
|
|
@ -1,52 +0,0 @@
|
|||
package sbt.internal.librarymanagement
|
||||
|
||||
import impl.{ GroupID, GroupArtifactID }
|
||||
import sbt.librarymanagement._
|
||||
|
||||
final class SbtExclusionRule(
|
||||
val organization: String,
|
||||
val name: String,
|
||||
val artifact: String,
|
||||
val configurations: Seq[String],
|
||||
val crossVersion: CrossVersion
|
||||
) {
|
||||
|
||||
def copy(
|
||||
organization: String = this.organization,
|
||||
name: String = this.name,
|
||||
artifact: String = this.artifact,
|
||||
configurations: Seq[String] = this.configurations,
|
||||
crossVersion: CrossVersion = this.crossVersion
|
||||
): SbtExclusionRule =
|
||||
SbtExclusionRule(
|
||||
organization = organization,
|
||||
name = name,
|
||||
artifact = artifact,
|
||||
configurations = configurations,
|
||||
crossVersion = crossVersion
|
||||
)
|
||||
}
|
||||
|
||||
object SbtExclusionRule {
|
||||
def apply(organization: String): SbtExclusionRule =
|
||||
new SbtExclusionRule(organization, "*", "*", Nil, CrossVersion.Disabled)
|
||||
|
||||
def apply(organization: String, name: String): SbtExclusionRule =
|
||||
new SbtExclusionRule(organization, name, "*", Nil, CrossVersion.Disabled)
|
||||
|
||||
def apply(
|
||||
organization: String,
|
||||
name: String,
|
||||
artifact: String,
|
||||
configurations: Seq[String],
|
||||
crossVersion: CrossVersion
|
||||
): SbtExclusionRule =
|
||||
new SbtExclusionRule(organization, name, artifact, configurations, crossVersion)
|
||||
|
||||
implicit def groupIdToExclusionRule(organization: GroupID): SbtExclusionRule =
|
||||
SbtExclusionRule(organization.groupID)
|
||||
implicit def stringToExclusionRule(organization: String): SbtExclusionRule =
|
||||
SbtExclusionRule(organization)
|
||||
implicit def groupArtifactIDToExcludsionRule(gaid: GroupArtifactID): SbtExclusionRule =
|
||||
SbtExclusionRule(gaid.groupID, gaid.artifactID, "*", Nil, gaid.crossVersion)
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
package sbt.internal.librarymanagement.formats
|
||||
|
||||
import sjsonnew._
|
||||
import java.util._
|
||||
import java.text._
|
||||
|
||||
trait DateFormat { self: BasicJsonProtocol =>
|
||||
private val format = new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy")
|
||||
|
||||
implicit lazy val DateFormat: JsonFormat[Date] = project(_.toString, format.parse _)
|
||||
}
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
package sbt.internal.librarymanagement.formats
|
||||
|
||||
import sjsonnew._
|
||||
import org.apache.ivy.plugins.resolver.DependencyResolver
|
||||
|
||||
trait DependencyResolverFormat { self: BasicJsonProtocol =>
|
||||
implicit lazy val DependencyResolverFormat: JsonFormat[DependencyResolver] = ???
|
||||
}
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
package sbt.internal.librarymanagement.formats
|
||||
|
||||
import sjsonnew._
|
||||
import xsbti._
|
||||
|
||||
trait GlobalLockFormat { self: BasicJsonProtocol =>
|
||||
implicit lazy val GlobalLockFormat: JsonFormat[GlobalLock] = ???
|
||||
}
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
package sbt.internal.librarymanagement.formats
|
||||
|
||||
import sjsonnew._
|
||||
import xsbti._
|
||||
|
||||
trait LoggerFormat { self: BasicJsonProtocol =>
|
||||
implicit lazy val LoggerFormat: JsonFormat[Logger] = ???
|
||||
}
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
package sbt.internal.librarymanagement.formats
|
||||
|
||||
import sjsonnew._
|
||||
import scala.xml._
|
||||
|
||||
trait NodeSeqFormat { self: BasicJsonProtocol =>
|
||||
implicit lazy val NodeSeqFormat: JsonFormat[NodeSeq] = ???
|
||||
}
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
package sbt.internal.librarymanagement
|
||||
package formats
|
||||
|
||||
import sjsonnew._
|
||||
import sbt.librarymanagement._
|
||||
|
||||
trait UpdateOptionsFormat { self: BasicJsonProtocol =>
|
||||
|
||||
implicit lazy val UpdateOptionsFormat: JsonFormat[UpdateOptions] =
|
||||
project(
|
||||
(uo: UpdateOptions) => (
|
||||
uo.circularDependencyLevel.name,
|
||||
uo.interProjectFirst,
|
||||
uo.latestSnapshots,
|
||||
uo.consolidatedResolution,
|
||||
uo.cachedResolution
|
||||
),
|
||||
(xs: (String, Boolean, Boolean, Boolean, Boolean)) =>
|
||||
new UpdateOptions(levels(xs._1), xs._2, xs._3, xs._4, xs._5, ConvertResolver.defaultConvert)
|
||||
)
|
||||
|
||||
private val levels: Map[String, CircularDependencyLevel] = Map(
|
||||
"warn" -> CircularDependencyLevel.Warn,
|
||||
"ignore" -> CircularDependencyLevel.Ignore,
|
||||
"error" -> CircularDependencyLevel.Error
|
||||
)
|
||||
}
|
||||
|
|
@ -26,7 +26,7 @@ trait DependencyBuilders {
|
|||
}
|
||||
|
||||
final class GroupID private[sbt] (private[sbt] val groupID: String) {
|
||||
def %(artifactID: String) = groupArtifact(artifactID, CrossVersion.Disabled)
|
||||
def %(artifactID: String) = groupArtifact(artifactID, Disabled())
|
||||
def %%(artifactID: String): GroupArtifactID = groupArtifact(artifactID, CrossVersion.binary)
|
||||
|
||||
private def groupArtifact(artifactID: String, cross: CrossVersion) =
|
||||
|
|
@ -53,7 +53,7 @@ final class ModuleIDConfigurable private[sbt] (moduleID: ModuleID) {
|
|||
{
|
||||
nonEmpty(configurations, "Configurations")
|
||||
val c = configurations
|
||||
moduleID.copy(configurations = Some(c))
|
||||
moduleID.withConfigurations(configurations = Some(c))
|
||||
}
|
||||
}
|
||||
final class RepositoryName private[sbt] (name: String) {
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ import sbt.io.{ DirectoryFilter, Hash, IO }
|
|||
import sbt.util.Logger
|
||||
import sbt.librarymanagement._
|
||||
import sbt.internal.librarymanagement.syntax._
|
||||
import sbt.internal.util.CacheStore
|
||||
|
||||
private[sbt] object CachedResolutionResolveCache {
|
||||
def createID(organization: String, name: String, revision: String) =
|
||||
|
|
@ -38,8 +39,9 @@ private[sbt] object CachedResolutionResolveCache {
|
|||
lazy val yyyymmdd: SimpleDateFormat = new SimpleDateFormat("yyyy-MM-dd")
|
||||
}
|
||||
|
||||
private[sbt] class CachedResolutionResolveCache() {
|
||||
private[sbt] class CachedResolutionResolveCache(fileToStore: File => CacheStore) {
|
||||
import CachedResolutionResolveCache._
|
||||
val jsonUtil = new JsonUtil(fileToStore)
|
||||
val updateReportCache: concurrent.Map[ModuleRevisionId, Either[ResolveException, UpdateReport]] = concurrent.TrieMap()
|
||||
// Used for subproject
|
||||
val projectReportCache: concurrent.Map[(ModuleRevisionId, LogicalClock), Either[ResolveException, UpdateReport]] = concurrent.TrieMap()
|
||||
|
|
@ -164,7 +166,7 @@ private[sbt] class CachedResolutionResolveCache() {
|
|||
else None) match {
|
||||
case Some(path) =>
|
||||
log.debug(s"parsing ${path.getAbsolutePath.toString}")
|
||||
val ur = JsonUtil.parseUpdateReport(md, path, cachedDescriptor, log)
|
||||
val ur = jsonUtil.parseUpdateReport(md, path, cachedDescriptor, log)
|
||||
if (ur.allFiles forall { _.exists }) {
|
||||
updateReportCache(md.getModuleRevisionId) = Right(ur)
|
||||
Some(Right(ur))
|
||||
|
|
@ -198,7 +200,7 @@ private[sbt] class CachedResolutionResolveCache() {
|
|||
if (changing) {
|
||||
cleanDynamicGraph()
|
||||
}
|
||||
JsonUtil.writeUpdateReport(ur, gp)
|
||||
jsonUtil.writeUpdateReport(ur, gp)
|
||||
// limit the update cache size
|
||||
if (updateReportCache.size > maxUpdateReportCacheSize) {
|
||||
updateReportCache.remove(updateReportCache.head._1)
|
||||
|
|
@ -221,7 +223,7 @@ private[sbt] class CachedResolutionResolveCache() {
|
|||
{
|
||||
def reconstructReports(surviving: Vector[ModuleID], evicted: Vector[ModuleID], mgr: String): (Vector[ModuleReport], Vector[ModuleReport]) = {
|
||||
val moduleIdMap = Map(conflicts map { x => x.module -> x }: _*)
|
||||
(surviving map moduleIdMap, evicted map moduleIdMap map { _.copy(evicted = true, evictedReason = 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)
|
||||
|
|
@ -257,6 +259,9 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine {
|
|||
private[sbt] def makeInstance: Ivy
|
||||
private[sbt] val ignoreTransitiveForce: Boolean = true
|
||||
|
||||
private[sbt] val fileToStore: File => CacheStore
|
||||
private val jsonUtil = new JsonUtil(fileToStore)
|
||||
|
||||
def withIvy[A](log: Logger)(f: Ivy => A): A =
|
||||
withIvy(new IvyLoggerInterface(log))(f)
|
||||
def withIvy[A](log: MessageLogger)(f: Ivy => A): A =
|
||||
|
|
@ -428,7 +433,7 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine {
|
|||
if (mr.evicted || mr.problem.nonEmpty) None
|
||||
else
|
||||
// https://github.com/sbt/sbt/issues/1763
|
||||
Some(mr.copy(callers = JsonUtil.filterOutArtificialCallers(mr.callers)))
|
||||
Some(mr.withCallers(jsonUtil.filterOutArtificialCallers(mr.callers)))
|
||||
} match {
|
||||
case Vector() => None
|
||||
case ms => Some(OrganizationArtifactReport(report0.organization, report0.name, ms))
|
||||
|
|
@ -504,7 +509,7 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine {
|
|||
if (callers.size == callers0.size) mr
|
||||
else {
|
||||
log.debug(s":: $rootModuleConf: removing caller $moduleWithMostCallers -> $next for sorting")
|
||||
mr.copy(callers = callers)
|
||||
mr.withCallers(callers)
|
||||
}
|
||||
}
|
||||
OrganizationArtifactReport(oar.organization, oar.name, mrs)
|
||||
|
|
@ -591,18 +596,18 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine {
|
|||
* Merges ModuleReports, which represents orgnization, name, and version.
|
||||
* Returns a touple of (surviving modules ++ non-conflicting modules, newly evicted modules).
|
||||
*/
|
||||
def mergeModuleReports(rootModuleConf: String, modules: Seq[ModuleReport], os: Vector[IvyOverride], log: Logger): (Vector[ModuleReport], Vector[ModuleReport]) =
|
||||
def mergeModuleReports(rootModuleConf: String, modules: Vector[ModuleReport], os: Vector[IvyOverride], log: Logger): (Vector[ModuleReport], Vector[ModuleReport]) =
|
||||
{
|
||||
if (modules.nonEmpty) {
|
||||
log.debug(s":: merging module reports for $rootModuleConf: ${modules.head.module.organization}:${modules.head.module.name}")
|
||||
}
|
||||
def mergeModuleReports(org: String, name: String, version: String, xs: Seq[ModuleReport]): ModuleReport = {
|
||||
def mergeModuleReports(org: String, name: String, version: String, xs: Vector[ModuleReport]): ModuleReport = {
|
||||
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 }).toList map { case (k, xs) => xs.head }
|
||||
val distinctByModuleId = allCallers.groupBy({ _.caller }).toVector map { case (k, xs) => xs.head }
|
||||
val allArtifacts = (xs flatMap { _.artifacts }).distinct
|
||||
xs.head.copy(artifacts = allArtifacts, evicted = completelyEvicted, callers = distinctByModuleId)
|
||||
xs.head.withArtifacts(allArtifacts).withEvicted(completelyEvicted).withCallers(distinctByModuleId)
|
||||
}
|
||||
val merged = (modules groupBy { m => (m.module.organization, m.module.name, m.module.revision) }).toSeq.toVector flatMap {
|
||||
case ((org, name, version), xs) =>
|
||||
|
|
@ -637,7 +642,7 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine {
|
|||
}
|
||||
x
|
||||
}
|
||||
val newlyEvicted = affected map { _.copy(evicted = true, evictedReason = Some("transitive-evict")) }
|
||||
val newlyEvicted = affected map { _.withEvicted(true).withEvictedReason(Some("transitive-evict")) }
|
||||
if (affected.isEmpty) oar
|
||||
else new OrganizationArtifactReport(organization, name, unaffected ++ newlyEvicted)
|
||||
}
|
||||
|
|
@ -669,7 +674,7 @@ 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 { _.copy(evicted = true, evictedReason = 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 }
|
||||
|
|
@ -677,13 +682,13 @@ 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 { _.copy(evicted = true, evictedReason = 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(_) }
|
||||
Option(strategy.findLatest(infos.toArray, None.orNull)) match {
|
||||
case Some(ModuleReportArtifactInfo(m)) =>
|
||||
(Vector(m), conflicts filterNot { _ == m } map { _.copy(evicted = true, evictedReason = Some(lcm.toString)) }, lcm.toString)
|
||||
(Vector(m), conflicts filterNot { _ == m } map { _.withEvicted(true).withEvictedReason(Some(lcm.toString)) }, lcm.toString)
|
||||
case _ => (conflicts, Vector(), lcm.toString)
|
||||
}
|
||||
}
|
||||
|
|
@ -696,7 +701,7 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine {
|
|||
mr.module.revision == ovrVersion
|
||||
} match {
|
||||
case Some(m) =>
|
||||
(Vector(m), conflicts filterNot { _ == m } map { _.copy(evicted = true, evictedReason = 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 { _.module }).mkString("(", ", ", ")"))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,22 +5,39 @@ package sbt.librarymanagement
|
|||
|
||||
import java.io.File
|
||||
import java.net.URL
|
||||
import sbt.serialization._
|
||||
|
||||
final case class Artifact(name: String, `type`: String, extension: String, classifier: Option[String], configurations: Iterable[Configuration], url: Option[URL], extraAttributes: Map[String, String]) {
|
||||
abstract class ArtifactExtra {
|
||||
def name: String
|
||||
def `type`: String
|
||||
def extension: String
|
||||
def classifier: Option[String]
|
||||
def configurations: Vector[Configuration]
|
||||
def url: Option[URL]
|
||||
def extraAttributes: Map[String, String]
|
||||
|
||||
protected[this] def copy(
|
||||
name: String = name,
|
||||
`type`: String = `type`,
|
||||
extension: String = extension,
|
||||
classifier: Option[String] = classifier,
|
||||
configurations: Vector[Configuration] = configurations,
|
||||
url: Option[URL] = url,
|
||||
extraAttributes: Map[String, String] = extraAttributes
|
||||
): Artifact
|
||||
|
||||
def extra(attributes: (String, String)*) = copy(extraAttributes = extraAttributes ++ ModuleID.checkE(attributes))
|
||||
}
|
||||
|
||||
import Configurations.{ Optional, Pom, Test }
|
||||
|
||||
object Artifact {
|
||||
def apply(name: String): Artifact = Artifact(name, DefaultType, DefaultExtension, None, Nil, None)
|
||||
def apply(name: String, extra: Map[String, String]): Artifact = Artifact(name, DefaultType, DefaultExtension, None, Nil, None, extra)
|
||||
def apply(name: String, classifier: String): Artifact = Artifact(name, DefaultType, DefaultExtension, Some(classifier), Nil, None)
|
||||
def apply(name: String, `type`: String, extension: String): Artifact = Artifact(name, `type`, extension, None, Nil, None)
|
||||
def apply(name: String, `type`: String, extension: String, classifier: String): Artifact = Artifact(name, `type`, extension, Some(classifier), Nil, None)
|
||||
def apply(name: String, url: URL): Artifact = Artifact(name, extract(url, DefaultType), extract(url, DefaultExtension), None, Nil, Some(url))
|
||||
def apply(name: String, `type`: String, extension: String, classifier: Option[String], configurations: Iterable[Configuration], url: Option[URL]): Artifact =
|
||||
abstract class ArtifactFunctions {
|
||||
def apply(name: String, extra: Map[String, String]): Artifact = Artifact(name, DefaultType, DefaultExtension, None, Vector.empty, None, extra)
|
||||
def apply(name: String, classifier: String): Artifact = Artifact(name, DefaultType, DefaultExtension, Some(classifier), Vector.empty, None)
|
||||
def apply(name: String, `type`: String, extension: String): Artifact = Artifact(name, `type`, extension, None, Vector.empty, None)
|
||||
def apply(name: String, `type`: String, extension: String, classifier: String): Artifact = Artifact(name, `type`, extension, Some(classifier), Vector.empty, None)
|
||||
def apply(name: String, url: URL): Artifact = Artifact(name, extract(url, DefaultType), extract(url, DefaultExtension), None, Vector.empty, Some(url))
|
||||
|
||||
def apply(name: String, `type`: String, extension: String, classifier: Option[String], configurations: Vector[Configuration], url: Option[URL]): Artifact =
|
||||
Artifact(name, `type`, extension, classifier, configurations, url, Map.empty)
|
||||
|
||||
val DefaultExtension = "jar"
|
||||
|
|
@ -28,7 +45,7 @@ object Artifact {
|
|||
|
||||
def sources(name: String) = classified(name, SourceClassifier)
|
||||
def javadoc(name: String) = classified(name, DocClassifier)
|
||||
def pom(name: String) = Artifact(name, PomType, PomType, None, Pom :: Nil, None)
|
||||
def pom(name: String) = Artifact(name, PomType, PomType, None, Vector(Pom), None)
|
||||
|
||||
// Possible ivy artifact types such that sbt will treat those artifacts at sources / docs
|
||||
val DefaultSourceTypes = Set("src", "source", "sources")
|
||||
|
|
@ -62,7 +79,7 @@ object Artifact {
|
|||
val name = file.getName
|
||||
val i = name.lastIndexOf('.')
|
||||
val base = if (i >= 0) name.substring(0, i) else name
|
||||
Artifact(base, extract(name, DefaultType), extract(name, DefaultExtension), None, Nil, Some(file.toURI.toURL))
|
||||
Artifact(base, extract(name, DefaultType), extract(name, DefaultExtension), None, Vector.empty, Some(file.toURI.toURL))
|
||||
}
|
||||
def artifactName(scalaVersion: ScalaVersion, module: ModuleID, artifact: Artifact): String =
|
||||
{
|
||||
|
|
@ -88,75 +105,5 @@ object Artifact {
|
|||
* The artifact is created under the default configuration.
|
||||
*/
|
||||
def classified(name: String, classifier: String): Artifact =
|
||||
Artifact(name, classifierType(classifier), DefaultExtension, Some(classifier), Nil, None)
|
||||
|
||||
private val optStringPickler = implicitly[Pickler[Option[String]]]
|
||||
private val optStringUnpickler = implicitly[Unpickler[Option[String]]]
|
||||
private val vectorConfigurationPickler = implicitly[Pickler[Vector[Configuration]]]
|
||||
private val vectorConfigurationUnpickler = implicitly[Unpickler[Vector[Configuration]]]
|
||||
private val stringStringMapPickler = implicitly[Pickler[Map[String, String]]]
|
||||
private val stringStringMapUnpickler = implicitly[Unpickler[Map[String, String]]]
|
||||
|
||||
implicit val pickler: Pickler[Artifact] = new Pickler[Artifact] {
|
||||
val tag = implicitly[FastTypeTag[Artifact]]
|
||||
val stringTag = implicitly[FastTypeTag[String]]
|
||||
val optionStringTag = implicitly[FastTypeTag[Option[String]]]
|
||||
val vectorConfigurationTag = implicitly[FastTypeTag[Vector[Configuration]]]
|
||||
val stringStringMapTag = implicitly[FastTypeTag[Map[String, String]]]
|
||||
def pickle(a: Artifact, builder: PBuilder): Unit = {
|
||||
builder.pushHints()
|
||||
builder.hintTag(tag)
|
||||
builder.beginEntry(a)
|
||||
builder.putField("name", { b =>
|
||||
b.hintTag(stringTag)
|
||||
stringPickler.pickle(a.name, b)
|
||||
})
|
||||
builder.putField("type", { b =>
|
||||
b.hintTag(stringTag)
|
||||
stringPickler.pickle(a.`type`, b)
|
||||
})
|
||||
builder.putField("extension", { b =>
|
||||
b.hintTag(stringTag)
|
||||
stringPickler.pickle(a.extension, b)
|
||||
})
|
||||
builder.putField("classifier", { b =>
|
||||
b.hintTag(optionStringTag)
|
||||
optStringPickler.pickle(a.classifier, b)
|
||||
})
|
||||
builder.putField("configurations", { b =>
|
||||
b.hintTag(vectorConfigurationTag)
|
||||
vectorConfigurationPickler.pickle(a.configurations.toVector, b)
|
||||
})
|
||||
builder.putField("url", { b =>
|
||||
b.hintTag(optionStringTag)
|
||||
optStringPickler.pickle(a.url map { _.toString }, b)
|
||||
})
|
||||
builder.putField("extraAttributes", { b =>
|
||||
b.hintTag(stringStringMapTag)
|
||||
stringStringMapPickler.pickle(a.extraAttributes, b)
|
||||
})
|
||||
builder.endEntry()
|
||||
builder.popHints()
|
||||
()
|
||||
}
|
||||
}
|
||||
implicit val unpickler: Unpickler[Artifact] = new Unpickler[Artifact] {
|
||||
val tag = implicitly[FastTypeTag[Artifact]]
|
||||
def unpickle(tpe: String, reader: PReader): Any = {
|
||||
reader.pushHints()
|
||||
// reader.hintTag(tag)
|
||||
reader.beginEntry()
|
||||
val name = stringPickler.unpickleEntry(reader.readField("name")).asInstanceOf[String]
|
||||
val tp = stringPickler.unpickleEntry(reader.readField("type")).asInstanceOf[String]
|
||||
val extension = stringPickler.unpickleEntry(reader.readField("extension")).asInstanceOf[String]
|
||||
val classifier = optStringUnpickler.unpickleEntry(reader.readField("classifier")).asInstanceOf[Option[String]]
|
||||
val configurations = vectorConfigurationUnpickler.unpickleEntry(reader.readField("configurations")).asInstanceOf[Vector[Configuration]]
|
||||
val u = optStringUnpickler.unpickleEntry(reader.readField("url")).asInstanceOf[Option[String]] map { new URL(_) }
|
||||
val extraAttributes = stringStringMapUnpickler.unpickleEntry(reader.readField("extraAttributes")).asInstanceOf[Map[String, String]]
|
||||
val result = Artifact(name, tp, extension, classifier, configurations, u, extraAttributes)
|
||||
reader.endEntry()
|
||||
reader.popHints()
|
||||
result
|
||||
}
|
||||
}
|
||||
Artifact(name, classifierType(classifier), DefaultExtension, Some(classifier), Vector.empty, None)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,8 +3,6 @@
|
|||
*/
|
||||
package sbt.librarymanagement
|
||||
|
||||
import sbt.serialization._
|
||||
|
||||
object Configurations {
|
||||
def config(name: String) = new Configuration(name)
|
||||
def default: Seq[Configuration] = defaultMavenConfigurations
|
||||
|
|
@ -50,18 +48,20 @@ object Configurations {
|
|||
private[sbt] def defaultConfiguration(mavenStyle: Boolean) = if (mavenStyle) Configurations.Compile else Configurations.Default
|
||||
private[sbt] def removeDuplicates(configs: Iterable[Configuration]) = Set(scala.collection.mutable.Map(configs.map(config => (config.name, config)).toSeq: _*).values.toList: _*)
|
||||
}
|
||||
/** Represents an Ivy configuration. */
|
||||
final case class Configuration(name: String, description: String, isPublic: Boolean, extendsConfigs: List[Configuration], transitive: Boolean) {
|
||||
|
||||
abstract class ConfigurationExtra {
|
||||
def name: String
|
||||
def description: String
|
||||
def isPublic: Boolean
|
||||
def extendsConfigs: Vector[Configuration]
|
||||
def transitive: Boolean
|
||||
|
||||
require(name != null && !name.isEmpty)
|
||||
require(description != null)
|
||||
def this(name: String) = this(name, "", true, Nil, true)
|
||||
|
||||
def describedAs(newDescription: String) = Configuration(name, newDescription, isPublic, extendsConfigs, transitive)
|
||||
def extend(configs: Configuration*) = Configuration(name, description, isPublic, configs.toList ::: extendsConfigs, transitive)
|
||||
def extend(configs: Configuration*) = Configuration(name, description, isPublic, configs.toVector ++ extendsConfigs, transitive)
|
||||
def notTransitive = intransitive
|
||||
def intransitive = Configuration(name, description, isPublic, extendsConfigs, false)
|
||||
def hide = Configuration(name, description, false, extendsConfigs, transitive)
|
||||
override def toString = name
|
||||
}
|
||||
object Configuration {
|
||||
implicit val pickler: Pickler[Configuration] with Unpickler[Configuration] = PicklerUnpickler.generate[Configuration]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,109 +1,22 @@
|
|||
package sbt.librarymanagement
|
||||
|
||||
import sbt.serialization._
|
||||
import sbt.internal.librarymanagement.SbtExclusionRule
|
||||
import sbt.internal.librarymanagement.cross.CrossVersionUtil
|
||||
|
||||
final case class ScalaVersion(full: String, binary: String)
|
||||
|
||||
/** Configures how a module will be cross-versioned. */
|
||||
sealed trait CrossVersion
|
||||
|
||||
object CrossVersion {
|
||||
abstract class CrossVersionFunctions {
|
||||
/** The first `major.minor` Scala version that the Scala binary version should be used for cross-versioning instead of the full version. */
|
||||
val TransitionScalaVersion = CrossVersionUtil.TransitionScalaVersion
|
||||
|
||||
/** The first `major.minor` sbt version that the sbt binary version should be used for cross-versioning instead of the full version. */
|
||||
val TransitionSbtVersion = CrossVersionUtil.TransitionSbtVersion
|
||||
|
||||
/** Disables cross versioning for a module.*/
|
||||
object Disabled extends CrossVersion { override def toString = "disabled" }
|
||||
|
||||
/**
|
||||
* Cross-versions a module using the result of applying `remapVersion` to the binary version.
|
||||
* For example, if `remapVersion = v => "2.10"` and the binary version is "2.9.2" or "2.10",
|
||||
* the module is cross-versioned with "2.10".
|
||||
*/
|
||||
final class Binary(val remapVersion: String => String) extends CrossVersion {
|
||||
override def toString = "Binary"
|
||||
override def hashCode = remapVersion.##
|
||||
override def equals(that: Any) = that match {
|
||||
case that: Binary => this.remapVersion == that.remapVersion
|
||||
case _ => false
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Cross-versions a module with the result of applying `remapVersion` to the full version.
|
||||
* For example, if `remapVersion = v => "2.10"` and the full version is "2.9.2" or "2.10.3",
|
||||
* the module is cross-versioned with "2.10".
|
||||
*/
|
||||
final class Full(val remapVersion: String => String) extends CrossVersion {
|
||||
override def toString = "Full"
|
||||
override def hashCode = remapVersion.##
|
||||
override def equals(that: Any) = that match {
|
||||
case that: Full => this.remapVersion == that.remapVersion
|
||||
case _ => false
|
||||
}
|
||||
}
|
||||
|
||||
private val disabledTag = implicitly[FastTypeTag[Disabled.type]]
|
||||
private val binaryTag = implicitly[FastTypeTag[Binary]]
|
||||
private val fullTag = implicitly[FastTypeTag[Full]]
|
||||
implicit val pickler: Pickler[CrossVersion] = new Pickler[CrossVersion] {
|
||||
val tag = implicitly[FastTypeTag[CrossVersion]]
|
||||
def pickle(a: CrossVersion, builder: PBuilder): Unit = {
|
||||
builder.pushHints()
|
||||
builder.hintTag(a match {
|
||||
case Disabled => disabledTag
|
||||
case x: Binary => binaryTag
|
||||
case x: Full => fullTag
|
||||
})
|
||||
builder.beginEntry(a)
|
||||
builder.endEntry()
|
||||
builder.popHints()
|
||||
()
|
||||
}
|
||||
}
|
||||
implicit val unpickler: Unpickler[CrossVersion] = new Unpickler[CrossVersion] {
|
||||
val tag = implicitly[FastTypeTag[CrossVersion]]
|
||||
def unpickle(tpe: String, reader: PReader): Any = {
|
||||
reader.pushHints()
|
||||
reader.hintTag(tag)
|
||||
val tpeStr = reader.beginEntry()
|
||||
val tpe = scala.pickling.FastTypeTag(tpeStr)
|
||||
// sys.error(tpe.toString)
|
||||
val result = tpe match {
|
||||
case t if t == disabledTag => Disabled
|
||||
case t if t == binaryTag => binary
|
||||
case t if t == fullTag => full
|
||||
}
|
||||
reader.endEntry()
|
||||
reader.popHints()
|
||||
result
|
||||
}
|
||||
}
|
||||
|
||||
/** Cross-versions a module with the full version (typically the full Scala version). */
|
||||
def full: CrossVersion = new Full(idStringFun)
|
||||
|
||||
/**
|
||||
* Cross-versions a module with the result of applying `remapVersion` to the full version
|
||||
* (typically the full Scala version). See also [[sbt.librarymanagement.CrossVersion.Full]].
|
||||
*/
|
||||
def fullMapped(remapVersion: String => String): CrossVersion = new Full(remapVersion)
|
||||
def full: CrossVersion = new Full()
|
||||
|
||||
/** Cross-versions a module with the binary version (typically the binary Scala version). */
|
||||
def binary: CrossVersion = new Binary(idStringFun)
|
||||
|
||||
/**
|
||||
* Cross-versions a module with the result of applying `remapVersion` to the binary version
|
||||
* (typically the binary Scala version). See also [[sbt.librarymanagement.CrossVersion.Binary]].
|
||||
*/
|
||||
def binaryMapped(remapVersion: String => String): CrossVersion = new Binary(remapVersion)
|
||||
|
||||
private[this] def idFun[T]: T => T = x => x
|
||||
private[this] val idStringFun = idFun[String]
|
||||
def binary: CrossVersion = new Binary()
|
||||
|
||||
private[sbt] def append(s: String): Option[String => String] = Some(x => crossName(x, s))
|
||||
|
||||
|
|
@ -114,9 +27,9 @@ object CrossVersion {
|
|||
*/
|
||||
def apply(cross: CrossVersion, fullVersion: String, binaryVersion: String): Option[String => String] =
|
||||
cross match {
|
||||
case Disabled => None
|
||||
case b: Binary => append(b.remapVersion(binaryVersion))
|
||||
case f: Full => append(f.remapVersion(fullVersion))
|
||||
case _: Disabled => None
|
||||
case _: Binary => append(binaryVersion)
|
||||
case _: Full => append(fullVersion)
|
||||
}
|
||||
|
||||
/** Constructs the cross-version function defined by `module` and `is`, if one is configured. */
|
||||
|
|
@ -128,7 +41,7 @@ object CrossVersion {
|
|||
is flatMap { i => apply(module, i) }
|
||||
|
||||
/** Cross-version each `Artifact` in `artifacts` according to cross-version function `cross`. */
|
||||
def substituteCross(artifacts: Seq[Artifact], cross: Option[String => String]): Seq[Artifact] =
|
||||
def substituteCross(artifacts: Vector[Artifact], cross: Option[String => String]): Vector[Artifact] =
|
||||
cross match {
|
||||
case None => artifacts
|
||||
case Some(is) => substituteCrossA(artifacts, cross)
|
||||
|
|
@ -147,14 +60,14 @@ object CrossVersion {
|
|||
private[sbt] def substituteCross(exclude: SbtExclusionRule, is: Option[IvyScala]): SbtExclusionRule = {
|
||||
val fopt: Option[String => String] =
|
||||
is flatMap { i => CrossVersion(exclude.crossVersion, i.scalaFullVersion, i.scalaBinaryVersion) }
|
||||
exclude.copy(name = applyCross(exclude.name, fopt))
|
||||
exclude.withName(applyCross(exclude.name, fopt))
|
||||
}
|
||||
|
||||
/** Cross-versions `a` according to cross-version function `cross`. */
|
||||
def substituteCross(a: Artifact, cross: Option[String => String]): Artifact =
|
||||
a.copy(name = applyCross(a.name, cross))
|
||||
a.withName(applyCross(a.name, cross))
|
||||
|
||||
private[sbt] def substituteCrossA(as: Seq[Artifact], cross: Option[String => String]): Seq[Artifact] =
|
||||
private[sbt] def substituteCrossA(as: Vector[Artifact], cross: Option[String => String]): Vector[Artifact] =
|
||||
as.map(art => substituteCross(art, cross))
|
||||
|
||||
/**
|
||||
|
|
@ -166,7 +79,7 @@ object CrossVersion {
|
|||
{
|
||||
val cross = apply(m.crossVersion, scalaFullVersion, scalaBinaryVersion)
|
||||
if (cross.isDefined)
|
||||
m.copy(name = applyCross(m.name, cross), explicitArtifacts = substituteCrossA(m.explicitArtifacts, cross))
|
||||
m.withName(applyCross(m.name, cross)).withExplicitArtifacts(substituteCrossA(m.explicitArtifacts, cross))
|
||||
else
|
||||
m
|
||||
}
|
||||
|
|
|
|||
|
|
@ -88,7 +88,7 @@ final class EvictionPair private[sbt] (
|
|||
val organization: String,
|
||||
val name: String,
|
||||
val winner: Option[ModuleReport],
|
||||
val evicteds: Seq[ModuleReport],
|
||||
val evicteds: Vector[ModuleReport],
|
||||
val includesDirect: Boolean,
|
||||
val showCallers: Boolean
|
||||
) {
|
||||
|
|
@ -168,7 +168,7 @@ object EvictionWarning {
|
|||
private[sbt] def processEvictions(module: IvySbt#Module, options: EvictionWarningOptions, reports: Seq[OrganizationArtifactReport]): EvictionWarning = {
|
||||
val directDependencies = module.moduleSettings match {
|
||||
case x: InlineConfiguration => x.dependencies
|
||||
case _ => Seq()
|
||||
case _ => Vector.empty
|
||||
}
|
||||
val pairs = reports map { detail =>
|
||||
val evicteds = detail.modules filter { _.evicted }
|
||||
|
|
|
|||
|
|
@ -3,54 +3,24 @@
|
|||
*/
|
||||
package sbt.librarymanagement
|
||||
|
||||
import java.net.URL
|
||||
import org.apache.ivy.core.module.descriptor
|
||||
import org.apache.ivy.util.filter.{ Filter => IvyFilter }
|
||||
import sbt.serialization._
|
||||
|
||||
/** Additional information about a project module */
|
||||
final case class ModuleInfo(nameFormal: String, description: String = "", homepage: Option[URL] = None, startYear: Option[Int] = None, licenses: Seq[(String, URL)] = Nil, organizationName: String = "", organizationHomepage: Option[URL] = None, scmInfo: Option[ScmInfo] = None, developers: Seq[Developer] = Seq()) {
|
||||
def this(nameFormal: String, description: String, homepage: Option[URL], startYear: Option[Int], licenses: Seq[(String, URL)], organizationName: String, organizationHomepage: Option[URL], scmInfo: Option[ScmInfo]) =
|
||||
this(nameFormal, description, homepage, startYear, licenses, organizationName, organizationHomepage, scmInfo, Seq())
|
||||
def formally(name: String) = copy(nameFormal = name)
|
||||
def describing(desc: String, home: Option[URL]) = copy(description = desc, homepage = home)
|
||||
def licensed(lics: (String, URL)*) = copy(licenses = lics)
|
||||
def organization(name: String, home: Option[URL]) = copy(organizationName = name, organizationHomepage = home)
|
||||
abstract class InclExclRuleFunctions {
|
||||
def everything = new InclExclRule("*", "*", "*", Vector.empty)
|
||||
}
|
||||
|
||||
/** Basic SCM information for a project module */
|
||||
final case class ScmInfo(browseUrl: URL, connection: String, devConnection: Option[String] = None)
|
||||
abstract class ArtifactTypeFilterExtra {
|
||||
def types: Set[String]
|
||||
def inverted: Boolean
|
||||
|
||||
final case class Developer(id: String, name: String, email: String, url: URL)
|
||||
protected[this] def copy(types: Set[String] = types, inverted: Boolean = inverted): ArtifactTypeFilter
|
||||
|
||||
/**
|
||||
* Rule to either:
|
||||
* <ul>
|
||||
* <li> exclude unwanted dependencies pulled in transitively by a module, or to</li>
|
||||
* <li> include and merge artifacts coming from the ModuleDescriptor if "dependencyArtifacts" are also provided.</li>
|
||||
* </ul>
|
||||
* Which one depends on the parameter name which it is passed to, but the filter has the same fields in both cases.
|
||||
*/
|
||||
final case class InclExclRule(organization: String = "*", name: String = "*", artifact: String = "*", configurations: Seq[String] = Nil)
|
||||
object InclExclRule {
|
||||
def everything = InclExclRule("*", "*", "*", Nil)
|
||||
|
||||
implicit val pickler: Pickler[InclExclRule] with Unpickler[InclExclRule] = PicklerUnpickler.generate[InclExclRule]
|
||||
}
|
||||
|
||||
/**
|
||||
* Work around the inadequacy of Ivy's ArtifactTypeFilter (that it cannot reverse a filter)
|
||||
* @param types represents the artifact types that we should try to resolve for (as in the allowed values of
|
||||
* `artifact[type]` from a dependency `<publications>` section). One can use this to filter
|
||||
* source / doc artifacts.
|
||||
* @param inverted whether to invert the types filter (i.e. allow only types NOT in the set)
|
||||
*/
|
||||
case class ArtifactTypeFilter(types: Set[String], inverted: Boolean) {
|
||||
def invert = copy(inverted = !inverted)
|
||||
def apply(a: descriptor.Artifact): Boolean = (types contains a.getType) ^ inverted
|
||||
}
|
||||
|
||||
object ArtifactTypeFilter {
|
||||
abstract class ArtifactTypeFilterFunctions {
|
||||
def allow(types: Set[String]) = ArtifactTypeFilter(types, false)
|
||||
def forbid(types: Set[String]) = ArtifactTypeFilter(types, true)
|
||||
|
||||
|
|
@ -59,16 +29,12 @@ object ArtifactTypeFilter {
|
|||
}
|
||||
}
|
||||
|
||||
final case class ModuleConfiguration(organization: String, name: String, revision: String, resolver: Resolver)
|
||||
object ModuleConfiguration {
|
||||
def apply(org: String, resolver: Resolver): ModuleConfiguration = apply(org, "*", "*", resolver)
|
||||
def apply(org: String, name: String, resolver: Resolver): ModuleConfiguration = ModuleConfiguration(org, name, "*", resolver)
|
||||
}
|
||||
abstract class ConflictManagerFunctions {
|
||||
// To avoid NPE (or making the val's below lazy)
|
||||
// For case classes refchecks rewrites apply calls to constructor calls, we have to do it manually
|
||||
def apply(name: String, organization: String = "*", module: String = "*"): ConflictManager
|
||||
def ConflictManager(name: String) = apply(name)
|
||||
|
||||
final case class ConflictManager(name: String, organization: String = "*", module: String = "*")
|
||||
|
||||
/** See http://ant.apache.org/ivy/history/latest-milestone/settings/conflict-managers.html for details of the different conflict managers.*/
|
||||
object ConflictManager {
|
||||
val all = ConflictManager("all")
|
||||
val latestTime = ConflictManager("latest-time")
|
||||
val latestRevision = ConflictManager("latest-revision")
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ object ScalaArtifacts {
|
|||
val ReflectID = "scala-reflect"
|
||||
val ActorsID = "scala-actors"
|
||||
val ScalapID = "scalap"
|
||||
val Artifacts = Seq(LibraryID, CompilerID, ReflectID, ActorsID, ScalapID)
|
||||
val Artifacts = Vector(LibraryID, CompilerID, ReflectID, ActorsID, ScalapID)
|
||||
val DottyIDPrefix = "dotty"
|
||||
|
||||
def dottyID(binaryVersion: String): String = s"${DottyIDPrefix}_${binaryVersion}"
|
||||
|
|
@ -28,8 +28,8 @@ object ScalaArtifacts {
|
|||
|
||||
private[sbt] def toolDependencies(org: String, version: String, isDotty: Boolean = false): Seq[ModuleID] =
|
||||
if (isDotty)
|
||||
Seq(ModuleID(org, DottyIDPrefix, version, Some(Configurations.ScalaTool.name + "->compile"),
|
||||
crossVersion = CrossVersion.binary))
|
||||
Seq(ModuleID(org, DottyIDPrefix, version).withConfigurations(Some(Configurations.ScalaTool.name + "->compile"))
|
||||
.withCrossVersion(CrossVersion.binary))
|
||||
else
|
||||
Seq(
|
||||
scalaToolDependency(org, ScalaArtifacts.CompilerID, version),
|
||||
|
|
@ -37,7 +37,7 @@ object ScalaArtifacts {
|
|||
)
|
||||
|
||||
private[this] def scalaToolDependency(org: String, id: String, version: String): ModuleID =
|
||||
ModuleID(org, id, version, Some(Configurations.ScalaTool.name + "->default,optional(default)"))
|
||||
ModuleID(org, id, version).withConfigurations(Some(Configurations.ScalaTool.name + "->default,optional(default)"))
|
||||
}
|
||||
object SbtArtifacts {
|
||||
val Organization = "org.scala-sbt"
|
||||
|
|
@ -45,9 +45,7 @@ object SbtArtifacts {
|
|||
|
||||
import ScalaArtifacts._
|
||||
|
||||
final case class IvyScala(scalaFullVersion: String, scalaBinaryVersion: String, configurations: Iterable[Configuration], checkExplicit: Boolean, filterImplicit: Boolean, overrideScalaVersion: Boolean, scalaOrganization: String = ScalaArtifacts.Organization, scalaArtifacts: Seq[String] = ScalaArtifacts.Artifacts)
|
||||
|
||||
private[sbt] object IvyScala {
|
||||
private[sbt] abstract class IvyScalaFunctions {
|
||||
/** Performs checks/adds filters on Scala dependencies (if enabled in IvyScala). */
|
||||
def checkModule(module: DefaultModuleDescriptor, conf: String, log: Logger)(check: IvyScala): Unit = {
|
||||
if (check.checkExplicit)
|
||||
|
|
|
|||
|
|
@ -6,13 +6,37 @@ package sbt.librarymanagement
|
|||
import java.net.URL
|
||||
|
||||
import sbt.internal.librarymanagement.mavenint.SbtPomExtraProperties
|
||||
import sbt.serialization._
|
||||
|
||||
final case class ModuleID(organization: String, name: String, revision: String, configurations: Option[String] = None, isChanging: Boolean = false, isTransitive: Boolean = true, isForce: Boolean = false, explicitArtifacts: Seq[Artifact] = Nil, inclusions: Seq[InclusionRule] = Nil, exclusions: Seq[ExclusionRule] = Nil, extraAttributes: Map[String, String] = Map.empty, crossVersion: CrossVersion = CrossVersion.Disabled, branchName: Option[String] = None) {
|
||||
override def toString: String =
|
||||
organization + ":" + name + ":" + revision +
|
||||
(configurations match { case Some(s) => ":" + s; case None => "" }) +
|
||||
(if (extraAttributes.isEmpty) "" else " " + extraString)
|
||||
abstract class ModuleIDExtra {
|
||||
def organization: String
|
||||
def name: String
|
||||
def revision: String
|
||||
def configurations: Option[String]
|
||||
def isChanging: Boolean
|
||||
def isTransitive: Boolean
|
||||
def isForce: Boolean
|
||||
def explicitArtifacts: Vector[Artifact]
|
||||
def inclusions: Vector[InclusionRule]
|
||||
def exclusions: Vector[ExclusionRule]
|
||||
def extraAttributes: Map[String, String]
|
||||
def crossVersion: CrossVersion
|
||||
def branchName: Option[String]
|
||||
|
||||
protected[this] def copy(
|
||||
organization: String = organization,
|
||||
name: String = name,
|
||||
revision: String = revision,
|
||||
configurations: Option[String] = configurations,
|
||||
isChanging: Boolean = isChanging,
|
||||
isTransitive: Boolean = isTransitive,
|
||||
isForce: Boolean = isForce,
|
||||
explicitArtifacts: Vector[Artifact] = explicitArtifacts,
|
||||
inclusions: Vector[InclusionRule] = inclusions,
|
||||
exclusions: Vector[ExclusionRule] = exclusions,
|
||||
extraAttributes: Map[String, String] = extraAttributes,
|
||||
crossVersion: CrossVersion = crossVersion,
|
||||
branchName: Option[String] = branchName
|
||||
): ModuleID
|
||||
|
||||
/** String representation of the extra attributes, excluding any information only attributes. */
|
||||
def extraString: String = extraDependencyAttributes.map { case (k, v) => k + "=" + v } mkString ("(", ", ", ")")
|
||||
|
|
@ -21,10 +45,7 @@ final case class ModuleID(organization: String, name: String, revision: String,
|
|||
def extraDependencyAttributes: Map[String, String] = extraAttributes.filterKeys(!_.startsWith(SbtPomExtraProperties.POM_INFO_KEY_PREFIX))
|
||||
|
||||
@deprecated("Use `cross(CrossVersion)`, the variant accepting a CrossVersion value constructed by a member of the CrossVersion object instead.", "0.12.0")
|
||||
def cross(v: Boolean): ModuleID = cross(if (v) CrossVersion.binary else CrossVersion.Disabled)
|
||||
|
||||
@deprecated("Use `cross(CrossVersion)`, the variant accepting a CrossVersion value constructed by a member of the CrossVersion object instead.", "0.12.0")
|
||||
def cross(v: Boolean, verRemap: String => String): ModuleID = cross(if (v) CrossVersion.binaryMapped(verRemap) else CrossVersion.Disabled)
|
||||
def cross(v: Boolean): ModuleID = cross(if (v) CrossVersion.binary else Disabled())
|
||||
|
||||
/** Specifies the cross-version behavior for this module. See [CrossVersion] for details.*/
|
||||
def cross(v: CrossVersion): ModuleID = copy(crossVersion = v)
|
||||
|
|
@ -64,7 +85,7 @@ final case class ModuleID(organization: String, name: String, revision: String,
|
|||
* Declares the explicit artifacts for this module. If this ModuleID represents a dependency,
|
||||
* these artifact definitions override the information in the dependency's published metadata.
|
||||
*/
|
||||
def artifacts(newArtifacts: Artifact*) = copy(explicitArtifacts = newArtifacts ++ this.explicitArtifacts)
|
||||
def artifacts(newArtifacts: Artifact*) = copy(explicitArtifacts = newArtifacts.toVector ++ explicitArtifacts)
|
||||
|
||||
/**
|
||||
* Applies the provided exclusions to dependencies of this module. Note that only exclusions that specify
|
||||
|
|
@ -73,7 +94,7 @@ final case class ModuleID(organization: String, name: String, revision: String,
|
|||
def excludeAll(rules: InclExclRule*) = copy(exclusions = this.exclusions ++ rules)
|
||||
|
||||
/** Excludes the dependency with organization `org` and `name` from being introduced by this dependency during resolution. */
|
||||
def exclude(org: String, name: String) = excludeAll(InclExclRule(org, name))
|
||||
def exclude(org: String, name: String) = excludeAll(InclExclRule().withOrganization(org).withName(name))
|
||||
|
||||
/**
|
||||
* Adds extra attributes for this module. All keys are prefixed with `e:` if they are not already so prefixed.
|
||||
|
|
@ -127,9 +148,7 @@ final case class ModuleID(organization: String, name: String, revision: String,
|
|||
def branch(branchName: Option[String]) = copy(branchName = branchName)
|
||||
}
|
||||
|
||||
object ModuleID {
|
||||
implicit val pickler: Pickler[ModuleID] with Unpickler[ModuleID] = PicklerUnpickler.generate[ModuleID]
|
||||
|
||||
abstract class ModuleIDFunctions {
|
||||
/** Prefixes all keys with `e:` if they are not already so prefixed. */
|
||||
def checkE(attributes: Seq[(String, String)]) =
|
||||
for ((key, value) <- attributes) yield if (key.startsWith("e:")) (key, value) else ("e:" + key, value)
|
||||
|
|
|
|||
|
|
@ -9,11 +9,7 @@ import scala.xml.XML
|
|||
import org.apache.ivy.plugins.resolver.DependencyResolver
|
||||
import org.xml.sax.SAXParseException
|
||||
|
||||
sealed trait Resolver {
|
||||
def name: String
|
||||
}
|
||||
final class RawRepository(val resolver: DependencyResolver) extends Resolver {
|
||||
def name = resolver.getName
|
||||
final class RawRepository(val resolver: DependencyResolver) extends Resolver(resolver.getName) {
|
||||
override def toString = "Raw(" + resolver.toString + ")"
|
||||
|
||||
override def equals(o: Any): Boolean = o match {
|
||||
|
|
@ -29,148 +25,30 @@ final class RawRepository(val resolver: DependencyResolver) extends Resolver {
|
|||
hash
|
||||
}
|
||||
}
|
||||
sealed case class ChainedResolver(name: String, resolvers: Seq[Resolver]) extends Resolver
|
||||
|
||||
/** An instance of a remote maven repository. Note: This will use Aether/Maven to resolve artifacts. */
|
||||
sealed case class MavenRepository(name: String, root: String, localIfFile: Boolean = true) extends Resolver {
|
||||
override def toString = s"$name: $root"
|
||||
def isCache: Boolean = false
|
||||
def withLocalIfFile(value: Boolean) = MavenRepository(name, root, value)
|
||||
}
|
||||
|
||||
/**
|
||||
* An instance of maven CACHE directory. You cannot treat a cache directory the same as a a remote repository because
|
||||
* the metadata is different (see Aether ML discussion).
|
||||
*/
|
||||
final class MavenCache(name: String, val rootFile: File) extends MavenRepository(name, rootFile.toURI.toURL.toString) {
|
||||
override val toString = s"cache:$name: ${rootFile.getAbsolutePath}"
|
||||
override def isCache: Boolean = true
|
||||
}
|
||||
object MavenCache {
|
||||
def apply(name: String, rootFile: File): MavenCache = new MavenCache(name, rootFile)
|
||||
}
|
||||
|
||||
final class Patterns(val ivyPatterns: Seq[String], val artifactPatterns: Seq[String], val isMavenCompatible: Boolean, val descriptorOptional: Boolean, val skipConsistencyCheck: Boolean) {
|
||||
private[sbt] def mavenStyle(): Patterns = Patterns(ivyPatterns, artifactPatterns, true)
|
||||
private[sbt] def withDescriptorOptional(): Patterns = Patterns(ivyPatterns, artifactPatterns, isMavenCompatible, true, skipConsistencyCheck)
|
||||
private[sbt] def withoutConsistencyCheck(): Patterns = Patterns(ivyPatterns, artifactPatterns, isMavenCompatible, descriptorOptional, true)
|
||||
private[sbt] def withIvys(patterns: Seq[String]): Patterns = Patterns(patterns ++ ivyPatterns, artifactPatterns, isMavenCompatible)
|
||||
private[sbt] def withArtifacts(patterns: Seq[String]): Patterns = Patterns(ivyPatterns, patterns ++ artifactPatterns, isMavenCompatible)
|
||||
override def toString = "Patterns(ivyPatterns=%s, artifactPatterns=%s, isMavenCompatible=%s, descriptorOptional=%s, skipConsistencyCheck=%s)".format(ivyPatterns, artifactPatterns, isMavenCompatible, descriptorOptional, skipConsistencyCheck)
|
||||
override def equals(obj: Any): Boolean = {
|
||||
obj match {
|
||||
case other: Patterns =>
|
||||
ivyPatterns == other.ivyPatterns && artifactPatterns == other.artifactPatterns && isMavenCompatible == other.isMavenCompatible && descriptorOptional == other.descriptorOptional && skipConsistencyCheck == other.skipConsistencyCheck
|
||||
case _ => false
|
||||
}
|
||||
}
|
||||
override def hashCode: Int = (ivyPatterns, artifactPatterns, isMavenCompatible, descriptorOptional, skipConsistencyCheck).hashCode
|
||||
}
|
||||
object Patterns {
|
||||
abstract class PatternsFunctions {
|
||||
implicit def defaultPatterns: Patterns = Resolver.defaultPatterns
|
||||
|
||||
def apply(artifactPatterns: String*): Patterns = Patterns(true, artifactPatterns: _*)
|
||||
def apply(isMavenCompatible: Boolean, artifactPatterns: String*): Patterns = Patterns(artifactPatterns, artifactPatterns, isMavenCompatible)
|
||||
def apply(ivyPatterns: Seq[String], artifactPatterns: Seq[String], isMavenCompatible: Boolean): Patterns = apply(ivyPatterns: Seq[String], artifactPatterns: Seq[String], isMavenCompatible: Boolean, false, false)
|
||||
def apply(ivyPatterns: Seq[String], artifactPatterns: Seq[String], isMavenCompatible: Boolean, descriptorOptional: Boolean, skipConsistencyCheck: Boolean): Patterns = new Patterns(ivyPatterns, artifactPatterns, isMavenCompatible, descriptorOptional, skipConsistencyCheck)
|
||||
}
|
||||
object RepositoryHelpers {
|
||||
final case class SshConnection(authentication: Option[SshAuthentication], hostname: Option[String], port: Option[Int]) {
|
||||
def copy(authentication: Option[SshAuthentication]) = SshConnection(authentication, hostname, port)
|
||||
def apply(isMavenCompatible: Boolean, artifactPatterns: String*): Patterns = {
|
||||
val patterns = artifactPatterns.toVector
|
||||
Patterns().withIvyPatterns(patterns).withArtifactPatterns(patterns).withIsMavenCompatible(isMavenCompatible)
|
||||
}
|
||||
/** Configuration specific to an Ivy filesystem resolver. */
|
||||
final case class FileConfiguration(isLocal: Boolean, isTransactional: Option[Boolean]) {
|
||||
def transactional() = FileConfiguration(isLocal, Some(true))
|
||||
def nontransactional() = FileConfiguration(isLocal, Some(false))
|
||||
def nonlocal() = FileConfiguration(false, isTransactional)
|
||||
}
|
||||
sealed trait SshAuthentication
|
||||
final case class PasswordAuthentication(user: String, password: Option[String]) extends SshAuthentication
|
||||
final case class KeyFileAuthentication(user: String, keyfile: File, password: Option[String]) extends SshAuthentication
|
||||
}
|
||||
import RepositoryHelpers.{ SshConnection, FileConfiguration }
|
||||
import RepositoryHelpers.{ KeyFileAuthentication, PasswordAuthentication, SshAuthentication }
|
||||
|
||||
/** sbt interface to an Ivy repository based on patterns, which is most Ivy repositories.*/
|
||||
sealed abstract class PatternsBasedRepository extends Resolver {
|
||||
type RepositoryType <: PatternsBasedRepository
|
||||
/** Should be implemented to create a new copy of this repository but with `patterns` as given.*/
|
||||
protected def copy(patterns: Patterns): RepositoryType
|
||||
|
||||
/** The object representing the configured patterns for this repository. */
|
||||
def patterns: Patterns
|
||||
|
||||
/** Enables maven 2 compatibility for this repository. */
|
||||
def mavenStyle() = copy(patterns.mavenStyle())
|
||||
|
||||
/** Makes descriptor metadata optional for this repository. */
|
||||
def descriptorOptional() = copy(patterns.withDescriptorOptional())
|
||||
|
||||
/** Disables consistency checking for this repository. */
|
||||
def skipConsistencyCheck() = copy(patterns.withoutConsistencyCheck())
|
||||
|
||||
/** Adds the given patterns for resolving/publishing Ivy files.*/
|
||||
def ivys(ivyPatterns: String*): RepositoryType = copy(patterns.withIvys(ivyPatterns))
|
||||
/** Adds the given patterns for resolving/publishing artifacts.*/
|
||||
def artifacts(artifactPatterns: String*): RepositoryType = copy(patterns.withArtifacts(artifactPatterns))
|
||||
}
|
||||
/** sbt interface for an Ivy filesystem repository. More convenient construction is done using Resolver.file. */
|
||||
final case class FileRepository(name: String, configuration: FileConfiguration, patterns: Patterns) extends PatternsBasedRepository {
|
||||
type RepositoryType = FileRepository
|
||||
protected def copy(patterns: Patterns): FileRepository = FileRepository(name, configuration, patterns)
|
||||
private def copy(configuration: FileConfiguration) = FileRepository(name, configuration, patterns)
|
||||
def transactional() = copy(configuration.transactional())
|
||||
def nonlocal() = copy(configuration.nonlocal())
|
||||
}
|
||||
final case class URLRepository(name: String, patterns: Patterns) extends PatternsBasedRepository {
|
||||
type RepositoryType = URLRepository
|
||||
protected def copy(patterns: Patterns): URLRepository = URLRepository(name, patterns)
|
||||
}
|
||||
/** sbt interface for an Ivy ssh-based repository (ssh and sftp). Requires the Jsch library.. */
|
||||
sealed abstract class SshBasedRepository extends PatternsBasedRepository {
|
||||
type RepositoryType <: SshBasedRepository
|
||||
protected def copy(connection: SshConnection): RepositoryType
|
||||
private def copy(authentication: SshAuthentication): RepositoryType = copy(connection.copy(Some(authentication)))
|
||||
|
||||
/** The object representing the configured ssh connection for this repository. */
|
||||
def connection: SshConnection
|
||||
|
||||
/** Configures this to use the specified user name and password when connecting to the remote repository. */
|
||||
def as(user: String, password: String): RepositoryType = as(user, Some(password))
|
||||
def as(user: String): RepositoryType = as(user, None)
|
||||
def as(user: String, password: Option[String]) = copy(new PasswordAuthentication(user, password))
|
||||
/** Configures this to use the specified keyfile and password for the keyfile when connecting to the remote repository. */
|
||||
def as(user: String, keyfile: File): RepositoryType = as(user, keyfile, None)
|
||||
def as(user: String, keyfile: File, password: String): RepositoryType = as(user, keyfile, Some(password))
|
||||
def as(user: String, keyfile: File, password: Option[String]): RepositoryType = copy(new KeyFileAuthentication(user, keyfile, password))
|
||||
}
|
||||
/** sbt interface for an Ivy repository over ssh. More convenient construction is done using Resolver.ssh. */
|
||||
final case class SshRepository(name: String, connection: SshConnection, patterns: Patterns, publishPermissions: Option[String]) extends SshBasedRepository {
|
||||
type RepositoryType = SshRepository
|
||||
protected def copy(patterns: Patterns): SshRepository = SshRepository(name, connection, patterns, publishPermissions)
|
||||
protected def copy(connection: SshConnection): SshRepository = SshRepository(name, connection, patterns, publishPermissions)
|
||||
/** Defines the permissions to set when publishing to this repository. */
|
||||
def withPermissions(publishPermissions: String): SshRepository = withPermissions(Some(publishPermissions))
|
||||
def withPermissions(publishPermissions: Option[String]): SshRepository = SshRepository(name, connection, patterns, publishPermissions)
|
||||
}
|
||||
/** sbt interface for an Ivy repository over sftp. More convenient construction is done using Resolver.sftp. */
|
||||
final case class SftpRepository(name: String, connection: SshConnection, patterns: Patterns) extends SshBasedRepository {
|
||||
type RepositoryType = SftpRepository
|
||||
protected def copy(patterns: Patterns): SftpRepository = SftpRepository(name, connection, patterns)
|
||||
protected def copy(connection: SshConnection): SftpRepository = SftpRepository(name, connection, patterns)
|
||||
}
|
||||
/** A repository that conforms to sbt launcher's interface */
|
||||
private[sbt] class FakeRepository(resolver: DependencyResolver) extends xsbti.Repository {
|
||||
def rawRepository = new RawRepository(resolver)
|
||||
}
|
||||
|
||||
import Resolver._
|
||||
trait ResolversSyntax {
|
||||
import Resolver._
|
||||
val DefaultMavenRepository = new MavenRepository("public", centralRepositoryRoot(useSecureResolvers))
|
||||
val JavaNet2Repository = new MavenRepository(JavaNet2RepositoryName, JavaNet2RepositoryRoot)
|
||||
val JCenterRepository = new MavenRepository(JCenterRepositoryName, JCenterRepositoryRoot)
|
||||
}
|
||||
|
||||
object DefaultMavenRepository extends MavenRepository("public", centralRepositoryRoot(useSecureResolvers))
|
||||
object JavaNet2Repository extends MavenRepository(JavaNet2RepositoryName, JavaNet2RepositoryRoot)
|
||||
object JCenterRepository extends MavenRepository(JCenterRepositoryName, JCenterRepositoryRoot)
|
||||
|
||||
object Resolver {
|
||||
abstract class ResolverFunctions {
|
||||
private[sbt] def useSecureResolvers = sys.props.get("sbt.repository.secure") map { _.toLowerCase == "true" } getOrElse true
|
||||
|
||||
val TypesafeRepositoryRoot = typesafeRepositoryRoot(useSecureResolvers)
|
||||
|
|
@ -342,7 +220,7 @@ object Resolver {
|
|||
/** Resolves the ivy file and artifact patterns in `patterns` against the given base. */
|
||||
private def resolvePatterns(base: String, basePatterns: Patterns): Patterns =
|
||||
{
|
||||
def resolveAll(patterns: Seq[String]) = patterns.map(p => resolvePattern(base, p))
|
||||
def resolveAll(patterns: Vector[String]) = patterns.map(p => resolvePattern(base, p))
|
||||
Patterns(resolveAll(basePatterns.ivyPatterns), resolveAll(basePatterns.artifactPatterns), basePatterns.isMavenCompatible, basePatterns.descriptorOptional, basePatterns.skipConsistencyCheck)
|
||||
}
|
||||
private[sbt] def resolvePattern(base: String, pattern: String): String =
|
||||
|
|
@ -351,7 +229,7 @@ object Resolver {
|
|||
if (normBase.endsWith("/") || pattern.startsWith("/")) normBase + pattern else normBase + "/" + pattern
|
||||
}
|
||||
def defaultFileConfiguration = FileConfiguration(true, None)
|
||||
def mavenStylePatterns = Patterns(Nil, mavenStyleBasePattern :: Nil, true)
|
||||
def mavenStylePatterns = Patterns().withArtifactPatterns(Vector(mavenStyleBasePattern))
|
||||
def ivyStylePatterns = defaultIvyPatterns //Patterns(Nil, Nil, false)
|
||||
|
||||
def defaultPatterns = mavenStylePatterns
|
||||
|
|
@ -381,17 +259,17 @@ object Resolver {
|
|||
}
|
||||
// TODO - should this just be the *exact* same as mavenLocal? probably...
|
||||
def publishMavenLocal: MavenCache = new MavenCache("publish-m2-local", mavenLocalDir)
|
||||
def mavenLocal: MavenRepository = new MavenCache("Maven2 Local", mavenLocalDir)
|
||||
def mavenLocal: IMavenRepository = new MavenCache("Maven2 Local", mavenLocalDir)
|
||||
def defaultLocal = defaultUserFileRepository("local")
|
||||
def defaultShared = defaultUserFileRepository("shared")
|
||||
def defaultUserFileRepository(id: String) =
|
||||
{
|
||||
val pList = s"$${ivy.home}/$id/$localBasePattern" :: Nil
|
||||
FileRepository(id, defaultFileConfiguration, Patterns(pList, pList, false))
|
||||
val pList = Vector(s"$${ivy.home}/$id/$localBasePattern")
|
||||
FileRepository(id, defaultFileConfiguration, Patterns().withIvyPatterns(pList).withArtifactPatterns(pList).withIsMavenCompatible(false))
|
||||
}
|
||||
def defaultIvyPatterns =
|
||||
{
|
||||
val pList = List(localBasePattern)
|
||||
Patterns(pList, pList, false)
|
||||
val pList = Vector(localBasePattern)
|
||||
Patterns().withIvyPatterns(pList).withArtifactPatterns(pList).withIsMavenCompatible(false)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,21 +5,13 @@ package sbt.librarymanagement
|
|||
|
||||
import java.io.File
|
||||
import java.{ util => ju }
|
||||
import sbt.serialization._
|
||||
|
||||
/**
|
||||
* Provides information about resolution of a single configuration.
|
||||
* @param configuration the configuration this report is for.
|
||||
* @param modules a sequence containing one report for each module resolved for this configuration.
|
||||
* @param details a sequence containing one report for each org/name, which may or may not be part of the final resolution.
|
||||
* @param evicted a sequence of evicted modules
|
||||
*/
|
||||
final class ConfigurationReport(
|
||||
val configuration: String,
|
||||
val modules: Seq[ModuleReport],
|
||||
val details: Seq[OrganizationArtifactReport]
|
||||
) {
|
||||
abstract class ConfigurationReportExtra {
|
||||
def configuration: String
|
||||
def modules: Vector[ModuleReport]
|
||||
def details: Vector[OrganizationArtifactReport]
|
||||
|
||||
/** a sequence of evicted modules */
|
||||
def evicted: Seq[ModuleID] =
|
||||
details flatMap (_.modules) filter (_.evicted) map (_.module)
|
||||
|
||||
|
|
@ -36,78 +28,36 @@ final class ConfigurationReport(
|
|||
val module = mr.module
|
||||
if (module.configurations.isEmpty) {
|
||||
val conf = mr.configurations map (c => s"$configuration->$c") mkString ";"
|
||||
module.copy(configurations = Some(conf))
|
||||
module.withConfigurations(Some(conf))
|
||||
} else module
|
||||
}
|
||||
|
||||
def retrieve(f: (String, ModuleID, Artifact, File) => File): ConfigurationReport =
|
||||
new ConfigurationReport(configuration, modules map { _.retrieve((mid, art, file) => f(configuration, mid, art, file)) }, details)
|
||||
}
|
||||
object ConfigurationReport {
|
||||
implicit val pickler: Pickler[ConfigurationReport] with Unpickler[ConfigurationReport] = PicklerUnpickler.generate[ConfigurationReport]
|
||||
}
|
||||
|
||||
/**
|
||||
* OrganizationArtifactReport represents an organization+name entry in Ivy resolution report.
|
||||
* In sbt's terminology, "module" consists of organization, name, and version.
|
||||
* In Ivy's, "module" means just organization and name, and the one including version numbers
|
||||
* are called revisions.
|
||||
*
|
||||
* A sequence of OrganizationArtifactReport called details is newly added to ConfigurationReport, replacing evicted.
|
||||
* (Note old evicted was just a seq of ModuleIDs).
|
||||
* OrganizationArtifactReport groups the ModuleReport of both winners and evicted reports by their organization and name,
|
||||
* which can be used to calculate detailed evction warning etc.
|
||||
*/
|
||||
final class OrganizationArtifactReport private[sbt] (
|
||||
val organization: String,
|
||||
val name: String,
|
||||
val modules: Seq[ModuleReport]
|
||||
) {
|
||||
override def toString: String = {
|
||||
val details = modules map { _.detailReport }
|
||||
s"\t$organization:$name\n${details.mkString}\n"
|
||||
}
|
||||
}
|
||||
object OrganizationArtifactReport {
|
||||
implicit val pickler: Pickler[OrganizationArtifactReport] with Unpickler[OrganizationArtifactReport] = PicklerUnpickler.generate[OrganizationArtifactReport]
|
||||
abstract class ModuleReportExtra {
|
||||
def module: ModuleID
|
||||
def artifacts: Vector[(Artifact, File)]
|
||||
def missingArtifacts: Vector[Artifact]
|
||||
def status: Option[String]
|
||||
def publicationDate: Option[ju.Date]
|
||||
def resolver: Option[String]
|
||||
def artifactResolver: Option[String]
|
||||
def evicted: Boolean
|
||||
def evictedData: Option[String]
|
||||
def evictedReason: Option[String]
|
||||
def problem: Option[String]
|
||||
def homepage: Option[String]
|
||||
def extraAttributes: Map[String, String]
|
||||
def isDefault: Option[Boolean]
|
||||
def branch: Option[String]
|
||||
def configurations: Vector[String]
|
||||
def licenses: Vector[(String, Option[String])]
|
||||
def callers: Vector[Caller]
|
||||
|
||||
def apply(organization: String, name: String, modules: Seq[ModuleReport]): OrganizationArtifactReport =
|
||||
new OrganizationArtifactReport(organization, name, modules)
|
||||
}
|
||||
protected[this] def arts: Vector[String] = artifacts.map(_.toString) ++ missingArtifacts.map(art => "(MISSING) " + art)
|
||||
|
||||
/**
|
||||
* Provides information about the resolution of a module.
|
||||
* This information is in the context of a specific configuration.
|
||||
* @param module the `ModuleID` this report is for.
|
||||
* @param artifacts the resolved artifacts for this module, paired with the File the artifact was retrieved to.
|
||||
* @param missingArtifacts the missing artifacts for this module.
|
||||
*/
|
||||
final class ModuleReport(
|
||||
val module: ModuleID,
|
||||
val artifacts: Seq[(Artifact, File)],
|
||||
val missingArtifacts: Seq[Artifact],
|
||||
val status: Option[String],
|
||||
val publicationDate: Option[ju.Date],
|
||||
val resolver: Option[String],
|
||||
val artifactResolver: Option[String],
|
||||
val evicted: Boolean,
|
||||
val evictedData: Option[String],
|
||||
val evictedReason: Option[String],
|
||||
val problem: Option[String],
|
||||
val homepage: Option[String],
|
||||
val extraAttributes: Map[String, String],
|
||||
val isDefault: Option[Boolean],
|
||||
val branch: Option[String],
|
||||
val configurations: Seq[String],
|
||||
val licenses: Seq[(String, Option[String])],
|
||||
val callers: Seq[Caller]
|
||||
) {
|
||||
|
||||
private[this] lazy val arts: Seq[String] = artifacts.map(_.toString) ++ missingArtifacts.map(art => "(MISSING) " + art)
|
||||
override def toString: String = {
|
||||
s"\t\t$module: " +
|
||||
(if (arts.size <= 1) "" else "\n\t\t\t") + arts.mkString("\n\t\t\t") + "\n"
|
||||
}
|
||||
def detailReport: String =
|
||||
s"\t\t- ${module.revision}\n" +
|
||||
(if (arts.size <= 1) "" else arts.mkString("\t\t\t", "\n\t\t\t", "\n")) +
|
||||
|
|
@ -148,10 +98,10 @@ final class ModuleReport(
|
|||
def retrieve(f: (ModuleID, Artifact, File) => File): ModuleReport =
|
||||
copy(artifacts = artifacts.map { case (art, file) => (art, f(module, art, file)) })
|
||||
|
||||
private[sbt] def copy(
|
||||
protected[this] def copy(
|
||||
module: ModuleID = module,
|
||||
artifacts: Seq[(Artifact, File)] = artifacts,
|
||||
missingArtifacts: Seq[Artifact] = missingArtifacts,
|
||||
artifacts: Vector[(Artifact, File)] = artifacts,
|
||||
missingArtifacts: Vector[Artifact] = missingArtifacts,
|
||||
status: Option[String] = status,
|
||||
publicationDate: Option[ju.Date] = publicationDate,
|
||||
resolver: Option[String] = resolver,
|
||||
|
|
@ -164,66 +114,31 @@ final class ModuleReport(
|
|||
extraAttributes: Map[String, String] = extraAttributes,
|
||||
isDefault: Option[Boolean] = isDefault,
|
||||
branch: Option[String] = branch,
|
||||
configurations: Seq[String] = configurations,
|
||||
licenses: Seq[(String, Option[String])] = licenses,
|
||||
callers: Seq[Caller] = callers
|
||||
): ModuleReport =
|
||||
new ModuleReport(module, artifacts, missingArtifacts, status, publicationDate, resolver, artifactResolver,
|
||||
evicted, evictedData, evictedReason, problem, homepage, extraAttributes, isDefault, branch, configurations, licenses, callers)
|
||||
configurations: Vector[String] = configurations,
|
||||
licenses: Vector[(String, Option[String])] = licenses,
|
||||
callers: Vector[Caller] = callers
|
||||
): ModuleReport
|
||||
}
|
||||
|
||||
object ModuleReport {
|
||||
def apply(module: ModuleID, artifacts: Seq[(Artifact, File)], missingArtifacts: Seq[Artifact]): ModuleReport =
|
||||
new ModuleReport(module, artifacts, missingArtifacts, None, None, None, None,
|
||||
false, None, None, None, None, Map(), None, None, Nil, Nil, Nil)
|
||||
implicit val pickler: Pickler[ModuleReport] with Unpickler[ModuleReport] = PicklerUnpickler.generate[ModuleReport]
|
||||
}
|
||||
|
||||
final class Caller(
|
||||
val caller: ModuleID,
|
||||
val callerConfigurations: Seq[String],
|
||||
val callerExtraAttributes: Map[String, String],
|
||||
val isForceDependency: Boolean,
|
||||
val isChangingDependency: Boolean,
|
||||
val isTransitiveDependency: Boolean,
|
||||
val isDirectlyForceDependency: Boolean
|
||||
) {
|
||||
override def toString: String =
|
||||
s"$caller"
|
||||
}
|
||||
object Caller {
|
||||
implicit val pickler: Pickler[Caller] with Unpickler[Caller] = PicklerUnpickler.generate[Caller]
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides information about dependency resolution.
|
||||
* It does not include information about evicted modules, only about the modules ultimately selected by the conflict manager.
|
||||
* This means that for a given configuration, there should only be one revision for a given organization and module name.
|
||||
* @param cachedDescriptor the location of the resolved module descriptor in the cache
|
||||
* @param configurations a sequence containing one report for each configuration resolved.
|
||||
* @param stats information about the update that produced this report
|
||||
* @see sbt.RichUpdateReport
|
||||
*/
|
||||
final class UpdateReport(val cachedDescriptor: File, val configurations: Seq[ConfigurationReport], val stats: UpdateStats, private[sbt] val stamps: Map[File, Long]) {
|
||||
@deprecated("Use the variant that provides timestamps of files.", "0.13.0")
|
||||
def this(cachedDescriptor: File, configurations: Seq[ConfigurationReport], stats: UpdateStats) =
|
||||
this(cachedDescriptor, configurations, stats, Map.empty)
|
||||
|
||||
override def toString = "Update report:\n\t" + stats + "\n" + configurations.mkString
|
||||
abstract class UpdateReportExtra {
|
||||
def cachedDescriptor: File
|
||||
def configurations: Vector[ConfigurationReport]
|
||||
def stats: UpdateStats
|
||||
private[sbt] def stamps: Map[File, Long]
|
||||
|
||||
/** All resolved modules in all configurations. */
|
||||
def allModules: Seq[ModuleID] =
|
||||
def allModules: Vector[ModuleID] =
|
||||
{
|
||||
val key = (m: ModuleID) => (m.organization, m.name, m.revision)
|
||||
configurations.flatMap(_.allModules).groupBy(key).toSeq map {
|
||||
configurations.flatMap(_.allModules).groupBy(key).toVector map {
|
||||
case (k, v) =>
|
||||
v reduceLeft { (agg, x) =>
|
||||
agg.copy(
|
||||
configurations = (agg.configurations, x.configurations) match {
|
||||
case (None, _) => x.configurations
|
||||
case (Some(ac), None) => Some(ac)
|
||||
case (Some(ac), Some(xc)) => Some(s"$ac;$xc")
|
||||
}
|
||||
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")
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -237,81 +152,4 @@ final class UpdateReport(val cachedDescriptor: File, val configurations: Seq[Con
|
|||
|
||||
/** Gets the names of all resolved configurations. This `UpdateReport` contains one `ConfigurationReport` for each configuration in this list. */
|
||||
def allConfigurations: Seq[String] = configurations.map(_.configuration)
|
||||
|
||||
private[sbt] def withStats(us: UpdateStats): UpdateReport =
|
||||
new UpdateReport(
|
||||
this.cachedDescriptor,
|
||||
this.configurations,
|
||||
us,
|
||||
this.stamps
|
||||
)
|
||||
}
|
||||
|
||||
object UpdateReport {
|
||||
private val vectorConfigurationReportPickler = implicitly[Pickler[Vector[ConfigurationReport]]]
|
||||
private val vectorConfigurationReportUnpickler = implicitly[Unpickler[Vector[ConfigurationReport]]]
|
||||
private val updateStatsPickler = implicitly[Pickler[UpdateStats]]
|
||||
private val updateStatsUnpickler = implicitly[Unpickler[UpdateStats]]
|
||||
private val flMapPickler = implicitly[Pickler[Map[File, Long]]]
|
||||
private val flMapUnpickler = implicitly[Unpickler[Map[File, Long]]]
|
||||
|
||||
implicit val pickler: Pickler[UpdateReport] with Unpickler[UpdateReport] = new Pickler[UpdateReport] with Unpickler[UpdateReport] {
|
||||
val tag = implicitly[FastTypeTag[UpdateReport]]
|
||||
val fileTag = implicitly[FastTypeTag[File]]
|
||||
val vectorConfigurationReportTag = implicitly[FastTypeTag[Vector[ConfigurationReport]]]
|
||||
val updateStatsTag = implicitly[FastTypeTag[UpdateStats]]
|
||||
val flMapTag = implicitly[FastTypeTag[Map[File, Long]]]
|
||||
def pickle(a: UpdateReport, builder: PBuilder): Unit = {
|
||||
builder.pushHints()
|
||||
builder.hintTag(tag)
|
||||
builder.beginEntry(a)
|
||||
builder.putField("cachedDescriptor", { b =>
|
||||
b.hintTag(fileTag)
|
||||
filePickler.pickle(a.cachedDescriptor, b)
|
||||
})
|
||||
builder.putField("configurations", { b =>
|
||||
b.hintTag(vectorConfigurationReportTag)
|
||||
vectorConfigurationReportPickler.pickle(a.configurations.toVector, b)
|
||||
})
|
||||
builder.putField("stats", { b =>
|
||||
b.hintTag(updateStatsTag)
|
||||
updateStatsPickler.pickle(a.stats, b)
|
||||
})
|
||||
builder.putField("stamps", { b =>
|
||||
b.hintTag(flMapTag)
|
||||
flMapPickler.pickle(a.stamps, b)
|
||||
})
|
||||
builder.endEntry()
|
||||
builder.popHints()
|
||||
()
|
||||
}
|
||||
|
||||
def unpickle(tpe: String, reader: PReader): Any = {
|
||||
reader.pushHints()
|
||||
reader.hintTag(tag)
|
||||
reader.beginEntry()
|
||||
val cachedDescriptor = filePickler.unpickleEntry(reader.readField("cachedDescriptor")).asInstanceOf[File]
|
||||
val configurations = vectorConfigurationReportUnpickler.unpickleEntry(reader.readField("configurations")).asInstanceOf[Vector[ConfigurationReport]]
|
||||
val stats = updateStatsUnpickler.unpickleEntry(reader.readField("stats")).asInstanceOf[UpdateStats]
|
||||
val stamps = flMapUnpickler.unpickleEntry(reader.readField("stamps")).asInstanceOf[Map[File, Long]]
|
||||
val result = new UpdateReport(cachedDescriptor, configurations, stats, stamps)
|
||||
reader.endEntry()
|
||||
reader.popHints()
|
||||
result
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
final class UpdateStats(val resolveTime: Long, val downloadTime: Long, val downloadSize: Long, val cached: Boolean) {
|
||||
override def toString = Seq("Resolve time: " + resolveTime + " ms", "Download time: " + downloadTime + " ms", "Download size: " + downloadSize + " bytes").mkString(", ")
|
||||
private[sbt] def withCached(c: Boolean): UpdateStats =
|
||||
new UpdateStats(
|
||||
resolveTime = this.resolveTime,
|
||||
downloadTime = this.downloadTime,
|
||||
downloadSize = this.downloadSize,
|
||||
cached = c
|
||||
)
|
||||
}
|
||||
object UpdateStats {
|
||||
implicit val pickler: Pickler[UpdateStats] with Unpickler[UpdateStats] = PicklerUnpickler.generate[UpdateStats]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
package sbt
|
||||
|
||||
package object librarymanagement {
|
||||
package object librarymanagement extends ResolversSyntax {
|
||||
type ExclusionRule = InclExclRule
|
||||
val ExclusionRule = InclExclRule
|
||||
|
||||
|
|
|
|||
|
|
@ -4,28 +4,36 @@ import sbt.io.IO
|
|||
import sbt.io.syntax._
|
||||
import java.io.File
|
||||
import cross.CrossVersionUtil
|
||||
import sbt.util.Logger
|
||||
import sbt.internal.util.ConsoleLogger
|
||||
import sbt.librarymanagement._
|
||||
import ivyint.SbtChainResolver
|
||||
import Configurations._
|
||||
|
||||
import sbt.internal.util.FileBasedStore
|
||||
|
||||
import sjsonnew.IsoString
|
||||
import sjsonnew.support.scalajson.unsafe.{ CompactPrinter, Converter }
|
||||
|
||||
import scala.json.ast.unsafe.JValue
|
||||
|
||||
trait BaseIvySpecification extends UnitSpec {
|
||||
def currentBase: File = new File(".")
|
||||
def currentTarget: File = currentBase / "target" / "ivyhome"
|
||||
def currentManaged: File = currentBase / "target" / "lib_managed"
|
||||
def currentDependency: File = currentBase / "target" / "dependency"
|
||||
def defaultModuleId: ModuleID = ModuleID("com.example", "foo", "0.1.0", Some("compile"))
|
||||
def defaultModuleId: ModuleID = ModuleID("com.example", "foo", "0.1.0").withConfigurations(Some("compile"))
|
||||
|
||||
implicit val isoString: IsoString[JValue] = IsoString.iso(CompactPrinter.apply, FixedParser.parseUnsafe)
|
||||
val fileToStore = (f: File) => new FileBasedStore(f, Converter)
|
||||
lazy val log = ConsoleLogger()
|
||||
|
||||
def configurations = Seq(Compile, Test, Runtime)
|
||||
def module(moduleId: ModuleID, deps: Seq[ModuleID], scalaFullVersion: Option[String],
|
||||
def configurations = Vector(Compile, Test, Runtime)
|
||||
def module(moduleId: ModuleID, deps: Vector[ModuleID], scalaFullVersion: Option[String],
|
||||
uo: UpdateOptions = UpdateOptions(), overrideScalaVersion: Boolean = true): IvySbt#Module = {
|
||||
val ivyScala = scalaFullVersion map { fv =>
|
||||
new IvyScala(
|
||||
scalaFullVersion = fv,
|
||||
scalaBinaryVersion = CrossVersionUtil.binaryScalaVersion(fv),
|
||||
configurations = Nil,
|
||||
configurations = Vector.empty,
|
||||
checkExplicit = true,
|
||||
filterImplicit = false,
|
||||
overrideScalaVersion = overrideScalaVersion
|
||||
|
|
@ -33,32 +41,32 @@ trait BaseIvySpecification extends UnitSpec {
|
|||
}
|
||||
|
||||
val moduleSetting: ModuleSettings = InlineConfiguration(
|
||||
false,
|
||||
ivyScala,
|
||||
module = moduleId,
|
||||
moduleInfo = ModuleInfo("foo"),
|
||||
dependencies = deps,
|
||||
configurations = configurations,
|
||||
ivyScala = ivyScala
|
||||
)
|
||||
val ivySbt = new IvySbt(mkIvyConfiguration(uo))
|
||||
dependencies = deps
|
||||
).withConfigurations(configurations)
|
||||
val ivySbt = new IvySbt(mkIvyConfiguration(uo), fileToStore)
|
||||
new ivySbt.Module(moduleSetting)
|
||||
}
|
||||
|
||||
def resolvers: Seq[Resolver] = Seq(DefaultMavenRepository)
|
||||
def resolvers: Vector[Resolver] = Vector(DefaultMavenRepository)
|
||||
|
||||
def chainResolver = ChainedResolver("sbt-chain", resolvers)
|
||||
|
||||
def mkIvyConfiguration(uo: UpdateOptions): IvyConfiguration = {
|
||||
val paths = new IvyPaths(currentBase, Some(currentTarget))
|
||||
val other = Nil
|
||||
val moduleConfs = Seq(ModuleConfiguration("*", chainResolver))
|
||||
val other = Vector.empty
|
||||
val moduleConfs = Vector(ModuleConfiguration("*", chainResolver))
|
||||
val off = false
|
||||
val check = Nil
|
||||
val check = Vector.empty
|
||||
val resCacheDir = currentTarget / "resolution-cache"
|
||||
new InlineIvyConfiguration(paths, resolvers, other, moduleConfs, off, None, check, Some(resCacheDir), uo, log)
|
||||
}
|
||||
|
||||
def makeUpdateConfiguration: UpdateConfiguration = {
|
||||
val retrieveConfig = new RetrieveConfiguration(currentManaged, Resolver.defaultRetrievePattern, false)
|
||||
val retrieveConfig = new RetrieveConfiguration(currentManaged, Resolver.defaultRetrievePattern).withSync(false)
|
||||
new UpdateConfiguration(Some(retrieveConfig), false, UpdateLogging.Full, ArtifactTypeFilter.forbid(Set("src", "doc")))
|
||||
}
|
||||
|
||||
|
|
@ -84,7 +92,7 @@ trait BaseIvySpecification extends UnitSpec {
|
|||
ivyFile = None,
|
||||
resolverName = resolver.name,
|
||||
artifacts = artifacts,
|
||||
checksums = Seq(),
|
||||
checksums = Vector.empty,
|
||||
logging = UpdateLogging.Full,
|
||||
overwrite = true
|
||||
)
|
||||
|
|
|
|||
|
|
@ -9,12 +9,12 @@ class CachedResolutionSpec extends BaseIvySpecification {
|
|||
"Resolving the same module twice" should "work" in {
|
||||
cleanIvyCache()
|
||||
val m = module(
|
||||
ModuleID("com.example", "foo", "0.1.0", Some("compile")),
|
||||
Seq(commonsIo13), Some("2.10.2"), UpdateOptions().withCachedResolution(true)
|
||||
ModuleID("com.example", "foo", "0.1.0").withConfigurations(Some("compile")),
|
||||
Vector(commonsIo13), Some("2.10.2"), UpdateOptions().withCachedResolution(true)
|
||||
)
|
||||
val report = ivyUpdate(m)
|
||||
cleanCachedResolutionCache(m)
|
||||
val report2 = ivyUpdate(m)
|
||||
val _ = ivyUpdate(m)
|
||||
// first resolution creates the minigraph
|
||||
println(report)
|
||||
// second resolution reads from the minigraph
|
||||
|
|
@ -25,8 +25,8 @@ class CachedResolutionSpec extends BaseIvySpecification {
|
|||
"Resolving the unsolvable module should" should "not work" in {
|
||||
// log.setLevel(Level.Debug)
|
||||
val m = module(
|
||||
ModuleID("com.example", "foo", "0.2.0", Some("compile")),
|
||||
Seq(mavenCayennePlugin302), Some("2.10.2"), UpdateOptions().withCachedResolution(true)
|
||||
ModuleID("com.example", "foo", "0.2.0").withConfigurations(Some("compile")),
|
||||
Vector(mavenCayennePlugin302), Some("2.10.2"), UpdateOptions().withCachedResolution(true)
|
||||
)
|
||||
ivyUpdateEither(m) match {
|
||||
case Right(_) => sys.error("this should've failed")
|
||||
|
|
@ -52,12 +52,12 @@ class CachedResolutionSpec extends BaseIvySpecification {
|
|||
// log.setLevel(Level.Debug)
|
||||
cleanIvyCache()
|
||||
val m = module(
|
||||
ModuleID("com.example", "foo", "0.3.0", Some("compile")),
|
||||
Seq(avro177, dataAvro1940, netty320),
|
||||
ModuleID("com.example", "foo", "0.3.0").withConfigurations(Some("compile")),
|
||||
Vector(avro177, dataAvro1940, netty320),
|
||||
Some("2.10.2"), UpdateOptions().withCachedResolution(true)
|
||||
)
|
||||
// first resolution creates the minigraph
|
||||
val report0 = ivyUpdate(m)
|
||||
val _ = ivyUpdate(m)
|
||||
cleanCachedResolutionCache(m)
|
||||
// second resolution reads from the minigraph
|
||||
val report = ivyUpdate(m)
|
||||
|
|
@ -66,11 +66,11 @@ class CachedResolutionSpec extends BaseIvySpecification {
|
|||
assert(!(modules exists { x: String => x contains """org.jboss.netty:netty:3.2.1.Final""" }))
|
||||
}
|
||||
|
||||
def commonsIo13 = ModuleID("commons-io", "commons-io", "1.3", Some("compile"))
|
||||
def mavenCayennePlugin302 = ModuleID("org.apache.cayenne.plugins", "maven-cayenne-plugin", "3.0.2", Some("compile"))
|
||||
def avro177 = ModuleID("org.apache.avro", "avro", "1.7.7", Some("compile"))
|
||||
def dataAvro1940 = ModuleID("com.linkedin.pegasus", "data-avro", "1.9.40", Some("compile"))
|
||||
def netty320 = ModuleID("org.jboss.netty", "netty", "3.2.0.Final", Some("compile"))
|
||||
def commonsIo13 = ModuleID("commons-io", "commons-io", "1.3").withConfigurations(Some("compile"))
|
||||
def mavenCayennePlugin302 = ModuleID("org.apache.cayenne.plugins", "maven-cayenne-plugin", "3.0.2").withConfigurations(Some("compile"))
|
||||
def avro177 = ModuleID("org.apache.avro", "avro", "1.7.7").withConfigurations(Some("compile"))
|
||||
def dataAvro1940 = ModuleID("com.linkedin.pegasus", "data-avro", "1.9.40").withConfigurations(Some("compile"))
|
||||
def netty320 = ModuleID("org.jboss.netty", "netty", "3.2.0.Final").withConfigurations(Some("compile"))
|
||||
|
||||
def defaultOptions = EvictionWarningOptions.default
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,12 +2,11 @@ package sbt.internal.librarymanagement
|
|||
|
||||
import java.io.File
|
||||
import java.util.concurrent.Callable
|
||||
import sbt.io.IO.{ createDirectory, delete, touch, withTemporaryDirectory }
|
||||
import sbt.io.IO.withTemporaryDirectory
|
||||
import sbt.io.IO
|
||||
import org.apache.ivy.util.ChecksumHelper
|
||||
import IfMissing.Fail
|
||||
import xsbti.ComponentProvider
|
||||
import sbt.util.Logger
|
||||
|
||||
// TODO - We need to re-enable this test. Right now, we dont' have a "stub" launcher for this.
|
||||
// This is testing something which uses a launcher interface, but was grabbing the underlying class directly
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
package sbt.librarymanagement
|
||||
|
||||
import java.io.File
|
||||
import sbt.internal.util.UnitSpec
|
||||
|
||||
class CrossVersionTest extends UnitSpec {
|
||||
|
|
@ -116,7 +115,7 @@ class CrossVersionTest extends UnitSpec {
|
|||
CrossVersion.binaryScalaVersion("2.10.1") shouldBe "2.10"
|
||||
}
|
||||
it should "return disabled cross version as equal to a copy" in {
|
||||
CrossVersion.Disabled shouldBe CrossVersion.Disabled
|
||||
Disabled() shouldBe Disabled()
|
||||
}
|
||||
it should "return full cross version as equal to a copy" in {
|
||||
CrossVersion.full shouldBe CrossVersion.full
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@ import org.apache.ivy.core.module.id.ModuleRevisionId
|
|||
import org.apache.ivy.core.resolve.ResolveOptions
|
||||
import sbt.librarymanagement._
|
||||
import sbt.io.IO.withTemporaryDirectory
|
||||
import sbt.util.Logger
|
||||
import sbt.internal.util.ConsoleLogger
|
||||
|
||||
class CustomPomParserTest extends UnitSpec {
|
||||
|
|
@ -16,8 +15,8 @@ class CustomPomParserTest extends UnitSpec {
|
|||
val repoUrl = getClass.getResource("/test-maven-repo")
|
||||
val local = MavenRepository("Test Repo", repoUrl.toExternalForm)
|
||||
val paths = new IvyPaths(new File("."), Some(cacheDir))
|
||||
val conf = new InlineIvyConfiguration(paths, Seq(local), Nil, Nil, false, None, Seq("sha1", "md5"), None, UpdateOptions(), log)
|
||||
val ivySbt = new IvySbt(conf)
|
||||
val conf = new InlineIvyConfiguration(paths, Vector(local), Vector.empty, Vector.empty, false, None, Vector("sha1", "md5"), None, UpdateOptions(), log)
|
||||
val ivySbt = new IvySbt(conf, DefaultFileToStore)
|
||||
val resolveOpts = new ResolveOptions().setConfs(Array("default"))
|
||||
val mrid = ModuleRevisionId.newInstance("com.test", "test-artifact", "1.0.0-SNAPSHOT")
|
||||
|
||||
|
|
|
|||
|
|
@ -2,8 +2,12 @@ package sbt.librarymanagement
|
|||
|
||||
import java.net.URL
|
||||
import java.io.File
|
||||
import sbt.serialization._
|
||||
import sbt.internal.util.UnitSpec
|
||||
|
||||
import sbt.internal._, librarymanagement._, util.UnitSpec
|
||||
import scala.json.ast.unsafe._
|
||||
import sjsonnew._, support.scalajson.unsafe._
|
||||
|
||||
import LibraryManagementCodec._
|
||||
|
||||
class DMSerializationSpec extends UnitSpec {
|
||||
"CrossVersion.full" should "roundtrip" in {
|
||||
|
|
@ -13,7 +17,7 @@ class DMSerializationSpec extends UnitSpec {
|
|||
roundtripStr(CrossVersion.binary: CrossVersion)
|
||||
}
|
||||
"CrossVersion.Disabled" should "roundtrip" in {
|
||||
roundtrip(CrossVersion.Disabled: CrossVersion)
|
||||
roundtrip(Disabled(): CrossVersion)
|
||||
}
|
||||
"""Artifact("foo")""" should "roundtrip" in {
|
||||
roundtrip(Artifact("foo"))
|
||||
|
|
@ -34,7 +38,7 @@ class DMSerializationSpec extends UnitSpec {
|
|||
roundtrip(ModuleID("org", "name", "1.0"))
|
||||
}
|
||||
"""ModuleReport(ModuleID("org", "name", "1.0"), Nil, Nil)""" should "roundtrip" in {
|
||||
roundtripStr(ModuleReport(ModuleID("org", "name", "1.0"), Nil, Nil))
|
||||
roundtripStr(ModuleReport(ModuleID("org", "name", "1.0"), Vector.empty, Vector.empty))
|
||||
}
|
||||
"Organization artifact report" should "roundtrip" in {
|
||||
roundtripStr(organizationArtifactReportExample)
|
||||
|
|
@ -55,17 +59,19 @@ class DMSerializationSpec extends UnitSpec {
|
|||
lazy val organizationArtifactReportExample =
|
||||
new OrganizationArtifactReport("org", "name", Vector(moduleReportExample))
|
||||
lazy val moduleReportExample =
|
||||
ModuleReport(ModuleID("org", "name", "1.0"), Nil, Nil)
|
||||
ModuleReport(ModuleID("org", "name", "1.0"), Vector.empty, Vector.empty)
|
||||
|
||||
def roundtrip[A: Pickler: Unpickler](a: A): Unit =
|
||||
def roundtrip[A: JsonReader: JsonWriter](a: A): Unit =
|
||||
roundtripBuilder(a) { _ shouldBe _ }
|
||||
def roundtripStr[A: Pickler: Unpickler](a: A): Unit =
|
||||
def roundtripStr[A: JsonReader: JsonWriter](a: A): Unit =
|
||||
roundtripBuilder(a) { _.toString shouldBe _.toString }
|
||||
def roundtripBuilder[A: Pickler: Unpickler](a: A)(f: (A, A) => Unit): Unit =
|
||||
def roundtripBuilder[A: JsonReader: JsonWriter](a: A)(f: (A, A) => Unit): Unit =
|
||||
{
|
||||
val json = toJsonString(a)
|
||||
val json = isoString to (Converter toJsonUnsafe a)
|
||||
println(json)
|
||||
val obj = fromJsonString[A](json).get
|
||||
val obj = Converter fromJsonUnsafe[A] (isoString from json)
|
||||
f(a, obj)
|
||||
}
|
||||
|
||||
implicit val isoString: IsoString[JValue] = IsoString.iso(CompactPrinter.apply, FixedParser.parseUnsafe)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -44,25 +44,25 @@ class EvictionWarningSpec extends BaseIvySpecification {
|
|||
it should "be detected if it's enabled" in scalaLibTransitiveWarn2()
|
||||
it should "print out message about the eviction if it's enabled" in scalaLibTransitiveWarn3()
|
||||
|
||||
def akkaActor214 = ModuleID("com.typesafe.akka", "akka-actor", "2.1.4", Some("compile")) cross CrossVersion.binary
|
||||
def akkaActor230 = ModuleID("com.typesafe.akka", "akka-actor", "2.3.0", Some("compile")) cross CrossVersion.binary
|
||||
def akkaActor234 = ModuleID("com.typesafe.akka", "akka-actor", "2.3.4", Some("compile")) cross CrossVersion.binary
|
||||
def scala2102 = ModuleID("org.scala-lang", "scala-library", "2.10.2", Some("compile"))
|
||||
def scala2103 = ModuleID("org.scala-lang", "scala-library", "2.10.3", Some("compile"))
|
||||
def scala2104 = ModuleID("org.scala-lang", "scala-library", "2.10.4", Some("compile"))
|
||||
def commonsIo13 = ModuleID("commons-io", "commons-io", "1.3", Some("compile"))
|
||||
def commonsIo14 = ModuleID("commons-io", "commons-io", "1.4", Some("compile"))
|
||||
def commonsIo24 = ModuleID("commons-io", "commons-io", "2.4", Some("compile"))
|
||||
def bnfparser10 = ModuleID("ca.gobits.bnf", "bnfparser", "1.0", Some("compile")) // uses commons-io 2.4
|
||||
def unfilteredUploads080 = ModuleID("net.databinder", "unfiltered-uploads", "0.8.0", Some("compile")) cross CrossVersion.binary // uses commons-io 1.4
|
||||
def bananaSesame04 = ModuleID("org.w3", "banana-sesame", "0.4", Some("compile")) cross CrossVersion.binary // uses akka-actor 2.1.4
|
||||
def akkaRemote234 = ModuleID("com.typesafe.akka", "akka-remote", "2.3.4", Some("compile")) cross CrossVersion.binary // uses akka-actor 2.3.4
|
||||
def akkaActor214 = ModuleID("com.typesafe.akka", "akka-actor", "2.1.4").withConfigurations(Some("compile")) cross CrossVersion.binary
|
||||
def akkaActor230 = ModuleID("com.typesafe.akka", "akka-actor", "2.3.0").withConfigurations(Some("compile")) cross CrossVersion.binary
|
||||
def akkaActor234 = ModuleID("com.typesafe.akka", "akka-actor", "2.3.4").withConfigurations(Some("compile")) cross CrossVersion.binary
|
||||
def scala2102 = ModuleID("org.scala-lang", "scala-library", "2.10.2").withConfigurations(Some("compile"))
|
||||
def scala2103 = ModuleID("org.scala-lang", "scala-library", "2.10.3").withConfigurations(Some("compile"))
|
||||
def scala2104 = ModuleID("org.scala-lang", "scala-library", "2.10.4").withConfigurations(Some("compile"))
|
||||
def commonsIo13 = ModuleID("commons-io", "commons-io", "1.3").withConfigurations(Some("compile"))
|
||||
def commonsIo14 = ModuleID("commons-io", "commons-io", "1.4").withConfigurations(Some("compile"))
|
||||
def commonsIo24 = ModuleID("commons-io", "commons-io", "2.4").withConfigurations(Some("compile"))
|
||||
def bnfparser10 = ModuleID("ca.gobits.bnf", "bnfparser", "1.0").withConfigurations(Some("compile")) // uses commons-io 2.4
|
||||
def unfilteredUploads080 = ModuleID("net.databinder", "unfiltered-uploads", "0.8.0").withConfigurations(Some("compile")) cross CrossVersion.binary // uses commons-io 1.4
|
||||
def bananaSesame04 = ModuleID("org.w3", "banana-sesame", "0.4").withConfigurations(Some("compile")) cross CrossVersion.binary // uses akka-actor 2.1.4
|
||||
def akkaRemote234 = ModuleID("com.typesafe.akka", "akka-remote", "2.3.4").withConfigurations(Some("compile")) cross CrossVersion.binary // uses akka-actor 2.3.4
|
||||
|
||||
def defaultOptions = EvictionWarningOptions.default
|
||||
|
||||
import sbt.internal.util.ShowLines._
|
||||
|
||||
def scalaVersionDeps = Seq(scala2102, akkaActor230)
|
||||
def scalaVersionDeps = Vector(scala2102, akkaActor230)
|
||||
|
||||
def scalaVersionWarn1() = {
|
||||
val m = module(defaultModuleId, scalaVersionDeps, Some("2.10.2"), overrideScalaVersion = false)
|
||||
|
|
@ -113,7 +113,7 @@ class EvictionWarningSpec extends BaseIvySpecification {
|
|||
EvictionWarning(m, defaultOptions.withWarnScalaVersionEviction(false), report, log).scalaEvictions should have size (0)
|
||||
}
|
||||
|
||||
def javaLibDirectDeps = Seq(commonsIo14, commonsIo24)
|
||||
def javaLibDirectDeps = Vector(commonsIo14, commonsIo24)
|
||||
|
||||
def javaLibWarn1() = {
|
||||
val m = module(defaultModuleId, javaLibDirectDeps, Some("2.10.3"))
|
||||
|
|
@ -151,20 +151,20 @@ class EvictionWarningSpec extends BaseIvySpecification {
|
|||
}
|
||||
|
||||
def javaLibNoWarn1() = {
|
||||
val deps = Seq(commonsIo14, commonsIo13)
|
||||
val deps = Vector(commonsIo14, commonsIo13)
|
||||
val m = module(defaultModuleId, deps, Some("2.10.3"))
|
||||
val report = ivyUpdate(m)
|
||||
EvictionWarning(m, defaultOptions, report, log).reportedEvictions should have size (0)
|
||||
}
|
||||
|
||||
def javaLibNoWarn2() = {
|
||||
val deps = Seq(commonsIo14, commonsIo13)
|
||||
val deps = Vector(commonsIo14, commonsIo13)
|
||||
val m = module(defaultModuleId, deps, Some("2.10.3"))
|
||||
val report = ivyUpdate(m)
|
||||
EvictionWarning(m, defaultOptions, report, log).lines shouldBe Nil
|
||||
}
|
||||
|
||||
def javaLibTransitiveDeps = Seq(unfilteredUploads080, bnfparser10)
|
||||
def javaLibTransitiveDeps = Vector(unfilteredUploads080, bnfparser10)
|
||||
|
||||
def javaLibTransitiveWarn1() = {
|
||||
val m = module(defaultModuleId, javaLibTransitiveDeps, Some("2.10.3"))
|
||||
|
|
@ -190,14 +190,14 @@ class EvictionWarningSpec extends BaseIvySpecification {
|
|||
}
|
||||
|
||||
def scalaLibWarn1() = {
|
||||
val deps = Seq(scala2104, akkaActor214, akkaActor234)
|
||||
val deps = Vector(scala2104, akkaActor214, akkaActor234)
|
||||
val m = module(defaultModuleId, deps, Some("2.10.4"))
|
||||
val report = ivyUpdate(m)
|
||||
EvictionWarning(m, defaultOptions, report, log).reportedEvictions should have size (1)
|
||||
}
|
||||
|
||||
def scalaLibWarn2() = {
|
||||
val deps = Seq(scala2104, akkaActor214, akkaActor234)
|
||||
val deps = Vector(scala2104, akkaActor214, akkaActor234)
|
||||
val m = module(defaultModuleId, deps, Some("2.10.4"))
|
||||
val report = ivyUpdate(m)
|
||||
EvictionWarning(m, defaultOptions, report, log).lines shouldBe
|
||||
|
|
@ -210,20 +210,20 @@ class EvictionWarningSpec extends BaseIvySpecification {
|
|||
}
|
||||
|
||||
def scalaLibNoWarn1() = {
|
||||
val deps = Seq(scala2104, akkaActor230, akkaActor234)
|
||||
val deps = Vector(scala2104, akkaActor230, akkaActor234)
|
||||
val m = module(defaultModuleId, deps, Some("2.10.4"))
|
||||
val report = ivyUpdate(m)
|
||||
EvictionWarning(m, defaultOptions, report, log).reportedEvictions should have size (0)
|
||||
}
|
||||
|
||||
def scalaLibNoWarn2() = {
|
||||
val deps = Seq(scala2104, akkaActor230, akkaActor234)
|
||||
val deps = Vector(scala2104, akkaActor230, akkaActor234)
|
||||
val m = module(defaultModuleId, deps, Some("2.10.4"))
|
||||
val report = ivyUpdate(m)
|
||||
EvictionWarning(m, defaultOptions, report, log).lines shouldBe Nil
|
||||
}
|
||||
|
||||
def scalaLibTransitiveDeps = Seq(scala2104, bananaSesame04, akkaRemote234)
|
||||
def scalaLibTransitiveDeps = Vector(scala2104, bananaSesame04, akkaRemote234)
|
||||
|
||||
def scalaLibTransitiveWarn1() = {
|
||||
val m = module(defaultModuleId, scalaLibTransitiveDeps, Some("2.10.4"))
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ class InconsistentDuplicateSpec extends UnitSpec {
|
|||
IvySbt.inconsistentDuplicateWarning(Seq(akkaActor230Test, akkaActor230)) shouldBe Nil
|
||||
}
|
||||
|
||||
def akkaActor214 = ModuleID("com.typesafe.akka", "akka-actor", "2.1.4", Some("compile")) cross CrossVersion.binary
|
||||
def akkaActor230 = ModuleID("com.typesafe.akka", "akka-actor", "2.3.0", Some("compile")) cross CrossVersion.binary
|
||||
def akkaActor230Test = ModuleID("com.typesafe.akka", "akka-actor", "2.3.0", Some("test")) cross CrossVersion.binary
|
||||
def akkaActor214 = ModuleID("com.typesafe.akka", "akka-actor", "2.1.4").withConfigurations(Some("compile")) cross CrossVersion.binary
|
||||
def akkaActor230 = ModuleID("com.typesafe.akka", "akka-actor", "2.3.0").withConfigurations(Some("compile")) cross CrossVersion.binary
|
||||
def akkaActor230Test = ModuleID("com.typesafe.akka", "akka-actor", "2.3.0").withConfigurations(Some("test")) cross CrossVersion.binary
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
package sbt.internal.librarymanagement
|
||||
|
||||
import java.io.File
|
||||
import sbt.util.Logger
|
||||
import sbt.internal.util.ConsoleLogger
|
||||
|
||||
// http://ant.apache.org/ivy/history/2.3.0/ivyfile/dependency.html
|
||||
|
|
|
|||
|
|
@ -2,14 +2,13 @@ package sbt.librarymanagement
|
|||
|
||||
import java.net.URL
|
||||
|
||||
import sbt._
|
||||
import sbt.internal.util.UnitSpec
|
||||
|
||||
object ResolverTest extends UnitSpec {
|
||||
|
||||
"Resolver url" should "propagate pattern descriptorOptional and skipConsistencyCheck." in {
|
||||
val pats = Seq("[orgPath]")
|
||||
val patsExpected = Seq("http://foo.com/test/[orgPath]")
|
||||
val pats = Vector("[orgPath]")
|
||||
val patsExpected = Vector("http://foo.com/test/[orgPath]")
|
||||
val patterns = Resolver.url("test", new URL("http://foo.com/test"))(Patterns(pats, pats, isMavenCompatible = false, descriptorOptional = true, skipConsistencyCheck = true)).patterns
|
||||
|
||||
patterns.ivyPatterns shouldBe patsExpected
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
package sbt.librarymanagement
|
||||
|
||||
import org.apache.ivy.core.module.id.{ ModuleId, ModuleRevisionId }
|
||||
import org.apache.ivy.core.module.id.ModuleRevisionId
|
||||
import org.apache.ivy.core.module.descriptor.DefaultDependencyDescriptor
|
||||
|
||||
import sbt.internal.util.UnitSpec
|
||||
|
|
|
|||
|
|
@ -9,10 +9,10 @@ import sbt.librarymanagement.{ ModuleID, RawRepository, Resolver, UpdateReport }
|
|||
class FakeResolverSpecification extends BaseIvySpecification {
|
||||
import FakeResolver._
|
||||
|
||||
val myModule = ModuleID("org.example", "my-module", "0.0.1-SNAPSHOT", Some("compile"))
|
||||
val example = ModuleID("com.example", "example", "1.0.0", Some("compile"))
|
||||
val anotherExample = ModuleID("com.example", "another-example", "1.0.0", Some("compile"))
|
||||
val nonExisting = ModuleID("com.example", "does-not-exist", "1.2.3", Some("compile"))
|
||||
val myModule = ModuleID("org.example", "my-module", "0.0.1-SNAPSHOT").withConfigurations(Some("compile"))
|
||||
val example = ModuleID("com.example", "example", "1.0.0").withConfigurations(Some("compile"))
|
||||
val anotherExample = ModuleID("com.example", "another-example", "1.0.0").withConfigurations(Some("compile"))
|
||||
val nonExisting = ModuleID("com.example", "does-not-exist", "1.2.3").withConfigurations(Some("compile"))
|
||||
|
||||
"The FakeResolver" should "find modules with only one artifact" in {
|
||||
val m = getModule(myModule)
|
||||
|
|
@ -66,8 +66,8 @@ class FakeResolverSpecification extends BaseIvySpecification {
|
|||
)
|
||||
|
||||
private def fakeResolver = new FakeResolver("FakeResolver", new File("tmp"), modules)
|
||||
override def resolvers: Seq[Resolver] = Seq(new RawRepository(fakeResolver))
|
||||
private def getModule(myModule: ModuleID): IvySbt#Module = module(defaultModuleId, Seq(myModule), None)
|
||||
override def resolvers: Vector[Resolver] = Vector(new RawRepository(fakeResolver))
|
||||
private def getModule(myModule: ModuleID): IvySbt#Module = module(defaultModuleId, Vector(myModule), None)
|
||||
private def getAllFiles(report: UpdateReport) =
|
||||
for {
|
||||
conf <- report.configurations
|
||||
|
|
@ -75,4 +75,4 @@ class FakeResolverSpecification extends BaseIvySpecification {
|
|||
(_, f) <- m.artifacts
|
||||
} yield f
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import sbt.librarymanagement._
|
|||
|
||||
class IvyRepoSpec extends BaseIvySpecification with DependencyBuilders {
|
||||
|
||||
val ourModuleID = ModuleID("com.example", "foo", "0.1.0", Some("compile"))
|
||||
val ourModuleID = ModuleID("com.example", "foo", "0.1.0").withConfigurations(Some("compile"))
|
||||
|
||||
def makeModuleForDepWithSources = {
|
||||
// By default a module seems to only have [compile, test, runtime], yet deps automatically map to
|
||||
|
|
@ -15,7 +15,7 @@ class IvyRepoSpec extends BaseIvySpecification with DependencyBuilders {
|
|||
|
||||
module(
|
||||
ourModuleID,
|
||||
Seq(dep), None //, UpdateOptions().withCachedResolution(true)
|
||||
Vector(dep), None //, UpdateOptions().withCachedResolution(true)
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -50,21 +50,19 @@ class IvyRepoSpec extends BaseIvySpecification with DependencyBuilders {
|
|||
val docTypes = Set("javadoc")
|
||||
// These will be the default classifiers that SBT should try, in case a dependency is Maven.
|
||||
// In this case though, they will be tried and should fail gracefully - only the
|
||||
val attemptedClassifiers = Seq("sources", "javadoc")
|
||||
val attemptedClassifiers = Vector("sources", "javadoc")
|
||||
|
||||
// The dep that we want to get the "classifiers" (i.e. sources / docs) for.
|
||||
// We know it has only one source artifact in the "compile" configuration.
|
||||
val dep = "com.test" % "module-with-srcs" % "0.1.00" % "compile"
|
||||
|
||||
val clMod = {
|
||||
import language.implicitConversions
|
||||
implicit val key = (m: ModuleID) => (m.organization, m.name, m.revision)
|
||||
val externalModules = Seq(dep)
|
||||
val externalModules = Vector(dep)
|
||||
// Note: need to extract ourModuleID so we can plug it in here, can't fish it back out of the IvySbt#Module (`m`)
|
||||
GetClassifiersModule(ourModuleID, externalModules, Seq(Configurations.Compile), attemptedClassifiers)
|
||||
GetClassifiersModule(ourModuleID, externalModules, Vector(Configurations.Compile), attemptedClassifiers)
|
||||
}
|
||||
|
||||
val gcm = GetClassifiersConfiguration(clMod, Map.empty, c.copy(artifactFilter = c.artifactFilter.invert), ivyScala, srcTypes, docTypes)
|
||||
val gcm = GetClassifiersConfiguration(clMod, Map.empty, c.withArtifactFilter(c.artifactFilter.invert), ivyScala, srcTypes, docTypes)
|
||||
|
||||
val report2 = IvyActions.updateClassifiers(m.owner, gcm, UnresolvedWarningConfiguration(), LogicalClock.unknown, None, Vector(), log)
|
||||
|
||||
|
|
@ -80,7 +78,7 @@ class IvyRepoSpec extends BaseIvySpecification with DependencyBuilders {
|
|||
}
|
||||
}
|
||||
|
||||
override lazy val resolvers: Seq[Resolver] = Seq(testIvy)
|
||||
override lazy val resolvers: Vector[Resolver] = Vector(testIvy)
|
||||
|
||||
lazy val testIvy = {
|
||||
val repoUrl = getClass.getResource("/test-ivy-repo")
|
||||
|
|
|
|||
|
|
@ -0,0 +1,58 @@
|
|||
import sbt.datatype.{ CodecCodeGen, TpeRef }
|
||||
|
||||
object DatatypeConfig {
|
||||
|
||||
/** Extract the only type parameter from a TpeRef */
|
||||
def oneArg(tpe: TpeRef): TpeRef = {
|
||||
val pat = s"""${CodecCodeGen.removeTypeParameters(tpe.name)}[<\\[](.+?)[>\\]]""".r
|
||||
val pat(arg0) = tpe.name
|
||||
TpeRef(arg0, false, false, false)
|
||||
}
|
||||
|
||||
/** Extract the two type parameters from a TpeRef */
|
||||
def twoArgs(tpe: TpeRef): List[TpeRef] = {
|
||||
val pat = s"""${CodecCodeGen.removeTypeParameters(tpe.name)}[<\\[](.+?), (.+?)[>\\]]""".r
|
||||
val pat(arg0, arg1) = tpe.name
|
||||
TpeRef(arg0, false, false, false) :: TpeRef(arg1, false, false, false) :: Nil
|
||||
}
|
||||
|
||||
/** Codecs that were manually written. */
|
||||
val myCodecs: PartialFunction[String, TpeRef => List[String]] = {
|
||||
case "java.util.Date" => { _ => "sbt.internal.librarymanagement.formats.DateFormat" :: Nil }
|
||||
|
||||
case "scala.xml.NodeSeq" => { _ => "sbt.internal.librarymanagement.formats.NodeSeqFormat" :: Nil }
|
||||
|
||||
case "org.apache.ivy.plugins.resolver.DependencyResolver" =>
|
||||
{ _ => "sbt.internal.librarymanagement.formats.DependencyResolverFormat" :: Nil }
|
||||
|
||||
case "xsbti.GlobalLock" => { _ => "sbt.internal.librarymanagement.formats.GlobalLockFormat" :: Nil }
|
||||
case "xsbti.Logger" => { _ => "sbt.internal.librarymanagement.formats.LoggerFormat" :: Nil }
|
||||
|
||||
case "sbt.librarymanagement.UpdateOptions" =>
|
||||
{ _ => "sbt.internal.librarymanagement.formats.UpdateOptionsFormat" :: Nil }
|
||||
|
||||
// TODO: These are handled by BasicJsonProtocol, and sbt-datatype should handle them by default, imo
|
||||
case "Option" | "Set" => { tpe => getFormats(oneArg(tpe)) }
|
||||
case "Map" | "Tuple2" | "scala.Tuple2" => { tpe => twoArgs(tpe).flatMap(getFormats) }
|
||||
case "Int" | "Long" => { _ => Nil }
|
||||
}
|
||||
|
||||
/** Types for which we don't include the format -- they're just aliases to InclExclRule */
|
||||
val excluded = Set(
|
||||
"sbt.librarymanagement.InclusionRule",
|
||||
"sbt.librarymanagement.ExclusionRule")
|
||||
|
||||
/** Returns the list of formats required to encode the given `TpeRef`. */
|
||||
val getFormats: TpeRef => List[String] =
|
||||
CodecCodeGen.extensibleFormatsForType {
|
||||
case TpeRef("sbt.internal.librarymanagement.RetrieveConfiguration", false, false, false) =>
|
||||
"sbt.librarymanagement.RetrieveConfigurationFormats" :: Nil
|
||||
case tpe @ TpeRef(name, _, _, _) if myCodecs isDefinedAt CodecCodeGen.removeTypeParameters(name) =>
|
||||
myCodecs(CodecCodeGen.removeTypeParameters(name))(tpe)
|
||||
case TpeRef(name, _, _, _) if excluded contains CodecCodeGen.removeTypeParameters(name) =>
|
||||
Nil
|
||||
case other =>
|
||||
CodecCodeGen.formatsForType(other)
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -5,7 +5,7 @@ object Dependencies {
|
|||
lazy val scala211 = "2.11.8"
|
||||
|
||||
val ioVersion = "1.0.0-M6"
|
||||
val utilVersion = "0.1.0-M13"
|
||||
val utilVersion = "0.1.0-M15"
|
||||
|
||||
private lazy val sbtIO = "org.scala-sbt" %% "io" % ioVersion
|
||||
|
||||
|
|
@ -43,6 +43,16 @@ object Dependencies {
|
|||
lazy val launcherInterface = "org.scala-sbt" % "launcher-interface" % "1.0.0"
|
||||
lazy val ivy = "org.scala-sbt.ivy" % "ivy" % "2.3.0-sbt-2cc8d2761242b072cedb0a04cb39435c4fa24f9a"
|
||||
lazy val jsch = "com.jcraft" % "jsch" % "0.1.46" intransitive ()
|
||||
lazy val sbtSerialization = "org.scala-sbt" %% "serialization" % "0.1.2"
|
||||
lazy val scalaReflect = Def.setting { "org.scala-lang" % "scala-reflect" % scalaVersion.value }
|
||||
lazy val scalaXml = scala211Module("scala-xml", "1.0.5")
|
||||
lazy val sjsonnewVersion = "0.4.1"
|
||||
lazy val sjsonnewScalaJson = "com.eed3si9n" %% "sjson-new-scalajson" % sjsonnewVersion
|
||||
|
||||
private def scala211Module(name: String, moduleVersion: String) =
|
||||
Def.setting {
|
||||
scalaVersion.value match {
|
||||
case sv if (sv startsWith "2.9.") || (sv startsWith "2.10.") => Nil
|
||||
case _ => ("org.scala-lang.modules" %% name % moduleVersion) :: Nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
sbt.version=0.13.9
|
||||
sbt.version=0.13.13
|
||||
|
|
|
|||
|
|
@ -0,0 +1 @@
|
|||
addSbtPlugin("org.scala-sbt" % "sbt-datatype" % "0.2.8")
|
||||
Loading…
Reference in New Issue