Songmu/gitconfig で Go から git config を取得する

備忘録。

git config の Go クライアントと言える Songmu/gitconfig について。

単一の設定値の取得

もっとも単純な例

[core]
  name = autopp

README.md の通りだが、gitconfig.Get で取得できる。

var conf string
var err error

conf, err = gitconfig.Get("core.user")
if err != nil && !gitconfig.IsNotFound(err) {
  // 設定値が見つからなかったとき以外の処理
}

fmt.Println(conf) // => autopp

gitconfig.Get は設定値が見つからなかった場合に特殊な errorを返す。これは gitconfig.IsNotFound で判別可能。

複数の設定値の取得

gitconfig は1つのキーに対して複数の値を紐付けることができる。

[ghq]
  root = ~/.ghq
  root = ~/go/src

これらを全て取得するために GetAll を使う

var conf []string
var err error

conf, err = gitconfig.GetAll("ghq.root")
if err != nil && !gitconfig.IsNotFound(err) {
  // 設定値が見つからなかったとき以外の処理
}

fmt.Println(conf) // => [~/.ghq,~/go/src]

任意の引数で git config を実行

Get, GetAll ではカバーできない特殊なオプションを使いたい場合、gitconfig.Dogit config を直接実行できる。 なお、--null オプションがデフォルトでつくため、--get-all を付けた場合は設定値がヌル文字区切りになる。

var conf string
var err error

conf, err = gitconfig.Do("--get-urlmatch ghq.vcs https://github.com")

// set もできる
_, err = gitconfig.Do("--global core.editor code")

テスト時の一時設定

ここが一番気に入っているところ。

gitconfig.WithConfig を使うことで、テストコード内で有効な一時的な gitconfig を扱うことができる。

func Test(t *testing.T) {
  // テスト用の gitconfig
  conf := `
[core]
  user = autopp2
`
  // gitconfig.WithConfig で一時的に設定を書き換える
  rollback := gitconfig.WithConfig(t, conf)
  // gitconfig.WithConfig が返した関数を呼び出すことで、元の設定に戻る(defer しておくといい)
  defer rollback()

  // Do test (omitted)
}

仕組みとしては一時ディレクトリに受け取った設定を書き込み、環境変数 GIT_CONFIG を書き換えることで、設定をすり替える。 そして返り値の関数を呼び出すと、GIT_CONFIG が元に戻って一時ディレクトリも削除される。