diff --git a/build.sbt b/build.sbt
index 0f38b6bde..9f0c79fb4 100644
--- a/build.sbt
+++ b/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 =>
diff --git a/librarymanagement/src/main/datatype/librarymanagement.json b/librarymanagement/src/main/datatype/librarymanagement.json
new file mode 100644
index 000000000..102b22748
--- /dev/null
+++ b/librarymanagement/src/main/datatype/librarymanagement.json
@@ -0,0 +1,780 @@
+{
+ "codecNamespace": "sbt.librarymanagement",
+ "fullCodec": "LibraryManagementCodec",
+ "types": [
+ {
+ "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": "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.ModuleReportParent",
+ "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": "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": "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": "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": "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": "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": "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": "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": "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": "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": "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.ConflictManagerCompanion"
+ },
+ {
+ "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.IvyScalaCompanion"
+ },
+ {
+ "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.InlineConfigurationCompanion"
+ }
+ ]
+ },
+ {
+ "name": "IvyPaths",
+ "namespace": "sbt.internal.librarymanagement",
+ "target": "Scala",
+ "type": "record",
+ "fields": [
+ { "name": "baseDirectory", "type": "java.io.File" },
+ { "name": "ivyHome", "type": "java.io.File?" }
+ ]
+ },
+ {
+ "name": "InclExclRule",
+ "namespace": "sbt.librarymanagement",
+ "target": "Scala",
+ "type": "record",
+ "doc": [
+ "Rule to either:",
+ "
",
+ "- exclude unwanted dependencies pulled in transitively by a module, or to
",
+ "- include and merge artifacts coming from the ModuleDescriptor if \"dependencyArtifacts\" are also provided.
",
+ "
",
+ "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.InclExclRuleCompanion"
+ },
+ {
+ "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",
+ "fields": [
+ { "name": "remapVersion", "type": "Function1[String, String]" }
+ ]
+ },
+ {
+ "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\"."
+ ],
+ "fields": [
+ { "name": "remapVersion", "type": "Function1[String, String]" }
+ ]
+ }
+ ],
+ "parentsCompanion": "sbt.librarymanagement.CrossVersionCompanion"
+ },
+ {
+ "name": "Configuration",
+ "namespace": "sbt.librarymanagement",
+ "target": "Scala",
+ "type": "record",
+ "doc": "Represents an Ivy configuration.",
+ "parents": "sbt.librarymanagement.ConfigurationParent",
+ "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": "Artifact",
+ "namespace": "sbt.librarymanagement",
+ "target": "Scala",
+ "type": "record",
+ "parents": "sbt.librarymanagement.ArtifactParent",
+ "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.ArtifactCompanion"
+ },
+ {
+ "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": "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": "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.PatternsCompanion"
+ },
+ {
+ "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.ResolverCompanion"
+ },
+ {
+ "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": "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": "UpdateReportLite",
+ "namespace": "sbt.internal.librarymanagement",
+ "target": "Scala",
+ "type": "record",
+ "fields": [
+ { "name": "configurations", "type": "sbt.internal.librarymanagement.ConfigurationReportLite*" }
+ ]
+ },
+ {
+ "name": "ConfigurationReportLite",
+ "namespace": "sbt.internal.librarymanagement",
+ "target": "Scala",
+ "type": "record",
+ "fields": [
+ { "name": "configuration", "type": "String" },
+ { "name": "details", "type": "sbt.librarymanagement.OrganizationArtifactReport*" }
+ ]
+ },
+ {
+ "name": "ModuleID",
+ "namespace": "sbt.librarymanagement",
+ "target": "Scala",
+ "type": "record",
+ "parents": "sbt.librarymanagement.ModuleIDParent",
+ "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.ModuleIDCompanion"
+ },
+ {
+ "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.ArtifactTypeFilterParent",
+ "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 `` 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.ArtifactTypeFilterCompanion"
+ },
+ {
+ "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.UpdateReportParent",
+ "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": "ConfigurationReport",
+ "namespace": "sbt.librarymanagement",
+ "target": "Scala",
+ "type": "record",
+ "doc": [
+ "Provides information about resolution of a single configuration."
+ ],
+ "parents": "sbt.librarymanagement.ConfigurationReportParent",
+ "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." ]
+ }
+ ]
+ }
+ ]
+}
diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ConvertResolver.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ConvertResolver.scala
index 1d0a6a470..a1d67b99c 100644
--- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ConvertResolver.scala
+++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ConvertResolver.scala
@@ -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 = {
diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/Ivy.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/Ivy.scala
index 29e8b0b42..320f549a0 100644
--- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/Ivy.scala
+++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/Ivy.scala
@@ -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
}
}
diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala
index d87001653..13a5d040b 100644
--- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala
+++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala
@@ -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
diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyCache.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyCache.scala
index ba3d97912..0c1c1f969 100644
--- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyCache.scala
+++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyCache.scala
@@ -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)
+}
diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyConfigurations.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyConfigurations.scala
index 7602f0de9..96cdf1585 100644
--- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyConfigurations.scala
+++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyConfigurations.scala
@@ -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 InlineConfigurationCompanion {
def configurations(explicitConfigurations: Iterable[Configuration], defaultConfiguration: Option[Configuration]) =
if (explicitConfigurations.isEmpty) {
defaultConfiguration match {
diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyRetrieve.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyRetrieve.scala
index b9917e1ad..6f0a7d42e 100644
--- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyRetrieve.scala
+++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyRetrieve.scala
@@ -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 =
diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/JsonUtil.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/JsonUtil.scala
index 69a6fa282..7be87317a 100644
--- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/JsonUtil.scala
+++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/JsonUtil.scala
@@ -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]
-}
diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/RichUpdateReport.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/RichUpdateReport.scala
index db283b6c7..8b9f82922 100644
--- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/RichUpdateReport.scala
+++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/RichUpdateReport.scala
@@ -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 =
diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/SbtExclusionRule.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/SbtExclusionRule.scala
deleted file mode 100644
index 76e74dcd4..000000000
--- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/SbtExclusionRule.scala
+++ /dev/null
@@ -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)
-}
diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/formats/DateFormat.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/formats/DateFormat.scala
new file mode 100644
index 000000000..337ff3bd8
--- /dev/null
+++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/formats/DateFormat.scala
@@ -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 _)
+}
diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/formats/DependencyResolverFormat.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/formats/DependencyResolverFormat.scala
new file mode 100644
index 000000000..3a8920373
--- /dev/null
+++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/formats/DependencyResolverFormat.scala
@@ -0,0 +1,12 @@
+package sbt.internal.librarymanagement.formats
+
+import sjsonnew._
+import org.apache.ivy.plugins.resolver.DependencyResolver
+
+trait DependencyResolverFormat { self: BasicJsonProtocol =>
+ implicit lazy val DependencyResolverFormat: JsonFormat[DependencyResolver] =
+ project(
+ MyCrazyReferences.referenced _,
+ (ref: String) => MyCrazyReferences(ref, classOf[DependencyResolver])
+ )
+}
diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/formats/Function1Format.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/formats/Function1Format.scala
new file mode 100644
index 000000000..12f4f2f94
--- /dev/null
+++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/formats/Function1Format.scala
@@ -0,0 +1,8 @@
+package sbt.internal.librarymanagement.formats
+
+import sjsonnew._
+
+trait Function1Format { self: BasicJsonProtocol =>
+ implicit def Function1Format[T, U]: JsonFormat[T => U] =
+ project(MyCrazyReferences.referenced _, (ref: String) => MyCrazyReferences(ref, classOf[T => U]))
+}
diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/formats/GlobalLockFormat.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/formats/GlobalLockFormat.scala
new file mode 100644
index 000000000..fda66ae6b
--- /dev/null
+++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/formats/GlobalLockFormat.scala
@@ -0,0 +1,9 @@
+package sbt.internal.librarymanagement.formats
+
+import sjsonnew._
+import xsbti._
+
+trait GlobalLockFormat { self: BasicJsonProtocol =>
+ implicit lazy val GlobalLockFormat: JsonFormat[GlobalLock] =
+ project(MyCrazyReferences.referenced _, (ref: String) => MyCrazyReferences(ref, classOf[GlobalLock]))
+}
diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/formats/LoggerFormat.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/formats/LoggerFormat.scala
new file mode 100644
index 000000000..5b84703d9
--- /dev/null
+++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/formats/LoggerFormat.scala
@@ -0,0 +1,9 @@
+package sbt.internal.librarymanagement.formats
+
+import sjsonnew._
+import xsbti._
+
+trait LoggerFormat { self: BasicJsonProtocol =>
+ implicit lazy val LoggerFormat: JsonFormat[Logger] =
+ project(MyCrazyReferences.referenced _, (ref: String) => MyCrazyReferences(ref, classOf[Logger]))
+}
diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/formats/MyCrazyReferences.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/formats/MyCrazyReferences.scala
new file mode 100644
index 000000000..7051e327e
--- /dev/null
+++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/formats/MyCrazyReferences.scala
@@ -0,0 +1,15 @@
+package sbt.internal.librarymanagement.formats
+
+import scala.collection.mutable
+
+object MyCrazyReferences {
+ private val references: mutable.Map[String, Any] = mutable.Map.empty
+
+ def apply[T](key: String, clazz: Class[T]): T = synchronized(clazz.cast(references(key)))
+
+ def referenced[T](value: T): String = synchronized {
+ val key = java.util.UUID.randomUUID.toString
+ references(key) = value
+ key
+ }
+}
diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/formats/NodeSeqFormat.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/formats/NodeSeqFormat.scala
new file mode 100644
index 000000000..df862fb61
--- /dev/null
+++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/formats/NodeSeqFormat.scala
@@ -0,0 +1,9 @@
+package sbt.internal.librarymanagement.formats
+
+import sjsonnew._
+import scala.xml._
+
+trait NodeSeqFormat { self: BasicJsonProtocol =>
+ implicit lazy val NodeSeqFormat: JsonFormat[NodeSeq] =
+ project(MyCrazyReferences.referenced _, (ref: String) => MyCrazyReferences(ref, classOf[NodeSeq]))
+}
diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/formats/UpdateOptionsFormat.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/formats/UpdateOptionsFormat.scala
new file mode 100644
index 000000000..e5e8b6e63
--- /dev/null
+++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/formats/UpdateOptionsFormat.scala
@@ -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
+ )
+}
diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/impl/DependencyBuilders.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/impl/DependencyBuilders.scala
index 9ceac2da6..6260f5ad6 100755
--- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/impl/DependencyBuilders.scala
+++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/impl/DependencyBuilders.scala
@@ -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) {
diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/CachedResolutionResolveEngine.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/CachedResolutionResolveEngine.scala
index ef9d20209..8c94be6f6 100644
--- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/CachedResolutionResolveEngine.scala
+++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/CachedResolutionResolveEngine.scala
@@ -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("(", ", ", ")"))
}
diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/Artifact.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/Artifact.scala
index fd9e33bef..7b843546a 100644
--- a/librarymanagement/src/main/scala/sbt/librarymanagement/Artifact.scala
+++ b/librarymanagement/src/main/scala/sbt/librarymanagement/Artifact.scala
@@ -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 ArtifactParent {
+ 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 ArtifactCompanion {
+ 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)
}
diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/Configuration.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/Configuration.scala
index f860d4abc..ad064f550 100644
--- a/librarymanagement/src/main/scala/sbt/librarymanagement/Configuration.scala
+++ b/librarymanagement/src/main/scala/sbt/librarymanagement/Configuration.scala
@@ -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 ConfigurationParent {
+ 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]
}
diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/CrossVersion.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/CrossVersion.scala
index d9869e030..88b15cf6a 100644
--- a/librarymanagement/src/main/scala/sbt/librarymanagement/CrossVersion.scala
+++ b/librarymanagement/src/main/scala/sbt/librarymanagement/CrossVersion.scala
@@ -1,89 +1,17 @@
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 CrossVersionCompanion {
/** 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)
@@ -114,9 +42,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 b: Binary => append(b.remapVersion(binaryVersion))
+ case f: Full => append(f.remapVersion(fullVersion))
}
/** Constructs the cross-version function defined by `module` and `is`, if one is configured. */
@@ -128,7 +56,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 +75,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 +94,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
}
diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/EvictionWarning.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/EvictionWarning.scala
index 2c93719ec..dde946c1f 100644
--- a/librarymanagement/src/main/scala/sbt/librarymanagement/EvictionWarning.scala
+++ b/librarymanagement/src/main/scala/sbt/librarymanagement/EvictionWarning.scala
@@ -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 }
diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/IvyInterface.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/IvyInterface.scala
index 54531bae4..275856dcd 100644
--- a/librarymanagement/src/main/scala/sbt/librarymanagement/IvyInterface.scala
+++ b/librarymanagement/src/main/scala/sbt/librarymanagement/IvyInterface.scala
@@ -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 InclExclRuleCompanion {
+ 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 ArtifactTypeFilterParent {
+ 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:
- *
- * - exclude unwanted dependencies pulled in transitively by a module, or to
- * - include and merge artifacts coming from the ModuleDescriptor if "dependencyArtifacts" are also provided.
- *
- * 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 `` 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 ArtifactTypeFilterCompanion {
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 ConflictManagerCompanion {
+ // 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")
diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/IvyScala.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/IvyScala.scala
index 8b004ef9d..c45b84799 100644
--- a/librarymanagement/src/main/scala/sbt/librarymanagement/IvyScala.scala
+++ b/librarymanagement/src/main/scala/sbt/librarymanagement/IvyScala.scala
@@ -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 IvyScalaCompanion {
/** 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)
diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/ModuleID.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/ModuleID.scala
index 2cbf37138..3716ac790 100644
--- a/librarymanagement/src/main/scala/sbt/librarymanagement/ModuleID.scala
+++ b/librarymanagement/src/main/scala/sbt/librarymanagement/ModuleID.scala
@@ -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 ModuleIDParent {
+ 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,10 @@ 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)
+ def cross(v: Boolean): ModuleID = cross(if (v) CrossVersion.binary else 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, verRemap: String => String): ModuleID = cross(if (v) CrossVersion.binaryMapped(verRemap) else Disabled())
/** Specifies the cross-version behavior for this module. See [CrossVersion] for details.*/
def cross(v: CrossVersion): ModuleID = copy(crossVersion = v)
@@ -64,7 +88,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 +97,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 +151,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 ModuleIDCompanion {
/** 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)
diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/Resolver.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/Resolver.scala
index 7f2c8779e..12a4c03f6 100644
--- a/librarymanagement/src/main/scala/sbt/librarymanagement/Resolver.scala
+++ b/librarymanagement/src/main/scala/sbt/librarymanagement/Resolver.scala
@@ -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 PatternsCompanion {
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 ResolverCompanion {
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)
}
}
diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/UpdateReport.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/UpdateReport.scala
index 06974aa90..fb0b0a87b 100644
--- a/librarymanagement/src/main/scala/sbt/librarymanagement/UpdateReport.scala
+++ b/librarymanagement/src/main/scala/sbt/librarymanagement/UpdateReport.scala
@@ -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 ConfigurationReportParent {
+ 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 ModuleReportParent {
+ 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 UpdateReportParent {
+ 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]
}
diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/package.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/package.scala
index 24e6eee19..a1892b2f0 100644
--- a/librarymanagement/src/main/scala/sbt/librarymanagement/package.scala
+++ b/librarymanagement/src/main/scala/sbt/librarymanagement/package.scala
@@ -1,6 +1,6 @@
package sbt
-package object librarymanagement {
+package object librarymanagement extends ResolversSyntax {
type ExclusionRule = InclExclRule
val ExclusionRule = InclExclRule
diff --git a/librarymanagement/src/test/scala/BaseIvySpecification.scala b/librarymanagement/src/test/scala/BaseIvySpecification.scala
index 7e561640d..a0f4bdfc0 100644
--- a/librarymanagement/src/test/scala/BaseIvySpecification.scala
+++ b/librarymanagement/src/test/scala/BaseIvySpecification.scala
@@ -10,22 +10,32 @@ 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 +43,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 +94,7 @@ trait BaseIvySpecification extends UnitSpec {
ivyFile = None,
resolverName = resolver.name,
artifacts = artifacts,
- checksums = Seq(),
+ checksums = Vector.empty,
logging = UpdateLogging.Full,
overwrite = true
)
diff --git a/librarymanagement/src/test/scala/CachedResolutionSpec.scala b/librarymanagement/src/test/scala/CachedResolutionSpec.scala
index 4fc6faa3e..85796bd20 100644
--- a/librarymanagement/src/test/scala/CachedResolutionSpec.scala
+++ b/librarymanagement/src/test/scala/CachedResolutionSpec.scala
@@ -9,8 +9,8 @@ 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)
@@ -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,8 +52,8 @@ 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
@@ -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
}
diff --git a/librarymanagement/src/test/scala/CrossVersionTest.scala b/librarymanagement/src/test/scala/CrossVersionTest.scala
index f70343e73..921ee1b18 100644
--- a/librarymanagement/src/test/scala/CrossVersionTest.scala
+++ b/librarymanagement/src/test/scala/CrossVersionTest.scala
@@ -116,7 +116,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
diff --git a/librarymanagement/src/test/scala/CustomPomParserTest.scala b/librarymanagement/src/test/scala/CustomPomParserTest.scala
index 16874c3d3..e90b0ba20 100644
--- a/librarymanagement/src/test/scala/CustomPomParserTest.scala
+++ b/librarymanagement/src/test/scala/CustomPomParserTest.scala
@@ -16,8 +16,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")
diff --git a/librarymanagement/src/test/scala/DMSerializationSpec.scala b/librarymanagement/src/test/scala/DMSerializationSpec.scala
index ab4d9f78c..ab1bb457b 100644
--- a/librarymanagement/src/test/scala/DMSerializationSpec.scala
+++ b/librarymanagement/src/test/scala/DMSerializationSpec.scala
@@ -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)
}
diff --git a/librarymanagement/src/test/scala/EvictionWarningSpec.scala b/librarymanagement/src/test/scala/EvictionWarningSpec.scala
index c1a77bf31..21d59b10a 100644
--- a/librarymanagement/src/test/scala/EvictionWarningSpec.scala
+++ b/librarymanagement/src/test/scala/EvictionWarningSpec.scala
@@ -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"))
diff --git a/librarymanagement/src/test/scala/InconsistentDuplicateSpec.scala b/librarymanagement/src/test/scala/InconsistentDuplicateSpec.scala
index 1e94e1196..4e0866d6c 100644
--- a/librarymanagement/src/test/scala/InconsistentDuplicateSpec.scala
+++ b/librarymanagement/src/test/scala/InconsistentDuplicateSpec.scala
@@ -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
}
diff --git a/librarymanagement/src/test/scala/ResolverTest.scala b/librarymanagement/src/test/scala/ResolverTest.scala
index 499e86db4..b2625304e 100644
--- a/librarymanagement/src/test/scala/ResolverTest.scala
+++ b/librarymanagement/src/test/scala/ResolverTest.scala
@@ -8,8 +8,8 @@ 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
diff --git a/librarymanagement/src/test/scala/sbt/internal/librarymanagement/FakeResolverSpecification.scala b/librarymanagement/src/test/scala/sbt/internal/librarymanagement/FakeResolverSpecification.scala
index 60e9f2dd7..27936225f 100644
--- a/librarymanagement/src/test/scala/sbt/internal/librarymanagement/FakeResolverSpecification.scala
+++ b/librarymanagement/src/test/scala/sbt/internal/librarymanagement/FakeResolverSpecification.scala
@@ -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
-}
\ No newline at end of file
+}
diff --git a/librarymanagement/src/test/scala/sbt/internal/librarymanagement/IvyRepoSpec.scala b/librarymanagement/src/test/scala/sbt/internal/librarymanagement/IvyRepoSpec.scala
index 9e15fbc01..fd7896c5b 100644
--- a/librarymanagement/src/test/scala/sbt/internal/librarymanagement/IvyRepoSpec.scala
+++ b/librarymanagement/src/test/scala/sbt/internal/librarymanagement/IvyRepoSpec.scala
@@ -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,7 +50,7 @@ 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.
@@ -59,12 +59,12 @@ class IvyRepoSpec extends BaseIvySpecification with DependencyBuilders {
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 +80,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")
diff --git a/project/DatatypeConfig.scala b/project/DatatypeConfig.scala
new file mode 100644
index 000000000..a83fb618a
--- /dev/null
+++ b/project/DatatypeConfig.scala
@@ -0,0 +1,61 @@
+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 "Function1" =>
+ { tpe => "sbt.internal.librarymanagement.formats.Function1Format" :: twoArgs(tpe).flatMap(getFormats) }
+
+ 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)
+ }
+
+}
diff --git a/project/Dependencies.scala b/project/Dependencies.scala
index 8232a3c7e..250adc2e2 100644
--- a/project/Dependencies.scala
+++ b/project/Dependencies.scala
@@ -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
+ }
+ }
}
diff --git a/project/build.properties b/project/build.properties
index 817bc38df..27e88aa11 100644
--- a/project/build.properties
+++ b/project/build.properties
@@ -1 +1 @@
-sbt.version=0.13.9
+sbt.version=0.13.13
diff --git a/project/sbt-datatype.sbt b/project/sbt-datatype.sbt
new file mode 100644
index 000000000..c13a23ad7
--- /dev/null
+++ b/project/sbt-datatype.sbt
@@ -0,0 +1 @@
+addSbtPlugin("org.scala-sbt" % "sbt-datatype" % "0.2.8")