package config import ( "fmt" "os" "strings" "gopkg.in/yaml.v3" ) // TeaLogin is one entry from a tea config.yml `logins:` list. Only the fields // teabot needs are modelled; unknown keys are ignored by the YAML decoder. type TeaLogin struct { Name string `yaml:"name"` URL string `yaml:"url"` Token string `yaml:"token"` Default bool `yaml:"default"` User string `yaml:"user"` } // teaConfigFile mirrors the top level of tea's config.yml. type teaConfigFile struct { Logins []TeaLogin `yaml:"logins"` } // ParseTeaConfig reads a tea config.yml and returns the login teabot should use. // It prefers a login whose URL matches wantURL, then the default login, then the // first login. This is the same file format as ~/.config/tea/config.yml. func ParseTeaConfig(path, wantURL string) (TeaLogin, error) { data, err := os.ReadFile(path) if err != nil { return TeaLogin{}, fmt.Errorf("reading tea config %s: %w", path, err) } var f teaConfigFile if err := yaml.Unmarshal(data, &f); err != nil { return TeaLogin{}, fmt.Errorf("parsing tea config %s: %w", path, err) } if len(f.Logins) == 0 { return TeaLogin{}, fmt.Errorf("tea config %s has no logins", path) } want := strings.TrimRight(wantURL, "/") var byURL, byDefault *TeaLogin for i := range f.Logins { l := &f.Logins[i] if want != "" && strings.TrimRight(l.URL, "/") == want && byURL == nil { byURL = l } if l.Default && byDefault == nil { byDefault = l } } switch { case byURL != nil: return *byURL, nil case byDefault != nil: return *byDefault, nil default: return f.Logins[0], nil } }