From 2b0bd61baca0d83b31dbea7a8e1a670d30a94a22 Mon Sep 17 00:00:00 2001 From: Luke Shumaker Date: Thu, 16 Nov 2017 17:06:26 -0500 Subject: frontend: implement tag --- frontend.go | 33 ++++++++++++++++++++++++++++++++- textproto/types.go | 42 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 74 insertions(+), 1 deletion(-) diff --git a/frontend.go b/frontend.go index 3319eee..c08e1b8 100644 --- a/frontend.go +++ b/frontend.go @@ -215,7 +215,38 @@ func (f *Frontend) parse() error { // 'from' SP LF // 'tagger' (SP )? SP LT GT SP LF // data - // TODO + c := CmdTag{RefName: trimLinePrefix(line, "tag ")} + + line, err = f.nextLine() + if err != nil { + return err + } + if !strings.HasPrefix(line, "from ") { + return fmt.Errorf("tag: expected from command: %v", line) + } + c.CommitIsh = trimLinePrefix(line, "from ") + + line, err = f.nextLine() + if err != nil { + return err + } + if !strings.HasPrefix(line, "tagger ") { + return fmt.Errorf("tag: expected tagger command: %v", line) + } + c.Tagger, err = textproto.ParseUserTime(trimLinePrefix(line, "tagger ")) + if err != nil { + return err + } + + line, err = f.nextLine() + if err != nil { + return err + } + c.Data, err = parse_data(line) + if err != nil { + return err + } + f.cmd <- c default: return UnsupportedCommand(line) } diff --git a/textproto/types.go b/textproto/types.go index 2109517..9a1731b 100644 --- a/textproto/types.go +++ b/textproto/types.go @@ -2,10 +2,13 @@ package textproto import ( "fmt" + "strconv" "strings" "time" ) +// BUG(lukeshu): Only supports the "raw" date format (not "rfc2822" or +// "now") type UserTime struct { Name string Email string @@ -28,6 +31,45 @@ func (ut UserTime) String() string { } } +func ParseUserTime(str string) (UserTime, error) { + ret := UserTime{} + lt := strings.IndexAny(str, "<>") + if lt < 0 || str[lt] != '<' { + return ret, fmt.Errorf("Missing < in ident string: %v", str) + } + if lt > 0 { + if str[lt-1] != ' ' { + return ret, fmt.Errorf("Missing space before < in ident string: %v", str) + } + ret.Name = str[:lt-1] + } + gt := lt + 1 + strings.IndexAny(str[lt+1:], "<>") + if gt < lt+1 || str[gt] != '>' { + return ret, fmt.Errorf("Missing > in ident string: %v", str) + } + if str[gt+1] != ' ' { + return ret, fmt.Errorf("Missing space after > in ident string: %v", str) + } + ret.Email = str[lt+1 : gt] + + strWhen := str[gt+2:] + sp := strings.IndexByte(strWhen, ' ') + if sp < 0 { + return ret, fmt.Errorf("missing time zone in when: %v", str) + } + sec, err := strconv.ParseInt(strWhen[:sp], 10, 64) + if err != nil { + return ret, err + } + tzt, err := time.Parse("-0700", strWhen[sp+1:]) + if err != nil { + return ret, err + } + ret.Time = time.Unix(sec, 0).In(tzt.Location()) + + return ret, nil +} + type Mode uint32 // 18 bits var ( -- cgit v1.2.3