Skip to content

Commit

Permalink
Merge branch 'series/4.x' into update/sbt-ci-release-1.9.2
Browse files Browse the repository at this point in the history
  • Loading branch information
kyri-petrou authored Dec 29, 2024
2 parents af9bd69 + f2b642e commit 1e70f05
Show file tree
Hide file tree
Showing 5 changed files with 86 additions and 76 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ jobs:
- name: Cache scala dependencies
uses: coursier/cache-action@v6
- name: Check Document Generation
run: ./sbt docs/compileDocs
run: sbt docs/compileDocs

lint:
runs-on: ubuntu-22.04
Expand Down
18 changes: 12 additions & 6 deletions .github/workflows/site.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,16 @@ jobs:
uses: actions/checkout@v3.3.0
with:
fetch-depth: '0'
- name: Setup Scala
- name: Setup JVM
uses: actions/setup-java@v4.5.0
with:
distribution: temurin
java-version: 17
check-latest: true
- name: Setup SBT
uses: sbt/setup-sbt@v1
- name: Check website build process
run: sbt docs/buildWebsite
run: sbt docs/buildWebsite
publish-docs:
name: Publish Docs
runs-on: ubuntu-latest
Expand All @@ -38,19 +40,21 @@ jobs:
uses: actions/checkout@v3.3.0
with:
fetch-depth: '0'
- name: Setup Scala
- name: Setup JVM
uses: actions/setup-java@v4.5.0
with:
distribution: temurin
java-version: 17
check-latest: true
- name: Setup SBT
uses: sbt/setup-sbt@v1
- name: Setup NodeJs
uses: actions/setup-node@v3
with:
node-version: 16.x
registry-url: https://registry.npmjs.org
- name: Publish Docs to NPM Registry
run: sbt docs/publishToNpm
run: sbt docs/publishToNpm
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
generate-readme:
Expand All @@ -63,14 +67,16 @@ jobs:
with:
ref: ${{ github.head_ref }}
fetch-depth: '0'
- name: Setup Scala
- name: Setup JVM
uses: actions/setup-java@v4.5.0
with:
distribution: temurin
java-version: 17
check-latest: true
- name: Setup SBT
uses: sbt/setup-sbt@v1
- name: Generate Readme
run: sbt docs/generateReadme
run: sbt docs/generateReadme
- name: Commit Changes
run: |
git config --local user.email "github-actions[bot]@users.noreply.github.com"
Expand Down
15 changes: 7 additions & 8 deletions core/shared/src/main/scala-3.x/zio/config/TupleConversion.scala
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ trait TupleConversion[A, B] {
object TupleConversion extends ImplicitTupleConversion

trait ImplicitTupleConversion {
inline given autoTupleConversion[Prod <: Product](using
given autoTupleConversion[Prod <: Product](using
m: Mirror.ProductOf[Prod]
): TupleConversion[Prod, m.MirroredElemTypes] =
new TupleConversion[Prod, m.MirroredElemTypes] {
Expand All @@ -20,12 +20,11 @@ trait ImplicitTupleConversion {

inline given autoTupleConversion1[Prod <: Product, A](using
c: TupleConversion[Prod, Tuple1[A]]
): TupleConversion[Prod, A] =
new TupleConversion[Prod, A] {
def to(a: Prod): A = {
val Tuple1(v) = c.to(a)
v
}
def from(b: A): Prod = c.from(Tuple1(b))
): TupleConversion[Prod, A] with {
def to(a: Prod): A = {
val Tuple1(v) = c.to(a)
v
}
def from(b: A): Prod = c.from(Tuple1(b))
}
}
4 changes: 1 addition & 3 deletions core/shared/src/main/scala/zio/config/package.scala
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
package zio

import zio.config.syntax.ConfigSyntax

package object config
extends KeyConversionFunctions
with ConfigSyntax
with syntax.ConfigSyntax
with ImplicitTupleConversion
with ConfigDocsModule {

Expand Down
Original file line number Diff line number Diff line change
@@ -1,21 +1,17 @@
package zio.config.magnolia

import zio.config._
import zio.NonEmptyChunk

import java.io.File
import java.net.{URI, URL}
import java.time.{Duration, Instant, LocalDate, LocalDateTime, LocalTime, OffsetDateTime}
import zio.Config.*
import zio.config.*
import zio.config.derivation.*
import zio.config.magnolia.DeriveConfig.*
import zio.{Chunk, Config, LogLevel, NonEmptyChunk}

import java.net.URI
import java.time.{LocalDate, LocalDateTime, LocalTime, OffsetDateTime, *}
import java.util.UUID
import scala.concurrent.duration.{Duration => ScalaDuration}
import scala.deriving._
import scala.compiletime.{constValue, constValueTuple, erasedValue, summonFrom, summonInline}
import scala.quoted
import scala.util.Try
import DeriveConfig._
import zio.{Chunk, Config, ConfigProvider, LogLevel}, Config._
import zio.config.syntax._
import zio.config.derivation._
import scala.annotation.{targetName, threadUnsafe}
import scala.compiletime.*
import scala.deriving.*

final case class DeriveConfig[A](desc: Config[A], metadata: Option[DeriveConfig.Metadata] = None) {
def ??(description: String): DeriveConfig[A] =
Expand Down Expand Up @@ -119,35 +115,43 @@ object DeriveConfig {
DeriveConfig.from(table(ev.desc))

inline def summonDeriveConfigForCoProduct[T <: Tuple]: List[DeriveConfig[Any]] =
inline erasedValue[T] match
inline erasedValue[T] match {
case _: EmptyTuple => Nil
case _: (t *: ts) =>
val desc = summonInline[DeriveConfig[t]]
DeriveConfig[Any](
desc.desc,
desc.metadata
) :: summonDeriveConfigForCoProduct[ts]
}

inline def summonDeriveConfigAll[T <: Tuple]: List[DeriveConfig[_]] =
inline erasedValue[T] match
inline erasedValue[T] match {
case _: EmptyTuple => Nil
case _: (t *: ts) =>
summonInline[DeriveConfig[t]] :: summonDeriveConfigAll[ts]
case _: (t *: ts) => summonInline[DeriveConfig[t]] :: summonDeriveConfigAll[ts]
}

inline def labelsOf[T <: Tuple]: List[String] =
inline erasedValue[T] match
inline erasedValue[T] match {
case _: EmptyTuple => Nil
case _: (t *: ts) => constValue[t].toString :: labelsOf[ts]
}

inline def customNamesOf[T]: List[String] =
Macros.nameOf[T].map(_.name)
inline Macros.nameOf[T] match {
case Nil => Nil
case names => names.map(_.name)
}

inline def customFieldNamesOf[T]: Map[String, name] =
Macros.fieldNameOf[T].flatMap { case (str, nmes) => nmes.map(name => (str, name)) }.toMap
inline Macros.fieldNameOf[T] match {
case Nil => Map.empty[String, name]
case names => names.flatMap { case (str, nmes) => nmes.map(name => (str, name)) }.toMap
}

inline given derived[T](using m: Mirror.Of[T]): DeriveConfig[T] =
inline m match
case s: Mirror.SumOf[T] =>
case _: Mirror.SumOf[T] =>
val coproductName: CoproductName =
CoproductName(
originalName = constValue[m.MirroredLabel],
Expand All @@ -156,11 +160,8 @@ object DeriveConfig {
typeDiscriminator = Macros.discriminator[T].headOption.map(_.keyName)
)

lazy val subClassDescriptions =
summonDeriveConfigForCoProduct[m.MirroredElemTypes]

lazy val desc =
mergeAllProducts(subClassDescriptions.map(castTo[DeriveConfig[T]]), coproductName.typeDiscriminator)
val subClassDescriptions = summonDeriveConfigForCoProduct[m.MirroredElemTypes]
val desc = mergeAllProducts(subClassDescriptions.map(castTo[DeriveConfig[T]]), coproductName.typeDiscriminator)

DeriveConfig.from(tryAllKeys(desc.desc, None, coproductName.alternativeNames))

Expand All @@ -172,44 +173,39 @@ object DeriveConfig {
descriptions = Macros.documentationOf[T].map(_.describe)
)

lazy val originalFieldNamesList =
labelsOf[m.MirroredElemLabels]

lazy val customFieldNameMap =
customFieldNamesOf[T]

lazy val documentations =
Macros.fieldDocumentationOf[T].toMap

lazy val fieldAndDefaultValues: Map[String, Any] =
Macros.defaultValuesOf[T].toMap

lazy val fieldNames =
originalFieldNamesList.foldRight(Nil: List[FieldName]) { (str, list) =>
val alternativeNames = customFieldNameMap.get(str).map(v => List(v.name)).getOrElse(Nil)
val descriptions = documentations.get(str).map(_.map(_.describe)).getOrElse(Nil)
FieldName(str, alternativeNames.toList, descriptions) :: list
}

lazy val fieldConfigs =
summonDeriveConfigAll[m.MirroredElemTypes].asInstanceOf[List[DeriveConfig[Any]]]
val originalFieldNamesList = labelsOf[m.MirroredElemLabels]
val customFieldNameMap = customFieldNamesOf[T]
val documentations = Macros.fieldDocumentationOf[T].toMap
val fieldNames = mapOriginalNames(originalFieldNamesList, documentations, customFieldNameMap)

lazy val fieldConfigsWithDefaultValues =
@threadUnsafe lazy val fieldConfigsWithDefaultValues = {
val fieldConfigs = summonDeriveConfigAll[m.MirroredElemTypes].asInstanceOf[List[DeriveConfig[Any]]]
val fieldAndDefaultValues = Macros.defaultValuesOf[T].toMap
addDefaultValues(fieldAndDefaultValues, originalFieldNamesList, fieldConfigs)
}

mergeAllFields(
fieldConfigsWithDefaultValues,
productName,
fieldNames,
lst => m.fromProduct(Tuple.fromArray(lst.toArray[Any])),
castTo[Product](_).productIterator.toList
lst => m.fromProduct(Tuple.fromArray(lst.toArray[Any]))
)

private def mapOriginalNames(
names: List[String],
docs: Map[String, List[describe]],
customFieldNames: Map[String, name]
): List[FieldName] =
names.foldRight(List.empty[FieldName]) { (str, list) =>
val alternativeNames = customFieldNames.get(str).map(v => List(v.name)).getOrElse(Nil)
val descriptions = docs.get(str).map(_.map(_.describe)).getOrElse(Nil)
FieldName(str, alternativeNames, descriptions) :: list
}

def mergeAllProducts[T](
allDescs: => List[DeriveConfig[T]],
typeDiscriminator: Option[String]
): DeriveConfig[T] =

): DeriveConfig[T] = {
val desc =
typeDiscriminator match {
case None =>
Expand Down Expand Up @@ -238,11 +234,12 @@ object DeriveConfig {

case None => Nil
}
}: _*
}*
)
}

DeriveConfig.from(desc)
}

def addDefaultValues(
defaultValues: Map[String, Any],
Expand All @@ -256,14 +253,23 @@ object DeriveConfig {
}
}

@deprecated("use overloaded method without providing `g`")
def mergeAllFields[T](
allDescs: => List[DeriveConfig[_]],
productName: ProductName,
fieldNames: => List[FieldName],
f: List[Any] => T,
g: T => List[Any]
): DeriveConfig[T] =
if fieldNames.isEmpty then // if there are no fields in the product then the value is the name of the product itself
mergeAllFields[T](allDescs, productName, fieldNames, f)

def mergeAllFields[T](
allDescs: => List[DeriveConfig[_]],
productName: ProductName,
fieldNames: List[FieldName],
f: List[Any] => T
): DeriveConfig[T] =
if fieldNames.isEmpty then { // if there are no fields in the product then the value is the name of the product itself
val tryAllPaths =
(productName.originalName :: productName.alternativeNames)
.map(n => zio.Config.constant(n))
Expand All @@ -273,17 +279,18 @@ object DeriveConfig {
tryAllPaths.map[T](_ => f(Nil)),
Some(Metadata.Object[T](productName, f(Nil))) // We propogate the info that product was actually an object
)
else
} else {
val listOfDesc =
fieldNames.zip(allDescs).map { case (fieldName, desc) =>
val fieldDesc = tryAllKeys(desc.desc, Some(fieldName.originalName), fieldName.alternativeNames)
fieldName.descriptions.foldRight(fieldDesc)((doc, desc) => desc ?? doc)
}

val descOfList =
Config.collectAll(listOfDesc.head, listOfDesc.tail: _*)
Config.collectAll(listOfDesc.head, listOfDesc.tail*)

DeriveConfig(descOfList.map(f), Some(Metadata.Product(productName, fieldNames)))
}

def tryAllKeys[A](
desc: Config[A],
Expand Down

0 comments on commit 1e70f05

Please sign in to comment.