mirror of
https://github.com/thegeeklab/git-sv.git
synced 2024-11-24 21:20:40 +00:00
parent
8ff0147ec9
commit
a1eaa78a6c
@ -183,7 +183,7 @@ Commands like `commit-log` and `commit-notes` has a range option. Supported rang
|
||||
|
||||
By default, it's used [--date=short](https://git-scm.com/docs/git-log#Documentation/git-log.txt---dateltformatgt) at `git log`, all dates returned from it will be in `YYYY-MM-DD` format.
|
||||
|
||||
Range `tag` will use `git describe` to get the last tag available if `start` is empty, the others types won't use the existing tags. It's recommended to always use a start limit in a old repository with a lot of commits. This behavior was maintained to not break the retrocompatibility.
|
||||
Range `tag` will use `git for-each-ref refs/tags` to get the last tag available if `start` is empty, the others types won't use the existing tags. It's recommended to always use a start limit in a old repository with a lot of commits. This behavior was maintained to not break the retrocompatibility.
|
||||
|
||||
Range `date` use git log `--since` and `--until`. It's possible to use all supported formats from [git log](https://git-scm.com/docs/git-log#Documentation/git-log.txt---sinceltdategt). If `end` is in `YYYY-MM-DD` format, `sv` will add a day on git log command to make the end date inclusive.
|
||||
|
||||
|
@ -41,11 +41,11 @@ func configShowHandler(cfg Config) func(c *cli.Context) error {
|
||||
|
||||
func currentVersionHandler(git sv.Git) func(c *cli.Context) error {
|
||||
return func(c *cli.Context) error {
|
||||
describe := git.Describe()
|
||||
lastTag := git.LastTag()
|
||||
|
||||
currentVer, err := sv.ToVersion(describe)
|
||||
currentVer, err := sv.ToVersion(lastTag)
|
||||
if err != nil {
|
||||
return err
|
||||
return fmt.Errorf("error parsing version: %s from git tag, message: %v", lastTag, err)
|
||||
}
|
||||
fmt.Printf("%d.%d.%d\n", currentVer.Major(), currentVer.Minor(), currentVer.Patch())
|
||||
return nil
|
||||
@ -54,19 +54,19 @@ func currentVersionHandler(git sv.Git) func(c *cli.Context) error {
|
||||
|
||||
func nextVersionHandler(git sv.Git, semverProcessor sv.SemVerCommitsProcessor) func(c *cli.Context) error {
|
||||
return func(c *cli.Context) error {
|
||||
describe := git.Describe()
|
||||
lastTag := git.LastTag()
|
||||
|
||||
currentVer, err := sv.ToVersion(describe)
|
||||
currentVer, err := sv.ToVersion(lastTag)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error parsing version: %s from describe, message: %v", describe, err)
|
||||
return fmt.Errorf("error parsing version: %s from git tag, message: %v", lastTag, err)
|
||||
}
|
||||
|
||||
commits, err := git.Log(sv.NewLogRange(sv.TagRange, describe, ""))
|
||||
commits, err := git.Log(sv.NewLogRange(sv.TagRange, lastTag, ""))
|
||||
if err != nil {
|
||||
return fmt.Errorf("error getting git log, message: %v", err)
|
||||
}
|
||||
|
||||
nextVer := semverProcessor.NextVersion(currentVer, commits)
|
||||
nextVer, _ := semverProcessor.NextVersion(currentVer, commits)
|
||||
fmt.Printf("%d.%d.%d\n", nextVer.Major(), nextVer.Minor(), nextVer.Patch())
|
||||
return nil
|
||||
}
|
||||
@ -119,7 +119,7 @@ func getTagCommits(git sv.Git, tag string) ([]sv.GitCommitLog, error) {
|
||||
func logRange(git sv.Git, rangeFlag, startFlag, endFlag string) (sv.LogRange, error) {
|
||||
switch rangeFlag {
|
||||
case string(sv.TagRange):
|
||||
return sv.NewLogRange(sv.TagRange, str(startFlag, git.Describe()), endFlag), nil
|
||||
return sv.NewLogRange(sv.TagRange, str(startFlag, git.LastTag()), endFlag), nil
|
||||
case string(sv.DateRange):
|
||||
return sv.NewLogRange(sv.DateRange, startFlag, endFlag), nil
|
||||
case string(sv.HashRange):
|
||||
@ -164,7 +164,8 @@ func releaseNotesHandler(git sv.Git, semverProcessor sv.SemVerCommitsProcessor,
|
||||
if tag := c.String("t"); tag != "" {
|
||||
rnVersion, date, commits, err = getTagVersionInfo(git, semverProcessor, tag)
|
||||
} else {
|
||||
rnVersion, date, commits, err = getNextVersionInfo(git, semverProcessor)
|
||||
// TODO: should generate release notes if version was not updated?
|
||||
rnVersion, _, date, commits, err = getNextVersionInfo(git, semverProcessor)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
@ -223,37 +224,38 @@ func find(tag string, tags []sv.GitTag) int {
|
||||
return -1
|
||||
}
|
||||
|
||||
func getNextVersionInfo(git sv.Git, semverProcessor sv.SemVerCommitsProcessor) (semver.Version, time.Time, []sv.GitCommitLog, error) {
|
||||
describe := git.Describe()
|
||||
func getNextVersionInfo(git sv.Git, semverProcessor sv.SemVerCommitsProcessor) (semver.Version, bool, time.Time, []sv.GitCommitLog, error) {
|
||||
lastTag := git.LastTag()
|
||||
|
||||
currentVer, err := sv.ToVersion(describe)
|
||||
currentVer, err := sv.ToVersion(lastTag)
|
||||
if err != nil {
|
||||
return semver.Version{}, time.Time{}, nil, fmt.Errorf("error parsing version: %s from describe, message: %v", describe, err)
|
||||
return semver.Version{}, false, time.Time{}, nil, fmt.Errorf("error parsing version: %s from git tag, message: %v", lastTag, err)
|
||||
}
|
||||
|
||||
commits, err := git.Log(sv.NewLogRange(sv.TagRange, describe, ""))
|
||||
commits, err := git.Log(sv.NewLogRange(sv.TagRange, lastTag, ""))
|
||||
if err != nil {
|
||||
return semver.Version{}, time.Time{}, nil, fmt.Errorf("error getting git log, message: %v", err)
|
||||
return semver.Version{}, false, time.Time{}, nil, fmt.Errorf("error getting git log, message: %v", err)
|
||||
}
|
||||
|
||||
return semverProcessor.NextVersion(currentVer, commits), time.Now(), commits, nil
|
||||
version, updated := semverProcessor.NextVersion(currentVer, commits)
|
||||
return version, updated, time.Now(), commits, nil
|
||||
}
|
||||
|
||||
func tagHandler(git sv.Git, semverProcessor sv.SemVerCommitsProcessor) func(c *cli.Context) error {
|
||||
return func(c *cli.Context) error {
|
||||
describe := git.Describe()
|
||||
lastTag := git.LastTag()
|
||||
|
||||
currentVer, err := sv.ToVersion(describe)
|
||||
currentVer, err := sv.ToVersion(lastTag)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error parsing version: %s from describe, message: %v", describe, err)
|
||||
return fmt.Errorf("error parsing version: %s from git tag, message: %v", lastTag, err)
|
||||
}
|
||||
|
||||
commits, err := git.Log(sv.NewLogRange(sv.TagRange, describe, ""))
|
||||
commits, err := git.Log(sv.NewLogRange(sv.TagRange, lastTag, ""))
|
||||
if err != nil {
|
||||
return fmt.Errorf("error getting git log, message: %v", err)
|
||||
}
|
||||
|
||||
nextVer := semverProcessor.NextVersion(currentVer, commits)
|
||||
nextVer, _ := semverProcessor.NextVersion(currentVer, commits)
|
||||
fmt.Printf("%d.%d.%d\n", nextVer.Major(), nextVer.Minor(), nextVer.Patch())
|
||||
|
||||
if err := git.Tag(nextVer); err != nil {
|
||||
@ -344,6 +346,17 @@ func changelogHandler(git sv.Git, semverProcessor sv.SemVerCommitsProcessor, rnP
|
||||
|
||||
size := c.Int("size")
|
||||
all := c.Bool("all")
|
||||
addNextVersion := c.Bool("add-next-version")
|
||||
|
||||
if addNextVersion {
|
||||
rnVersion, updated, date, commits, uerr := getNextVersionInfo(git, semverProcessor)
|
||||
if uerr != nil {
|
||||
return uerr
|
||||
}
|
||||
if updated {
|
||||
releaseNotes = append(releaseNotes, rnProcessor.Create(&rnVersion, date, commits))
|
||||
}
|
||||
}
|
||||
for i, tag := range tags {
|
||||
if !all && i >= size {
|
||||
break
|
||||
@ -361,7 +374,7 @@ func changelogHandler(git sv.Git, semverProcessor sv.SemVerCommitsProcessor, rnP
|
||||
|
||||
currentVer, err := sv.ToVersion(tag.Name)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error parsing version: %s from describe, message: %v", tag.Name, err)
|
||||
return fmt.Errorf("error parsing version: %s from git tag, message: %v", tag.Name, err)
|
||||
}
|
||||
releaseNotes = append(releaseNotes, rnProcessor.Create(¤tVer, tag.Date, commits))
|
||||
}
|
||||
|
@ -128,6 +128,7 @@ func main() {
|
||||
Flags: []cli.Flag{
|
||||
&cli.IntFlag{Name: "size", Value: 10, Aliases: []string{"n"}, Usage: "get changelog from last 'n' tags"},
|
||||
&cli.BoolFlag{Name: "all", Usage: "ignore size parameter, get changelog for every tag"},
|
||||
&cli.BoolFlag{Name: "add-next-version", Usage: "add next version on change log (commits since last tag, but only if there is a new version to release)"},
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -20,7 +20,7 @@ const (
|
||||
|
||||
// Git commands
|
||||
type Git interface {
|
||||
Describe() string
|
||||
LastTag() string
|
||||
Log(lr LogRange) ([]GitCommitLog, error)
|
||||
Commit(header, body, footer string) error
|
||||
Tag(version semver.Version) error
|
||||
@ -78,9 +78,9 @@ func NewGit(messageProcessor MessageProcessor, cfg TagConfig) *GitImpl {
|
||||
}
|
||||
}
|
||||
|
||||
// Describe runs git describe, it no tag found, return empty
|
||||
func (GitImpl) Describe() string {
|
||||
cmd := exec.Command("git", "describe", "--abbrev=0", "--tags")
|
||||
// LastTag get last tag, if no tag found, return empty
|
||||
func (GitImpl) LastTag() string {
|
||||
cmd := exec.Command("git", "for-each-ref", "refs/tags", "--sort", "-creatordate", "--format", "%(refname:short)", "--count", "1")
|
||||
out, err := cmd.CombinedOutput()
|
||||
if err != nil {
|
||||
return ""
|
||||
|
12
sv/semver.go
12
sv/semver.go
@ -26,7 +26,7 @@ func ToVersion(value string) (semver.Version, error) {
|
||||
|
||||
// SemVerCommitsProcessor interface
|
||||
type SemVerCommitsProcessor interface {
|
||||
NextVersion(version semver.Version, commits []GitCommitLog) semver.Version
|
||||
NextVersion(version semver.Version, commits []GitCommitLog) (semver.Version, bool)
|
||||
}
|
||||
|
||||
// SemVerCommitsProcessorImpl process versions using commit log
|
||||
@ -50,7 +50,7 @@ func NewSemVerCommitsProcessor(vcfg VersioningConfig, mcfg CommitMessageConfig)
|
||||
}
|
||||
|
||||
// NextVersion calculates next version based on commit log
|
||||
func (p SemVerCommitsProcessorImpl) NextVersion(version semver.Version, commits []GitCommitLog) semver.Version {
|
||||
func (p SemVerCommitsProcessorImpl) NextVersion(version semver.Version, commits []GitCommitLog) (semver.Version, bool) {
|
||||
var versionToUpdate = none
|
||||
for _, commit := range commits {
|
||||
if v := p.versionTypeToUpdate(commit); v > versionToUpdate {
|
||||
@ -60,13 +60,13 @@ func (p SemVerCommitsProcessorImpl) NextVersion(version semver.Version, commits
|
||||
|
||||
switch versionToUpdate {
|
||||
case major:
|
||||
return version.IncMajor()
|
||||
return version.IncMajor(), true
|
||||
case minor:
|
||||
return version.IncMinor()
|
||||
return version.IncMinor(), true
|
||||
case patch:
|
||||
return version.IncPatch()
|
||||
return version.IncPatch(), true
|
||||
default:
|
||||
return version
|
||||
return version, false
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -14,21 +14,26 @@ func TestSemVerCommitsProcessorImpl_NextVersion(t *testing.T) {
|
||||
version semver.Version
|
||||
commits []GitCommitLog
|
||||
want semver.Version
|
||||
wantUpdated bool
|
||||
}{
|
||||
{"no update", true, version("0.0.0"), []GitCommitLog{}, version("0.0.0")},
|
||||
{"no update on unknown type", true, version("0.0.0"), []GitCommitLog{commitlog("a", map[string]string{})}, version("0.0.0")},
|
||||
{"no update on unmapped known type", false, version("0.0.0"), []GitCommitLog{commitlog("none", map[string]string{})}, version("0.0.0")},
|
||||
{"update patch on unknown type", false, version("0.0.0"), []GitCommitLog{commitlog("a", map[string]string{})}, version("0.0.1")},
|
||||
{"patch update", false, version("0.0.0"), []GitCommitLog{commitlog("patch", map[string]string{})}, version("0.0.1")},
|
||||
{"minor update", false, version("0.0.0"), []GitCommitLog{commitlog("patch", map[string]string{}), commitlog("minor", map[string]string{})}, version("0.1.0")},
|
||||
{"major update", false, version("0.0.0"), []GitCommitLog{commitlog("patch", map[string]string{}), commitlog("major", map[string]string{})}, version("1.0.0")},
|
||||
{"breaking change update", false, version("0.0.0"), []GitCommitLog{commitlog("patch", map[string]string{}), commitlog("patch", map[string]string{"breaking-change": "break"})}, version("1.0.0")},
|
||||
{"no update", true, version("0.0.0"), []GitCommitLog{}, version("0.0.0"), false},
|
||||
{"no update on unknown type", true, version("0.0.0"), []GitCommitLog{commitlog("a", map[string]string{})}, version("0.0.0"), false},
|
||||
{"no update on unmapped known type", false, version("0.0.0"), []GitCommitLog{commitlog("none", map[string]string{})}, version("0.0.0"), false},
|
||||
{"update patch on unknown type", false, version("0.0.0"), []GitCommitLog{commitlog("a", map[string]string{})}, version("0.0.1"), true},
|
||||
{"patch update", false, version("0.0.0"), []GitCommitLog{commitlog("patch", map[string]string{})}, version("0.0.1"), true},
|
||||
{"minor update", false, version("0.0.0"), []GitCommitLog{commitlog("patch", map[string]string{}), commitlog("minor", map[string]string{})}, version("0.1.0"), true},
|
||||
{"major update", false, version("0.0.0"), []GitCommitLog{commitlog("patch", map[string]string{}), commitlog("major", map[string]string{})}, version("1.0.0"), true},
|
||||
{"breaking change update", false, version("0.0.0"), []GitCommitLog{commitlog("patch", map[string]string{}), commitlog("patch", map[string]string{"breaking-change": "break"})}, version("1.0.0"), true},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
p := NewSemVerCommitsProcessor(VersioningConfig{UpdateMajor: []string{"major"}, UpdateMinor: []string{"minor"}, UpdatePatch: []string{"patch"}, IgnoreUnknown: tt.ignoreUnknown}, CommitMessageConfig{Types: []string{"major", "minor", "patch", "none"}})
|
||||
if got := p.NextVersion(tt.version, tt.commits); !reflect.DeepEqual(got, tt.want) {
|
||||
t.Errorf("SemVerCommitsProcessorImpl.NextVersion() = %v, want %v", got, tt.want)
|
||||
got, gotUpdated := p.NextVersion(tt.version, tt.commits)
|
||||
if !reflect.DeepEqual(got, tt.want) {
|
||||
t.Errorf("SemVerCommitsProcessorImpl.NextVersion() Version = %v, want %v", got, tt.want)
|
||||
}
|
||||
if tt.wantUpdated != gotUpdated {
|
||||
t.Errorf("SemVerCommitsProcessorImpl.NextVersion() Updated = %v, want %v", gotUpdated, tt.wantUpdated)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user