Skip to content

Commit

Permalink
Fix yml anchors/references when converting yml-to-json
Browse files Browse the repository at this point in the history
Apparently they've started using Anchors and Aliases in yml files
upstream (see e.g. uk.yml -> male_first_name -> first_name).

Seems like jackson can't handle Anchors properly
(see FasterXML/jackson-dataformats-text#98)

As a workaround, we use snakeyaml to read .yml files to Map objects,
and then we use jackson to write them to .json files, since snakeyaml
seems to support anchors just fine without needing to jump through hoops.
  • Loading branch information
serpro69 committed Feb 16, 2024
1 parent 244a90b commit 530f140
Show file tree
Hide file tree
Showing 2 changed files with 11 additions and 6 deletions.
3 changes: 2 additions & 1 deletion buildSrc/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,6 @@ dependencies {
implementation("com.adarshr:gradle-test-logger-plugin:4.0.0")
// used by yaml-to-json buildSrc plugin
implementation("com.fasterxml.jackson.core:jackson-databind:2.15.3")
implementation("com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.15.3")
// use snakeyaml instead of jackson-dataformat-yaml to properly handle yaml anchors and write them as actual values to json
implementation("org.yaml:snakeyaml:2.2")
}
14 changes: 9 additions & 5 deletions buildSrc/src/main/kotlin/yaml-to-json.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory
import org.gradle.kotlin.dsl.create
import org.yaml.snakeyaml.Yaml

interface Yaml2JsonPluginExtension {
val input: Property<File>
Expand All @@ -9,7 +8,13 @@ interface Yaml2JsonPluginExtension {

class Yaml2JsonPlugin : Plugin<Project> {
val jsonMapper = ObjectMapper()
val yamlMapper = ObjectMapper(YAMLFactory())
// https://github.com/FasterXML/jackson-dataformats-text/issues/98
/* We use snakeyaml since it can handle Anchors and References (Aliases) in yml files, which jackson can't apparently.
* We still can use jackson to write to json, because at that time,
* the Map we created from yaml will contain proper values and not simply anchor names,
* like it happens when using jackson to read yaml.
*/
val yamlMapper = Yaml()

override fun apply(p: Project) {
val ext = p.extensions.create<Yaml2JsonPluginExtension>("yaml2jsonExt")
Expand Down Expand Up @@ -50,8 +55,7 @@ class Yaml2JsonPlugin : Plugin<Project> {
}

private fun writeYamlToJson(src: File, dest: File) {
val map = yamlMapper.readValue(src.inputStream(), Map::class.java)
val map = yamlMapper.loadAs(src.inputStream(), Map::class.java)
jsonMapper.writeValue(dest, map)
}
}

0 comments on commit 530f140

Please sign in to comment.