Skip to content

Commit 27728f4

Browse files
authored
simplify tag check logic to revisions (#10)
* simplify tag check logic to revisions checks commits on the initial iterations to get data regarding the latest and previous tags and based on that list out the changelog , also uses revisions to check for tags instead of going through the nearestTag again and again * refactor: change API to use an opened repo instead expose the open repository to cli , this makes it easier for commitlog- web and also for writing tests with in memory repositories * add tests to for basic functionality only checking the basic set of functionalities, test still need to be added for tag level checks and custom hashes * add tests for start and end hash * adds tests for checking between tags * add test action * ci: modify changelog generation * ci: bump go version * explicitly install memfs * tests: force test tagger * rename test
1 parent 5c905bd commit 27728f4

File tree

8 files changed

+389
-108
lines changed

8 files changed

+389
-108
lines changed

.github/workflows/changelog.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ jobs:
1515
- name: Generate Change Log
1616
id: generate_log
1717
run: |
18-
curl -sf https://gobinaries.com/barelyhuman/commitlog | sh
18+
curl -sSL https://bina.egoist.sh/barelyhuman/commitlog | sh
1919
commitlog > CHANGELOG.md
2020
- uses: ncipollo/release-action@v1
2121
with:

.github/workflows/test.yml

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
name: Test
2+
3+
on:
4+
- push
5+
- pull_request
6+
7+
jobs:
8+
build_and_test:
9+
runs-on: ubuntu-latest
10+
steps:
11+
- uses: actions/checkout@v2
12+
13+
- name: Set up Go
14+
uses: actions/setup-go@v2
15+
with:
16+
go-version: 1.16
17+
18+
- name: Build
19+
run: go build -v ./...
20+
21+
- name: Test
22+
run: go test -v ./...

cmd/commitlog/commitlog.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,9 @@ func Run(args []string) {
3434
log.Fatalln(err)
3535
}
3636

37-
changelog, clogErr := clog.CommitLog(*repoPath, *startCommit, *endCommit, *inclusionFlags, *skipClassification)
37+
currentRepository := clog.OpenRepository(*repoPath)
38+
39+
changelog, clogErr := clog.CommitLog(currentRepository, *startCommit, *endCommit, *inclusionFlags, *skipClassification)
3840

3941
if clogErr.Err != nil {
4042
log.Fatal(clogErr.Message, clogErr.Err)

go.mod

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,6 @@ go 1.13
55
require (
66
github.com/AlecAivazis/survey/v2 v2.2.8
77
github.com/fatih/color v1.12.0
8+
github.com/go-git/go-billy/v5 v5.0.0 // indirect
89
github.com/go-git/go-git/v5 v5.2.0
910
)

log/gitutils.go

Lines changed: 8 additions & 93 deletions
Original file line numberDiff line numberDiff line change
@@ -11,105 +11,20 @@ import (
1111
"github.com/go-git/go-git/v5/plumbing/object"
1212
)
1313

14-
var (
15-
latestTag *plumbing.Reference
16-
previousTag *plumbing.Reference
17-
)
18-
19-
// GetLatestTagFromRepository - Get the latest Tag reference from the repo
20-
func GetLatestTagFromRepository(repository *git.Repository) (*plumbing.Reference, *plumbing.Reference, error) {
21-
tagRefs, err := repository.Tags()
22-
if err != nil {
23-
return nil, nil, err
24-
}
25-
26-
var latestTagCommit *object.Commit
27-
var latestTagName *plumbing.Reference
28-
var previousTag *plumbing.Reference
29-
var previousTagReturn *plumbing.Reference
30-
31-
err = tagRefs.ForEach(func(tagRef *plumbing.Reference) error {
32-
revision := plumbing.Revision(tagRef.Name())
33-
34-
tagCommitHash, err := repository.ResolveRevision(revision)
35-
if err != nil {
36-
return err
37-
}
38-
39-
commit, err := repository.CommitObject(*tagCommitHash)
14+
func IsHashATag(currentRepository *git.Repository, hash plumbing.Hash) bool {
15+
isTag := false
16+
tags, _ := currentRepository.Tags()
17+
tags.ForEach(func(tagRef *plumbing.Reference) error {
18+
revHash, err := currentRepository.ResolveRevision(plumbing.Revision(tagRef.Name()))
4019
if err != nil {
4120
return err
4221
}
43-
44-
if latestTagCommit == nil {
45-
latestTagCommit = commit
46-
latestTagName = tagRef
47-
previousTagReturn = previousTag
48-
}
49-
50-
if commit.Committer.When.After(latestTagCommit.Committer.When) {
51-
latestTagCommit = commit
52-
latestTagName = tagRef
53-
previousTagReturn = previousTag
22+
if *revHash == hash {
23+
isTag = true
5424
}
55-
56-
previousTag = tagRef
57-
5825
return nil
5926
})
60-
61-
if err != nil {
62-
return nil, nil, err
63-
}
64-
65-
return latestTagName, previousTagReturn, nil
66-
}
67-
68-
// isCommitToNearestTag - go through git revisions to find the latest tag and the nearest next tag
69-
func isCommitToNearestTag(repo *git.Repository, commit *object.Commit) bool {
70-
if latestTag == nil || previousTag == nil {
71-
var err error
72-
latestTag, previousTag, err = GetLatestTagFromRepository(repo)
73-
if err != nil {
74-
log.Fatal("Error getting latest tags from repository")
75-
}
76-
}
77-
78-
ref, err := repo.Head()
79-
80-
if err != nil {
81-
log.Fatal("Unable to get repository HEAD:", err)
82-
}
83-
84-
tillLatest := latestTag != nil && latestTag.Hash().String() != ref.Hash().String()
85-
86-
if err != nil {
87-
log.Fatal("Couldn't get latest tag...", err)
88-
}
89-
90-
if latestTag == nil || previousTag == nil {
91-
return false
92-
}
93-
94-
// Ignore errors as these are to be optionally checked
95-
followedTagReferenceLatest, err := repo.ResolveRevision(plumbing.Revision(latestTag.Name()))
96-
97-
if err != nil {
98-
log.Fatal("Failed to get referenced commit hash for latestTag's revision")
99-
}
100-
101-
followedTagReferencePrev, err := repo.ResolveRevision(plumbing.Revision(previousTag.Name()))
102-
103-
if err != nil {
104-
log.Fatal("Failed to get referenced commit hash for previous's revision")
105-
}
106-
107-
if tillLatest {
108-
return *followedTagReferenceLatest == commit.Hash
109-
}
110-
111-
return *followedTagReferencePrev == commit.Hash
112-
27+
return isTag
11328
}
11429

11530
// normalizeCommit - reduces the commit message to the first line and ignore the description text of the commit

log/log.go

Lines changed: 28 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -133,29 +133,26 @@ func (container *logContainer) canAddToContainer(skip bool) bool {
133133
return true
134134
}
135135

136-
/*
137-
TODO:
138-
- [] if the current start is also a tag then get data till prev tag
139-
- [] add in option to include the description, if the commit has a description
140-
*/
141-
142136
// CommitLog - Generate commit log
143-
func CommitLog(path string, startCommitString string, endCommitString string, inclusionFlags string, skipClassification bool) (string, ErrMessage) {
144-
currentRepository := OpenRepository(path)
137+
func CommitLog(currentRepository *git.Repository, startCommitString string, endCommitString string, inclusionFlags string, skipClassification bool) (string, ErrMessage) {
145138
baseCommitReference, err := currentRepository.Head()
146139
var startHash, endHash *object.Commit
147140
var cIter object.CommitIter
148141

149142
if err != nil {
150-
return "", ErrMessage{"Unable to get repository HEAD:", err}
143+
return "", ErrMessage{"Unable to get repository HEAD, are you sure you are in a git repository? Error:", err}
151144
}
152145

153146
startHash = GetCommitFromString(startCommitString, currentRepository)
154147
endHash = GetCommitFromString(endCommitString, currentRepository)
148+
isHeadTag := false
155149

156150
if startHash != nil {
157151
cIter, err = currentRepository.Log(&git.LogOptions{From: startHash.Hash})
158152
} else {
153+
if IsHashATag(currentRepository, baseCommitReference.Hash()) {
154+
isHeadTag = true
155+
}
159156
cIter, err = currentRepository.Log(&git.LogOptions{From: baseCommitReference.Hash()})
160157
}
161158

@@ -165,8 +162,26 @@ func CommitLog(path string, startCommitString string, endCommitString string, in
165162

166163
var commits []*object.Commit
167164

165+
var latestTag *object.Commit
166+
var previousTag *object.Commit
167+
tagAssignment := 0
168+
168169
err = cIter.ForEach(func(c *object.Commit) error {
169170
commits = append(commits, c)
171+
if isHeadTag && tagAssignment == 0 && latestTag == nil && c.Hash == baseCommitReference.Hash() {
172+
latestTag = c
173+
tagAssignment += 1
174+
175+
} else if IsHashATag(currentRepository, c.Hash) {
176+
if latestTag == nil && tagAssignment == 0 {
177+
latestTag = c
178+
tagAssignment += 1
179+
}
180+
if previousTag == nil && tagAssignment == 1 {
181+
previousTag = c
182+
tagAssignment += 1
183+
}
184+
}
170185
return nil
171186
})
172187

@@ -195,15 +210,15 @@ func CommitLog(path string, startCommitString string, endCommitString string, in
195210
key = strings.SplitN(strings.TrimSpace(key), ":", 2)[0]
196211
normalizedHash := c.Hash.String() + " - " + normalizeCommit(c.Message, scopedKey)
197212

198-
logContainer.AddCommit(key, normalizedHash, skipClassification)
199-
200-
if endHash == nil && isCommitToNearestTag(currentRepository, c) {
213+
if endHash == nil && previousTag != nil && previousTag.Hash == c.Hash {
201214
break
202215
} else if endHash != nil && c.Hash == endHash.Hash {
203216
break
204217
}
205-
}
206218

219+
logContainer.AddCommit(key, normalizedHash, skipClassification)
220+
221+
}
207222
return logContainer.ToMarkdown(skipClassification), ErrMessage{}
208223
}
209224

0 commit comments

Comments
 (0)