Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 7 additions & 4 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -17,4 +18,6 @@ script:
- sbt ++$TRAVIS_SCALA_VERSION test doc
cache:
directories:
- $HOME/.ivy2
- $HOME/.cache/coursier
- $HOME/.ivy2/cache
- $HOME/.sbt
5 changes: 4 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -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)
Expand Down
26 changes: 15 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand Down Expand Up @@ -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.
Expand All @@ -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.

Expand All @@ -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*,
Expand Down Expand Up @@ -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
<dependency>
<groupId>io.tmos</groupId>
<artifactId>arm4s_${scala.binary.version}</artifactId>
<version>1.0.0</version>
<version>1.1.0</version>
</dependency>
```
## Using ARM4S
Expand Down
8 changes: 3 additions & 5 deletions build.sbt
Original file line number Diff line number Diff line change
@@ -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,
Expand Down
15 changes: 0 additions & 15 deletions project/Build.scala

This file was deleted.

2 changes: 1 addition & 1 deletion project/build.properties
Original file line number Diff line number Diff line change
@@ -1 +1 @@
sbt.version=1.2.1
sbt.version=1.3.8
4 changes: 2 additions & 2 deletions project/plugins.sbt
Original file line number Diff line number Diff line change
@@ -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")
5 changes: 5 additions & 0 deletions src/test/scala-2.10/io/tmos/arm/Compat.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package io.tmos.arm

object Compat {
val CollectionConverters = scala.collection.JavaConverters
}
5 changes: 5 additions & 0 deletions src/test/scala-2.11/io/tmos/arm/Compat.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package io.tmos.arm

object Compat {
val CollectionConverters = scala.collection.JavaConverters
}
5 changes: 5 additions & 0 deletions src/test/scala-2.12/io/tmos/arm/Compat.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package io.tmos.arm

object Compat {
val CollectionConverters = scala.collection.JavaConverters
}
5 changes: 5 additions & 0 deletions src/test/scala-2.13/io/tmos/arm/Compat.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package io.tmos.arm

object Compat {
val CollectionConverters = scala.jdk.CollectionConverters
}
4 changes: 2 additions & 2 deletions src/test/scala/io/tmos/arm/ArmMethodsSuite.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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 {

Expand Down
6 changes: 3 additions & 3 deletions src/test/scala/io/tmos/arm/CustomResourceSuite.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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._

Expand Down Expand Up @@ -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]

Expand Down
6 changes: 3 additions & 3 deletions src/test/scala/io/tmos/arm/DefaultManagedResourceSuite.scala
Original file line number Diff line number Diff line change
@@ -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

Expand All @@ -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)
}
Expand Down
4 changes: 2 additions & 2 deletions src/test/scala/io/tmos/arm/ImplicitsSuite.scala
Original file line number Diff line number Diff line change
@@ -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._
Expand Down
2 changes: 1 addition & 1 deletion version.sbt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
version in ThisBuild := "1.1.0"
version in ThisBuild := "1.1.1"