alpha
This commit is contained in:
87
README.md
87
README.md
@@ -1,3 +1,88 @@
|
|||||||
# config
|
# config
|
||||||
|
|
||||||
Описание интерфейса конфигурации, а так же инструменты для загрузки и разбора из формата YAML
|
[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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
5
go.mod
Normal file
5
go.mod
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
module git.gm6.ru/icewind/config
|
||||||
|
|
||||||
|
go 1.25.4
|
||||||
|
|
||||||
|
require gopkg.in/yaml.v3 v3.0.1
|
||||||
4
go.sum
Normal file
4
go.sum
Normal file
@@ -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=
|
||||||
5
iconfig.go
Normal file
5
iconfig.go
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
package config
|
||||||
|
|
||||||
|
type IConfig interface {
|
||||||
|
Check() error
|
||||||
|
}
|
||||||
22
load.go
Normal file
22
load.go
Normal file
@@ -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
|
||||||
|
}
|
||||||
31
load_test.go
Normal file
31
load_test.go
Normal file
@@ -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)
|
||||||
|
}
|
||||||
7
test-data/config.yaml
Normal file
7
test-data/config.yaml
Normal file
@@ -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
|
||||||
Reference in New Issue
Block a user