Repository: 7mind/izumi
Pull request #954 (2020-03-15 21:04:32)

Fix reading case classes with private fields as configs by updating to magnolia-0.12.8

codecov-io: # [Codecov](https://codecov.io/gh/7mind/izumi/pull/954?src=pr&el=h1) Report
> Merging [#954](https://codecov.io/gh/7mind/izumi/pull/954?src=pr&el=desc) into [develop](https://codecov.io/gh/7mind/izumi/commit/f461f36edd26ba82a0c3197341f9d97300878217&el=desc) will **increase** coverage by `0.28%`.
> The diff coverage is `n/a`.


```diff
@@             Coverage Diff             @@
##           develop     #954      +/-   ##
===========================================
+ Coverage    58.25%   58.54%   +0.28%     
===========================================
  Files          357      356       -1     
  Lines         7652     7463     -189     
  Branches       486      485       -1     
===========================================
- Hits          4458     4369      -89     
+ Misses        3194     3094     -100     
```


Patch:
diff --git a/build.sbt b/build.sbt
index 609d31285..313a94446 100644
--- a/build.sbt
+++ b/build.sbt
@@ -629,7 +629,8 @@ lazy val `fundamentals-json-circe` = project.in(file("fundamentals/fundamentals-
       "io.circe" %% "circe-parser" % V.circe,
       "io.circe" %% "circe-literal" % V.circe,
       "io.circe" %% "circe-generic-extras" % V.circe_generic_extras,
-      "io.circe" %% "circe-derivation" % V.circe_derivation
+      "io.circe" %% "circe-derivation" % V.circe_derivation,
+      "org.scala-lang" % "scala-reflect" % scalaVersion.value % Provided
     )
   )
   .settings(
@@ -1034,6 +1035,7 @@ lazy val `distage-extension-config` = project.in(file("distage/distage-extension
       "org.scala-lang.modules" %% "scala-collection-compat" % V.collection_compat,
       "org.scalatest" %% "scalatest" % V.scalatest % Test,
       "com.github.pureconfig" %% "pureconfig-magnolia" % V.pureconfig,
+      "com.propensive" %% "magnolia" % V.magnolia,
       "org.scala-lang" % "scala-reflect" % scalaVersion.value % Provided
     )
   )
diff --git a/distage/distage-core-api/.jvm/src/main/scala/izumi/distage/model/reflection/MirrorProvider.scala b/distage/distage-core-api/.jvm/src/main/scala/izumi/distage/model/reflection/MirrorProvider.scala
index 24cf278b1..1dfe7ca47 100644
--- a/distage/distage-core-api/.jvm/src/main/scala/izumi/distage/model/reflection/MirrorProvider.scala
+++ b/distage/distage-core-api/.jvm/src/main/scala/izumi/distage/model/reflection/MirrorProvider.scala
@@ -2,7 +2,6 @@ package izumi.distage.model.reflection
 
 import java.lang.reflect.Modifier
 
-import izumi.distage.model.reflection.SafeType
 import izumi.fundamentals.reflection.TypeUtil
 
 trait MirrorProvider {
diff --git a/project/Deps.sc b/project/Deps.sc
index e1ba26d13..2f2f481d1 100644
--- a/project/Deps.sc
+++ b/project/Deps.sc
@@ -17,6 +17,7 @@ object Izumi {
     val circe_generic_extras = Version.VExpr("V.circe_generic_extras")
     val circe_derivation = Version.VExpr("V.circe_derivation")
     val pureconfig = Version.VExpr("V.pureconfig")
+    val magnolia = Version.VExpr("V.magnolia")
     val jawn = Version.VExpr("V.jawn")
     val http4s = Version.VExpr("V.http4s")
     val classgraph = Version.VExpr("V.classgraph")
@@ -77,6 +78,7 @@ object Izumi {
       circe_derivation,
     ).map(_ in Scope.Compile.all)
     final val pureconfig_magnolia = Library("com.github.pureconfig", "pureconfig-magnolia", V.pureconfig, LibraryType.Auto)
+    final val magnolia = Library("com.propensive", "magnolia", V.magnolia, LibraryType.Auto)
 
     final val zio_core = Library("dev.zio", "zio", V.zio, LibraryType.Auto)
     final val zio_interop_cats = Library("dev.zio", "zio-interop-cats", V.zio_interop_cats, LibraryType.Auto)
@@ -442,7 +444,7 @@ object Izumi {
       ),
       Artifact(
         name = Projects.distage.config,
-        libs = Seq(pureconfig_magnolia).map(_ in Scope.Compile.all) ++ Seq(scala_reflect in Scope.Provided.all),
+        libs = Seq(pureconfig_magnolia, magnolia).map(_ in Scope.Compile.all) ++ Seq(scala_reflect in Scope.Provided.all),
         depends = Seq(Projects.distage.model).map(_ in Scope.Compile.all) ++
           Seq(Projects.distage.core).map(_ tin Scope.Test.all),
         platforms = Targets.jvm,
diff --git a/project/Versions.scala b/project/Versions.scala
index 1bfb3621d..c0f79e10e 100644
--- a/project/Versions.scala
+++ b/project/Versions.scala
@@ -16,6 +16,7 @@ object V {
   val circe_generic_extras = "0.13.0"
   val circe_derivation = "0.13.0-M2"
   val pureconfig = "0.12.3"
+  val magnolia = "0.12.8"
   val jawn = "1.0.0"
 
   val http4s = "0.21.1"


Test patch:
diff --git a/distage/distage-extension-config/src/test/resources/private-fields-test.conf b/distage/distage-extension-config/src/test/resources/private-fields-test.conf
new file mode 100644
index 000000000..dbfae791d
--- /dev/null
+++ b/distage/distage-extension-config/src/test/resources/private-fields-test.conf
@@ -0,0 +1,3 @@
+PrivateCaseClass {
+  private-custom-field-name = super secret value
+}
diff --git a/distage/distage-extension-config/src/test/scala/com/github/pshirshov/configapp/TestConfigReaders.scala b/distage/distage-extension-config/src/test/scala/com/github/pshirshov/configapp/TestConfigReaders.scala
index 0732b7c58..978d59c87 100644
--- a/distage/distage-extension-config/src/test/scala/com/github/pshirshov/configapp/TestConfigReaders.scala
+++ b/distage/distage-extension-config/src/test/scala/com/github/pshirshov/configapp/TestConfigReaders.scala
@@ -25,6 +25,12 @@ case class CustomCaseClass(
                             mapListCustomObject: Map[String, List[CustomObject]],
                           )
 
+case class PrivateCaseClass(
+                             private val `private-custom-field-name`: String
+                           ) {
+  val customFieldName = `private-custom-field-name`
+}
+
 case class CustomObject(value: Int)
 object CustomObject {
   implicit val pureconfigReader: ConfigReader[CustomObject] = ConfigReader.fromStringOpt {
@@ -84,4 +90,9 @@ object TestConfigReaders {
     make[Service[CustomCaseClass]]
     makeConfig[CustomCaseClass]("CustomCaseClass")
   })
+
+  final val privateFieldsCodecDefinition = PlannerInput.noGc(new ConfigModuleDef {
+    make[Service[PrivateCaseClass]]
+    makeConfig[PrivateCaseClass]("PrivateCaseClass")
+  })
 }
diff --git a/distage/distage-extension-config/src/test/scala/izumi/distage/config/ConfigTest.scala b/distage/distage-extension-config/src/test/scala/izumi/distage/config/ConfigTest.scala
index 175881931..b23fad7de 100644
--- a/distage/distage-extension-config/src/test/scala/izumi/distage/config/ConfigTest.scala
+++ b/distage/distage-extension-config/src/test/scala/izumi/distage/config/ConfigTest.scala
@@ -14,7 +14,8 @@ import scala.collection.immutable.ListSet
 
 final class ConfigTest extends AnyWordSpec {
   def mkConfigModule(path: String)(p: PlannerInput): PlannerInput = {
-    p.copy(bindings = p.bindings ++ mkModule(ConfigFactory.load(path)))
+    p.copy(bindings = p.bindings ++
+      mkModule(ConfigFactory.load(path, ConfigParseOptions.defaults().setAllowMissing(false), ConfigResolveOptions.noSystem())))
   }
 
   def mkModule(config: Config): AppConfigModule = {
@@ -148,6 +149,13 @@ final class ConfigTest extends AnyWordSpec {
       assert(context.get[Service[BackticksCaseClass]].conf == BackticksCaseClass(true))
     }
 
+    "resolve case classes with private fields" in {
+      val context = Injector()
+        .produce(mkConfigModule("private-fields-test.conf")(TestConfigReaders.privateFieldsCodecDefinition)).unsafeGet()
+
+      assert(context.get[Service[PrivateCaseClass]].conf == PrivateCaseClass("super secret value"))
+    }
+
     "resolve config sealed traits (with progression test for https://github.com/scala/bug/issues/11645)" in {
       // FIXME: pureconfig-magnolia can't read enumerations properly
       val context1 =
diff --git a/distage/distage-testkit-scalatest/src/main/scala/izumi/distage/testkit/services/scalatest/dstest/DistageAbstractScalatestSpec.scala b/distage/distage-testkit-scalatest/src/main/scala/izumi/distage/testkit/services/scalatest/dstest/DistageAbstractScalatestSpec.scala
index 571926c0b..aea631362 100644
--- a/distage/distage-testkit-scalatest/src/main/scala/izumi/distage/testkit/services/scalatest/dstest/DistageAbstractScalatestSpec.scala
+++ b/distage/distage-testkit-scalatest/src/main/scala/izumi/distage/testkit/services/scalatest/dstest/DistageAbstractScalatestSpec.scala
@@ -1,6 +1,6 @@
 package izumi.distage.testkit.services.scalatest.dstest
 
-import distage.{Tag, TagK, TagKK}
+import distage.{TagK, TagKK}
 import izumi.distage.model.effect.DIEffect
 import izumi.distage.model.providers.ProviderMagnet
 import izumi.distage.testkit.TestConfig
diff --git a/distage/distage-testkit-scalatest/src/test/scala/izumi/distage/testkit/distagesuite/DistageTestExample.scala b/distage/distage-testkit-scalatest/src/test/scala/izumi/distage/testkit/distagesuite/DistageTestExample.scala
index 8a907978c..5a5a070fc 100644
--- a/distage/distage-testkit-scalatest/src/test/scala/izumi/distage/testkit/distagesuite/DistageTestExample.scala
+++ b/distage/distage-testkit-scalatest/src/test/scala/izumi/distage/testkit/distagesuite/DistageTestExample.scala
@@ -144,12 +144,12 @@ abstract class DistageTestExampleBase[F[_]: TagK](implicit F: DIEffect[F]) exten
 
     "test 4 (should be ignored)" in {
       _: ApplePaymentProvider[F] =>
-        assert(???)
+        assert(false)
     }
 
     "test 5 (should be ignored)" skip {
       _: MockCachedUserService[F] =>
-        assert(???)
+        assert(false)
     }
 
     "test 6 (should be ignored)" in {