diff options
| author | Max Resnick <max@ofmax.li> | 2023-06-24 13:28:15 -0700 |
|---|---|---|
| committer | Max Resnick <max@ofmax.li> | 2023-06-24 13:28:15 -0700 |
| commit | f2522a2e0dde56d6a33bfdf163e81a5bebe3da68 (patch) | |
| tree | 9cc6c701afdc273ce348f2e059001b9f942583fe /main.go | |
| download | go-bumpver-454543069e9d573c3b6110dad2cdb250a34b37de.tar.gz | |
init commit0.0.0
Diffstat (limited to 'main.go')
| -rw-r--r-- | main.go | 144 |
1 files changed, 144 insertions, 0 deletions
@@ -0,0 +1,144 @@ +package main + +import ( + "fmt" + "log" + "os" + "sort" + + "github.com/go-git/go-billy/v5/memfs" + "github.com/go-git/go-git/v5" + "github.com/go-git/go-git/v5/plumbing" + "github.com/go-git/go-git/v5/storage/memory" + + "github.com/spf13/cobra" + flags "github.com/spf13/pflag" + + "github.com/Masterminds/semver/v3" +) + +var ( + clonedRepo = &git.Repository{} + localRepo = &git.Repository{} + repoDir string + rootCmd = &cobra.Command{ + Use: "semverbump part [major|minor|patch]", + Short: "A tool for bumping semver git tags.", + ValidArgs: []string{"major", "minor", "patch"}, + Args: cobra.MatchAll(cobra.ExactArgs(1), cobra.OnlyValidArgs), + Long: `Inspired by the python bumpversion tool.`, + RunE: func(cmd *cobra.Command, args []string) error { + part := args[0] + localRepo, err := git.PlainOpen(repoDir) + if err != nil { + return err + } + + remoteURL := getRemoteURL(localRepo) + fs := memfs.New() + storer := memory.NewStorage() + remoteRepo, err := git.Clone(storer, fs, &git.CloneOptions{ + URL: remoteURL, + }) + if err != nil { + log.Fatal(err) + } + + tags := findTags(remoteRepo) + latestVersion := latestTag(tags) + if latestVersion == nil { + fmt.Println("No tags found. Not doing anything") + return nil + } + nextVersion := semver.Version{} + switch part { + case "major": + nextVersion = latestVersion.IncMajor() + case "minor": + nextVersion = latestVersion.IncMinor() + case "patch": + nextVersion = latestVersion.IncPatch() + } + fmt.Println(nextVersion) + return err + }, + } +) + +// TODO this only works for a single remote +func getRemoteURL(repo *git.Repository) string { + _, err := repo.Config() + if err != nil { + log.Fatal(err) + } + remotes, err := repo.Remotes() + if err != nil { + log.Fatalf("error getting remotes %s", err) + } + if len(remotes) == 0 { + return "" + + } + primaryConfig := remotes[0].Config() + return primaryConfig.URLs[0] +} + +func latestTag(tags []*semver.Version) *semver.Version { + numTags := len(tags) + if numTags == 0 { + return nil + } + return tags[numTags-1] +} + +func findTags(repo *git.Repository) []*semver.Version { + repoTagsIter, err := repo.Tags() + if err != nil { + log.Fatal(err) + } + repoTags := []*semver.Version{} + if err := repoTagsIter.ForEach(func(ref *plumbing.Reference) error { + if err != nil { + log.Fatal(err) + } + rn := plumbing.ReferenceName(ref.Name()) + version, err := semver.NewVersion(rn.Short()) + if err != nil { + // not a semver + return nil + } + repoTags = append(repoTags, version) + return nil + }); err != nil { + // log.error + fmt.Printf("Iteration Error %s", err) + } + sort.Sort(semver.Collection(repoTags)) + return repoTags +} + +func main() { + // Clone the given repository to the given directory + + //repo, err := git.PlainClone("/tmp/foo", false, &git.CloneOptions{ + // URL: "https://github.com/grumps/selector", + // Progress: os.Stdout, + //}) + //if err != nil { + // log.Fatal(err) + //} + if err := rootCmd.Execute(); err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(1) + } +} + +func init() { + // global flags + cwd, err := os.Getwd() + if err != nil { + log.Fatalf("couldn't get cwd %s", err) + } + repoDir = *flags.String("repoDir", cwd, "repo to examine") + //pflag +} |