64 lines
2.0 KiB
Go
64 lines
2.0 KiB
Go
package branch
|
|||
|
|
|
||
|
|
import (
|
||
|
|
"fmt"
|
||
|
|
"regexp"
|
||
|
|
"strconv"
|
||
|
|
)
|
||
|
|
|
||
|
|
// DefaultBranchPattern matches "release/X.Y" or "origin/release/X.Y".
|
||
|
|
// Group 1 = major, group 2 = minor.
|
||
|
|
const DefaultBranchPattern = `^(?:.*/)?release/(\d+)\.(\d+)$`
|
||
|
|
|
||
|
|
// Info holds the major.minor version pinned by the branch name, plus the tag prefix from config.
|
||
|
|
type Info struct {
|
||
|
|
Major int
|
||
|
|
Minor int
|
||
|
|
TagPrefix string // set from config after Parse (default "v")
|
||
|
|
}
|
||
|
|
|
||
|
|
// Parse extracts major and minor from a branch name using the provided regex pattern.
|
||
|
|
// The pattern must contain exactly two capture groups: group 1 = major, group 2 = minor.
|
||
|
|
// TagPrefix is left at its zero value — the caller sets it from config.
|
||
|
|
func Parse(name, pattern string) (Info, error) {
|
||
|
|
re, err := regexp.Compile(pattern)
|
||
|
|
if err != nil {
|
||
|
|
return Info{}, fmt.Errorf("invalid branch pattern %q: %w", pattern, err)
|
||
|
|
}
|
||
|
|
|
||
|
|
m := re.FindStringSubmatch(name)
|
||
|
|
if len(m) < 3 {
|
||
|
|
return Info{}, fmt.Errorf("branch %q does not match pattern %q", name, pattern)
|
||
|
|
}
|
||
|
|
|
||
|
|
major, err := strconv.Atoi(m[1])
|
||
|
|
if err != nil {
|
||
|
|
return Info{}, fmt.Errorf("invalid major version in branch %q: %w", name, err)
|
||
|
|
}
|
||
|
|
minor, err := strconv.Atoi(m[2])
|
||
|
|
if err != nil {
|
||
|
|
return Info{}, fmt.Errorf("invalid minor version in branch %q: %w", name, err)
|
||
|
|
}
|
||
|
|
|
||
|
|
return Info{Major: major, Minor: minor}, nil
|
||
|
|
}
|
||
|
|
|
||
|
|
// MatchesTag checks whether a tag (e.g. "v1.2.3" or "1.2.3") belongs to this branch's version range.
|
||
|
|
// Uses TagPrefix to match the expected format. Returns the patch number and true on match.
|
||
|
|
func (i Info) MatchesTag(tag string) (patch int, ok bool) {
|
||
|
|
prefix := fmt.Sprintf("%s%d.%d.", i.TagPrefix, i.Major, i.Minor)
|
||
|
|
if len(tag) <= len(prefix) || tag[:len(prefix)] != prefix {
|
||
|
|
return 0, false
|
||
|
|
}
|
||
|
|
p, err := strconv.Atoi(tag[len(prefix):])
|
||
|
|
if err != nil {
|
||
|
|
return 0, false
|
||
|
|
}
|
||
|
|
return p, true
|
||
|
|
}
|
||
|
|
|
||
|
|
// TagName formats a version string (e.g. "1.2.4") into a full tag name (e.g. "v1.2.4" or "1.2.4").
|
||
|
|
func (i Info) TagName(version string) string {
|
||
|
|
return i.TagPrefix + version
|
||
|
|
}
|