mirror of https://git.sr.ht/~rjarry/aerc
You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
141 lines
2.5 KiB
Go
141 lines
2.5 KiB
Go
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 <commit-ish>."`
|
|
}
|
|
|
|
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
|
|
}
|