From 1c89edd87bf53c8e34091ff5f86fcf907dd8bfe5 Mon Sep 17 00:00:00 2001 From: Volker Schukai <volker.schukai@schukai.com> Date: Sat, 6 Jan 2024 12:59:07 +0100 Subject: [PATCH] fix: the tags are now processed branch-related #15 --- README.md | 1 - source/commandline.go | 7 ++ source/git.go | 147 ++++++++++++++++++++++-------------------- 3 files changed, 84 insertions(+), 71 deletions(-) diff --git a/README.md b/README.md index ba4bb36..4fa95e6 100644 --- a/README.md +++ b/README.md @@ -101,7 +101,6 @@ version predict **Makefile** ```makefile - build: version patch --path $(PROJECT_ROOT)version.json --selector "version" $(eval VERSION := $(shell cat version.json | jq -r .version)) diff --git a/source/commandline.go b/source/commandline.go index 612357e..b778a9e 100644 --- a/source/commandline.go +++ b/source/commandline.go @@ -264,6 +264,13 @@ func executeCommand() { err = writeVersion(newVersion) if err != nil { + + if activeCommand.Name == "auto" || activeCommand.Name == "predict" { + if arguments.Auto.ExitCode || arguments.Predict.ExitCode { + os.Exit(10) + } + } + _, err := fmt.Fprintf(os.Stderr, "Error: %s\n", err) if err != nil { fmt.Printf("Error: %s\n", err) diff --git a/source/git.go b/source/git.go index d4c8404..aa4c303 100644 --- a/source/git.go +++ b/source/git.go @@ -90,7 +90,7 @@ func GetCommitType() (CommitType, error) { fmt.Println("tag commit:", tagCommit) } - commitType, err := getCommitTypeSinceTag(tagCommit) + commitType, err := findNextTagType(gitRepo, tagCommit, verbosity) if err != nil { return OtherCommit, err } @@ -103,7 +103,7 @@ func GetCommitType() (CommitType, error) { } func getLatestSemanticTag() (SemanticVersion, error) { - tagList, err := getSemanticTags() + tagList, err := getSemanticTags(gitRepo) if err != nil { return SemanticVersion{}, err } @@ -124,51 +124,66 @@ func getTagCommit(tag string) (*object.Commit, error) { return nil, fmt.Errorf("failed to get tags: %v", err) } - var tagCommit *object.Commit + var commitHash *object.Commit err = tags.ForEach(func(t *plumbing.Reference) error { - if t.Name().Short() == tag { + if t.Name().Short() != tag { + return nil + } - tagObj, err := r.TagObject(t.Hash()) - if err == plumbing.ErrObjectNotFound { - commit, err := r.CommitObject(t.Hash()) - if err != nil { - return err - } - tagCommit = commit - } else if err != nil { - return err - } else { - - tagCommit, err = tagObj.Commit() - if err != nil { - return err - } - } - return ErrStopIteration + // Resolve the tag to a commit + obj, err := r.TagObject(t.Hash()) + var hash plumbing.Hash + if err == nil { + // This is an annotated tag + hash = obj.Target + } else { + // This is a lightweight tag or an error occurred + hash = t.Hash() } - return nil + + commitHash, err = r.CommitObject(hash) + + return ErrStopIteration + }) if err != nil && err != ErrStopIteration { return nil, fmt.Errorf("failed to iterate over tags: %v", err) } - if tagCommit == nil { + if commitHash == nil { return nil, fmt.Errorf("tag '%s' not found in commit log", tag) } - return tagCommit, nil + return commitHash, nil } -func getSemanticTags() ([]SemanticVersion, error) { - - r := gitRepo - +func getSemanticTags(r *git.Repository) ([]SemanticVersion, error) { tags, err := r.Tags() if err != nil { return nil, fmt.Errorf("failed to get tags: %v", err) } + headRef, err := r.Head() + if err != nil { + return nil, fmt.Errorf("failed to get branch: %v", err) + } + + commitIter, err := r.Log(&git.LogOptions{From: headRef.Hash()}) + if err != nil { + return nil, fmt.Errorf("failed to get commit history: %v", err) + } + + commitHistory := make(map[plumbing.Hash]bool) + err = commitIter.ForEach(func(c *object.Commit) error { + commitHistory[c.Hash] = true + return nil + }) + + if err != nil { + return nil, fmt.Errorf("failed to iterate over commits: %v", err) + } + var tagList []SemanticVersion err = tags.ForEach(func(tag *plumbing.Reference) error { tagName := tag.Name().Short() @@ -177,6 +192,26 @@ func getSemanticTags() ([]SemanticVersion, error) { fmt.Println("found tag: ", tagName) } + // Resolve the tag to a commit + var commitHash plumbing.Hash + obj, err := r.TagObject(tag.Hash()) + if err == nil { + // This is an annotated tag + commitHash = obj.Target + } else { + // This is a lightweight tag or an error occurred + commitHash = tag.Hash() + + if verbosity { + fmt.Println("tag " + tagName + " is a lightweight tag, you should use an annotated tag") + } + + } + + if _, exists := commitHistory[commitHash]; !exists { + return nil + } + if versionRegex.MatchString(tagName) { tagList = append(tagList, ParseSemanticVersion(tagName)) } @@ -199,69 +234,45 @@ func getSemanticTags() ([]SemanticVersion, error) { return tagList, nil } -func getCommitTypeSinceTag(tagCommit *object.Commit) (CommitType, error) { - - r := gitRepo +func findNextTagType(r *git.Repository, tagCommit *object.Commit, verbosity bool) (CommitType, error) { cIter, err := r.Log(&git.LogOptions{}) + if err != nil { - return OtherCommit, fmt.Errorf("failed to get commit log: %v", err) + return OtherCommit, fmt.Errorf("failed to get commit log from tag: %v", err) } - var commitType CommitType - found := false - + var commitType CommitType = OtherCommit counter := 0 err = cIter.ForEach(func(commit *object.Commit) error { - counter++ if commit.Hash == tagCommit.Hash { - found = true - - if verbosity { - fmt.Println("found tag commit after", counter, "commits") - } - - return storer.ErrStop // stop iteration + return storer.ErrStop } message := strings.TrimSpace(commit.Message) - if strings.HasPrefix(message, "feat") { - commitType = FeatCommit - found = true - if verbosity { - fmt.Println("found feat commit after", counter, "commits") + fmt.Printf("Found 'feat' commit after %d commits\n", counter) } - + return storer.ErrStop } else if strings.HasPrefix(message, "fix") { - - // if we already found a feat or breaking commit, we don't care about fix commits - if commitType < FixCommit && commitType > OtherCommit { - return nil - } - - commitType = FixCommit - - if verbosity { - fmt.Println("found fix commit after", counter, "commits") + if commitType < FixCommit { + commitType = FixCommit + if verbosity { + fmt.Printf("Found 'fix' commit after %d commits\n", counter) + } } - } else if containsBreakingChangeFooter(message) { commitType = BreakingCommit - found = true - if verbosity { - fmt.Println("found breaking commit after", counter, "commits") + fmt.Printf("Found breaking change after %d commits\n", counter) } - - return storer.ErrStop // stop iteration + return storer.ErrStop } - return nil }) @@ -269,10 +280,6 @@ func getCommitTypeSinceTag(tagCommit *object.Commit) (CommitType, error) { return OtherCommit, fmt.Errorf("failed to iterate over commit log: %v", err) } - if !found { - return OtherCommit, fmt.Errorf("tag commit not found in commit log") - } - return commitType, nil } -- GitLab