From fce836437bb1ef391ed41c8e430e74ede8b23fda Mon Sep 17 00:00:00 2001 From: Matías Insaurralde Date: Sat, 28 Mar 2026 01:49:09 +0000 Subject: [PATCH] knotserver/git: extract parseTagRecord helper from Tags Signed-off-by: Matías Insaurralde --- knotserver/git/tag.go | 122 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---------------------------------------------------- 1 file(s) changed, 70 insertion(s)(+), 52 deletion(s)(-) diff --git a/knotserver/git/tag.go b/knotserver/git/tag.go --- a/knotserver/git/tag.go +++ b/knotserver/git/tag.go @@ -16,6 +16,73 @@ Pattern string } +// numTagFields is the number of fields per record produced by the for-each-ref +// format string built in Tags. +const numTagFields = 11 + +// parseTagRecord parses a single for-each-ref output record into an object.Tag. +// +// Returns (object.Tag{}, false, nil) when the record is too short and should be +// skipped. Returns (object.Tag{}, false, err) when the object type is +// unrecognised. Returns (tag, true, nil) on success. +func parseTagRecord(line string) (object.Tag, bool, error) { + parts := strings.SplitN(strings.TrimSpace(line), fieldSeparator, numTagFields) + if len(parts) < 6 { + return object.Tag{}, false, nil + } + + tagName := parts[0] + objectHash := parts[1] + objectType := parts[2] + targetHash := parts[3] // dereferenced object hash (empty for lightweight tags) + // targetType := parts[4] // dereferenced object type (empty for lightweight tags) + taggerName := parts[5] + taggerEmail := parts[6] + taggerDate := parts[7] + subject := parts[8] + body := parts[9] + signature := parts[10] + + // combine subject and body for the message + var message string + if subject != "" && body != "" { + message = subject + "\n\n" + body + } else if subject != "" { + message = subject + } else { + message = body + } + + // parse creation time + var createdAt time.Time + if unix, err := strconv.ParseInt(taggerDate, 10, 64); err == nil { + createdAt = time.Unix(unix, 0) + } + + // parse object type + typ, err := plumbing.ParseObjectType(objectType) + if err != nil { + return object.Tag{}, false, err + } + + // strip email separators + taggerEmail = strings.TrimSuffix(strings.TrimPrefix(taggerEmail, "<"), ">") + + return object.Tag{ + Hash: plumbing.NewHash(objectHash), + Name: tagName, + Tagger: object.Signature{ + Name: taggerName, + Email: taggerEmail, + When: createdAt, + }, + Message: message, + PGPSignature: signature, + TargetType: typ, + Target: plumbing.NewHash(targetHash), + }, true, nil +} + func (g *GitRepo) Tags(opts *TagsOptions) ([]object.Tag, error) { if opts == nil { opts = &TagsOptions{} @@ -84,62 +151,13 @@ tags := make([]object.Tag, 0, len(records)) for _, line := range records { - parts := strings.SplitN(strings.TrimSpace(line), fieldSeparator, len(fields)) - if len(parts) < 6 { - continue - } - - tagName := parts[0] - objectHash := parts[1] - objectType := parts[2] - targetHash := parts[3] // dereferenced object hash (empty for lightweight tags) - // targetType := parts[4] // dereferenced object type (empty for lightweight tags) - taggerName := parts[5] - taggerEmail := parts[6] - taggerDate := parts[7] - subject := parts[8] - body := parts[9] - signature := parts[10] - - // combine subject and body for the message - var message string - if subject != "" && body != "" { - message = subject + "\n\n" + body - } else if subject != "" { - message = subject - } else { - message = body - } - - // parse creation time - var createdAt time.Time - if unix, err := strconv.ParseInt(taggerDate, 10, 64); err == nil { - createdAt = time.Unix(unix, 0) - } - - // parse object type - typ, err := plumbing.ParseObjectType(objectType) + tag, ok, err := parseTagRecord(line) if err != nil { return nil, err } - - // strip email separators - taggerEmail = strings.TrimSuffix(strings.TrimPrefix(taggerEmail, "<"), ">") - - tag := object.Tag{ - Hash: plumbing.NewHash(objectHash), - Name: tagName, - Tagger: object.Signature{ - Name: taggerName, - Email: taggerEmail, - When: createdAt, - }, - Message: message, - PGPSignature: signature, - TargetType: typ, - Target: plumbing.NewHash(targetHash), + if !ok { + continue } - tags = append(tags, tag) } -- tangled.sh