diff --git a/.scalafmt.conf b/.scalafmt.conf index 8392aa694..e98e60599 100644 --- a/.scalafmt.conf +++ b/.scalafmt.conf @@ -1,4 +1,4 @@ -version = 2.0.0-RC8 +version = 2.0.0 maxColumn = 100 project.git = true project.excludeFilters = [ /sbt-test/, /input_sources/, /contraband-scala/ ] diff --git a/.travis.yml b/.travis.yml index e1d3fa441..a8a7e50e7 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,5 +1,4 @@ -sudo: false -dist: trusty +dist: xenial group: stable language: scala @@ -14,21 +13,21 @@ env: matrix: include: - env: - - TRAVIS_JDK=11.0.3.hs-adpt + - ADOPTOPENJDK=11 - env: - - TRAVIS_JDK=8.0.212.hs-adpt + - ADOPTOPENJDK=8 before_install: # adding $HOME/.sdkman to cache would create an empty directory, which interferes with the initial installation - - "[[ -d /home/travis/.sdkman/ ]] && [[ -d /home/travis/.sdkman/bin/ ]] || rm -rf /home/travis/.sdkman/" + - "[[ -d $HOME/.sdkman/bin/ ]] || rm -rf $HOME/.sdkman/" - curl -sL https://get.sdkman.io | bash - - echo sdkman_auto_answer=true > /home/travis/.sdkman/etc/config - - source "/home/travis/.sdkman/bin/sdkman-init.sh" + - echo sdkman_auto_answer=true > $HOME/.sdkman/etc/config + - source "$HOME/.sdkman/bin/sdkman-init.sh" install: - - sdk install java $TRAVIS_JDK + - sdk install java $(sdk list java | grep -o "$ADOPTOPENJDK\.[0-9\.]*hs-adpt" | head -1) - bin/fixpreloaded.sh - - unset _JAVA_OPTIONS + - unset JAVA_HOME - java -Xmx32m -version # detect sbt version from project/build.properties # - export TRAVIS_SBT=$(grep sbt.version= project/build.properties | sed -e 's/sbt.version=//g' ) && echo "sbt $TRAVIS_SBT" diff --git a/build.sbt b/build.sbt index f47cccaf3..25e1d9eab 100644 --- a/build.sbt +++ b/build.sbt @@ -27,6 +27,7 @@ def commonSettings: Seq[Setting[_]] = Def.settings( resolvers += Resolver.sonatypeRepo("snapshots"), resolvers += Resolver.sbtPluginRepo("releases"), resolvers += "bintray-sbt-maven-releases" at "https://dl.bintray.com/sbt/maven-releases/", + testFrameworks += new TestFramework("verify.runner.Framework"), // concurrentRestrictions in Global += Util.testExclusiveRestriction, testOptions += Tests.Argument(TestFrameworks.ScalaCheck, "-w", "1"), javacOptions in compile ++= Seq("-Xlint", "-Xlint:-serial"), @@ -41,7 +42,9 @@ def commonSettings: Seq[Setting[_]] = Def.settings( case _ => old ++ List("-Ywarn-unused", "-Ywarn-unused-import", "-YdisableFlatCpCaching") } }, - inCompileAndTest(scalacOptions in console --= Vector("-Ywarn-unused-import", "-Ywarn-unused", "-Xlint")), + inCompileAndTest( + scalacOptions in console --= Vector("-Ywarn-unused-import", "-Ywarn-unused", "-Xlint") + ), scalafmtOnCompile := true, Test / scalafmtOnCompile := true, publishArtifact in Compile := true, @@ -51,13 +54,22 @@ def commonSettings: Seq[Setting[_]] = Def.settings( val mimaSettings = Def settings ( mimaPreviousArtifacts := Set( - "1.0.0", "1.0.1", "1.0.2", "1.0.3", "1.0.4", - "1.1.0", "1.1.1", "1.1.2", "1.1.3", "1.1.4", + "1.0.0", + "1.0.1", + "1.0.2", + "1.0.3", + "1.0.4", + "1.1.0", + "1.1.1", + "1.1.2", + "1.1.3", + "1.1.4", "1.2.0", - ) map (version => - organization.value %% moduleName.value % version - cross (if (crossPaths.value) CrossVersion.binary else CrossVersion.disabled) - ), + ) map ( + version => + organization.value %% moduleName.value % version + cross (if (crossPaths.value) CrossVersion.binary else CrossVersion.disabled) + ), ) lazy val lmRoot = (project in file(".")) @@ -72,7 +84,8 @@ lazy val lmRoot = (project in file(".")) Some(ScmInfo(url(s"https://github.com/$slug"), s"git@github.com:$slug.git")) }, bintrayPackage := "librarymanagement", - )), + ) + ), commonSettings, name := "LM Root", publish := {}, @@ -96,8 +109,13 @@ lazy val lmCore = (project in file("core")) okhttpUrlconnection, sjsonnewScalaJson.value % Optional, scalaTest % Test, - scalaCheck % Test + scalaCheck % Test, + scalaVerify % Test, ), + libraryDependencies ++= (scalaVersion.value match { + case v if v.startsWith("2.12.") => List(compilerPlugin(silencerPlugin)) + case _ => List() + }), libraryDependencies += scalaXml, resourceGenerators in Compile += Def .task( @@ -128,33 +146,32 @@ lazy val lmCore = (project in file("core")) mimaBinaryIssueFilters ++= Seq( exclude[DirectMissingMethodProblem]("sbt.librarymanagement.EvictionWarningOptions.this"), exclude[DirectMissingMethodProblem]("sbt.librarymanagement.EvictionWarningOptions.copy"), - exclude[IncompatibleResultTypeProblem]("sbt.librarymanagement.EvictionWarningOptions.copy$default$7"), - + exclude[IncompatibleResultTypeProblem]( + "sbt.librarymanagement.EvictionWarningOptions.copy$default$7" + ), // internal class moved exclude[MissingClassProblem]("sbt.internal.librarymanagement.InlineConfigurationFunctions"), // dropped internal class parent (InlineConfigurationFunctions) exclude[MissingTypesProblem]("sbt.librarymanagement.ModuleDescriptorConfiguration$"), - // Configuration's copy method was never meant to be public exclude[DirectMissingMethodProblem]("sbt.librarymanagement.Configuration.copy"), exclude[DirectMissingMethodProblem]("sbt.librarymanagement.Configuration.copy$default$*"), - // the data type copy methods were never meant to be public exclude[DirectMissingMethodProblem]("sbt.librarymanagement.ArtifactExtra.copy"), exclude[DirectMissingMethodProblem]("sbt.librarymanagement.ArtifactExtra.copy$default$*"), exclude[DirectMissingMethodProblem]("sbt.librarymanagement.ModuleReportExtra.copy"), exclude[DirectMissingMethodProblem]("sbt.librarymanagement.ModuleReportExtra.copy$default$*"), exclude[DirectMissingMethodProblem]("sbt.librarymanagement.ArtifactTypeFilterExtra.copy"), - exclude[DirectMissingMethodProblem]("sbt.librarymanagement.ArtifactTypeFilterExtra.copy$default$*"), + exclude[DirectMissingMethodProblem]( + "sbt.librarymanagement.ArtifactTypeFilterExtra.copy$default$*" + ), exclude[DirectMissingMethodProblem]("sbt.librarymanagement.ModuleIDExtra.copy"), exclude[DirectMissingMethodProblem]("sbt.librarymanagement.ModuleIDExtra.copy$default$*"), - // these abstract classes are private[librarymanagement] so it's fine if they have more methods exclude[ReversedMissingMethodProblem]("sbt.librarymanagement.ArtifactExtra.*"), exclude[ReversedMissingMethodProblem]("sbt.librarymanagement.ModuleReportExtra.*"), exclude[ReversedMissingMethodProblem]("sbt.librarymanagement.ArtifactTypeFilterExtra.*"), exclude[ReversedMissingMethodProblem]("sbt.librarymanagement.ModuleIDExtra.*"), - // these abstract classes are private[librarymanagement] so they can lose these abstract methods exclude[DirectMissingMethodProblem]("sbt.librarymanagement.ArtifactExtra.type"), exclude[DirectMissingMethodProblem]("sbt.librarymanagement.ArtifactExtra.url"), @@ -164,9 +181,10 @@ lazy val lmCore = (project in file("core")) exclude[DirectMissingMethodProblem]("sbt.librarymanagement.ArtifactExtra.classifier"), exclude[DirectMissingMethodProblem]("sbt.librarymanagement.ArtifactExtra.extension"), exclude[DirectMissingMethodProblem]("sbt.librarymanagement.ArtifactTypeFilterExtra.types"), - // contraband issue - exclude[DirectMissingMethodProblem]("sbt.internal.librarymanagement.ConfigurationReportLite.copy*"), + exclude[DirectMissingMethodProblem]( + "sbt.internal.librarymanagement.ConfigurationReportLite.copy*" + ), exclude[DirectMissingMethodProblem]("sbt.internal.librarymanagement.UpdateReportLite.copy*"), exclude[DirectMissingMethodProblem]("sbt.librarymanagement.Artifact.copy*"), exclude[DirectMissingMethodProblem]("sbt.librarymanagement.ArtifactTypeFilter.copy*"), @@ -183,7 +201,9 @@ lazy val lmCore = (project in file("core")) exclude[DirectMissingMethodProblem]("sbt.librarymanagement.FileConfiguration.copy*"), exclude[DirectMissingMethodProblem]("sbt.librarymanagement.FileRepository.copy*"), exclude[DirectMissingMethodProblem]("sbt.librarymanagement.Full.copy*"), - exclude[DirectMissingMethodProblem]("sbt.librarymanagement.GetClassifiersConfiguration.copy*"), + exclude[DirectMissingMethodProblem]( + "sbt.librarymanagement.GetClassifiersConfiguration.copy*" + ), exclude[DirectMissingMethodProblem]("sbt.librarymanagement.GetClassifiersModule.copy*"), exclude[DirectMissingMethodProblem]("sbt.librarymanagement.InclExclRule.copy*"), exclude[DirectMissingMethodProblem]("sbt.librarymanagement.IvyFileConfiguration.copy*"), @@ -192,7 +212,9 @@ lazy val lmCore = (project in file("core")) exclude[DirectMissingMethodProblem]("sbt.librarymanagement.MavenCache.copy*"), exclude[DirectMissingMethodProblem]("sbt.librarymanagement.MavenRepo.copy*"), exclude[DirectMissingMethodProblem]("sbt.librarymanagement.ModuleConfiguration.copy*"), - exclude[DirectMissingMethodProblem]("sbt.librarymanagement.ModuleDescriptorConfiguration.copy*"), + exclude[DirectMissingMethodProblem]( + "sbt.librarymanagement.ModuleDescriptorConfiguration.copy*" + ), exclude[DirectMissingMethodProblem]("sbt.librarymanagement.ModuleID.copy*"), exclude[DirectMissingMethodProblem]("sbt.librarymanagement.ModuleInfo.copy*"), exclude[DirectMissingMethodProblem]("sbt.librarymanagement.ModuleReport.copy*"), @@ -212,29 +234,29 @@ lazy val lmCore = (project in file("core")) exclude[DirectMissingMethodProblem]("sbt.librarymanagement.UpdateReport.copy*"), exclude[DirectMissingMethodProblem]("sbt.librarymanagement.UpdateStats.copy*"), exclude[DirectMissingMethodProblem]("sbt.librarymanagement.URLRepository.copy*"), + // private[sbt] + exclude[DirectMissingMethodProblem]( + "sbt.librarymanagement.ResolverFunctions.useSecureResolvers" + ), + exclude[ReversedMissingMethodProblem]( + "sbt.librarymanagement.MavenRepository.allowInsecureProtocol" + ) ), ) .configure(addSbtIO, addSbtUtilLogging, addSbtUtilPosition, addSbtUtilCache) -lazy val lmCommonTest = (project in file("common-test")) +lazy val lmIvy = (project in file("ivy")) + .enablePlugins(ContrabandPlugin, JsonCodecPlugin) .dependsOn(lmCore) - .settings( - commonSettings, - skip in publish := true, - name := "common-test", - libraryDependencies ++= Seq(scalaTest, scalaCheck), - scalacOptions in (Compile, console) --= - Vector("-Ywarn-unused-import", "-Ywarn-unused", "-Xlint"), - mimaSettings, - ) - -lazy val lmIvy = (project in file("ivy")) - .enablePlugins(ContrabandPlugin, JsonCodecPlugin) - .dependsOn(lmCore, lmCommonTest % Test) .settings( commonSettings, name := "librarymanagement-ivy", - libraryDependencies ++= Seq(ivy), + libraryDependencies ++= Seq( + ivy, + scalaTest % Test, + scalaCheck % Test, + scalaVerify % Test, + ), managedSourceDirectories in Compile += baseDirectory.value / "src" / "main" / "contraband-scala", sourceManaged in (Compile, generateContrabands) := baseDirectory.value / "src" / "main" / "contraband-scala", @@ -243,33 +265,68 @@ lazy val lmIvy = (project in file("ivy")) Vector("-Ywarn-unused-import", "-Ywarn-unused", "-Xlint"), mimaSettings, mimaBinaryIssueFilters ++= Seq( - exclude[DirectMissingMethodProblem]("sbt.internal.librarymanagement.ivyint.GigahorseUrlHandler#SbtUrlInfo.this"), - exclude[IncompatibleMethTypeProblem]("sbt.internal.librarymanagement.ivyint.GigahorseUrlHandler#SbtUrlInfo.this"), - exclude[DirectMissingMethodProblem]("sbt.internal.librarymanagement.ivyint.GigahorseUrlHandler.checkStatusCode"), - + exclude[DirectMissingMethodProblem]( + "sbt.internal.librarymanagement.ivyint.GigahorseUrlHandler#SbtUrlInfo.this" + ), + exclude[IncompatibleMethTypeProblem]( + "sbt.internal.librarymanagement.ivyint.GigahorseUrlHandler#SbtUrlInfo.this" + ), + exclude[DirectMissingMethodProblem]( + "sbt.internal.librarymanagement.ivyint.GigahorseUrlHandler.checkStatusCode" + ), // sbt.internal methods that changed type signatures and aren't used elsewhere in production code - exclude[DirectMissingMethodProblem]("sbt.internal.librarymanagement.IvySbt#ParallelCachedResolutionResolveEngine.mergeErrors"), - exclude[DirectMissingMethodProblem]("sbt.internal.librarymanagement.IvySbt.cleanCachedResolutionCache"), + exclude[DirectMissingMethodProblem]( + "sbt.internal.librarymanagement.IvySbt#ParallelCachedResolutionResolveEngine.mergeErrors" + ), + exclude[DirectMissingMethodProblem]( + "sbt.internal.librarymanagement.IvySbt.cleanCachedResolutionCache" + ), exclude[DirectMissingMethodProblem]("sbt.internal.librarymanagement.IvyRetrieve.artifacts"), - exclude[DirectMissingMethodProblem]("sbt.internal.librarymanagement.IvyScalaUtil.checkModule"), - exclude[DirectMissingMethodProblem]("sbt.internal.librarymanagement.ivyint.CachedResolutionResolveEngine.mergeErrors"), - exclude[DirectMissingMethodProblem]("sbt.internal.librarymanagement.ivyint.CachedResolutionResolveCache.buildArtificialModuleDescriptor"), - exclude[DirectMissingMethodProblem]("sbt.internal.librarymanagement.ivyint.CachedResolutionResolveCache.buildArtificialModuleDescriptors"), - exclude[ReversedMissingMethodProblem]("sbt.internal.librarymanagement.ivyint.CachedResolutionResolveEngine.mergeErrors"), - - exclude[DirectMissingMethodProblem]("sbt.internal.librarymanagement.ivyint.GigahorseUrlHandler#SbtUrlInfo.this"), - exclude[IncompatibleMethTypeProblem]("sbt.internal.librarymanagement.ivyint.GigahorseUrlHandler#SbtUrlInfo.this"), - exclude[DirectMissingMethodProblem]("sbt.internal.librarymanagement.ivyint.GigahorseUrlHandler.checkStatusCode"), - + exclude[DirectMissingMethodProblem]( + "sbt.internal.librarymanagement.IvyScalaUtil.checkModule" + ), + exclude[DirectMissingMethodProblem]( + "sbt.internal.librarymanagement.ivyint.CachedResolutionResolveEngine.mergeErrors" + ), + exclude[DirectMissingMethodProblem]( + "sbt.internal.librarymanagement.ivyint.CachedResolutionResolveCache.buildArtificialModuleDescriptor" + ), + exclude[DirectMissingMethodProblem]( + "sbt.internal.librarymanagement.ivyint.CachedResolutionResolveCache.buildArtificialModuleDescriptors" + ), + exclude[ReversedMissingMethodProblem]( + "sbt.internal.librarymanagement.ivyint.CachedResolutionResolveEngine.mergeErrors" + ), + exclude[DirectMissingMethodProblem]( + "sbt.internal.librarymanagement.ivyint.GigahorseUrlHandler#SbtUrlInfo.this" + ), + exclude[IncompatibleMethTypeProblem]( + "sbt.internal.librarymanagement.ivyint.GigahorseUrlHandler#SbtUrlInfo.this" + ), + exclude[DirectMissingMethodProblem]( + "sbt.internal.librarymanagement.ivyint.GigahorseUrlHandler.checkStatusCode" + ), // contraband issue - exclude[DirectMissingMethodProblem]("sbt.librarymanagement.ivy.ExternalIvyConfiguration.copy*"), + exclude[DirectMissingMethodProblem]( + "sbt.librarymanagement.ivy.ExternalIvyConfiguration.copy*" + ), exclude[DirectMissingMethodProblem]("sbt.librarymanagement.ivy.InlineIvyConfiguration.copy*"), exclude[DirectMissingMethodProblem]("sbt.librarymanagement.ivy.IvyPaths.copy*"), - - exclude[DirectMissingMethodProblem]("sbt.internal.librarymanagement.ivyint.GigahorseUrlHandler.urlFactory"), - exclude[DirectMissingMethodProblem]("sbt.internal.librarymanagement.ivyint.GigahorseUrlHandler.http"), - exclude[DirectMissingMethodProblem]("sbt.internal.librarymanagement.ivyint.GigahorseUrlHandler.open"), - exclude[DirectMissingMethodProblem]("sbt.internal.librarymanagement.ivyint.GigahorseUrlHandler.this"), + exclude[DirectMissingMethodProblem]( + "sbt.internal.librarymanagement.ivyint.GigahorseUrlHandler.urlFactory" + ), + exclude[DirectMissingMethodProblem]( + "sbt.internal.librarymanagement.ivyint.GigahorseUrlHandler.http" + ), + exclude[DirectMissingMethodProblem]( + "sbt.internal.librarymanagement.ivyint.GigahorseUrlHandler.open" + ), + exclude[DirectMissingMethodProblem]( + "sbt.internal.librarymanagement.ivyint.GigahorseUrlHandler.this" + ), + exclude[DirectMissingMethodProblem]( + "sbt.internal.librarymanagement.CustomPomParser.versionRangeFlag" + ), ), ) @@ -279,11 +336,13 @@ lazy val lmScriptedTest = (project in file("scripted-test")) commonSettings, skip in publish := true, name := "scripted-test", - scriptedLaunchOpts := { scriptedLaunchOpts.value ++ - Seq("-Xmx1024M", "-Dplugin.version=" + version.value) + scriptedLaunchOpts := { + scriptedLaunchOpts.value ++ + Seq("-Xmx1024M", "-Dplugin.version=" + version.value) }, scriptedBufferLog := false - ).enablePlugins(SbtScriptedIT) + ) + .enablePlugins(SbtScriptedIT) // we are updating the nightly process, so we are commenting this out for now // addCommandAlias("scriptedIvy", Seq( @@ -304,14 +363,16 @@ def customCommands: Seq[Setting[_]] = Seq( } ) -inThisBuild(Seq( - whitesourceProduct := "Lightbend Reactive Platform", - whitesourceAggregateProjectName := "sbt-lm-master", - whitesourceAggregateProjectToken := "9bde4ccbaab7401a91f8cda337af84365d379e13abaf473b85cb16e3f5c65cb6", - whitesourceIgnoredScopes += "scalafmt", - whitesourceFailOnError := sys.env.contains("WHITESOURCE_PASSWORD"), // fail if pwd is present - whitesourceForceCheckAllDependencies := true, -)) +inThisBuild( + Seq( + whitesourceProduct := "Lightbend Reactive Platform", + whitesourceAggregateProjectName := "sbt-lm-master", + whitesourceAggregateProjectToken := "9bde4ccbaab7401a91f8cda337af84365d379e13abaf473b85cb16e3f5c65cb6", + whitesourceIgnoredScopes += "scalafmt", + whitesourceFailOnError := sys.env.contains("WHITESOURCE_PASSWORD"), // fail if pwd is present + whitesourceForceCheckAllDependencies := true, + ) +) def inCompileAndTest(ss: SettingsDefinition*): Seq[Setting[_]] = Seq(Compile, Test) flatMap (inConfig(_)(Def.settings(ss: _*))) diff --git a/common-test/src/main/scala/sbt/internal/librarymanagement/UnitSpec.scala b/common-test/src/main/scala/sbt/internal/librarymanagement/UnitSpec.scala deleted file mode 100644 index dfd947c8f..000000000 --- a/common-test/src/main/scala/sbt/internal/librarymanagement/UnitSpec.scala +++ /dev/null @@ -1,5 +0,0 @@ -package sbt.internal.librarymanagement - -import org.scalatest._ - -abstract class UnitSpec extends FlatSpec with Matchers diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/Artifact.scala b/core/src/main/contraband-scala/sbt/librarymanagement/Artifact.scala index d337cb364..9cae77dca 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/Artifact.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/Artifact.scala @@ -12,22 +12,24 @@ final class Artifact private ( val configurations: Vector[sbt.librarymanagement.ConfigRef], val url: Option[java.net.URL], val extraAttributes: Map[String, String], - val checksum: Option[sbt.librarymanagement.Checksum]) extends sbt.librarymanagement.ArtifactExtra with Serializable { - - private def this(name: String) = this(name, Artifact.DefaultType, Artifact.DefaultExtension, None, Vector.empty, None, Map.empty, None) + val checksum: Option[sbt.librarymanagement.Checksum], + val allowInsecureProtocol: Boolean) extends sbt.librarymanagement.ArtifactExtra with Serializable { + private[sbt] def validateProtocol(logger: sbt.util.Logger): Unit = Resolver.validateArtifact(this, logger) + private def this(name: String) = this(name, Artifact.DefaultType, Artifact.DefaultExtension, None, Vector.empty, None, Map.empty, None, false) + private def this(name: String, `type`: String, extension: String, classifier: Option[String], configurations: Vector[sbt.librarymanagement.ConfigRef], url: Option[java.net.URL], extraAttributes: Map[String, String], checksum: Option[sbt.librarymanagement.Checksum]) = this(name, `type`, extension, classifier, configurations, url, extraAttributes, checksum, false) override def equals(o: Any): Boolean = o match { - case x: Artifact => (this.name == x.name) && (this.`type` == x.`type`) && (this.extension == x.extension) && (this.classifier == x.classifier) && (this.configurations == x.configurations) && (this.url == x.url) && (this.extraAttributes == x.extraAttributes) && (this.checksum == x.checksum) + case x: Artifact => (this.name == x.name) && (this.`type` == x.`type`) && (this.extension == x.extension) && (this.classifier == x.classifier) && (this.configurations == x.configurations) && (this.url == x.url) && (this.extraAttributes == x.extraAttributes) && (this.checksum == x.checksum) && (this.allowInsecureProtocol == x.allowInsecureProtocol) case _ => false } override def hashCode: Int = { - 37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (17 + "sbt.librarymanagement.Artifact".##) + name.##) + `type`.##) + extension.##) + classifier.##) + configurations.##) + url.##) + extraAttributes.##) + checksum.##) + 37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (17 + "sbt.librarymanagement.Artifact".##) + name.##) + `type`.##) + extension.##) + classifier.##) + configurations.##) + url.##) + extraAttributes.##) + checksum.##) + allowInsecureProtocol.##) } override def toString: String = { - "Artifact(" + name + ", " + `type` + ", " + extension + ", " + classifier + ", " + configurations + ", " + url + ", " + extraAttributes + ", " + checksum + ")" + "Artifact(" + name + ", " + `type` + ", " + extension + ", " + classifier + ", " + configurations + ", " + url + ", " + extraAttributes + ", " + checksum + ", " + allowInsecureProtocol + ")" } - private[this] def copy(name: String = name, `type`: String = `type`, extension: String = extension, classifier: Option[String] = classifier, configurations: Vector[sbt.librarymanagement.ConfigRef] = configurations, url: Option[java.net.URL] = url, extraAttributes: Map[String, String] = extraAttributes, checksum: Option[sbt.librarymanagement.Checksum] = checksum): Artifact = { - new Artifact(name, `type`, extension, classifier, configurations, url, extraAttributes, checksum) + private[this] def copy(name: String = name, `type`: String = `type`, extension: String = extension, classifier: Option[String] = classifier, configurations: Vector[sbt.librarymanagement.ConfigRef] = configurations, url: Option[java.net.URL] = url, extraAttributes: Map[String, String] = extraAttributes, checksum: Option[sbt.librarymanagement.Checksum] = checksum, allowInsecureProtocol: Boolean = allowInsecureProtocol): Artifact = { + new Artifact(name, `type`, extension, classifier, configurations, url, extraAttributes, checksum, allowInsecureProtocol) } def withName(name: String): Artifact = { copy(name = name) @@ -53,9 +55,13 @@ final class Artifact private ( def withChecksum(checksum: Option[sbt.librarymanagement.Checksum]): Artifact = { copy(checksum = checksum) } + def withAllowInsecureProtocol(allowInsecureProtocol: Boolean): Artifact = { + copy(allowInsecureProtocol = allowInsecureProtocol) + } } object Artifact extends sbt.librarymanagement.ArtifactFunctions { def apply(name: String): Artifact = new Artifact(name) def apply(name: String, `type`: String, extension: String, classifier: Option[String], configurations: Vector[sbt.librarymanagement.ConfigRef], url: Option[java.net.URL], extraAttributes: Map[String, String], checksum: Option[sbt.librarymanagement.Checksum]): Artifact = new Artifact(name, `type`, extension, classifier, configurations, url, extraAttributes, checksum) + def apply(name: String, `type`: String, extension: String, classifier: Option[String], configurations: Vector[sbt.librarymanagement.ConfigRef], url: Option[java.net.URL], extraAttributes: Map[String, String], checksum: Option[sbt.librarymanagement.Checksum], allowInsecureProtocol: Boolean): Artifact = new Artifact(name, `type`, extension, classifier, configurations, url, extraAttributes, checksum, allowInsecureProtocol) } diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/ArtifactFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/ArtifactFormats.scala index 4dfc42b54..2c9b2a02d 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/ArtifactFormats.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/ArtifactFormats.scala @@ -19,8 +19,9 @@ implicit lazy val ArtifactFormat: JsonFormat[sbt.librarymanagement.Artifact] = n val url = unbuilder.readField[Option[java.net.URL]]("url") val extraAttributes = unbuilder.readField[Map[String, String]]("extraAttributes") val checksum = unbuilder.readField[Option[sbt.librarymanagement.Checksum]]("checksum") + val allowInsecureProtocol = unbuilder.readField[Boolean]("allowInsecureProtocol") unbuilder.endObject() - sbt.librarymanagement.Artifact(name, `type`, extension, classifier, configurations, url, extraAttributes, checksum) + sbt.librarymanagement.Artifact(name, `type`, extension, classifier, configurations, url, extraAttributes, checksum, allowInsecureProtocol) case None => deserializationError("Expected JsObject but found None") } @@ -35,6 +36,7 @@ implicit lazy val ArtifactFormat: JsonFormat[sbt.librarymanagement.Artifact] = n builder.addField("url", obj.url) builder.addField("extraAttributes", obj.extraAttributes) builder.addField("checksum", obj.checksum) + builder.addField("allowInsecureProtocol", obj.allowInsecureProtocol) builder.endObject() } } diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/ChainedResolver.scala b/core/src/main/contraband-scala/sbt/librarymanagement/ChainedResolver.scala index d98e6d1cb..fa950e86b 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/ChainedResolver.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/ChainedResolver.scala @@ -7,7 +7,7 @@ package sbt.librarymanagement final class ChainedResolver private ( name: String, val resolvers: Vector[sbt.librarymanagement.Resolver]) extends sbt.librarymanagement.Resolver(name) with Serializable { - + private[sbt] override def validateProtocol(logger: sbt.util.Logger): Unit = resolvers.foreach(_.validateProtocol(logger)) override def equals(o: Any): Boolean = o match { diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/DisabledFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/DisabledFormats.scala deleted file mode 100644 index 7c0602834..000000000 --- a/core/src/main/contraband-scala/sbt/librarymanagement/DisabledFormats.scala +++ /dev/null @@ -1,27 +0,0 @@ -/** - * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. - */ - -// DO NOT EDIT MANUALLY -package sbt.librarymanagement -import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } -trait DisabledFormats { self: sjsonnew.BasicJsonProtocol => -implicit lazy val DisabledFormat: JsonFormat[sbt.librarymanagement.Disabled] = new JsonFormat[sbt.librarymanagement.Disabled] { - override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.Disabled = { - jsOpt match { - case Some(js) => - unbuilder.beginObject(js) - - unbuilder.endObject() - sbt.librarymanagement.Disabled() - case None => - deserializationError("Expected JsObject but found None") - } - } - override def write[J](obj: sbt.librarymanagement.Disabled, builder: Builder[J]): Unit = { - builder.beginObject() - - builder.endObject() - } -} -} diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/MavenCache.scala b/core/src/main/contraband-scala/sbt/librarymanagement/MavenCache.scala index b1501e3d4..1ed824c7b 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/MavenCache.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/MavenCache.scala @@ -14,7 +14,8 @@ final class MavenCache private ( localIfFile: Boolean, val rootFile: java.io.File) extends sbt.librarymanagement.MavenRepository(name, root, localIfFile) with Serializable { def this(name: String, rootFile: java.io.File) = this(name, rootFile.toURI.toURL.toString, true, rootFile) - def isCache: Boolean = true + override def isCache: Boolean = true + override def allowInsecureProtocol: Boolean = false private def this(name: String, root: String, rootFile: java.io.File) = this(name, root, true, rootFile) override def equals(o: Any): Boolean = o match { diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/MavenRepo.scala b/core/src/main/contraband-scala/sbt/librarymanagement/MavenRepo.scala index b01c6d8a9..a23e1a225 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/MavenRepo.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/MavenRepo.scala @@ -4,25 +4,30 @@ // DO NOT EDIT MANUALLY package sbt.librarymanagement +/** This is the internal implementation of actual Maven Repository (as opposed to a file cache). */ final class MavenRepo private ( name: String, root: String, - localIfFile: Boolean) extends sbt.librarymanagement.MavenRepository(name, root, localIfFile) with Serializable { - def isCache: Boolean = false - private def this(name: String, root: String) = this(name, root, true) + localIfFile: Boolean, + val _allowInsecureProtocol: Boolean) extends sbt.librarymanagement.MavenRepository(name, root, localIfFile) with Serializable { + override def isCache: Boolean = false + override def allowInsecureProtocol: Boolean = _allowInsecureProtocol + private[sbt] override def validateProtocol(logger: sbt.util.Logger): Unit = Resolver.validateMavenRepo(this, logger) + private def this(name: String, root: String) = this(name, root, true, false) + private def this(name: String, root: String, localIfFile: Boolean) = this(name, root, localIfFile, false) override def equals(o: Any): Boolean = o match { - case x: MavenRepo => (this.name == x.name) && (this.root == x.root) && (this.localIfFile == x.localIfFile) + case x: MavenRepo => (this.name == x.name) && (this.root == x.root) && (this.localIfFile == x.localIfFile) && (this._allowInsecureProtocol == x._allowInsecureProtocol) case _ => false } override def hashCode: Int = { - 37 * (37 * (37 * (37 * (17 + "sbt.librarymanagement.MavenRepo".##) + name.##) + root.##) + localIfFile.##) + 37 * (37 * (37 * (37 * (37 * (17 + "sbt.librarymanagement.MavenRepo".##) + name.##) + root.##) + localIfFile.##) + _allowInsecureProtocol.##) } override def toString: String = { s"$name: $root" } - private[this] def copy(name: String = name, root: String = root, localIfFile: Boolean = localIfFile): MavenRepo = { - new MavenRepo(name, root, localIfFile) + private[this] def copy(name: String = name, root: String = root, localIfFile: Boolean = localIfFile, _allowInsecureProtocol: Boolean = _allowInsecureProtocol): MavenRepo = { + new MavenRepo(name, root, localIfFile, _allowInsecureProtocol) } def withName(name: String): MavenRepo = { copy(name = name) @@ -33,9 +38,13 @@ final class MavenRepo private ( def withLocalIfFile(localIfFile: Boolean): MavenRepo = { copy(localIfFile = localIfFile) } + def with_allowInsecureProtocol(_allowInsecureProtocol: Boolean): MavenRepo = { + copy(_allowInsecureProtocol = _allowInsecureProtocol) + } } object MavenRepo { def apply(name: String, root: String): MavenRepo = new MavenRepo(name, root) def apply(name: String, root: String, localIfFile: Boolean): MavenRepo = new MavenRepo(name, root, localIfFile) + def apply(name: String, root: String, localIfFile: Boolean, _allowInsecureProtocol: Boolean): MavenRepo = new MavenRepo(name, root, localIfFile, _allowInsecureProtocol) } diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/MavenRepoFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/MavenRepoFormats.scala index 235de9643..e4c979985 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/MavenRepoFormats.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/MavenRepoFormats.scala @@ -14,8 +14,9 @@ implicit lazy val MavenRepoFormat: JsonFormat[sbt.librarymanagement.MavenRepo] = val name = unbuilder.readField[String]("name") val root = unbuilder.readField[String]("root") val localIfFile = unbuilder.readField[Boolean]("localIfFile") + val _allowInsecureProtocol = unbuilder.readField[Boolean]("_allowInsecureProtocol") unbuilder.endObject() - sbt.librarymanagement.MavenRepo(name, root, localIfFile) + sbt.librarymanagement.MavenRepo(name, root, localIfFile, _allowInsecureProtocol) case None => deserializationError("Expected JsObject but found None") } @@ -25,6 +26,7 @@ implicit lazy val MavenRepoFormat: JsonFormat[sbt.librarymanagement.MavenRepo] = builder.addField("name", obj.name) builder.addField("root", obj.root) builder.addField("localIfFile", obj.localIfFile) + builder.addField("_allowInsecureProtocol", obj._allowInsecureProtocol) builder.endObject() } } diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/MavenRepository.scala b/core/src/main/contraband-scala/sbt/librarymanagement/MavenRepository.scala index f1bbb608c..3f891ef19 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/MavenRepository.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/MavenRepository.scala @@ -10,6 +10,12 @@ abstract class MavenRepository( val root: String, val localIfFile: Boolean) extends sbt.librarymanagement.Resolver(name) with Serializable { def isCache: Boolean + def allowInsecureProtocol: Boolean + def withAllowInsecureProtocol(allowInsecureProtocol: Boolean): MavenRepository = + this match { + case x: MavenRepo => x.with_allowInsecureProtocol(allowInsecureProtocol) + case x: MavenCache => x + } def this(name: String, root: String) = this(name, root, true) diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/Resolver.scala b/core/src/main/contraband-scala/sbt/librarymanagement/Resolver.scala index c6caf7eaf..448b04334 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/Resolver.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/Resolver.scala @@ -6,7 +6,8 @@ package sbt.librarymanagement abstract class Resolver( val name: String) extends Serializable { - + /** check for HTTP */ + private[sbt] def validateProtocol(logger: sbt.util.Logger): Unit = () diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/URLRepository.scala b/core/src/main/contraband-scala/sbt/librarymanagement/URLRepository.scala index 1768cacda..9f0efa520 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/URLRepository.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/URLRepository.scala @@ -6,22 +6,23 @@ package sbt.librarymanagement final class URLRepository private ( name: String, - patterns: sbt.librarymanagement.Patterns) extends sbt.librarymanagement.PatternsBasedRepository(name, patterns) with Serializable { - - + patterns: sbt.librarymanagement.Patterns, + val allowInsecureProtocol: Boolean) extends sbt.librarymanagement.PatternsBasedRepository(name, patterns) with Serializable { + private[sbt] override def validateProtocol(logger: sbt.util.Logger): Unit = Resolver.validateURLRepository(this, logger) + private def this(name: String, patterns: sbt.librarymanagement.Patterns) = this(name, patterns, false) override def equals(o: Any): Boolean = o match { - case x: URLRepository => (this.name == x.name) && (this.patterns == x.patterns) + case x: URLRepository => (this.name == x.name) && (this.patterns == x.patterns) && (this.allowInsecureProtocol == x.allowInsecureProtocol) case _ => false } override def hashCode: Int = { - 37 * (37 * (37 * (17 + "sbt.librarymanagement.URLRepository".##) + name.##) + patterns.##) + 37 * (37 * (37 * (37 * (17 + "sbt.librarymanagement.URLRepository".##) + name.##) + patterns.##) + allowInsecureProtocol.##) } override def toString: String = { - "URLRepository(" + name + ", " + patterns + ")" + "URLRepository(" + name + ", " + patterns + ", " + allowInsecureProtocol + ")" } - private[this] def copy(name: String = name, patterns: sbt.librarymanagement.Patterns = patterns): URLRepository = { - new URLRepository(name, patterns) + private[this] def copy(name: String = name, patterns: sbt.librarymanagement.Patterns = patterns, allowInsecureProtocol: Boolean = allowInsecureProtocol): URLRepository = { + new URLRepository(name, patterns, allowInsecureProtocol) } def withName(name: String): URLRepository = { copy(name = name) @@ -29,8 +30,12 @@ final class URLRepository private ( def withPatterns(patterns: sbt.librarymanagement.Patterns): URLRepository = { copy(patterns = patterns) } + def withAllowInsecureProtocol(allowInsecureProtocol: Boolean): URLRepository = { + copy(allowInsecureProtocol = allowInsecureProtocol) + } } object URLRepository { def apply(name: String, patterns: sbt.librarymanagement.Patterns): URLRepository = new URLRepository(name, patterns) + def apply(name: String, patterns: sbt.librarymanagement.Patterns, allowInsecureProtocol: Boolean): URLRepository = new URLRepository(name, patterns, allowInsecureProtocol) } diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/URLRepositoryFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/URLRepositoryFormats.scala index dbf9e9cfa..4ab1b23c8 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/URLRepositoryFormats.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/URLRepositoryFormats.scala @@ -13,8 +13,9 @@ implicit lazy val URLRepositoryFormat: JsonFormat[sbt.librarymanagement.URLRepos unbuilder.beginObject(js) val name = unbuilder.readField[String]("name") val patterns = unbuilder.readField[sbt.librarymanagement.Patterns]("patterns") + val allowInsecureProtocol = unbuilder.readField[Boolean]("allowInsecureProtocol") unbuilder.endObject() - sbt.librarymanagement.URLRepository(name, patterns) + sbt.librarymanagement.URLRepository(name, patterns, allowInsecureProtocol) case None => deserializationError("Expected JsObject but found None") } @@ -23,6 +24,7 @@ implicit lazy val URLRepositoryFormat: JsonFormat[sbt.librarymanagement.URLRepos builder.beginObject() builder.addField("name", obj.name) builder.addField("patterns", obj.patterns) + builder.addField("allowInsecureProtocol", obj.allowInsecureProtocol) builder.endObject() } } diff --git a/core/src/main/contraband/librarymanagement.json b/core/src/main/contraband/librarymanagement.json index 52cb34905..67d655470 100644 --- a/core/src/main/contraband/librarymanagement.json +++ b/core/src/main/contraband/librarymanagement.json @@ -143,7 +143,11 @@ { "name": "configurations", "type": "sbt.librarymanagement.ConfigRef*", "default": "Vector.empty", "since": "0.0.1" }, { "name": "url", "type": "Option[java.net.URL]", "default": "None", "since": "0.0.1" }, { "name": "extraAttributes", "type": "Map[String, String]", "default": "Map.empty", "since": "0.0.1" }, - { "name": "checksum", "type": "Option[sbt.librarymanagement.Checksum]", "default": "None", "since": "0.0.1" } + { "name": "checksum", "type": "Option[sbt.librarymanagement.Checksum]", "default": "None", "since": "0.0.1" }, + { "name": "allowInsecureProtocol", "type": "Boolean", "default": "false", "since": "1.3.0" } + ], + "extra": [ + "private[sbt] def validateProtocol(logger: sbt.util.Logger): Unit = Resolver.validateArtifact(this, logger)" ], "parentsCompanion": "sbt.librarymanagement.ArtifactFunctions" }, @@ -557,6 +561,10 @@ "fields": [ { "name": "name", "type": "String" } ], + "extra": [ + "/** check for HTTP */", + "private[sbt] def validateProtocol(logger: sbt.util.Logger): Unit = ()" + ], "types": [ { "name": "ChainedResolver", @@ -565,6 +573,9 @@ "type": "record", "fields": [ { "name": "resolvers", "type": "sbt.librarymanagement.Resolver*" } + ], + "extra": [ + "private[sbt] override def validateProtocol(logger: sbt.util.Logger): Unit = resolvers.foreach(_.validateProtocol(logger))" ] }, { @@ -583,7 +594,17 @@ "namespace": "sbt.librarymanagement", "target": "Scala", "type": "record", - "extra": "def isCache: Boolean = false", + "doc": [ + "This is the internal implementation of actual Maven Repository (as opposed to a file cache)." + ], + "fields": [ + { "name": "_allowInsecureProtocol", "type": "Boolean", "default": "false", "since": "1.3.0" } + ], + "extra": [ + "override def isCache: Boolean = false", + "override def allowInsecureProtocol: Boolean = _allowInsecureProtocol", + "private[sbt] override def validateProtocol(logger: sbt.util.Logger): Unit = Resolver.validateMavenRepo(this, logger)" + ], "toString": "s\"$name: $root\"" }, { @@ -600,13 +621,22 @@ ], "extra": [ "def this(name: String, rootFile: java.io.File) = this(name, rootFile.toURI.toURL.toString, true, rootFile)", - "def isCache: Boolean = true" + "override def isCache: Boolean = true", + "override def allowInsecureProtocol: Boolean = false" ], "toString": "s\"cache:$name: ${rootFile.getAbsolutePath}\"", "extraCompanion": "def apply(name: String, rootFile: java.io.File): MavenCache = new MavenCache(name, rootFile)" } ], - "extra": "def isCache: Boolean", + "extra": [ + "def isCache: Boolean", + "def allowInsecureProtocol: Boolean", + "def withAllowInsecureProtocol(allowInsecureProtocol: Boolean): MavenRepository =", + " this match {", + " case x: MavenRepo => x.with_allowInsecureProtocol(allowInsecureProtocol)", + " case x: MavenCache => x", + " }" + ], "parentsCompanion": "sbt.librarymanagement.MavenRepositoryFunctions" }, { @@ -641,7 +671,13 @@ "name": "URLRepository", "namespace": "sbt.librarymanagement", "target": "Scala", - "type": "record" + "type": "record", + "fields": [ + { "name": "allowInsecureProtocol", "type": "boolean", "default": "false", "since": "1.3.0" } + ], + "extra": [ + "private[sbt] override def validateProtocol(logger: sbt.util.Logger): Unit = Resolver.validateURLRepository(this, logger)" + ] }, { "name": "SshBasedRepository", diff --git a/core/src/main/scala/sbt/internal/librarymanagement/LMSysProp.scala b/core/src/main/scala/sbt/internal/librarymanagement/LMSysProp.scala new file mode 100644 index 000000000..d2a28d3eb --- /dev/null +++ b/core/src/main/scala/sbt/internal/librarymanagement/LMSysProp.scala @@ -0,0 +1,63 @@ +/* + * sbt + * Copyright 2011 - 2018, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under Apache License 2.0 (see LICENSE) + */ + +package sbt +package internal +package librarymanagement + +import java.util.Locale +import scala.util.control.NonFatal + +object LMSysProp { + def booleanOpt(name: String): Option[Boolean] = + sys.props.get(name).flatMap { x => + x.toLowerCase(Locale.ENGLISH) match { + case "1" | "always" | "true" => Some(true) + case "0" | "never" | "false" => Some(false) + case "auto" => None + case _ => None + } + } + + def getOrFalse(name: String): Boolean = booleanOpt(name).getOrElse(false) + def getOrTrue(name: String): Boolean = booleanOpt(name).getOrElse(true) + + // System property style: + // 1. use sbt. prefix + // 2. prefer short nouns + // 3. use dot for namespacing, and avoid making dot-separated English phrase + // 4. make active/enable properties, instead of "sbt.disable." + // + // Good: sbt.offline + // + // Bad: + // sbt.disable.interface.classloader.cache + // sbt.task.timings.on.shutdown + // sbt.skip.version.write -> sbt.genbuildprops=false + + val useSecureResolvers: Boolean = getOrTrue("sbt.repository.secure") + + lazy val modifyVersionRange: Boolean = getOrTrue("sbt.modversionrange") + + lazy val isJavaVersion9Plus: Boolean = javaVersion > 8 + lazy val javaVersion: Int = { + try { + // See Oracle section 1.5.3 at: + // https://docs.oracle.com/javase/8/docs/technotes/guides/versioning/spec/versioning2.html + val version = sys.props("java.specification.version").split("\\.").toList.map(_.toInt) + version match { + case 1 :: minor :: _ => minor + case major :: _ => major + case _ => 0 + } + } catch { + case NonFatal(_) => 0 + } + } + + lazy val useGigahorse: Boolean = getOrFalse("sbt.gigahorse") +} diff --git a/core/src/main/scala/sbt/internal/librarymanagement/SemanticSelectorExtra.scala b/core/src/main/scala/sbt/internal/librarymanagement/SemanticSelectorExtra.scala index c609a1529..f3f28cf7a 100644 --- a/core/src/main/scala/sbt/internal/librarymanagement/SemanticSelectorExtra.scala +++ b/core/src/main/scala/sbt/internal/librarymanagement/SemanticSelectorExtra.scala @@ -4,6 +4,7 @@ import sbt.librarymanagement.VersionNumber import sbt.internal.librarymanagement.SemSelOperator.{ Lt, Lte, Gt, Gte, Eq } import scala.annotation.tailrec +import java.util.Locale private[librarymanagement] abstract class SemSelAndChunkFunctions { protected def parse(andClauseToken: String): SemSelAndChunk = { @@ -123,10 +124,11 @@ private[librarymanagement] abstract class SemComparatorExtra { // Identifiers consisting of only digits are compared numerically. // Numeric identifiers always have lower precedence than non-numeric identifiers. // Identifiers with letters are compared case insensitive lexical order. - case (true, true) => implicitly[Ordering[Long]].compare(ts1head.toLong, ts2head.toLong) - case (false, true) => 1 - case (true, false) => -1 - case (false, false) => ts1head.toLowerCase.compareTo(ts2head.toLowerCase) + case (true, true) => implicitly[Ordering[Long]].compare(ts1head.toLong, ts2head.toLong) + case (false, true) => 1 + case (true, false) => -1 + case (false, false) => + ts1head.toLowerCase(Locale.ENGLISH).compareTo(ts2head.toLowerCase(Locale.ENGLISH)) } if (cmp == 0) compareTags(ts1.tail, ts2.tail) else cmp diff --git a/core/src/main/scala/sbt/librarymanagement/ArtifactExtra.scala b/core/src/main/scala/sbt/librarymanagement/ArtifactExtra.scala index f90b9e29b..63a992d2d 100644 --- a/core/src/main/scala/sbt/librarymanagement/ArtifactExtra.scala +++ b/core/src/main/scala/sbt/librarymanagement/ArtifactExtra.scala @@ -26,14 +26,18 @@ private[librarymanagement] abstract class ArtifactFunctions { 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 = + def apply(name: String, url: URL): Artifact = Artifact(name, url, false) + def apply(name: String, url: URL, allowInsecureProtocol: Boolean): Artifact = Artifact( name, extract(url, DefaultType), extract(url, DefaultExtension), None, Vector.empty, - Some(url) + Some(url), + Map.empty, + None, + allowInsecureProtocol ) private final val empty = Map.empty[String, String] diff --git a/core/src/main/scala/sbt/librarymanagement/CrossVersion.scala b/core/src/main/scala/sbt/librarymanagement/CrossVersion.scala index 6c37596b3..4ab1b6446 100644 --- a/core/src/main/scala/sbt/librarymanagement/CrossVersion.scala +++ b/core/src/main/scala/sbt/librarymanagement/CrossVersion.scala @@ -39,7 +39,7 @@ sealed class Disabled private () extends sbt.librarymanagement.CrossVersion() wi } object Disabled extends sbt.librarymanagement.Disabled { - def apply(): Disabled = new Disabled() + def apply(): Disabled = Disabled } /** @@ -331,14 +331,30 @@ trait CrossVersionFormats { with sbt.librarymanagement.ConstantFormats with sbt.librarymanagement.PatchFormats with sbt.librarymanagement.FullFormats => - implicit lazy val CrossVersionFormat: JsonFormat[sbt.librarymanagement.CrossVersion] = - flatUnionFormat6[ - sbt.librarymanagement.CrossVersion, - sbt.librarymanagement.Disabled, - sbt.librarymanagement.Disabled.type, - sbt.librarymanagement.Binary, - sbt.librarymanagement.Constant, - sbt.librarymanagement.Patch, - sbt.librarymanagement.Full + implicit lazy val CrossVersionFormat: JsonFormat[CrossVersion] = { + val format = flatUnionFormat6[ + CrossVersion, + Disabled, + Disabled.type, + Binary, + Constant, + Patch, + Full ]("type") + // This is a hand-crafted formatter to avoid Disabled$ showing up in JSON + new JsonFormat[CrossVersion] { + override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): CrossVersion = + format.read(jsOpt, unbuilder) + override def write[J](obj: CrossVersion, builder: Builder[J]): Unit = { + if (obj == Disabled) { + builder.beginPreObject() + builder.addFieldName("type") + builder.writeString("Disabled") + builder.endPreObject() + builder.beginObject() + builder.endObject() + } else format.write(obj, builder) + } + } + } } diff --git a/core/src/main/scala/sbt/librarymanagement/CrossVersionExtra.scala b/core/src/main/scala/sbt/librarymanagement/CrossVersionExtra.scala index d8e54d8c8..43a46073f 100644 --- a/core/src/main/scala/sbt/librarymanagement/CrossVersionExtra.scala +++ b/core/src/main/scala/sbt/librarymanagement/CrossVersionExtra.scala @@ -8,7 +8,11 @@ final case class ScalaVersion(full: String, binary: String) private[librarymanagement] abstract class CrossVersionFunctions { /** Compatibility with 0.13 */ - final def Disabled = sbt.librarymanagement.Disabled + @deprecated( + "use CrossVersion.disabled instead. prior to sbt 1.3.0, Diabled did not work without apply(). sbt/sbt#4977", + "1.3.0" + ) + final val Disabled = sbt.librarymanagement.Disabled final val Binary = sbt.librarymanagement.Binary final val Constant = sbt.librarymanagement.Constant final val Full = sbt.librarymanagement.Full @@ -37,7 +41,7 @@ private[librarymanagement] abstract class CrossVersionFunctions { def binary: CrossVersion = Binary() /** Disables cross versioning for a module. */ - def disabled: CrossVersion = Disabled + def disabled: CrossVersion = sbt.librarymanagement.Disabled /** Cross-versions a module with a constant string (typically the binary Scala version). */ def constant(value: String): CrossVersion = Constant(value) diff --git a/core/src/main/scala/sbt/librarymanagement/DependencyBuilders.scala b/core/src/main/scala/sbt/librarymanagement/DependencyBuilders.scala index 09b1d8468..99e64106d 100755 --- a/core/src/main/scala/sbt/librarymanagement/DependencyBuilders.scala +++ b/core/src/main/scala/sbt/librarymanagement/DependencyBuilders.scala @@ -67,7 +67,7 @@ object DependencyBuilders { } final class RepositoryName private[sbt] (name: String) { - def at(location: String) = { + def at(location: String): MavenRepository = { nonEmpty(location, "Repository location") MavenRepository(name, location) } diff --git a/core/src/main/scala/sbt/librarymanagement/EvictionWarning.scala b/core/src/main/scala/sbt/librarymanagement/EvictionWarning.scala index 22405934c..c090cd2ad 100644 --- a/core/src/main/scala/sbt/librarymanagement/EvictionWarning.scala +++ b/core/src/main/scala/sbt/librarymanagement/EvictionWarning.scala @@ -183,7 +183,7 @@ object EvictionPair { } val winnerRev = a.winner match { case Some(r) => s":${r.module.revision} is selected over ${revsStr}" - case _ => " is evicted completely" + case _ => " is evicted for all versions" } val title = s"\t* ${a.organization}:${a.name}$winnerRev" title :: (if (a.showCallers) callers.reverse else Nil) ::: List("") @@ -312,7 +312,9 @@ object EvictionWarning { binaryIncompatibleEvictionExists = true } case p => - if (!guessCompatible(p)) { + // don't report on a transitive eviction that does not have a winner + // https://github.com/sbt/sbt/issues/4946 + if (!guessCompatible(p) && p.winner.isDefined) { if (options.warnTransitiveEvictions) transitiveEvictions += p if (options.warnEvictionSummary) diff --git a/core/src/main/scala/sbt/librarymanagement/ModuleIDExtra.scala b/core/src/main/scala/sbt/librarymanagement/ModuleIDExtra.scala index f15c5acb3..40db9def1 100644 --- a/core/src/main/scala/sbt/librarymanagement/ModuleIDExtra.scala +++ b/core/src/main/scala/sbt/librarymanagement/ModuleIDExtra.scala @@ -8,6 +8,7 @@ import java.net.URL import sbt.internal.librarymanagement.mavenint.SbtPomExtraProperties import scala.collection.mutable.ListBuffer import sbt.librarymanagement.syntax._ +import sbt.util.Logger private[librarymanagement] abstract class ModuleIDExtra { def organization: String @@ -75,10 +76,10 @@ private[librarymanagement] abstract class ModuleIDExtra { // () required for chaining /** Do not follow dependencies of this module. Synonym for `intransitive`.*/ - def notTransitive() = intransitive() + def notTransitive(): ModuleID = intransitive() /** Do not follow dependencies of this module. Synonym for `notTransitive`.*/ - def intransitive() = withIsTransitive(false) + def intransitive(): ModuleID = withIsTransitive(false) /** * Marks this dependency as "changing". Ivy will always check if the metadata has changed and then if the artifact has changed, @@ -86,46 +87,58 @@ private[librarymanagement] abstract class ModuleIDExtra { * * See the "Changes in artifacts" section of https://ant.apache.org/ivy/history/trunk/concept.html for full details. */ - def changing() = withIsChanging(true) + def changing(): ModuleID = withIsChanging(true) /** * Indicates that conflict resolution should only select this module's revision. * This prevents a newer revision from being pulled in by a transitive dependency, for example. */ - def force() = withIsForce(true) + def force(): ModuleID = withIsForce(true) + + private[sbt] def validateProtocol(logger: Logger): Unit = { + explicitArtifacts foreach { _.validateProtocol(logger) } + } /** * Specifies a URL from which the main artifact for this dependency can be downloaded. * This value is only consulted if the module is not found in a repository. * It is not included in published metadata. */ - def from(url: String) = artifacts(Artifact(name, new URL(url))) + def from(url: String): ModuleID = from(url, false) + + /** + * Specifies a URL from which the main artifact for this dependency can be downloaded. + * This value is only consulted if the module is not found in a repository. + * It is not included in published metadata. + */ + def from(url: String, allowInsecureProtocol: Boolean): ModuleID = + artifacts(Artifact(name, new URL(url), allowInsecureProtocol)) /** Adds a dependency on the artifact for this module with classifier `c`. */ - def classifier(c: String) = artifacts(Artifact(name, c)) + def classifier(c: String): ModuleID = artifacts(Artifact(name, c)) /** * 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*) = + def artifacts(newArtifacts: Artifact*): ModuleID = withExplicitArtifacts(newArtifacts.toVector ++ explicitArtifacts) /** * Applies the provided exclusions to dependencies of this module. Note that only exclusions that specify * both the exact organization and name and nothing else will be included in a pom.xml. */ - def excludeAll(rules: ExclusionRule*) = withExclusions(exclusions ++ rules) + def excludeAll(rules: ExclusionRule*): ModuleID = withExclusions(exclusions ++ rules) /** Excludes the dependency with organization `org` and `name` from being introduced by this dependency during resolution. */ - def exclude(org: String, name: String) = + def exclude(org: String, name: String): ModuleID = excludeAll(ExclusionRule().withOrganization(org).withName(name)) /** * Adds extra attributes for this module. All keys are prefixed with `e:` if they are not already so prefixed. * This information will only be published in an ivy.xml and not in a pom.xml. */ - def extra(attributes: (String, String)*) = + def extra(attributes: (String, String)*): ModuleID = withExtraAttributes(extraAttributes ++ ModuleID.checkE(attributes)) /** @@ -133,30 +146,30 @@ private[librarymanagement] abstract class ModuleIDExtra { * for performance and correctness. This method adds a dependency on this module's artifact with the "sources" * classifier. If you want to also depend on the main artifact, be sure to also call `jar()` or use `withSources()` instead. */ - def sources() = artifacts(Artifact.sources(name)) + def sources(): ModuleID = artifacts(Artifact.sources(name)) /** * Not recommended for new use. This method is not deprecated, but the `update-classifiers` task is preferred * for performance and correctness. This method adds a dependency on this module's artifact with the "javadoc" * classifier. If you want to also depend on the main artifact, be sure to also call `jar()` or use `withJavadoc()` instead. */ - def javadoc() = artifacts(Artifact.javadoc(name)) + def javadoc(): ModuleID = artifacts(Artifact.javadoc(name)) - def pomOnly() = artifacts(Artifact.pom(name)) + def pomOnly(): ModuleID = artifacts(Artifact.pom(name)) /** * Not recommended for new use. This method is not deprecated, but the `update-classifiers` task is preferred * for performance and correctness. This method adds a dependency on this module's artifact with the "sources" * classifier. If there is not already an explicit dependency on the main artifact, this adds one. */ - def withSources() = jarIfEmpty.sources() + def withSources(): ModuleID = jarIfEmpty.sources() /** * Not recommended for new use. This method is not deprecated, but the `update-classifiers` task is preferred * for performance and correctness. This method adds a dependency on this module's artifact with the "javadoc" * classifier. If there is not already an explicit dependency on the main artifact, this adds one. */ - def withJavadoc() = jarIfEmpty.javadoc() + def withJavadoc(): ModuleID = jarIfEmpty.javadoc() private def jarIfEmpty = if (explicitArtifacts.isEmpty) jar() else this @@ -164,14 +177,14 @@ private[librarymanagement] abstract class ModuleIDExtra { * Declares a dependency on the main artifact. This is implied by default unless artifacts are explicitly declared, such * as when adding a dependency on an artifact with a classifier. */ - def jar() = artifacts(Artifact(name)) + def jar(): ModuleID = artifacts(Artifact(name)) /** * Sets the Ivy branch of this module. */ - def branch(branchName: String) = withBranchName(Some(branchName)) + def branch(branchName: String): ModuleID = withBranchName(Some(branchName)) - def branch(branchName: Option[String]) = withBranchName(branchName) + def branch(branchName: Option[String]): ModuleID = withBranchName(branchName) } private[librarymanagement] abstract class ModuleIDFunctions { diff --git a/core/src/main/scala/sbt/librarymanagement/ResolverExtra.scala b/core/src/main/scala/sbt/librarymanagement/ResolverExtra.scala index d359f31ad..33944a268 100644 --- a/core/src/main/scala/sbt/librarymanagement/ResolverExtra.scala +++ b/core/src/main/scala/sbt/librarymanagement/ResolverExtra.scala @@ -7,6 +7,7 @@ import java.io.{ IOException, File } import java.net.URL import scala.xml.XML import org.xml.sax.SAXParseException +import sbt.util.Logger final class RawRepository(val resolver: AnyRef, name: String) extends Resolver(name) { override def toString = "Raw(" + resolver.toString + ")" @@ -94,8 +95,7 @@ private[sbt] class FakeRepository(resolver: AnyRef, name: String) extends xsbti. } private[librarymanagement] abstract class ResolverFunctions { - private[sbt] def useSecureResolvers = - sys.props.get("sbt.repository.secure") map { _.toLowerCase == "true" } getOrElse true + import sbt.internal.librarymanagement.LMSysProp.useSecureResolvers val TypesafeRepositoryRoot = typesafeRepositoryRoot(useSecureResolvers) val SbtRepositoryRoot = sbtRepositoryRoot(useSecureResolvers) @@ -403,4 +403,61 @@ private[librarymanagement] abstract class ResolverFunctions { val pList = Vector(localBasePattern) Patterns().withIvyPatterns(pList).withArtifactPatterns(pList).withIsMavenCompatible(false) } + + private[sbt] def warnHttp(value: String, suggestion: String, logger: Logger): Unit = { + logger.warn(s"insecure HTTP request is deprecated '$value'; switch to HTTPS$suggestion") + } + private[sbt] def isInsecureUrl(str: String): Boolean = { + // don't try to parse str as URL because it could contain $variable from Ivy pattern + str.startsWith("http:") && + !(str.startsWith("http://localhost/") + || str.startsWith("http://localhost:") + || str.startsWith("http://127.0.0.1/") + || str.startsWith("http://127.0.0.1:")) + } + private[sbt] def validateURLRepository(repo: URLRepository, logger: Logger): Unit = { + if (repo.allowInsecureProtocol) () + else { + val patterns = repo.patterns + val ivy = patterns.ivyPatterns.headOption match { + case Some(x) => isInsecureUrl(x) + case _ => false + } + val art = patterns.artifactPatterns.headOption match { + case Some(x) => isInsecureUrl(x) + case _ => false + } + if (ivy || art) { + warnHttp( + patterns.toString, + s""" or opt-in as Resolver.url("${repo.name}", url(...)).withAllowInsecureProtocol(true)""", + logger + ) + } + } + } + + private[sbt] def validateMavenRepo(repo: MavenRepo, logger: Logger): Unit = + if (repo.allowInsecureProtocol) () + else if (isInsecureUrl(repo.root)) { + warnHttp( + repo.root, + s""" or opt-in as ("${repo.name}" at "${repo.root}").withAllowInsecureProtocol(true)""", + logger + ) + } + + private[sbt] def validateArtifact(art: Artifact, logger: Logger): Unit = + if (art.allowInsecureProtocol) () + else { + art.url foreach { url => + if (isInsecureUrl(url.toString)) { + warnHttp( + art.toString, + " or opt-in using from(url(...), allowInsecureProtocol = true) on ModuleID or .withAllowInsecureProtocol(true) on Artifact", + logger + ) + } + } + } } diff --git a/core/src/test/scala/example/tests/CrossVersionCompatTest.scala b/core/src/test/scala/example/tests/CrossVersionCompatTest.scala new file mode 100644 index 000000000..8aa136e8c --- /dev/null +++ b/core/src/test/scala/example/tests/CrossVersionCompatTest.scala @@ -0,0 +1,72 @@ +package example.tests + +import sbt.librarymanagement.{ CrossVersion, Disabled } +import verify.BasicTestSuite +import com.github.ghik.silencer.silent + +@silent +object CrossVersionCompatTest extends BasicTestSuite { + test("CrossVersion.Disabled is typed to be Disabled") { + assert(CrossVersion.Disabled match { + case _: Disabled => true + case _ => false + }) + } + + test("CrossVersion.Disabled functions as disabled") { + assert(CrossVersion(CrossVersion.disabled, "1.0.0", "1.0") == None) + assert(CrossVersion(CrossVersion.Disabled, "1.0.0", "1.0") == None) + } + + test("CrossVersion.Disabled() is typed to be Disabled") { + assert(CrossVersion.Disabled() match { + case _: Disabled => true + case _ => false + }) + } + + test("CrossVersion.Disabled() functions as disabled") { + assert(CrossVersion(CrossVersion.disabled, "1.0.0", "1.0") == None) + assert(CrossVersion(CrossVersion.Disabled(), "1.0.0", "1.0") == None) + } + + test("CrossVersion.Disabled is stable") { + assert(CrossVersion.Disabled match { + case CrossVersion.Disabled => true + case _ => false + }) + } + + test("sbt.librarymanagement.Disabled is typed to be Disabled") { + assert(Disabled match { + case _: Disabled => true + case _ => false + }) + } + + test("sbt.librarymanagement.Disabled is stable") { + assert(Disabled match { + case Disabled => true + case _ => false + }) + } + + test("sbt.librarymanagement.Disabled() is typed to be Disabled") { + assert(Disabled() match { + case _: Disabled => true + case _ => false + }) + } + + test("CrossVersion.disabled is sbt.librarymanagement.Disabled") { + assert(CrossVersion.disabled == Disabled) + } + + test("CrossVersion.Disabled is sbt.librarymanagement.Disabled") { + assert(CrossVersion.Disabled == Disabled) + } + + test("CrossVersion.Disabled() is sbt.librarymanagement.Disabled") { + assert(CrossVersion.Disabled() == Disabled) + } +} diff --git a/core/src/test/scala/sbt/librarymanagement/ModuleIdTest.scala b/core/src/test/scala/sbt/librarymanagement/ModuleIdTest.scala index a9bab61f0..1698f317a 100644 --- a/core/src/test/scala/sbt/librarymanagement/ModuleIdTest.scala +++ b/core/src/test/scala/sbt/librarymanagement/ModuleIdTest.scala @@ -1,8 +1,11 @@ package sbt.librarymanagement import sbt.internal.librarymanagement.UnitSpec +import sjsonnew.support.scalajson.unsafe.{ Converter, CompactPrinter, Parser } class ModuleIdTest extends UnitSpec { + val expectedJson = + """{"organization":"com.acme","name":"foo","revision":"1","isChanging":false,"isTransitive":true,"isForce":false,"explicitArtifacts":[],"inclusions":[],"exclusions":[],"extraAttributes":{},"crossVersion":{"type":"Disabled"}}""" "Module Id" should "return cross-disabled module id as equal to a copy" in { ModuleID("com.acme", "foo", "1") shouldBe ModuleID("com.acme", "foo", "1") } @@ -14,4 +17,15 @@ class ModuleIdTest extends UnitSpec { (ModuleID("com.acme", "foo", "1") cross CrossVersion.binary) shouldBe (ModuleID("com.acme", "foo", "1") cross CrossVersion.binary) } + it should "format itself into JSON" in { + import LibraryManagementCodec._ + val json = Converter.toJson(ModuleID("com.acme", "foo", "1")).get + assert(CompactPrinter(json) == expectedJson) + } + it should "thaw back from JSON" in { + import LibraryManagementCodec._ + val json = Parser.parseUnsafe(expectedJson) + val m = Converter.fromJsonUnsafe[ModuleID](json) + assert(m == ModuleID("com.acme", "foo", "1")) + } } diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/CustomPomParser.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/CustomPomParser.scala index c906fc818..591e3e881 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/CustomPomParser.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/CustomPomParser.scala @@ -242,9 +242,6 @@ object CustomPomParser { transform(dd, _ => newId) case None => dd } - private[sbt] lazy val versionRangeFlag = sys.props.get("sbt.modversionrange") map { - _.toLowerCase == "true" - } getOrElse true import collection.JavaConverters._ def addExtra( @@ -281,7 +278,7 @@ object CustomPomParser { addExtra(dd, dependencyExtra) } val withVersionRangeMod: Seq[DependencyDescriptor] = - if (versionRangeFlag) withExtra map { stripVersionRange } else withExtra + if (LMSysProp.modifyVersionRange) withExtra map { stripVersionRange } else withExtra val unique = IvySbt.mergeDuplicateDefinitions(withVersionRangeMod) unique foreach dmd.addDependency diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/ErrorMessageAuthenticator.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/ErrorMessageAuthenticator.scala index 1e842c458..2ba03b741 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/ErrorMessageAuthenticator.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/ErrorMessageAuthenticator.scala @@ -15,7 +15,8 @@ object ErrorMessageAuthenticator { private var securityWarningLogged = false private def originalAuthenticator: Option[Authenticator] = { - if (isJavaVersion9Plus) getDefaultAuthenticator else getTheAuthenticator + if (LMSysProp.isJavaVersion9Plus) getDefaultAuthenticator + else getTheAuthenticator } private[this] def getTheAuthenticator: Option[Authenticator] = { @@ -100,15 +101,6 @@ object ErrorMessageAuthenticator { } doInstallIfIvy(originalAuthenticator) } - - private[this] def isJavaVersion9Plus = javaVersion > 8 - private[this] def javaVersion = { - // See Oracle section 1.5.3 at: - // https://docs.oracle.com/javase/8/docs/technotes/guides/versioning/spec/versioning2.html - val version = sys.props("java.specification.version").split("\\.").map(_.toInt) - if (version(0) == 1) version(1) else version(0) - } - } /** diff --git a/ivy/src/main/scala/sbt/librarymanagement/ivy/UpdateOptions.scala b/ivy/src/main/scala/sbt/librarymanagement/ivy/UpdateOptions.scala index 6f12ba053..0a41509bb 100644 --- a/ivy/src/main/scala/sbt/librarymanagement/ivy/UpdateOptions.scala +++ b/ivy/src/main/scala/sbt/librarymanagement/ivy/UpdateOptions.scala @@ -4,6 +4,7 @@ package ivy import org.apache.ivy.plugins.resolver.DependencyResolver import org.apache.ivy.core.settings.IvySettings import sbt.util.Logger +import sbt.internal.librarymanagement.LMSysProp /** * Represents configurable options for update task. @@ -36,8 +37,8 @@ final class UpdateOptions private[sbt] ( copy(interProjectFirst = interProjectFirst) def withLatestSnapshots(latestSnapshots: Boolean): UpdateOptions = copy(latestSnapshots = latestSnapshots) - def withCachedResolution(cachedResoluton: Boolean): UpdateOptions = - copy(cachedResolution = cachedResoluton) + def withCachedResolution(cachedResolution: Boolean): UpdateOptions = + copy(cachedResolution = cachedResolution) def withGigahorse(gigahorse: Boolean): UpdateOptions = copy(gigahorse = gigahorse) @@ -109,7 +110,7 @@ object UpdateOptions { interProjectFirst = true, latestSnapshots = true, cachedResolution = false, - gigahorse = sys.props.get("sbt.gigahorse") map { _.toLowerCase == "true" } getOrElse true, + gigahorse = LMSysProp.useGigahorse, resolverConverter = PartialFunction.empty, moduleResolvers = Map.empty ) diff --git a/common-test/src/main/scala/sbt/internal/librarymanagement/AbstractEngineSpec.scala b/ivy/src/test/scala/sbt/internal/librarymanagement/AbstractEngineSpec.scala similarity index 86% rename from common-test/src/main/scala/sbt/internal/librarymanagement/AbstractEngineSpec.scala rename to ivy/src/test/scala/sbt/internal/librarymanagement/AbstractEngineSpec.scala index e676b7857..55089330d 100644 --- a/common-test/src/main/scala/sbt/internal/librarymanagement/AbstractEngineSpec.scala +++ b/ivy/src/test/scala/sbt/internal/librarymanagement/AbstractEngineSpec.scala @@ -1,8 +1,9 @@ package sbt.internal.librarymanagement import sbt.librarymanagement._ +import verify.BasicTestSuite -abstract class AbstractEngineSpec extends UnitSpec { +abstract class AbstractEngineSpec extends BasicTestSuite { def cleanCache(): Unit def module( diff --git a/ivy/src/test/scala/sbt/internal/librarymanagement/ComponentManagerTest.scala b/ivy/src/test/scala/sbt/internal/librarymanagement/ComponentManagerTest.scala index 2a9f3f675..dc2947e26 100644 --- a/ivy/src/test/scala/sbt/internal/librarymanagement/ComponentManagerTest.scala +++ b/ivy/src/test/scala/sbt/internal/librarymanagement/ComponentManagerTest.scala @@ -7,65 +7,83 @@ import sbt.io.IO import org.apache.ivy.util.ChecksumHelper import IfMissing.Fail import xsbti.ComponentProvider +import verify.BasicTestSuite // TODO - We need to re-enable this test. Right now, we dont' have a "stub" launcher for this. // This is testing something which uses a launcher interface, but was grabbing the underlying class directly // when it really should, instead, be stubbing out the underyling class. -class ComponentManagerTest extends UnitSpec { +object ComponentManagerTest extends BasicTestSuite { val TestID = "manager-test" - "Component manager" should "throw an exception if 'file' is called for a non-existing component" in { + test( + "Component manager should throw an exception if 'file' is called for a non-existing component" + ) { withManager { manager => - intercept[InvalidComponent] { manager.file(TestID)(Fail) } - () + intercept[InvalidComponent] { + manager.file(TestID)(Fail) + () + } } } - it should "throw an exception if 'file' is called for an empty component" in { + + test("it should throw an exception if 'file' is called for an empty component") { withManager { manager => manager.define(TestID, Nil) - intercept[InvalidComponent] { manager.file(TestID)(Fail) } - () + intercept[InvalidComponent] { + manager.file(TestID)(Fail) + () + } } } - it should "return the file for a single-file component" in { + + test("it should return the file for a single-file component") { withManager { manager => val hash = defineFile(manager, TestID, "a") - checksum(manager.file(TestID)(Fail)) shouldBe hash + assert(checksum(manager.file(TestID)(Fail)) == hash) } } - it should "throw an exception if 'file' is called for multi-file component" in { + + test("it should throw an exception if 'file' is called for multi-file component") { withManager { manager => defineFiles(manager, TestID, "a", "b") - intercept[InvalidComponent] { manager.file(TestID)(Fail) } - () + intercept[InvalidComponent] { + manager.file(TestID)(Fail) + () + } } } - it should "return the files for a multi-file component" in { + + test("it should return the files for a multi-file component") { withManager { manager => val hashes = defineFiles(manager, TestID, "a", "b") - checksum(manager.files(TestID)(Fail)) should contain theSameElementsAs (hashes) + assert(checksum(manager.files(TestID)(Fail)).toSet == hashes.toSet) } } - it should "return the files for a single-file component" in { + + test("it should return the files for a single-file component") { withManager { manager => val hashes = defineFiles(manager, TestID, "a") - checksum(manager.files(TestID)(Fail)) should contain theSameElementsAs (hashes) + assert(checksum(manager.files(TestID)(Fail)).toSet == hashes.toSet) } } - it should "throw an exception if 'files' is called for a non-existing component" in { + + test("it should throw an exception if 'files' is called for a non-existing component") { withManager { manager => - intercept[InvalidComponent] { manager.files(TestID)(Fail) } - () + intercept[InvalidComponent] { + manager.files(TestID)(Fail) + () + } } } - it should "properly cache a file and then retrieve it to an unresolved component" in { + + test("it should properly cache a file and then retrieve it to an unresolved component") { withTemporaryDirectory { ivyHome => withManagerHome(ivyHome) { definingManager => val hash = defineFile(definingManager, TestID, "a") try { definingManager.cache(TestID) withManagerHome(ivyHome) { usingManager => - checksum(usingManager.file(TestID)(Fail)) shouldBe hash + assert(checksum(usingManager.file(TestID)(Fail)) == hash) } } finally { definingManager.clearCache(TestID) diff --git a/ivy/src/test/scala/sbt/internal/librarymanagement/CustomPomParserTest.scala b/ivy/src/test/scala/sbt/internal/librarymanagement/CustomPomParserTest.scala index 97d5c54cb..e987b7c18 100644 --- a/ivy/src/test/scala/sbt/internal/librarymanagement/CustomPomParserTest.scala +++ b/ivy/src/test/scala/sbt/internal/librarymanagement/CustomPomParserTest.scala @@ -8,9 +8,12 @@ import sbt.librarymanagement._ import sbt.librarymanagement.ivy.{ InlineIvyConfiguration, IvyPaths } import sbt.io.IO.withTemporaryDirectory import sbt.internal.util.ConsoleLogger +import verify.BasicTestSuite -class CustomPomParserTest extends UnitSpec { - "CustomPomParser" should "resolve an artifact with packaging 'scala-jar' as a regular jar file." in { +object CustomPomParserTest extends BasicTestSuite { + test( + "CustomPomParser should resolve an artifact with packaging 'scala-jar' as a regular jar file." + ) { val log = ConsoleLogger() withTemporaryDirectory { cacheDir => val repoUrl = getClass.getResource("/test-maven-repo") @@ -28,12 +31,12 @@ class CustomPomParserTest extends UnitSpec { ivy.resolve(mrid, resolveOpts, true) } - resolveReport.hasError shouldBe false - resolveReport.getArtifacts.size() shouldBe 1 + assert(!resolveReport.hasError) + assert(resolveReport.getArtifacts.size() == 1) val artifact: IvyArtifact = resolveReport.getArtifacts.asInstanceOf[java.util.List[IvyArtifact]].get(0) - artifact.getModuleRevisionId shouldBe mrid - artifact.getExt shouldBe "jar" + assert(artifact.getModuleRevisionId == mrid) + assert(artifact.getExt == "jar") } } } diff --git a/ivy/src/test/scala/sbt/internal/librarymanagement/DMSerializationSpec.scala b/ivy/src/test/scala/sbt/internal/librarymanagement/DMSerializationSpec.scala index 586b04531..ace394002 100644 --- a/ivy/src/test/scala/sbt/internal/librarymanagement/DMSerializationSpec.scala +++ b/ivy/src/test/scala/sbt/internal/librarymanagement/DMSerializationSpec.scala @@ -6,47 +6,59 @@ import java.io.File import sbt.librarymanagement._ import sjsonnew.shaded.scalajson.ast.unsafe._ import sjsonnew._, support.scalajson.unsafe._ -import org.scalatest.Assertion import LibraryManagementCodec._ +import verify.BasicTestSuite -class DMSerializationSpec extends UnitSpec { - "CrossVersion.full" should "roundtrip" in { +object DMSerializationSpec extends BasicTestSuite { + test("CrossVersion.full should roundtrip") { roundtripStr(CrossVersion.full: CrossVersion) } - "CrossVersion.binary" should "roundtrip" in { + + test("CrossVersion.binary should roundtrip") { roundtripStr(CrossVersion.binary: CrossVersion) } - "CrossVersion.Disabled" should "roundtrip" in { + + test("CrossVersion.Disabled should roundtrip") { roundtrip(Disabled(): CrossVersion) } - """Artifact("foo")""" should "roundtrip" in { + + test("""Artifact("foo") should roundtrip""") { roundtrip(Artifact("foo")) } - """Artifact("foo", "sources")""" should "roundtrip" in { + + test("""Artifact("foo", "sources") should roundtrip""") { roundtrip(Artifact("foo", "sources")) } - """Artifact.pom("foo")""" should "roundtrip" in { + + test("""Artifact.pom("foo") should roundtrip""") { roundtrip(Artifact.pom("foo")) } - """Artifact("foo", url("http://example.com/"))""" should "roundtrip" in { + + test("""Artifact("foo", url("http://example.com/")) should roundtrip""") { roundtrip(Artifact("foo", new URL("http://example.com/"))) } - """Artifact("foo").extra(("key", "value"))""" should "roundtrip" in { + + test("""Artifact("foo").extra(("key", "value")) should roundtrip""") { roundtrip(Artifact("foo").extra(("key", "value"))) } - """ModuleID("org", "name", "1.0")""" should "roundtrip" in { + + test("""ModuleID("org", "name", "1.0") should roundtrip""") { roundtrip(ModuleID("org", "name", "1.0")) } - """ModuleReport(ModuleID("org", "name", "1.0"), Nil, Nil)""" should "roundtrip" in { + + test("""ModuleReport(ModuleID("org", "name", "1.0"), Nil, Nil) should roundtrip""") { roundtripStr(ModuleReport(ModuleID("org", "name", "1.0"), Vector.empty, Vector.empty)) } - "Organization artifact report" should "roundtrip" in { + + test("Organization artifact report should roundtrip") { roundtripStr(organizationArtifactReportExample) } - "Configuration report" should "roundtrip" in { + + test("Configuration report should roundtrip") { roundtripStr(configurationReportExample) } - "Update report" should "roundtrip" in { + + test("Update report should roundtrip") { roundtripStr(updateReportExample) } @@ -68,13 +80,17 @@ class DMSerializationSpec extends UnitSpec { lazy val moduleReportExample = ModuleReport(ModuleID("org", "name", "1.0"), Vector.empty, Vector.empty) - def roundtrip[A: JsonReader: JsonWriter](a: A): Assertion = - roundtripBuilder(a) { _ shouldBe _ } + def roundtrip[A: JsonReader: JsonWriter](a: A): Unit = + roundtripBuilder(a) { (x1, x2) => + assert(x1 == x2) + } - def roundtripStr[A: JsonReader: JsonWriter](a: A): Assertion = - roundtripBuilder(a) { _.toString shouldBe _.toString } + def roundtripStr[A: JsonReader: JsonWriter](a: A): Unit = + roundtripBuilder(a) { (x1, x2) => + assert(x1.toString == x2.toString) + } - def roundtripBuilder[A: JsonReader: JsonWriter](a: A)(f: (A, A) => Assertion): Assertion = { + def roundtripBuilder[A: JsonReader: JsonWriter](a: A)(f: (A, A) => Unit): Unit = { val json = isoString to (Converter toJsonUnsafe a) println(json) val obj = Converter fromJsonUnsafe [A] (isoString from json) diff --git a/ivy/src/test/scala/sbt/internal/librarymanagement/EvictionWarningSpec.scala b/ivy/src/test/scala/sbt/internal/librarymanagement/EvictionWarningSpec.scala index 3a90fc05a..925bdb599 100644 --- a/ivy/src/test/scala/sbt/internal/librarymanagement/EvictionWarningSpec.scala +++ b/ivy/src/test/scala/sbt/internal/librarymanagement/EvictionWarningSpec.scala @@ -4,52 +4,269 @@ import sbt.librarymanagement._ import sbt.internal.librarymanagement.cross.CrossVersionUtil import sbt.librarymanagement.syntax._ -class EvictionWarningSpec extends BaseIvySpecification { +object EvictionWarningSpec extends BaseIvySpecification { // This is a specification to check the eviction warnings - """Eviction of non-overridden scala-library whose scalaVersion - """ should "be detected" in scalaVersionWarn1() - it should "not be detected if it's disabled" in scalaVersionWarn2() - it should "print out message about the eviction" in scalaVersionWarn3() - it should "print out message about the eviction with callers" in scalaVersionWarn4() - it should "print out summary about the eviction if warn eviction summary enabled" in scalaVersionWarn5() + import sbt.util.ShowLines._ + def scalaVersionDeps = Vector(scala2102, akkaActor230) - """Non-eviction of overridden scala-library whose scalaVersion - """ should "not be detected if it's enabled" in scalaVersionNoWarn1() - it should "not be detected if it's disabled" in scalaVersionNoWarn2() + test("Eviction of non-overridden scala-library whose scalaVersion should be detected") { + val m = module(defaultModuleId, scalaVersionDeps, Some("2.10.2"), overrideScalaVersion = false) + val report = ivyUpdate(m) + assert(EvictionWarning(m, fullOptions, report).scalaEvictions.size == 1) + } - """Including two (suspect) binary incompatible Java libraries to direct dependencies - """ should "be detected as eviction" in javaLibWarn1() - it should "not be detected if it's disabled" in javaLibWarn2() - it should "print out message about the eviction" in javaLibWarn3() - it should "print out message about the eviction with callers" in javaLibWarn4() - it should "print out summary about the eviction if warn eviction summary enabled" in javaLibWarn5() + test("it should not be detected if it's disabled") { + val m = module(defaultModuleId, scalaVersionDeps, Some("2.10.2"), overrideScalaVersion = false) + val report = ivyUpdate(m) + assert( + EvictionWarning(m, fullOptions.withWarnScalaVersionEviction(false), report).scalaEvictions.size == 0 + ) + } - """Including two (suspect) binary compatible Java libraries to direct dependencies - """ should "not be detected as eviction" in javaLibNoWarn1() - it should "not print out message about the eviction" in javaLibNoWarn2() + test("it should print out message about the eviction") { + val m = module(defaultModuleId, scalaVersionDeps, Some("2.10.2"), overrideScalaVersion = false) + val report = ivyUpdate(m) + assert( + EvictionWarning(m, fullOptions.withShowCallers(false), report).lines == + List( + "Scala version was updated by one of library dependencies:", + "\t* org.scala-lang:scala-library:2.10.3 is selected over 2.10.2", + "", + "To force scalaVersion, add the following:", + "\tscalaModuleInfo ~= (_.map(_.withOverrideScalaVersion(true)))" + ) + ) + } - """Including two (suspect) transitively binary incompatible Java libraries to direct dependencies - """ should "be detected as eviction" in javaLibTransitiveWarn2() + test("it should print out message about the eviction with callers") { + val m = module(defaultModuleId, scalaVersionDeps, Some("2.10.2"), overrideScalaVersion = false) + val report = ivyUpdate(m) + assert( + EvictionWarning(m, fullOptions, report).lines == + List( + "Scala version was updated by one of library dependencies:", + "\t* org.scala-lang:scala-library:2.10.3 is selected over 2.10.2", + "\t +- com.typesafe.akka:akka-actor_2.10:2.3.0 (depends on 2.10.3)", + "\t +- com.example:foo:0.1.0 (depends on 2.10.2)", + "", + "To force scalaVersion, add the following:", + "\tscalaModuleInfo ~= (_.map(_.withOverrideScalaVersion(true)))" + ) + ) + } - //it should "print out message about the eviction if it's enabled" in javaLibTransitiveWarn3() + test("it should print out summary about the eviction if warn eviction summary enabled") { + val m = module(defaultModuleId, scalaVersionDeps, Some("2.10.2"), overrideScalaVersion = false) + val report = ivyUpdate(m) + assert( + EvictionWarning(m, EvictionWarningOptions.summary, report).lines == + List( + "There may be incompatibilities among your library dependencies; run 'evicted' to see detailed eviction warnings." + ) + ) + } - """Including two (suspect) binary incompatible Scala libraries to direct dependencies - """ should "be detected as eviction" in scalaLibWarn1() - it should "print out message about the eviction" in scalaLibWarn2() - it should "print out summary about the eviction if warn eviction summary enabled" in scalaLibWarn3() + test( + """Non-eviction of overridden scala-library whose scalaVersion should "not be detected if it's enabled"""" + ) { + val m = module(defaultModuleId, scalaVersionDeps, Some("2.10.2")) + val report = ivyUpdate(m) + assert(EvictionWarning(m, fullOptions, report).scalaEvictions.size == 0) + } - """Including two (suspect) binary compatible Scala libraries to direct dependencies - """ should "not be detected as eviction" in scalaLibNoWarn1() - it should "not print out message about the eviction" in scalaLibNoWarn2() - it should "not print out summary about the eviction even if warn eviction summary enabled" in scalaLibNoWarn3() + test("it should not be detected if it's disabled") { + val m = module(defaultModuleId, scalaVersionDeps, Some("2.10.2")) + val report = ivyUpdate(m) + assert( + EvictionWarning(m, fullOptions.withWarnScalaVersionEviction(false), report).scalaEvictions.size == 0 + ) + } - """Including two (suspect) transitively binary incompatible Scala libraries to direct dependencies - """ should "be detected as eviction" in scalaLibTransitiveWarn2() - it should "print out message about the eviction if it's enabled" in scalaLibTransitiveWarn3() - it should "print out summary about the eviction if warn eviction summary enabled" in scalaLibTransitiveWarn4() + test( + """Including two (suspect) binary incompatible Java libraries to direct dependencies should be detected as eviction""" + ) { + val m = module(defaultModuleId, javaLibDirectDeps, Some("2.10.3")) + val report = ivyUpdate(m) + assert(EvictionWarning(m, fullOptions, report).reportedEvictions.size == 1) + } - "Comparing sbt 0.x" should "use Second Segment Variation semantics" in { + test("it should not be detected if it's disabled") { + val m = module(defaultModuleId, javaLibDirectDeps, Some("2.10.3")) + val report = ivyUpdate(m) + assert( + EvictionWarning( + m, + fullOptions + .withWarnDirectEvictions(false) + .withWarnTransitiveEvictions(false), + report + ).reportedEvictions.size == 0 + ) + } + + test("it should print out message about the eviction") { + val m = module(defaultModuleId, javaLibDirectDeps, Some("2.10.3")) + val report = ivyUpdate(m) + assert( + EvictionWarning(m, fullOptions, report).lines == + List( + "Found version conflict(s) in library dependencies; some are suspected to be binary incompatible:", + "", + "\t* commons-io:commons-io:2.4 is selected over 1.4", + "\t +- com.example:foo:0.1.0 (depends on 1.4)", + "" + ) + ) + } + + test("it should print out message about the eviction with callers") { + val m = module(defaultModuleId, javaLibDirectDeps, Some("2.10.3")) + val report = ivyUpdate(m) + assert( + EvictionWarning(m, fullOptions.withShowCallers(true), report).lines == + List( + "Found version conflict(s) in library dependencies; some are suspected to be binary incompatible:", + "", + "\t* commons-io:commons-io:2.4 is selected over 1.4", + "\t +- com.example:foo:0.1.0 (depends on 1.4)", + "" + ) + ) + } + + test("it should print out summary about the eviction if warn eviction summary enabled") { + val m = module(defaultModuleId, javaLibDirectDeps, Some("2.10.3")) + val report = ivyUpdate(m) + assert( + EvictionWarning(m, EvictionWarningOptions.summary, report).lines == + List( + "There may be incompatibilities among your library dependencies; run 'evicted' to see detailed eviction warnings." + ) + ) + } + + test( + """Including two (suspect) binary compatible Java libraries to direct dependencies should not be detected as eviction""" + ) { + val deps = Vector(commonsIo14, commonsIo13) + val m = module(defaultModuleId, deps, Some("2.10.3")) + val report = ivyUpdate(m) + assert(EvictionWarning(m, fullOptions, report).reportedEvictions.size == 0) + } + + test("it should not print out message about the eviction") { + val deps = Vector(commonsIo14, commonsIo13) + val m = module(defaultModuleId, deps, Some("2.10.3")) + val report = ivyUpdate(m) + assert(EvictionWarning(m, fullOptions, report).lines == Nil) + } + + test( + """Including two (suspect) transitively binary incompatible Java libraries to direct dependencies should be detected as eviction""" + ) { + val m = module(defaultModuleId, javaLibTransitiveDeps, Some("2.10.3")) + val report = ivyUpdate(m) + assert(EvictionWarning(m, fullOptions, report).reportedEvictions.size == 1) + } + + test( + """Including two (suspect) binary incompatible Scala libraries to direct dependencies should be detected as eviction""" + ) { + val deps = Vector(scala2104, akkaActor214, akkaActor234) + val m = module(defaultModuleId, deps, Some("2.10.4")) + val report = ivyUpdate(m) + assert(EvictionWarning(m, fullOptions, report).reportedEvictions.size == 1) + } + + test("it should print out message about the eviction") { + val deps = Vector(scala2104, akkaActor214, akkaActor234) + val m = module(defaultModuleId, deps, Some("2.10.4")) + val report = ivyUpdate(m) + assert( + EvictionWarning(m, fullOptions, report).lines == + List( + "Found version conflict(s) in library dependencies; some are suspected to be binary incompatible:", + "", + "\t* com.typesafe.akka:akka-actor_2.10:2.3.4 is selected over 2.1.4", + "\t +- com.example:foo:0.1.0 (depends on 2.1.4)", + "" + ) + ) + } + + test("it should print out summary about the eviction if warn eviction summary enabled") { + val deps = Vector(scala2104, akkaActor214, akkaActor234) + val m = module(defaultModuleId, deps, Some("2.10.4")) + val report = ivyUpdate(m) + assert( + EvictionWarning(m, EvictionWarningOptions.summary, report).lines == + List( + "There may be incompatibilities among your library dependencies; run 'evicted' to see detailed eviction warnings." + ) + ) + } + + test( + """Including two (suspect) binary compatible Scala libraries to direct dependencies should not be detected as eviction""" + ) { + val deps = Vector(scala2104, akkaActor230, akkaActor234) + val m = module(defaultModuleId, deps, Some("2.10.4")) + val report = ivyUpdate(m) + assert(EvictionWarning(m, fullOptions, report).reportedEvictions.size == 0) + } + + test("it should not print out message about the eviction") { + val deps = Vector(scala2104, akkaActor230, akkaActor234) + val m = module(defaultModuleId, deps, Some("2.10.4")) + val report = ivyUpdate(m) + assert(EvictionWarning(m, fullOptions, report).lines == Nil) + } + + test("it should not print out summary about the eviction even if warn eviction summary enabled") { + val deps = Vector(scala2104, akkaActor230, akkaActor234) + val m = module(defaultModuleId, deps, Some("2.10.4")) + val report = ivyUpdate(m) + assert(EvictionWarning(m, EvictionWarningOptions.summary, report).lines == Nil) + } + + test( + """Including two (suspect) transitively binary incompatible Scala libraries to direct dependencies should be detected as eviction""" + ) { + val m = module(defaultModuleId, scalaLibTransitiveDeps, Some("2.10.4")) + val report = ivyUpdate(m) + assert(EvictionWarning(m, fullOptions, report).reportedEvictions.size == 1) + } + + test("it should print out message about the eviction if it's enabled") { + val m = module(defaultModuleId, scalaLibTransitiveDeps, Some("2.10.4")) + val report = ivyUpdate(m) + assert( + EvictionWarning(m, fullOptions, report).lines == + List( + "Found version conflict(s) in library dependencies; some are suspected to be binary incompatible:", + "", + "\t* com.typesafe.akka:akka-actor_2.10:2.3.4 is selected over 2.1.4", + "\t +- com.typesafe.akka:akka-remote_2.10:2.3.4 (depends on 2.3.4)", + "\t +- org.w3:banana-rdf_2.10:0.4 (depends on 2.1.4)", + "\t +- org.w3:banana-sesame_2.10:0.4 (depends on 2.1.4)", + "" + ) + ) + } + + test("it should print out summary about the eviction if warn eviction summary enabled") { + val m = module(defaultModuleId, scalaLibTransitiveDeps, Some("2.10.4")) + val report = ivyUpdate(m) + assert( + EvictionWarning(m, EvictionWarningOptions.summary, report).lines == + List( + "There may be incompatibilities among your library dependencies; run 'evicted' to see detailed eviction warnings." + ) + ) + } + + test("Comparing sbt 0.x should use Second Segment Variation semantics") { val m1 = "org.scala-sbt" % "util-logging" % "0.13.16" val m2 = "org.scala-sbt" % "util-logging" % "0.13.1" assert( @@ -57,7 +274,7 @@ class EvictionWarningSpec extends BaseIvySpecification { ) } - "Comparing sbt 1.x" should "use Semantic Versioning semantics" in { + test("Comparing sbt 1.x should use Semantic Versioning semantics") { val m1 = "org.scala-sbt" % "util-logging_2.12" % "1.0.0" val m2 = "org.scala-sbt" % "util-logging_2.12" % "1.1.0" assert( @@ -91,244 +308,9 @@ class EvictionWarningSpec extends BaseIvySpecification { ModuleID("com.typesafe.akka", "akka-remote", "2.3.4").withConfigurations(Some("compile")) cross CrossVersion.binary // uses akka-actor 2.3.4 def fullOptions = EvictionWarningOptions.full - - import sbt.util.ShowLines._ - - def scalaVersionDeps = Vector(scala2102, akkaActor230) - - def scalaVersionWarn1() = { - val m = module(defaultModuleId, scalaVersionDeps, Some("2.10.2"), overrideScalaVersion = false) - val report = ivyUpdate(m) - EvictionWarning(m, fullOptions, report).scalaEvictions should have size (1) - } - - def scalaVersionWarn2() = { - val m = module(defaultModuleId, scalaVersionDeps, Some("2.10.2"), overrideScalaVersion = false) - val report = ivyUpdate(m) - EvictionWarning(m, fullOptions.withWarnScalaVersionEviction(false), report).scalaEvictions should have size (0) - } - - def scalaVersionWarn3() = { - val m = module(defaultModuleId, scalaVersionDeps, Some("2.10.2"), overrideScalaVersion = false) - val report = ivyUpdate(m) - EvictionWarning(m, fullOptions.withShowCallers(false), report).lines shouldBe - List( - "Scala version was updated by one of library dependencies:", - "\t* org.scala-lang:scala-library:2.10.3 is selected over 2.10.2", - "", - "To force scalaVersion, add the following:", - "\tscalaModuleInfo ~= (_.map(_.withOverrideScalaVersion(true)))" - ) - } - - def scalaVersionWarn4() = { - val m = module(defaultModuleId, scalaVersionDeps, Some("2.10.2"), overrideScalaVersion = false) - val report = ivyUpdate(m) - EvictionWarning(m, fullOptions, report).lines shouldBe - List( - "Scala version was updated by one of library dependencies:", - "\t* org.scala-lang:scala-library:2.10.3 is selected over 2.10.2", - "\t +- com.typesafe.akka:akka-actor_2.10:2.3.0 (depends on 2.10.3)", - "\t +- com.example:foo:0.1.0 (depends on 2.10.2)", - "", - "To force scalaVersion, add the following:", - "\tscalaModuleInfo ~= (_.map(_.withOverrideScalaVersion(true)))" - ) - } - - def scalaVersionWarn5() = { - val m = module(defaultModuleId, scalaVersionDeps, Some("2.10.2"), overrideScalaVersion = false) - val report = ivyUpdate(m) - EvictionWarning(m, EvictionWarningOptions.summary, report).lines shouldBe - List( - "There may be incompatibilities among your library dependencies; run 'evicted' to see detailed eviction warnings." - ) - } - - def scalaVersionNoWarn1() = { - val m = module(defaultModuleId, scalaVersionDeps, Some("2.10.2")) - val report = ivyUpdate(m) - EvictionWarning(m, fullOptions, report).scalaEvictions should have size (0) - } - - def scalaVersionNoWarn2() = { - val m = module(defaultModuleId, scalaVersionDeps, Some("2.10.2")) - val report = ivyUpdate(m) - EvictionWarning(m, fullOptions.withWarnScalaVersionEviction(false), report).scalaEvictions should have size (0) - } - def javaLibDirectDeps = Vector(commonsIo14, commonsIo24) - - def javaLibWarn1() = { - val m = module(defaultModuleId, javaLibDirectDeps, Some("2.10.3")) - val report = ivyUpdate(m) - EvictionWarning(m, fullOptions, report).reportedEvictions should have size (1) - } - - def javaLibWarn2() = { - val m = module(defaultModuleId, javaLibDirectDeps, Some("2.10.3")) - val report = ivyUpdate(m) - EvictionWarning( - m, - fullOptions - .withWarnDirectEvictions(false) - .withWarnTransitiveEvictions(false), - report - ).reportedEvictions should have size (0) - } - - def javaLibWarn3() = { - val m = module(defaultModuleId, javaLibDirectDeps, Some("2.10.3")) - val report = ivyUpdate(m) - EvictionWarning(m, fullOptions, report).lines shouldBe - List( - "Found version conflict(s) in library dependencies; some are suspected to be binary incompatible:", - "", - "\t* commons-io:commons-io:2.4 is selected over 1.4", - "\t +- com.example:foo:0.1.0 (depends on 1.4)", - "" - ) - } - - def javaLibWarn4() = { - val m = module(defaultModuleId, javaLibDirectDeps, Some("2.10.3")) - val report = ivyUpdate(m) - EvictionWarning(m, fullOptions.withShowCallers(true), report).lines shouldBe - List( - "Found version conflict(s) in library dependencies; some are suspected to be binary incompatible:", - "", - "\t* commons-io:commons-io:2.4 is selected over 1.4", - "\t +- com.example:foo:0.1.0 (depends on 1.4)", - "" - ) - } - - def javaLibWarn5() = { - val m = module(defaultModuleId, javaLibDirectDeps, Some("2.10.3")) - val report = ivyUpdate(m) - EvictionWarning(m, EvictionWarningOptions.summary, report).lines shouldBe - List( - "There may be incompatibilities among your library dependencies; run 'evicted' to see detailed eviction warnings." - ) - } - - def javaLibNoWarn1() = { - val deps = Vector(commonsIo14, commonsIo13) - val m = module(defaultModuleId, deps, Some("2.10.3")) - val report = ivyUpdate(m) - EvictionWarning(m, fullOptions, report).reportedEvictions should have size (0) - } - - def javaLibNoWarn2() = { - val deps = Vector(commonsIo14, commonsIo13) - val m = module(defaultModuleId, deps, Some("2.10.3")) - val report = ivyUpdate(m) - EvictionWarning(m, fullOptions, report).lines shouldBe Nil - } - def javaLibTransitiveDeps = Vector(unfilteredUploads080, bnfparser10) - - def javaLibTransitiveWarn2() = { - val m = module(defaultModuleId, javaLibTransitiveDeps, Some("2.10.3")) - val report = ivyUpdate(m) - EvictionWarning(m, fullOptions, report).reportedEvictions should have size (1) - } - - def javaLibTransitiveWarn3() = { - val m = module(defaultModuleId, javaLibTransitiveDeps, Some("2.10.3")) - val report = ivyUpdate(m) - EvictionWarning(m, fullOptions, report).lines shouldBe - List( - "There may be incompatibilities among your library dependencies; run 'evicted' to see detailed eviction warnings.", - "Here are some of the libraries that were evicted:", - "\t* commons-io:commons-io:1.4 -> 2.4 (caller: ca.gobits.bnf:bnfparser:1.0, net.databinder:unfiltered-uploads_2.10:0.8.0)" - ) - } - - def scalaLibWarn1() = { - val deps = Vector(scala2104, akkaActor214, akkaActor234) - val m = module(defaultModuleId, deps, Some("2.10.4")) - val report = ivyUpdate(m) - EvictionWarning(m, fullOptions, report).reportedEvictions should have size (1) - } - - def scalaLibWarn2() = { - val deps = Vector(scala2104, akkaActor214, akkaActor234) - val m = module(defaultModuleId, deps, Some("2.10.4")) - val report = ivyUpdate(m) - EvictionWarning(m, fullOptions, report).lines shouldBe - List( - "Found version conflict(s) in library dependencies; some are suspected to be binary incompatible:", - "", - "\t* com.typesafe.akka:akka-actor_2.10:2.3.4 is selected over 2.1.4", - "\t +- com.example:foo:0.1.0 (depends on 2.1.4)", - "" - ) - } - - def scalaLibWarn3() = { - val deps = Vector(scala2104, akkaActor214, akkaActor234) - val m = module(defaultModuleId, deps, Some("2.10.4")) - val report = ivyUpdate(m) - EvictionWarning(m, EvictionWarningOptions.summary, report).lines shouldBe - List( - "There may be incompatibilities among your library dependencies; run 'evicted' to see detailed eviction warnings." - ) - } - - def scalaLibNoWarn1() = { - val deps = Vector(scala2104, akkaActor230, akkaActor234) - val m = module(defaultModuleId, deps, Some("2.10.4")) - val report = ivyUpdate(m) - EvictionWarning(m, fullOptions, report).reportedEvictions should have size (0) - } - - def scalaLibNoWarn2() = { - val deps = Vector(scala2104, akkaActor230, akkaActor234) - val m = module(defaultModuleId, deps, Some("2.10.4")) - val report = ivyUpdate(m) - EvictionWarning(m, fullOptions, report).lines shouldBe Nil - } - - def scalaLibNoWarn3() = { - val deps = Vector(scala2104, akkaActor230, akkaActor234) - val m = module(defaultModuleId, deps, Some("2.10.4")) - val report = ivyUpdate(m) - EvictionWarning(m, EvictionWarningOptions.summary, report).lines shouldBe Nil - } - def scalaLibTransitiveDeps = Vector(scala2104, bananaSesame04, akkaRemote234) - - def scalaLibTransitiveWarn2() = { - val m = module(defaultModuleId, scalaLibTransitiveDeps, Some("2.10.4")) - val report = ivyUpdate(m) - EvictionWarning(m, fullOptions, report).reportedEvictions should have size (1) - } - - def scalaLibTransitiveWarn3() = { - val m = module(defaultModuleId, scalaLibTransitiveDeps, Some("2.10.4")) - val report = ivyUpdate(m) - EvictionWarning(m, fullOptions, report).lines shouldBe - List( - "Found version conflict(s) in library dependencies; some are suspected to be binary incompatible:", - "", - "\t* com.typesafe.akka:akka-actor_2.10:2.3.4 is selected over 2.1.4", - "\t +- com.typesafe.akka:akka-remote_2.10:2.3.4 (depends on 2.3.4)", - "\t +- org.w3:banana-rdf_2.10:0.4 (depends on 2.1.4)", - "\t +- org.w3:banana-sesame_2.10:0.4 (depends on 2.1.4)", - "" - ) - } - - def scalaLibTransitiveWarn4() = { - val m = module(defaultModuleId, scalaLibTransitiveDeps, Some("2.10.4")) - val report = ivyUpdate(m) - EvictionWarning(m, EvictionWarningOptions.summary, report).lines shouldBe - List( - "There may be incompatibilities among your library dependencies; run 'evicted' to see detailed eviction warnings." - ) - } - def dummyScalaModuleInfo(v: String): ScalaModuleInfo = ScalaModuleInfo( scalaFullVersion = v, diff --git a/ivy/src/test/scala/sbt/internal/librarymanagement/FakeResolverSpecification.scala b/ivy/src/test/scala/sbt/internal/librarymanagement/FakeResolverSpecification.scala index fdb5cc413..89095a51c 100644 --- a/ivy/src/test/scala/sbt/internal/librarymanagement/FakeResolverSpecification.scala +++ b/ivy/src/test/scala/sbt/internal/librarymanagement/FakeResolverSpecification.scala @@ -6,7 +6,7 @@ import java.io.File import sbt.librarymanagement.{ ModuleID, RawRepository, Resolver, UpdateReport, ResolveException } -class FakeResolverSpecification extends BaseIvySpecification { +object FakeResolverSpecification extends BaseIvySpecification { import FakeResolver._ val myModule = @@ -17,36 +17,42 @@ class FakeResolverSpecification extends BaseIvySpecification { val nonExisting = ModuleID("com.example", "does-not-exist", "1.2.3").withConfigurations(Some("compile")) - "The FakeResolver" should "find modules with only one artifact" in { + test("The FakeResolver should find modules with only one artifact") { val m = getModule(myModule) val report = ivyUpdate(m) val allFiles = getAllFiles(report) - report.allModules.length shouldBe 1 - report.configurations.length shouldBe 3 - allFiles.toSet.size shouldBe 1 - allFiles(1).getName shouldBe "artifact1-0.0.1-SNAPSHOT.jar" + assert(report.allModules.length == 1) + assert(report.configurations.length == 3) + assert(allFiles.toSet.size == 1) + assert(allFiles(1).getName == "artifact1-0.0.1-SNAPSHOT.jar") } - it should "find modules with more than one artifact" in { + test("it should find modules with more than one artifact") { val m = getModule(example) val report = ivyUpdate(m) val allFiles = getAllFiles(report).toSet - report.allModules.length shouldBe 1 - report.configurations.length shouldBe 3 - allFiles.toSet.size shouldBe 2 - allFiles map (_.getName) shouldBe Set("artifact1-1.0.0.jar", "artifact2-1.0.0.txt") + assert(report.allModules.length == 1) + assert(report.configurations.length == 3) + assert(allFiles.toSet.size == 2) + assert(allFiles.map(_.getName) == Set("artifact1-1.0.0.jar", "artifact2-1.0.0.txt")) } - it should "fail gracefully when asked for unknown modules" in { + test("it should fail gracefully when asked for unknown modules") { val m = getModule(nonExisting) - a[ResolveException] should be thrownBy ivyUpdate(m) + intercept[ResolveException] { + ivyUpdate(m) + () + } } - it should "fail gracefully when some artifacts cannot be found" in { + test("it should fail gracefully when some artifacts cannot be found") { val m = getModule(anotherExample) - the[ResolveException] thrownBy ivyUpdate(m) should have message "download failed: com.example#another-example;1.0.0!non-existing.txt" + intercept[ResolveException] { + ivyUpdate(m) + () + } } private def artifact1 = new File(getClass.getResource("/artifact1.jar").toURI.getPath) diff --git a/ivy/src/test/scala/sbt/internal/librarymanagement/FrozenModeSpec.scala b/ivy/src/test/scala/sbt/internal/librarymanagement/FrozenModeSpec.scala index c6620bee7..cae7b3f48 100644 --- a/ivy/src/test/scala/sbt/internal/librarymanagement/FrozenModeSpec.scala +++ b/ivy/src/test/scala/sbt/internal/librarymanagement/FrozenModeSpec.scala @@ -4,7 +4,7 @@ import sbt.librarymanagement._ import sbt.librarymanagement.ivy.UpdateOptions import sbt.librarymanagement.syntax._ -class FrozenModeSpec extends BaseIvySpecification { +object FrozenModeSpec extends BaseIvySpecification { private final val targetDir = Some(currentDependency) private final val onlineConf = makeUpdateConfiguration(false, targetDir) private final val frozenConf = makeUpdateConfiguration(false, targetDir).withFrozen(true) @@ -26,7 +26,7 @@ class FrozenModeSpec extends BaseIvySpecification { "com.lihaoyi" % "sourcecode_2.12" % "0.1.3" % "compile" ) - it should "fail when artifacts are missing in the cache" in { + test("fail when artifacts are missing in the cache") { cleanIvyCache() def update(module: IvySbt#Module, conf: UpdateConfiguration) = IvyActions.updateEither(module, conf, warningConf, log) diff --git a/ivy/src/test/scala/sbt/internal/librarymanagement/InclExclSpec.scala b/ivy/src/test/scala/sbt/internal/librarymanagement/InclExclSpec.scala index 1c35fc007..d05f115ef 100644 --- a/ivy/src/test/scala/sbt/internal/librarymanagement/InclExclSpec.scala +++ b/ivy/src/test/scala/sbt/internal/librarymanagement/InclExclSpec.scala @@ -2,10 +2,53 @@ package sbt.internal.librarymanagement import sbt.librarymanagement._ import sbt.librarymanagement.syntax._ -import org.scalatest.Assertion import DependencyBuilders.OrganizationArtifactName -class InclExclSpec extends BaseIvySpecification { +object InclExclSpec extends BaseIvySpecification { + val scala210 = Some("2.10.4") + test("it should exclude any version of lift-json via a new exclusion rule") { + val toExclude = ExclusionRule("net.liftweb", "lift-json_2.10") + val report = getIvyReport(createLiftDep(toExclude), scala210) + testLiftJsonIsMissing(report) + } + + test("it should exclude any version of lift-json with explicit Scala version") { + val excluded: OrganizationArtifactName = "net.liftweb" % "lift-json_2.10" + val report = getIvyReport(createLiftDep(excluded), scala210) + testLiftJsonIsMissing(report) + } + + test("it should exclude any version of cross-built lift-json") { + val excluded: OrganizationArtifactName = "net.liftweb" %% "lift-json" + val report = getIvyReport(createLiftDep(excluded), scala210) + testLiftJsonIsMissing(report) + } + + val scala2122 = Some("2.12.2") + test("it should exclude a concrete version of lift-json when it's full cross version") { + val excluded: ModuleID = ("org.scalameta" % "scalahost" % "1.7.0").cross(CrossVersion.full) + val report = getIvyReport(createMetaDep(excluded), scala2122) + testScalahostIsMissing(report) + } + + test("it should exclude any version of lift-json when it's full cross version") { + val excluded = new OrganizationArtifactName("net.liftweb", "lift-json", CrossVersion.full) + val report = getIvyReport(createMetaDep(excluded), scala2122) + testScalahostIsMissing(report) + } + + test("it should exclude any version of scala-library via * artifact id") { + val toExclude = ExclusionRule("org.scala-lang", "*") + val report = getIvyReport(createLiftDep(toExclude), scala210) + testScalaLibraryIsMissing(report) + } + + test("it should exclude any version of scala-library via * org id") { + val toExclude = ExclusionRule("*", "scala-library") + val report = getIvyReport(createLiftDep(toExclude), scala210) + testScalaLibraryIsMissing(report) + } + def createLiftDep(toExclude: ExclusionRule): ModuleID = ("net.liftweb" %% "lift-mapper" % "2.6-M4" % "compile").excludeAll(toExclude) @@ -20,68 +63,24 @@ class InclExclSpec extends BaseIvySpecification { ivyUpdate(ivyModule) } - def testLiftJsonIsMissing(report: UpdateReport): Assertion = { + def testLiftJsonIsMissing(report: UpdateReport): Unit = { assert( !report.allModules.exists(_.name.contains("lift-json")), "lift-json has not been excluded." ) } - def testScalaLibraryIsMissing(report: UpdateReport): Assertion = { + def testScalaLibraryIsMissing(report: UpdateReport): Unit = { assert( !report.allModules.exists(_.name.contains("scala-library")), "scala-library has not been excluded." ) } - def testScalahostIsMissing(report: UpdateReport): Assertion = { + def testScalahostIsMissing(report: UpdateReport): Unit = { assert( !report.allModules.exists(_.name.contains("scalahost")), "scalahost has not been excluded." ) } - - val scala210 = Some("2.10.4") - it should "exclude any version of lift-json via a new exclusion rule" in { - val toExclude = ExclusionRule("net.liftweb", "lift-json_2.10") - val report = getIvyReport(createLiftDep(toExclude), scala210) - testLiftJsonIsMissing(report) - } - - it should "exclude any version of lift-json with explicit Scala version" in { - val excluded: OrganizationArtifactName = "net.liftweb" % "lift-json_2.10" - val report = getIvyReport(createLiftDep(excluded), scala210) - testLiftJsonIsMissing(report) - } - - it should "exclude any version of cross-built lift-json" in { - val excluded: OrganizationArtifactName = "net.liftweb" %% "lift-json" - val report = getIvyReport(createLiftDep(excluded), scala210) - testLiftJsonIsMissing(report) - } - - val scala2122 = Some("2.12.2") - it should "exclude a concrete version of lift-json when it's full cross version" in { - val excluded: ModuleID = ("org.scalameta" % "scalahost" % "1.7.0").cross(CrossVersion.full) - val report = getIvyReport(createMetaDep(excluded), scala2122) - testScalahostIsMissing(report) - } - - it should "exclude any version of lift-json when it's full cross version" in { - val excluded = new OrganizationArtifactName("net.liftweb", "lift-json", CrossVersion.full) - val report = getIvyReport(createMetaDep(excluded), scala2122) - testScalahostIsMissing(report) - } - - it should "exclude any version of scala-library via * artifact id" in { - val toExclude = ExclusionRule("org.scala-lang", "*") - val report = getIvyReport(createLiftDep(toExclude), scala210) - testScalaLibraryIsMissing(report) - } - - it should "exclude any version of scala-library via * org id" in { - val toExclude = ExclusionRule("*", "scala-library") - val report = getIvyReport(createLiftDep(toExclude), scala210) - testScalaLibraryIsMissing(report) - } } diff --git a/ivy/src/test/scala/sbt/internal/librarymanagement/InconsistentDuplicateSpec.scala b/ivy/src/test/scala/sbt/internal/librarymanagement/InconsistentDuplicateSpec.scala index 8ba690221..db9344070 100644 --- a/ivy/src/test/scala/sbt/internal/librarymanagement/InconsistentDuplicateSpec.scala +++ b/ivy/src/test/scala/sbt/internal/librarymanagement/InconsistentDuplicateSpec.scala @@ -1,23 +1,26 @@ package sbt.internal.librarymanagement import sbt.librarymanagement._ +import verify.BasicTestSuite // This is a specification to check the inconsistent duplicate warnings -class InconsistentDuplicateSpec extends UnitSpec { - "Duplicate with different version" should "be warned" in { - IvySbt.inconsistentDuplicateWarning(Seq(akkaActor214, akkaActor230)) shouldBe - List( - "Multiple dependencies with the same organization/name but different versions. To avoid conflict, pick one version:", - " * com.typesafe.akka:akka-actor:(2.1.4, 2.3.0)" - ) +object InconsistentDuplicateSpec extends BasicTestSuite { + test("Duplicate with different version should be warned") { + assert( + IvySbt.inconsistentDuplicateWarning(Seq(akkaActor214, akkaActor230)) == + List( + "Multiple dependencies with the same organization/name but different versions. To avoid conflict, pick one version:", + " * com.typesafe.akka:akka-actor:(2.1.4, 2.3.0)" + ) + ) } - it should "not be warned if in different configurations" in { - IvySbt.inconsistentDuplicateWarning(Seq(akkaActor214, akkaActor230Test)) shouldBe Nil + test("it should not be warned if in different configurations") { + assert(IvySbt.inconsistentDuplicateWarning(Seq(akkaActor214, akkaActor230Test)) == Nil) } - "Duplicate with same version" should "not be warned" in { - IvySbt.inconsistentDuplicateWarning(Seq(akkaActor230Test, akkaActor230)) shouldBe Nil + test("Duplicate with same version should not be warned") { + assert(IvySbt.inconsistentDuplicateWarning(Seq(akkaActor230Test, akkaActor230)) == Nil) } def akkaActor214 = diff --git a/ivy/src/test/scala/sbt/internal/librarymanagement/IvyRepoSpec.scala b/ivy/src/test/scala/sbt/internal/librarymanagement/IvyRepoSpec.scala index 468b9fef6..97515d9ef 100644 --- a/ivy/src/test/scala/sbt/internal/librarymanagement/IvyRepoSpec.scala +++ b/ivy/src/test/scala/sbt/internal/librarymanagement/IvyRepoSpec.scala @@ -5,7 +5,7 @@ import sbt.librarymanagement._ import sbt.librarymanagement.syntax._ import InternalDefaults._ -class IvyRepoSpec extends BaseIvySpecification { +object IvyRepoSpec extends BaseIvySpecification { val ourModuleID = ModuleID("com.example", "foo", "0.1.0").withConfigurations(Some("compile")) @@ -21,7 +21,9 @@ class IvyRepoSpec extends BaseIvySpecification { ) } - "ivyUpdate from ivy repository" should "resolve only binary artifact from module which also contains a sources artifact under the same configuration." in { + test( + "ivyUpdate from ivy repository should resolve only binary artifact from module which also contains a sources artifact under the same configuration." + ) { cleanIvyCache() val m = makeModuleForDepWithSources @@ -33,13 +35,15 @@ class IvyRepoSpec extends BaseIvySpecification { case Some(Seq(mr)) => inside(mr.artifacts) { case Seq((ar, _)) => - ar.`type` shouldBe "jar" - ar.extension shouldBe "jar" + assert(ar.`type` == "jar") + assert(ar.extension == "jar") } } } - it should "resolve only sources artifact of an acceptable artifact type, \"src\", when calling updateClassifiers." in { + test( + "it should resolve only sources artifact of an acceptable artifact type, \"src\", when calling updateClassifiers." + ) { cleanIvyCache() val m = makeModuleForDepWithSources @@ -90,9 +94,9 @@ class IvyRepoSpec extends BaseIvySpecification { case Some(Seq(mr)) => inside(mr.artifacts) { case Seq((ar, _)) => - ar.name shouldBe "libmodule-source" - ar.`type` shouldBe "src" - ar.extension shouldBe "jar" + assert(ar.name == "libmodule-source") + assert(ar.`type` == "src") + assert(ar.extension == "jar") } } } diff --git a/ivy/src/test/scala/sbt/internal/librarymanagement/MakePomSpec.scala b/ivy/src/test/scala/sbt/internal/librarymanagement/MakePomSpec.scala index 886b2018e..30c36e093 100644 --- a/ivy/src/test/scala/sbt/internal/librarymanagement/MakePomSpec.scala +++ b/ivy/src/test/scala/sbt/internal/librarymanagement/MakePomSpec.scala @@ -1,79 +1,87 @@ package sbt.internal.librarymanagement import sbt.internal.util.ConsoleLogger +import verify.BasicTestSuite // http://ant.apache.org/ivy/history/2.3.0/ivyfile/dependency.html // http://maven.apache.org/enforcer/enforcer-rules/versionRanges.html -class MakePomSpec extends UnitSpec { +object MakePomSpec extends BasicTestSuite { // This is a specification to check the Ivy revision number conversion to pom. - "1.0" should "convert to 1.0" in convertTo("1.0", "1.0") + test("1.0 should convert to 1.0") { + convertTo("1.0", "1.0") + } - "[1.0,2.0]" should "convert to [1.0,2.0]" in { + test("[1.0,2.0] should convert to [1.0,2.0]") { convertTo("[1.0,2.0]", "[1.0,2.0]") } - "[1.0,2.0[" should "convert to [1.0,2.0)" in { + test("[1.0,2.0[ should convert to [1.0,2.0)") { convertTo("[1.0,2.0[", "[1.0,2.0)") } - "]1.0,2.0]" should "convert to (1.0,2.0]" in { + test("]1.0,2.0] should convert to (1.0,2.0]") { convertTo("]1.0,2.0]", "(1.0,2.0]") } - "]1.0,2.0[" should "convert to (1.0,2.0)" in { + test("]1.0,2.0[ should convert to (1.0,2.0)") { convertTo("]1.0,2.0[", "(1.0,2.0)") } - "[1.0,)" should "convert to [1.0,)" in { + test("[1.0,) should convert to [1.0,)") { convertTo("[1.0,)", "[1.0,)") } - "]1.0,)" should "convert to (1.0,)" in { + test("]1.0,) should convert to (1.0,)") { convertTo("]1.0,)", "(1.0,)") } - "(,2.0]" should "convert to (,2.0]" in { + test("(,2.0] should convert to (,2.0]") { convertTo("(,2.0]", "(,2.0]") } - "(,2.0[" should "convert to (,2.0)" in { + test("(,2.0[ should convert to (,2.0)") { convertTo("(,2.0[", "(,2.0)") } - "1.+" should "convert to [1,2)" in { + test("1.+ should convert to [1,2)") { convertTo("1.+", "[1,2)") } - "1.2.3.4.+" should "convert to [1.2.3.4,1.2.3.5)" in { + test("1.2.3.4.+ should convert to [1.2.3.4,1.2.3.5)") { convertTo("1.2.3.4.+", "[1.2.3.4,1.2.3.5)") } - "12.31.42.+" should "convert to [12.31.42,12.31.43)" in { + test("12.31.42.+ should convert to [12.31.42,12.31.43)") { convertTo("12.31.42.+", "[12.31.42,12.31.43)") } - "1.1+" should "convert to [1.1,1.2),[1.10,1.20),[1.100,1.200),[1.1000,1.2000),[1.10000,1.20000)" in { + test( + "1.1+ should convert to [1.1,1.2),[1.10,1.20),[1.100,1.200),[1.1000,1.2000),[1.10000,1.20000)" + ) { convertTo("1.1+", "[1.1,1.2),[1.10,1.20),[1.100,1.200),[1.1000,1.2000),[1.10000,1.20000)") } - "1+" should "convert to [1,2),[10,20),[100,200),[1000,2000),[10000,20000)" in { + test("1+ should convert to [1,2),[10,20),[100,200),[1000,2000),[10000,20000)") { convertTo("1+", "[1,2),[10,20),[100,200),[1000,2000),[10000,20000)") } - "+" should "convert to [0,)" in convertTo("+", "[0,)") + test("+ should convert to [0,)") { + convertTo("+", "[0,)") + } - "foo+" should "convert to foo+" in beParsedAsError("foo+") + test("foo+ should convert to foo+") { + beParsedAsError("foo+") + } val mp = new MakePom(ConsoleLogger()) def convertTo(s: String, expected: String): Unit = { - MakePom.makeDependencyVersion(s) shouldBe expected - () + assert(MakePom.makeDependencyVersion(s) == expected) } def beParsedAsError(s: String): Unit = { intercept[Throwable] { MakePom.makeDependencyVersion(s) + () } - () } } diff --git a/ivy/src/test/scala/sbt/internal/librarymanagement/ManagedChecksumsSpec.scala b/ivy/src/test/scala/sbt/internal/librarymanagement/ManagedChecksumsSpec.scala index 7ef540583..e9e133d4c 100644 --- a/ivy/src/test/scala/sbt/internal/librarymanagement/ManagedChecksumsSpec.scala +++ b/ivy/src/test/scala/sbt/internal/librarymanagement/ManagedChecksumsSpec.scala @@ -7,7 +7,7 @@ import sbt.librarymanagement._ import sbt.librarymanagement.ivy._ import sbt.io.IO -class ManagedChecksumsSpec extends BaseIvySpecification { +object ManagedChecksumsSpec extends BaseIvySpecification { private final def targetDir = Some(currentDependency) private final def onlineConf = makeUpdateConfiguration(false, targetDir) private final def warningConf = UnresolvedWarningConfiguration() @@ -47,7 +47,7 @@ class ManagedChecksumsSpec extends BaseIvySpecification { assert(shaFile.exists(), s"The checksum $Checksum for $file does not exist") } - "Managed checksums" should "should download the checksum files" in { + test("Managed checksums should should download the checksum files") { cleanAll() val updateOptions = UpdateOptions() val toResolve = module(defaultModuleId, dependencies, None, updateOptions) diff --git a/ivy/src/test/scala/sbt/internal/librarymanagement/MergeDescriptorSpec.scala b/ivy/src/test/scala/sbt/internal/librarymanagement/MergeDescriptorSpec.scala index ded1a9f15..898402224 100644 --- a/ivy/src/test/scala/sbt/internal/librarymanagement/MergeDescriptorSpec.scala +++ b/ivy/src/test/scala/sbt/internal/librarymanagement/MergeDescriptorSpec.scala @@ -5,8 +5,8 @@ import sbt.librarymanagement._ import sbt.librarymanagement.ivy.UpdateOptions import sbt.internal.librarymanagement.ivyint._ -class MergeDescriptorSpec extends BaseIvySpecification { - "Merging duplicate dependencies" should "work" in { +object MergeDescriptorSpec extends BaseIvySpecification { + test("Merging duplicate dependencies should work") { cleanIvyCache() val m = module( ModuleID("com.example", "foo", "0.1.0").withConfigurations(Some("compile")), @@ -25,8 +25,8 @@ class MergeDescriptorSpec extends BaseIvySpecification { val a1: DependencyArtifactDescriptor = arts.toList(1) val configs0 = a0.getConfigurations.toList val configs1 = a1.getConfigurations.toList - configs0 shouldEqual List("compile") - configs1 shouldEqual List("test") + assert(configs0 == List("compile")) + assert(configs1 == List("test")) } } } diff --git a/ivy/src/test/scala/sbt/internal/librarymanagement/ModuleResolversTest.scala b/ivy/src/test/scala/sbt/internal/librarymanagement/ModuleResolversTest.scala index 8519a6d95..d1b06b242 100644 --- a/ivy/src/test/scala/sbt/internal/librarymanagement/ModuleResolversTest.scala +++ b/ivy/src/test/scala/sbt/internal/librarymanagement/ModuleResolversTest.scala @@ -5,7 +5,7 @@ import sbt.librarymanagement.syntax._ import sbt.librarymanagement.ivy.UpdateOptions import Resolver._ -class ModuleResolversTest extends BaseIvySpecification { +object ModuleResolversTest extends BaseIvySpecification { override final val resolvers = Vector( DefaultMavenRepository, JavaNet2Repository, @@ -20,7 +20,7 @@ class ModuleResolversTest extends BaseIvySpecification { "com.jfrog.bintray.client" % "bintray-client-java-api" % "0.9.2" % "compile" ).map(_.withIsTransitive(false)) - "The direct resolvers in update options" should "skip the rest of resolvers" in { + test("The direct resolvers in update options should skip the rest of resolvers") { cleanIvyCache() val updateOptions = UpdateOptions() val ivyModule = module(stubModule, dependencies, None, updateOptions) diff --git a/ivy/src/test/scala/sbt/internal/librarymanagement/OfflineModeSpec.scala b/ivy/src/test/scala/sbt/internal/librarymanagement/OfflineModeSpec.scala index 028c2b0b3..5044be951 100644 --- a/ivy/src/test/scala/sbt/internal/librarymanagement/OfflineModeSpec.scala +++ b/ivy/src/test/scala/sbt/internal/librarymanagement/OfflineModeSpec.scala @@ -2,10 +2,9 @@ package sbt.internal.librarymanagement import sbt.librarymanagement._ import sbt.librarymanagement.ivy.UpdateOptions -import org.scalatest.{ Assertion, DiagrammedAssertions } import sbt.io.IO -class OfflineModeSpec extends BaseIvySpecification with DiagrammedAssertions { +object OfflineModeSpec extends BaseIvySpecification { private final def targetDir = Some(currentDependency) private final def onlineConf = makeUpdateConfiguration(false, targetDir) private final def offlineConf = makeUpdateConfiguration(true, targetDir) @@ -26,7 +25,7 @@ class OfflineModeSpec extends BaseIvySpecification with DiagrammedAssertions { IO.delete(currentDependency) } - def checkOnlineAndOfflineResolution(updateOptions: UpdateOptions): Assertion = { + def checkOnlineAndOfflineResolution(updateOptions: UpdateOptions): Unit = { cleanAll() val toResolve = module(defaultModuleId, dependencies, None, updateOptions) if (updateOptions.cachedResolution) @@ -46,15 +45,15 @@ class OfflineModeSpec extends BaseIvySpecification with DiagrammedAssertions { assert(originalResolveTime > resolveTime) } - "Offline update configuration" should "reuse the caches when offline is enabled" in { + test("Offline update configuration should reuse the caches when offline is enabled") { checkOnlineAndOfflineResolution(normalOptions) } - it should "reuse the caches when offline and cached resolution are enabled" in { + test("it should reuse the caches when offline and cached resolution are enabled") { checkOnlineAndOfflineResolution(cachedOptions) } - def checkFailingResolution(updateOptions: UpdateOptions): Assertion = { + def checkFailingResolution(updateOptions: UpdateOptions): Unit = { cleanAll() val toResolve = module(defaultModuleId, dependencies, None, updateOptions) if (updateOptions.cachedResolution) cleanCachedResolutionCache(toResolve) @@ -63,11 +62,11 @@ class OfflineModeSpec extends BaseIvySpecification with DiagrammedAssertions { assert(failedOfflineResolution.isLeft) } - it should "fail when artifacts are missing in the cache" in { + test("it should fail when artifacts are missing in the cache") { checkFailingResolution(normalOptions) } - it should "fail when artifacts are missing in the cache for cached resolution" in { + test("it should fail when artifacts are missing in the cache for cached resolution") { checkFailingResolution(cachedOptions) } } diff --git a/common-test/src/main/scala/sbt/internal/librarymanagement/ResolutionSpec.scala b/ivy/src/test/scala/sbt/internal/librarymanagement/ResolutionSpec.scala similarity index 74% rename from common-test/src/main/scala/sbt/internal/librarymanagement/ResolutionSpec.scala rename to ivy/src/test/scala/sbt/internal/librarymanagement/ResolutionSpec.scala index fe14d1370..818da8155 100644 --- a/common-test/src/main/scala/sbt/internal/librarymanagement/ResolutionSpec.scala +++ b/ivy/src/test/scala/sbt/internal/librarymanagement/ResolutionSpec.scala @@ -8,7 +8,7 @@ import sbt.librarymanagement.syntax._ abstract class ResolutionSpec extends AbstractEngineSpec { import ShowLines._ - "Resolving the same module twice" should "work" in { + test("Resolving the same module twice should work") { cleanCache() val m = module( exampleModuleId("0.1.0"), @@ -22,10 +22,10 @@ abstract class ResolutionSpec extends AbstractEngineSpec { println(report) // second resolution reads from the minigraph println(report.configurations.head.modules.head.artifacts) - report.configurations.size shouldBe 3 + assert(report.configurations.size == 3) } - "Resolving the unsolvable module should" should "not work" in { + test("Resolving the unsolvable module should should not work") { // log.setLevel(Level.Debug) val m = module( exampleModuleId("0.2.0"), @@ -40,11 +40,15 @@ abstract class ResolutionSpec extends AbstractEngineSpec { updateEither(m) match { case Right(_) => sys.error("this should've failed 2") case Left(uw) => - uw.lines should contain allOf ("\n\tNote: Unresolved dependencies path:", - "\t\tfoundrylogic.vpp:vpp:2.2.1", - "\t\t +- org.apache.cayenne:cayenne-tools:3.0.2", - "\t\t +- org.apache.cayenne.plugins:maven-cayenne-plugin:3.0.2", - "\t\t +- com.example:foo:0.2.0") + List( + "\n\tNote: Unresolved dependencies path:", + "\t\tfoundrylogic.vpp:vpp:2.2.1", + "\t\t +- org.apache.cayenne:cayenne-tools:3.0.2", + "\t\t +- org.apache.cayenne.plugins:maven-cayenne-plugin:3.0.2", + "\t\t +- com.example:foo:0.2.0" + ) foreach { line => + assert(uw.lines.contains[String](line)) + } } } @@ -52,7 +56,7 @@ abstract class ResolutionSpec extends AbstractEngineSpec { // data-avro:1.9.40 depends on avro:1.4.0, which depends on netty:3.2.1.Final. // avro:1.4.0 will be evicted by avro:1.7.7. // #2046 says that netty:3.2.0.Final is incorrectly evicted by netty:3.2.1.Final - "Resolving a module with a pseudo-conflict" should "work" in { + test("Resolving a module with a pseudo-conflict should work") { // log.setLevel(Level.Debug) cleanCache() val m = module( @@ -74,7 +78,7 @@ abstract class ResolutionSpec extends AbstractEngineSpec { })) } - "Resolving a module with sbt cross build" should "work" in { + test("Resolving a module with sbt cross build should work") { cleanCache() val attributes013 = Map("e:sbtVersion" -> "0.13", "e:scalaVersion" -> "2.10") val attributes10 = Map("e:sbtVersion" -> "1.0", "e:scalaVersion" -> "2.12") @@ -88,11 +92,13 @@ abstract class ResolutionSpec extends AbstractEngineSpec { Vector(sbtRelease.withExtraAttributes(attributes10)), Some("2.12.3") ) - update(module013).configurations.head.modules.map(_.toString).loneElement should include( - "com.github.gseitz:sbt-release:1.0.6 (scalaVersion=2.10, sbtVersion=0.13)" + assert( + update(module013).configurations.head.modules.map(_.toString).loneElement + contains "com.github.gseitz:sbt-release:1.0.6 (scalaVersion=2.10, sbtVersion=0.13)" ) - update(module10).configurations.head.modules.map(_.toString).loneElement should include( - "com.github.gseitz:sbt-release:1.0.6 (scalaVersion=2.12, sbtVersion=1.0)" + assert( + update(module10).configurations.head.modules.map(_.toString).loneElement + contains "com.github.gseitz:sbt-release:1.0.6 (scalaVersion=2.12, sbtVersion=1.0)" ) } diff --git a/ivy/src/test/scala/sbt/internal/librarymanagement/ResolverSpec.scala b/ivy/src/test/scala/sbt/internal/librarymanagement/ResolverSpec.scala new file mode 100644 index 000000000..92cb9fa32 --- /dev/null +++ b/ivy/src/test/scala/sbt/internal/librarymanagement/ResolverSpec.scala @@ -0,0 +1,18 @@ +package sbttest + +import java.net.URL +import sbt.librarymanagement._ +import sbt.librarymanagement.syntax._ +import verify.BasicTestSuite + +class ResolverSpec extends BasicTestSuite { + test("Resolver.url") { + Resolver.url("Test Repo", new URL("http://example.com/"))(Resolver.ivyStylePatterns) + () + } + + test("at") { + "something" at "http://example.com" + () + } +} diff --git a/ivy/src/test/scala/sbt/internal/librarymanagement/ScalaOverrideTest.scala b/ivy/src/test/scala/sbt/internal/librarymanagement/ScalaOverrideTest.scala index 3dcfff33f..d9ed46cf3 100644 --- a/ivy/src/test/scala/sbt/internal/librarymanagement/ScalaOverrideTest.scala +++ b/ivy/src/test/scala/sbt/internal/librarymanagement/ScalaOverrideTest.scala @@ -6,8 +6,9 @@ import org.apache.ivy.core.module.descriptor.DefaultDependencyDescriptor import sbt.internal.librarymanagement.IvyScalaUtil.OverrideScalaMediator import sbt.librarymanagement._ import sbt.librarymanagement.ScalaArtifacts._ +import verify.BasicTestSuite -class ScalaOverrideTest extends UnitSpec { +object ScalaOverrideTest extends BasicTestSuite { val OtherOrgID = "other.org" def check(org0: String, version0: String)(org1: String, name1: String, version1: String) = { @@ -21,85 +22,126 @@ class ScalaOverrideTest extends UnitSpec { dd.addDependencyConfiguration("compile", "compile") val res = osm.mediate(dd) - res.getDependencyRevisionId shouldBe ModuleRevisionId.newInstance(org0, name1, version0) + assert(res.getDependencyRevisionId == ModuleRevisionId.newInstance(org0, name1, version0)) } - """OverrideScalaMediator - """ should "Override compiler version" in check(Organization, "2.11.8")( - Organization, - CompilerID, - "2.11.9" - ) - it should "Override library version" in check(Organization, "2.11.8")( - Organization, - LibraryID, - "2.11.8" - ) - it should "Override reflect version" in check(Organization, "2.11.8")( - Organization, - ReflectID, - "2.11.7" - ) - it should "Override actors version" in check(Organization, "2.11.8")( - Organization, - ActorsID, - "2.11.6" - ) - it should "Override scalap version" in check(Organization, "2.11.8")( - Organization, - ScalapID, - "2.11.5" - ) + test("""OverrideScalaMediator should override compiler version""") { + check(Organization, "2.11.8")( + Organization, + CompilerID, + "2.11.9" + ) + } - it should "Override default compiler organization" in check(OtherOrgID, "2.11.8")( - Organization, - CompilerID, - "2.11.9" - ) - it should "Override default library organization" in check(OtherOrgID, "2.11.8")( - Organization, - LibraryID, - "2.11.8" - ) - it should "Override default reflect organization" in check(OtherOrgID, "2.11.8")( - Organization, - ReflectID, - "2.11.7" - ) - it should "Override default actors organization" in check(OtherOrgID, "2.11.8")( - Organization, - ActorsID, - "2.11.6" - ) - it should "Override default scalap organization" in check(OtherOrgID, "2.11.8")( - Organization, - ScalapID, - "2.11.5" - ) + test("it should override library version") { + check(Organization, "2.11.8")( + Organization, + LibraryID, + "2.11.8" + ) + } - it should "Override custom compiler organization" in check(Organization, "2.11.8")( - OtherOrgID, - CompilerID, - "2.11.9" - ) - it should "Override custom library organization" in check(Organization, "2.11.8")( - OtherOrgID, - LibraryID, - "2.11.8" - ) - it should "Override custom reflect organization" in check(Organization, "2.11.8")( - OtherOrgID, - ReflectID, - "2.11.7" - ) - it should "Override custom actors organization" in check(Organization, "2.11.8")( - OtherOrgID, - ActorsID, - "2.11.6" - ) - it should "Override custom scalap organization" in check(Organization, "2.11.8")( - OtherOrgID, - ScalapID, - "2.11.5" - ) + test("it should override reflect version") { + check(Organization, "2.11.8")( + Organization, + ReflectID, + "2.11.7" + ) + } + + test("it should override actors version") { + check(Organization, "2.11.8")( + Organization, + ActorsID, + "2.11.6" + ) + } + + test("it should override scalap version") { + check(Organization, "2.11.8")( + Organization, + ScalapID, + "2.11.5" + ) + } + + test("it should override default compiler organization") { + check(OtherOrgID, "2.11.8")( + Organization, + CompilerID, + "2.11.9" + ) + } + + test("it should override default library organization") { + check(OtherOrgID, "2.11.8")( + Organization, + LibraryID, + "2.11.8" + ) + } + + test("it should override default reflect organization") { + check(OtherOrgID, "2.11.8")( + Organization, + ReflectID, + "2.11.7" + ) + } + + test("it should override default actors organization") { + check(OtherOrgID, "2.11.8")( + Organization, + ActorsID, + "2.11.6" + ) + } + + test("it should override default scalap organization") { + check(OtherOrgID, "2.11.8")( + Organization, + ScalapID, + "2.11.5" + ) + } + + test("it should override custom compiler organization") { + check(Organization, "2.11.8")( + OtherOrgID, + CompilerID, + "2.11.9" + ) + } + + test("it should override custom library organization") { + check(Organization, "2.11.8")( + OtherOrgID, + LibraryID, + "2.11.8" + ) + } + + test("it should override custom reflect organization") { + check(Organization, "2.11.8")( + OtherOrgID, + ReflectID, + "2.11.7" + ) + } + + test("it should override custom actors organization") { + check(Organization, "2.11.8")( + OtherOrgID, + ActorsID, + "2.11.6" + ) + } + + test("it should override custom scalap organization") { + check(Organization, "2.11.8")( + OtherOrgID, + ScalapID, + "2.11.5" + ) + } } diff --git a/ivy/src/test/scala/sbt/internal/librarymanagement/SftpRepoSpec.scala b/ivy/src/test/scala/sbt/internal/librarymanagement/SftpRepoSpec.scala index 8da14644a..2bf13668d 100644 --- a/ivy/src/test/scala/sbt/internal/librarymanagement/SftpRepoSpec.scala +++ b/ivy/src/test/scala/sbt/internal/librarymanagement/SftpRepoSpec.scala @@ -10,7 +10,7 @@ import java.nio.file.Paths //by default this test is ignored //to run this you need to change "repo" to point to some sftp repository which contains a dependency referring a dependency in same repo //it will then attempt to authenticate via key file and fetch the dependency specified via "org" and "module" -class SftpRepoSpec extends BaseIvySpecification { +object SftpRepoSpec extends BaseIvySpecification { val repo: Option[String] = None // val repo: Option[String] = Some("some repo") //a dependency which depends on another in the repo @@ -25,7 +25,7 @@ class SftpRepoSpec extends BaseIvySpecification { }.toVector ++ super.resolvers } - "resolving multiple deps from sftp repo" should "not hang or fail" in { + test("resolving multiple deps from sftp repo should not hang or fail") { repo match { case Some(repo) => IO.delete(currentTarget / "cache" / org(repo)) diff --git a/ivy/src/test/scala/sbt/internal/librarymanagement/UpdateOptionsSpec.scala b/ivy/src/test/scala/sbt/internal/librarymanagement/UpdateOptionsSpec.scala index 9b7c9c126..5729bd06e 100644 --- a/ivy/src/test/scala/sbt/internal/librarymanagement/UpdateOptionsSpec.scala +++ b/ivy/src/test/scala/sbt/internal/librarymanagement/UpdateOptionsSpec.scala @@ -1,24 +1,26 @@ package sbt.internal.librarymanagement import sbt.librarymanagement.ivy._ +import verify.BasicTestSuite -class UpdateOptionsSpec extends UnitSpec { - - "UpdateOptions" should "have proper toString defined" in { - UpdateOptions().toString() should be("""|UpdateOptions( +class UpdateOptionsSpec extends BasicTestSuite { + test("UpdateOptions should have proper toString defined") { + assert(UpdateOptions().toString() == """|UpdateOptions( | circularDependencyLevel = warn, | latestSnapshots = true, | cachedResolution = false |)""".stripMargin) - UpdateOptions() - .withCircularDependencyLevel(CircularDependencyLevel.Error) - .withCachedResolution(true) - .withLatestSnapshots(false) - .toString() should be("""|UpdateOptions( + assert( + UpdateOptions() + .withCircularDependencyLevel(CircularDependencyLevel.Error) + .withCachedResolution(true) + .withLatestSnapshots(false) + .toString() == """|UpdateOptions( | circularDependencyLevel = error, | latestSnapshots = false, | cachedResolution = true - |)""".stripMargin) + |)""".stripMargin + ) } } diff --git a/project/Dependencies.scala b/project/Dependencies.scala index d9a1e088a..a6cf0fdef 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -7,8 +7,8 @@ object Dependencies { def nightlyVersion: Option[String] = sys.props.get("sbt.build.version") - private val ioVersion = nightlyVersion.getOrElse("1.3.0-M10") - private val utilVersion = nightlyVersion.getOrElse("1.3.0-M7") + private val ioVersion = nightlyVersion.getOrElse("1.3.0-M16") + private val utilVersion = nightlyVersion.getOrElse("1.3.0-M9") private val sbtIO = "org.scala-sbt" %% "io" % ioVersion @@ -51,6 +51,7 @@ object Dependencies { val scalaCompiler = Def.setting { "org.scala-lang" % "scala-compiler" % scalaVersion.value } val scalaXml = "org.scala-lang.modules" %% "scala-xml" % "1.2.0" val scalaTest = "org.scalatest" %% "scalatest" % "3.0.6-SNAP5" + val scalaVerify = "com.eed3si9n.verify" %% "verify" % "0.1.0" val scalaCheck = "org.scalacheck" %% "scalacheck" % "1.14.0" val sjsonnew = Def.setting { "com.eed3si9n" %% "sjson-new-core" % contrabandSjsonNewVersion.value @@ -60,4 +61,5 @@ object Dependencies { } val gigahorseOkhttp = "com.eed3si9n" %% "gigahorse-okhttp" % "0.5.0" val okhttpUrlconnection = "com.squareup.okhttp3" % "okhttp-urlconnection" % "3.7.0" + val silencerPlugin = "com.github.ghik" %% "silencer-plugin" % "1.4.1" }