package main import ( "flag" "fmt" "os" "strings" "go.jolheiser.com/go-spectre" ) func main() { pw, err := doMain(os.Args[1:]) if err != nil { fmt.Println(err) return } fmt.Println(pw) } func doMain(args []string) (string, error) { fs := flag.NewFlagSet("spectre", flag.ExitOnError) fs.Usage = func() { fmt.Fprintln(fs.Output(), "spectre [FLAGS] [site]") fs.PrintDefaults() } usernameFlag := fs.String("username", "", "username") secretFlag := fs.String("secret", "", "secret") counterFlag := fs.Int("counter", 1, "counter") scoperFlag := fs.String("scoper", "com.lyndir.masterpassword", "scoper base") scopeFlag := spectre.Authentication fs.Func("scope", "scope", func(s string) (err error) { scopeFlag, err = spectre.ParseScope(s) return }) var templateFlag spectre.Template fs.Func("template", "template", func(s string) (err error) { templateFlag, err = spectre.ParseTemplate(s) return }) if err := fs.Parse(args); err != nil { return "", err } if err := checkEnv(fs); err != nil { return "", err } if templateFlag == "" { templateFlag = scopeFlag.DefaultTemplate() } if *usernameFlag == "" || *secretFlag == "" || fs.NArg() < 1 { return "", requiredArgs{ missingUsername: *usernameFlag == "", missingSecret: *secretFlag == "", missingSite: fs.NArg() < 1, } } s, err := spectre.New(*usernameFlag, *secretFlag, spectre.WithScoper(spectre.SimpleScoper{ Key: *scoperFlag, })) if err != nil { return "", err } return s.Site(fs.Arg(0), spectre.WithScope(scopeFlag), spectre.WithTemplate(templateFlag), spectre.WithCounter(*counterFlag), ), nil } type requiredArgs struct { missingUsername bool missingSecret bool missingSite bool } func (r requiredArgs) Error() string { s := "--username, --secret, and are required, missing: " if r.missingUsername { s += "\n- username" } if r.missingSecret { s += "\n- secret" } if r.missingSite { s += "\n- site name" } return s } func checkEnv(fs *flag.FlagSet) error { provided := map[string]struct{}{} fs.Visit(func(f *flag.Flag) { provided[f.Name] = struct{}{} }) var visitErr error fs.VisitAll(func(f *flag.Flag) { if visitErr != nil { return } if _, ok := provided[f.Name]; ok { return } env := os.Getenv(fmt.Sprintf("SPECTRE_%s", strings.ToUpper(f.Name))) if env == "" { return } if err := fs.Set(f.Name, env); err != nil { visitErr = fmt.Errorf("could not set flag %q to %q", f.Name, env) } }) return nil }