From dc351c9a227551771da1281882a7a5b98edd86a5 Mon Sep 17 00:00:00 2001 From: Hau Nguyen Date: Sun, 16 Jul 2023 20:51:21 +0700 Subject: [PATCH] feat: list semver tags --- go.mod | 1 + go.sum | 2 ++ internal/git/commit.go | 23 -------------------- internal/git/example/main.go | 26 +++++++++++++++++++++++ internal/git/models.go | 28 ++++++++++++++++++++++++ internal/git/repository.go | 41 +++++++++++++++++++++++++++++++++++- 6 files changed, 97 insertions(+), 24 deletions(-) delete mode 100644 internal/git/commit.go create mode 100644 internal/git/example/main.go create mode 100644 internal/git/models.go diff --git a/go.mod b/go.mod index 9e67a38..756cf2f 100644 --- a/go.mod +++ b/go.mod @@ -3,6 +3,7 @@ module github.com/haunt98/changeloguru go 1.18 require ( + github.com/Masterminds/semver/v3 v3.2.1 github.com/go-git/go-git/v5 v5.7.0 github.com/make-go-great/color-go v0.4.1 github.com/make-go-great/date-go v0.5.0 diff --git a/go.sum b/go.sum index ddee5aa..f28e9ed 100644 --- a/go.sum +++ b/go.sum @@ -1,3 +1,5 @@ +github.com/Masterminds/semver/v3 v3.2.1 h1:RN9w6+7QoMeJVGyfmbcgs28Br8cvmnucEXnY0rYXWg0= +github.com/Masterminds/semver/v3 v3.2.1/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ= github.com/Microsoft/go-winio v0.5.2 h1:a9IhgEQBCUEk6QCdml9CiJGhAws+YwffDHEMp1VMrpA= github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY= github.com/ProtonMail/go-crypto v0.0.0-20230518184743-7afd39499903 h1:ZK3C5DtzV2nVAQTx5S5jQvMeDqWtD1By5mOoyY/xJek= diff --git a/internal/git/commit.go b/internal/git/commit.go deleted file mode 100644 index ee3c1a9..0000000 --- a/internal/git/commit.go +++ /dev/null @@ -1,23 +0,0 @@ -package git - -import ( - "github.com/go-git/go-git/v5/plumbing/object" -) - -// Commit stores all git-commit information -type Commit struct { - Author Author - Message string -} - -// Convert from git-commit -func newCommit(commit *object.Commit) Commit { - return Commit{ - Message: commit.Message, - Author: Author{ - Name: commit.Author.Name, - Email: commit.Author.Email, - When: commit.Author.When, - }, - } -} diff --git a/internal/git/example/main.go b/internal/git/example/main.go new file mode 100644 index 0000000..816f86f --- /dev/null +++ b/internal/git/example/main.go @@ -0,0 +1,26 @@ +package main + +import ( + "log" + + "github.com/haunt98/changeloguru/internal/git" +) + +func main() { + r, err := git.NewRepository(".") + if err != nil { + log.Fatal(err) + } + + commits, err := r.Log("", "") + if err != nil { + log.Fatal(err) + } + log.Println("Commits: ", commits) + + tags, err := r.SemVerTags() + if err != nil { + log.Fatal(err) + } + log.Println("Tags: ", tags) +} diff --git a/internal/git/models.go b/internal/git/models.go new file mode 100644 index 0000000..eaefc1f --- /dev/null +++ b/internal/git/models.go @@ -0,0 +1,28 @@ +package git + +import ( + "github.com/Masterminds/semver/v3" + "github.com/go-git/go-git/v5/plumbing/object" +) + +// Commit stores all git-commit information +type Commit struct { + Author Author + Message string +} + +// Convert from go-git +func newCommit(c *object.Commit) Commit { + return Commit{ + Message: c.Message, + Author: Author{ + Name: c.Author.Name, + Email: c.Author.Email, + When: c.Author.When, + }, + } +} + +type SemVerTag struct { + Version *semver.Version +} diff --git a/internal/git/repository.go b/internal/git/repository.go index 1b14733..41a5561 100644 --- a/internal/git/repository.go +++ b/internal/git/repository.go @@ -2,7 +2,9 @@ package git import ( "fmt" + "sort" + "github.com/Masterminds/semver/v3" "github.com/go-git/go-git/v5" "github.com/go-git/go-git/v5/plumbing" "github.com/go-git/go-git/v5/plumbing/object" @@ -12,13 +14,15 @@ import ( const ( head = "HEAD" - defaultCommitCount = 10 + defaultCommitCount = 128 + defaultTagCount = 32 ) // Repository is an abstraction for git-repository type Repository interface { Log(fromRev, toRev string) ([]Commit, error) Commit(commitMessage string, paths ...string) error + SemVerTags() ([]SemVerTag, error) } type repo struct { @@ -161,3 +165,38 @@ func newIterFn(commits *[]Commit, beginFn, endFn stopFn) func(c *object.Commit) return nil } } + +// Return SemVer tags from earliest to latest +func (r *repo) SemVerTags() ([]SemVerTag, error) { + iter, err := r.gitRepo.Tags() + if err != nil { + return nil, err + } + + versions := make([]*semver.Version, 0, defaultTagCount) + + if err := iter.ForEach(func(r *plumbing.Reference) error { + version, err := semver.NewVersion(r.Name().Short()) + if err != nil { + // Ignore bad tag + return nil + } + + versions = append(versions, version) + + return nil + }); err != nil { + return nil, err + } + + sort.Sort(semver.Collection(versions)) + + tags := make([]SemVerTag, 0, len(versions)) + for _, version := range versions { + tags = append(tags, SemVerTag{ + Version: version, + }) + } + + return tags, nil +}