From 63845483c83af6cd4aef4a90102ac620286a57a4 Mon Sep 17 00:00:00 2001 From: Kai <450507+neko-kai@users.noreply.github.com> Date: Mon, 17 Jun 2024 21:36:40 +0100 Subject: [PATCH] Hotfix: fix a regression in 1.2.9 where ConfTags with similar paths were lost when module was included (#2136) --- .../distage/model/definition/BindingTag.scala | 6 +++- .../izumi/distage/config/ConfigTest.scala | 30 ++++++++++++++++--- .../distage/config/ConfigModuleDef.scala | 6 ++-- .../izumi/distage/config/model/ConfTag.scala | 7 ++--- 4 files changed, 37 insertions(+), 12 deletions(-) diff --git a/distage/distage-core-api/src/main/scala/izumi/distage/model/definition/BindingTag.scala b/distage/distage-core-api/src/main/scala/izumi/distage/model/definition/BindingTag.scala index 3f4f96a6f9..6500b503ed 100644 --- a/distage/distage-core-api/src/main/scala/izumi/distage/model/definition/BindingTag.scala +++ b/distage/distage-core-api/src/main/scala/izumi/distage/model/definition/BindingTag.scala @@ -5,7 +5,11 @@ import izumi.fundamentals.platform.cache.CachedProductHashcode import scala.language.implicitConversions -/** An attachment that can be added to a binding using its `.tagged` method */ +/** An attachment that can be added to a binding using its `.tagged` method + * + * @note an inheritor of BindingTag must be an immutable case class + * and all of its fields must be used in `equals` / `hashCode`. + */ trait BindingTag extends CachedProductHashcode { this: Product => } object BindingTag { diff --git a/distage/distage-extension-config/.jvm/src/test/scala/izumi/distage/config/ConfigTest.scala b/distage/distage-extension-config/.jvm/src/test/scala/izumi/distage/config/ConfigTest.scala index fb9bd084fb..ed9ebc36cf 100644 --- a/distage/distage-extension-config/.jvm/src/test/scala/izumi/distage/config/ConfigTest.scala +++ b/distage/distage-extension-config/.jvm/src/test/scala/izumi/distage/config/ConfigTest.scala @@ -2,11 +2,12 @@ package izumi.distage.config import com.github.pshirshov.configapp.SealedTrait.CaseClass2 import com.github.pshirshov.configapp.SealedTrait2.{No, Yes} -import com.github.pshirshov.configapp._ -import com.typesafe.config._ -import distage.Injector -import izumi.distage.config.model.AppConfig +import com.github.pshirshov.configapp.* +import com.typesafe.config.* +import distage.{Injector, Mode, Repo} +import izumi.distage.config.model.{AppConfig, ConfTag} import izumi.distage.model.PlannerInput +import izumi.distage.model.definition.ModuleDef import org.scalatest.wordspec.AnyWordSpec import scala.collection.immutable.ListSet @@ -163,6 +164,27 @@ final class ConfigTest extends AnyWordSpec { assert(context2.get[Service[SealedCaseClass]].conf == SealedCaseClass(SealedTrait.CaseClass2(2, false, No))) } + "regression test: same path ConfTags are preserved when processing includes" in { + final case class A() + final case class B() + final case class C() + + val defn = new ModuleDef { + tag(Repo.Prod) + + include(new ConfigModuleDef { + tag(Mode.Test) + makeConfig[A]("x") + makeConfig[B]("x") + makeConfig[C]("x") + }) + } + + val confTags = defn.bindings.toList.flatMap(_.tags.collect { case c: ConfTag => c }) + + assert(confTags.map(_.tpe).toSet.size == 3) + } + } } diff --git a/distage/distage-extension-config/src/main/scala/izumi/distage/config/ConfigModuleDef.scala b/distage/distage-extension-config/src/main/scala/izumi/distage/config/ConfigModuleDef.scala index 6ba5824158..f8e582ef2a 100644 --- a/distage/distage-extension-config/src/main/scala/izumi/distage/config/ConfigModuleDef.scala +++ b/distage/distage-extension-config/src/main/scala/izumi/distage/config/ConfigModuleDef.scala @@ -44,15 +44,15 @@ object ConfigModuleDef { final class FromConfig[T](private val make: MakeDSL[T]) extends AnyVal { def fromConfig(path: String)(implicit tag: Tag[T], dec: DIConfigReader[T], meta: DIConfigMeta[T]): MakeDSLUnnamedAfterFrom[T] = { val parser = wireConfig[T](path) - make.tagged(ConfTag(path)(parser, meta.tpe)).from(parser) + make.tagged(ConfTag(path, parser, meta.tpe)).from(parser) } def fromConfigNamed(path: String)(implicit tag: Tag[T], dec: DIConfigReader[T], meta: DIConfigMeta[T]): MakeDSLNamedAfterFrom[T] = { val parser = wireConfig[T](path) - make.named(path).tagged(ConfTag(path)(parser, meta.tpe)).from(parser) + make.named(path).tagged(ConfTag(path, parser, meta.tpe)).from(parser) } def fromConfigWithDefault(path: String)(default: => T)(implicit tag: Tag[T], dec: DIConfigReader[T], meta: DIConfigMeta[T]): MakeDSLUnnamedAfterFrom[T] = { val parser = wireConfigWithDefault[T](path)(default) - make.tagged(ConfTag(path)(parser, meta.tpe)).from(parser) + make.tagged(ConfTag(path, parser, meta.tpe)).from(parser) } } diff --git a/distage/distage-extension-config/src/main/scala/izumi/distage/config/model/ConfTag.scala b/distage/distage-extension-config/src/main/scala/izumi/distage/config/model/ConfTag.scala index dfc902a9e0..25a120ae5b 100644 --- a/distage/distage-extension-config/src/main/scala/izumi/distage/config/model/ConfTag.scala +++ b/distage/distage-extension-config/src/main/scala/izumi/distage/config/model/ConfTag.scala @@ -4,8 +4,7 @@ import izumi.distage.config.codec.ConfigMetaType import izumi.distage.model.definition.BindingTag final case class ConfTag( - confPath: String -)(/* excluded from equals/hashCode */ - val parser: AppConfig => Any, - val tpe: ConfigMetaType, + confPath: String, + parser: AppConfig => Any, + tpe: ConfigMetaType, ) extends BindingTag