Skip to content

Commit

Permalink
Simplify ReadModule, ConfigSource and PropertyTree (#635)
Browse files Browse the repository at this point in the history
* Redesign configsource and propertyTree

* Remove ConfigSource_ and make ConfigSourceModule tied with String K and String V

* Move the memoization at ZManaged level

* Make all simple config sources devoid of ZIO

* Remove Step in ReadError as it is redundant to Step in PropertyTreePath

* Remove the hack of `ConfigSource` being part of `Sequence` and `Map` nodes in `ConfigDescriptor`, Recurse `Read` using `PropertyTree`, and Remove hacky `LeafForSequence` (#636)

* Loop ReadModule using PropertyTree instead of leaf values

* Try property tree all the way

* Remove LeafForSequence data types and remove its concerns from ReadModule

* Remove property tree optional values from recursions and simplify further

* Remove source nodes from sequence and map forever

* Fix empty check for recursive config and make simple recursive list read test pass

* Remove unused imports

* Uncomment recursive tests

* Fix zio-native and zio-js

* Experimenting with configsource cache, seem to be working

* Remove printlns

* Use type aliases going forward

* Improve performance for all non-recursive configs

* Clean up the ConfigSourceModule

* use whenM for program summary

* Fix slowness in collectAllRoundTripTest

* Fix recursive config test for memoized resources

* Reduce calls to tree

* Rename reader to managed reader

* Clean type aliases

* Make sure resource is released after every config fetch

* Reset environment

* Add tests

* Improve System Environment ConfigSource (#657)

* Loop ReadModule using PropertyTree instead of leaf values

* Try property tree all the way

* Remove LeafForSequence data types and remove its concerns from ReadModule

* Remove property tree optional values from recursions and simplify further

* Remove source nodes from sequence and map forever

* Fix empty check for recursive config and make simple recursive list read test pass

* Remove unused imports

* Uncomment recursive tests

* Fix zio-native and zio-js

* Experimenting with configsource cache, seem to be working

* Remove printlns

* Use type aliases going forward

* Improve performance for all non-recursive configs

* Clean up the ConfigSourceModule

* use whenM for program summary

* Fix slowness in collectAllRoundTripTest

* Fix recursive config test for memoized resources

* Reduce calls to tree

* Rename reader to managed reader

* Clean type aliases

* Make sure resource is released after every config fetch

* Reset environment

* Add tests

* Add more tests

* System env logic improvements

- Pick errors early for System Env, such as invalid delimiters, and avoid pushing it further to ReadModule
- Improve performance by making propertyTree is calculated only once per system environment fetch.

* Compile for scala3

* Make sure zio-config-magnolia works for all scala versions with the new core redesign

* Implement typesafe config with the new changes in core

* Fix pure config

* Fix refined module to work with latest design

* Fix more tests for the new design

* Clean up ReadModule

* Start changing examples

* Fix more examples

* Implement strictlyOnce and toLayer

* Add comments

* Fix all examples based on the new design

* Fix all examples and clean up

* Remove unused imports

* Fix API docs in ConfigDescriptorModule

* Experiment on layers

* Try out configLayer and configLayer_

* Update comments

* Fix shapeless module

* Fix yaml module

* Make leaf for yaml strict

* Remove unused imports

* Fix magnolia tests

* Remove unused imports

* Fix lint

* Remove unused imports

* Add silent for scala-2.11

* Add silent

* Fix lint again

* Reformat and lint

* Fix lint again

* Fix the lint again

* Start fixing docs

* Again lint

* Fix all documentations

* Fix formatting and docs
  • Loading branch information
afsalthaj authored Nov 22, 2021
1 parent 3f38848 commit dfeeb5c
Show file tree
Hide file tree
Showing 101 changed files with 3,068 additions and 2,951 deletions.
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package zio.config.cats

import cats._
import zio.config._, ConfigDescriptor._
import zio.config._

package object instances {
implicit val cfgDescInvariantSemiGroupal: InvariantSemigroupal[ConfigDescriptor] =
Expand Down
68 changes: 38 additions & 30 deletions core/js/src/main/scala/zio/config/ConfigStringModule.scala
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
package zio.config

import com.github.ghik.silencer.silent
import zio.system.System
import zio.{Has, Layer, Tag, ZIO, ZLayer}
import zio.{Has, Layer, Tag, ZLayer}

import java.time.{Instant, LocalDate, LocalDateTime, LocalTime}
import java.util.{Properties, UUID}
import scala.concurrent.duration.Duration

trait ConfigStringModule extends ConfigModule with ConfigSourceStringModule {

trait ConfigStringModule extends ConfigModule with ConfigSourceModule {
object ConfigDescriptor extends ConfigDescriptorFunctions {
import ConfigDescriptorAdt._

Expand All @@ -21,6 +21,9 @@ trait ConfigStringModule extends ConfigModule with ConfigSourceStringModule {
*
* val valueConfig: ConfigDescriptor[Either[BigDecimal, String]] = bigDecimal.orElseEither(string)
*
* // Describes fetching a map that is under the path "key-values" where the value of each can be either a BigDecimal or
* // if it's not try to fetch it as a String. An example source config
*
* val sourceString =
* """
* {
Expand Down Expand Up @@ -72,6 +75,9 @@ trait ConfigStringModule extends ConfigModule with ConfigSourceStringModule {
*
* val valueConfig: ConfigDescriptor[Either[BigInt, String]] = bigInt.orElseEither(string)
*
* // Describes fetching a map that is under the path "key-values" where the value of each can be either a BigDecimal or
* // if it's not try to fetch it as a String. An example source config
*
* val sourceString =
* """
* {
Expand Down Expand Up @@ -582,7 +588,6 @@ trait ConfigStringModule extends ConfigModule with ConfigSourceStringModule {
source: String = "constant",
keyDelimiter: Option[Char] = None,
valueDelimiter: Option[Char] = None,
leafForSequence: LeafForSequence = LeafForSequence.Valid,
filterKeys: String => Boolean = _ => true
)(implicit tag: Tag[A]): Layer[ReadError[String], Has[A]] =
fromConfigDescriptor(
Expand All @@ -591,7 +596,6 @@ trait ConfigStringModule extends ConfigModule with ConfigSourceStringModule {
source,
keyDelimiter,
valueDelimiter,
leafForSequence,
filterKeys
)
)
Expand Down Expand Up @@ -620,11 +624,10 @@ trait ConfigStringModule extends ConfigModule with ConfigSourceStringModule {
configDescriptor: ConfigDescriptor[A],
source: String,
keyDelimiter: Option[Char] = None,
leafForSequence: LeafForSequence = LeafForSequence.Valid,
filterKeys: String => Boolean = _ => true
)(implicit tag: Tag[A]): Layer[ReadError[String], Has[A]] =
fromConfigDescriptor(
configDescriptor from ConfigSource.fromMultiMap(map, source, keyDelimiter, leafForSequence, filterKeys)
configDescriptor from ConfigSource.fromMultiMap(map, source, keyDelimiter, filterKeys)
)

/**
Expand Down Expand Up @@ -654,7 +657,6 @@ trait ConfigStringModule extends ConfigModule with ConfigSourceStringModule {
source: String,
keyDelimiter: Option[Char] = None,
valueDelimiter: Option[Char] = None,
leafForSequence: LeafForSequence = LeafForSequence.Valid,
filterKeys: String => Boolean = _ => true
)(implicit tag: Tag[A]): Layer[ReadError[String], Has[A]] =
fromConfigDescriptor(
Expand All @@ -663,7 +665,6 @@ trait ConfigStringModule extends ConfigModule with ConfigSourceStringModule {
source,
keyDelimiter,
valueDelimiter,
leafForSequence,
filterKeys
)
)
Expand Down Expand Up @@ -694,13 +695,11 @@ trait ConfigStringModule extends ConfigModule with ConfigSourceStringModule {
configDescriptor: ConfigDescriptor[A],
keyDelimiter: Option[Char] = None,
valueDelimiter: Option[Char] = None,
leafForSequence: LeafForSequence = LeafForSequence.Valid,
filterKeys: String => Boolean = _ => true
)(implicit tag: Tag[A]): Layer[Throwable, Has[A]] =
fromConfigDescriptorM(
ConfigSource
.fromPropertiesFile(filePath, keyDelimiter, valueDelimiter, leafForSequence, filterKeys)
.map(configDescriptor from _)
)(implicit tag: Tag[A]): Layer[ReadError[String], Has[A]] =
fromConfigDescriptor(
configDescriptor from ConfigSource
.fromPropertiesFile(filePath, keyDelimiter, valueDelimiter, filterKeys)
)

/**
Expand All @@ -726,12 +725,23 @@ trait ConfigStringModule extends ConfigModule with ConfigSourceStringModule {
*
* Note: The delimiter '.' for keys doesn't work in system environment.
*/
@silent("a type was inferred to be `Any`")
def fromSystemEnv[K, V, A](
configDescriptor: ConfigDescriptor[A],
keyDelimiter: Option[Char] = None,
valueDelimiter: Option[Char] = None
valueDelimiter: Option[Char] = None,
filterKeys: String => Boolean = _ => true
)(implicit tag: Tag[A]): ZLayer[System, ReadError[String], Has[A]] =
fromConfigDescriptorM(ConfigSource.fromSystemEnv(keyDelimiter, valueDelimiter).map(configDescriptor from _))
ZLayer.fromServiceM((system: System.Service) =>
read(
configDescriptor from ConfigSource.fromSystemEnv(
keyDelimiter,
valueDelimiter,
filterKeys,
system
)
)
)

/**
* Consider providing keyDelimiter if you need to consider flattened config as a nested config.
Expand All @@ -754,30 +764,28 @@ trait ConfigStringModule extends ConfigModule with ConfigSourceStringModule {
* nested("KAFKA")(string("SERVERS") |@| string("SERDE"))(KafkaConfig.apply, KafkaConfig.unapply)
* }}}
*/
@silent("a type was inferred to be `Any`")
def fromSystemProperties[K, V, A](
configDescriptor: ConfigDescriptor[A],
keyDelimiter: Option[Char] = None,
valueDelimiter: Option[Char] = None,
leafForSequence: LeafForSequence = LeafForSequence.Valid,
filterKeys: String => Boolean = _ => true
)(implicit tag: Tag[A]): ZLayer[System, ReadError[String], Has[A]] =
fromConfigDescriptorM(
ConfigSource
.fromSystemProps(keyDelimiter, valueDelimiter, leafForSequence, filterKeys)
.map(configDescriptor from _)
ZLayer.fromServiceM((system: System.Service) =>
read(
configDescriptor from ConfigSource.fromSystemProps(
keyDelimiter,
valueDelimiter,
filterKeys,
system
)
)
)

private[config] def fromConfigDescriptor[A](
configDescriptor: ConfigDescriptor[A]
)(implicit tag: Tag[A]): Layer[ReadError[K], Has[A]] =
ZLayer.fromEffect(ZIO.fromEither(read(configDescriptor)))

private[config] def fromConfigDescriptorM[R, E >: ReadError[K], A](
configDescriptor: ZIO[R, E, ConfigDescriptor[A]]
)(implicit tag: Tag[A]): ZLayer[R, E, Has[A]] =
ZLayer.fromEffect(
configDescriptor.flatMap(descriptor => ZIO.fromEither(read(descriptor)))
)
ZLayer.fromEffect(read(configDescriptor))
}

}
55 changes: 31 additions & 24 deletions core/jvm/src/main/scala/zio/config/ConfigStringModule.scala
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package zio.config

import com.github.ghik.silencer.silent
import zio.system.System
import zio.{Has, Layer, Tag, ZIO, ZLayer}

Expand All @@ -9,8 +10,7 @@ import java.time.{Instant, LocalDate, LocalDateTime, LocalTime}
import java.util.{Properties, UUID}
import scala.concurrent.duration.Duration

trait ConfigStringModule extends ConfigModule with ConfigSourceStringModule {

trait ConfigStringModule extends ConfigModule with ConfigSourceModule {
object ConfigDescriptor extends ConfigDescriptorFunctions {
import ConfigDescriptorAdt._

Expand Down Expand Up @@ -682,7 +682,6 @@ trait ConfigStringModule extends ConfigModule with ConfigSourceStringModule {
source: String = "constant",
keyDelimiter: Option[Char] = None,
valueDelimiter: Option[Char] = None,
leafForSequence: LeafForSequence = LeafForSequence.Valid,
filterKeys: String => Boolean = _ => true
)(implicit tag: Tag[A]): Layer[ReadError[String], Has[A]] =
fromConfigDescriptor(
Expand All @@ -691,7 +690,6 @@ trait ConfigStringModule extends ConfigModule with ConfigSourceStringModule {
source,
keyDelimiter,
valueDelimiter,
leafForSequence,
filterKeys
)
)
Expand Down Expand Up @@ -720,11 +718,10 @@ trait ConfigStringModule extends ConfigModule with ConfigSourceStringModule {
configDescriptor: ConfigDescriptor[A],
source: String,
keyDelimiter: Option[Char] = None,
leafForSequence: LeafForSequence = LeafForSequence.Valid,
filterKeys: String => Boolean = _ => true
)(implicit tag: Tag[A]): Layer[ReadError[String], Has[A]] =
fromConfigDescriptor(
configDescriptor from ConfigSource.fromMultiMap(map, source, keyDelimiter, leafForSequence, filterKeys)
configDescriptor from ConfigSource.fromMultiMap(map, source, keyDelimiter, filterKeys)
)

/**
Expand Down Expand Up @@ -754,7 +751,6 @@ trait ConfigStringModule extends ConfigModule with ConfigSourceStringModule {
source: String,
keyDelimiter: Option[Char] = None,
valueDelimiter: Option[Char] = None,
leafForSequence: LeafForSequence = LeafForSequence.Valid,
filterKeys: String => Boolean = _ => true
)(implicit tag: Tag[A]): Layer[ReadError[String], Has[A]] =
fromConfigDescriptor(
Expand All @@ -763,7 +759,6 @@ trait ConfigStringModule extends ConfigModule with ConfigSourceStringModule {
source,
keyDelimiter,
valueDelimiter,
leafForSequence,
filterKeys
)
)
Expand Down Expand Up @@ -794,13 +789,11 @@ trait ConfigStringModule extends ConfigModule with ConfigSourceStringModule {
configDescriptor: ConfigDescriptor[A],
keyDelimiter: Option[Char] = None,
valueDelimiter: Option[Char] = None,
leafForSequence: LeafForSequence = LeafForSequence.Valid,
filterKeys: String => Boolean = _ => true
)(implicit tag: Tag[A]): Layer[Throwable, Has[A]] =
fromConfigDescriptorM(
ConfigSource
.fromPropertiesFile(filePath, keyDelimiter, valueDelimiter, leafForSequence, filterKeys)
.map(configDescriptor from _)
)(implicit tag: Tag[A]): Layer[ReadError[String], Has[A]] =
fromConfigDescriptor(
configDescriptor from ConfigSource
.fromPropertiesFile(filePath, keyDelimiter, valueDelimiter, filterKeys)
)

/**
Expand All @@ -826,17 +819,22 @@ trait ConfigStringModule extends ConfigModule with ConfigSourceStringModule {
*
* Note: The delimiter '.' for keys doesn't work in system environment.
*/
@silent("a type was inferred to be `Any`")
def fromSystemEnv[K, V, A](
configDescriptor: ConfigDescriptor[A],
keyDelimiter: Option[Char] = None,
valueDelimiter: Option[Char] = None,
leafForSequence: LeafForSequence = LeafForSequence.Valid,
filterKeys: String => Boolean = _ => true
)(implicit tag: Tag[A]): ZLayer[System, ReadError[String], Has[A]] =
fromConfigDescriptorM(
ConfigSource
.fromSystemEnv(keyDelimiter, valueDelimiter, leafForSequence, filterKeys)
.map(configDescriptor from _)
ZLayer.fromServiceM((system: System.Service) =>
read(
configDescriptor from ConfigSource.fromSystemEnv(
keyDelimiter,
valueDelimiter,
filterKeys,
system
)
)
)

/**
Expand All @@ -860,25 +858,34 @@ trait ConfigStringModule extends ConfigModule with ConfigSourceStringModule {
* nested("KAFKA")(string("SERVERS") |@| string("SERDE"))(KafkaConfig.apply, KafkaConfig.unapply)
* }}}
*/
@silent("a type was inferred to be `Any`")
def fromSystemProperties[K, V, A](
configDescriptor: ConfigDescriptor[A],
keyDelimiter: Option[Char] = None,
valueDelimiter: Option[Char] = None
valueDelimiter: Option[Char] = None,
filterKeys: String => Boolean = _ => true
)(implicit tag: Tag[A]): ZLayer[System, ReadError[String], Has[A]] =
fromConfigDescriptorM(
ConfigSource.fromSystemProps(keyDelimiter, valueDelimiter).map(configDescriptor from _)
ZLayer.fromServiceM((system: System.Service) =>
read(
configDescriptor from ConfigSource.fromSystemProps(
keyDelimiter,
valueDelimiter,
filterKeys,
system
)
)
)

private[config] def fromConfigDescriptor[A](
configDescriptor: ConfigDescriptor[A]
)(implicit tag: Tag[A]): Layer[ReadError[K], Has[A]] =
ZLayer.fromEffect(ZIO.fromEither(read(configDescriptor)))
ZLayer.fromEffect(read(configDescriptor))

private[config] def fromConfigDescriptorM[R, E >: ReadError[K], A](
configDescriptor: ZIO[R, E, ConfigDescriptor[A]]
)(implicit tag: Tag[A]): ZLayer[R, E, Has[A]] =
ZLayer.fromEffect(
configDescriptor.flatMap(descriptor => ZIO.fromEither(read(descriptor)))
configDescriptor.flatMap(descriptor => read(descriptor))
)
}

Expand Down
Loading

0 comments on commit dfeeb5c

Please sign in to comment.