aboutsummaryrefslogtreecommitdiff
path: root/main.go
diff options
context:
space:
mode:
Diffstat (limited to 'main.go')
-rw-r--r--main.go143
1 files changed, 130 insertions, 13 deletions
diff --git a/main.go b/main.go
index 45992f9..e57bf8a 100644
--- a/main.go
+++ b/main.go
@@ -6,30 +6,118 @@ import (
"log"
"os"
"sort"
+ "strconv"
+ "strings"
"github.com/go-git/go-git/v5"
"github.com/go-git/go-git/v5/plumbing"
"github.com/spf13/cobra"
- flags "github.com/spf13/pflag"
+ "github.com/spf13/viper"
"github.com/Masterminds/semver/v3"
)
+type FmtPart string
+
var (
- errNoRemoteFound = errors.New("No remotes found")
- clonedRepo = &git.Repository{}
- localRepo = &git.Repository{}
- repoDir string
- remoteName string
- rootCmd = &cobra.Command{
+ BumpInt FmtPart = "$BumpInt"
+ KeyArg FmtPart = "$KeyArg"
+)
+
+type preReleaseVersion struct {
+ Fmt []string
+ KeyArgs map[string]string
+ v *semver.Version
+ versionPart string
+}
+
+// incPreRelease bumps a prerelease
+// if no existing pre-release render
+// if exists find the bump part
+func (prf *preReleaseVersion) incPreRelease() (semver.Version, error) {
+ currentPreRelease := prf.v.Prerelease()
+ newPreRelease := currentPreRelease == ""
+ currentPreReleaseParts := strings.Split(currentPreRelease, ".")
+ newPreReleaseParts := []string{}
+ // Loop over each of the format parts
+ // Align the output to match the output
+ for idx, fmtPart := range prf.Fmt {
+ partArgs := strings.Split(fmtPart, " ")
+ switch partArgs[0] {
+ case string(BumpInt):
+ // Handle a new pre-release
+ if newPreRelease {
+ newPreReleaseParts = append(newPreReleaseParts, "0")
+ continue
+ }
+ // bump int
+ // current int ++
+ currentVerStrPart := currentPreReleaseParts[idx]
+ currentVerPart, err := strconv.Atoi(currentVerStrPart)
+ if err != nil {
+ return semver.Version{}, err
+ }
+ newPreReleaseParts = append(newPreReleaseParts, strconv.Itoa(currentVerPart+1))
+ case string(KeyArg):
+ // check len
+ value, ok := prf.KeyArgs[partArgs[1]]
+ if !ok {
+ log.Fatalf("%s not found", partArgs[1])
+ return semver.Version{}, errors.New("KeyArg not found")
+ }
+ newPreReleaseParts = append(newPreReleaseParts, value)
+ default:
+ newPreReleaseParts = append(newPreReleaseParts, partArgs[0])
+ }
+ }
+ nextVersion := semver.Version{}
+ preReleaseStr := strings.Join(newPreReleaseParts, ".")
+ // When we are _JUST_ bumping the prerelease
+ if !newPreRelease {
+ newVersion, err := prf.v.SetPrerelease(preReleaseStr)
+ if err != nil {
+ log.Fatal(err)
+ return semver.Version{}, err
+ }
+ return newVersion, nil
+ }
+ switch prf.versionPart {
+ case "major":
+ nextVersion = prf.v.IncMajor()
+ case "minor":
+ nextVersion = prf.v.IncMinor()
+ case "patch":
+ nextVersion = prf.v.IncPatch()
+ }
+ newVersion, err := nextVersion.SetPrerelease(preReleaseStr)
+ if err != nil {
+ log.Fatal(err)
+ return semver.Version{}, err
+ }
+ return newVersion, nil
+}
+
+var (
+ errNoRemoteFound = errors.New("No remotes found")
+ clonedRepo = &git.Repository{}
+ localRepo = &git.Repository{}
+ repoDir string
+ remoteName string
+ preReleaseFmtArgs map[string]string = make(map[string]string)
+ preRelease bool
+ 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]
+ Long: `Inspired by the python bump2version tool.`,
+ RunE: func(cmd *cobra.Command, argz []string) error {
+ part := argz[0]
+ preRelease := viper.GetBool("prerelease")
+ // remoteName := viper.GetString("remote-name")
+ repoDir := viper.GetString("repo-dir")
+
localRepo, err := git.PlainOpen(repoDir)
if err != nil {
return err
@@ -44,6 +132,11 @@ var (
return errors.New("No tags found. Not doing anything")
}
+ versionPart := ""
+ if preRelease {
+ versionPart = part
+ part = "prerelease"
+ }
// actual bump
nextVersion := semver.Version{}
switch part {
@@ -53,6 +146,17 @@ var (
nextVersion = lastVersion.IncMinor()
case "patch":
nextVersion = lastVersion.IncPatch()
+ case "prerelease":
+ preRelVersion := preReleaseVersion{
+ []string{"PR", "$KeyArg PR_NUM"},
+ preReleaseFmtArgs,
+ lastVersion,
+ versionPart,
+ }
+ nextVersion, err = preRelVersion.incPreRelease()
+ if err != nil {
+ return err
+ }
}
fmt.Fprint(cmd.OutOrStdout(), nextVersion)
return err
@@ -99,10 +203,23 @@ func main() {
func init() {
// global flags
- cwd, err := os.Getwd()
+ viper.SetConfigName(".version")
+ viper.SetConfigType("toml")
+ viper.AddConfigPath(".")
+ cwd := ""
+ err := viper.ReadInConfig() // Find and read the config file
+ if err != nil { // Handle errors reading the config file
+ fmt.Println(err)
+ cwd, err = os.Getwd()
+ }
if err != nil {
log.Fatal(err)
}
- repoDir = *flags.String("repo-dir", cwd, "repo to examine")
- remoteName = *flags.String("remote-name", "origin", "remote to search and push to")
+
+ rootCmd.PersistentFlags().BoolVarP(&preRelease, "prerelease", "p", false, "create a prerelease tag for the (major|minor|patch)")
+ rootCmd.PersistentFlags().String("prerelease-fmt", "PR $KeyArg PR_NUM $BumpInt", "The format string for prerelease versions")
+ rootCmd.PersistentFlags().StringToStringVarP(&preReleaseFmtArgs, "key-args", "k", nil, "key=arg for the fmt string")
+ repoDir = *rootCmd.PersistentFlags().String("repo-dir", cwd, "repo to examine")
+ remoteName = *rootCmd.PersistentFlags().String("remote-name", "origin", "remote to search and push to")
+ viper.BindPFlags(rootCmd.PersistentFlags())
}