From c5c20db754274f110388606646240243d12939cc Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Thu, 20 Jul 2017 11:13:52 +0100 Subject: [PATCH 01/19] Add Constant aliases to CrossVersion --- .../main/scala/sbt/librarymanagement/CrossVersionExtra.scala | 2 ++ 1 file changed, 2 insertions(+) diff --git a/core/src/main/scala/sbt/librarymanagement/CrossVersionExtra.scala b/core/src/main/scala/sbt/librarymanagement/CrossVersionExtra.scala index 93c28a199..a57a9f4f3 100644 --- a/core/src/main/scala/sbt/librarymanagement/CrossVersionExtra.scala +++ b/core/src/main/scala/sbt/librarymanagement/CrossVersionExtra.scala @@ -10,9 +10,11 @@ abstract class CrossVersionFunctions { /** Compatibility with 0.13 */ final val Disabled = sbt.librarymanagement.Disabled final val Binary = sbt.librarymanagement.Binary + final val Constant = sbt.librarymanagement.Constant final val Full = sbt.librarymanagement.Full final val Patch = sbt.librarymanagement.Patch type Binary = sbt.librarymanagement.Binary + type Constant = sbt.librarymanagement.Constant type Full = sbt.librarymanagement.Full type Patch = sbt.librarymanagement.Patch From 66b8863d799607e2535cbc7d9757f3b206e01b8f Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Thu, 20 Jul 2017 17:13:35 +0100 Subject: [PATCH 02/19] Add, configure & enable MiMa --- .travis.yml | 4 ++-- build.sbt | 8 +++++++- project/plugins.sbt | 1 + 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index 7b9d62d48..2a123e73c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,8 +7,8 @@ scala: script: # drop scalafmt on the 1.0.0 branch to dogfood 1.0.0-RC2 before there is a sbt 1.0 of new-sbt-scalafnt -# - sbt -Dfile.encoding=UTF8 -J-XX:ReservedCodeCacheSize=256M ";++$TRAVIS_SCALA_VERSION test;scalafmt::test;test:scalafmt::test" - - sbt -Dfile.encoding=UTF8 -J-XX:ReservedCodeCacheSize=256M ";++$TRAVIS_SCALA_VERSION test" +# - sbt -Dfile.encoding=UTF8 -J-XX:ReservedCodeCacheSize=256M ";++$TRAVIS_SCALA_VERSION;mimaReportBinaryIssues;test;scalafmt::test;test:scalafmt::test" + - sbt -Dfile.encoding=UTF8 -J-XX:ReservedCodeCacheSize=256M ";++$TRAVIS_SCALA_VERSION;mimaReportBinaryIssues;test" cache: directories: diff --git a/build.sbt b/build.sbt index e249b949f..326830172 100644 --- a/build.sbt +++ b/build.sbt @@ -30,6 +30,10 @@ def commonSettings: Seq[Setting[_]] = Seq( parallelExecution in Test := false ) +val mimaSettings = Def settings ( + mimaPreviousArtifacts := Set(organization.value %% moduleName.value % "1.0.0-X18") +) + lazy val lmRoot = (project in file(".")) .aggregate(lmCore, lmIvy) .settings( @@ -91,7 +95,8 @@ lazy val lmCore = (project in file("core")) val sdirs = (managedSourceDirectories in Compile).value val base = baseDirectory.value (((srcs --- sdirs --- base) pair (relativeTo(sdirs) | relativeTo(base) | flat)) toSeq) - } + }, + mimaSettings, ) .configure(addSbtIO, addSbtUtilLogging, addSbtUtilPosition, addSbtUtilCache) @@ -107,6 +112,7 @@ lazy val lmIvy = (project in file("ivy")) sourceManaged in (Compile, generateContrabands) := baseDirectory.value / "src" / "main" / "contraband-scala", contrabandFormatsForType in generateContrabands in Compile := DatatypeConfig.getFormats, scalacOptions in (Compile, console) --= Vector("-Ywarn-unused-import", "-Ywarn-unused", "-Xlint"), + mimaSettings, ) def customCommands: Seq[Setting[_]] = Seq( diff --git a/project/plugins.sbt b/project/plugins.sbt index 3023a6dc1..86d334893 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -2,5 +2,6 @@ addSbtPlugin("org.scala-sbt" % "sbt-houserules" % "0.3.3") addSbtPlugin("org.scala-sbt" % "sbt-contraband" % "0.3.0-M9") // addSbtPlugin("com.lucidchart" % "sbt-scalafmt" % "1.3") +addSbtPlugin("com.typesafe" % "sbt-mima-plugin" % "0.1.14") scalacOptions += "-language:postfixOps" From 26fa1c5f4bd6a727deb493d9c0f187f168706cfa Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Sun, 23 Jul 2017 02:34:36 -0400 Subject: [PATCH 03/19] Fixes sbtApiVersion logic The NonRelease pattern matcher is ony checking for the third segment, but for sbt 1.x, we need to check both the second and third segment since 1.1.0-M1 would be bincompat with 1.0. Fixes sbt/sbt#3360 --- .../librarymanagement/cross/CrossVersionUtil.scala | 11 +++++++---- ivy/src/test/scala/CrossVersionTest.scala | 3 +++ 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/core/src/main/scala/sbt/internal/librarymanagement/cross/CrossVersionUtil.scala b/core/src/main/scala/sbt/internal/librarymanagement/cross/CrossVersionUtil.scala index b9d4cc2dd..b9e784a51 100644 --- a/core/src/main/scala/sbt/internal/librarymanagement/cross/CrossVersionUtil.scala +++ b/core/src/main/scala/sbt/internal/librarymanagement/cross/CrossVersionUtil.scala @@ -36,10 +36,13 @@ object CrossVersionUtil { * Compatible versions include 0.12.0-1 and 0.12.0-RC1 for Some(0, 12). */ private[sbt] def sbtApiVersion(v: String): Option[(Long, Long)] = v match { - case ReleaseV(x, y, _, _) => Some(sbtApiVersion(x.toLong, y.toLong)) - case CandidateV(x, y, _, _) => Some(sbtApiVersion(x.toLong, y.toLong)) - case NonReleaseV_n(x, y, z, _) if z.toInt > 0 => Some(sbtApiVersion(x.toLong, y.toLong)) - case _ => None + case ReleaseV(x, y, _, _) => Some(sbtApiVersion(x.toLong, y.toLong)) + case CandidateV(x, y, _, _) => Some(sbtApiVersion(x.toLong, y.toLong)) + case NonReleaseV_n(x, y, z, _) if x.toLong == 0 && z.toLong > 0 => + Some(sbtApiVersion(x.toLong, y.toLong)) + case NonReleaseV_n(x, y, z, _) if x.toLong > 0 && (y.toLong > 0 || z.toLong > 0) => + Some(sbtApiVersion(x.toLong, y.toLong)) + case _ => None } private def sbtApiVersion(x: Long, y: Long) = { diff --git a/ivy/src/test/scala/CrossVersionTest.scala b/ivy/src/test/scala/CrossVersionTest.scala index b2c52a732..5ba8d8b72 100644 --- a/ivy/src/test/scala/CrossVersionTest.scala +++ b/ivy/src/test/scala/CrossVersionTest.scala @@ -135,6 +135,9 @@ class CrossVersionTest extends UnitSpec { it should "for 1.3.0 return 1.0" in { binarySbtVersion("1.3.0") shouldBe "1.0" } + it should "for 1.3.0-SNAPSHOT return 1.0" in { + binarySbtVersion("1.3.0-SNAPSHOT") shouldBe "1.0" + } it should "for 1.10.0 return 1.0" in { binarySbtVersion("1.10.0") shouldBe "1.0" } From 3db33720a943aca1c5f6e3bdd8ca5d63eb3d6041 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Mon, 24 Jul 2017 05:16:42 -0400 Subject: [PATCH 04/19] Use IvyAuthenticator and JavaNetAuthenticator Fixes sbt/sbt#3331 The siatuation is a bit complicated. Currently the credentials are stored in Ivy's credential store. This needs to be translated into `java.net.Authenticator` by installing `IvyAuthenticator` and `ErrorMessageAuthenticator` in succession. This, then, needs to be translated into OkHttp Authenticator using `okhttp3.JavaNetAuthenticator`. --- .../scala/sbt/librarymanagement/Http.scala | 6 -- .../ivyint/GigahorseUrlHandler.scala | 55 +++++++++++++++++-- 2 files changed, 49 insertions(+), 12 deletions(-) diff --git a/core/src/main/scala/sbt/librarymanagement/Http.scala b/core/src/main/scala/sbt/librarymanagement/Http.scala index 3fee33b82..9870d9b0f 100644 --- a/core/src/main/scala/sbt/librarymanagement/Http.scala +++ b/core/src/main/scala/sbt/librarymanagement/Http.scala @@ -1,13 +1,7 @@ package sbt.librarymanagement import gigahorse._, support.okhttp.Gigahorse -import okhttp3.{ OkUrlFactory, OkHttpClient } -import java.net.{ URL, HttpURLConnection } object Http { lazy val http: HttpClient = Gigahorse.http(Gigahorse.config) - - private[sbt] lazy val urlFactory = new OkUrlFactory(http.underlying[OkHttpClient]) - private[sbt] def open(url: URL): HttpURLConnection = - urlFactory.open(url) } diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/GigahorseUrlHandler.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/GigahorseUrlHandler.scala index 6603919b5..69ab22cf7 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/GigahorseUrlHandler.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/GigahorseUrlHandler.scala @@ -4,9 +4,8 @@ package ivyint import java.net.{ URL, UnknownHostException, HttpURLConnection } import java.io.{ File, IOException, InputStream, ByteArrayOutputStream, ByteArrayInputStream } import org.apache.ivy.util.{ CopyProgressListener, Message, FileUtil } -import org.apache.ivy.util.url.{ URLHandler, AbstractURLHandler, BasicURLHandler } +import org.apache.ivy.util.url.{ URLHandler, AbstractURLHandler, BasicURLHandler, IvyAuthenticator } import org.apache.ivy.util.url.URLHandler._ -import sbt.librarymanagement.Http import sbt.io.{ IO, Using } // Copied from Ivy's BasicURLHandler. @@ -24,8 +23,14 @@ class GigahorseUrlHandler extends AbstractURLHandler { * if the url is not reachable. */ def getURLInfo(url0: URL, timeout: Int): URLInfo = { + // Install the ErrorMessageAuthenticator + if ("http" == url0.getProtocol() || "https" == url0.getProtocol()) { + IvyAuthenticator.install() + ErrorMessageAuthenticator.install() + } + val url = normalizeToURL(url0) - val con = Http.open(url) + val con = GigahorseUrlHandler.open(url) val infoOption = try { con match { case httpCon: HttpURLConnection => @@ -65,8 +70,14 @@ class GigahorseUrlHandler extends AbstractURLHandler { } def openStream(url0: URL): InputStream = { + // Install the ErrorMessageAuthenticator + if ("http" == url0.getProtocol() || "https" == url0.getProtocol()) { + IvyAuthenticator.install() + ErrorMessageAuthenticator.install() + } + val url = normalizeToURL(url0) - val conn = Http.open(url) + val conn = GigahorseUrlHandler.open(url) conn.setRequestProperty("Accept-Encoding", "gzip,deflate") conn match { case httpCon: HttpURLConnection => @@ -91,8 +102,14 @@ class GigahorseUrlHandler extends AbstractURLHandler { } def download(src0: URL, dest: File, l: CopyProgressListener): Unit = { + // Install the ErrorMessageAuthenticator + if ("http" == src0.getProtocol() || "https" == src0.getProtocol()) { + IvyAuthenticator.install() + ErrorMessageAuthenticator.install() + } + val src = normalizeToURL(src0) - val srcConn = Http.open(src) + val srcConn = GigahorseUrlHandler.open(src) srcConn.setRequestProperty("Accept-Encoding", "gzip,deflate") srcConn match { case httpCon: HttpURLConnection => @@ -126,8 +143,16 @@ class GigahorseUrlHandler extends AbstractURLHandler { } def upload(source: File, dest0: URL, l: CopyProgressListener): Unit = { + if( ("http" != dest0.getProtocol()) && ("https" != dest0.getProtocol())) { + throw new UnsupportedOperationException( + "URL repository only support HTTP PUT at the moment") + } + + IvyAuthenticator.install() + ErrorMessageAuthenticator.install() + val dest = normalizeToURL(dest0) - val conn = Http.open(dest) match { + val conn = GigahorseUrlHandler.open(dest) match { case c: HttpURLConnection => c } conn.setDoOutput(true) @@ -169,3 +194,21 @@ class GigahorseUrlHandler extends AbstractURLHandler { } } } + +object GigahorseUrlHandler { + import gigahorse._, support.okhttp.Gigahorse + import okhttp3.{ OkUrlFactory, OkHttpClient, JavaNetAuthenticator } + + lazy val http: HttpClient = Gigahorse.http(Gigahorse.config) + + private[sbt] def urlFactory = { + val client0 = http.underlying[OkHttpClient] + val client = client0.newBuilder() + .authenticator(new JavaNetAuthenticator) + .build + new OkUrlFactory(client) + } + + private[sbt] def open(url: URL): HttpURLConnection = + urlFactory.open(url) +} From ace8d88f9fb4a41c5ff64e58d5fe7bd2ad015788 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Tue, 25 Jul 2017 04:09:44 -0400 Subject: [PATCH 05/19] Filter out ":: loading settings" Fixes sbt/sbt#3287 I'm not sure why we started to see these messages, but given that their info is mapped to our info, it kind of makes sense that it is surfacing. The fix is hacky, but it should work. --- .../internal/librarymanagement/IvyLogger.scala | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/IvyLogger.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/IvyLogger.scala index f178a95f0..29f61222a 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/IvyLogger.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/IvyLogger.scala @@ -7,7 +7,7 @@ import org.apache.ivy.util.{ Message, MessageLogger, MessageLoggerEngine } import sbt.util.Logger /** Interface to Ivy logging. */ -private final class IvyLoggerInterface(logger: Logger) extends MessageLogger { +private[sbt] final class IvyLoggerInterface(logger: Logger) extends MessageLogger { def rawlog(msg: String, level: Int): Unit = log(msg, level) def log(msg: String, level: Int): Unit = { import Message.{ MSG_DEBUG, MSG_VERBOSE, MSG_INFO, MSG_WARN, MSG_ERR } @@ -24,7 +24,7 @@ private final class IvyLoggerInterface(logger: Logger) extends MessageLogger { def debug(msg: String): Unit = () def verbose(msg: String): Unit = logger.verbose(msg) def deprecated(msg: String): Unit = warn(msg) - def info(msg: String): Unit = logger.info(msg) + def info(msg: String): Unit = if (SbtIvyLogger.acceptInfo(msg)) logger.info(msg) def rawinfo(msg: String): Unit = info(msg) def warn(msg: String): Unit = logger.warn(msg) def error(msg: String): Unit = if (SbtIvyLogger.acceptError(msg)) logger.error(msg) @@ -43,13 +43,16 @@ private final class IvyLoggerInterface(logger: Logger) extends MessageLogger { def isShowProgress = false def setShowProgress(progress: Boolean): Unit = () } -private final class SbtMessageLoggerEngine extends MessageLoggerEngine { +private[sbt] final class SbtMessageLoggerEngine extends MessageLoggerEngine { /** This is a hack to filter error messages about 'unknown resolver ...'. */ override def error(msg: String): Unit = if (SbtIvyLogger.acceptError(msg)) super.error(msg) override def sumupProblems(): Unit = clearProblems() } -private object SbtIvyLogger { - val UnknownResolver = "unknown resolver" - def acceptError(msg: String) = (msg ne null) && !msg.startsWith(UnknownResolver) +private[sbt] object SbtIvyLogger { + final val unknownResolver = "unknown resolver" + def acceptError(msg: String) = (msg ne null) && !msg.startsWith(unknownResolver) + + final val loadingSettings = ":: loading settings" + def acceptInfo(msg: String) = (msg ne null) && !msg.startsWith(loadingSettings) } From 22f47be292135a4d7118cd03732dca434b293bf2 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Tue, 25 Jul 2017 17:19:45 -0400 Subject: [PATCH 06/19] Change overwrite warning Previously the warning read: Attempting to overwrite $destination This usage is deprecated and will be removed in sbt 1.0. This is an empty threat since we did not remove the feature. I'm replacing it with: Attempting to overwrite $destination (non-SNAPSHOT) You need to remove it from the cache manually to take effect. Fixes sbt/sbt#3271 --- .../sbt/internal/librarymanagement/ConvertResolver.scala | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/ConvertResolver.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/ConvertResolver.scala index f31d223d3..a90399b8b 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/ConvertResolver.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/ConvertResolver.scala @@ -400,10 +400,11 @@ private[sbt] object ConvertResolver { try super.put(source, destination, overwrite) catch { case e: java.io.IOException if e.getMessage.contains("destination already exists") => + val overwriteWarning = + if (destination contains "-SNAPSHOT") s"Attempting to overwrite $destination" + else "Attempting to overwrite $destination (non-SNAPSHOT)\n\tYou need to remove it from the cache manually to take effect." import org.apache.ivy.util.Message - Message.warn( - s"Attempting to overwrite $destination\n\tThis usage is deprecated and will be removed in sbt 1.0." - ) + Message.warn(overwriteWarning) super.put(source, destination, true) } } From 1512d73a076820b3f50ece9107a80a4737408143 Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Wed, 26 Jul 2017 11:40:54 +0100 Subject: [PATCH 07/19] Upgrade to mima 0.1.15 & add exclusions --- build.sbt | 17 ++++++++++++++--- project/plugins.sbt | 2 +- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/build.sbt b/build.sbt index 326830172..91c79119e 100644 --- a/build.sbt +++ b/build.sbt @@ -1,7 +1,6 @@ import Dependencies._ import Path._ - -// import com.typesafe.tools.mima.core._, ProblemFilters._ +import com.typesafe.tools.mima.core._, ProblemFilters._ def baseVersion = "1.0.0-SNAPSHOT" @@ -24,7 +23,6 @@ def commonSettings: Seq[Setting[_]] = Seq( case _ => old ++ List("-Ywarn-unused", "-Ywarn-unused-import", "-YdisableFlatCpCaching") } }, - // mimaPreviousArtifacts := Set(), // Some(organization.value %% moduleName.value % "1.0.0"), publishArtifact in Compile := true, publishArtifact in Test := false, parallelExecution in Test := false @@ -97,6 +95,14 @@ lazy val lmCore = (project in file("core")) (((srcs --- sdirs --- base) pair (relativeTo(sdirs) | relativeTo(base) | flat)) toSeq) }, mimaSettings, + mimaBinaryIssueFilters ++= Seq( + // method urlFactory()okhttp3.OkUrlFactory in object sbt.librarymanagement.Http does not have a correspondent in current version + // Was private[sbt] and manually checked to be unused in Zinc or sbt + ProblemFilters.exclude[DirectMissingMethodProblem]("sbt.librarymanagement.Http.urlFactory"), + // method open(java.net.URL)java.net.HttpURLConnection in object sbt.librarymanagement.Http does not have a correspondent in current version + // Was private[sbt] and manually checked to be unused in Zinc or sbt + ProblemFilters.exclude[DirectMissingMethodProblem]("sbt.librarymanagement.Http.open"), + ) ) .configure(addSbtIO, addSbtUtilLogging, addSbtUtilPosition, addSbtUtilCache) @@ -113,6 +119,11 @@ lazy val lmIvy = (project in file("ivy")) contrabandFormatsForType in generateContrabands in Compile := DatatypeConfig.getFormats, scalacOptions in (Compile, console) --= Vector("-Ywarn-unused-import", "-Ywarn-unused", "-Xlint"), mimaSettings, + mimaBinaryIssueFilters ++= Seq( + // method UnknownResolver()java.lang.String in object sbt.internal.librarymanagement.SbtIvyLogger does not have a correspondent in current version + // Was in a private object in sbt.internal and manually checked to be unused in Zinc or sbt + ProblemFilters.exclude[DirectMissingMethodProblem]("sbt.internal.librarymanagement.SbtIvyLogger.UnknownResolver") + ) ) def customCommands: Seq[Setting[_]] = Seq( diff --git a/project/plugins.sbt b/project/plugins.sbt index 86d334893..12fc4e3b1 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -2,6 +2,6 @@ addSbtPlugin("org.scala-sbt" % "sbt-houserules" % "0.3.3") addSbtPlugin("org.scala-sbt" % "sbt-contraband" % "0.3.0-M9") // addSbtPlugin("com.lucidchart" % "sbt-scalafmt" % "1.3") -addSbtPlugin("com.typesafe" % "sbt-mima-plugin" % "0.1.14") +addSbtPlugin("com.typesafe" % "sbt-mima-plugin" % "0.1.15") scalacOptions += "-language:postfixOps" From 93c06d29b1f84eece613c51273438fa9dec04a99 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Tue, 25 Jul 2017 16:58:40 -0400 Subject: [PATCH 08/19] Implement better fake formats than ??? Fixes sbt/librarymanagement#67 Fixes sbt/sbt#3288 --- .../formats/GlobalLockFormat.scala | 19 ++++++++++++++++++- .../formats/LoggerFormat.scala | 10 +++++++++- 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/core/src/main/scala/sbt/internal/librarymanagement/formats/GlobalLockFormat.scala b/core/src/main/scala/sbt/internal/librarymanagement/formats/GlobalLockFormat.scala index 2f4342d24..fffd9b6a8 100644 --- a/core/src/main/scala/sbt/internal/librarymanagement/formats/GlobalLockFormat.scala +++ b/core/src/main/scala/sbt/internal/librarymanagement/formats/GlobalLockFormat.scala @@ -2,7 +2,24 @@ package sbt.internal.librarymanagement.formats import sjsonnew._ import xsbti._ +import java.io.File +import java.util.concurrent.Callable +/** + * A fake JsonFormat for xsbti.GlobalLock. + * This is mostly for making IvyConfiguration serializable to JSON. + */ trait GlobalLockFormat { self: BasicJsonProtocol => - implicit lazy val GlobalLockFormat: JsonFormat[GlobalLock] = ??? + import GlobalLockFormats._ + + implicit lazy val globalLockIsoString: IsoString[GlobalLock] = + IsoString.iso(_ => "", _ => NoGlobalLock) + + implicit lazy val GlobalLockFormat: JsonFormat[GlobalLock] = implicitly +} + +private[sbt] object GlobalLockFormats { + object NoGlobalLock extends GlobalLock { + def apply[T](lockFile: File, run: Callable[T]) = run.call() + } } diff --git a/core/src/main/scala/sbt/internal/librarymanagement/formats/LoggerFormat.scala b/core/src/main/scala/sbt/internal/librarymanagement/formats/LoggerFormat.scala index b751672bd..954b48127 100644 --- a/core/src/main/scala/sbt/internal/librarymanagement/formats/LoggerFormat.scala +++ b/core/src/main/scala/sbt/internal/librarymanagement/formats/LoggerFormat.scala @@ -2,7 +2,15 @@ package sbt.internal.librarymanagement.formats import sjsonnew._ import xsbti._ +import sbt.util.Logger.Null +/** + * A fake JsonFormat for xsbti.Logger. + * This is mostly for making IvyConfiguration serializable to JSON. + */ trait LoggerFormat { self: BasicJsonProtocol => - implicit lazy val LoggerFormat: JsonFormat[Logger] = ??? + implicit lazy val xsbtiLoggerIsoString: IsoString[Logger] = + IsoString.iso(_ => "", _ => Null) + + implicit lazy val LoggerFormat: JsonFormat[Logger] = implicitly } From d6e2720201f2209a2f7eb0b1c500321a176f4be0 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Fri, 28 Jul 2017 01:37:01 -0400 Subject: [PATCH 09/19] Let `ModuleDescriptor` declare cache inputs --- build.sbt | 2 + .../LibraryManagementInterface.scala | 10 +++ .../sbt/internal/librarymanagement/Ivy.scala | 73 ++++++++++++++++++- 3 files changed, 84 insertions(+), 1 deletion(-) diff --git a/build.sbt b/build.sbt index 91c79119e..3debd56b2 100644 --- a/build.sbt +++ b/build.sbt @@ -102,6 +102,8 @@ lazy val lmCore = (project in file("core")) // method open(java.net.URL)java.net.HttpURLConnection in object sbt.librarymanagement.Http does not have a correspondent in current version // Was private[sbt] and manually checked to be unused in Zinc or sbt ProblemFilters.exclude[DirectMissingMethodProblem]("sbt.librarymanagement.Http.open"), + // New methods added to LM API + ProblemFilters.exclude[ReversedMissingMethodProblem]("sbt.librarymanagement.ModuleDescriptor.*"), ) ) .configure(addSbtIO, addSbtUtilLogging, addSbtUtilPosition, addSbtUtilCache) diff --git a/core/src/main/scala/sbt/librarymanagement/LibraryManagementInterface.scala b/core/src/main/scala/sbt/librarymanagement/LibraryManagementInterface.scala index 6afc27e2d..33c72c55f 100644 --- a/core/src/main/scala/sbt/librarymanagement/LibraryManagementInterface.scala +++ b/core/src/main/scala/sbt/librarymanagement/LibraryManagementInterface.scala @@ -81,4 +81,14 @@ trait ModuleDescriptor { * if any. */ def scalaModuleInfo: Option[ScalaModuleInfo] + + /** + * The input parameters used to construct the `ModuleSettings`. + */ + def moduleSettings: ModuleSettings + + /** + * Hash for extra parameter that were not captured as `moduleSettings`. + */ + def extraInputHash: Long } diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/Ivy.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/Ivy.scala index 86c1ef5f2..dcf5f3327 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/Ivy.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/Ivy.scala @@ -36,10 +36,12 @@ import org.apache.ivy.util.extendable.ExtendableItem import org.apache.ivy.util.url._ import scala.xml.NodeSeq import scala.collection.mutable -import sbt.util.Logger +import scala.util.{ Success, Failure } +import sbt.util._ import sbt.librarymanagement.{ ModuleDescriptorConfiguration => InlineConfiguration, _ } import sbt.librarymanagement.ivy._ import sbt.librarymanagement.syntax._ + import IvyInternalDefaults._ import Resolver.PluginPattern import ivyint.{ @@ -49,6 +51,8 @@ import ivyint.{ SbtDefaultDependencyDescriptor, GigahorseUrlHandler } +import sjsonnew.JsonFormat +import sjsonnew.support.murmurhash.Hasher final class IvySbt(val configuration: IvyConfiguration) { self => /* @@ -336,6 +340,73 @@ final class IvySbt(val configuration: IvyConfiguration) { self => ) } private def toURL(file: File) = file.toURI.toURL + + // Todo: We just need writing side of this codec. We can clean up the reads. + private[sbt] object AltLibraryManagementCodec extends IvyLibraryManagementCodec { + import sbt.io.Hash + type InlineIvyHL = (Option[IvyPaths], Vector[Resolver], Vector[Resolver], Vector[ + ModuleConfiguration], Vector[String], Boolean) + def inlineIvyToHL(i: InlineIvyConfiguration): InlineIvyHL = + (i.paths, i.resolvers, i.otherResolvers, i.moduleConfigurations, + i.checksums, i.managedChecksums) + + type ExternalIvyHL = (Option[PlainFileInfo], Array[Byte]) + def externalIvyToHL(e: ExternalIvyConfiguration): ExternalIvyHL = + (e.baseDirectory.map(FileInfo.exists.apply), + e.uri.map(Hash.contentsIfLocal).getOrElse(Array.empty)) + + // Redefine to use a subset of properties, that are serialisable + override implicit lazy val InlineIvyConfigurationFormat: JsonFormat[InlineIvyConfiguration] = { + def hlToInlineIvy(i: InlineIvyHL): InlineIvyConfiguration = { + val (paths, resolvers, otherResolvers, moduleConfigurations, checksums, managedChecksums) = i + InlineIvyConfiguration() + .withPaths(paths) + .withResolvers(resolvers) + .withOtherResolvers(otherResolvers) + .withModuleConfigurations(moduleConfigurations) + .withManagedChecksums(managedChecksums) + .withChecksums(checksums) + } + projectFormat[InlineIvyConfiguration, InlineIvyHL](inlineIvyToHL, hlToInlineIvy) + } + + // Redefine to use a subset of properties, that are serialisable + override implicit lazy val ExternalIvyConfigurationFormat + : JsonFormat[ExternalIvyConfiguration] = { + def hlToExternalIvy(e: ExternalIvyHL): ExternalIvyConfiguration = { + val (baseDirectory, _) = e + ExternalIvyConfiguration( + None, + Some(NullLogger), + UpdateOptions(), + baseDirectory.map(_.file), + None /* the original uri is destroyed.. */, + Vector.empty + ) + } + projectFormat[ExternalIvyConfiguration, ExternalIvyHL](externalIvyToHL, hlToExternalIvy) + } + + // Redefine to switch to unionFormat + override implicit lazy val IvyConfigurationFormat: JsonFormat[IvyConfiguration] = + unionFormat2[IvyConfiguration, InlineIvyConfiguration, ExternalIvyConfiguration] + + object NullLogger extends sbt.internal.util.BasicLogger { + override def control(event: sbt.util.ControlEvent.Value, message: ⇒ String): Unit = () + override def log(level: Level.Value, message: ⇒ String): Unit = () + override def logAll(events: Seq[sbt.util.LogEvent]): Unit = () + override def success(message: ⇒ String): Unit = () + override def trace(t: ⇒ Throwable): Unit = () + } + } + + def extraInputHash: Long = { + import AltLibraryManagementCodec._ + Hasher.hash(owner.configuration) match { + case Success(keyHash) => keyHash.toLong + case Failure(_) => 0L + } + } } } From 208b8e427932f41bb17c0a7b6f2767622306ecae Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Fri, 28 Jul 2017 02:00:17 -0400 Subject: [PATCH 10/19] Exclude ReversedMissingMethodProblem sbt.internal.librarymanagement.formats.* --- build.sbt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/build.sbt b/build.sbt index 3debd56b2..144eb0a9a 100644 --- a/build.sbt +++ b/build.sbt @@ -104,6 +104,8 @@ lazy val lmCore = (project in file("core")) ProblemFilters.exclude[DirectMissingMethodProblem]("sbt.librarymanagement.Http.open"), // New methods added to LM API ProblemFilters.exclude[ReversedMissingMethodProblem]("sbt.librarymanagement.ModuleDescriptor.*"), + // New formats for Logger and GlockLock + ProblemFilters.exclude[ReversedMissingMethodProblem]("sbt.internal.librarymanagement.formats.*"), ) ) .configure(addSbtIO, addSbtUtilLogging, addSbtUtilPosition, addSbtUtilCache) From f976c6824b8ce0e8dec26c584a60f12806af0a39 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Fri, 28 Jul 2017 02:11:20 -0400 Subject: [PATCH 11/19] Name the reverse missing methods --- build.sbt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/build.sbt b/build.sbt index 144eb0a9a..6830f8389 100644 --- a/build.sbt +++ b/build.sbt @@ -103,7 +103,9 @@ lazy val lmCore = (project in file("core")) // Was private[sbt] and manually checked to be unused in Zinc or sbt ProblemFilters.exclude[DirectMissingMethodProblem]("sbt.librarymanagement.Http.open"), // New methods added to LM API - ProblemFilters.exclude[ReversedMissingMethodProblem]("sbt.librarymanagement.ModuleDescriptor.*"), + ProblemFilters.exclude[ReversedMissingMethodProblem]("sbt.librarymanagement.ModuleDescriptor.moduleSettings"), + // New methods added to LM API + ProblemFilters.exclude[ReversedMissingMethodProblem]("sbt.librarymanagement.ModuleDescriptor.extraInputHash"), // New formats for Logger and GlockLock ProblemFilters.exclude[ReversedMissingMethodProblem]("sbt.internal.librarymanagement.formats.*"), ) From 749a1c9a9b8b4eea3dbfd7550269a65733fb67fa Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Fri, 28 Jul 2017 07:18:27 +0100 Subject: [PATCH 12/19] Fix MiMa failures --- build.sbt | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/build.sbt b/build.sbt index 91c79119e..a34ca446e 100644 --- a/build.sbt +++ b/build.sbt @@ -102,6 +102,15 @@ lazy val lmCore = (project in file("core")) // method open(java.net.URL)java.net.HttpURLConnection in object sbt.librarymanagement.Http does not have a correspondent in current version // Was private[sbt] and manually checked to be unused in Zinc or sbt ProblemFilters.exclude[DirectMissingMethodProblem]("sbt.librarymanagement.Http.open"), + + // method globalLockIsoString()sjsonnew.IsoString in trait sbt.internal.librarymanagement.formats.GlobalLockFormat is present only in current version + // method xsbtiLoggerIsoString()sjsonnew.IsoString in trait sbt.internal.librarymanagement.formats.LoggerFormat is present only in current version + // These only fail in Scala 2.11 + // We're _probably_ ok to add these between sbt 1 RC2 and RC3, + // but it's dangerous territory in general + // see typesafehub/migration-manager#183 for an example of what happens.. + ProblemFilters.exclude[ReversedMissingMethodProblem]("sbt.internal.librarymanagement.formats.GlobalLockFormat.globalLockIsoString"), + ProblemFilters.exclude[ReversedMissingMethodProblem]("sbt.internal.librarymanagement.formats.LoggerFormat.xsbtiLoggerIsoString"), ) ) .configure(addSbtIO, addSbtUtilLogging, addSbtUtilPosition, addSbtUtilCache) From 8f912301be4d6e7bda6188fc8ec5ce51911d161d Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Fri, 28 Jul 2017 07:56:02 +0100 Subject: [PATCH 13/19] Upgrade to Scala 2.12.3 --- .travis.yml | 2 +- project/Dependencies.scala | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 2a123e73c..b63e2b2f4 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,7 +3,7 @@ jdk: oraclejdk8 scala: - 2.11.11 - - 2.12.2 + - 2.12.3 script: # drop scalafmt on the 1.0.0 branch to dogfood 1.0.0-RC2 before there is a sbt 1.0 of new-sbt-scalafnt diff --git a/project/Dependencies.scala b/project/Dependencies.scala index 57048034a..1bca36c6f 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -4,7 +4,7 @@ import sbt.contraband.ContrabandPlugin.autoImport._ object Dependencies { val scala211 = "2.11.11" - val scala212 = "2.12.2" + val scala212 = "2.12.3" private val ioVersion = "1.0.0-M13" private val utilVersion = "1.0.0-M27" From 52923854cc5ba87e0737664fcd66e19c5ec46d1f Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Thu, 27 Jul 2017 15:55:47 +0100 Subject: [PATCH 14/19] Make sure UpdateReport has a nice toString Fixes sbt/sbt#3357 --- .../OrganizationArtifactReport.scala | 3 +- .../main/contraband/librarymanagement.json | 4 ++ core/src/test/scala/UpdateReportSpec.scala | 41 +++++++++++++++++++ 3 files changed, 47 insertions(+), 1 deletion(-) create mode 100644 core/src/test/scala/UpdateReportSpec.scala diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/OrganizationArtifactReport.scala b/core/src/main/contraband-scala/sbt/librarymanagement/OrganizationArtifactReport.scala index 3b62b191a..112c4708b 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/OrganizationArtifactReport.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/OrganizationArtifactReport.scala @@ -30,7 +30,8 @@ final class OrganizationArtifactReport private ( 37 * (37 * (37 * (37 * (17 + "sbt.librarymanagement.OrganizationArtifactReport".##) + organization.##) + name.##) + modules.##) } override def toString: String = { - "OrganizationArtifactReport(" + organization + ", " + name + ", " + modules + ")" + val details = modules map { _.detailReport } + s"\t$organization:$name\n${details.mkString}\n" } protected[this] def copy(organization: String = organization, name: String = name, modules: Vector[sbt.librarymanagement.ModuleReport] = modules): OrganizationArtifactReport = { new OrganizationArtifactReport(organization, name, modules) diff --git a/core/src/main/contraband/librarymanagement.json b/core/src/main/contraband/librarymanagement.json index fa7506f95..c7a04ede8 100644 --- a/core/src/main/contraband/librarymanagement.json +++ b/core/src/main/contraband/librarymanagement.json @@ -596,6 +596,10 @@ { "name": "organization", "type": "String" }, { "name": "name", "type": "String" }, { "name": "modules", "type": "sbt.librarymanagement.ModuleReport*" } + ], + "toString": [ + "val details = modules map { _.detailReport }", + "s\"\\t$organization:$name\\n${details.mkString}\\n\"" ] }, { diff --git a/core/src/test/scala/UpdateReportSpec.scala b/core/src/test/scala/UpdateReportSpec.scala new file mode 100644 index 000000000..cc7dfd7fd --- /dev/null +++ b/core/src/test/scala/UpdateReportSpec.scala @@ -0,0 +1,41 @@ +package sbt.librarymanagement + +import java.io.File + +import org.scalatest._ + +class UpdateReportSpec extends FlatSpec with Matchers { + "UpdateReport.toString" should "have a nice toString" in { + assert(updateReport.toString === s""" + |Update report: + | Resolve time: 0 ms, Download time: 0 ms, Download size: 0 bytes + | compile: + | org:name + | - 1.0 + | evicted: false + | + |""".stripMargin.drop(1)) + } + + lazy val updateReport = + UpdateReport( + new File("cachedDescriptor.data"), + Vector(configurationReport), + UpdateStats(0, 0, 0, false), + Map.empty + ) + + lazy val configurationReport = + ConfigurationReport( + ConfigRef("compile"), + Vector(moduleReport), + Vector(organizationArtifactReport) + ) + + lazy val moduleReport = + ModuleReport(ModuleID("org", "name", "1.0"), Vector.empty, Vector.empty) + + lazy val organizationArtifactReport = + OrganizationArtifactReport("org", "name", Vector(moduleReport)) + +} From 831e99bd59d977134b51ef2f3f9cc7f5e254aa9d Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Fri, 28 Jul 2017 12:47:41 -0400 Subject: [PATCH 15/19] Contraband 0.3.0 --- project/plugins.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/plugins.sbt b/project/plugins.sbt index 12fc4e3b1..fa1b88965 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -1,5 +1,5 @@ addSbtPlugin("org.scala-sbt" % "sbt-houserules" % "0.3.3") -addSbtPlugin("org.scala-sbt" % "sbt-contraband" % "0.3.0-M9") +addSbtPlugin("org.scala-sbt" % "sbt-contraband" % "0.3.0") // addSbtPlugin("com.lucidchart" % "sbt-scalafmt" % "1.3") addSbtPlugin("com.typesafe" % "sbt-mima-plugin" % "0.1.15") From 0a42cf07498e9aefd0c078f9e7fd861653bfcb4a Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Fri, 28 Jul 2017 12:47:57 -0400 Subject: [PATCH 16/19] IO 1.0.0-RC3, Util 1.0.0-RC3 --- project/Dependencies.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/project/Dependencies.scala b/project/Dependencies.scala index 1bca36c6f..428f3786a 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -6,8 +6,8 @@ object Dependencies { val scala211 = "2.11.11" val scala212 = "2.12.3" - private val ioVersion = "1.0.0-M13" - private val utilVersion = "1.0.0-M27" + private val ioVersion = "1.0.0-RC3" + private val utilVersion = "1.0.0-RC3" private val sbtIO = "org.scala-sbt" %% "io" % ioVersion From 8e8f9a5380854d5511c7d25995be3e1cba229cf7 Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Mon, 31 Jul 2017 11:39:05 +0100 Subject: [PATCH 17/19] Bump mimaPreviousArtifacts to 1.0.0-RC3 --- build.sbt | 30 ++---------------------------- 1 file changed, 2 insertions(+), 28 deletions(-) diff --git a/build.sbt b/build.sbt index 9f96c390e..2b2b4bd16 100644 --- a/build.sbt +++ b/build.sbt @@ -1,6 +1,6 @@ import Dependencies._ import Path._ -import com.typesafe.tools.mima.core._, ProblemFilters._ +//import com.typesafe.tools.mima.core._, ProblemFilters._ def baseVersion = "1.0.0-SNAPSHOT" @@ -29,7 +29,7 @@ def commonSettings: Seq[Setting[_]] = Seq( ) val mimaSettings = Def settings ( - mimaPreviousArtifacts := Set(organization.value %% moduleName.value % "1.0.0-X18") + mimaPreviousArtifacts := Set(organization.value %% moduleName.value % "1.0.0-RC3") ) lazy val lmRoot = (project in file(".")) @@ -82,7 +82,6 @@ lazy val lmCore = (project in file("core")) version.value, resourceManaged.value, streams.value, (compile in Compile).value ) ).taskValue, - // mimaBinaryIssueFilters ++= Seq(), managedSourceDirectories in Compile += baseDirectory.value / "src" / "main" / "contraband-scala", sourceManaged in (Compile, generateContrabands) := baseDirectory.value / "src" / "main" / "contraband-scala", @@ -95,26 +94,6 @@ lazy val lmCore = (project in file("core")) (((srcs --- sdirs --- base) pair (relativeTo(sdirs) | relativeTo(base) | flat)) toSeq) }, mimaSettings, - mimaBinaryIssueFilters ++= Seq( - // method urlFactory()okhttp3.OkUrlFactory in object sbt.librarymanagement.Http does not have a correspondent in current version - // Was private[sbt] and manually checked to be unused in Zinc or sbt - ProblemFilters.exclude[DirectMissingMethodProblem]("sbt.librarymanagement.Http.urlFactory"), - // method open(java.net.URL)java.net.HttpURLConnection in object sbt.librarymanagement.Http does not have a correspondent in current version - // Was private[sbt] and manually checked to be unused in Zinc or sbt - ProblemFilters.exclude[DirectMissingMethodProblem]("sbt.librarymanagement.Http.open"), - // New methods added to LM API - ProblemFilters.exclude[ReversedMissingMethodProblem]("sbt.librarymanagement.ModuleDescriptor.moduleSettings"), - // New methods added to LM API - ProblemFilters.exclude[ReversedMissingMethodProblem]("sbt.librarymanagement.ModuleDescriptor.extraInputHash"), - // method globalLockIsoString()sjsonnew.IsoString in trait sbt.internal.librarymanagement.formats.GlobalLockFormat is present only in current version - // method xsbtiLoggerIsoString()sjsonnew.IsoString in trait sbt.internal.librarymanagement.formats.LoggerFormat is present only in current version - // These only fail in Scala 2.11 - // We're _probably_ ok to add these between sbt 1 RC2 and RC3, - // but it's dangerous territory in general - // see typesafehub/migration-manager#183 for an example of what happens.. - ProblemFilters.exclude[ReversedMissingMethodProblem]("sbt.internal.librarymanagement.formats.GlobalLockFormat.globalLockIsoString"), - ProblemFilters.exclude[ReversedMissingMethodProblem]("sbt.internal.librarymanagement.formats.LoggerFormat.xsbtiLoggerIsoString"), - ) ) .configure(addSbtIO, addSbtUtilLogging, addSbtUtilPosition, addSbtUtilCache) @@ -131,11 +110,6 @@ lazy val lmIvy = (project in file("ivy")) contrabandFormatsForType in generateContrabands in Compile := DatatypeConfig.getFormats, scalacOptions in (Compile, console) --= Vector("-Ywarn-unused-import", "-Ywarn-unused", "-Xlint"), mimaSettings, - mimaBinaryIssueFilters ++= Seq( - // method UnknownResolver()java.lang.String in object sbt.internal.librarymanagement.SbtIvyLogger does not have a correspondent in current version - // Was in a private object in sbt.internal and manually checked to be unused in Zinc or sbt - ProblemFilters.exclude[DirectMissingMethodProblem]("sbt.internal.librarymanagement.SbtIvyLogger.UnknownResolver") - ) ) def customCommands: Seq[Setting[_]] = Seq( From 14cc1c56e2f11f286d0b94d26df794b0ac381b73 Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Mon, 31 Jul 2017 14:54:52 +0100 Subject: [PATCH 18/19] Upgrade to sbt 1.0.0-RC3 --- project/build.properties | 2 +- project/plugins.sbt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/project/build.properties b/project/build.properties index c9e698a14..12c38d389 100644 --- a/project/build.properties +++ b/project/build.properties @@ -1 +1 @@ -sbt.version=1.0.0-RC2 +sbt.version=1.0.0-RC3 diff --git a/project/plugins.sbt b/project/plugins.sbt index fa1b88965..7ddf08986 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -2,6 +2,6 @@ addSbtPlugin("org.scala-sbt" % "sbt-houserules" % "0.3.3") addSbtPlugin("org.scala-sbt" % "sbt-contraband" % "0.3.0") // addSbtPlugin("com.lucidchart" % "sbt-scalafmt" % "1.3") -addSbtPlugin("com.typesafe" % "sbt-mima-plugin" % "0.1.15") +addSbtPlugin("com.typesafe" % "sbt-mima-plugin" % "0.1.17") scalacOptions += "-language:postfixOps" From 3258e7b41343f2bbb8e3ef7a61e9ee3f223724ee Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Wed, 9 Aug 2017 21:14:57 -0400 Subject: [PATCH 19/19] IO 1.0.0, Util 1.0.0 --- project/Dependencies.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/project/Dependencies.scala b/project/Dependencies.scala index 428f3786a..9f92915e6 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -6,8 +6,8 @@ object Dependencies { val scala211 = "2.11.11" val scala212 = "2.12.3" - private val ioVersion = "1.0.0-RC3" - private val utilVersion = "1.0.0-RC3" + private val ioVersion = "1.0.0" + private val utilVersion = "1.0.0" private val sbtIO = "org.scala-sbt" %% "io" % ioVersion