refactor: switch config format from YAML to TOML

- Replace gopkg.in/yaml.v3 with github.com/BurntSushi/toml
- Update struct tags from yaml to toml
- Update config tests to use TOML syntax
- Add testdata/config.toml, update Helm configmap template
This commit is contained in:
2026-08-10 17:19:09 +08:00
parent 4e467e1136
commit 321d78a017
7 changed files with 129 additions and 67 deletions
+24
View File
@@ -0,0 +1,24 @@
[server]
addr = ":8080"
[git]
type = "gitea"
base_url = "https://git.example.com"
token = "test-token"
[cluster]
kubeconfig = "/dev/null"
namespace = "proto-gen"
job_timeout = 600
max_concurrent = 2
toolchain_registry = "registry.example.com/proto-gen"
target_repo_template = "{proto_repo}-gen-{lang}"
[[plugins]]
language = "go"
image = "proto-gen-go:v1.34.2"
[[plugins]]
language = "nodejs"
image = "proto-gen-ts:v0.9.0"
+21 -17
View File
@@ -3,22 +3,26 @@ kind: ConfigMap
metadata: metadata:
name: {{ .Release.Name }}-config name: {{ .Release.Name }}-config
data: data:
config.yaml: | config.toml: |
server: [server]
addr: ":8080" addr = ":8080"
git:
type: gitea [git]
base_url: "{{ .Values.git.baseUrl }}" type = "gitea"
token: "${GIT_TOKEN}" base_url = "{{ .Values.git.baseUrl }}"
cluster: token = "${GIT_TOKEN}"
kubeconfig: /etc/proto-gen/kubeconfig
namespace: {{ .Values.cluster.namespace }} [cluster]
job_timeout: {{ .Values.cluster.jobTimeout }} kubeconfig = "/etc/proto-gen/kubeconfig"
max_concurrent: {{ .Values.cluster.maxConcurrent }} namespace = "{{ .Values.cluster.namespace }}"
toolchain_registry: "{{ .Values.toolchainRegistry }}" job_timeout = {{ .Values.cluster.jobTimeout }}
target_repo_template: "{{ .Values.targetRepoTemplate }}" max_concurrent = {{ .Values.cluster.maxConcurrent }}
plugins:
toolchain_registry = "{{ .Values.toolchainRegistry }}"
target_repo_template = "{{ .Values.targetRepoTemplate }}"
{{- range .Values.plugins }} {{- range .Values.plugins }}
- language: {{ .language }} [[plugins]]
image: "{{ .image }}" language = "{{ .language }}"
image = "{{ .image }}"
{{- end }} {{- end }}
+2 -1
View File
@@ -3,9 +3,9 @@ module proto-gen
go 1.26.5 go 1.26.5
require ( require (
github.com/BurntSushi/toml v1.6.0
github.com/go-chi/chi/v5 v5.3.1 github.com/go-chi/chi/v5 v5.3.1
github.com/google/uuid v1.6.0 github.com/google/uuid v1.6.0
gopkg.in/yaml.v3 v3.0.1
k8s.io/api v0.36.3 k8s.io/api v0.36.3
k8s.io/apimachinery v0.36.3 k8s.io/apimachinery v0.36.3
k8s.io/client-go v0.36.3 k8s.io/client-go v0.36.3
@@ -44,6 +44,7 @@ require (
google.golang.org/protobuf v1.36.12-0.20260120151049-f2248ac996af // indirect google.golang.org/protobuf v1.36.12-0.20260120151049-f2248ac996af // indirect
gopkg.in/evanphx/json-patch.v4 v4.13.0 // indirect gopkg.in/evanphx/json-patch.v4 v4.13.0 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/inf.v0 v0.9.1 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
k8s.io/klog/v2 v2.140.0 // indirect k8s.io/klog/v2 v2.140.0 // indirect
k8s.io/kube-openapi v0.0.0-20260317180543-43fb72c5454a // indirect k8s.io/kube-openapi v0.0.0-20260317180543-43fb72c5454a // indirect
k8s.io/utils v0.0.0-20260210185600-b8788abfbbc2 // indirect k8s.io/utils v0.0.0-20260210185600-b8788abfbbc2 // indirect
+2
View File
@@ -1,3 +1,5 @@
github.com/BurntSushi/toml v1.6.0 h1:dRaEfpa2VI55EwlIW72hMRHdWouJeRF7TPYhI+AUQjk=
github.com/BurntSushi/toml v1.6.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+19 -19
View File
@@ -6,39 +6,39 @@ import (
"regexp" "regexp"
"strings" "strings"
"gopkg.in/yaml.v3" "github.com/BurntSushi/toml"
) )
type Config struct { type Config struct {
Server ServerConfig `yaml:"server"` Server ServerConfig `toml:"server"`
Git GitConfig `yaml:"git"` Git GitConfig `toml:"git"`
Cluster ClusterConfig `yaml:"cluster"` Cluster ClusterConfig `toml:"cluster"`
ToolchainRegistry string `yaml:"toolchain_registry"` ToolchainRegistry string `toml:"toolchain_registry"`
TargetRepoTemplate string `yaml:"target_repo_template"` TargetRepoTemplate string `toml:"target_repo_template"`
Plugins []PluginConfig `yaml:"plugins"` Plugins []PluginConfig `toml:"plugins"`
} }
type ServerConfig struct { type ServerConfig struct {
Addr string `yaml:"addr"` Addr string `toml:"addr"`
PublicURL string `yaml:"public_url"` PublicURL string `toml:"public_url"`
} }
type GitConfig struct { type GitConfig struct {
Type string `yaml:"type"` Type string `toml:"type"`
BaseURL string `yaml:"base_url"` BaseURL string `toml:"base_url"`
Token string `yaml:"token"` Token string `toml:"token"`
} }
type ClusterConfig struct { type ClusterConfig struct {
Kubeconfig string `yaml:"kubeconfig"` Kubeconfig string `toml:"kubeconfig"`
Namespace string `yaml:"namespace"` Namespace string `toml:"namespace"`
JobTimeout int `yaml:"job_timeout"` JobTimeout int `toml:"job_timeout"`
MaxConcurrent int `yaml:"max_concurrent"` MaxConcurrent int `toml:"max_concurrent"`
} }
type PluginConfig struct { type PluginConfig struct {
Language string `yaml:"language"` Language string `toml:"language"`
Image string `yaml:"image"` Image string `toml:"image"`
} }
var envVarRegex = regexp.MustCompile(`\$\{(\w+)\}`) var envVarRegex = regexp.MustCompile(`\$\{(\w+)\}`)
@@ -52,7 +52,7 @@ func Load(path string) (*Config, error) {
expanded := expandEnvVars(string(data)) expanded := expandEnvVars(string(data))
var cfg Config var cfg Config
if err := yaml.Unmarshal([]byte(expanded), &cfg); err != nil { if _, err := toml.Decode(expanded, &cfg); err != nil {
return nil, fmt.Errorf("parsing config: %w", err) return nil, fmt.Errorf("parsing config: %w", err)
} }
+34 -28
View File
@@ -7,20 +7,22 @@ import (
) )
func TestLoad_MissingFile(t *testing.T) { func TestLoad_MissingFile(t *testing.T) {
_, err := Load("/nonexistent/config.yaml") _, err := Load("/nonexistent/config.toml")
if err == nil { if err == nil {
t.Fatal("expected error for missing file") t.Fatal("expected error for missing file")
} }
} }
func TestLoad_MissingGitToken(t *testing.T) { func TestLoad_MissingGitToken(t *testing.T) {
cfg := `server: cfg := `[server]
addr: ":8080" addr = ":8080"
git:
type: gitea [git]
base_url: "https://git.example.com" type = "gitea"
cluster: base_url = "https://git.example.com"
namespace: proto-gen`
[cluster]
namespace = "proto-gen"`
path := writeTempConfig(t, cfg) path := writeTempConfig(t, cfg)
os.Setenv("GIT_TOKEN", "") os.Setenv("GIT_TOKEN", "")
_, err := Load(path) _, err := Load(path)
@@ -33,19 +35,22 @@ func TestLoad_ValidConfig(t *testing.T) {
os.Setenv("GIT_TOKEN", "test-token") os.Setenv("GIT_TOKEN", "test-token")
defer os.Unsetenv("GIT_TOKEN") defer os.Unsetenv("GIT_TOKEN")
cfg := `server: cfg := `[server]
addr: ":9090" addr = ":9090"
git:
type: gitea [git]
base_url: "https://git.example.com" type = "gitea"
token: ${GIT_TOKEN} base_url = "https://git.example.com"
cluster: token = "${GIT_TOKEN}"
namespace: proto-gen
job_timeout: 300 [cluster]
max_concurrent: 3 namespace = "proto-gen"
plugins: job_timeout = 300
- language: go max_concurrent = 3
image: "proto-gen-go:v1.0"`
[[plugins]]
language = "go"
image = "proto-gen-go:v1.0"`
path := writeTempConfig(t, cfg) path := writeTempConfig(t, cfg)
got, err := Load(path) got, err := Load(path)
@@ -73,12 +78,13 @@ func TestLoad_DefaultValues(t *testing.T) {
os.Setenv("GIT_TOKEN", "test-token") os.Setenv("GIT_TOKEN", "test-token")
defer os.Unsetenv("GIT_TOKEN") defer os.Unsetenv("GIT_TOKEN")
cfg := `git: cfg := `[git]
type: gitea type = "gitea"
base_url: "https://git.example.com" base_url = "https://git.example.com"
token: ${GIT_TOKEN} token = "${GIT_TOKEN}"
cluster:
namespace: proto-gen` [cluster]
namespace = "proto-gen"`
path := writeTempConfig(t, cfg) path := writeTempConfig(t, cfg)
got, err := Load(path) got, err := Load(path)
@@ -119,7 +125,7 @@ func TestGetPluginByLanguage(t *testing.T) {
func writeTempConfig(t *testing.T, content string) string { func writeTempConfig(t *testing.T, content string) string {
t.Helper() t.Helper()
dir := t.TempDir() dir := t.TempDir()
path := filepath.Join(dir, "config.yaml") path := filepath.Join(dir, "config.toml")
if err := os.WriteFile(path, []byte(content), 0644); err != nil { if err := os.WriteFile(path, []byte(content), 0644); err != nil {
t.Fatalf("writing temp config: %v", err) t.Fatalf("writing temp config: %v", err)
} }
+25
View File
@@ -0,0 +1,25 @@
[server]
addr = ":8080"
public_url = "https://gen.example.com"
[git]
type = "gitea"
base_url = "https://git.example.com"
token = "${GIT_TOKEN}"
[cluster]
kubeconfig = "/etc/proto-gen/kubeconfig"
namespace = "proto-gen"
job_timeout = 600
max_concurrent = 2
toolchain_registry = "registry.example.com/proto-gen"
target_repo_template = "{proto_repo}-gen-{lang}"
[[plugins]]
language = "go"
image = "proto-gen-go:v1.34.2"
[[plugins]]
language = "nodejs"
image = "proto-gen-ts:v0.9.0"