-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
(+semver: feature) Add cobra and command line args (#2)
Signed-off-by: Joshua Benjamin <[email protected]>
- Loading branch information
1 parent
a8eb8e9
commit f1cfba2
Showing
74 changed files
with
11,995 additions
and
243 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 |
---|---|---|
|
@@ -5,3 +5,5 @@ go: | |
|
||
go_import_path: github.com/annymsMthd/gogitver | ||
|
||
script: | ||
- make |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
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
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,39 @@ | ||
package cmd | ||
|
||
import ( | ||
"fmt" | ||
"os" | ||
|
||
"github.com/annymsMthd/gogitver/pkg/git" | ||
"github.com/spf13/cobra" | ||
) | ||
|
||
var rootCmd = &cobra.Command{ | ||
Use: "gogitver", | ||
Short: "gogitver is a semver generator that uses git history", | ||
Long: ``, | ||
Run: runRoot, | ||
} | ||
|
||
func init() { | ||
rootCmd.Flags().String("path", ".", "the path to the git repostiory") | ||
} | ||
|
||
// Execute gogitver | ||
func Execute() { | ||
if err := rootCmd.Execute(); err != nil { | ||
fmt.Println(err) | ||
os.Exit(1) | ||
} | ||
} | ||
|
||
func runRoot(cmd *cobra.Command, args []string) { | ||
f := cmd.Flag("path") | ||
|
||
version, err := git.GetCurrentVerion(f.Value.String()) | ||
if err != nil { | ||
panic(err) | ||
} | ||
|
||
fmt.Println(version) | ||
} |
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 |
---|---|---|
@@ -1,246 +1,7 @@ | ||
package main | ||
|
||
import ( | ||
"fmt" | ||
"regexp" | ||
"strings" | ||
|
||
"github.com/coreos/go-semver/semver" | ||
git "gopkg.in/src-d/go-git.v4" | ||
"gopkg.in/src-d/go-git.v4/plumbing" | ||
"gopkg.in/src-d/go-git.v4/plumbing/object" | ||
) | ||
|
||
type gitVersion struct { | ||
IsSolid bool | ||
Name *semver.Version | ||
|
||
MajorBump bool | ||
MinorBump bool | ||
PatchBump bool | ||
} | ||
import "github.com/annymsMthd/gogitver/cmd/gogitver/cmd" | ||
|
||
func main() { | ||
tagMap := make(map[string]string) | ||
|
||
r, err := git.PlainOpen(".") | ||
if err != nil { | ||
panic(err) | ||
} | ||
|
||
tags, err := r.Tags() | ||
if err != nil { | ||
panic(err) | ||
} | ||
|
||
err = tags.ForEach(func(ref *plumbing.Reference) error { | ||
c, err := r.CommitObject(ref.Hash()) | ||
if err != nil { | ||
return err | ||
} | ||
tagMap[c.Hash.String()] = ref.Name().Short() | ||
return nil | ||
}) | ||
if err != nil { | ||
panic(err) | ||
} | ||
|
||
h, err := r.Head() | ||
if err != nil { | ||
panic(err) | ||
} | ||
|
||
v, err := getVersion(r, h, tagMap) | ||
if err != nil { | ||
panic(err) | ||
} | ||
|
||
fmt.Println(v) | ||
} | ||
|
||
func getVersion(r *git.Repository, h *plumbing.Reference, tagMap map[string]string) (version *semver.Version, err error) { | ||
currentBranch, err := getCurrentBranch(r, h) | ||
if err != nil { | ||
panic(err) | ||
} | ||
|
||
masterHead, err := r.Reference("refs/heads/master", false) | ||
if err != nil { | ||
panic(err) | ||
} | ||
|
||
masterVersion, err := getMasterVersion(r, masterHead, tagMap) | ||
if err != nil { | ||
panic(err) | ||
} | ||
|
||
if h.Hash() == masterHead.Hash() { | ||
return masterVersion, nil | ||
} | ||
|
||
c, err := r.CommitObject(h.Hash()) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
versionMap := []gitVersion{} | ||
err = walkVersion(r, c, tagMap, &versionMap, masterHead.Hash().String()) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
var baseVersion *semver.Version | ||
index := len(versionMap) - 1 | ||
if index == -1 { | ||
return nil, fmt.Errorf("Cannot determine version in branch") | ||
} | ||
|
||
if versionMap[index].IsSolid { | ||
if versionMap[index].Name.LessThan(*masterVersion) { | ||
return nil, fmt.Errorf("Branch has tag '%s' whose version is less than master '%s'", versionMap[index].Name, masterVersion) | ||
} | ||
baseVersion = versionMap[index].Name | ||
index-- | ||
} else { | ||
baseVersion = masterVersion | ||
} | ||
|
||
if index < 0 { | ||
return baseVersion, nil | ||
} | ||
|
||
for ; index >= 0; index-- { | ||
v := versionMap[index] | ||
switch { | ||
case v.MajorBump: | ||
baseVersion.BumpMajor() | ||
case v.MinorBump: | ||
baseVersion.BumpMinor() | ||
case v.PatchBump: | ||
baseVersion.BumpPatch() | ||
} | ||
} | ||
|
||
baseVersion.PreRelease = semver.PreRelease(currentBranch) | ||
|
||
return baseVersion, nil | ||
} | ||
|
||
func getMasterVersion(r *git.Repository, masterHead *plumbing.Reference, tagMap map[string]string) (version *semver.Version, err error) { | ||
versionMap := []gitVersion{} | ||
|
||
c, err := r.CommitObject(masterHead.Hash()) | ||
if err != nil { | ||
return nil, err | ||
} | ||
err = walkVersion(r, c, tagMap, &versionMap, "") | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
var baseVersion *semver.Version | ||
index := len(versionMap) - 1 | ||
if versionMap[index].IsSolid { | ||
baseVersion = versionMap[index].Name | ||
index-- | ||
} else { | ||
baseVersion, err = semver.NewVersion("0.0.0") | ||
if err != nil { | ||
return nil, err | ||
} | ||
} | ||
|
||
if index < 0 { | ||
return baseVersion, nil | ||
} | ||
|
||
for ; index >= 0; index-- { | ||
v := versionMap[index] | ||
switch { | ||
case v.MajorBump: | ||
baseVersion.BumpMajor() | ||
case v.MinorBump: | ||
baseVersion.BumpMinor() | ||
case v.PatchBump: | ||
baseVersion.BumpPatch() | ||
} | ||
} | ||
|
||
return baseVersion, nil | ||
} | ||
|
||
func walkVersion(r *git.Repository, ref *object.Commit, tagMap map[string]string, versionMap *[]gitVersion, endHash string) error { | ||
tag, ok := tagMap[ref.Hash.String()] | ||
if ok { | ||
tagVersion, err := semver.NewVersion(tag) | ||
if err != nil { | ||
return err | ||
} | ||
*versionMap = append(*versionMap, gitVersion{IsSolid: true, Name: tagVersion}) | ||
return nil | ||
} | ||
|
||
matched, err := regexp.MatchString("(\\+semver: major)|(\\+semver: breaking)", ref.Message) | ||
if err != nil { | ||
return err | ||
} | ||
if matched { | ||
*versionMap = append(*versionMap, gitVersion{IsSolid: false, MajorBump: true}) | ||
return checkWalkParent(r, ref, tagMap, versionMap, endHash) | ||
} | ||
|
||
matched, err = regexp.MatchString("(\\+semver: minor)|(\\+semver: feature)", ref.Message) | ||
if err != nil { | ||
return err | ||
} | ||
if matched { | ||
*versionMap = append(*versionMap, gitVersion{IsSolid: false, MinorBump: true}) | ||
return checkWalkParent(r, ref, tagMap, versionMap, endHash) | ||
} | ||
|
||
*versionMap = append(*versionMap, gitVersion{IsSolid: false, PatchBump: true}) | ||
|
||
return checkWalkParent(r, ref, tagMap, versionMap, endHash) | ||
} | ||
|
||
func checkWalkParent(r *git.Repository, ref *object.Commit, tagMap map[string]string, versionMap *[]gitVersion, endHash string) error { | ||
if ref.NumParents() == 0 { | ||
return nil | ||
} | ||
|
||
parent, err := ref.Parent(0) | ||
if err != nil { | ||
return nil | ||
} | ||
|
||
if parent.Hash.String() == endHash { | ||
return nil | ||
} | ||
|
||
return walkVersion(r, parent, tagMap, versionMap, endHash) | ||
} | ||
|
||
func getCurrentBranch(r *git.Repository, h *plumbing.Reference) (name string, err error) { | ||
branchName := "" | ||
|
||
refs, err := r.References() | ||
if err != nil { | ||
panic(err) | ||
} | ||
err = refs.ForEach(func(r *plumbing.Reference) error { | ||
if r.Name().IsBranch() && r.Hash() == h.Hash() { | ||
branchName = r.Name().Short() | ||
} | ||
return nil | ||
}) | ||
if err != nil { | ||
panic(err) | ||
} | ||
|
||
if branchName == "" { | ||
return "", fmt.Errorf("Cannot determine branch") | ||
} | ||
|
||
branchName = strings.Replace(branchName, "/", "-", -1) | ||
return branchName, nil | ||
cmd.Execute() | ||
} |
Oops, something went wrong.