package main import ( "errors" "regexp" "strconv" "strings" ) type semVerBump uint const ( semVerBumpMinor semVerBump = iota semVerBumpPatch semVerBumpMajor ) type semVer struct { Major, Minor, Patch int PreReleaseInformation string MetaData string } func (s *semVer) String() string { v := []string{strings.Join([]string{ strconv.Itoa(s.Major), strconv.Itoa(s.Minor), strconv.Itoa(s.Patch), }, ".")} if s.PreReleaseInformation != "" { v = append(v, "-"+s.PreReleaseInformation) } if s.MetaData != "" { v = append(v, "+"+s.MetaData) } return strings.Join(v, "") } func parseSemVer(version string) (*semVer, error) { var ( s semVer err error ) version = strings.TrimLeft(version, "v") // Ensure the version is not prefixed like v0.1.0 t := strings.SplitN(version, "+", 2) if len(t) == 2 { s.MetaData = t[1] } t = strings.SplitN(t[0], "-", 2) if len(t) == 2 { s.PreReleaseInformation = t[1] } elements := strings.Split(t[0], ".") if len(elements) != 3 { return nil, errors.New("Version does not match semantic versioning format") } s.Major, err = strconv.Atoi(elements[0]) if err != nil { return nil, err } s.Minor, err = strconv.Atoi(elements[1]) if err != nil { return nil, err } s.Patch, err = strconv.Atoi(elements[2]) if err != nil { return nil, err } return &s, nil } func (s *semVer) Bump(bumpType semVerBump) { switch bumpType { case semVerBumpPatch: s.Patch += 1 case semVerBumpMinor: s.Patch = 0 s.Minor += 1 case semVerBumpMajor: s.Patch = 0 s.Minor = 0 s.Major += 1 } } func selectBumpType(logs []commit) (semVerBump, error) { bump := semVerBumpMinor matchers := map[*regexp.Regexp]semVerBump{} for _, m := range config.MatchPatch { r, err := regexp.Compile(m) if err != nil { return 0, err } matchers[r] = semVerBumpPatch } for _, m := range config.MatchMajor { r, err := regexp.Compile(m) if err != nil { return 0, err } matchers[r] = semVerBumpMajor } for _, l := range logs { for m, t := range matchers { if m.MatchString(l.Subject) && t > bump { bump = t } } } return bump, nil }