diff --git a/.travis.yml b/.travis.yml index 9a8e438..7e6cae9 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,12 +1,13 @@ language: scala sudo: false jdk: - - oraclejdk8 + - openjdk8 + - openjdk11 scala: - 2.10.7 - 2.11.12 - - 2.12.7 - - 2.13.0-M5 + - 2.12.10 + - 2.13.1 branches: only: - master @@ -17,4 +18,6 @@ script: - sbt ++$TRAVIS_SCALA_VERSION test doc cache: directories: - - $HOME/.ivy2 + - $HOME/.cache/coursier + - $HOME/.ivy2/cache + - $HOME/.sbt diff --git a/CHANGELOG.md b/CHANGELOG.md index c1ad4ce..7c51687 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,9 @@ # Changelog -## [1.1.0](https://github.com/tmoschou/arm4s/tree/develop) (2018-10-30) +## 1.1.1 (Unreleased) +- Added cross build for Scala 2.13.1, 2.12.10 + +## [1.1.0](https://github.com/tmoschou/arm4s/releases/tag/v1.1.0) (2018-10-30) - Added cross build for Scala 2.13-M5 - Support explicitly passing the CanManage object to `ImplicitManageable`'s methods [#5](https://github.com/tmoschou/arm4s/issues/5) - `CanManage`'s `onFinally` and`onException` now defaults to no-op implementation [#6](https://github.com/tmoschou/arm4s/issues/6) diff --git a/README.md b/README.md index d4910b3..2801503 100644 --- a/README.md +++ b/README.md @@ -2,8 +2,8 @@ |Branch|Status| |:-----|:----:| - |*master*|[![Build Status](https://travis-ci.org/tmoschou/arm4s.svg?branch=master)](https://travis-ci.org/tmoschou/arm4s)| - |*develop*|[![Build Status](https://travis-ci.org/tmoschou/arm4s.svg?branch=develop)](https://travis-ci.org/tmoschou/arm4s)| + |*master*|[![Build Status](https://travis-ci.com/tmoschou/arm4s.svg?branch=master)](https://travis-ci.com/tmoschou/arm4s)| + |*develop*|[![Build Status](https://travis-ci.com/tmoschou/arm4s.svg?branch=develop)](https://travis-ci.com/tmoschou/arm4s)| [![Scaladocs](https://www.javadoc.io/badge/io.tmos/arm4s_2.12.svg?label=Scaladoc)](https://www.javadoc.io/doc/io.tmos/arm4s_2.12) @@ -42,7 +42,7 @@ val line = for { For more examples see, the Examples section below. -# Rational +# Rationale Manual management of resources have proven to be error prone, and when done "correctly" - ugly. @@ -59,13 +59,17 @@ For instance, if you are doing any of the following, then you should consider th // don't do this val r = new Resource(...) try { - ... // assume we throw an exception here + doStuff1(r) // assume we throw an exception here + doStuff2(r) } finally { r.close() // what if we throw an exception here too? } ``` -Not good - we just masked (lost) the first 'important' exception! +Not good - we just masked (lost) the first 'important' exception with no +indication as to whether our main try block completed normally, or if it +did not, then whereabouts it did fail. + You may be tempted to wrap the close in another try/catch and log it so that the first exception isn't ever dropped. @@ -83,16 +87,16 @@ try { } ``` -Still Bad - If `close()` throws an exception, the application has no idea one was thrown and +Still Bad - If `close()` throws an exception, the application has no idea one was thrown on close and with no opportunity to fail fast and safely. Especially so, if the main try clause didn't -throw any exception, in which case _no_ exception is propagated. +throw any exception at all, in which case _no_ exception is propagated. Instead we should utilise `Throwable.addSuppressed` to propagate the 'first' important exception with any subsequent exceptions attached as 'suppressed'. -Now, that was for one resource! - What if you needed to close multiple resources +Now, that was for one resource. - What if you needed to close multiple resources in a finally block, each of which could independently throw an exception on close. -Could you get it right? If you do - well done! +Could you get it right? If you do - well done. But the next developer who reads is unlikely to understand it. This is where this library comes in and does things *correctly* and *succinctly*, @@ -128,14 +132,14 @@ exception scenarios and with the following goals regarding exception safe behavi In SBT: ```scala -libraryDependencies += "io.tmos" %% "arm4s" % "1.0.0" +libraryDependencies += "io.tmos" %% "arm4s" % "1.1.0" ``` In Maven: ```xml io.tmos arm4s_${scala.binary.version} - 1.0.0 + 1.1.0 ``` ## Using ARM4S diff --git a/build.sbt b/build.sbt index 8290bc5..976926a 100644 --- a/build.sbt +++ b/build.sbt @@ -1,16 +1,14 @@ -import Build._ - val arm = (project in file(".")). settings( organization := "io.tmos", name := "arm4s", - scalaVersion := "2.12.7", + scalaVersion := "2.13.1", // remember to update travis CI - crossScalaVersions := Seq("2.10.7", "2.11.12", "2.12.7", "2.13.0-M5" ), + crossScalaVersions := Seq("2.10.7", "2.11.12", "2.12.10", "2.13.1" ), scalacOptions ++= Seq("-deprecation", "-feature", "-Xfatal-warnings"), Compile / doc / scalacOptions ++= Seq("-groups", "-implicits"), autoAPIMappings := true, - libraryDependencies ++= scalaTest.value, + libraryDependencies += "org.scalatest" %% "scalatest" % "3.1.0" % Test, licenses := Seq("BSD-3-Clause" -> url("https://opensource.org/licenses/BSD-3-Clause")), homepage := Some(url("https://github.com/tmoschou/arm4s")), publishMavenStyle := true, diff --git a/project/Build.scala b/project/Build.scala deleted file mode 100644 index 4cb8733..0000000 --- a/project/Build.scala +++ /dev/null @@ -1,15 +0,0 @@ -import sbt.{Def, _} -import Keys._ - -object Build { - - lazy val scalaTest: Def.Initialize[Seq[ModuleID]] = Def.setting { - CrossVersion.partialVersion(scalaVersion.value) match { - case Some((2, v)) if v <= 12 => - Seq("org.scalatest" %% "scalatest" % "3.0.5" % "test") - case _ => - Seq("org.scalatest" %% "scalatest" % "3.0.6-SNAP3" % "test") - } - } - -} diff --git a/project/build.properties b/project/build.properties index 5620cc5..a919a9b 100644 --- a/project/build.properties +++ b/project/build.properties @@ -1 +1 @@ -sbt.version=1.2.1 +sbt.version=1.3.8 diff --git a/project/plugins.sbt b/project/plugins.sbt index 11f6eed..15af305 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -1,5 +1,5 @@ // https://github.com/jodersky/sbt-gpg -addSbtPlugin("io.crashbox" % "sbt-gpg" % "0.2.0") +addSbtPlugin("io.crashbox" % "sbt-gpg" % "0.2.1") // https://github.com/xerial/sbt-sonatype -addSbtPlugin("org.xerial.sbt" % "sbt-sonatype" % "2.0") +addSbtPlugin("org.xerial.sbt" % "sbt-sonatype" % "3.8.1") diff --git a/src/test/scala-2.10/io/tmos/arm/Compat.scala b/src/test/scala-2.10/io/tmos/arm/Compat.scala new file mode 100644 index 0000000..967462f --- /dev/null +++ b/src/test/scala-2.10/io/tmos/arm/Compat.scala @@ -0,0 +1,5 @@ +package io.tmos.arm + +object Compat { + val CollectionConverters = scala.collection.JavaConverters +} diff --git a/src/test/scala-2.11/io/tmos/arm/Compat.scala b/src/test/scala-2.11/io/tmos/arm/Compat.scala new file mode 100644 index 0000000..967462f --- /dev/null +++ b/src/test/scala-2.11/io/tmos/arm/Compat.scala @@ -0,0 +1,5 @@ +package io.tmos.arm + +object Compat { + val CollectionConverters = scala.collection.JavaConverters +} diff --git a/src/test/scala-2.12/io/tmos/arm/Compat.scala b/src/test/scala-2.12/io/tmos/arm/Compat.scala new file mode 100644 index 0000000..967462f --- /dev/null +++ b/src/test/scala-2.12/io/tmos/arm/Compat.scala @@ -0,0 +1,5 @@ +package io.tmos.arm + +object Compat { + val CollectionConverters = scala.collection.JavaConverters +} diff --git a/src/test/scala-2.13/io/tmos/arm/Compat.scala b/src/test/scala-2.13/io/tmos/arm/Compat.scala new file mode 100644 index 0000000..0992609 --- /dev/null +++ b/src/test/scala-2.13/io/tmos/arm/Compat.scala @@ -0,0 +1,5 @@ +package io.tmos.arm + +object Compat { + val CollectionConverters = scala.jdk.CollectionConverters +} diff --git a/src/test/scala/io/tmos/arm/ArmMethodsSuite.scala b/src/test/scala/io/tmos/arm/ArmMethodsSuite.scala index 73759ed..7164179 100644 --- a/src/test/scala/io/tmos/arm/ArmMethodsSuite.scala +++ b/src/test/scala/io/tmos/arm/ArmMethodsSuite.scala @@ -3,11 +3,11 @@ package io.tmos.arm import java.io.Closeable import io.tmos.arm.ArmMethods._ -import org.scalatest.WordSpec import scala.collection.mutable +import org.scalatest.wordspec.AnyWordSpec -class ArmMethodsSuite extends WordSpec { +class ArmMethodsSuite extends AnyWordSpec { "AutoClosable resources" when { diff --git a/src/test/scala/io/tmos/arm/CustomResourceSuite.scala b/src/test/scala/io/tmos/arm/CustomResourceSuite.scala index d63d903..c1b9e31 100644 --- a/src/test/scala/io/tmos/arm/CustomResourceSuite.scala +++ b/src/test/scala/io/tmos/arm/CustomResourceSuite.scala @@ -4,9 +4,9 @@ import java.io.{BufferedReader, InputStreamReader, PrintWriter} import java.net.{InetAddress, ServerSocket, Socket, SocketException} import java.util.concurrent.{Callable, CompletableFuture, ExecutorService, Executors, TimeUnit} -import org.scalatest.FunSuite +import org.scalatest.funsuite.AnyFunSuite -class CustomResourceSuite extends FunSuite { +class CustomResourceSuite extends AnyFunSuite { import Implicits._ @@ -35,7 +35,7 @@ class CustomResourceSuite extends FunSuite { test("complex example of custom manager for Executor service and delegated resource management") { - import scala.collection.JavaConverters._ + import Compat.CollectionConverters._ val serverSocketFuture = new CompletableFuture[ServerSocket] diff --git a/src/test/scala/io/tmos/arm/DefaultManagedResourceSuite.scala b/src/test/scala/io/tmos/arm/DefaultManagedResourceSuite.scala index 6efdfe9..1689c67 100644 --- a/src/test/scala/io/tmos/arm/DefaultManagedResourceSuite.scala +++ b/src/test/scala/io/tmos/arm/DefaultManagedResourceSuite.scala @@ -1,8 +1,8 @@ package io.tmos.arm -import org.scalatest.FunSuite +import org.scalatest.funsuite.AnyFunSuite -class DefaultManagedResourceSuite extends FunSuite { +class DefaultManagedResourceSuite extends AnyFunSuite { case object SimpleResource @@ -21,7 +21,7 @@ class DefaultManagedResourceSuite extends FunSuite { test("under normal operation, only onFinally should be called") { implicit val manager: Manager[SimpleResource.type] = new Manager[SimpleResource.type] val managedResource = new DefaultManagedResource(SimpleResource) - managedResource.map(_ => Unit) + managedResource.map(_ => ()) assert(!manager.onExceptionCalled) assert(manager.onFinallyCalled) } diff --git a/src/test/scala/io/tmos/arm/ImplicitsSuite.scala b/src/test/scala/io/tmos/arm/ImplicitsSuite.scala index ed0f28a..9a79371 100644 --- a/src/test/scala/io/tmos/arm/ImplicitsSuite.scala +++ b/src/test/scala/io/tmos/arm/ImplicitsSuite.scala @@ -1,8 +1,8 @@ package io.tmos.arm -import org.scalatest.FunSuite +import org.scalatest.funsuite.AnyFunSuite -class ImplicitsSuite extends FunSuite { +class ImplicitsSuite extends AnyFunSuite { test("has implicit manage converter") { import Implicits._ diff --git a/version.sbt b/version.sbt index 48af491..61ca1d8 100644 --- a/version.sbt +++ b/version.sbt @@ -1 +1 @@ -version in ThisBuild := "1.1.0" +version in ThisBuild := "1.1.1"