package main import ( "dehub" "errors" "flag" "fmt" "os" "strings" "gopkg.in/src-d/go-git.v4/plumbing" ) type subCmdCtx struct { repo *dehub.Repo args []string } var subCmds = []struct { name, descr string body func(sctx subCmdCtx) error }{ { name: "commit", descr: "commits staged changes to the head of the current branch", body: func(sctx subCmdCtx) error { flag := flag.NewFlagSet("commit", flag.ExitOnError) msg := flag.String("msg", "", "Commit message to use") accountID := flag.String("account-id", "", "Account to sign commit as") flag.Parse(sctx.args) if *msg == "" || *accountID == "" { return errors.New("-msg and -account-id are both required") } cfg, err := sctx.repo.LoadConfig() if err != nil { return err } var account dehub.Account var ok bool for _, account = range cfg.Accounts { if account.ID == *accountID { ok = true break } } if !ok { return fmt.Errorf("account ID %q not found in config", *accountID) } else if l := len(account.Signifiers); l == 0 || l > 1 { return fmt.Errorf("account %q has %d signifiers, only one is supported right now", *accountID, l) } sig := account.Signifiers[0] sigInt, err := sig.Interface() if err != nil { return fmt.Errorf("could not cast %+v to SignifierInterface: %w", sig, err) } _, hash, err := sctx.repo.CommitMaster(*msg, *accountID, sigInt) if err != nil { return err } fmt.Printf("changes committed to HEAD as %s\n", hash) return nil }, }, { name: "verify", descr: "verifies one or more commits as having the proper credentials", body: func(sctx subCmdCtx) error { flag := flag.NewFlagSet("verify", flag.ExitOnError) rev := flag.String("rev", "HEAD", "Revision of commit to verify") flag.Parse(sctx.args) h, err := sctx.repo.GitRepo.ResolveRevision(plumbing.Revision(*rev)) if err != nil { return fmt.Errorf("could not resolve revision %q: %w", *rev, err) } if err := sctx.repo.VerifyMasterCommit(*h); err != nil { return fmt.Errorf("could not verify commit at %q (%s): %w", *rev, *h, err) } fmt.Printf("commit at %q (%s) is good to go!\n", *rev, *h) return nil }, }, } func printHelp() { fmt.Printf("USAGE: %s [-h]\n\n", os.Args[0]) fmt.Println("COMMANDS") for _, subCmd := range subCmds { fmt.Printf("\t%s : %s\n", subCmd.name, subCmd.descr) } } func exitErr(err error) { fmt.Fprintf(os.Stderr, "exiting: %v\n", err) os.Stderr.Sync() os.Stdout.Sync() os.Exit(1) } func main() { if len(os.Args) < 2 { printHelp() return } subCmdName := strings.ToLower(os.Args[1]) for _, subCmd := range subCmds { if subCmd.name != subCmdName { continue } r, err := dehub.OpenRepo(".") if err != nil { exitErr(err) } err = subCmd.body(subCmdCtx{ repo: r, args: os.Args[2:], }) if err != nil { exitErr(err) } return } fmt.Printf("unknown command %q\n\n", subCmdName) printHelp() }