From b400e55f69355fa3ca37ca19e687aa7bf398519d Mon Sep 17 00:00:00 2001 From: Vladimir V Maksimov Date: Sat, 13 Dec 2025 14:46:46 +0300 Subject: [PATCH] alpha --- README.md | 87 ++++++++++++++++++++++++++++++++++++++++++- go.mod | 5 +++ go.sum | 4 ++ iconfig.go | 5 +++ load.go | 22 +++++++++++ load_test.go | 31 +++++++++++++++ test-data/config.yaml | 7 ++++ 7 files changed, 160 insertions(+), 1 deletion(-) create mode 100644 go.mod create mode 100644 go.sum create mode 100644 iconfig.go create mode 100644 load.go create mode 100644 load_test.go create mode 100644 test-data/config.yaml diff --git a/README.md b/README.md index 6aa36ae..7a97d19 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,88 @@ # config -Описание интерфейса конфигурации, а так же инструменты для загрузки и разбора из формата YAML \ No newline at end of file +[https://pkg.go.dev/git.gm6.ru/icewind/config](https://pkg.go.dev/git.gm6.ru/icewind/config) + +Минималистичный Go-пакет для загрузки и валидации конфигурации из YAML-файлов. + +Пакет решает простую, но часто встречающуюся задачу: +- загрузить конфигурацию из файла или из `[]byte` +- распарсить YAML в пользовательскую структуру +- автоматически выполнить валидацию конфига после загрузки + +--- + +## Возможности + +- 📄 Загрузка конфигурации из файла (`LoadFromFile`) +- 💾 Загрузка конфигурации из памяти (`LoadFromData`) +- 🔍 Валидация через пользовательский метод `Check()` +- 🧩 Использование стандартного `gopkg.in/yaml.v3` +- ⚡ Минимальный и прозрачный API без лишних зависимостей + +--- + +## Установка + +```bash +go get git.gm6.ru/icewind/config +``` + +Объект данных конфига должен соотвутствовать интерфейсу + +```go +type IConfig interface { + Check() error +} +``` + +Этот метод будет автоматически вызван после успешного парсинга YAML. +Если Check() возвращает ошибку — загрузка конфигурации считается неуспешной. + +##Пример конфигурационного файла в формате YAML + +```yaml +addrs: + - 127.0.0.1:8080 + - 192.168.1.1:8080 + - 172.16.0.1:8080 +name: "Config version 1" +enabled: true +version: 1 +``` + +##Пример использования + +```go +package main + +import ( + "errors" + + "git.gm6.ru/icewind/config" +) + +type AppConfig struct { + Addrs []string `yaml:"addrs"` + Name string `yaml:"name"` + Enabled bool `yaml:"enabled"` + Version int `yaml:"version"` +} + +func (c *AppConfig) Check() error { + if c.Version <= 0 { + return errors.New("version must be > 0") + } + if len(c.Addrs) == 0 { + return errors.New("addrs list must not be empty") + } + return nil +} + +func main() { + var cfg AppConfig + + if err := config.LoadFromFile("config.yaml", &cfg); err != nil { + panic(err) + } +} +``` \ No newline at end of file diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..5529c9c --- /dev/null +++ b/go.mod @@ -0,0 +1,5 @@ +module git.gm6.ru/icewind/config + +go 1.25.4 + +require gopkg.in/yaml.v3 v3.0.1 diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..a62c313 --- /dev/null +++ b/go.sum @@ -0,0 +1,4 @@ +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/iconfig.go b/iconfig.go new file mode 100644 index 0000000..81f61de --- /dev/null +++ b/iconfig.go @@ -0,0 +1,5 @@ +package config + +type IConfig interface { + Check() error +} diff --git a/load.go b/load.go new file mode 100644 index 0000000..521a15a --- /dev/null +++ b/load.go @@ -0,0 +1,22 @@ +package config + +import ( + "os" + + "gopkg.in/yaml.v3" +) + +func LoadFromFile(path string, obj IConfig) (err error) { + var data []byte + if data, err = os.ReadFile(path); err == nil { + err = LoadFromData(data, obj) + } + return +} + +func LoadFromData(data []byte, obj IConfig) (err error) { + if err = yaml.Unmarshal(data, obj); err == nil { + err = obj.Check() + } + return +} diff --git a/load_test.go b/load_test.go new file mode 100644 index 0000000..7c24284 --- /dev/null +++ b/load_test.go @@ -0,0 +1,31 @@ +package config_test + +import ( + "errors" + "testing" + + "git.gm6.ru/icewind/config" +) + +type TestObject struct { + Addrs []string `yaml:"addrs"` + Name string `yaml:"name"` + Enabled bool `yaml:"enabled"` + Version string `yaml:"version"` +} + +func (s *TestObject) Check() error { + if len(s.Addrs) == 0 { + return errors.New("addrs expected") + } + return nil +} + +func TestLoadFromFile(t *testing.T) { + path := "./test-data/config.yaml" + var obj TestObject + if err := config.LoadFromFile(path, &obj); err != nil { + t.Fatal(err) + } + t.Log(obj) +} diff --git a/test-data/config.yaml b/test-data/config.yaml new file mode 100644 index 0000000..0fec2b3 --- /dev/null +++ b/test-data/config.yaml @@ -0,0 +1,7 @@ +addrs: + - 127.0.0.1:8080 + 192.168.1.1:8080 + 172.16.0.1:8080 +name: "Config version 1" +enabled: true +version: 1 \ No newline at end of file