Skip to content

Instantly share code, notes, and snippets.

@dtanner
Last active April 19, 2023 20:03
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dtanner/617a05f650ea69a05f2a724abee8f508 to your computer and use it in GitHub Desktop.
Save dtanner/617a05f650ea69a05f2a724abee8f508 to your computer and use it in GitHub Desktop.
Kotlin script to generate GitHub Actions README documentation from Action inputs
#!/usr/bin/env kotlin
@file:DependsOn("com.fasterxml.jackson.module:jackson-module-kotlin:2.14.2")
@file:DependsOn("com.fasterxml.jackson.datatype:jackson-datatype-jdk8:2.14.2")
@file:DependsOn("com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.14.2")
@file:DependsOn("com.fasterxml.jackson.core:jackson-databind:2.14.2")
import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory
import com.fasterxml.jackson.module.kotlin.KotlinModule
import com.fasterxml.jackson.module.kotlin.readValue
val inputYaml = """
some-foo:
description: The foo that you foo with.
required: true
some-bar:
description: The bar for the foo
some-baz:
description: The baz
default: reasonable-baz
""".trimIndent()
data class InputField(
val description: String? = "",
val required: Boolean = false,
val default: String? = "",
val type: String? = "",
)
val yamlMapper = ObjectMapper(YAMLFactory()).apply { registerModule(KotlinModule()) }
val inputs = yamlMapper.readValue<Map<String, InputField>>(inputYaml)
val maxNameLength = inputs.keys.maxOf { it.length }
val nameHeader = "Name".padEnd(length = maxNameLength, padChar = ' ')
val maxRequiredLength = 8
val requiredHeader = "Required".padEnd(length = maxRequiredLength, padChar = ' ')
val maxDefaultLength = inputs.values.maxOf { it.default?.length ?: 8 }
val defaultHeader = "Default".padEnd(length = maxDefaultLength, padChar = ' ')
val maxDescriptionLength = inputs.values.maxOf { it.description?.length ?: 12 }
val descriptionHeader = "Description".padEnd(length = maxDescriptionLength, padChar = ' ')
val spacer = "-"
fun spacerFor(length: Int): String = spacer.padEnd(length = length, padChar = '-')
val rows = inputs.map {
"""
| ${it.key.padEnd(length = maxNameLength, padChar = ' ')}
| ${(if (it.value.required) "X" else "").padEnd(length = maxRequiredLength, padChar = ' ')}
| ${it.value.default?.padEnd(length = maxDefaultLength, padChar = ' ')}
| ${it.value.description?.padEnd(length = maxDescriptionLength, padChar = ' ')}
|
""".replace("\n", "")
}.joinToString(separator = "\n")
val output = """
| $nameHeader | $requiredHeader | $defaultHeader | $descriptionHeader |
|-${spacerFor(maxNameLength)}-|-${spacerFor(maxRequiredLength)}-|-${spacerFor(maxDefaultLength)}-|-${spacerFor(maxDescriptionLength)}-|
$rows
""".trimIndent()
println(output)
@dtanner
Copy link
Author

dtanner commented Apr 19, 2023

Name Required Default Description
some-foo X The foo that you foo with.
some-bar The bar for the foo
some-baz reasonable-baz The baz

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment