Skip to content

Commit

Permalink
fix: depends_on must support conditions (#5)
Browse files Browse the repository at this point in the history
The depends_on may be a list or a map depending on the
docker-compose spec. It now supports both.

Closes: #4
  • Loading branch information
derlin authored Feb 7, 2023
1 parent 62e5050 commit 823c565
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 7 deletions.
17 changes: 11 additions & 6 deletions src/main/kotlin/ch/derlin/dcvizmermaid/data/Service.kt
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
package ch.derlin.dcvizmermaid.data

import ch.derlin.dcvizmermaid.helpers.OrList
import ch.derlin.dcvizmermaid.helpers.OrMap
import ch.derlin.dcvizmermaid.helpers.YAML
import ch.derlin.dcvizmermaid.helpers.YamlUtils.getByPath
import ch.derlin.dcvizmermaid.helpers.YamlUtils.getListByPath
import ch.derlin.dcvizmermaid.helpers.YamlUtils.getListOrMapByPath

class Service(val name: String, private val content: YAML) {

Expand All @@ -13,8 +15,11 @@ class Service(val name: String, private val content: YAML) {
.map { Link.parse(name, it) }

private fun linksFromDependsOn(): List<Link> =
content.getListByPath("depends_on", listOf<String>())
.map { Link.parse(name, it) }
when (val dependsOn = content.getListOrMapByPath("depends_on")) {
is OrList -> dependsOn.list
is OrMap -> dependsOn.map.keys
else -> listOf()
}.map { Link.parse(name, it) }

fun volumes(): List<VolumeBinding> =
listOf("volumes", "volumes_from")
Expand All @@ -27,9 +32,9 @@ class Service(val name: String, private val content: YAML) {

fun envMatchingPorts(): List<MaybeReference> {
// environments can be expressed either as list, or as map...
val environmentValues = when (val env = content.getByPath("environment")) {
is Map<*, *> -> env.values.mapNotNull { it as? String }
is List<*> -> env.mapNotNull { it as? String }.map { it.substringAfter("=") }
val environmentValues = when (val env = content.getListOrMapByPath("environment")) {
is OrList -> env.list.map { it.substringAfter("=") }
is OrMap -> env.map.values.mapNotNull { it as? String }
else -> listOf()
}
return environmentValues
Expand Down
12 changes: 11 additions & 1 deletion src/main/kotlin/ch/derlin/dcvizmermaid/helpers/YamlUtils.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ import kotlin.reflect.KClass

typealias YAML = Map<String, Any?>

sealed class ListOrMap
data class OrList(val list: List<String>) : ListOrMap()
data class OrMap(val map: YAML = mapOf()) : ListOrMap()

@Suppress("UNCHECKED_CAST")
object YamlUtils {

Expand All @@ -17,6 +21,12 @@ object YamlUtils {
value as List<T>
} ?: default

fun YAML.getListOrMapByPath(path: String): ListOrMap? = when (val value = this.getByPath(path)) {
is List<*> -> OrList(value as List<String>)
is Map<*, *> -> OrMap(value as YAML)
else -> null
}

fun <T : Any> YAML.getByPath(path: String, type: KClass<T>): T? = getByPath(path)?.let {
require(type.isInstance(it)) { "Wrong type for $it" }
it as T
Expand All @@ -32,5 +42,5 @@ object YamlUtils {
}

// useful to avoid the "uncheck cast" warnings in the calling code
fun Any.asYaml(): YAML = this as YAML
fun Any.asYaml(): YAML = (this as? YAML) ?: mapOf()
}
31 changes: 31 additions & 0 deletions src/test/kotlin/ch/derlin/dcvizmermaid/data/ServiceTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package ch.derlin.dcvizmermaid.data
import assertk.assertAll
import assertk.assertThat
import assertk.assertions.isEqualTo
import ch.derlin.dcvizmermaid.helpers.YamlUtils
import org.junit.jupiter.api.Test

class ServiceTest {
Expand All @@ -20,6 +21,36 @@ class ServiceTest {
}
}

@Test
fun `parse depends_on as list or map form`() {

assertAll {
listOf(
"""
depends_on:
- foo
- bar
""",
"""
depends_on:
foo:
bar:
""",
"""
depends_on:
foo:
condition: service_healthy
bar:
condition: service_completed_successfully
"""
).forEach { yaml ->
assertThat(yaml)
.transform { Service("service", YamlUtils.load(yaml)).links().map { it.to } }
.isEqualTo(listOf("foo", "bar"))
}
}
}

@Test
fun `parse maybe reference`() {
val dockerHostIp = "$" + "{" + "DOCKER_HOST_IP" + "}"
Expand Down

0 comments on commit 823c565

Please sign in to comment.