0
0
mirror of https://github.com/thegeeklab/git-sv.git synced 2024-11-24 21:20:40 +00:00
git-sv/sv/semver.go
2019-11-17 14:03:50 -03:00

100 lines
2.5 KiB
Go

package sv
import "github.com/Masterminds/semver"
type versionType int
const (
none versionType = iota
patch
minor
major
)
// ToVersion parse string to semver.Version
func ToVersion(value string) (semver.Version, error) {
version := value
if version == "" {
version = "0.0.0"
}
v, err := semver.NewVersion(version)
if err != nil {
return semver.Version{}, err
}
return *v, nil
}
// BreakingChangeTag breaking change tag from commit metadata
const BreakingChangeTag string = "breakingchange"
// SemVerCommitsProcessor interface
type SemVerCommitsProcessor interface {
NextVersion(version semver.Version, commits []GitCommitLog) semver.Version
}
// SemVerCommitsProcessorImpl process versions using commit log
type SemVerCommitsProcessorImpl struct {
MajorVersionTypes map[string]struct{}
MinorVersionTypes map[string]struct{}
PatchVersionTypes map[string]struct{}
IncludeUnknownTypeAsPatch bool
}
// NewSemVerCommitsProcessor SemanticVersionCommitsProcessorImpl constructor
func NewSemVerCommitsProcessor(unknownAsPatch bool, majorTypes, minorTypes, patchTypes []string) *SemVerCommitsProcessorImpl {
return &SemVerCommitsProcessorImpl{
IncludeUnknownTypeAsPatch: unknownAsPatch,
MajorVersionTypes: toMap(majorTypes),
MinorVersionTypes: toMap(minorTypes),
PatchVersionTypes: toMap(patchTypes),
}
}
// NextVersion calculates next version based on commit log
func (p SemVerCommitsProcessorImpl) NextVersion(version semver.Version, commits []GitCommitLog) semver.Version {
var versionToUpdate = none
for _, commit := range commits {
if v := p.versionTypeToUpdate(commit); v > versionToUpdate {
versionToUpdate = v
}
}
switch versionToUpdate {
case major:
return version.IncMajor()
case minor:
return version.IncMinor()
case patch:
return version.IncPatch()
default:
return version
}
}
func (p SemVerCommitsProcessorImpl) versionTypeToUpdate(commit GitCommitLog) versionType {
if _, exists := commit.Metadata[BreakingChangeTag]; exists {
return major
}
if _, exists := p.MajorVersionTypes[commit.Type]; exists {
return major
}
if _, exists := p.MinorVersionTypes[commit.Type]; exists {
return minor
}
if _, exists := p.PatchVersionTypes[commit.Type]; exists {
return patch
}
if p.IncludeUnknownTypeAsPatch {
return patch
}
return none
}
func toMap(values []string) map[string]struct{} {
result := make(map[string]struct{})
for _, v := range values {
result[v] = struct{}{}
}
return result
}