package main import ( "fmt" "io/ioutil" "sort" "github.com/pkg/errors" "gopkg.in/yaml.v2" ) const ( authorAccessRead = 0 authorAccessCheck = 1 authorAccessWrite = 2 ) const defaultConfigPath = "~/.config/stick/stick.yml" type config struct { Salt string Serve string Authors []*authorConfig Notebooks []*notebookConfig Debug bool } type authorConfig struct { Email string Name string } type notebookConfig struct { Label string Repo string Serve map[string]int } func readConfigFile(path string) (*config, error) { var err error if path == "" { path = defaultConfigPath } path, err = expandPath(path) if err != nil { return nil, err } data, err := ioutil.ReadFile(path) if err != nil { return nil, err } c := &config{} err = c.load(data) return c, err } func readConfigData(data []byte) (*config, error) { c := &config{} err := c.load(data) return c, err } func (c *config) load(data []byte) error { var config map[string]interface{} err := yaml.Unmarshal(data, &config) if err != nil { return err } if salt, ok := config["salt"]; ok { c.Salt = salt.(string) } if serve, ok := config["serve"]; ok { c.Serve = serve.(string) } if as, ok := config["authors"]; ok { auths := as.(map[interface{}]interface{}) for aemail, aname := range auths { c.Authors = append(c.Authors, &authorConfig{Email: aemail.(string), Name: aname.(string)}) } } if nbsv, ok := config["notebooks"]; ok { nbs := nbsv.(map[interface{}]interface{}) var labels []string for label := range nbs { labels = append(labels, label.(string)) } sort.Strings(labels) for _, label := range labels { nbconfig := ¬ebookConfig{Label: label, Serve: make(map[string]int)} nbo := nbs[label].(map[interface{}]interface{}) for option, v := range nbo { switch option.(string) { case "repo": nbconfig.Repo = v.(string) case "serve": nbsv := v.([]interface{}) for _, nbsvi := range nbsv { switch nbsvi.(type) { case string: nbconfig.Serve[nbsvi.(string)] = authorAccessRead case map[interface{}]interface{}: nbsvx := nbsvi.(map[interface{}]interface{}) for nbsvxi, nbsvxa := range nbsvx { access := -1 switch nbsvxa.(string) { case "read": access = authorAccessRead case "check": access = authorAccessCheck case "write": access = authorAccessWrite } if access == -1 { return errors.New(fmt.Sprintf("invalid serve configuration: invalid access level specified for %s (%s should be read/check/write)", nbsvxi, nbsvxa.(string))) } nbconfig.Serve[nbsvxi.(string)] = access } default: return errors.New(fmt.Sprintf("invalid serve configuration: %T", nbsvi)) } } } } if nbconfig.Repo == "" { return errors.New("invalid notebook configuration: no repo path supplied") } c.Notebooks = append(c.Notebooks, nbconfig) } } return nil }