From 0d3f833a049314f622bd06402ba0c423cb88f6dd Mon Sep 17 00:00:00 2001 From: Ihor Vovk Date: Wed, 3 Jul 2024 15:01:59 +0200 Subject: [PATCH] Prepare sonatype release. Add documentation about modularization (#4) --- .github/workflows/release.yml | 23 ++++++ .github/workflows/scala.yml | 1 + README.md | 80 ++++++++++++++++++- build.sbt | 19 ++++- project/plugins.sbt | 1 + .../AllocationLifecycleListener.scala | 2 +- .../cats_effect_simple_di/Allocator.scala | 2 +- .../cats_effect_simple_di/AllocatorTest.scala | 2 +- 8 files changed, 121 insertions(+), 9 deletions(-) create mode 100644 .github/workflows/release.yml create mode 100644 project/plugins.sbt rename src/main/scala/{com/ihorvovk => io/github}/cats_effect_simple_di/AllocationLifecycleListener.scala (94%) rename src/main/scala/{com/ihorvovk => io/github}/cats_effect_simple_di/Allocator.scala (96%) rename src/test/scala/{com/ihorvovk => io/github}/cats_effect_simple_di/AllocatorTest.scala (97%) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..77615dd --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,23 @@ +name: Release +on: + push: + branches: [main] + tags: ["v*"] +jobs: + publish: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + - uses: actions/setup-java@v4 + with: + java-version: '21' + distribution: 'temurin' + cache: 'sbt' + - run: sbt ci-release + env: + PGP_PASSPHRASE: ${{ secrets.PGP_PASSPHRASE }} + PGP_SECRET: ${{ secrets.PGP_SECRET }} + SONATYPE_PASSWORD: ${{ secrets.SONATYPE_PASSWORD }} + SONATYPE_USERNAME: ${{ secrets.SONATYPE_USERNAME }} diff --git a/.github/workflows/scala.yml b/.github/workflows/scala.yml index 3b6d871..92fdd72 100644 --- a/.github/workflows/scala.yml +++ b/.github/workflows/scala.yml @@ -19,6 +19,7 @@ jobs: with: java-version: '21' distribution: 'temurin' + cache: 'sbt' - name: Run tests run: sbt test \ No newline at end of file diff --git a/README.md b/README.md index 31d79c1..dbab894 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ grows. The suggested approach would be: ```scala -import com.ihorvovk.cats_effect_simple_di.Allocator +import io.github.cats_effect_simple_di.Allocator // create a Dependencies object: class Dependencies(allocator: Allocator) { @@ -58,7 +58,83 @@ If you want to see the order of initialization and finalization of resources, us creating an `Allocator` object. This will log the allocation and finalization of resources in the order they happen: ```scala -import com.ihorvovk.cats_effect_simple_di.AllocationLifecycleListener +import io.github.cats_effect_simple_di.AllocationLifecycleListener Allocator.create(runtime, LogbackAllocationListener) +``` + +## Modularization + +You can have multiple dependencies objects and combine them together. In this case, you can either reuse the same +`Allocator` object or create a new one for each dependency object, but wrap their instantiation +in `allocator.allocate{}` so that they are shut down in the right order: + +Example reusing the same `Allocator` object: +```scala +// AWS - specific dependencies +class AwsDependencies(allocator: Allocator) { + lazy val s3Client: S3Client = allocator.allocate { + S3ClientBuilder.default.build + } +} + +// Main application dependencies +object Dependencies { + def create(runtime: IORuntime): Resource[IO, Dependencies] = + Allocator.create(runtime).map(new Dependencies(_)) +} + +class Dependencies(allocator: Allocator) { + val aws = new AwsDependencies(allocator) + + lazy val http4sClient: Client[IO] = allocator.allocate { + EmberClientBuilder.default[IO].build + } +} + +object App extends IOApp.Simple { + override def run: IO[Unit] = Dependencies.create(runtime).use { deps => + // use aws.s3Client here + deps.aws.s3Client + } +} +``` + +Example creating a new `Allocator` object for each Dependencies object: + +```scala +// AWS - specific dependencies +object AwsDependencies { + def create(runtime: IORuntime): Resource[IO, AwsDependencies] = + Allocator.create(runtime).map(new AwsDependencies(_)) +} + +class AwsDependencies(allocator: Allocator) { + lazy val s3Client: S3Client = allocator.allocate { + S3ClientBuilder.default.build + } +} + +// Main application dependencies +object Dependencies { + def create(runtime: IORuntime): Resource[IO, Dependencies] = + Allocator.create(runtime).map(new Dependencies(_)) +} + +class Dependencies(allocator: Allocator) { + lazy val aws = allocator.allocate { + AwsDependencies.create(IORuntime.global) + } + + lazy val http4sClient: Client[IO] = http4sAllocator.allocate { + EmberClientBuilder.default[IO].build + } +} + +object App extends IOApp.Simple { + override def run: IO[Unit] = Dependencies.create(runtime).use { deps => + // use aws.s3Client here + deps.aws.s3Client + } +} ``` \ No newline at end of file diff --git a/build.sbt b/build.sbt index 82163f2..93d04bd 100644 --- a/build.sbt +++ b/build.sbt @@ -1,11 +1,22 @@ - -organization := "com.ihorvovk" name := "cats-effect-simple-di" -version := "0.0.1" -scalaVersion := "3.4.2" +scalaVersion := "3.3.3" scalacOptions ++= Seq("-unchecked", "-feature", "-deprecation", "-Xfatal-warnings", "-Wunused:imports") +inThisBuild(List( + organization := "io.github.igor-vovk", + homepage := Some(url("https://github.com/igor-vovk/cats-effect-simple-di")), + licenses := List("Apache-2.0" -> url("http://www.apache.org/licenses/LICENSE-2.0")), + developers := List( + Developer( + "igor-vovk", + "Ihor Vovk", + "ideals-03.gushing@icloud.com", + url("https://github.com/igor-vovk") + ) + ) +)) + lazy val Versions = new { val catsEffect = "3.5.4" val scalatest = "3.2.18" diff --git a/project/plugins.sbt b/project/plugins.sbt new file mode 100644 index 0000000..d77db57 --- /dev/null +++ b/project/plugins.sbt @@ -0,0 +1 @@ +addSbtPlugin("com.github.sbt" % "sbt-ci-release" % "1.5.12") \ No newline at end of file diff --git a/src/main/scala/com/ihorvovk/cats_effect_simple_di/AllocationLifecycleListener.scala b/src/main/scala/io/github/cats_effect_simple_di/AllocationLifecycleListener.scala similarity index 94% rename from src/main/scala/com/ihorvovk/cats_effect_simple_di/AllocationLifecycleListener.scala rename to src/main/scala/io/github/cats_effect_simple_di/AllocationLifecycleListener.scala index 1d3f7d0..778e5ff 100644 --- a/src/main/scala/com/ihorvovk/cats_effect_simple_di/AllocationLifecycleListener.scala +++ b/src/main/scala/io/github/cats_effect_simple_di/AllocationLifecycleListener.scala @@ -1,4 +1,4 @@ -package com.ihorvovk.cats_effect_simple_di +package io.github.cats_effect_simple_di import cats.effect.IO diff --git a/src/main/scala/com/ihorvovk/cats_effect_simple_di/Allocator.scala b/src/main/scala/io/github/cats_effect_simple_di/Allocator.scala similarity index 96% rename from src/main/scala/com/ihorvovk/cats_effect_simple_di/Allocator.scala rename to src/main/scala/io/github/cats_effect_simple_di/Allocator.scala index a8b131d..4457523 100644 --- a/src/main/scala/com/ihorvovk/cats_effect_simple_di/Allocator.scala +++ b/src/main/scala/io/github/cats_effect_simple_di/Allocator.scala @@ -1,4 +1,4 @@ -package com.ihorvovk.cats_effect_simple_di +package io.github.cats_effect_simple_di import cats.Show import cats.effect.unsafe.IORuntime diff --git a/src/test/scala/com/ihorvovk/cats_effect_simple_di/AllocatorTest.scala b/src/test/scala/io/github/cats_effect_simple_di/AllocatorTest.scala similarity index 97% rename from src/test/scala/com/ihorvovk/cats_effect_simple_di/AllocatorTest.scala rename to src/test/scala/io/github/cats_effect_simple_di/AllocatorTest.scala index 21bd421..b86c455 100644 --- a/src/test/scala/com/ihorvovk/cats_effect_simple_di/AllocatorTest.scala +++ b/src/test/scala/io/github/cats_effect_simple_di/AllocatorTest.scala @@ -1,4 +1,4 @@ -package com.ihorvovk.cats_effect_simple_di +package io.github.cats_effect_simple_di import cats.effect.unsafe.IORuntime import cats.effect.unsafe.implicits.global