Skip to content

Commit

Permalink
Add Fly4s module
Browse files Browse the repository at this point in the history
  • Loading branch information
geirolz committed Jun 30, 2023
1 parent 29545e6 commit 772afa7
Show file tree
Hide file tree
Showing 10 changed files with 208 additions and 29 deletions.
17 changes: 13 additions & 4 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,13 @@ lazy val root: Project = project
.settings(
copyReadMe := IO.copyFile(file("docs/compiled/README.md"), file("README.md"))
)
.aggregate(core, docs, config, testing, log4cats, odin, pureconfig)
.aggregate(core, docs, config, testing, log4cats, odin, pureconfig, fly4s)

lazy val docs: Project =
project
.in(file("docs"))
.enablePlugins(MdocPlugin)
.dependsOn(core, config, log4cats, odin, pureconfig)
.dependsOn(core, config, log4cats, odin, pureconfig, fly4s)
.settings(
baseSettings,
noPublishSettings,
Expand Down Expand Up @@ -142,13 +142,22 @@ lazy val odin: Project =
libraryDependencies ++= ProjectDependencies.Integrations.Odin.dedicated
)

lazy val `pureconfig`: Project =
lazy val pureconfig: Project =
module("pureconfig")(
folder = s"$integrationsFolder/pureconfig",
publishAs = Some(subProjectName("pureconfig"))
).dependsOn(core, config)
.settings(
libraryDependencies ++= ProjectDependencies.Integrations.ConfigPureConfig.dedicated
libraryDependencies ++= ProjectDependencies.Integrations.Pureconfig.dedicated
)

lazy val fly4s: Project =
module("fly4s")(
folder = s"$integrationsFolder/fly4s",
publishAs = Some(subProjectName("fly4s"))
).dependsOn(core)
.settings(
libraryDependencies ++= ProjectDependencies.Integrations.Fly4s.dedicated
)

//=============================== MODULES UTILS ===============================
Expand Down
28 changes: 14 additions & 14 deletions core/src/main/scala/com/geirolz/app/toolkit/App.scala
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ class App[
val loggerBuilder: F[LOGGER_T[F]],
val configLoader: F[CONFIG],
val resourcesLoader: F[RESOURCES],
val beforeRunF: App.Dependencies[APP_INFO, LOGGER_T[F], CONFIG, DEPENDENCIES, RESOURCES] => F[Unit],
val beforeProvidingF: App.Dependencies[APP_INFO, LOGGER_T[F], CONFIG, DEPENDENCIES, RESOURCES] => F[Unit],
val onFinalizeF: App.Dependencies[APP_INFO, LOGGER_T[F], CONFIG, DEPENDENCIES, RESOURCES] => F[Unit],
val failureHandlerLoader: App.Resources[APP_INFO, LOGGER_T[F], CONFIG, RESOURCES] => FailureHandler[F, FAILURE],
val dependenciesLoader: App.Resources[APP_INFO, LOGGER_T[F], CONFIG, RESOURCES] => Resource[F, FAILURE \/ DEPENDENCIES],
Expand Down Expand Up @@ -60,15 +60,15 @@ class App[
def withMessages(messages: AppMessages): Self =
copyWith(appMessages = messages)

def beforeRun(
def beforeProviding(
f: App.Dependencies[APP_INFO, LOGGER_T[F], CONFIG, DEPENDENCIES, RESOURCES] => F[Unit]
): Self =
copyWith(beforeRunF = f)
copyWith(beforeProvidingF = beforeProvidingF >> f)

def onFinalize(
f: App.Dependencies[APP_INFO, LOGGER_T[F], CONFIG, DEPENDENCIES, RESOURCES] => F[Unit]
): Self =
copyWith(onFinalizeF = f)
copyWith(onFinalizeF = onFinalizeF >> f)

private[toolkit] def _compile(appArgs: List[String]): Resource[F, FAILURE \/ F[NonEmptyList[FAILURE] \/ Unit]] =
(
Expand Down Expand Up @@ -146,7 +146,7 @@ class App[
} yield maybeReducedFailures.toLeft(())
} yield {
appLoggerF.info(appMessages.startingApp) >>
beforeRunF(appDependencies) >>
beforeProvidingF(appDependencies) >>
appLogic
.onCancel(appLoggerF.info(appMessages.appWasStopped))
.onError(e => appLoggerF.error(e)(appMessages.appEnErrorOccurred))
Expand Down Expand Up @@ -180,13 +180,13 @@ class App[
RES2,
DEPS2
](
appInfo: APP_INFO2 = this.appInfo,
appMessages: AppMessages = this.appMessages,
loggerBuilder: G[LOGGER_T2[G]] = this.loggerBuilder,
configLoader: G[CONFIG2] = this.configLoader,
resourcesLoader: G[RES2] = this.resourcesLoader,
beforeRunF: App.Dependencies[APP_INFO2, LOGGER_T2[G], CONFIG2, DEPS2, RES2] => G[Unit] = this.beforeRunF,
onFinalizeF: App.Dependencies[APP_INFO2, LOGGER_T2[G], CONFIG2, DEPS2, RES2] => G[Unit] = this.onFinalizeF,
appInfo: APP_INFO2 = this.appInfo,
appMessages: AppMessages = this.appMessages,
loggerBuilder: G[LOGGER_T2[G]] = this.loggerBuilder,
configLoader: G[CONFIG2] = this.configLoader,
resourcesLoader: G[RES2] = this.resourcesLoader,
beforeProvidingF: App.Dependencies[APP_INFO2, LOGGER_T2[G], CONFIG2, DEPS2, RES2] => G[Unit] = this.beforeProvidingF,
onFinalizeF: App.Dependencies[APP_INFO2, LOGGER_T2[G], CONFIG2, DEPS2, RES2] => G[Unit] = this.onFinalizeF,
failureHandlerLoader: App.Resources[APP_INFO2, LOGGER_T2[G], CONFIG2, RES2] => FailureHandler[
G,
FAILURE2
Expand All @@ -205,7 +205,7 @@ class App[
loggerBuilder = loggerBuilder,
configLoader = configLoader,
resourcesLoader = resourcesLoader,
beforeRunF = beforeRunF,
beforeProvidingF = beforeProvidingF,
onFinalizeF = onFinalizeF,
failureHandlerLoader = failureHandlerLoader,
dependenciesLoader = dependenciesLoader,
Expand Down Expand Up @@ -434,7 +434,7 @@ object App extends AppSyntax {
failureHandlerLoader = _ => FailureHandler.cancelAll,
loggerBuilder = loggerBuilder,
resourcesLoader = resourcesLoader,
beforeRunF = _ => ().pure[F],
beforeProvidingF = _ => ().pure[F],
onFinalizeF = _ => ().pure[F],
configLoader = configLoader,
dependenciesLoader = dependenciesLoader,
Expand Down
74 changes: 66 additions & 8 deletions docs/source/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,10 +78,10 @@ object Main extends IOApp {
App[IO]
.withInfo(
SimpleAppInfo.string(
name = "toolkit",
version = "0.0.1",
scalaVersion = "2.13.10",
sbtVersion = "1.8.0"
name = "toolkit",
version = "0.0.1",
scalaVersion = "2.13.10",
sbtVersion = "1.8.0"
)
)
.withLogger(ToolkitLogger.console[IO](_))
Expand All @@ -108,6 +108,10 @@ object Main extends IOApp {
```sbt
libraryDependencies += "com.github.geirolz" %% "toolkit-pureconfig" % "@VERSION@"
```
Import the syntax
```scala
import com.geirolz.app.toolkit.config.pureconfig.syntax.*
```

Which allows you to use `withPureConfigLoader` to load the config from a `ConfigSource.default`

Expand All @@ -127,10 +131,10 @@ object TestConfig {
App[IO]
.withInfo(
SimpleAppInfo.string(
name = "toolkit",
version = "0.0.1",
scalaVersion = "2.13.10",
sbtVersion = "1.8.0"
name = "toolkit",
version = "0.0.1",
scalaVersion = "2.13.10",
sbtVersion = "1.8.0"
)
)
.withPureConfigLoader[TestConfig]
Expand All @@ -149,4 +153,58 @@ libraryDependencies += "com.github.geirolz" %% "toolkit-log4cats" % "@VERSION@"

```sbt
libraryDependencies += "com.github.geirolz" %% "toolkit-odin" % "@VERSION@"
```

#### fly4s

```sbt
libraryDependencies += "com.github.geirolz" %% "toolkit-fly4s" % "@VERSION@"
```

Import the syntax
```scala
import com.geirolz.app.toolkit.fly4s.syntax.*
```

Which allows you to use `beforeProvidingMigrateDatabaseWithConfig` on `App` to migrate the database before running the
app.
To have access to the whole app dependencies you can use `beforeProvidingMigrateDatabaseWith` instead while to have
access to
the whole app dependencies to provide a custom `Fly4s` instance you can use `beforeProvidingMigrateDatabase`.

```scala mdoc:silent

import cats.Show
import com.geirolz.app.toolkit.fly4s.syntax.*

case class TestConfig(dbUrl: String, dbUser: Option[String], dbPassword: Option[Array[Char]])

object TestConfig {
implicit val show: Show[TestConfig] = Show.fromToString
}

App[IO]
.withInfo(
SimpleAppInfo.string(
name = "toolkit",
version = "0.0.1",
scalaVersion = "2.13.10",
sbtVersion = "1.8.0"
)
)
.withConfig(
TestConfig(
dbUrl = "jdbc:postgresql://localhost:5432/toolkit",
dbUser = Some("postgres"),
dbPassword = Some("postgres".toCharArray)
)
)
.withoutDependencies
.provideOne(_ => IO.unit)
.beforeProvidingMigrateDatabaseWithConfig(
url = _.dbUrl,
user = _.dbUser,
password = _.dbPassword
)
.run_
```
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ object AppMain extends IOApp {
.drain
)
)
.beforeRun(_.logger.info("CUSTOM PRE-RUN"))
.beforeProviding(_.logger.info("CUSTOM PRE-RUN"))
.onFinalize(_.logger.info("CUSTOM END"))
.run(args)
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ object AppWithFailures extends IOApp {
.drain
)
)
.beforeRun(_.logger.info("CUSTOM PRE-RUN"))
.beforeProviding(_.logger.info("CUSTOM PRE-RUN"))
.onFinalize(_.logger.info("CUSTOM END"))
.run(args)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package com.geirolz.app.toolkit

package object fly4s {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package com.geirolz.app.toolkit.fly4s

import cats.effect.Resource
import cats.effect.kernel.Async
import com.geirolz.app.toolkit.{App, SimpleAppInfo}
import fly4s.core.Fly4s
import fly4s.core.data.Fly4sConfig

object syntax extends AllSyntax
private[fly4s] sealed trait AllSyntax {

import cats.syntax.all.*

implicit class AppResourcesLoaderOps[F[+_]: Async, FAILURE, APP_INFO <: SimpleAppInfo[?], LOGGER_T[_[_]], CONFIG, RESOURCES, DEPENDENCIES](
app: App[F, FAILURE, APP_INFO, LOGGER_T, CONFIG, RESOURCES, DEPENDENCIES]
) {

def beforeProvidingMigrateDatabaseWithConfig(
url: CONFIG => String,
user: CONFIG => Option[String] = _ => None,
password: CONFIG => Option[Array[Char]] = _ => None,
config: Fly4sConfig = Fly4sConfig.default,
classLoader: ClassLoader = Thread.currentThread.getContextClassLoader
): App[F, FAILURE, APP_INFO, LOGGER_T, CONFIG, RESOURCES, DEPENDENCIES] =
beforeProvidingMigrateDatabaseWith(
url = d => url(d.config),
user = d => user(d.config),
password = d => password(d.config),
config = config,
classLoader = classLoader
)

def beforeProvidingMigrateDatabaseWith(
url: App.Dependencies[APP_INFO, LOGGER_T[F], CONFIG, DEPENDENCIES, RESOURCES] => String,
user: App.Dependencies[APP_INFO, LOGGER_T[F], CONFIG, DEPENDENCIES, RESOURCES] => Option[String] = _ => None,
password: App.Dependencies[APP_INFO, LOGGER_T[F], CONFIG, DEPENDENCIES, RESOURCES] => Option[Array[Char]] = _ => None,
config: Fly4sConfig = Fly4sConfig.default,
classLoader: ClassLoader = Thread.currentThread.getContextClassLoader
): App[F, FAILURE, APP_INFO, LOGGER_T, CONFIG, RESOURCES, DEPENDENCIES] =
beforeProvidingMigrateDatabase(dep =>
Fly4s
.make[F](
url = url(dep),
user = user(dep),
password = password(dep),
config = config,
classLoader = classLoader
)
)

def beforeProvidingMigrateDatabase(
f: App.Dependencies[APP_INFO, LOGGER_T[F], CONFIG, DEPENDENCIES, RESOURCES] => Resource[F, Fly4s[F]]
): App[F, FAILURE, APP_INFO, LOGGER_T, CONFIG, RESOURCES, DEPENDENCIES] =
app.beforeProviding(dep => f(dep).use(_.migrate).void)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package com.geirolz.app.toolkit.fly4s

import cats.effect.IO
import com.geirolz.app.toolkit.fly4s.syntax.*
import com.geirolz.app.toolkit.fly4s.testing.TestConfig
import com.geirolz.app.toolkit.{App, SimpleAppInfo}

class Fly4sSupportSuite extends munit.CatsEffectSuite {

test("Syntax works as expected") {
assertIO_(
App[IO]
.withInfo(
SimpleAppInfo.string(
name = "toolkit",
version = "0.0.1",
scalaVersion = "2.13.10",
sbtVersion = "1.8.0"
)
)
.withConfig(
TestConfig(
dbUrl = "jdbc:postgresql://localhost:5432/toolkit",
dbUser = Some("postgres"),
dbPassword = Some("postgres".toCharArray)
)
)
.withoutDependencies
.provideOne(_ => IO.unit)
.beforeProvidingMigrateDatabaseWithConfig(
url = _.dbUrl,
user = _.dbUser,
password = _.dbPassword
)
.run_
)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package com.geirolz.app.toolkit.fly4s.testing

import cats.Show

case class TestConfig(dbUrl: String, dbUser: Option[String], dbPassword: Option[Array[Char]])
object TestConfig {
implicit val show: Show[TestConfig] = Show.fromToString
}
9 changes: 8 additions & 1 deletion project/ProjectDependencies.scala
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ object ProjectDependencies {
private val circeVersion = "0.14.5"
private val circeGenericExtraVersion = "0.14.3"
private val pureConfigVersion = "0.17.4"
private val fly4sVersion = "0.0.18"
private val munitVersion = "0.7.29"
private val munitEffectVersion = "1.0.7"
private val slf4Version = "2.0.7"
Expand Down Expand Up @@ -96,11 +97,17 @@ object ProjectDependencies {
)
}

object ConfigPureConfig {
object Pureconfig {
lazy val dedicated: Seq[ModuleID] = List(
"com.github.pureconfig" %% "pureconfig-core" % pureConfigVersion
)
}

object Fly4s {
lazy val dedicated: Seq[ModuleID] = List(
"com.github.geirolz" %% "fly4s-core" % fly4sVersion
)
}
}

object Plugins {
Expand Down

0 comments on commit 772afa7

Please sign in to comment.