generated from fallion/go-template
-
-
Notifications
You must be signed in to change notification settings - Fork 19
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- PreviousTag finds the tag that preceded the current one
- Loading branch information
Showing
2 changed files
with
122 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
package history | ||
|
||
import ( | ||
"errors" | ||
"log" | ||
"sort" | ||
"time" | ||
|
||
"gopkg.in/src-d/go-git.v4" | ||
"gopkg.in/src-d/go-git.v4/plumbing" | ||
) | ||
|
||
var ( | ||
// ErrPrevTagNotAvailable is returned when no previous tag is found. | ||
ErrPrevTagNotAvailable = errors.New("previous tag is not available") | ||
) | ||
|
||
type tag struct { | ||
hash plumbing.Hash | ||
time time.Time | ||
} | ||
|
||
// PreviousTag sorts tags based on when their commit happened and returns the one previous | ||
// to the current. | ||
func (g *Git) PreviousTag(currentHash plumbing.Hash) (plumbing.Hash, error) { | ||
tagrefs, err := g.repo.Tags() | ||
|
||
if err != nil { | ||
return currentHash, err | ||
} | ||
|
||
defer tagrefs.Close() | ||
|
||
var tagHashes []tag | ||
|
||
err = tagrefs.ForEach(func(t *plumbing.Reference) error { | ||
commitDate, err := g.commitDate(t.Hash()) | ||
|
||
if err != nil { | ||
return err | ||
} | ||
|
||
tagHashes = append(tagHashes, tag{time: commitDate, hash: t.Hash()}) | ||
return nil | ||
}) | ||
|
||
if err != nil { | ||
if g.Debug { | ||
log.Printf("[ERR] getting previous tag failed: %v", err) | ||
} | ||
return currentHash, err | ||
} | ||
|
||
// Tags are alphabetically ordered. We need to sort them by date. | ||
sortedTags := sortTags(g.repo, tagHashes) | ||
|
||
if g.Debug { | ||
log.Println("Sorted tag output: ") | ||
for _, taginstance := range sortedTags { | ||
log.Printf("hash: %v time: %v", taginstance.hash, taginstance.time.UTC()) | ||
} | ||
} | ||
|
||
// If there are fewer than two tags assume that the currentCommit is the newest tag | ||
if len(sortedTags) < 2 { | ||
if g.Debug { | ||
log.Println("[ERR] previous tag not available") | ||
} | ||
return currentHash, ErrPrevTagNotAvailable | ||
} | ||
|
||
if sortedTags[0].hash != currentHash { | ||
if g.Debug { | ||
log.Println("[ERR] current commit does not have a tag attached, building from this commit") | ||
} | ||
return sortedTags[0].hash, nil | ||
} | ||
|
||
if g.Debug { | ||
log.Printf("success: previous tag found at %v", sortedTags[1].hash) | ||
} | ||
|
||
return sortedTags[1].hash, nil | ||
} | ||
|
||
// sortTags sorts the tags according to when their parent commit happened. | ||
func sortTags(repo *git.Repository, tags []tag) []tag { | ||
sort.Slice(tags, func(i, j int) bool { | ||
return tags[i].time.After(tags[j].time) | ||
}) | ||
|
||
return tags | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
package history | ||
|
||
import ( | ||
"log" | ||
"testing" | ||
|
||
"github.com/stretchr/testify/assert" | ||
"gopkg.in/src-d/go-git.v4" | ||
) | ||
|
||
func TestPreviousTag(t *testing.T) { | ||
repo, _ := git.PlainOpen("../../testdata/git_tags") | ||
testGit := &Git{repo: repo, Debug: true} | ||
|
||
head, err := repo.Head() | ||
|
||
assert.NoError(t, err) | ||
|
||
tagHash, err := testGit.PreviousTag(head.Hash()) | ||
|
||
assert.NoError(t, err) | ||
|
||
log.Print(tagHash) | ||
|
||
commit, err := repo.CommitObject(tagHash) | ||
assert.NoError(t, err) | ||
assert.Equal(t, "chore: first commit on master\n", commit.Message) | ||
|
||
} |