All ProjectsHome
csb
csb/src/csb-config.go
csb-config.go Raw
package main

import (
	"fmt"
	"io/ioutil"
	"os"
	"path"
	"path/filepath"

	"github.com/BurntSushi/toml"
	"github.com/docopt/docopt-go"
)

func main() {
	binname := filepath.Base(os.Args[0])
	usage := fmt.Sprintf(`Reads and writes repository configurations

Usage:
  %[1]s new [<path>]
  %[1]s get <option> [<path>]
  %[1]s set <option> <value> [<path>]
`, binname)

	arguments, err := docopt.Parse(usage, nil, true, "0.1.0", false)
	if err != nil {
		fmt.Fprintln(os.Stderr, err)
		os.Exit(1)
	}

	var p string
	if arguments["<path>"] != nil {
		p = arguments["<path>"].(string)
	} else {
		p = ""
	}
	confpath := path.Join(p, "config.toml")

	if arguments["new"].(bool) {
		f, err := os.Create(confpath)
		if err != nil {
			fmt.Fprintln(os.Stderr, err)
			os.Exit(7)
		}
		f.Close()
		os.Exit(0)
	}

	f, err := os.Open(confpath)
	if err != nil {
		if os.IsNotExist(err) {
			fmt.Fprintf(os.Stderr,
				"Missing config file, use `new` to initialize the config\n",
				binname)
		}
		fmt.Fprintln(os.Stderr, err)
		os.Exit(2)
	}
	confb, err := ioutil.ReadAll(f)
	_ = f.Close() //This cannot error, as it was only opened for reading
	if err != nil {
		fmt.Fprintln(os.Stderr, err)
		os.Exit(3)
	}

	c := make(map[string]interface{})
	err = toml.Unmarshal(confb, &c)
	if err != nil {
		fmt.Fprintln(os.Stderr, err)
		os.Exit(4)
	}

	if arguments["get"].(bool) {
		v := c[arguments["<option>"].(string)]
		if v == nil {
			fmt.Fprintf(os.Stderr, "Option `%[1]s` not set\n", arguments["<option>"])
			os.Exit(8)
		}
		fmt.Println(v)
		os.Exit(0)
	}
	if arguments["set"].(bool) {
		//TODO: handle things other than strings
		c[arguments["<option>"].(string)] = arguments["<value>"].(string)
		//TODO: create new file and swap atomically
		f, err := os.Create(confpath)
		if err != nil {
			fmt.Fprintln(os.Stderr, err)
			os.Exit(5)
		}
		e := toml.NewEncoder(f)
		err = e.Encode(c)
		if err != nil {
			fmt.Fprintln(os.Stderr, err)
			os.Exit(6)
		}
	}
	os.Exit(0)
}