From d6f424c71ca19a92402186fde7c2c015b43d7b67 Mon Sep 17 00:00:00 2001 From: slashformotion Date: Thu, 2 Oct 2025 18:31:51 +0200 Subject: [PATCH] feat: add dotenv.dist format the goal of this format is to provide an informative .env.dist files to fill out by the different teams that are using the software configured using environment variables --- README.md | 2 +- _examples/simple/config.go | 1 + _examples/simple/doc.env | 8 +++---- _examples/simple/doc.env.dist | 20 +++++++++++++++++ render/config.go | 12 ++++++++++ render/templ/dotenv.tmpl | 4 ++-- render/templ/dotenvdist.tmpl | 41 +++++++++++++++++++++++++++++++++++ types/model.go | 1 + 8 files changed, 82 insertions(+), 7 deletions(-) create mode 100644 _examples/simple/doc.env.dist create mode 100644 render/templ/dotenvdist.tmpl diff --git a/README.md b/README.md index cb28a0b..a12cc9f 100644 --- a/README.md +++ b/README.md @@ -72,7 +72,7 @@ type Config struct { * `-types` (glob string, *optional*) - Type glob pattern for type names to process. If not specified, the next type after `go:generate` is used. * `-target` (`enum(caarlos0, cleanenv)` string, optional, default `caarlos0`) - Set env library target. * `-output` (path string, **required**) - Output file name for generated documentation. - * `-format` (`enum(markdown, plaintext, html, dotenv, json)` string, *optional*) - Output format for documentation. Default is `markdown`. + * `-format` (`enum(markdown, plaintext, html, dotenv, dotenv.dist, json)` string, *optional*) - Output format for documentation. Default is `markdown`. * `-no-styles` (`bool`, *optional*) - If true, CSS styles will not be included for `html` format. * `-env-prefix` (`string`, *optional*) - Sets additional global prefix for all environment variables. * `-tag-name` (string, *optional*, default: `env`) - Use custom tag name instead of `env`. diff --git a/_examples/simple/config.go b/_examples/simple/config.go index c46104f..57b7dff 100644 --- a/_examples/simple/config.go +++ b/_examples/simple/config.go @@ -8,6 +8,7 @@ package main //go:generate go run ../../ -output doc.md -format markdown //go:generate go run ../../ -output doc.html -format html //go:generate go run ../../ -output doc.env -format dotenv +//go:generate go run ../../ -output doc.env.dist -format dotenv.dist //go:generate go run ../../ -output doc.json -format json type Config struct { // Hosts name of hosts to listen on. diff --git a/_examples/simple/doc.env b/_examples/simple/doc.env index 4d32876..65b9a73 100644 --- a/_examples/simple/doc.env +++ b/_examples/simple/doc.env @@ -8,13 +8,13 @@ # ## Hosts name of hosts to listen on. ## (separated by ';', required) -# HOST="" +HOST="" ## Port to listen on. ## (required, non-empty) -# PORT="" +PORT="" ## Debug mode enabled. ## (default: 'false') -# DEBUG="false" +DEBUG="false" ## Prefix for something. -# PREFIX="" +PREFIX="" diff --git a/_examples/simple/doc.env.dist b/_examples/simple/doc.env.dist new file mode 100644 index 0000000..9731c01 --- /dev/null +++ b/_examples/simple/doc.env.dist @@ -0,0 +1,20 @@ +# Environment Variables + + +## Config +## Config is an example configuration structure. +## It is used to generate documentation for the configuration +## using the commands below. +# +# Hosts name of hosts to listen on. +# (separated by ';', required) +HOST= +# Port to listen on. +# (required, non-empty) +PORT= +# Debug mode enabled. +# (default: 'false') +DEBUG="false" +# Prefix for something. +PREFIX= + diff --git a/render/config.go b/render/config.go index 47db92e..491a6cf 100644 --- a/render/config.go +++ b/render/config.go @@ -65,6 +65,18 @@ var configs = map[types.OutFormat]renderConfig{ }, tmpl: newTmplText("dotenv.tmpl"), }, + types.OutFormatEnvDist: { + Item: renderItemConfig{ + SeparatorFormat: "separated by '%s'", + SeparatorDefault: "comma-separated", + OptRequired: "required", + OptExpand: "expand", + OptFromFile: "from-file", + OptNonEmpty: "non-empty", + EnvDefaultFormat: "default: '%s'", + }, + tmpl: newTmplText("dotenvdist.tmpl"), + }, types.OutFormatJSON: { Item: renderItemConfig{}, tmpl: newTmplText("json.tmpl"), diff --git a/render/templ/dotenv.tmpl b/render/templ/dotenv.tmpl index 86ac7cb..18f3aa6 100644 --- a/render/templ/dotenv.tmpl +++ b/render/templ/dotenv.tmpl @@ -11,9 +11,9 @@ {{- end }} {{- template "item.options" (list $ $cfg "## (%s)\n") }} {{- if $.EnvDefault }} - {{- printf `# %s="%s"` $.EnvName $.EnvDefault }} + {{- printf `%s="%s"` $.EnvName $.EnvDefault }} {{- else }} - {{- printf `# %s=""` $.EnvName }} + {{- printf `%s=""` $.EnvName }} {{- end }} {{- end }} {{- $children := $.Children 0 }} diff --git a/render/templ/dotenvdist.tmpl b/render/templ/dotenvdist.tmpl new file mode 100644 index 0000000..01bcf3e --- /dev/null +++ b/render/templ/dotenvdist.tmpl @@ -0,0 +1,41 @@ +{{- define "item" }} + {{- $ := index . 0 }} + {{- $cfg := index . 1 }} + {{- if eq $.EnvName "" }} +# + {{- end }} + {{- template "doc.lines" (list $.Doc "#") }} + {{- if $.EnvName }} + {{- if $.Doc }} + {{- printf "\n" }} + {{- end }} + {{- template "item.options" (list $ $cfg "# (%s)\n") }} + {{- if $.EnvDefault }} + {{- printf `%s="%s"` $.EnvName $.EnvDefault }} + {{- else }} + {{- printf `%s=""` $.EnvName }} + {{- end }} + {{- end }} + {{- $children := $.Children 0 }} + {{- if $children }} +# + {{- range $child := $children }} + {{- template "item" (list $child $cfg) }} + {{- end }} + {{- end }} +{{- end -}} + +{{- $cfg := $.Config -}} +# {{ .Title }} +{{ range .Sections }} +{{- print "\n" }} + {{- if .Name }} +## {{ .Name }} + {{- end }} + {{- template "doc.lines" (list .Doc "##") }} +# + {{- range $item := .Items }} + {{- template "item" (list $item $cfg.Item) }} + {{- end }} +{{- end }} + diff --git a/types/model.go b/types/model.go index 2789ded..89286bf 100644 --- a/types/model.go +++ b/types/model.go @@ -10,6 +10,7 @@ const ( OutFormatHTML OutFormat = "html" OutFormatTxt OutFormat = "plaintext" OutFormatEnv OutFormat = "dotenv" + OutFormatEnvDist OutFormat = "dotenv.dist" OutFormatJSON OutFormat = "json" )