package patch import ( "errors" "fmt" "net/textproto" "strings" "git.sr.ht/~rjarry/aerc/app" "git.sr.ht/~rjarry/aerc/commands" "git.sr.ht/~rjarry/aerc/commands/account" "git.sr.ht/~rjarry/aerc/lib/pama" "git.sr.ht/~rjarry/aerc/lib/pama/models" "git.sr.ht/~rjarry/go-opt/v2" ) type Find struct { Filter bool `opt:"-f" desc:"Filter message list instead of search."` Commit []string `opt:"..." required:"true" complete:"Complete" desc:"Search for ."` } func init() { register(Find{}) } func (Find) Description() string { return "Search for applied patches." } func (Find) Context() commands.CommandContext { return commands.GLOBAL } func (Find) Aliases() []string { return []string{"find"} } func (*Find) Complete(arg string) []string { m := pama.New() p, err := m.CurrentProject() if err != nil { return nil } options := make([]string, len(p.Commits)) for i, c := range p.Commits { options[i] = fmt.Sprintf("%-6.6s %s", c.ID, c.Subject) } return commands.FilterList(options, arg, nil) } func (s Find) Execute(_ []string) error { m := pama.New() p, err := m.CurrentProject() if err != nil { return err } if len(s.Commit) == 0 { return errors.New("missing commit hash") } lexed := opt.LexArgs(strings.TrimSpace(s.Commit[0])) hash, err := lexed.ArgSafe(0) if err != nil { return err } if len(hash) < 4 { return errors.New("Commit hash is too short.") } var c models.Commit for _, commit := range p.Commits { if strings.Contains(commit.ID, hash) { c = commit break } } if c.ID == "" { var err error c, err = m.Find(hash, p) if err != nil { return err } } // If Message-Id is provided, find it in store if c.MessageId != "" { if selectMessageId(c.MessageId) { return nil } } // Fallback to a search based on the subject line args := []string{"search"} if s.Filter { args[0] = "filter" } headers := make(textproto.MIMEHeader) args = append(args, fmt.Sprintf("-H Subject:%s", c.Subject)) headers.Add("Subject", c.Subject) cmd := account.SearchFilter{ Headers: headers, } return cmd.Execute(args) } func selectMessageId(msgid string) bool { acct := app.SelectedAccount() if acct == nil { return false } store := acct.Store() if store == nil { return false } for uid, msg := range store.Messages { if msg == nil { continue } if msg.RFC822Headers == nil { continue } id, err := msg.RFC822Headers.MessageID() if err != nil { continue } if id == msgid { store.Select(uid) return true } } return false }