Movatterモバイル変換


[0]ホーム

URL:


Copy/Cut/Paste/Hatena

YAMLファイルの全ての値にos.Expandenv(os.Expand)を適用するgithub.com/k1LoW/expandを作った

私は作るツールの設定ファイルのフォーマットをYAMLにすることが多いです。

そして各値で環境変数を展開できるようにする機能を追加することがあります。

以下のような設定ファイルを読み込んだ際に、${COVERAGE_ACCEPTABLE}${COVERAGE_BADGE_PATH}環境変数から読み込んで変数展開してあげる機能を追加します。

coverage:acceptable: ${COVERAGE_ACCEPTABLE}badge:path: ${COVERAGE_BADGE_PATH}comment:enable: ${COMMENT_ENABLE}

値が文字列であればYAMLファイルをエンコードしてからos.Expandenv を呼べばいいですし、今まではそのように作っていたのですが以下のような課題がありました。

数値や真偽値の変数展開の実装が面倒

${xxxxx} はどう見ても文字列なので、数値や真偽値の変数展開を実現するためにはUnmarshalする際に一工夫が必要になります。

そこまでの実装のモチベーションが持てず、大抵「環境変数展開対象外」にしていました。

os.Expandenv をひたすら書く必要がある

YAMLの文字列を構造体に変更した後に変数展開をする場合、os.Expandenvを各値に対してひたすら適用する必要があります*1。適用漏れもあったり。

そういったYAMLを設定ファイルに採用しているツールが手元に増えてきたので、YAMLファイルの全ての値に対してos.Expandenv(os.Expand)を適用する関数を作ってみました。

github.com

github.com/k1LoW/expand

使い方は簡単で、以下のようにexpand.Expand* を呼べば []byte や string なYAMLの各値にだけos.Expandenv(os.Expand)を適用します。

c := &Config{}p :="config.yml"buf, err := os.ReadFile(p)if err !=nil {return err}if err := yaml.Unmarshal(expand.ExpandenvYAMLBytes(buf), c); err !=nil {return err}

提供している関数はexpand package - github.com/k1LoW/expand - pkg.go.dev をみてください。

実装は、ありがたいことにgithub.com/goccy/go-yaml が Lexer をpublicなAPIとして公開してくれているので、それを利用させてもらっています。Lexer の活用事例としてycat があり、かなり参考にさせてもらいました*2

github.com

今後

せっかくYAMLのための関数を作ったので、他のフォーマットや構造体の関数も作ってみようかなとは思いました。思っただけです。

もし何かあればフィードバックもらえると嬉しいです。

*1:全ての値を走査するために「reflectを使って再帰的に」という手段もあるとは思います

*2:特に func (p *Printer) PrintTokens(tokens token.Tokens) string。ほぼそのままといってもいいです

検索

引用をストックしました

引用するにはまずログインしてください

引用をストックできませんでした。再度お試しください

限定公開記事のため引用できません。

読者です読者をやめる読者になる読者になる

[8]ページ先頭

©2009-2025 Movatter.jp