web-dev-qa-db-ja.com

Goで設定を処理する方法

私はGoプログラミングの初心者です、そして、私は不思議に思います:Goプログラムのための設定パラメータを扱うための好ましい方法は何ですか(人が使うかもしれない種類のものpropertiesファイルまたはiniファイル、他のコンテキストでは)

267
theglauber

JSON 形式は、私にとって非常にうまくいきました。標準ライブラリはインデントされたデータ構造を書くためのメソッドを提供するので、それはかなり読みやすいです。

this golang-nuts thread も参照してください。

JSONの利点は、リストやマッピングのセマンティクス(かなり便利になることがあります)を提供しながら解析するのが非常に簡単で、人間が読解/編集できることです。これは、多くのini型構成パーサーには当てはまりません。

使用例

conf.json

{
    "Users": ["UserA","UserB"],
    "Groups": ["GroupA"]
}

設定を読み込むプログラム

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]
231
nemo

別の選択肢は TOML を使うことです。これはTom Preston-Wernerによって作成されたINI風のフォーマットです。私は そのためのGoパーサ を構築しました。それは 広範囲にテストされています 。ここで提案されている他のオプションと同じように使用できます。たとえば、something.tomlにこのTOMLデータがあるとします。

Age = 198
Cats = [ "Cauchy", "Plato" ]
Pi = 3.14
Perfection = [ 6, 28, 496, 8128 ]
DOB = 1987-07-05T05:45:00Z

それから、Goプログラムに次のようにロードすることができます。

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
}
87
BurntSushi5

Viper は、JSON、YAML、およびTOMLと連携するゴラン構成管理システムです。とてもおもしろいですね。

46
Micah

私はたいていJSONをもっと複雑なデータ構造のために使います。欠点は、エラーがどこにあったのか、Edgeのさまざまなケースに問題があるのか​​、そうでないのかをユーザーに知らせるための一連のコードが簡単に出ることです。

基本的な設定(APIキー、ポート番号など)については、 gcfg パッケージを使用して非常にうまくいっています。これはgit configフォーマットに基づいています。

ドキュメントから:

設定例:

; Comment line
[section]
name = value # Another comment
flag # implicit value for bool is true

構造化します。

type Config struct {
    Section struct {
            Name string
            Flag bool
    }
}

そしてコードはそれを読むために必要でした:

var cfg Config
err := gcfg.ReadFileInto(&cfg, "myconfig.gcfg")

スライス値もサポートしているので、キーを複数回指定したり、その他のNice機能をそのように指定することができます。

44

標準の goフラグiniflags を使用するだけです。

標準のgoフラグには以下の利点があります。

  • 慣用句.
  • 使いやすい。プロジェクトで使用している任意のパッケージにフラグを簡単に追加して散在させることができます。
  • フラグは、デフォルト値と説明をそのままサポートしています。
  • フラグは、デフォルト値と説明を含む標準の「ヘルプ」出力を提供します。

標準のGoフラグが持つ唯一の欠点は、アプリで使用されているフラグの数が多くなり過ぎた場合の管理上の問題です。

Iniflagsはこの問題をエレガントに解決します。メインパッケージの2行を変更するだけで、iniファイルからフラグ値を読み取ることが魔法のようにサポートされます。 iniファイルからのフラグは、コマンドラインで新しい値を渡すことによって上書きすることができます。

詳細については https://groups.google.com/forum/#!topic/golang-nuts/TByzyPgoAQE もご覧ください。

38
valyala

私はIniライクなファイルを使う Gcfg を使い始めました。それは簡単です - あなたが何か簡単なものが欲しいなら、これは良い選択です。

これが私が現在使用している読み込みコードです。これはデフォルト設定を持ち、私の設定のいくつかを上書きするコマンドラインフラグ(図示せず)を許可します:

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
}
12
Rick-777

設定を見てください

// 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)
8

この記事のように toml を使う 設定ファイルを読むGo

6
herodot

https://github.com/spf13/viper および https://github.com/zpatrick/go -config は設定ファイル用のとても良いライブラリです。

6
surfeurX

私はgolangで簡単なini設定ライブラリを書きました。

https://github.com/c4pt0r/cfg

ゴロチン安全、使いやすい

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)
    }
}

==================更新==========================

最近私はセクションをサポートするINIパーサが必要です、そして私は簡単なパッケージを書きます:

github.com/c4pt0r/cfg

uは "flag"パッケージを使ってINIを解析することができます。

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)
}
5
c4pt0r

また、 go-libucl 、UCL(ユニバーサル構成言語)用のGoバインディングのセットにも興味があるかもしれません。 UCLはJSONに少し似ていますが、人間に対するサポートが優れています。SI乗数(10k、40Mなど)のようなコメントと人間が読める構文をサポートし、ボイラープレートが少し少なくなっています(キーの周りの引用符など)。あなたが既にそれに精通しているなら、それは実際にはかなりnginx設定ファイルフォーマットに近いです。

4
trombonehero

私は nemo に同意し、それを本当に簡単にするための小さなツールを書きました。

bitbucket.org/gotamer/cfg はjsonの設定パッケージです。

  • アプリケーション内の構成アイテムを構造体として定義します。
  • あなたのstructからのjson設定ファイルテンプレートは最初の実行で保存されます
  • 実行時の変更を設定に保存することができます

例としてdoc.goを参照してください。

2
RoboTamer

私はJSONを試しました。出来た。しかし、私は設定しているかもしれない正確なフィールドと型の構造体を作成しなければならないのが嫌いです。私にとってそれは痛みでした。私はそれが私が見つけることができるすべての設定オプションによって使用される方法であることに気づきました。動的言語の経験があると、そのような冗長性の恩恵に私は盲目になるかもしれません。私は新しいシンプルな設定ファイルフォーマットを作り、それを読むためのもっとダイナミックなlibを作りました。

https://github.com/chrisftw/ezconf

私はGoの世界ではかなり新しいので、Goのやり方ではないかもしれません。しかし、それは動作します、それはかなり速く、そして使用するのはとても簡単です。

長所

  • 超シンプル
  • 少ないコード

短所

  • 配列やマップの種類なし
  • 非常にフラットなファイル形式
  • 非標準のconfファイル
  • 私は今Goコミュニティで一般的に眉をひそめているなら、私は今、私は今、それに慣れている小さなコンベンションを持っていますか。 (configディレクトリでconfigファイルを探す)
1
chrisftw