Skip to content

Commit b2a0d9a

Browse files
committed
0.9.95 fix #54 "Shared config objects"
#54 (comment)
1 parent 6743c7d commit b2a0d9a

File tree

10 files changed

+111
-58
lines changed

10 files changed

+111
-58
lines changed

build.sbt

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
lazy val tscfgVersion = setVersion("0.9.94")
1+
lazy val tscfgVersion = setVersion("0.9.95")
22

33
organization := "com.github.carueda"
44
name := "tscfg"

changelog.md

+6
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
2019-10-07 - 0.9.95
2+
3+
- fix #54 "Shared config objects"
4+
https://github.com/carueda/tscfg/issues/54#issuecomment-539096913.
5+
In short, the `@define`s are traversed first in ModelBuilder.
6+
17
2019-09-14 - 0.9.94
28

39
- resolve #54 "Shared config objects"

src/main/resources/application.conf

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
tscfg.version = 0.9.94
1+
tscfg.version = 0.9.95

src/main/scala/tscfg/ModelBuilder.scala

+12-36
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@ package tscfg
22

33
import com.typesafe.config._
44
import tscfg.generators.tsConfigUtil
5-
import tscfg.model.{AnnType, DURATION, ObjectType, SIZE}
65
import tscfg.model.durations.ms
6+
import tscfg.model.{DURATION, SIZE}
77

88
import scala.collection.JavaConverters._
99

@@ -42,13 +42,18 @@ class ModelBuilder(assumeAllRequired: Boolean = false) {
4242
private val warns = collection.mutable.ArrayBuffer[Warning]()
4343

4444
private def fromConfig(namespace: Namespace, conf: Config): model.ObjectType = {
45-
// do two passes as lightbend config does not necessarily preserve member order:
46-
val ot = fromConfig1(namespace, conf)
47-
fromConfig2(namespace, ot)
48-
}
49-
50-
private def fromConfig1(namespace: Namespace, conf: Config): model.ObjectType = {
5145
val memberStructs = getMemberStructs(conf)
46+
// have the `@define`s be traversed first:
47+
.sortWith { case (childStruct, s2)
48+
if (childStruct.isLeaf) false
49+
else if (s2.isLeaf) true
50+
else {
51+
val cv = conf.getValue(childStruct.name)
52+
val comments = cv.origin().comments().asScala.toList
53+
comments.exists(_.trim.startsWith("@define"))
54+
}
55+
}
56+
5257
val members: immutable.Map[String, model.AnnType] = memberStructs.map { childStruct
5358
val name = childStruct.name
5459
val cv = conf.getValue(name)
@@ -121,35 +126,6 @@ class ModelBuilder(assumeAllRequired: Boolean = false) {
121126
model.ObjectType(members)
122127
}
123128

124-
private def fromConfig2(namespace: Namespace, ot: model.ObjectType): model.ObjectType = {
125-
val resolvedMembers = ot.members.map { case (name, annType)
126-
val modAnnType = annType.t match {
127-
128-
case _:model.STRING.type
129-
annType.default match {
130-
case Some(strValue)
131-
namespace.resolveDefine(strValue) match {
132-
case Some(ort) AnnType(ort)
133-
case _ annType
134-
}
135-
136-
case None annType
137-
}
138-
139-
//// the following would be part of changes to allow recursive type
140-
//case ot:ObjectType ⇒
141-
// val ot2 = fromConfig2(namespace, ot)
142-
// AnnType(ot2)
143-
144-
case _ annType
145-
}
146-
147-
name modAnnType
148-
}
149-
150-
model.ObjectType(resolvedMembers)
151-
}
152-
153129
private case class Struct(name: String, members: mutable.HashMap[String, Struct] = mutable.HashMap.empty) {
154130
def isLeaf: Boolean = members.isEmpty
155131
// $COVERAGE-OFF$

src/main/scala/tscfg/Namespace.scala

+11-16
Original file line numberDiff line numberDiff line change
@@ -3,21 +3,15 @@ package tscfg
33
import tscfg.model.{ObjectRefType, Type}
44

55
object Namespace {
6-
val root: Namespace = new Namespace("", None)
7-
8-
def getAllDefines: Map[String, Type] = {
9-
allDefines.toMap
10-
}
11-
12-
private def addToAllDefines(defineFullPath: String, t: Type): Unit = {
13-
allDefines.update(defineFullPath, t)
14-
}
15-
16-
private val allDefines = collection.mutable.HashMap[String, Type]()
6+
/** Returns a new, empty root namespace. */
7+
def root: Namespace = new Namespace("", None,
8+
collection.mutable.HashMap[String, Type]())
179
}
1810

19-
class Namespace private(simpleName: String, parent: Option[Namespace]) {
20-
import Namespace.addToAllDefines
11+
class Namespace private(simpleName: String, parent: Option[Namespace],
12+
allDefines: collection.mutable.HashMap[String, Type]) {
13+
14+
def getAllDefines: Map[String, Type] = allDefines.toMap
2115

2216
def getPath: Seq[String] = parent match {
2317
case None Seq.empty
@@ -26,7 +20,7 @@ class Namespace private(simpleName: String, parent: Option[Namespace]) {
2620

2721
def getPathString: String = getPath.mkString(".")
2822

29-
def extend(simpleName: String): Namespace = new Namespace(simpleName, Some(this))
23+
def extend(simpleName: String): Namespace = new Namespace(simpleName, Some(this), allDefines)
3024

3125
private val defineNames = collection.mutable.HashSet[String]()
3226

@@ -35,13 +29,14 @@ class Namespace private(simpleName: String, parent: Option[Namespace]) {
3529
assert(simpleName.nonEmpty)
3630

3731
if (defineNames.contains(simpleName)) {
38-
println(s"WARN: duplicate @define '$simpleName' in namespace $getPathString. Ignoring previous entry")
32+
val ns = if (getPath.nonEmpty) s"'$getPathString'" else "(root)"
33+
println(s"WARN: duplicate @define '$simpleName' in namespace $ns. Ignoring previous entry")
3934
// TODO include in build warnings
4035
}
4136

4237
defineNames.add(simpleName)
4338

44-
addToAllDefines(resolvedFullPath(simpleName), t)
39+
allDefines.update(resolvedFullPath(simpleName), t)
4540
}
4641

4742
private def resolvedFullPath(simpleName: String): String = parent match {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
#@define
2+
Struct = {
3+
a = int
4+
}
5+
6+
exampleD {
7+
test = Struct
8+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
#@define
2+
Struct = {
3+
a = int
4+
}
5+
6+
exampleE {
7+
test = Struct
8+
}

src/test/scala/tscfg/NamespaceSpec.scala

+4-4
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ class NamespaceSpec extends Specification {
2222
"add and resolve define" in {
2323
root.addDefine("RootDef1", objectType)
2424
root.resolveDefine("RootDef1") must beSome
25-
Namespace.getAllDefines.keys must_== Set("RootDef1")
25+
root.getAllDefines.keys must_== Set("RootDef1")
2626
}
2727
}
2828

@@ -35,7 +35,7 @@ class NamespaceSpec extends Specification {
3535
ns00.addDefine("n00def1", objectType)
3636
ns00.resolveDefine("n00def1") must beSome
3737

38-
Namespace.getAllDefines.keys must_== Set("RootDef1", "ns00.n00def1")
38+
root.getAllDefines.keys must_== Set("RootDef1", "ns00.n00def1")
3939
}
4040

4141
"resolve define in parent namespace" in {
@@ -52,7 +52,7 @@ class NamespaceSpec extends Specification {
5252
ns000.addDefine("n000def1", objectType)
5353
ns000.resolveDefine("n000def1") must beSome
5454

55-
Namespace.getAllDefines.keys must_== Set(
55+
root.getAllDefines.keys must_== Set(
5656
"RootDef1", "ns00.n00def1", "ns00.ns000.n000def1"
5757
)
5858
}
@@ -77,7 +77,7 @@ class NamespaceSpec extends Specification {
7777

7878
"all defines" should {
7979
"resolve" in {
80-
val all = Namespace.getAllDefines
80+
val all = root.getAllDefines
8181
all.size must_== 3
8282
all.get("RootDef1") must beSome(objectType)
8383
all.get("ns00.n00def1") must beSome(objectType)

src/test/scala/tscfg/generators/java/JavaMainSpec.scala

+30
Original file line numberDiff line numberDiff line change
@@ -732,6 +732,36 @@ class JavaMainSpec extends Specification {
732732
}
733733
}
734734

735+
"issue 54 - shared config - exampleD" should {
736+
"be handled" in {
737+
val c = new JavaIssue54exampleDCfg(ConfigFactory.parseString(
738+
"""
739+
|exampleD {
740+
| test {
741+
| a = 1
742+
| }
743+
|}
744+
|""".stripMargin))
745+
746+
c.exampleD.test.a === 1
747+
}
748+
}
749+
750+
"issue 54 - shared config - exampleE" should {
751+
"be handled" in {
752+
val c = new JavaIssue54exampleECfg(ConfigFactory.parseString(
753+
"""
754+
|exampleE {
755+
| test {
756+
| a = 1
757+
| }
758+
|}
759+
|""".stripMargin))
760+
761+
c.exampleE.test.a === 1
762+
}
763+
}
764+
735765
/* SKIP due to weird travis-ci issue (with the scala version, not the java one)
736766
"issue 54 - shared config - example2" should {
737767
"be handled" in {

src/test/scala/tscfg/generators/scala/ScalaMainSpec.scala

+30
Original file line numberDiff line numberDiff line change
@@ -641,6 +641,36 @@ class ScalaMainSpec extends Specification {
641641
}
642642
}
643643

644+
"issue 54 - shared config - exampleD" should {
645+
"be handled" in {
646+
val c = ScalaIssue54exampleDCfg(ConfigFactory.parseString(
647+
"""
648+
|exampleD {
649+
| test {
650+
| a = 1
651+
| }
652+
|}
653+
|""".stripMargin))
654+
655+
c.exampleD.test.a === 1
656+
}
657+
}
658+
659+
"issue 54 - shared config - exampleE" should {
660+
"be handled" in {
661+
val c = ScalaIssue54exampleECfg(ConfigFactory.parseString(
662+
"""
663+
|exampleE {
664+
| test {
665+
| a = 1
666+
| }
667+
|}
668+
|""".stripMargin))
669+
670+
c.exampleE.test.a === 1
671+
}
672+
}
673+
644674
// for some strange reason ScalaIssue54bCfg keeps of getting wrongly generated on travis-ci:
645675
// [error] /home/travis/build/carueda/tscfg/src/test/scala/tscfg/example/ScalaIssue54bCfg.scala:8: not found: type Shared
646676
// [error] e : Shared,

0 commit comments

Comments
 (0)