Soy nuevo en la programación de Go y me pregunto: ¿cuál es la forma preferida de manejar los parámetros de configuración para un programa Go (el tipo de cosas para las que uno podría usar archivos de propiedades o archivos ini , en otros contextos)?
Soy nuevo en la programación de Go y me pregunto: ¿cuál es la forma preferida de manejar los parámetros de configuración para un programa Go (el tipo de cosas para las que uno podría usar archivos de propiedades o archivos ini , en otros contextos)?
Respuestas:
El formato JSON me funcionó bastante bien. La biblioteca estándar ofrece métodos para escribir la estructura de datos con sangría, por lo que es bastante legible.
Vea también este hilo de nueces de golang .
Los beneficios de JSON son que es bastante simple de analizar y que se puede leer / editar por humanos, al tiempo que ofrece semántica para listas y mapeos (que puede ser bastante útil), que no es el caso con muchos analizadores de configuración de tipo ini.
Ejemplo de uso:
conf.json :
{
"Users": ["UserA","UserB"],
"Groups": ["GroupA"]
}
Programa para leer la configuración
import (
"encoding/json"
"os"
"fmt"
)
type Configuration struct {
Users []string
Groups []string
}
file, _ := os.Open("conf.json")
defer file.Close()
decoder := json.NewDecoder(file)
configuration := Configuration{}
err := decoder.Decode(&configuration)
if err != nil {
fmt.Println("error:", err)
}
fmt.Println(configuration.Users) // output: [UserA, UserB]
defer file.Close()
después de comprobar abrir err
Otra opción es usar TOML , que es un formato similar a INI creado por Tom Preston-Werner. Yo construí un analizador Vaya para él que está ampliamente probado . Puede usarlo como otras opciones propuestas aquí. Por ejemplo, si tiene estos datos TOML ensomething.toml
Age = 198
Cats = [ "Cauchy", "Plato" ]
Pi = 3.14
Perfection = [ 6, 28, 496, 8128 ]
DOB = 1987-07-05T05:45:00Z
Luego puede cargarlo en su programa Go con algo como
type Config struct {
Age int
Cats []string
Pi float64
Perfection []int
DOB time.Time
}
var conf Config
if _, err := toml.DecodeFile("something.toml", &conf); err != nil {
// handle error
}
Viper es un sistema de gestión de configuración de golang que funciona con JSON, YAML y TOML. Se ve muy interesante.
Usualmente uso JSON para estructuras de datos más complicadas. La desventaja es que fácilmente terminas con un montón de código para decirle al usuario dónde estuvo el error, varios casos extremos y qué no.
Para la configuración básica (claves API, números de puerto, ...) he tenido muy buena suerte con el gcfg paquete . Se basa en el formato de configuración de git.
De la documentación:
Configuración de muestra:
; Comment line
[section]
name = value # Another comment
flag # implicit value for bool is true
Go struct:
type Config struct {
Section struct {
Name string
Flag bool
}
}
Y el código necesario para leerlo:
var cfg Config
err := gcfg.ReadFileInto(&cfg, "myconfig.gcfg")
También admite valores de división, por lo que puede permitir especificar una clave varias veces y otras características agradables como esa.
Simplemente use las banderas de go estándar con iniflags .
Las banderas estándar go tienen los siguientes beneficios:
El único inconveniente que tienen las banderas de go estándar son los problemas de administración cuando la cantidad de banderas utilizadas en su aplicación es demasiado grande.
Iniflags resuelve este problema con elegancia: solo modifique dos líneas en su paquete principal y mágicamente obtendrá soporte para leer los valores del indicador desde el archivo ini. Las banderas de los archivos ini se pueden anular pasando nuevos valores en la línea de comandos.
Consulte también https://groups.google.com/forum/#!topic/golang-nuts/TByzyPgoAQE para más detalles.
go test
no me deja pasar banderas) mientras que un archivo de configuración no lo haría.
*FlagName = value
He empezado a usar Gcfg que usa archivos similares a Ini. Es simple: si quieres algo simple, esta es una buena opción.
Aquí está el código de carga que estoy usando actualmente, que tiene configuraciones predeterminadas y permite marcas de línea de comando (no mostradas) que anulan algunas de mis configuraciones:
package util
import (
"code.google.com/p/gcfg"
)
type Config struct {
Port int
Verbose bool
AccessLog string
ErrorLog string
DbDriver string
DbConnection string
DbTblPrefix string
}
type configFile struct {
Server Config
}
const defaultConfig = `
[server]
port = 8000
verbose = false
accessLog = -
errorLog = -
dbDriver = mysql
dbConnection = testuser:TestPasswd9@/test
dbTblPrefix =
`
func LoadConfiguration(cfgFile string, port int, verbose bool) Config {
var err error
var cfg configFile
if cfgFile != "" {
err = gcfg.ReadFileInto(&cfg, cfgFile)
} else {
err = gcfg.ReadStringInto(&cfg, defaultConfig)
}
PanicOnError(err)
if port != 0 {
cfg.Server.Port = port
}
if verbose {
cfg.Server.Verbose = true
}
return cfg.Server
}
echa un vistazo a gonfig
// load
config, _ := gonfig.FromJson(myJsonFile)
// read with defaults
host, _ := config.GetString("service/host", "localhost")
port, _ := config.GetInt("service/port", 80)
test, _ := config.GetBool("service/testing", false)
rate, _ := config.GetFloat("service/rate", 0.0)
// parse section into target structure
config.GetAs("service/template", &template)
https://github.com/spf13/viper y https://github.com/zpatrick/go-config son bibliotecas bastante buenas para archivos de configuración.
Use toml como este artículo Leyendo archivos de configuración de la manera Go
Escribí una biblioteca simple de configuración ini en golang.
seguro para la rutina, fácil de usar
package cfg
import (
"testing"
)
func TestCfg(t *testing.T) {
c := NewCfg("test.ini")
if err := c.Load() ; err != nil {
t.Error(err)
}
c.WriteInt("hello", 42)
c.WriteString("hello1", "World")
v, err := c.ReadInt("hello", 0)
if err != nil || v != 42 {
t.Error(err)
}
v1, err := c.ReadString("hello1", "")
if err != nil || v1 != "World" {
t.Error(err)
}
if err := c.Save(); err != nil {
t.Error(err)
}
}
=================== Actualización =======================
Recientemente necesito un analizador INI con soporte de sección, y escribo un paquete simple:
github.com/c4pt0r/cfg
puede analizar INI como si usara el paquete "flag":
package main
import (
"log"
"github.com/c4pt0r/ini"
)
var conf = ini.NewConf("test.ini")
var (
v1 = conf.String("section1", "field1", "v1")
v2 = conf.Int("section1", "field2", 0)
)
func main() {
conf.Parse()
log.Println(*v1, *v2)
}
También le puede interesar go-libucl , un conjunto de enlaces Go para UCL, el Lenguaje de configuración universal. UCL es un poco como JSON, pero con un mejor soporte para humanos: admite comentarios y construcciones legibles por humanos como multiplicadores SI (10k, 40M, etc.) y tiene un poco menos repetitivo (por ejemplo, comillas alrededor de las teclas). En realidad, está bastante cerca del formato de archivo de configuración nginx, si ya está familiarizado con eso.
Estoy de acuerdo con nemo y escribí una pequeña herramienta para que todo sea realmente fácil.
bitbucket.org/gotamer/cfg es un paquete de configuración json
Ver doc.go para un ejemplo
Intenté JSON. Funcionó. Pero odio tener que crear la estructura de los campos y tipos exactos que podría estar configurando. Para mí eso fue un dolor. Noté que era el método utilizado por todas las opciones de configuración que pude encontrar. Quizás mi experiencia en lenguajes dinámicos me deja ciego a los beneficios de tal verbosidad. Hice un nuevo formato de archivo de configuración simple y una biblioteca más dinámica para leerlo.
https://github.com/chrisftw/ezconf
Soy bastante nuevo en el mundo Go, por lo que podría no ser el camino Go. Pero funciona, es bastante rápido y súper simple de usar.