From 540bb3d7419aab314fdb999dd57eeac3c53f5fad Mon Sep 17 00:00:00 2001
From: Reaper <ahoy@barelyhuman.dev>
Date: Fri, 10 Jun 2022 16:35:00 +0530
Subject: [PATCH 01/51] fix doc generation

---
 scripts/generate-docs.sh | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/scripts/generate-docs.sh b/scripts/generate-docs.sh
index eb487e7..f07ccab 100755
--- a/scripts/generate-docs.sh
+++ b/scripts/generate-docs.sh
@@ -6,4 +6,9 @@ curl -o mudkip.tgz -L https://github.com/barelyhuman/mudkip/releases/latest/down
 tar -xvzf mudkip.tgz
 install linux-amd64/mudkip /usr/local/bin
 
-mudkip --stylesheet="./docs/styles.css"
\ No newline at end of file
+# hack for github pages till mudkip doesn't add baseURL functionality
+sed -i s#/#/commitlog/#g ./docs/_sidebar.md
+
+mudkip --stylesheet="./docs/styles.css"
+
+

From b78e0676272c13bd7d4506c16627137a00a175d3 Mon Sep 17 00:00:00 2001
From: Reaper <ahoy@barelyhuman.dev>
Date: Fri, 10 Jun 2022 17:47:01 +0530
Subject: [PATCH 02/51] setup for the cli redo

---
 README.md             |   2 +-
 commands/commitlog.go |   7 +++
 commands/release.go   |   7 +++
 go.mod                |   3 +-
 go.sum                |  16 ++++--
 main.go               | 118 ++++++++++++++++++++++++++++++++++++++++--
 6 files changed, 144 insertions(+), 9 deletions(-)
 create mode 100644 commands/commitlog.go
 create mode 100644 commands/release.go

diff --git a/README.md b/README.md
index 81982de..3ea1e3c 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@
 <p align="center">
   <img src="https://raw.githubusercontent.com/barelyhuman/commitlog/main/assets/commitlog.png" height="64">
-<p align="center">Changelog generator using Commit History</p>
+<p align="center">commits to changelogs</p>
 
 [![Go Report Card](https://goreportcard.com/badge/github.com/barelyhuman/commitlog)](https://goreportcard.com/report/github.com/barelyhuman/commitlog)
 
diff --git a/commands/commitlog.go b/commands/commitlog.go
new file mode 100644
index 0000000..3a3db4a
--- /dev/null
+++ b/commands/commitlog.go
@@ -0,0 +1,7 @@
+package commands
+
+import "github.com/urfave/cli/v2"
+
+func Commitlog(c *cli.Context) (err error) {
+	return
+}
diff --git a/commands/release.go b/commands/release.go
new file mode 100644
index 0000000..7a4bebf
--- /dev/null
+++ b/commands/release.go
@@ -0,0 +1,7 @@
+package commands
+
+import "github.com/urfave/cli/v2"
+
+func Release(c *cli.Context) (err error) {
+	return
+}
diff --git a/go.mod b/go.mod
index 82e1fe9..f81b481 100644
--- a/go.mod
+++ b/go.mod
@@ -1,11 +1,12 @@
 module github.com/barelyhuman/commitlog
 
-go 1.13
+go 1.16
 
 require (
 	github.com/AlecAivazis/survey/v2 v2.2.8
 	github.com/fatih/color v1.12.0
 	github.com/go-git/go-billy/v5 v5.0.0
 	github.com/go-git/go-git/v5 v5.2.0
+	github.com/urfave/cli/v2 v2.8.1
 	golang.org/x/sys v0.0.0-20220412211240-33da011f77ad // indirect
 )
diff --git a/go.sum b/go.sum
index c15ba1c..80ecf88 100644
--- a/go.sum
+++ b/go.sum
@@ -1,5 +1,6 @@
 github.com/AlecAivazis/survey/v2 v2.2.8 h1:TgxCwybKdBckmC+/P9/5h49rw/nAHe/itZL0dgHs+Q0=
 github.com/AlecAivazis/survey/v2 v2.2.8/go.mod h1:9DYvHgXtiXm6nCn+jXnOXLKbH+Yo9u8fAS/SduGdoPk=
+github.com/BurntSushi/toml v1.1.0/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
 github.com/Netflix/go-expect v0.0.0-20180615182759-c93bf25de8e8 h1:xzYJEypr/85nBpB11F9br+3HUrpgb+fcm5iADzXXYEw=
 github.com/Netflix/go-expect v0.0.0-20180615182759-c93bf25de8e8/go.mod h1:oX5x61PbNXchhh0oikYAH+4Pcfw5LKv21+Jnpr6r6Pc=
 github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7 h1:uSoVVbwJiQipAclBbw+8quDsfcvFjOpI5iCf4p/cqCs=
@@ -8,6 +9,8 @@ github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239 h1:kFOfPq6dUM1hTo
 github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c=
 github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio=
 github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs=
+github.com/cpuguy83/go-md2man/v2 v2.0.1 h1:r/myEWzV9lfsM1tFLgDyu0atFtJ1fXn261LKYj/3DxU=
+github.com/cpuguy83/go-md2man/v2 v2.0.1/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
 github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
 github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
@@ -16,7 +19,6 @@ github.com/emirpasic/gods v1.12.0 h1:QAUIPSaCu4G+POclxeqb3F+WPpdKqFGlw36+yOzGlrg
 github.com/emirpasic/gods v1.12.0/go.mod h1:YfzfFFoVP/catgzJb4IKIqXjX78Ha8FMSDh3ymbK86o=
 github.com/fatih/color v1.12.0 h1:mRhaKNwANqRgUBGKmnI5ZxEk7QXmjQeCcuYFMX2bfcc=
 github.com/fatih/color v1.12.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM=
-github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568 h1:BHsljHzVlRcyQhjrss6TZTdY2VfCqZPbv5k3iBFa2ZQ=
 github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc=
 github.com/gliderlabs/ssh v0.2.2 h1:6zsha5zo/TWhRhwqCD3+EarCAgZ2yN28ipRnGPnwkI0=
 github.com/gliderlabs/ssh v0.2.2/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0=
@@ -64,14 +66,20 @@ github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
 github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
 github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
 github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
+github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
 github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0=
 github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
 github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
 github.com/stretchr/testify v1.2.1/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
 github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
 github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
+github.com/urfave/cli/v2 v2.8.1 h1:CGuYNZF9IKZY/rfBe3lJpccSoIY1ytfvmgQT90cNOl4=
+github.com/urfave/cli/v2 v2.8.1/go.mod h1:Z41J9TPoffeoqP0Iza0YbAhGvymRdZAd2uPmZ5JxRdY=
 github.com/xanzy/ssh-agent v0.2.1 h1:TCbipTQL2JiiCprBWx9frJ2eJlCYT00NmctrHxVAr70=
 github.com/xanzy/ssh-agent v0.2.1/go.mod h1:mLlQY/MoOhWBj+gOGMQkOeiEvkx+8pJSI+0Bx9h2kr4=
+github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 h1:bAn7/zixMGCfxrRTfdpNzjtPYqr8smhKouy9mxVdGPU=
+github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8=
 golang.org/x/crypto v0.0.0-20190219172222-a4c6cb3142f2/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
 golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
 golang.org/x/crypto v0.0.0-20190530122614-20be4c3c3ed5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
@@ -91,8 +99,9 @@ golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7w
 golang.org/x/sys v0.0.0-20220412211240-33da011f77ad h1:ntjMns5wyP/fN65tdBD4g8J5w8n015+iIIs9rtjXkY0=
 golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
-golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
 golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
+golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=
+golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
 golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
 gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
 gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
@@ -101,5 +110,6 @@ gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8
 gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME=
 gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI=
 gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
-gopkg.in/yaml.v2 v2.2.4 h1:/eiJrUcujPVeJ3xlSWaiNi3uSVmDGBK1pDHUHAnao1I=
 gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
+gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
diff --git a/main.go b/main.go
index a074bcf..79d75d8 100644
--- a/main.go
+++ b/main.go
@@ -1,11 +1,121 @@
-// SPDX-License-Identifier: MIT
-
 package main
 
 import (
-	"github.com/barelyhuman/commitlog/cmd"
+	_ "embed"
+	"fmt"
+	"log"
+	"os"
+
+	"github.com/barelyhuman/commitlog/commands"
+	"github.com/urfave/cli/v2"
 )
 
+//go:embed .commitlog.release
+var version string
+
 func main() {
-	cmd.Init()
+	app := &cli.App{
+		Name:  "commitlog",
+		Usage: "commits to changelogs",
+		Action: func(c *cli.Context) error {
+			fmt.Println(
+				"[commitlog] we no longer support direct invocation, please use the subcommand `generate` to generate a log or `release` to manage your .commitlog.release",
+			)
+
+			return nil
+		},
+		Commands: []*cli.Command{
+			{
+				Name:    "generate",
+				Aliases: []string{"g"},
+				Usage:   "commits to changelogs",
+				Action: func(c *cli.Context) error {
+					return commands.Commitlog(c)
+				},
+				Flags: []cli.Flag{
+					&cli.BoolFlag{
+						Name:  "promo",
+						Usage: "add promo text to the end of output",
+					},
+					&cli.StringFlag{
+						Name:  "out",
+						Usage: "path to the output `FILE`",
+					},
+					&cli.BoolFlag{
+						Name:  "stdio",
+						Usage: "print to the stdout",
+					},
+					&cli.StringFlag{
+						Name: "start",
+						Usage: "`START` reference for the commit to include commits from," +
+							"This is inclusive of the given commit reference",
+					},
+					&cli.StringFlag{
+						Name: "end",
+						Usage: "`END` reference for the commit to stop including commits at." +
+							"This is exclusive of the given commit reference",
+					},
+				},
+			},
+			{
+				Name:    "release",
+				Aliases: []string{"r"},
+				Usage:   "manage .commitlog.release version",
+				Action: func(c *cli.Context) error {
+					return commands.Release(c)
+				},
+				Flags: []cli.Flag{
+					&cli.BoolFlag{
+						Name:  "init",
+						Usage: "initialise commitlog release",
+					},
+					&cli.BoolFlag{
+						Name: "pre-release",
+						Usage: "create a pre-release version. will default to patch increment unless" +
+							"specified and not already a pre-release",
+					},
+					&cli.StringFlag{
+						Name:  "pre-release-tag",
+						Value: "beta",
+						Usage: "create a pre-release version",
+					},
+					&cli.BoolFlag{
+						Name:  "major",
+						Usage: "create a major version",
+					},
+					&cli.BoolFlag{
+						Name:  "minor",
+						Usage: "create a minor version",
+					},
+					&cli.BoolFlag{
+						Name:  "patch",
+						Usage: "create a patch version",
+					},
+					&cli.BoolFlag{
+						Name:  "commit",
+						Value: false,
+						Usage: "if true will create a commit, of the changed version",
+					},
+					&cli.BoolFlag{
+						Name:  "tag",
+						Value: false,
+						Usage: "if true will create a tag, with the given version",
+					},
+				},
+			},
+		},
+	}
+
+	cli.VersionFlag = &cli.BoolFlag{
+		Name:    "version",
+		Aliases: []string{"v"},
+		Usage:   "print only the version",
+	}
+
+	app.Version = version
+
+	err := app.Run(os.Args)
+	if err != nil {
+		log.Fatal(err)
+	}
 }

From b513e53cbbc30e5b667fbba373b9589911a47ac0 Mon Sep 17 00:00:00 2001
From: Reaper <ahoy@barelyhuman.dev>
Date: Sat, 11 Jun 2022 17:49:49 +0530
Subject: [PATCH 03/51] feat: generator subcommand implementation

implement the base set of functionality for the
generator command
TODO: should improve the naming of the internal structs
---
 .gitignore            |   3 +-
 commands/commitlog.go |  67 +++++++++-
 lib/commits.go        |  51 +++++++
 main.go               |  23 +++-
 pkg/generator.go      | 304 ++++++++++++++++++++++++++++++++++++++++++
 5 files changed, 441 insertions(+), 7 deletions(-)
 create mode 100644 lib/commits.go
 create mode 100644 pkg/generator.go

diff --git a/.gitignore b/.gitignore
index 8fc5d91..d6f3ffe 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,4 +1,5 @@
 CHANGELOG.md
 ./commitlog
 .DS_Store
-dist
\ No newline at end of file
+dist
+commitlog
diff --git a/commands/commitlog.go b/commands/commitlog.go
index 3a3db4a..b87b6a5 100644
--- a/commands/commitlog.go
+++ b/commands/commitlog.go
@@ -1,7 +1,70 @@
 package commands
 
-import "github.com/urfave/cli/v2"
+import (
+	"github.com/barelyhuman/commitlog/pkg"
+	"github.com/urfave/cli/v2"
+)
 
 func Commitlog(c *cli.Context) (err error) {
-	return
+	path := c.String("path")
+	addPromo := c.Bool("promo")
+	out := c.String("out")
+	stdio := c.Bool("stdio")
+	startRef := c.String("start")
+	endRef := c.String("end")
+	categories := c.String("categories")
+
+	gOptions := []pkg.GeneratorConfigMod{}
+
+	if addPromo {
+		gOptions = append(gOptions,
+			pkg.WithPromo(),
+		)
+	}
+
+	// either write to a file or to the stdio with true by default
+	if len(out) > 0 {
+		gOptions = append(gOptions,
+			pkg.WithOutputToFile(out),
+		)
+	} else if stdio {
+		gOptions = append(gOptions,
+			pkg.WithOutputToStdio(),
+		)
+	}
+
+	if len(startRef) > 0 {
+		gOptions = append(gOptions,
+			pkg.WithStartReference(startRef),
+		)
+	}
+
+	if len(endRef) > 0 {
+		gOptions = append(gOptions,
+			pkg.WithEndReference(endRef),
+		)
+	}
+
+	if len(categories) > 0 {
+		gOptions = append(gOptions,
+			pkg.WithCategories(categories),
+		)
+	}
+
+	generator := pkg.CreateGenerator(path,
+		gOptions...)
+
+	err = generator.ReadCommmits()
+
+	if err != nil {
+		return err
+	}
+
+	err = generator.Classify()
+
+	if err != nil {
+		return err
+	}
+
+	return generator.Generate()
 }
diff --git a/lib/commits.go b/lib/commits.go
new file mode 100644
index 0000000..b71616c
--- /dev/null
+++ b/lib/commits.go
@@ -0,0 +1,51 @@
+package lib
+
+import (
+	"log"
+	"strings"
+
+	"github.com/go-git/go-git/v5"
+	"github.com/go-git/go-git/v5/plumbing"
+	"github.com/go-git/go-git/v5/plumbing/object"
+)
+
+func IsHashATag(currentRepository *git.Repository, hash plumbing.Hash) bool {
+	isTag := false
+	tags, _ := currentRepository.Tags()
+	tags.ForEach(func(tagRef *plumbing.Reference) error {
+		revHash, err := currentRepository.ResolveRevision(plumbing.Revision(tagRef.Name()))
+		if err != nil {
+			return err
+		}
+		if *revHash == hash {
+			isTag = true
+		}
+		return nil
+	})
+	return isTag
+}
+
+func GetCommitFromString(repo *git.Repository, commitString string) *object.Commit {
+	if commitString == "" {
+		return nil
+	}
+
+	hash, err := repo.ResolveRevision(plumbing.Revision(commitString))
+	if err != nil {
+		log.Fatal("Unable to get Repo head:", err)
+	}
+
+	commitRef, err := repo.CommitObject(*hash)
+	if err != nil {
+		log.Fatal("Unable to get resolve commit:", err)
+	}
+	return commitRef
+}
+
+func CommitToLog(c *object.Commit) string {
+	var commitMsg strings.Builder
+	commitMsg.WriteString(c.Hash.String())
+	commitMsg.WriteString(" ")
+	commitMsg.WriteString(strings.Split(c.Message, "\n")[0])
+	return commitMsg.String()
+}
diff --git a/main.go b/main.go
index 79d75d8..67437d0 100644
--- a/main.go
+++ b/main.go
@@ -33,25 +33,40 @@ func main() {
 					return commands.Commitlog(c)
 				},
 				Flags: []cli.Flag{
+					&cli.StringFlag{
+						Name:    "path",
+						Value:   ".",
+						Aliases: []string{"p"},
+						Usage:   "root with the '.git' folder `PATH`",
+					},
 					&cli.BoolFlag{
 						Name:  "promo",
 						Usage: "add promo text to the end of output",
 					},
 					&cli.StringFlag{
-						Name:  "out",
-						Usage: "path to the output `FILE`",
+						Name:    "out",
+						Aliases: []string{"o"},
+						Usage:   "path to the output `FILE`",
 					},
 					&cli.BoolFlag{
 						Name:  "stdio",
+						Value: true,
 						Usage: "print to the stdout",
 					},
 					&cli.StringFlag{
-						Name: "start",
+						Name:  "categories",
+						Value: "",
+						Usage: "categories to use, includes all commits by default. any text you add here will be used to create categories out of the commits",
+					},
+					&cli.StringFlag{
+						Name:    "start",
+						Aliases: []string{"s"},
 						Usage: "`START` reference for the commit to include commits from," +
 							"This is inclusive of the given commit reference",
 					},
 					&cli.StringFlag{
-						Name: "end",
+						Name:    "end",
+						Aliases: []string{"e"},
 						Usage: "`END` reference for the commit to stop including commits at." +
 							"This is exclusive of the given commit reference",
 					},
diff --git a/pkg/generator.go b/pkg/generator.go
new file mode 100644
index 0000000..b0358b3
--- /dev/null
+++ b/pkg/generator.go
@@ -0,0 +1,304 @@
+package pkg
+
+import (
+	"fmt"
+	"io"
+	"log"
+	"os"
+	"regexp"
+	"strings"
+
+	"github.com/barelyhuman/commitlog/lib"
+	"github.com/go-git/go-git/v5"
+	"github.com/go-git/go-git/v5/plumbing/object"
+)
+
+type commitClassification struct {
+	key     string
+	commits []string
+}
+
+type Generator struct {
+	repo                *git.Repository
+	workingDirectorPath string
+	startRef            string
+	endRef              string
+	addPromo            bool
+	categories          []string
+	output              struct {
+		stdio    bool
+		file     bool
+		filePath string
+	}
+	classifiedCommits []commitClassification
+	inMarkdown        string
+	commitToProcess   []*object.Commit
+}
+
+type GeneratorConfigMod func(*Generator)
+
+func (g *Generator) openRepo() {
+	if g.repo != nil {
+		return
+	}
+
+	r, err := git.PlainOpen(g.workingDirectorPath)
+	if err != nil {
+		log.Fatal("Error opening Repository: ", err)
+	}
+	g.repo = r
+}
+
+func (g *Generator) readCommitsInTags() (err error) {
+	// make sure the repo is open
+	g.openRepo()
+
+	var commits []*object.Commit
+
+	var latestTagCommit *object.Commit
+	var previousTagCommit *object.Commit
+
+	commitsIter, err := g.repo.Log(&git.LogOptions{})
+	if err != nil {
+		err = fmt.Errorf("[commitlog] Failed to get commits from given hash %v", err)
+		return
+	}
+	defer commitsIter.Close()
+
+	// loop through the commits to get the
+	// most recent tagged commit and the 2nd most recent
+	// tagged commit
+	for {
+		c, err := commitsIter.Next()
+
+		if err == io.EOF {
+			break
+		}
+
+		isTag := lib.IsHashATag(g.repo, c.Hash)
+		if isTag {
+			if latestTagCommit == nil {
+				latestTagCommit = c
+			} else if previousTagCommit == nil {
+				previousTagCommit = c
+				break
+			}
+		}
+	}
+
+	commitsIter, err = g.repo.Log(&git.LogOptions{From: latestTagCommit.Hash})
+
+	if err != nil {
+		err = fmt.Errorf("[commitlog] Failed to get commits from given hash %v", err)
+		return
+	}
+	defer commitsIter.Close()
+
+	for {
+		c, err := commitsIter.Next()
+
+		if err == io.EOF {
+			break
+		}
+
+		// do not include the last matching commit
+		if previousTagCommit != nil && c.Hash == previousTagCommit.Hash {
+			break
+		}
+
+		commits = append(commits, c)
+	}
+
+	// this will either have commits between 2 tags or all commits if no tags exist
+	g.commitToProcess = commits
+
+	return
+
+}
+
+func (g *Generator) readCommitsInRange() (err error) {
+	// make sure the repo is open
+	g.openRepo()
+
+	var commits []*object.Commit
+	var commitsIter object.CommitIter
+
+	startHash := lib.GetCommitFromString(g.repo, g.startRef)
+	endHash := lib.GetCommitFromString(g.repo, g.endRef)
+
+	if startHash != nil {
+		commitsIter, err = g.repo.Log(&git.LogOptions{From: startHash.Hash})
+	} else {
+		commitsIter, err = g.repo.Log(&git.LogOptions{})
+	}
+
+	if err != nil {
+		err = fmt.Errorf("[commitlog] Failed to get commits from given hash %v", err)
+		return
+	}
+
+	for {
+		c, err := commitsIter.Next()
+
+		if err == io.EOF {
+			break
+		}
+
+		if endHash != nil && c.Hash == endHash.Hash {
+			break
+		}
+
+		commits = append(commits, c)
+	}
+
+	g.commitToProcess = commits
+
+	return
+
+}
+
+// ReadCommmits will try to collect commits in the given range
+// or default to current tag to the previous tag or current commit to
+// recent tag, in the same order of priority
+func (g *Generator) ReadCommmits() (err error) {
+	// make sure the repo is open
+	g.openRepo()
+
+	if len(g.startRef) > 0 || len(g.endRef) > 0 {
+		g.readCommitsInRange()
+	} else {
+		g.readCommitsInTags()
+	}
+
+	return
+}
+
+func (g *Generator) Classify() (err error) {
+	// write the classification using the existing commits
+	if len(g.categories) == 0 {
+		allCommits := []string{}
+
+		for _, commit := range g.commitToProcess {
+			allCommits = append(allCommits, lib.CommitToLog(commit))
+		}
+
+		g.classifiedCommits = []commitClassification{
+			{
+				key:     "All Changes",
+				commits: allCommits,
+			},
+		}
+
+		return
+	}
+
+	for _, catg := range g.categories {
+		rgx, err := regexp.Compile(catg)
+		if err != nil {
+			break
+		}
+
+		catgCommits := []string{}
+
+		for _, commit := range g.commitToProcess {
+			if !rgx.Match([]byte(commit.Message)) {
+				continue
+			}
+
+			catgCommits = append(catgCommits, lib.CommitToLog(commit))
+		}
+
+		g.classifiedCommits = append(g.classifiedCommits, commitClassification{
+			key:     catg,
+			commits: catgCommits,
+		})
+	}
+
+	return
+
+}
+
+func (g *Generator) Generate() (err error) {
+
+	var inMardown strings.Builder
+
+	for _, class := range g.classifiedCommits {
+
+		// title
+		inMardown.Write([]byte("##"))
+		inMardown.Write([]byte(" "))
+		inMardown.Write([]byte(class.key))
+
+		inMardown.Write([]byte("\n"))
+
+		// each commit with 2 returns to separate the long description one's
+		for _, commitMsg := range class.commits {
+			inMardown.Write([]byte(commitMsg))
+			inMardown.Write([]byte("\n\n"))
+		}
+
+	}
+
+	if g.output.stdio {
+		fmt.Println(inMardown.String())
+	}
+
+	if g.output.file {
+		err = os.WriteFile(g.output.filePath, []byte(inMardown.String()), os.ModePerm)
+		if err != nil {
+			return
+		}
+	}
+
+	return
+}
+
+func CreateGenerator(path string, mods ...GeneratorConfigMod) *Generator {
+	generator := &Generator{
+		workingDirectorPath: path,
+	}
+
+	for _, mod := range mods {
+		mod(generator)
+	}
+
+	return generator
+}
+
+func WithPromo() GeneratorConfigMod {
+	return func(g *Generator) {
+		g.addPromo = true
+	}
+}
+
+func WithOutputToFile(filePath string) GeneratorConfigMod {
+	return func(g *Generator) {
+		g.output.file = true
+		g.output.filePath = filePath
+	}
+}
+
+func WithOutputToStdio() GeneratorConfigMod {
+	return func(g *Generator) {
+		g.output.stdio = true
+	}
+}
+
+func WithStartReference(startRef string) GeneratorConfigMod {
+	return func(g *Generator) {
+		g.startRef = startRef
+	}
+}
+
+func WithEndReference(endRef string) GeneratorConfigMod {
+	return func(g *Generator) {
+		g.endRef = endRef
+	}
+}
+
+func WithCategories(categories string) GeneratorConfigMod {
+	return func(g *Generator) {
+		parts := strings.Split(categories, ",")
+		g.categories = parts
+	}
+}

From 6527745e298b4e871f9312ae3ac92c95332a3d63 Mon Sep 17 00:00:00 2001
From: Reaper <ahoy@barelyhuman.dev>
Date: Sat, 11 Jun 2022 17:58:40 +0530
Subject: [PATCH 04/51] chore: remove fluff from older versions

---
 cmd/cmd.go                 |  35 ----
 cmd/commitlog/commitlog.go |  48 -----
 cmd/release/release.go     | 365 -------------------------------------
 log/gitutils.go            |  70 -------
 log/log.go                 | 258 --------------------------
 log/log_test.go            | 176 ------------------
 log/tag_test.go            | 150 ---------------
 logcategory.go             | 120 ------------
 8 files changed, 1222 deletions(-)
 delete mode 100644 cmd/cmd.go
 delete mode 100644 cmd/commitlog/commitlog.go
 delete mode 100644 cmd/release/release.go
 delete mode 100644 log/gitutils.go
 delete mode 100644 log/log.go
 delete mode 100644 log/log_test.go
 delete mode 100644 log/tag_test.go
 delete mode 100644 logcategory.go

diff --git a/cmd/cmd.go b/cmd/cmd.go
deleted file mode 100644
index f3355cf..0000000
--- a/cmd/cmd.go
+++ /dev/null
@@ -1,35 +0,0 @@
-package cmd
-
-import (
-	"os"
-
-	commitlogCmd "github.com/barelyhuman/commitlog/cmd/commitlog"
-	releaseCmd "github.com/barelyhuman/commitlog/cmd/release"
-)
-
-// Init - initializes the commands and also handles the classification
-func Init() {
-
-	// Install the needed commands from the cmd package
-	releaseCmd.Install()
-	commitlogCmd.Install()
-
-	// Classify which command to run, also pass the arguments to the command to parse
-	if len(os.Args) > 1 {
-		switch os.Args[1] {
-		case "release":
-			{
-				releaseCmd.Run(os.Args[2:])
-				return
-			}
-		case "log":
-			{
-				commitlogCmd.Run(os.Args[2:])
-				return
-			}
-		}
-	}
-
-	// Default Command, parse all flags
-	commitlogCmd.Run(os.Args[1:])
-}
diff --git a/cmd/commitlog/commitlog.go b/cmd/commitlog/commitlog.go
deleted file mode 100644
index 2ae44ce..0000000
--- a/cmd/commitlog/commitlog.go
+++ /dev/null
@@ -1,48 +0,0 @@
-package commitlog
-
-import (
-	"flag"
-	"fmt"
-	"log"
-
-	clog "github.com/barelyhuman/commitlog/log"
-)
-
-var clogCmd *flag.FlagSet
-var repoPath *string
-var startCommit *string
-var endCommit *string
-var inclusionFlags *string
-var skipClassification *bool
-var addPromotional *bool
-
-// Install - add flags and other options
-func Install() {
-	clogCmd = flag.NewFlagSet("commitlog", flag.ExitOnError)
-	repoPath = clogCmd.String("p", ".", "path to the repository, points to the current working directory by default")
-	startCommit = clogCmd.String("s", "", "commit hash string / revision (ex. HEAD, HEAD^, HEAD~2) \n to start collecting commit messages from")
-	endCommit = clogCmd.String("e", "", "commit hash string / revision (ex. HEAD, HEAD^, HEAD~2) \n to stop collecting commit message at")
-	inclusionFlags = clogCmd.String("i", clog.SupportedKeys, "commit types to be includes")
-	skipClassification = clogCmd.Bool("skip", false, "if enabled will skip trying to classify and just give a list of changes")
-	addPromotional = clogCmd.Bool("promo", false, "if enabled will add a \"generated by\" promotional tag to the changelog ")
-}
-
-// Run - execute the command
-func Run(args []string) {
-
-	err := clogCmd.Parse(args)
-
-	if err != nil {
-		log.Fatalln(err)
-	}
-
-	currentRepository := clog.OpenRepository(*repoPath)
-
-	changelog, clogErr := clog.CommitLog(currentRepository, *startCommit, *endCommit, *inclusionFlags, *skipClassification, *addPromotional)
-
-	if clogErr.Err != nil {
-		log.Fatal(clogErr.Message, clogErr.Err)
-	}
-
-	fmt.Println(changelog)
-}
diff --git a/cmd/release/release.go b/cmd/release/release.go
deleted file mode 100644
index 978ccab..0000000
--- a/cmd/release/release.go
+++ /dev/null
@@ -1,365 +0,0 @@
-package release
-
-import (
-	"flag"
-	"fmt"
-	"io/fs"
-	"os"
-	"strconv"
-	"strings"
-
-	clog "github.com/barelyhuman/commitlog/log"
-	"github.com/fatih/color"
-	"github.com/go-git/go-git/v5"
-
-	survey "github.com/AlecAivazis/survey/v2"
-)
-
-var (
-	releaseCmd *flag.FlagSet
-	major      *bool
-	minor      *bool
-	patch      *bool
-	beta       *bool
-	betaSuffix *string
-)
-
-const configFileName = ".commitlog.release"
-
-var semverPrompt = &survey.Select{
-	Message: "Choose a semver version (choose none for prerelease/beta increments):",
-	Options: []string{"major", "minor", "patch", "none"},
-	Default: "none",
-}
-
-var betaPrompt = &survey.Confirm{
-	Message: "Is it a beta release?",
-}
-
-var betaSuffixPrompt = &survey.Input{
-	Message: "Enter the exiting beta suffix (if any) (eg: beta or dev or canary) :",
-	Default: "",
-}
-
-var confirmCreation = &survey.Confirm{
-	Message: "Do you want me to create a commit for the new version?:",
-}
-
-type Config struct {
-	version *TagVersion
-}
-
-// TagVersion - struct holding the broken down tag
-type TagVersion struct {
-	major       int64
-	minor       int64
-	patch       int64
-	beta        bool
-	betaSuffix  string
-	betaVersion int64
-}
-
-// Install - add flags and other options
-func Install() {
-	releaseCmd = flag.NewFlagSet("release", flag.ExitOnError)
-	major = releaseCmd.Bool("major", false, "If release is a *major* one, will increment the x.0.0 ")
-	minor = releaseCmd.Bool("minor", false, "If release is a *minor* one, will increment the 0.x.0 ")
-	patch = releaseCmd.Bool("patch", false, "If release is a *patch*, will increment the 0.0.x ")
-	beta = releaseCmd.Bool("beta", false, "If the release is a beta/prerelease")
-	betaSuffix = releaseCmd.String("beta-suffix", "", "If the release is a beta, to add/increment tag with `-beta.x` or mentioned string")
-}
-
-func bail(err error) {
-	if err != nil {
-		fail(err.Error())
-		panic(1)
-	}
-}
-
-func bullet(msg string) {
-	color.New(color.FgWhite).Add(color.Bold).Println(msg)
-}
-
-func fail(msg string) {
-	color.New(color.FgRed).Add(color.Bold).Println(msg)
-}
-
-func success(msg string) {
-	color.New(color.FgGreen).Add(color.Bold).Println(msg)
-}
-
-func dim(msg string) {
-	color.White(msg)
-}
-
-// Run - execute the command
-func Run(args []string) {
-
-	err := releaseCmd.Parse(args)
-
-	bail(err)
-
-	isInitialised, err := checkReleaseInit()
-	bail(err)
-
-	if !isInitialised {
-		bullet("Initializing Commitlog Release")
-		err := initialiseRelease()
-		bail(err)
-		success("Created, .commitlog.release")
-		dim("Please, modify the file to match the current latest version or leave it as is if starting with a new project")
-	}
-
-	config, err := readConfigFile()
-	bail(err)
-
-	askQuestions(args)
-
-	err = createRelease(config, *major, *minor, *patch, *beta, *betaSuffix)
-
-	bail(err)
-}
-
-// checkReleaseInit - check if release was already initialised in the particular folder, if not, it'll return false
-func checkReleaseInit() (bool, error) {
-	files, err := os.ReadDir(".")
-	if err != nil {
-		return false, err
-	}
-
-	hasConfigFile := false
-
-	for _, file := range files {
-		if file.Name() == configFileName {
-			hasConfigFile = true
-		}
-	}
-
-	return hasConfigFile, nil
-}
-
-// initialiseRelease - create the .commitlog.release file in the current folder
-// TODO: need to add a question before doing so
-func initialiseRelease() error {
-	err := os.WriteFile(configFileName, []byte("0.0.0"), os.ModePerm)
-	return err
-}
-
-// readConfigFile - read the file and parse it as a config, limited to version details for now
-func readConfigFile() (Config, error) {
-	config := Config{}
-	dataInBytes, err := os.ReadFile(configFileName)
-	if err != nil {
-		return config, err
-	}
-
-	asString := string(dataInBytes)
-
-	success("Current Version:")
-	bullet(asString)
-
-	version, _ := breakTag(asString)
-
-	config.version = version
-
-	return config, nil
-}
-
-// createRelease - create a release based on the read config and given parameters
-func createRelease(config Config, incMajor bool, incMinor bool, incPatch bool, incBeta bool, betaSuffixString string) error {
-	updatedVersion := TagVersion{
-		major:       config.version.major,
-		minor:       config.version.minor,
-		patch:       config.version.patch,
-		beta:        incBeta,
-		betaSuffix:  betaSuffixString,
-		betaVersion: config.version.betaVersion,
-	}
-
-	resetBeta := false
-
-	if incMajor {
-		updatedVersion.major++
-		updatedVersion.minor = 0
-		updatedVersion.patch = 0
-		resetBeta = true
-	}
-
-	if incMinor {
-		updatedVersion.minor++
-		updatedVersion.patch = 0
-		resetBeta = true
-	}
-
-	if incPatch {
-		updatedVersion.patch++
-		resetBeta = true
-	}
-
-	updatedVersionString := fmt.Sprintf("v%v.%v.%v", updatedVersion.major, updatedVersion.minor, updatedVersion.patch)
-
-	if updatedVersion.beta {
-		if resetBeta {
-			updatedVersion.betaVersion = 0
-		} else {
-			updatedVersion.betaVersion++
-		}
-
-		var sb strings.Builder
-
-		if len(updatedVersion.betaSuffix) > 1 {
-			sb.WriteString(updatedVersionString + fmt.Sprintf("-%v.", updatedVersion.betaSuffix))
-		} else {
-			sb.WriteString(updatedVersionString + "-")
-		}
-		sb.WriteString(fmt.Sprintf("%v", updatedVersion.betaVersion))
-		updatedVersionString = sb.String()
-	}
-
-	success("New Version")
-	bullet(updatedVersionString)
-
-	var confirmed bool
-
-	survey.AskOne(confirmCreation, &confirmed)
-
-	if !confirmed {
-		fail("✖ Cancelled")
-		return nil
-	}
-
-	err := writeUpdatedVersion(updatedVersionString)
-	if err != nil {
-		return err
-	}
-
-	success("✔ Updated Version")
-
-	return nil
-}
-
-func writeUpdatedVersion(versionString string) error {
-	err := os.WriteFile(configFileName, []byte(versionString), fs.ModePerm)
-	if err != nil {
-		return err
-	}
-
-	err = createCommit(versionString)
-	return err
-}
-
-func createCommit(versionString string) error {
-	repo := clog.OpenRepository(".")
-
-	wt, err := repo.Worktree()
-	if err != nil {
-		return err
-	}
-
-	_, err = wt.Add(configFileName)
-	if err != nil {
-		return err
-	}
-
-	commit, err := wt.Commit(versionString, &git.CommitOptions{})
-	if err != nil {
-		return err
-	}
-
-	_, err = repo.CreateTag(versionString, commit, &git.CreateTagOptions{
-		Message: versionString,
-	})
-
-	return err
-}
-
-// askQuestions - Check semver and beta if no args were supplied
-func askQuestions(args []string) error {
-	var semver string
-
-	if len(args) < 1 {
-		err := survey.AskOne(semverPrompt, &semver)
-
-		if err != nil {
-			return err
-		}
-
-		err = survey.AskOne(betaPrompt, beta)
-
-		if err != nil {
-			return err
-		}
-
-		if *beta {
-			err = survey.AskOne(betaSuffixPrompt, betaSuffix)
-			if err != nil {
-				return err
-			}
-		}
-
-		switch semver {
-		case "major":
-			{
-				*major = true
-				break
-			}
-		case "minor":
-			{
-				*minor = true
-				break
-			}
-		case "patch":
-			{
-				*patch = true
-				break
-			}
-		}
-	}
-
-	return nil
-}
-
-// breakTag - break the given semver version string into proper version values, does support breaking semver pre-release strings
-func breakTag(tagString string) (*TagVersion, bool) {
-	hasV := false
-	version := &TagVersion{}
-	tagSplits := strings.Split(tagString, ".")
-
-	majorStringSplit := strings.Split(tagSplits[0], "")
-
-	if len(majorStringSplit) > 1 {
-		hasV = true
-		major, err := strconv.ParseInt(majorStringSplit[1], 10, 32)
-		bail(err)
-		version.major = major
-	} else {
-		major, err := strconv.ParseInt(majorStringSplit[0], 10, 32)
-		bail(err)
-		version.major = major
-	}
-
-	minor, err := strconv.ParseInt(tagSplits[1], 10, 32)
-	bail(err)
-	version.minor = minor
-
-	if len(tagSplits) > 3 {
-		version.beta = true
-		betaV, err := strconv.ParseInt(tagSplits[3], 10, 32)
-		bail(err)
-		version.betaVersion = betaV
-	} else {
-		version.betaVersion = -1
-	}
-
-	patchStringSplit := strings.Split(tagSplits[2], "-")
-
-	patch, err := strconv.ParseInt(patchStringSplit[0], 10, 32)
-	bail(err)
-	version.patch = patch
-
-	if len(patchStringSplit) > 1 {
-		version.betaSuffix = patchStringSplit[1]
-	}
-
-	return version, hasV
-}
diff --git a/log/gitutils.go b/log/gitutils.go
deleted file mode 100644
index 0981e78..0000000
--- a/log/gitutils.go
+++ /dev/null
@@ -1,70 +0,0 @@
-// SPDX-License-Identifier: MIT
-
-package commitlog
-
-import (
-	"log"
-	"strings"
-
-	"github.com/go-git/go-git/v5"
-	"github.com/go-git/go-git/v5/plumbing"
-	"github.com/go-git/go-git/v5/plumbing/object"
-)
-
-func IsHashATag(currentRepository *git.Repository, hash plumbing.Hash) bool {
-	isTag := false
-	tags, _ := currentRepository.Tags()
-	tags.ForEach(func(tagRef *plumbing.Reference) error {
-		revHash, err := currentRepository.ResolveRevision(plumbing.Revision(tagRef.Name()))
-		if err != nil {
-			return err
-		}
-		if *revHash == hash {
-			isTag = true
-		}
-		return nil
-	})
-	return isTag
-}
-
-// normalizeCommit - reduces the commit message to the first line and ignore the description text of the commit
-func normalizeCommit(commitMessage string, key string) string {
-	var message string
-	for i, msg := range strings.Split(commitMessage, "\n") {
-		if i == 0 {
-			message = msg
-			break
-		}
-	}
-
-	removedPrefix := strings.TrimPrefix(strings.TrimSuffix(message, "\n"), key)
-	return strings.TrimSpace(strings.TrimSuffix(removedPrefix, "\n"))
-}
-
-// OpenRepository - open the git repository and return repository reference
-func OpenRepository(path string) *git.Repository {
-	r, err := git.PlainOpen(path)
-	if err != nil {
-		log.Fatal("Error opening Repository: ", err)
-	}
-
-	return r
-}
-
-// GetCommitFromString - get commit from hash string
-func GetCommitFromString(commitString string, repo *git.Repository) *object.Commit {
-	if commitString == "" {
-		return nil
-	}
-
-	hash, err := repo.ResolveRevision(plumbing.Revision(commitString))
-	if err != nil {
-		log.Fatal("Unable to get Repo head:", err)
-	}
-
-	commitRef, err := repo.CommitObject(*hash)
-	if err != nil {
-		log.Fatal("Unable to get resolve commit:", err)
-	}
-	return commitRef
-}
diff --git a/log/log.go b/log/log.go
deleted file mode 100644
index 0061b27..0000000
--- a/log/log.go
+++ /dev/null
@@ -1,258 +0,0 @@
-// SPDX-License-Identifier: MIT
-
-package commitlog
-
-import (
-	"bytes"
-	"fmt"
-	"regexp"
-	"strings"
-
-	"github.com/go-git/go-git/v5"
-	"github.com/go-git/go-git/v5/plumbing/object"
-)
-
-// SupportedKeys - keys that are supported by the package
-const SupportedKeys = "ci|refactor|docs|fix|feat|test|chore|other"
-
-// ErrMessage - simple interface around error with a custom message
-type ErrMessage struct {
-	Message string
-	Err     error
-}
-
-type commitTypeInclusions [][]byte
-
-// logContainer - Container of log strings
-type logContainer struct {
-	include bool
-	commits []string
-}
-
-// logsByCategory - Type to hold logs by each's category
-// to be left as ALLCAPS to be considered as symbols instead of selectors
-type logsByCategory struct {
-	CI           logContainer
-	FIX          logContainer
-	REFACTOR     logContainer
-	FEATURE      logContainer
-	DOCS         logContainer
-	CHORE        logContainer
-	TEST         logContainer
-	OTHER        logContainer
-	UNCLASSIFIED logContainer
-}
-
-// Setup - Initialize all Log Containers
-func (logs logsByCategory) Setup() {
-	logs.CI.include = true
-	logs.FIX.include = true
-	logs.REFACTOR.include = true
-	logs.FEATURE.include = true
-	logs.DOCS.include = true
-	logs.CHORE.include = true
-	logs.TEST.include = true
-	logs.OTHER.include = true
-	logs.UNCLASSIFIED.include = true
-}
-
-// printLog - loops through the collected logs to write them to string builder
-func (container logContainer) printLog(out *strings.Builder, title string, skipped bool) {
-	if !container.include {
-		return
-	}
-	if len(container.commits) > 0 {
-		if !skipped {
-			out.WriteString(fmt.Sprintf("\n\n## %s  \n", title))
-		}
-		for _, item := range container.commits {
-			out.WriteString(item + "  \n")
-		}
-	}
-}
-
-// ToMarkdown - Generate markdown output for the collected commits
-func (logs *logsByCategory) ToMarkdown(skipped bool) string {
-	var markdownString strings.Builder
-
-	if !skipped {
-		logs.FEATURE.printLog(&markdownString, "Features", skipped)
-		logs.FIX.printLog(&markdownString, "Fixes", skipped)
-		logs.REFACTOR.printLog(&markdownString, "Performance", skipped)
-		logs.CI.printLog(&markdownString, "CI", skipped)
-		logs.DOCS.printLog(&markdownString, "Docs", skipped)
-		logs.CHORE.printLog(&markdownString, "Chores", skipped)
-		logs.TEST.printLog(&markdownString, "Tests", skipped)
-		logs.OTHER.printLog(&markdownString, "Other Changes", skipped)
-	} else {
-		logs.UNCLASSIFIED.include = true
-		logs.UNCLASSIFIED.printLog(&markdownString, "Unclassified Changes", skipped)
-	}
-
-	return markdownString.String()
-}
-
-// AddCommit - Add a commit to the needed logContainer based on skip and include flag
-func (logs *logsByCategory) AddCommit(key, commitHash string, skip bool) {
-	addCommitToContainer := logs.findContainerByKey(key)
-	if !addCommitToContainer.canAddToContainer(skip) {
-		addCommitToContainer = &logs.UNCLASSIFIED
-	}
-	if addCommitToContainer != nil {
-		addCommitToContainer.commits = append(addCommitToContainer.commits, commitHash)
-	}
-}
-
-func (logs *logsByCategory) findContainerByKey(key string) *logContainer {
-	switch key {
-	case "ci":
-		return &logs.CI
-	case "fix":
-		return &logs.FIX
-	case "refactor":
-		return &logs.REFACTOR
-	case "feat", "feature":
-		return &logs.FEATURE
-	case "docs":
-		return &logs.DOCS
-	case "test":
-		return &logs.TEST
-	case "chore":
-		return &logs.CHORE
-	default:
-		return &logs.OTHER
-	}
-}
-
-func (container *logContainer) canAddToContainer(skip bool) bool {
-	if container.include && !skip {
-		return true
-	} else if skip && container.include {
-		return false
-	}
-	return true
-}
-
-// CommitLog - Generate commit log
-func CommitLog(currentRepository *git.Repository, startCommitString string, endCommitString string, inclusionFlags string, skipClassification bool, addPromotional bool) (string, ErrMessage) {
-	baseCommitReference, err := currentRepository.Head()
-	var startHash, endHash *object.Commit
-	var cIter object.CommitIter
-
-	if err != nil {
-		return "", ErrMessage{"Unable to get repository HEAD, are you sure you are in a git repository? Error:", err}
-	}
-
-	startHash = GetCommitFromString(startCommitString, currentRepository)
-	endHash = GetCommitFromString(endCommitString, currentRepository)
-	isHeadTag := false
-
-	if startHash != nil {
-		cIter, err = currentRepository.Log(&git.LogOptions{From: startHash.Hash})
-	} else {
-		if IsHashATag(currentRepository, baseCommitReference.Hash()) {
-			isHeadTag = true
-		}
-		cIter, err = currentRepository.Log(&git.LogOptions{From: baseCommitReference.Hash()})
-	}
-
-	if err != nil {
-		return "", ErrMessage{"Unable to get repository commits:", err}
-	}
-
-	var commits []*object.Commit
-
-	var latestTag *object.Commit
-	var previousTag *object.Commit
-	tagAssignment := 0
-
-	err = cIter.ForEach(func(c *object.Commit) error {
-		commits = append(commits, c)
-		if isHeadTag && tagAssignment == 0 && latestTag == nil && c.Hash == baseCommitReference.Hash() {
-			latestTag = c
-			tagAssignment += 1
-
-		} else if IsHashATag(currentRepository, c.Hash) {
-			if latestTag == nil && tagAssignment == 0 {
-				latestTag = c
-				tagAssignment += 1
-			}
-			if previousTag == nil && tagAssignment == 1 {
-				previousTag = c
-				tagAssignment += 1
-			}
-		}
-		return nil
-	})
-
-	if err != nil {
-		return "", ErrMessage{"Error getting commits : ", err}
-	}
-
-	var inclusions commitTypeInclusions
-	inclusions = append(inclusions, bytes.SplitN([]byte(inclusionFlags), []byte("|"), -1)...)
-	inclusions = append(inclusions, bytes.SplitN([]byte(inclusionFlags), []byte(","), -1)...)
-	logContainer := logsByCategory{}
-
-	logContainer.Setup()
-
-	logContainer.CI.include = inclusions.checkInclusion("ci")
-	logContainer.FIX.include = inclusions.checkInclusion("fix")
-	logContainer.REFACTOR.include = inclusions.checkInclusion("refactor")
-	logContainer.FEATURE.include = inclusions.checkInclusion("feat")
-	logContainer.DOCS.include = inclusions.checkInclusion("docs")
-	logContainer.CHORE.include = inclusions.checkInclusion("chore")
-	logContainer.TEST.include = inclusions.checkInclusion("test")
-	logContainer.OTHER.include = inclusions.checkInclusion("other")
-
-	for _, c := range commits {
-		key, scopedKey := findKeyInCommit(SupportedKeys, c.Message)
-		key = strings.SplitN(strings.TrimSpace(key), ":", 2)[0]
-		normalizedHash := c.Hash.String() + " - " + normalizeCommit(c.Message, scopedKey)
-
-		if endHash == nil && previousTag != nil && previousTag.Hash == c.Hash {
-			break
-		} else if endHash != nil && c.Hash == endHash.Hash {
-			break
-		}
-
-		logContainer.AddCommit(key, normalizedHash, skipClassification)
-
-	}
-
-	changeLogText := logContainer.ToMarkdown(skipClassification) + "\n"
-
-	if addPromotional {
-		changeLogText += "generated by [commitlog](https://github.com/commitlog)"
-	}
-
-	return changeLogText, ErrMessage{}
-}
-
-func (inclusions *commitTypeInclusions) checkInclusion(flagToCheck string) bool {
-	if inclusions != nil {
-		for _, flag := range *inclusions {
-			if string(flag) == flagToCheck {
-				return true
-			}
-		}
-	}
-	return false
-}
-
-func findKeyInCommit(key string, commitMessage string) (string, string) {
-	re := regexp.MustCompile(`^(` + key + `)[:]|^((` + key + `)\((\w+[, /\\]*)+\)[:])`)
-	keyMatches := re.FindAllStringSubmatch(commitMessage, -1)
-	if len(keyMatches) == 0 {
-		return "", ""
-	}
-
-	scopedKey := keyMatches[0][0]
-	scopelessKey := keyMatches[0][3]
-
-	if scopelessKey == "" {
-		scopelessKey = keyMatches[0][1]
-	}
-
-	return scopelessKey, scopedKey
-}
diff --git a/log/log_test.go b/log/log_test.go
deleted file mode 100644
index 6a200ff..0000000
--- a/log/log_test.go
+++ /dev/null
@@ -1,176 +0,0 @@
-package commitlog
-
-import (
-	"log"
-	"strings"
-	"testing"
-	"time"
-
-	"github.com/go-git/go-billy/v5/memfs"
-	"github.com/go-git/go-git/v5"
-	"github.com/go-git/go-git/v5/plumbing/object"
-	"github.com/go-git/go-git/v5/storage/memory"
-)
-
-var testCommits []string = []string{
-	"fix: fix commit",
-	"feat: feat commit",
-	"docs: doc update commit",
-	"chore: chore commit",
-	"other commit",
-}
-
-var expectedCommits []string
-
-func bail(err error) {
-	if err != nil {
-		log.Panic(err)
-	}
-}
-
-func setup() *git.Repository {
-	var fs = memfs.New()
-	repo, _ := git.Init(memory.NewStorage(), fs)
-	wt, err := repo.Worktree()
-	bail(err)
-
-	for _, testCommitMsg := range testCommits {
-		commit, err := wt.Commit(testCommitMsg, &git.CommitOptions{
-			Author: &object.Signature{
-				Name:  "Reaper",
-				Email: "ahoy@barelyhuman.dev",
-				When:  time.Now(),
-			},
-		})
-		bail(err)
-		expectedCommits = append(expectedCommits, commit.String())
-	}
-
-	return repo
-}
-
-var repo *git.Repository = setup()
-
-func TestCommitLogDefault(t *testing.T) {
-
-	log, _ := CommitLog(repo, "", "", SupportedKeys, false, false)
-	if log == "" {
-		t.Fail()
-	}
-
-	for _, commit := range expectedCommits {
-		if !strings.Contains(log, commit) {
-			t.Fail()
-		}
-	}
-
-	t.Log(log)
-
-}
-
-func TestCommitLogSkipped(t *testing.T) {
-
-	log, _ := CommitLog(repo, "", "", SupportedKeys, true, false)
-	if log == "" {
-		t.Fail()
-	}
-
-	for _, commit := range expectedCommits {
-		// Shouldn't contain classification headings
-		if strings.Contains(log, "##") {
-			t.Fail()
-		}
-
-		if !strings.Contains(log, commit) {
-			t.Fail()
-		}
-	}
-
-	t.Log(log)
-}
-
-func TestCommitLogInclusions(t *testing.T) {
-
-	// include only feature commits
-	log, _ := CommitLog(repo, "", "", "feat", true, false)
-	if log == "" {
-		t.Fail()
-	}
-
-	ignoredHeadings := []string{
-		"## Fixes",
-		"## Performance",
-		"## CI",
-		"## Docs",
-		"## Chores",
-		"## Tests",
-		"## Other Changes",
-	}
-
-	for _, heading := range ignoredHeadings {
-		if strings.Contains(log, heading) {
-			t.Fail()
-		}
-	}
-
-	t.Log(log)
-}
-
-func TestCommitLogStartHash(t *testing.T) {
-
-	expectedCommitsLen := len(expectedCommits)
-	startCommitHash := expectedCommits[expectedCommitsLen-2]
-	lastCommit := expectedCommits[expectedCommitsLen-1]
-	acceptedCommitHashes := expectedCommits[0 : expectedCommitsLen-1]
-
-	t.Log("Commits: ", expectedCommits)
-	t.Log("Start At:", startCommitHash)
-
-	log, _ := CommitLog(repo, startCommitHash, "", SupportedKeys, true, false)
-	if log == "" {
-		t.Fail()
-	}
-
-	// should have all commits except the last one
-	if strings.Contains(log, lastCommit) {
-		t.Fail()
-	}
-
-	for _, commitHash := range acceptedCommitHashes {
-		if !strings.Contains(log, commitHash) {
-			t.Log("Failed at:", commitHash)
-			t.Fail()
-		}
-	}
-
-	t.Log("\n", log)
-}
-
-func TestCommitLogEndHash(t *testing.T) {
-
-	endCommitHash := expectedCommits[1]
-	firstCommit := expectedCommits[0]
-	acceptedCommitHashes := expectedCommits[2:]
-
-	t.Log("Commits: ", expectedCommits)
-	t.Log("End At:", endCommitHash)
-
-	log, _ := CommitLog(repo, "", endCommitHash, SupportedKeys, true, false)
-	if log == "" {
-		t.Fail()
-	}
-
-	// should have all commits except the first one
-	if strings.Contains(log, firstCommit) {
-		t.Fail()
-	}
-
-	for _, commitHash := range acceptedCommitHashes {
-		if !strings.Contains(log, commitHash) {
-			t.Log("Failed at:", commitHash)
-			t.Fail()
-		}
-	}
-
-	t.Log("\n", log)
-}
diff --git a/log/tag_test.go b/log/tag_test.go
deleted file mode 100644
index 1f2be66..0000000
--- a/log/tag_test.go
+++ /dev/null
@@ -1,150 +0,0 @@
-package commitlog
-
-import (
-	"strings"
-	"testing"
-	"time"
-
-	"github.com/go-git/go-git/v5"
-	"github.com/go-git/go-git/v5/plumbing"
-	"github.com/go-git/go-git/v5/plumbing/object"
-)
-
-func getTagOptions(message string) *git.CreateTagOptions {
-	return &git.CreateTagOptions{
-		Message: message,
-		Tagger: &object.Signature{
-			Name:  "Test",
-			Email: "test@reaper.im",
-			When:  time.Now(),
-		},
-	}
-
-}
-
-func TestCommitLogSingleTag(t *testing.T) {
-	secondCommit := expectedCommits[1]
-	acceptedCommits := expectedCommits[2:]
-
-	t.Log("Commits:", expectedCommits)
-	t.Log("Tagged:", secondCommit)
-
-	hash, err := repo.ResolveRevision(plumbing.Revision(secondCommit))
-	bail(err)
-
-	_, err = repo.CreateTag("0.0.0", *hash, getTagOptions("0.0.0"))
-	bail(err)
-
-	log, _ := CommitLog(repo, "", "", SupportedKeys, true, false)
-	if log == "" {
-		t.Fail()
-	}
-
-	if strings.Contains(log, expectedCommits[0]) {
-		t.Fail()
-	}
-
-	for _, commit := range acceptedCommits {
-		if !strings.Contains(log, commit) {
-			t.Fail()
-		}
-	}
-
-	t.Log(log)
-
-	// clean-up
-	bail(repo.DeleteTag("0.0.0"))
-
-}
-
-// Test with 2 tags, one on the second commit and one on the 2nd last commit,
-// should only have the last commit in the log
-func TestCommitLogDualTag(t *testing.T) {
-	secondCommit := expectedCommits[1]
-	secondLastCommit := expectedCommits[len(expectedCommits)-2]
-	acceptedCommit := expectedCommits[len(expectedCommits)-1]
-
-	t.Log("Commits:", expectedCommits)
-	t.Log("Tagged:", secondCommit, secondLastCommit)
-
-	secondHash, err := repo.ResolveRevision(plumbing.Revision(secondCommit))
-	bail(err)
-
-	secondLastHash, err := repo.ResolveRevision(plumbing.Revision(secondLastCommit))
-	bail(err)
-
-	_, err = repo.CreateTag("0.0.0", *secondHash, getTagOptions("0.0.0"))
-	bail(err)
-
-	_, err = repo.CreateTag("0.0.1", *secondLastHash, getTagOptions("0.0.1"))
-	bail(err)
-
-	log, _ := CommitLog(repo, "", "", SupportedKeys, true, false)
-	if log == "" {
-		t.Fail()
-	}
-
-	for _, commit := range expectedCommits {
-		if commit == acceptedCommit {
-			if !strings.Contains(log, acceptedCommit) {
-				t.Fail()
-			}
-		} else {
-			if strings.Contains(log, commit) {
-				t.Fail()
-			}
-		}
-
-	}
-
-	t.Log(log)
-
-	// clean-up
-	bail(repo.DeleteTag("0.0.0"))
-	bail(repo.DeleteTag("0.0.1"))
-}
-
-// Test with 2 tags, one on the second commit and one on the last commit,
-// should give all commits till the 1st tag
-func TestCommitLogHeadTag(t *testing.T) {
-	secondCommit := expectedCommits[1]
-	lastCommit := expectedCommits[len(expectedCommits)-1]
-
-	t.Log("Commits:", expectedCommits)
-	t.Log("Tagged:", secondCommit, lastCommit)
-
-	secondHash, err := repo.ResolveRevision(plumbing.Revision(secondCommit))
-	bail(err)
-
-	lastHash, err := repo.ResolveRevision(plumbing.Revision(lastCommit))
-	bail(err)
-
-	_, err = repo.CreateTag("0.0.0", *secondHash, getTagOptions("0.0.0"))
-	bail(err)
-
-	_, err = repo.CreateTag("0.0.1", *lastHash, getTagOptions("0.0.1"))
-	bail(err)
-
-	log, _ := CommitLog(repo, "", "", SupportedKeys, true, false)
-	if log == "" {
-		t.Fail()
-	}
-
-	for index, commit := range expectedCommits {
-		if index <= 1 {
-			if strings.Contains(log, commit) {
-				t.Fail()
-			}
-		}
-		if index > 1 && !strings.Contains(log, commit) {
-			t.Fail()
-		}
-
-	}
-
-	t.Log(log)
-
-	// clean-up
-	bail(repo.DeleteTag("0.0.0"))
-	bail(repo.DeleteTag("0.0.1"))
-}
diff --git a/logcategory.go b/logcategory.go
deleted file mode 100644
index eb96716..0000000
--- a/logcategory.go
+++ /dev/null
@@ -1,120 +0,0 @@
-// SPDX-License-Identifier: MIT
-
-package main
-
-import (
-	"fmt"
-	"strings"
-)
-
-// logContainer - Container of log strings
-type logContainer struct {
-	include bool
-	commits []string
-}
-
-// logsByCategory - Type to hold logs by each's category
-// to be left as ALLCAPS to be considered as symbols instead of selectors
-type logsByCategory struct {
-	CI           logContainer
-	FIX          logContainer
-	REFACTOR     logContainer
-	FEATURE      logContainer
-	DOCS         logContainer
-	CHORE        logContainer
-	TEST         logContainer
-	OTHER        logContainer
-	UNCLASSIFIED logContainer
-}
-
-// Setup - Initialize all Log Containers
-func (logs logsByCategory) Setup() {
-	logs.CI.include = true
-	logs.FIX.include = true
-	logs.REFACTOR.include = true
-	logs.FEATURE.include = true
-	logs.DOCS.include = true
-	logs.CHORE.include = true
-	logs.TEST.include = true
-	logs.OTHER.include = true
-	logs.UNCLASSIFIED.include = true
-}
-
-// printLog - loops through the collected logs to write them to string builder
-func (container logContainer) printLog(out *strings.Builder, title string, skipped bool) {
-	if !container.include {
-		return
-	}
-	if len(container.commits) > 0 {
-		if !skipped {
-			out.WriteString(fmt.Sprintf("\n\n## %s  \n", title))
-		}
-		for _, item := range container.commits {
-			out.WriteString(item + "\n")
-		}
-	}
-}
-
-// ToMarkdown - Generate markdown output for the collected commits
-func (logs *logsByCategory) ToMarkdown(skipped bool) string {
-	var markdownString strings.Builder
-
-	markdownString.WriteString("# Changelog \n")
-
-	if !skipped {
-		logs.FEATURE.printLog(&markdownString, "Features", skipped)
-		logs.FIX.printLog(&markdownString, "Fixes", skipped)
-		logs.REFACTOR.printLog(&markdownString, "Performance", skipped)
-		logs.CI.printLog(&markdownString, "CI", skipped)
-		logs.DOCS.printLog(&markdownString, "Docs", skipped)
-		logs.CHORE.printLog(&markdownString, "Chores", skipped)
-		logs.TEST.printLog(&markdownString, "Tests", skipped)
-		logs.OTHER.printLog(&markdownString, "Other Changes", skipped)
-	} else {
-		logs.UNCLASSIFIED.include = true
-		logs.UNCLASSIFIED.printLog(&markdownString, "Unclassified Changes", skipped)
-	}
-
-	return markdownString.String()
-}
-
-// AddCommit - Add a commit to the needed logContainer based on skip and include flag
-func (logs *logsByCategory) AddCommit(key, commitHash string, skip bool) {
-	addCommitToContainer := logs.findContainerByKey(key)
-	if !addCommitToContainer.canAddToContainer(skip) {
-		addCommitToContainer = &logs.UNCLASSIFIED
-	}
-	if addCommitToContainer != nil {
-		addCommitToContainer.commits = append(addCommitToContainer.commits, commitHash)
-	}
-}
-
-func (logs *logsByCategory) findContainerByKey(key string) *logContainer {
-	switch key {
-	case "ci":
-		return &logs.CI
-	case "fix":
-		return &logs.FIX
-	case "refactor":
-		return &logs.REFACTOR
-	case "feat", "feature":
-		return &logs.FEATURE
-	case "docs":
-		return &logs.DOCS
-	case "test":
-		return &logs.TEST
-	case "chore":
-		return &logs.CHORE
-	default:
-		return &logs.OTHER
-	}
-}
-
-func (container *logContainer) canAddToContainer(skip bool) bool {
-	if container.include && !skip {
-		return true
-	} else if skip && container.include {
-		return false
-	}
-	return true
-}

From 9080580575d3579b3d11dd114830eb128f0c8130 Mon Sep 17 00:00:00 2001
From: Reaper <ahoy@barelyhuman.dev>
Date: Fri, 24 Jun 2022 11:46:40 +0530
Subject: [PATCH 05/51] feat: releaser base maj,min,patch setup

---
 commands/release.go |  55 ++++++++++++++-
 go.mod              |   4 +-
 go.sum              |  34 +++-------
 main.go             |   2 +-
 pkg/generator.go    |  50 ++++++++------
 pkg/releaser.go     | 160 ++++++++++++++++++++++++++++++++++++++++++++
 6 files changed, 252 insertions(+), 53 deletions(-)
 create mode 100644 pkg/releaser.go

diff --git a/commands/release.go b/commands/release.go
index 7a4bebf..41968cb 100644
--- a/commands/release.go
+++ b/commands/release.go
@@ -1,7 +1,58 @@
 package commands
 
-import "github.com/urfave/cli/v2"
+import (
+	"fmt"
+	"os"
+
+	"github.com/barelyhuman/commitlog/pkg"
+	"github.com/urfave/cli/v2"
+)
 
 func Release(c *cli.Context) (err error) {
-	return
+
+	_, err = os.ReadFile(".commitlog.release")
+
+	if os.IsNotExist(err) {
+		err = fmt.Errorf("couldn't find the release file, please run the `--init` flag first")
+		return
+	}
+
+	fileData, err := os.ReadFile(".commitlog.release")
+
+	if err != nil {
+		err = fmt.Errorf("error reading the version file: %v", err)
+		return err
+	}
+
+	versionString := string(fileData)
+
+	releaserOpts := []pkg.ReleaserMod{}
+
+	if c.Bool("major") {
+		releaserOpts = append(releaserOpts, pkg.WithMajorIncrement(), pkg.WithMinorReset(), pkg.WithPatchReset())
+	}
+
+	if c.Bool("minor") {
+		releaserOpts = append(releaserOpts, pkg.WithMinorIncrement(), pkg.WithPatchReset())
+	}
+
+	if c.Bool("patch") {
+		releaserOpts = append(releaserOpts, pkg.WithPatchIncrement())
+	}
+
+	releaser, err := pkg.CreateNewReleaser(versionString, releaserOpts...)
+
+	if err != nil {
+		return err
+	}
+
+	// TODO:
+	// add commit
+	// add tagging
+	// add push
+	// methods to the `releaser`
+
+	err = os.WriteFile(".commitlog.release", []byte(releaser.String()), os.ModePerm)
+
+	return err
 }
diff --git a/go.mod b/go.mod
index f81b481..c6abd65 100644
--- a/go.mod
+++ b/go.mod
@@ -3,10 +3,8 @@ module github.com/barelyhuman/commitlog
 go 1.16
 
 require (
-	github.com/AlecAivazis/survey/v2 v2.2.8
-	github.com/fatih/color v1.12.0
-	github.com/go-git/go-billy/v5 v5.0.0
 	github.com/go-git/go-git/v5 v5.2.0
 	github.com/urfave/cli/v2 v2.8.1
+	golang.org/x/mod v0.5.1
 	golang.org/x/sys v0.0.0-20220412211240-33da011f77ad // indirect
 )
diff --git a/go.sum b/go.sum
index 80ecf88..516600b 100644
--- a/go.sum
+++ b/go.sum
@@ -1,8 +1,4 @@
-github.com/AlecAivazis/survey/v2 v2.2.8 h1:TgxCwybKdBckmC+/P9/5h49rw/nAHe/itZL0dgHs+Q0=
-github.com/AlecAivazis/survey/v2 v2.2.8/go.mod h1:9DYvHgXtiXm6nCn+jXnOXLKbH+Yo9u8fAS/SduGdoPk=
 github.com/BurntSushi/toml v1.1.0/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
-github.com/Netflix/go-expect v0.0.0-20180615182759-c93bf25de8e8 h1:xzYJEypr/85nBpB11F9br+3HUrpgb+fcm5iADzXXYEw=
-github.com/Netflix/go-expect v0.0.0-20180615182759-c93bf25de8e8/go.mod h1:oX5x61PbNXchhh0oikYAH+4Pcfw5LKv21+Jnpr6r6Pc=
 github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7 h1:uSoVVbwJiQipAclBbw+8quDsfcvFjOpI5iCf4p/cqCs=
 github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7/go.mod h1:6zEj6s6u/ghQa61ZWa/C2Aw3RkjiTBOix7dkqa1VLIs=
 github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239 h1:kFOfPq6dUM1hTo4JG6LR5AXSUEsOjtdm0kw0FtQtMJA=
@@ -17,8 +13,6 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c
 github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
 github.com/emirpasic/gods v1.12.0 h1:QAUIPSaCu4G+POclxeqb3F+WPpdKqFGlw36+yOzGlrg=
 github.com/emirpasic/gods v1.12.0/go.mod h1:YfzfFFoVP/catgzJb4IKIqXjX78Ha8FMSDh3ymbK86o=
-github.com/fatih/color v1.12.0 h1:mRhaKNwANqRgUBGKmnI5ZxEk7QXmjQeCcuYFMX2bfcc=
-github.com/fatih/color v1.12.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM=
 github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc=
 github.com/gliderlabs/ssh v0.2.2 h1:6zsha5zo/TWhRhwqCD3+EarCAgZ2yN28ipRnGPnwkI0=
 github.com/gliderlabs/ssh v0.2.2/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0=
@@ -32,32 +26,18 @@ github.com/go-git/go-git/v5 v5.2.0 h1:YPBLG/3UK1we1ohRkncLjaXWLW+HKp5QNM/jTli2Jg
 github.com/go-git/go-git/v5 v5.2.0/go.mod h1:kh02eMX+wdqqxgNMEyq8YgwlIOsDOa9homkUq1PoTMs=
 github.com/google/go-cmp v0.3.0 h1:crn/baboCvb5fXaQ0IJ1SGTsTVrWpDsCWC8EGETZijY=
 github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
-github.com/hinshun/vt10x v0.0.0-20180616224451-1954e6464174 h1:WlZsjVhE8Af9IcZDGgJGQpNflI3+MJSBhsgT5PCtzBQ=
-github.com/hinshun/vt10x v0.0.0-20180616224451-1954e6464174/go.mod h1:DqJ97dSdRW1W22yXSB90986pcOyQ7r45iio1KN2ez1A=
 github.com/imdario/mergo v0.3.9 h1:UauaLniWCFHWd+Jp9oCEkTBj8VO/9DKg3PV3VCNMDIg=
 github.com/imdario/mergo v0.3.9/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
 github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A=
 github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo=
 github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
-github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs=
-github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8=
 github.com/kevinburke/ssh_config v0.0.0-20190725054713-01f96b0aa0cd h1:Coekwdh0v2wtGp9Gmz1Ze3eVRAWJMLokvN3QjdzCHLY=
 github.com/kevinburke/ssh_config v0.0.0-20190725054713-01f96b0aa0cd/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM=
 github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
 github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
-github.com/kr/pty v1.1.4 h1:5Myjjh3JY/NaAi4IsUbHADytDyl1VE1Y9PXDlL+P/VQ=
-github.com/kr/pty v1.1.4/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
 github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
 github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
 github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
-github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
-github.com/mattn/go-colorable v0.1.8 h1:c1ghPdyEDarC70ftn0y+A/Ee++9zz8ljHG1b13eJ0s8=
-github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
-github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
-github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY=
-github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
-github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b h1:j7+1HpAFS1zy5+Q4qx1fWh90gTKwiN4QCGoY9TWyyO4=
-github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE=
 github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
 github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
 github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
@@ -71,7 +51,6 @@ github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQD
 github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0=
 github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
 github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
-github.com/stretchr/testify v1.2.1/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
 github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
 github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
 github.com/urfave/cli/v2 v2.8.1 h1:CGuYNZF9IKZY/rfBe3lJpccSoIY1ytfvmgQT90cNOl4=
@@ -82,19 +61,19 @@ github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 h1:bAn7/zixMGCfxrRT
 github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8=
 golang.org/x/crypto v0.0.0-20190219172222-a4c6cb3142f2/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
 golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
-golang.org/x/crypto v0.0.0-20190530122614-20be4c3c3ed5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
+golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
 golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073 h1:xMPOj6Pz6UipU1wXLkrtqpHbR0AVFnyPEQq/wRWz9lM=
 golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
+golang.org/x/mod v0.5.1 h1:OJxoQ/rynoF0dcCdI7cLPktw/hR2cueqYfjm43oqK38=
+golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro=
 golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
 golang.org/x/net v0.0.0-20200301022130-244492dfa37a h1:GuSPYbZzB5/dcLNCwLQLsg3obCJtX9IJhpXkvY7kzk0=
 golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20190221075227-b4e8571b14e0/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
-golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20190530182044-ad28b68e88f1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20220412211240-33da011f77ad h1:ntjMns5wyP/fN65tdBD4g8J5w8n015+iIIs9rtjXkY0=
 golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
@@ -103,6 +82,9 @@ golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
 golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=
 golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
 golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
+golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
 gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
 gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU=
diff --git a/main.go b/main.go
index 67437d0..568420e 100644
--- a/main.go
+++ b/main.go
@@ -10,7 +10,7 @@ import (
 	"github.com/urfave/cli/v2"
 )
 
-//go:embed .commitlog.release
+// go:embed .commitlog.release
 var version string
 
 func main() {
diff --git a/pkg/generator.go b/pkg/generator.go
index b0358b3..26c49da 100644
--- a/pkg/generator.go
+++ b/pkg/generator.go
@@ -13,26 +13,28 @@ import (
 	"github.com/go-git/go-git/v5/plumbing/object"
 )
 
-type commitClassification struct {
+// commitsByCategory is a collection of commits by a given key
+// the _key_ can be `all-changes` or a dynamic key / pattern defined
+// by the user
+type commitsByCategory struct {
 	key     string
 	commits []string
 }
 
 type Generator struct {
-	repo                *git.Repository
-	workingDirectorPath string
-	startRef            string
-	endRef              string
-	addPromo            bool
-	categories          []string
-	output              struct {
+	repo       *git.Repository
+	dirPath    string
+	startRef   string
+	endRef     string
+	addPromo   bool
+	categories []string
+	output     struct {
 		stdio    bool
 		file     bool
 		filePath string
 	}
-	classifiedCommits []commitClassification
-	inMarkdown        string
-	commitToProcess   []*object.Commit
+	classifiedCommits []commitsByCategory
+	rawCommits        []*object.Commit
 }
 
 type GeneratorConfigMod func(*Generator)
@@ -42,7 +44,7 @@ func (g *Generator) openRepo() {
 		return
 	}
 
-	r, err := git.PlainOpen(g.workingDirectorPath)
+	r, err := git.PlainOpen(g.dirPath)
 	if err != nil {
 		log.Fatal("Error opening Repository: ", err)
 	}
@@ -110,7 +112,7 @@ func (g *Generator) readCommitsInTags() (err error) {
 	}
 
 	// this will either have commits between 2 tags or all commits if no tags exist
-	g.commitToProcess = commits
+	g.rawCommits = commits
 
 	return
 
@@ -151,7 +153,7 @@ func (g *Generator) readCommitsInRange() (err error) {
 		commits = append(commits, c)
 	}
 
-	g.commitToProcess = commits
+	g.rawCommits = commits
 
 	return
 
@@ -165,9 +167,15 @@ func (g *Generator) ReadCommmits() (err error) {
 	g.openRepo()
 
 	if len(g.startRef) > 0 || len(g.endRef) > 0 {
-		g.readCommitsInRange()
+		err = g.readCommitsInRange()
+		if err != nil {
+			return
+		}
 	} else {
-		g.readCommitsInTags()
+		err = g.readCommitsInTags()
+		if err != nil {
+			return
+		}
 	}
 
 	return
@@ -178,11 +186,11 @@ func (g *Generator) Classify() (err error) {
 	if len(g.categories) == 0 {
 		allCommits := []string{}
 
-		for _, commit := range g.commitToProcess {
+		for _, commit := range g.rawCommits {
 			allCommits = append(allCommits, lib.CommitToLog(commit))
 		}
 
-		g.classifiedCommits = []commitClassification{
+		g.classifiedCommits = []commitsByCategory{
 			{
 				key:     "All Changes",
 				commits: allCommits,
@@ -200,7 +208,7 @@ func (g *Generator) Classify() (err error) {
 
 		catgCommits := []string{}
 
-		for _, commit := range g.commitToProcess {
+		for _, commit := range g.rawCommits {
 			if !rgx.Match([]byte(commit.Message)) {
 				continue
 			}
@@ -208,7 +216,7 @@ func (g *Generator) Classify() (err error) {
 			catgCommits = append(catgCommits, lib.CommitToLog(commit))
 		}
 
-		g.classifiedCommits = append(g.classifiedCommits, commitClassification{
+		g.classifiedCommits = append(g.classifiedCommits, commitsByCategory{
 			key:     catg,
 			commits: catgCommits,
 		})
@@ -255,7 +263,7 @@ func (g *Generator) Generate() (err error) {
 
 func CreateGenerator(path string, mods ...GeneratorConfigMod) *Generator {
 	generator := &Generator{
-		workingDirectorPath: path,
+		dirPath: path,
 	}
 
 	for _, mod := range mods {
diff --git a/pkg/releaser.go b/pkg/releaser.go
new file mode 100644
index 0000000..e53ad6d
--- /dev/null
+++ b/pkg/releaser.go
@@ -0,0 +1,160 @@
+package pkg
+
+import (
+	"fmt"
+	"strconv"
+	"strings"
+
+	"golang.org/x/mod/semver"
+)
+
+type version struct {
+	major     int
+	minor     int
+	patch     int
+	preString string
+}
+
+type Releaser struct {
+	raw  string
+	v    version
+	next version
+}
+
+func (r *Releaser) HasPrerelease() bool {
+	return len(r.v.preString) > 0
+}
+
+func (r *Releaser) String() (s string) {
+	var b strings.Builder
+
+	b.Write([]byte("v"))
+
+	b.WriteString(strconv.Itoa(r.next.major))
+	b.WriteString(".")
+	b.WriteString(strconv.Itoa(r.next.minor))
+	b.WriteString(".")
+	b.WriteString(strconv.Itoa(r.next.patch))
+
+	if len(r.next.preString) > 0 {
+		b.Write([]byte("-"))
+		b.Write([]byte(r.next.preString))
+	}
+
+	s = b.String()
+
+	return
+}
+
+type ReleaserMod func(*Releaser)
+
+func CreateNewReleaser(vString string, mods ...ReleaserMod) (r *Releaser, err error) {
+
+	if !semver.IsValid(vString) {
+		err = fmt.Errorf("invalid version string")
+		return
+	}
+
+	r = &Releaser{}
+	r.raw = vString
+
+	simplifiedV := semver.Canonical(vString)
+
+	vParts := strings.Split(simplifiedV, ".")
+
+	r.v.patch, err = strconv.Atoi(vParts[2])
+	if err != nil {
+		return
+	}
+
+	r.v.minor, err = strconv.Atoi(vParts[1])
+	if err != nil {
+		return
+	}
+
+	majorStr := strings.Replace(vParts[0], "v", "", -1)
+	r.v.major, err = strconv.Atoi(majorStr)
+	if err != nil {
+		return
+	}
+
+	r.v.preString = semver.Prerelease(vString)
+
+	r.next.major = r.v.major
+	r.next.minor = r.v.minor
+	r.next.patch = r.v.patch
+	r.next.preString = r.v.preString
+
+	for _, mod := range mods {
+		mod(r)
+	}
+
+	return
+}
+
+func WithPrerelease(pre string) ReleaserMod {
+	return func(r *Releaser) {
+		r.next.preString = pre
+	}
+}
+
+func WithPrereleaseIncrement() ReleaserMod {
+	return func(r *Releaser) {
+		preParts := strings.Split(r.v.preString, ".")
+		prePointer, _ := strconv.Atoi(preParts[1])
+		prePointer += 1
+		preParts[1] = strconv.Itoa(prePointer)
+		r.next.preString = strings.Join(preParts[:], ".")
+	}
+}
+
+func WithMajorIncrement() ReleaserMod {
+	return func(r *Releaser) {
+		r.next.major += 1
+	}
+}
+
+func WithMinorIncrement() ReleaserMod {
+	return func(r *Releaser) {
+		r.next.minor += 1
+	}
+}
+
+func WithPatchIncrement() ReleaserMod {
+	return func(r *Releaser) {
+		r.next.patch += 1
+	}
+}
+
+func WithMajorReset() ReleaserMod {
+	return func(r *Releaser) {
+		r.next.major = 0
+	}
+}
+
+func WithMinorReset() ReleaserMod {
+	return func(r *Releaser) {
+		r.next.minor = 0
+	}
+}
+
+func WithPatchReset() ReleaserMod {
+	return func(r *Releaser) {
+		r.next.patch = 0
+	}
+}
+
+func WithPrereleaseReset() ReleaserMod {
+	return func(r *Releaser) {
+		preParts := strings.Split(r.v.preString, ".")
+		// reset something like `beta.1` to `beta.0`
+		preParts[1] = strconv.Itoa(0)
+		r.next.preString = strings.Join(preParts[:], ".")
+	}
+}
+
+func WithClearPrerelease() ReleaserMod {
+	return func(r *Releaser) {
+		r.next.preString = ""
+	}
+}

From 511efc6c7964f0734f956d7b71c97821532a0666 Mon Sep 17 00:00:00 2001
From: Reaper <ahoy@barelyhuman.dev>
Date: Sat, 25 Jun 2022 19:09:25 +0530
Subject: [PATCH 06/51] add commit and push

---
 commands/release.go | 50 +++++++++++++++++++++++++++++++++++++++------
 main.go             | 12 ++++++++---
 2 files changed, 53 insertions(+), 9 deletions(-)

diff --git a/commands/release.go b/commands/release.go
index 41968cb..9022100 100644
--- a/commands/release.go
+++ b/commands/release.go
@@ -5,6 +5,9 @@ import (
 	"os"
 
 	"github.com/barelyhuman/commitlog/pkg"
+	"github.com/go-git/go-git/v5"
+	"github.com/go-git/go-git/v5/config"
+	"github.com/go-git/go-git/v5/plumbing"
 	"github.com/urfave/cli/v2"
 )
 
@@ -46,13 +49,48 @@ func Release(c *cli.Context) (err error) {
 		return err
 	}
 
-	// TODO:
-	// add commit
-	// add tagging
-	// add push
-	// methods to the `releaser`
-
 	err = os.WriteFile(".commitlog.release", []byte(releaser.String()), os.ModePerm)
+	if err != nil {
+		return
+	}
+
+	openRepo, err := git.PlainOpen(c.String("path"))
+	if err != nil {
+		return err
+	}
+
+	var commitHash plumbing.Hash
+	wt, err := openRepo.Worktree()
+	if err != nil {
+		return err
+	}
+
+	if c.Bool("commit") {
+		wt.Add(".commitlog.release")
+		commitHash, err = wt.Commit("chore: version"+releaser.String(), &git.CommitOptions{})
+		if err != nil {
+			return err
+		}
+
+		_, err = openRepo.CreateTag(releaser.String(), commitHash, &git.CreateTagOptions{})
+		if err != nil {
+			err = fmt.Errorf("looks like there was error while creating a tag for the version commit, please try again or create a tag manually: %v", err)
+			return err
+		}
+	}
+
+	if c.Bool("push") {
+		_, err := wt.Status()
+		if err != nil {
+			return err
+		}
+
+		openRepo.Push(&git.PushOptions{
+			RemoteName: "origin",
+			Progress:   os.Stdout,
+			RefSpecs:   []config.RefSpec{config.RefSpec("refs/tags/*:refs/tags/*")},
+		})
+	}
 
 	return err
 }
diff --git a/main.go b/main.go
index 568420e..0a0aa99 100644
--- a/main.go
+++ b/main.go
@@ -84,6 +84,12 @@ func main() {
 						Name:  "init",
 						Usage: "initialise commitlog release",
 					},
+					&cli.StringFlag{
+						Name:    "path",
+						Value:   ".",
+						Aliases: []string{"p"},
+						Usage:   "root with the '.git' folder `PATH`",
+					},
 					&cli.BoolFlag{
 						Name: "pre-release",
 						Usage: "create a pre-release version. will default to patch increment unless" +
@@ -109,12 +115,12 @@ func main() {
 					&cli.BoolFlag{
 						Name:  "commit",
 						Value: false,
-						Usage: "if true will create a commit, of the changed version",
+						Usage: "if true will create a commit and tag, of the changed version",
 					},
 					&cli.BoolFlag{
-						Name:  "tag",
+						Name:  "push",
 						Value: false,
-						Usage: "if true will create a tag, with the given version",
+						Usage: "if true will create push the created release commit + tag on origin",
 					},
 				},
 			},

From 0a946f6d1ca4cd3d9b70d944feec6a7de294e9be Mon Sep 17 00:00:00 2001
From: Reaper <ahoy@barelyhuman.dev>
Date: Sat, 25 Jun 2022 20:13:13 +0530
Subject: [PATCH 07/51] chore: use baseurl flag on mudkip

---
 scripts/generate-docs.sh | 5 +----
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/scripts/generate-docs.sh b/scripts/generate-docs.sh
index f07ccab..5bbfc4a 100755
--- a/scripts/generate-docs.sh
+++ b/scripts/generate-docs.sh
@@ -6,9 +6,6 @@ curl -o mudkip.tgz -L https://github.com/barelyhuman/mudkip/releases/latest/down
 tar -xvzf mudkip.tgz
 install linux-amd64/mudkip /usr/local/bin
 
-# hack for github pages till mudkip doesn't add baseURL functionality
-sed -i s#/#/commitlog/#g ./docs/_sidebar.md
-
-mudkip --stylesheet="./docs/styles.css"
+mudkip --stylesheet="./docs/styles.css" --baseurl='/commitlog/'
 
 

From 110c9b260e6de1e2be9af28b3592c373ab6fc501 Mon Sep 17 00:00:00 2001
From: Reaper <ahoy@barelyhuman.dev>
Date: Sat, 25 Jun 2022 20:40:19 +0530
Subject: [PATCH 08/51] feat: handling for pre increment

---
 commands/release.go |  4 ++++
 main.go             |  4 ++--
 pkg/releaser.go     | 10 ++++++++--
 3 files changed, 14 insertions(+), 4 deletions(-)

diff --git a/commands/release.go b/commands/release.go
index 9022100..8efe9d0 100644
--- a/commands/release.go
+++ b/commands/release.go
@@ -43,6 +43,10 @@ func Release(c *cli.Context) (err error) {
 		releaserOpts = append(releaserOpts, pkg.WithPatchIncrement())
 	}
 
+	if c.Bool("pre") {
+		releaserOpts = append(releaserOpts, pkg.WithPrereleaseIncrement())
+	}
+
 	releaser, err := pkg.CreateNewReleaser(versionString, releaserOpts...)
 
 	if err != nil {
diff --git a/main.go b/main.go
index 0a0aa99..0972338 100644
--- a/main.go
+++ b/main.go
@@ -91,12 +91,12 @@ func main() {
 						Usage:   "root with the '.git' folder `PATH`",
 					},
 					&cli.BoolFlag{
-						Name: "pre-release",
+						Name: "pre",
 						Usage: "create a pre-release version. will default to patch increment unless" +
 							"specified and not already a pre-release",
 					},
 					&cli.StringFlag{
-						Name:  "pre-release-tag",
+						Name:  "pre-tag",
 						Value: "beta",
 						Usage: "create a pre-release version",
 					},
diff --git a/pkg/releaser.go b/pkg/releaser.go
index e53ad6d..ec32656 100644
--- a/pkg/releaser.go
+++ b/pkg/releaser.go
@@ -37,7 +37,6 @@ func (r *Releaser) String() (s string) {
 	b.WriteString(strconv.Itoa(r.next.patch))
 
 	if len(r.next.preString) > 0 {
-		b.Write([]byte("-"))
 		b.Write([]byte(r.next.preString))
 	}
 
@@ -62,7 +61,14 @@ func CreateNewReleaser(vString string, mods ...ReleaserMod) (r *Releaser, err er
 
 	vParts := strings.Split(simplifiedV, ".")
 
-	r.v.patch, err = strconv.Atoi(vParts[2])
+	preParts := strings.Split(vParts[2], "-")
+
+	if len(preParts) > 1 {
+		r.v.patch, err = strconv.Atoi(preParts[0])
+	} else {
+		r.v.patch, err = strconv.Atoi(vParts[2])
+	}
+
 	if err != nil {
 		return
 	}

From e0ce9c693c554158b7b4841b799524164d9c3e83 Mon Sep 17 00:00:00 2001
From: Reaper <ahoy@barelyhuman.dev>
Date: Sun, 26 Jun 2022 14:34:51 +0530
Subject: [PATCH 09/51] feat(releaser): add init and pre-tag handlers

will add support for using the init flag and
pre-tag flags on the release command
also adds a sub feature for the path flag
---
 .gitignore          |  1 +
 commands/release.go | 61 ++++++++++++++++++++++++++++++++-------------
 pkg/releaser.go     | 39 +++++++++++++++++++++++------
 3 files changed, 76 insertions(+), 25 deletions(-)

diff --git a/.gitignore b/.gitignore
index d6f3ffe..b74d987 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,3 +3,4 @@ CHANGELOG.md
 .DS_Store
 dist
 commitlog
+lab
\ No newline at end of file
diff --git a/commands/release.go b/commands/release.go
index 8efe9d0..b527c76 100644
--- a/commands/release.go
+++ b/commands/release.go
@@ -3,6 +3,7 @@ package commands
 import (
 	"fmt"
 	"os"
+	"path"
 
 	"github.com/barelyhuman/commitlog/pkg"
 	"github.com/go-git/go-git/v5"
@@ -13,14 +14,29 @@ import (
 
 func Release(c *cli.Context) (err error) {
 
-	_, err = os.ReadFile(".commitlog.release")
+	fileDir := c.String("path")
+	filePath := path.Join(fileDir, ".commitlog.release")
+
+	if c.Bool("init") {
+		_, err = os.Stat(filePath)
+		if os.IsNotExist(err) {
+			err = nil
+			os.WriteFile(filePath, []byte("v0.0.0"), os.ModePerm)
+			fmt.Println("[commitlog] Initialized commitlog release")
+		} else {
+			err = fmt.Errorf(".commitlog.release already exists, cannot override")
+		}
+		return
+	}
+
+	_, err = os.Stat(filePath)
 
 	if os.IsNotExist(err) {
 		err = fmt.Errorf("couldn't find the release file, please run the `--init` flag first")
 		return
 	}
 
-	fileData, err := os.ReadFile(".commitlog.release")
+	fileData, err := os.ReadFile(filePath)
 
 	if err != nil {
 		err = fmt.Errorf("error reading the version file: %v", err)
@@ -29,7 +45,12 @@ func Release(c *cli.Context) (err error) {
 
 	versionString := string(fileData)
 
-	releaserOpts := []pkg.ReleaserMod{}
+	releaserOpts := []pkg.ReleaserMod{
+		// add in the pre-tag,
+		// will be used only if the pre flag
+		// is true
+		pkg.WithPreTag(c.String("pre-tag")),
+	}
 
 	if c.Bool("major") {
 		releaserOpts = append(releaserOpts, pkg.WithMajorIncrement(), pkg.WithMinorReset(), pkg.WithPatchReset())
@@ -53,30 +74,36 @@ func Release(c *cli.Context) (err error) {
 		return err
 	}
 
-	err = os.WriteFile(".commitlog.release", []byte(releaser.String()), os.ModePerm)
+	err = os.WriteFile(filePath, []byte(releaser.String()), os.ModePerm)
 	if err != nil {
 		return
 	}
 
-	openRepo, err := git.PlainOpen(c.String("path"))
-	if err != nil {
-		return err
-	}
+	var gitRepo *git.Repository
+	var toTagHash plumbing.Hash
+	var repoWt *git.Worktree
 
-	var commitHash plumbing.Hash
-	wt, err := openRepo.Worktree()
-	if err != nil {
-		return err
+	if c.Bool("commit") || c.Bool("push") {
+		gitRepo, err = git.PlainOpen(c.String("path"))
+		if err != nil {
+			return err
+		}
+
+		repoWt, err = gitRepo.Worktree()
+
+		if err != nil {
+			return err
+		}
 	}
 
 	if c.Bool("commit") {
-		wt.Add(".commitlog.release")
-		commitHash, err = wt.Commit("chore: version"+releaser.String(), &git.CommitOptions{})
+		repoWt.Add(filePath)
+		toTagHash, err = repoWt.Commit("chore: version"+releaser.String(), &git.CommitOptions{})
 		if err != nil {
 			return err
 		}
 
-		_, err = openRepo.CreateTag(releaser.String(), commitHash, &git.CreateTagOptions{})
+		_, err = gitRepo.CreateTag(releaser.String(), toTagHash, &git.CreateTagOptions{})
 		if err != nil {
 			err = fmt.Errorf("looks like there was error while creating a tag for the version commit, please try again or create a tag manually: %v", err)
 			return err
@@ -84,12 +111,12 @@ func Release(c *cli.Context) (err error) {
 	}
 
 	if c.Bool("push") {
-		_, err := wt.Status()
+		_, err := repoWt.Status()
 		if err != nil {
 			return err
 		}
 
-		openRepo.Push(&git.PushOptions{
+		gitRepo.Push(&git.PushOptions{
 			RemoteName: "origin",
 			Progress:   os.Stdout,
 			RefSpecs:   []config.RefSpec{config.RefSpec("refs/tags/*:refs/tags/*")},
diff --git a/pkg/releaser.go b/pkg/releaser.go
index ec32656..faa0521 100644
--- a/pkg/releaser.go
+++ b/pkg/releaser.go
@@ -16,9 +16,10 @@ type version struct {
 }
 
 type Releaser struct {
-	raw  string
-	v    version
-	next version
+	raw    string
+	v      version
+	next   version
+	preTag string
 }
 
 func (r *Releaser) HasPrerelease() bool {
@@ -37,6 +38,7 @@ func (r *Releaser) String() (s string) {
 	b.WriteString(strconv.Itoa(r.next.patch))
 
 	if len(r.next.preString) > 0 {
+		b.Write([]byte("-"))
 		b.Write([]byte(r.next.preString))
 	}
 
@@ -86,6 +88,8 @@ func CreateNewReleaser(vString string, mods ...ReleaserMod) (r *Releaser, err er
 
 	r.v.preString = semver.Prerelease(vString)
 
+	r.preTag = strings.Split(r.v.preString, ".")[0]
+
 	r.next.major = r.v.major
 	r.next.minor = r.v.minor
 	r.next.patch = r.v.patch
@@ -106,11 +110,24 @@ func WithPrerelease(pre string) ReleaserMod {
 
 func WithPrereleaseIncrement() ReleaserMod {
 	return func(r *Releaser) {
-		preParts := strings.Split(r.v.preString, ".")
-		prePointer, _ := strconv.Atoi(preParts[1])
-		prePointer += 1
-		preParts[1] = strconv.Itoa(prePointer)
-		r.next.preString = strings.Join(preParts[:], ".")
+
+		// if a pre string already exists
+		if len(r.v.preString) > 0 {
+			preParts := strings.Split(r.v.preString, ".")
+			prePointer, _ := strconv.Atoi(preParts[1])
+			prePointer += 1
+			preParts[1] = strconv.Itoa(prePointer)
+			preParts[0] = r.preTag
+			r.next.preString = strings.Join(preParts[:], ".")
+			return
+		}
+
+		preToCreate := []string{
+			r.preTag,
+			"0",
+		}
+
+		r.next.preString = strings.Join(preToCreate[:], ".")
 	}
 }
 
@@ -164,3 +181,9 @@ func WithClearPrerelease() ReleaserMod {
 		r.next.preString = ""
 	}
 }
+
+func WithPreTag(preTag string) ReleaserMod {
+	return func(r *Releaser) {
+		r.preTag = preTag
+	}
+}

From 909fd032facdeb4fb7633a4fad82dced28e8de83 Mon Sep 17 00:00:00 2001
From: Reaper <ahoy@barelyhuman.dev>
Date: Sun, 26 Jun 2022 14:36:02 +0530
Subject: [PATCH 10/51] chore: swap debugging logger with stderr printer

removes the logger as most of the logical part has been
now tested
---
 main.go | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/main.go b/main.go
index 0972338..f975fee 100644
--- a/main.go
+++ b/main.go
@@ -3,7 +3,6 @@ package main
 import (
 	_ "embed"
 	"fmt"
-	"log"
 	"os"
 
 	"github.com/barelyhuman/commitlog/commands"
@@ -88,7 +87,8 @@ func main() {
 						Name:    "path",
 						Value:   ".",
 						Aliases: []string{"p"},
-						Usage:   "root with the '.git' folder `PATH`",
+						Usage: "`PATH` to a folder where .commitlog.release exists or is to be created." +
+							"(note: do not use `--commit` or `--push` if the file isn't in the root)",
 					},
 					&cli.BoolFlag{
 						Name: "pre",
@@ -137,6 +137,6 @@ func main() {
 
 	err := app.Run(os.Args)
 	if err != nil {
-		log.Fatal(err)
+		fmt.Fprintf(os.Stderr, "[commitlog] %v", err)
 	}
 }

From 5bafe9d105298001707c7c816e60d3ef0257a816 Mon Sep 17 00:00:00 2001
From: Reaper <ahoy@barelyhuman.dev>
Date: Sun, 26 Jun 2022 15:02:02 +0530
Subject: [PATCH 11/51] fix: tag creation

---
 commands/release.go | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/commands/release.go b/commands/release.go
index b527c76..00b714e 100644
--- a/commands/release.go
+++ b/commands/release.go
@@ -97,13 +97,16 @@ func Release(c *cli.Context) (err error) {
 	}
 
 	if c.Bool("commit") {
+		msg := "chore: " + releaser.String()
 		repoWt.Add(filePath)
-		toTagHash, err = repoWt.Commit("chore: version"+releaser.String(), &git.CommitOptions{})
+		toTagHash, err = repoWt.Commit(msg, &git.CommitOptions{})
 		if err != nil {
 			return err
 		}
 
-		_, err = gitRepo.CreateTag(releaser.String(), toTagHash, &git.CreateTagOptions{})
+		_, err = gitRepo.CreateTag(releaser.String(), toTagHash, &git.CreateTagOptions{
+			Message: msg,
+		})
 		if err != nil {
 			err = fmt.Errorf("looks like there was error while creating a tag for the version commit, please try again or create a tag manually: %v", err)
 			return err

From 09fc85c0d1d52d770bbbf39ac45907103a53d354 Mon Sep 17 00:00:00 2001
From: Reaper <ahoy@barelyhuman.dev>
Date: Sun, 26 Jun 2022 15:13:41 +0530
Subject: [PATCH 12/51] refactor: swap go-git for push with exec

will use exec for the git push commands
since go-git requires manual authentication
while pushing
---
 commands/release.go | 24 +++++++++++++++++-------
 lib/commands.go     | 18 ++++++++++++++++++
 2 files changed, 35 insertions(+), 7 deletions(-)
 create mode 100644 lib/commands.go

diff --git a/commands/release.go b/commands/release.go
index 00b714e..2a79d33 100644
--- a/commands/release.go
+++ b/commands/release.go
@@ -3,11 +3,12 @@ package commands
 import (
 	"fmt"
 	"os"
+	"os/exec"
 	"path"
 
+	"github.com/barelyhuman/commitlog/lib"
 	"github.com/barelyhuman/commitlog/pkg"
 	"github.com/go-git/go-git/v5"
-	"github.com/go-git/go-git/v5/config"
 	"github.com/go-git/go-git/v5/plumbing"
 	"github.com/urfave/cli/v2"
 )
@@ -114,16 +115,25 @@ func Release(c *cli.Context) (err error) {
 	}
 
 	if c.Bool("push") {
-		_, err := repoWt.Status()
+		_, err = repoWt.Status()
 		if err != nil {
 			return err
 		}
 
-		gitRepo.Push(&git.PushOptions{
-			RemoteName: "origin",
-			Progress:   os.Stdout,
-			RefSpecs:   []config.RefSpec{config.RefSpec("refs/tags/*:refs/tags/*")},
-		})
+		cmd := exec.Command("git", "push")
+		cmd.Dir = fileDir
+		err = lib.Command(cmd)
+
+		if err != nil {
+			return err
+		}
+
+		cmd = exec.Command("git", "push", "--tags")
+		cmd.Dir = fileDir
+
+		if err = lib.Command(cmd); err != nil {
+			return err
+		}
 	}
 
 	return err
diff --git a/lib/commands.go b/lib/commands.go
new file mode 100644
index 0000000..b8fb4b4
--- /dev/null
+++ b/lib/commands.go
@@ -0,0 +1,18 @@
+package lib
+
+import (
+	"log"
+	"os/exec"
+	"strings"
+)
+
+func Command(cmd *exec.Cmd) error {
+	var w strings.Builder
+	cmd.Stderr = &w
+	err := cmd.Run()
+	if err != nil {
+		log.Println(strings.TrimSpace(w.String()))
+		return err
+	}
+	return nil
+}

From 87ce3fc76b252908cdd81f9537713f8d67813652 Mon Sep 17 00:00:00 2001
From: Reaper <ahoy@barelyhuman.dev>
Date: Sun, 26 Jun 2022 15:15:24 +0530
Subject: [PATCH 13/51] chore: v2.0.0-beta.0

---
 .commitlog.release | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/.commitlog.release b/.commitlog.release
index 60453e6..c2bdfd2 100755
--- a/.commitlog.release
+++ b/.commitlog.release
@@ -1 +1 @@
-v1.0.0
\ No newline at end of file
+v2.0.0-beta.0
\ No newline at end of file

From 2c063e623d1124fa4ab857f53285ce0bd640144a Mon Sep 17 00:00:00 2001
From: Reaper <ahoy@barelyhuman.dev>
Date: Sun, 26 Jun 2022 17:10:47 +0530
Subject: [PATCH 14/51] docs: base index and structure

---
 .github/workflows/create-binaries.yml |   1 +
 .gitignore                            |   3 +-
 docs/_sidebar.md                      |   7 --
 docs/download.md                      |  41 +++++++
 docs/index.md                         | 134 ++++++++++++++++++---
 docs/install.md                       |  39 ------
 docs/manual.md                        |  68 ++---------
 docs/quick-start.md                   |  33 ------
 docs/selective-changelogs.md          |  76 ------------
 docs/styles.css                       | 164 --------------------------
 docs/usage.md                         |  17 ---
 docs/versioning.md                    |  20 ----
 scripts/generate-docs.sh              |   6 +-
 scripts/get-release-urls.sh           |  27 +++++
 14 files changed, 201 insertions(+), 435 deletions(-)
 delete mode 100644 docs/_sidebar.md
 create mode 100644 docs/download.md
 delete mode 100644 docs/install.md
 delete mode 100644 docs/quick-start.md
 delete mode 100644 docs/selective-changelogs.md
 delete mode 100644 docs/styles.css
 delete mode 100644 docs/usage.md
 delete mode 100644 docs/versioning.md
 create mode 100755 scripts/get-release-urls.sh

diff --git a/.github/workflows/create-binaries.yml b/.github/workflows/create-binaries.yml
index a8459b8..e9e0c24 100644
--- a/.github/workflows/create-binaries.yml
+++ b/.github/workflows/create-binaries.yml
@@ -25,3 +25,4 @@ jobs:
           github_token: ${{ secrets.GITHUB_TOKEN }}
           goos: ${{ matrix.goos }}
           goarch: ${{ matrix.goarch }}
+          ldflags: "-w -s"
diff --git a/.gitignore b/.gitignore
index b74d987..9af1d52 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,4 +3,5 @@ CHANGELOG.md
 .DS_Store
 dist
 commitlog
-lab
\ No newline at end of file
+lab
+api_urls.json
\ No newline at end of file
diff --git a/docs/_sidebar.md b/docs/_sidebar.md
deleted file mode 100644
index 5c7adf6..0000000
--- a/docs/_sidebar.md
+++ /dev/null
@@ -1,7 +0,0 @@
-- [Home](/)
-- [Install](/install)
-- [Quick Start](/quick-start)
-- [Usage](/usage)
-  - [Selective Changelogs](/selective-changelogs)
-  - [Version Management](/versioning)
-  - [Manual](/manual)
diff --git a/docs/download.md b/docs/download.md
new file mode 100644
index 0000000..29e647e
--- /dev/null
+++ b/docs/download.md
@@ -0,0 +1,41 @@
+<!-- meta -->
+<title>
+    commitlog | downloads
+</title>
+<meta name="description" content="commits to changelog generator">
+<!-- meta end -->
+
+### [commitlog](/)
+
+[Manual](/manual)\
+[Download &darr;](/download)
+
+#### Downloads
+
+[commitlog-v2.0.0-beta.0-darwin-amd64.tar.gz]("https://github.com/barelyhuman/commitlog/releases/download/v2.0.0-beta.0/commitlog-v2.0.0-beta.0-darwin-amd64.tar.gz")
+
+[commitlog-v2.0.0-beta.0-darwin-amd64.tar.gz.md5]("https://github.com/barelyhuman/commitlog/releases/download/v2.0.0-beta.0/commitlog-v2.0.0-beta.0-darwin-amd64.tar.gz.md5")
+
+[commitlog-v2.0.0-beta.0-darwin-arm64.tar.gz]("https://github.com/barelyhuman/commitlog/releases/download/v2.0.0-beta.0/commitlog-v2.0.0-beta.0-darwin-arm64.tar.gz")
+
+[commitlog-v2.0.0-beta.0-darwin-arm64.tar.gz.md5]("https://github.com/barelyhuman/commitlog/releases/download/v2.0.0-beta.0/commitlog-v2.0.0-beta.0-darwin-arm64.tar.gz.md5")
+
+[commitlog-v2.0.0-beta.0-linux-386.tar.gz]("https://github.com/barelyhuman/commitlog/releases/download/v2.0.0-beta.0/commitlog-v2.0.0-beta.0-linux-386.tar.gz")
+
+[commitlog-v2.0.0-beta.0-linux-386.tar.gz.md5]("https://github.com/barelyhuman/commitlog/releases/download/v2.0.0-beta.0/commitlog-v2.0.0-beta.0-linux-386.tar.gz.md5")
+
+[commitlog-v2.0.0-beta.0-linux-amd64.tar.gz]("https://github.com/barelyhuman/commitlog/releases/download/v2.0.0-beta.0/commitlog-v2.0.0-beta.0-linux-amd64.tar.gz")
+
+[commitlog-v2.0.0-beta.0-linux-amd64.tar.gz.md5]("https://github.com/barelyhuman/commitlog/releases/download/v2.0.0-beta.0/commitlog-v2.0.0-beta.0-linux-amd64.tar.gz.md5")
+
+[commitlog-v2.0.0-beta.0-linux-arm64.tar.gz]("https://github.com/barelyhuman/commitlog/releases/download/v2.0.0-beta.0/commitlog-v2.0.0-beta.0-linux-arm64.tar.gz")
+
+[commitlog-v2.0.0-beta.0-linux-arm64.tar.gz.md5]("https://github.com/barelyhuman/commitlog/releases/download/v2.0.0-beta.0/commitlog-v2.0.0-beta.0-linux-arm64.tar.gz.md5")
+
+[commitlog-v2.0.0-beta.0-windows-386.zip]("https://github.com/barelyhuman/commitlog/releases/download/v2.0.0-beta.0/commitlog-v2.0.0-beta.0-windows-386.zip")
+
+[commitlog-v2.0.0-beta.0-windows-386.zip.md5]("https://github.com/barelyhuman/commitlog/releases/download/v2.0.0-beta.0/commitlog-v2.0.0-beta.0-windows-386.zip.md5")
+
+[commitlog-v2.0.0-beta.0-windows-amd64.zip]("https://github.com/barelyhuman/commitlog/releases/download/v2.0.0-beta.0/commitlog-v2.0.0-beta.0-windows-amd64.zip")
+
+[commitlog-v2.0.0-beta.0-windows-amd64.zip.md5]("https://github.com/barelyhuman/commitlog/releases/download/v2.0.0-beta.0/commitlog-v2.0.0-beta.0-windows-amd64.zip.md5")
diff --git a/docs/index.md b/docs/index.md
index 81982de..6184909 100644
--- a/docs/index.md
+++ b/docs/index.md
@@ -1,28 +1,126 @@
-<p align="center">
-  <img src="https://raw.githubusercontent.com/barelyhuman/commitlog/main/assets/commitlog.png" height="64">
-<p align="center">Changelog generator using Commit History</p>
+<!-- meta -->
+<title>
+    commitlog
+</title>
+<meta name="description" content="commits to changelog generator">
+<!-- meta end -->
 
-[![Go Report Card](https://goreportcard.com/badge/github.com/barelyhuman/commitlog)](https://goreportcard.com/report/github.com/barelyhuman/commitlog)
+### [commitlog](/)
 
-## Philosophy
+[Manual](/manual)\
+[Download &darr;](/download)
 
-- Work on all major operating systems
-- Not platform dependent, not tied to Github, Gitlab, or anything. It's just markdown.
-- Ability to generate change logs between version tags
-- Handle release versioning of the project
-- Stay small
+#### Index
 
-## Why
+- [Source](https://github.com/barelyhuman/commitlog)
+- [Quick Start](#quick-start)
+- [About](#about)
+  - [Philosophy](#philosophy)
+  - [Installation](#installation)
+- [Manual](#manual)
+- [License](#license)
 
-Every language has it's own isolated version of a tool like this, for someone who works with multiple languages, it's easier to
-have the same tool working everywhere, without having to setup something get it working. There's an even tighter scoped version of this, [nimclog](https://github.com/barelyhuman/nimclog).
+<h4 id="quick-start">Quick Start</h4>
 
-The point of the tool is not to create super descriptive changelogs for you but to help your changelogs have enough information for you as a developer to be able to write proper changelogs while having references to the changes in one place.
+For the one's who already know the tool and wanna get started quickly.
 
-## Documentation
+You can get the CLI in the following ways
 
-The documentation can be read from the `docs` folder of the repository, or on the [website](https://barelyhuman.github.io/commitlog)
+1. You can get the binaries from the [download section](/download)
 
-## License
+2. Using `go get`
 
-[MIT](/LICENSE)
+```sh
+go get -u github.com/barelyhuman/commitlog
+```
+
+3. Using goblin
+
+```sh
+curl -sf https://goblin.barelyhuman.xyz/github.com/barelyhuman/commitlog | sh
+```
+
+Once installed you can just run `commitlog generate` or the shorter version
+`commitlog g` to get all the changes between the recent tags.
+
+<h4 id="about">About</h4>
+
+<h5 id="philosophy">Philosophy</h5>
+
+**_commitlog_** simply exists because I wasn't able to find a decent enough tool
+to do this without being bound to a specific programming language and it's
+toolset. The closes one to this is the `git`'s own `shortlog` and `log` commands
+
+- **Language Agnostic** - No one needs the entire programming toolset or the
+  language to be setup on the system to be able to just generate logs
+
+- **Decently Sized** - Not everyone has a powerful system and CI systems are
+  still very limited in terms of resources since they give you shared spaces and
+  automating generating this is a common practice so it doesn't make sense for
+  it to install a runtime worth 100MB to run it.
+
+  The binary itself is around 10-13MB which is fairly big for a tool like this
+  but this is due to go's nature of embedding the platform runtime with the
+  binary and this might not be ideal for some and so there's another similar
+  smaller scoped version [nimclog](https://github.com/barelyhuman/nimclog) which
+  is in KB's
+
+- **Flexible** - There are no set standards for how you write commit messages.
+  Commitlint is a good standard and pretty widely used and also what commitlog
+  v1 used as the base for categorizing.
+
+  V2 however, doesn't have a set commit category standard, it accepts regex's
+  that you will categorize your commits for you.
+
+  This is more for experienced developers who have a their own pattern of
+  writing commits and would like a tool that'd work with their pattern instead
+  of creating friction
+
+- **Extensible** - The entire thing is open source and MIT licenses,
+  specifically for you to be able to fix and add things as needed. Each command
+  has been kept away from the domain logic to be able to use `commitlog` even as
+  a library and build your own tool if you wish to, though if there's something
+  you wish the CLI supported, you are free to open issues and I really like
+  people helping with the development since that helps keeping the tool alive
+  longer.
+
+<h5 id="installation">Installation</h5>
+
+The installation is pretty straightforwad. You [download](/download) the binary
+from the download section of this website or use something like
+[goblin](https://goblin.barelyhuman.xyz) to build the binary for your specific
+system (rarely needed) since the releases actually accommodate the most used
+operating systems and architectures already.
+
+**Linux/Mac (Unix Systems)**
+
+Once downloaded, you can use the `install` command on *nix systems to link the
+binary to a location that's already in your PATH variable.
+
+eg:
+
+```bash
+# install commitlog from current directory to the /usr/local/bin directory
+install $(pwd)/commitlog /usr/local/bin
+```
+
+This should give you the ability to use the `commitlog` command anywhere in your
+system
+
+**Windows**
+
+Similar to the linux setup, you can download the `.exe` file and add it to a
+location that your environment path already has. An easier thing to do is to
+store the entire thing in your secondary partition and add that location to your
+PATH. You can use this resource from Java docs to help you with modifying the
+PATH variables
+
+- [Modifying PATH in Windows](https://www.java.com/en/download/help/path.html)
+
+<h4 id="manual">Manual</h4>
+
+[Read Manual &rarr;](/manual)
+
+<h4 id="license">License</h4>
+
+commitlog is MIT Licensed and you can read the entire license in the [source code](https://github.com/barelyhuman/commitlog)
diff --git a/docs/install.md b/docs/install.md
deleted file mode 100644
index 9845d8c..0000000
--- a/docs/install.md
+++ /dev/null
@@ -1,39 +0,0 @@
-### [commitlog](/)
-
-# Install
-
-## From goblin
-
-Goblin will build the project for your specific system so it might take a bit of time based on the traffic
-
-```sh
-curl -sf https://goblin.reaper.im/github.com/barelyhuman/commitlog
-```
-
-## From Releases
-
-To avoid the above work load you can download the binaries from the github releases pages
-[Commitlog Releases &rarr;](https://github.com/barelyhuman/commitlog/releases)
-
-## From Source
-
-If you have golang installed on your system you can build the binary on your system
-
-```sh
-# clone the repository
-git clone https://github.com/barelyhuman/commitlog
-
-# cd into the folder
-cd commitlog
-
-# run go mod to download needed deps
-go mod tidy
-
-# run go build and wait for it to complete
-go build
-
-# if on unix, use the `install` command to install it onto a system used path
-install goblin /usr/local/bin
-# or if you need perms
-sudo install goblin /usr/local/bin
-```
diff --git a/docs/manual.md b/docs/manual.md
index e3f5bde..5a53383 100644
--- a/docs/manual.md
+++ b/docs/manual.md
@@ -1,61 +1,15 @@
-### [commitlog](/)
-
-## Manual
-
-```
-$ commitlog <subcommand> [flags]
-```
-
-### Subcommands
-
-- `log`
-- `release` (added in v0.0.7-dev.7)
+<!-- meta -->
+<title>
+    commitlog | manual
+</title>
+<meta name="description" content="commits to changelog generator">
+<!-- meta end -->
 
-#### `commitlog log`
-
-```sh
-eg:
-$ commitlog log -p .
-## or the shorthand
-$ commitlog
-```
-
-```sh
-Usage of commitlog:
-  -e string
-        commit hash string / revision (ex. HEAD, HEAD^, HEAD~2)
-         to stop collecting commit message at
-  -i string
-        commit types to be includes (default "ci|refactor|docs|fix|feat|test|chore|other")
-  -p string
-        path to the repository, points to the current working directory by default (default ".")
-  -promo
-        if enabled will add a "generated by" promotional tag to the changelog
-  -s string
-        commit hash string / revision (ex. HEAD, HEAD^, HEAD~2)
-         to start collecting commit messages from
-  -skip
-        if enabled will skip trying to classify and just give a list of changes
-```
-
-<small>`-promo` (added in v1.0.0)</small>
+### [commitlog](/)
 
-#### `commitlog release`
+[Manual](/manual)\
+[Download &darr;](/download)
 
-```sh
-$ commitlog release [init | <flags>]
-```
+# Manual
 
-```sh
-Usage of release:
-  -beta
-        If the release is a beta/prerelease
-  -beta-suffix -beta.x
-        If the release is a beta, to add/increment tag with -beta.x or mentioned string
-  -major
-        If release is a *major* one, will increment the x.0.0
-  -minor
-        If release is a *minor* one, will increment the 0.x.0
-  -patch
-        If release is a *patch*, will increment the 0.0.x
-```
+TBD
diff --git a/docs/quick-start.md b/docs/quick-start.md
deleted file mode 100644
index 2f702de..0000000
--- a/docs/quick-start.md
+++ /dev/null
@@ -1,33 +0,0 @@
-### [commitlog](/)
-
-# Quick Start
-
-## Changelog
-
-1. Install using one of the methods from [Installation Instructions](/install)
-2. Change terminal directory into the git repository you want the changelogs from.
-3. run the base command
-
-   ```sh
-   # on mac
-   $ commitlog | pbcopy
-
-   # on linux with x11
-   $ commitlog | xclip
-   ```
-
-## Version Management
-
-1. Install using one of the methods from [Installation Instructions](/install)
-2. Change terminal directory into the git repository you want the changelogs from.
-3. Initialise version management
-
-   ```sh
-   $ commitlog release init
-   ```
-
-4. If working in an existing project, change the `.commitlog.release` file to match with the current version of the project.
-5. Run the needed command to increase versino
-   ```sh
-   $ commitlog release
-   ```
diff --git a/docs/selective-changelogs.md b/docs/selective-changelogs.md
deleted file mode 100644
index b2e4c2e..0000000
--- a/docs/selective-changelogs.md
+++ /dev/null
@@ -1,76 +0,0 @@
-### [commitlog](/)
-
-# Selective Changelogs
-
-## Classification
-
-Commitlog was built on a minor subset of classification flags from the commitlint spec
-which includes the following type of commits.
-
-`ci|refactor|docs|fix|feat|test|chore|other`
-
-These are all turned on by default on the cli and will use the commit message's subject to classify commits for you.
-
-Eg:
-The following git message would generate a commitlog like so
-
-```
-# git message
-feat: added handling for feature flags
-```
-
-```markdown
-<!-- COMMITLOG -->
-
-# Features
-
-53cb64436a3df5b22702cf6d012a4d09df93d930 - added handling for feature flags
-```
-
-Everything that cannot be classified in the above types will be put into `other`
-
-### Selected types
-
-If you only want to include feature and fix flags for changelogs you could do so in the following manner
-
-```sh
-$ commitlog -i "fix|feat"
-# or
-$ commitlog -i "fix,feat"
-```
-
-### Skip classification
-
-If you wish to avoid classification all together and just want commits between a range you can do so as well (though you are better off without the tool for this usecase since git handles this natively)
-
-```sh
-$ commitlog --skip
-```
-
-## Commits in range
-
-A very common use case is to get commits between a range if you aren't using tags in your current workflow.
-This can be done by using **git revision handles** or the **commit hashes**.
-
-Eg:
-Let's say I want the last 3 commits
-
-```sh
-$ commitlog -s HEAD -e HEAD~4
-```
-
-<small>`HEAD~4` since the end commit is excluded from the range.</small>
-
-Both `-s` and `-e` are individual flags and don't have to be used together.
-
-So something like will also give you the last 4 commits.
-
-```sh
-$ commitlog -e HEAD~4
-```
-
-and the following would give you all commits till the next tagged instance starting form the given commit
-
-```sh
-$ commitlog -s HEAD~4
-```
diff --git a/docs/styles.css b/docs/styles.css
deleted file mode 100644
index 4162af1..0000000
--- a/docs/styles.css
+++ /dev/null
@@ -1,164 +0,0 @@
-@import url("https://rsms.me/inter/inter.css");
-@import url("https://cdn.jsdelivr.net/npm/hack-font@3/build/web/hack.css");
-
-@import url("https://unpkg.com/highlight.js@11.5.1/styles/base16/one-light.css")
-screen;
-
-@import url("https://unpkg.com/highlight.js@11.5.1/styles/base16/onedark.css")
-  screen and (prefers-color-scheme: dark);
-
-/* https://barelyhuman.github.io/zinccolors/ */
-:root {
-  --zinc-50: #fafafa;
-  --zinc-100: #f4f4f5;
-  --zinc-200: #e4e4e7;
-  --zinc-300: #d4d4d8;
-  --zinc-400: #a1a1aa;
-  --zinc-500: #71717a;
-  --zinc-600: #52525b;
-  --zinc-700: #3f3f46;
-  --zinc-800: #27272a;
-  --zinc-900: #18181b;
-}
-
-/* vars for everything else */
-:root {
-  --base: var(--zinc-50);
-  --surface: var(--zinc-100);
-  --overlay: var(--zinc-200);
-  --text: var(--zinc-700);
-  --subtle: var(--zinc-400);
-  --muted: var(--zinc-300);
-
-  --font-sans: "Hack", monospace;
-  --font-mono: "Hack", monospace;
-}
-
-html {
-  font-size: 100%;
-}
-
-body {
-  background: var(--base);
-  font-family: var(--font-sans);
-  font-weight: 400;
-  line-height: 1.75;
-  color: var(--text);
-  margin: 0 auto;
-  padding: 1rem;
-}
-
-p {
-  margin-bottom: 1rem;
-}
-
-h1,
-h2,
-h3,
-h4,
-h5 {
-  margin: 3rem 0 1.38rem;
-  font-family: var(--font-sans);
-  font-weight: 400;
-  line-height: 1.3;
-}
-
-h1 {
-  margin-top: 0;
-  font-size: 3.052rem;
-}
-
-h2 {
-  font-size: 2.441rem;
-}
-
-h3 {
-  font-size: 1.953rem;
-}
-
-h4 {
-  font-size: 1.563rem;
-}
-
-h5 {
-  font-size: 1.25rem;
-}
-
-small,
-.text_small {
-  font-size: 0.8rem;
-}
-
-pre,
-code {
-  font-family: var(--font-mono);
-}
-
-code {
-  background: var(--surface);
-  padding: 2px;
-  border-radius: 4px;
-}
-
-pre {
-  white-space: pre-wrap;
-}
-
-pre > .hljs {
-  background: var(--surface);
-  border-radius: 6px;
-  padding: 1em;
-}
-
-a {
-  color: var(--subtle);
-  text-decoration: none;
-}
-
-a:hover {
-  color: var(--text);
-  text-decoration: underline;
-}
-
-.layout-container {
-  display: flex;
-  align-items: baseline;
-  gap: 1em;
-}
-
-nav.sidebar {
-  display: none;
-  min-width: 250px;
-  max-width: 350px;
-}
-
-nav.sidebar ul {
-  padding-left: 0.75rem;
-}
-
-nav.sidebar li {
-  list-style-type: none;
-}
-
-nav.sidebar li::before {
-  content: "\2192";
-  color: var(--muted);
-  margin-inline-end: 1ch;
-}
-
-@media screen and (prefers-color-scheme: dark) {
-  :root {
-    --base: var(--zinc-900);
-    --surface: var(--zinc-800);
-    --overlay: var(--zinc-700);
-    --text: var(--zinc-100);
-    --subtle: var(--zinc-400);
-    --muted: var(--zinc-500);
-  }
-}
-
-@media screen and (min-width: 768px) {
-  nav.sidebar {
-    display: flex;
-  }
-}
diff --git a/docs/usage.md b/docs/usage.md
deleted file mode 100644
index 3b23531..0000000
--- a/docs/usage.md
+++ /dev/null
@@ -1,17 +0,0 @@
-### [commitlog](/)
-
-# Usage
-
-If you are looking for an overview of the flags, please check the [manual](/manual).
-
-The base command should serve enough for most people but let's still get into the details of what can be done.
-
-- The cli allows you to select a range which can be reference strings like (HEAD, HEAD~2) and this will give you commits in that range, exclusive of the end reference.
-- classification is optional but is turned on by default and uses the inclusion types to do the classification
-- You can also handle managing releases by using the `release` subcommand.
-
-For details on how to do each
-
-[Selective Changelogs &rarr;](/selective-changelogs)
-
-[Versioning &rarr;](/versioning)
diff --git a/docs/versioning.md b/docs/versioning.md
deleted file mode 100644
index 1666b3e..0000000
--- a/docs/versioning.md
+++ /dev/null
@@ -1,20 +0,0 @@
-### [commitlog](/)
-
-## Version Management
-
-There's not much to version management as it's a very simple handler of semver increments.
-
-### Initialise Versioning
-
-To work with `commitlog release` you'll need a `.commitlog.release` file in your repo and that can be added using the following command. This will set the initial version to be `v0.0.0` when starting and you can sync it with you current package version manually by changing the file.
-(We wish to add automatic syncing with major language version management systems but I'll need help due to low bandwidth)
-
-```sh
-$ commitlog release init
-```
-
-### Increments
-
-You can then run the `commitlog release` command to initialise the TUI flow for selecting the next version or you can do the same using the flags if you are in a **non-interactive** environment.
-
-**Note**: Increments are of the standard semver spec with the minor change of pre-releases being called **beta** releases
diff --git a/scripts/generate-docs.sh b/scripts/generate-docs.sh
index 5bbfc4a..c5c63ea 100755
--- a/scripts/generate-docs.sh
+++ b/scripts/generate-docs.sh
@@ -1,11 +1,11 @@
 #!/usr/bin/env bash
 
-mkdir -p docs 
-cp ./README.md ./docs/index.md
 curl -o mudkip.tgz -L https://github.com/barelyhuman/mudkip/releases/latest/download/linux-amd64.tgz
 tar -xvzf mudkip.tgz
 install linux-amd64/mudkip /usr/local/bin
 
-mudkip --stylesheet="./docs/styles.css" --baseurl='/commitlog/'
+./scripts/get-release-urls.sh
+
+mudkip --baseurl='/commitlog/'
 
 
diff --git a/scripts/get-release-urls.sh b/scripts/get-release-urls.sh
new file mode 100755
index 0000000..94696ae
--- /dev/null
+++ b/scripts/get-release-urls.sh
@@ -0,0 +1,27 @@
+#!/usr/bin/env bash
+
+curl -sL https://api.github.com/repos/barelyhuman/commitlog/releases | jq '[ .[0].assets[] | {name:.name,url:.url} ]' > api_urls.json
+
+cat >./docs/download.md<<EOF
+<!-- meta -->
+<title>
+    commitlog | downloads
+</title>
+<meta name="description" content="commits to changelog generator">
+<!-- meta end -->
+
+### [commitlog](/)
+
+[Manual](/manual)       
+[Download &darr;](/download)
+
+#### Downloads
+
+EOF
+
+jq -c '.[]' api_urls.json | while read i; do
+    url=$(echo $i | jq '.url' --raw-output)
+    name=$(echo $i | jq '.name' --raw-output)
+    bdurl=$(curl -sL $url | jq '.browser_download_url')
+    echo "[$name]($bdurl)    " >> ./docs/download.md
+done
\ No newline at end of file

From 9c4b170c88156a20554c0e962a07d5ae82e2ccf4 Mon Sep 17 00:00:00 2001
From: Reaper <ahoy@barelyhuman.dev>
Date: Sun, 26 Jun 2022 17:34:14 +0530
Subject: [PATCH 15/51] base style for docs

---
 docs/styles.css          | 80 ++++++++++++++++++++++++++++++++++++++++
 scripts/generate-docs.sh |  2 +-
 2 files changed, 81 insertions(+), 1 deletion(-)
 create mode 100644 docs/styles.css

diff --git a/docs/styles.css b/docs/styles.css
new file mode 100644
index 0000000..d795fbc
--- /dev/null
+++ b/docs/styles.css
@@ -0,0 +1,80 @@
+@import url("https://fonts.googleapis.com/css2?family=Fira+Code:wght@400;600;700&display=swap");
+
+html {
+    font-size: 87.5%;
+    /*14px*/
+}
+
+body {
+    max-width: 100ch;
+    margin: 0 auto;
+    padding: 1em;
+
+    font-family: "Fira Code", monospace;
+    font-weight: 400;
+    line-height: 1.75;
+}
+
+h1,
+h2,
+h3,
+h4,
+h5 {
+    margin: 3rem 0 1.38rem;
+    font-family: "Fira Code", monospace;
+    font-weight: 400;
+    line-height: 1.3;
+}
+
+h1 {
+    margin-top: 0;
+    font-size: 3.052rem;
+}
+
+h2 {
+    font-size: 2.441rem;
+}
+
+h3 {
+    font-size: 1.953rem;
+}
+
+h4 {
+    font-size: 1.563rem;
+}
+
+h5 {
+    font-size: 1.25rem;
+}
+
+small,
+.text_small {
+    font-size: 0.8rem;
+}
+
+pre,
+code {
+    font-size: 1rem;
+}
+
+code {
+    padding: 5px;
+    border: 1px solid slategray;
+}
+
+pre {
+    padding: 10px;
+    border: 1px solid slategray;
+}
+
+pre>code {
+    border: 0px;
+}
+
+a {
+    color: inherit;
+}
+
+a:hover {
+    color: dodgerblue;
+}
\ No newline at end of file
diff --git a/scripts/generate-docs.sh b/scripts/generate-docs.sh
index c5c63ea..40dbe1a 100755
--- a/scripts/generate-docs.sh
+++ b/scripts/generate-docs.sh
@@ -6,6 +6,6 @@ install linux-amd64/mudkip /usr/local/bin
 
 ./scripts/get-release-urls.sh
 
-mudkip --baseurl='/commitlog/'
+mudkip --baseurl='/commitlog/' --stylesheet="./docs/styles.css"
 
 

From 61904b7d9003277860d8b60b8e53c90d29aa4bdb Mon Sep 17 00:00:00 2001
From: Reaper <ahoy@barelyhuman.dev>
Date: Sun, 26 Jun 2022 18:14:38 +0530
Subject: [PATCH 16/51] docs: manual update for basics

---
 docs/manual.md  | 193 +++++++++++++++++++++++++++++++++++++++++++++++-
 docs/styles.css |  29 +++++++-
 2 files changed, 217 insertions(+), 5 deletions(-)

diff --git a/docs/manual.md b/docs/manual.md
index 5a53383..eb81808 100644
--- a/docs/manual.md
+++ b/docs/manual.md
@@ -12,4 +12,195 @@
 
 # Manual
 
-TBD
+- [Basics](#basics)
+  - [generate](#generate)
+  - [release](#release)
+- [Advanced](#advanced)
+- [CLI](#cli)
+
+<h3 id="basics">Basics</h3>
+
+**_`commitlog`_** come with 2 basic functionalities
+
+- Generating commits as changelogs in markdown
+- Managing your version and tags
+
+Both the above are available as sub commands and we'll go through each one by
+one.
+
+Just running `commitlog` no longer works as it did in v1, you'll need to specify
+a sub command to get it working.
+
+This has been done to keep it simpler to keep arbitrary behaviour to a minimum
+
+<h4 id="generate">generate</h3>
+
+The first one is `generate` and in most cases you'll just be using this to
+handle generation of commits as a list of markdown notes
+
+Here's an example of what it'll look like to run the `generate` sub-command
+
+```sh
+$ commitlog generate
+# or 
+$ commitlog g
+```
+
+**Output**:
+
+```md
+## All Changes
+87ce3fc76b252908cdd81f9537713f8d67813652 chore: v2.0.0-beta.0
+
+09fc85c0d1d52d770bbbf39ac45907103a53d354 refactor: swap go-git for push with exec
+
+5bafe9d105298001707c7c816e60d3ef0257a816 fix: tag creation
+
+909fd032facdeb4fb7633a4fad82dced28e8de83 chore: swap debugging logger with stderr printer
+<!-- .... more commits till the end of tag -->
+```
+
+The behaviour of the `generate` command is like so
+
+- go through all commits from the current `HEAD` (commit with the `HEAD`
+  reference) till the last commit or the most recent tagged commit.
+- the other case is where if the latest commit is also a tagged commit, it'll
+  still go till the most recent tagged commit.
+
+  eg: v0.0.2 -> HEAD, v0.0.1 -> SOMEHASH, would give you the commits between
+  both the tags.
+
+This is the default behavior of commitlog and can be changed by passing various
+flags which you'll read about soon.
+
+<h4 id="release">release</h3>
+
+The `release` sub-command is a complimentary sub-command added to commitlog to
+help you with managing release versions. I understand that most languages have
+their own package version management and you might want to work with them but
+that's also why the `release` sub-command isn't something you need, it's there
+for cases where you might wanna use it.
+
+My primary usecase is when working with repositories that work with multiple
+languages and I'd prefer a unified version.
+
+The `release` command doesn't modify your source code files but instead handles
+the version with it's own file named `.commitlog.release`, which just holds the
+**version** number right now and while this does have the X.X.X format (semantic
+versioning format) the increments or how you handle them doesn't have to be.
+
+The command is flexible enough for you to combine and create your own way of
+versioning.
+
+##### Initialize
+
+```sh
+$ commitlog release --init
+# or 
+$ commitlog r --init
+```
+
+Once initialized, you'll see a `.commitlog.release` file in your repo with the
+version `v0.0.0` to start with.
+
+##### Increments
+
+Post that you can use the remaining flags to help you incrementing the version
+as needed.
+
+```sh
+$ commitlog r --major # change to v1.0.0
+$ commitlog r --minor # change to v0.1.0
+$ commitlog r --patch # change to v0.0.1
+$ commitlog r --pre # change to v0.0.0-beta.0
+$ commitlog r --pre --pre-tag="dev" # change to v0.0.0-dev.0
+
+# or go bonkers 
+$ commitlog r --patch --pre --pre-tag="dev" # change to v0.0.1-dev.0
+$ commitlog r --major --patch --pre --pre-tag="dev" # change to v1.0.1-dev.0
+```
+
+#### Git actions
+
+Most times you'd also want a tool like this to create commits and tags for you
+which is fair, so `release` does come with a few git actions.
+
+- `--commit` (will create a commit and tag it for you)
+- `--push` (will push the commits and tags for you)
+
+The whole command would look a little something like this
+
+```sh
+$ commitlog r --patch --commit --push
+```
+
+<h3 id="advanced">Advanced</h3>
+
+**TBD**
+
+<h3 id="cli">CLI</h3>
+
+This is the entire CLI reference, which you can also access by using the `-h`
+flag on the downloaded binary.
+
+**`commitlog -h`**
+
+```
+NAME:
+   commitlog - commits to changelogs
+
+USAGE:
+   commitlog [global options] command [command options] [arguments...]
+
+COMMANDS:
+   generate, g  commits to changelogs
+   release, r   manage .commitlog.release version
+   help, h      Shows a list of commands or help for one command
+
+GLOBAL OPTIONS:
+   --help, -h  show help (default: false)
+```
+
+---
+
+**`commitlog g -h`**
+
+```
+NAME:
+   commitlog generate - commits to changelogs
+
+USAGE:
+   commitlog generate [command options] [arguments...]
+
+OPTIONS:
+   --categories value       categories to use, includes all commits by default. any text you add here will be used to create categories out of the commits
+   --end END, -e END        END reference for the commit to stop including commits at.This is exclusive of the given commit reference
+   --out FILE, -o FILE      path to the output FILE
+   --path PATH, -p PATH     root with the '.git' folder PATH (default: ".")
+   --promo                  add promo text to the end of output (default: false)
+   --start START, -s START  START reference for the commit to include commits from,This is inclusive of the given commit reference
+   --stdio                  print to the stdout (default: true)
+```
+
+---
+
+**`commitlog r -h`**
+
+```
+NAME:
+   commitlog release - manage .commitlog.release version
+
+USAGE:
+   commitlog release [command options] [arguments...]
+
+OPTIONS:
+   --commit              if true will create a commit and tag, of the changed version (default: false)
+   --init                initialise commitlog release (default: false)
+   --major               create a major version (default: false)
+   --minor               create a minor version (default: false)
+   --patch               create a patch version (default: false)
+   --path PATH, -p PATH  PATH to a folder where .commitlog.release exists or is to be created.(note: do not use `--commit` or `--push` if the file isn't in the root) (default: ".")
+   --pre                 create a pre-release version. will default to patch increment unlessspecified and not already a pre-release (default: false)
+   --pre-tag value       create a pre-release version (default: "beta")
+   --push                if true will create push the created release commit + tag on origin (default: false)
+```
diff --git a/docs/styles.css b/docs/styles.css
index d795fbc..3c159a3 100644
--- a/docs/styles.css
+++ b/docs/styles.css
@@ -1,5 +1,19 @@
 @import url("https://fonts.googleapis.com/css2?family=Fira+Code:wght@400;600;700&display=swap");
 
+
+:root {
+    --base: #fff;
+    --surface: #efefef;
+    --text: #333;
+    --muted: #444;
+    --accent: dodgerblue;
+}
+
+html,
+body {
+    background: var(--base);
+}
+
 html {
     font-size: 87.5%;
     /*14px*/
@@ -9,7 +23,7 @@ body {
     max-width: 100ch;
     margin: 0 auto;
     padding: 1em;
-
+    color: var(--text);
     font-family: "Fira Code", monospace;
     font-weight: 400;
     line-height: 1.75;
@@ -59,15 +73,17 @@ code {
 
 code {
     padding: 5px;
-    border: 1px solid slategray;
+    border: 1px solid var(--surface);
 }
 
 pre {
+    white-space: pre-wrap;
     padding: 10px;
-    border: 1px solid slategray;
+    border: 1px solid var(--surface);
 }
 
 pre>code {
+    padding: 0px;
     border: 0px;
 }
 
@@ -76,5 +92,10 @@ a {
 }
 
 a:hover {
-    color: dodgerblue;
+    color: var(--accent);
+}
+
+hr {
+    border: 0px;
+    border-top: 1px solid var(--surface);
 }
\ No newline at end of file

From d669db159928420bea185226a5332985cdc124e7 Mon Sep 17 00:00:00 2001
From: Reaper <ahoy@barelyhuman.dev>
Date: Sun, 26 Jun 2022 18:15:26 +0530
Subject: [PATCH 17/51] remove generation to local

---
 scripts/generate-docs.sh | 2 --
 1 file changed, 2 deletions(-)

diff --git a/scripts/generate-docs.sh b/scripts/generate-docs.sh
index 40dbe1a..ee3c79a 100755
--- a/scripts/generate-docs.sh
+++ b/scripts/generate-docs.sh
@@ -4,8 +4,6 @@ curl -o mudkip.tgz -L https://github.com/barelyhuman/mudkip/releases/latest/down
 tar -xvzf mudkip.tgz
 install linux-amd64/mudkip /usr/local/bin
 
-./scripts/get-release-urls.sh
-
 mudkip --baseurl='/commitlog/' --stylesheet="./docs/styles.css"
 
 

From 51409cc40531d2660bba2660fde827a00f10ac06 Mon Sep 17 00:00:00 2001
From: Reaper <ahoy@barelyhuman.dev>
Date: Sun, 26 Jun 2022 18:17:19 +0530
Subject: [PATCH 18/51] styles: dark mode

---
 docs/styles.css | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/docs/styles.css b/docs/styles.css
index 3c159a3..650d401 100644
--- a/docs/styles.css
+++ b/docs/styles.css
@@ -9,6 +9,16 @@
     --accent: dodgerblue;
 }
 
+@media (prefers-color-scheme:dark) {
+    :root {
+        --base: #111;
+        --surface: #333;
+        --text: #eee;
+        --muted: #ddd;
+        --accent: dodgerblue;
+    }
+}
+
 html,
 body {
     background: var(--base);

From fefc89475e08883646034b65ada20f4dd5e601e2 Mon Sep 17 00:00:00 2001
From: Reaper <ahoy@barelyhuman.dev>
Date: Sun, 26 Jun 2022 21:27:05 +0530
Subject: [PATCH 19/51] docs: add advanced cases to the manual

---
 docs/manual.md | 120 +++++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 117 insertions(+), 3 deletions(-)

diff --git a/docs/manual.md b/docs/manual.md
index eb81808..9eb5e2c 100644
--- a/docs/manual.md
+++ b/docs/manual.md
@@ -16,6 +16,9 @@
   - [generate](#generate)
   - [release](#release)
 - [Advanced](#advanced)
+  - [Selective Log Ranges](#selective-log-ranges)
+  - [From a different repo](#from-a-different-repo)
+  - [Categorize](#categorize)
 - [CLI](#cli)
 
 <h3 id="basics">Basics</h3>
@@ -70,8 +73,21 @@ The behaviour of the `generate` command is like so
   eg: v0.0.2 -> HEAD, v0.0.1 -> SOMEHASH, would give you the commits between
   both the tags.
 
-This is the default behavior of commitlog and can be changed by passing various
-flags which you'll read about soon.
+The default behaviour of **_commitlog_** is to print to the stdout of your
+terminal which might not be what you wish to do.
+
+So, if you wish to ever write to a file , you can use the `--out FILE` flag to
+write the output to a file instead.
+
+```sh
+$ commitlog g -o ./CHANGELOG.md
+```
+
+> **Note**: commitlog will overwrite the file with the new output, make sure you
+> create a backup of the file when working with this.
+
+> **Note**: In coming versions an append mode will be added to the CLI to avoid
+> having to deal with this manually
 
 <h4 id="release">release</h3>
 
@@ -136,7 +152,105 @@ $ commitlog r --patch --commit --push
 
 <h3 id="advanced">Advanced</h3>
 
-**TBD**
+These are not really hard to guess or achieve but are in the advanced section as
+this isn't something a beginner user might need to mess with. If you have other
+use cases that you feel like should be added here, raise a issue.
+
+<h4 id="selective-log-ranges">Selective Log Ranges</h4>
+There's enough cases where the entire history between the tags makes no sense. You might just want a specific set of commits and this is very easy to do with commitlog
+
+```sh
+$ commitlog g --start HEAD --end HEAD~3 
+# would return the last 3 commits
+```
+
+And as you might have understood, commitlog does work with git's revision system
+so you can reuse git's own revision pointers as needed. Though it's mostly
+easier to just use the HASH since, finding the hashes in `git log` is easier
+than finding the number you have to type after the `HEAD~`
+
+<h4 id="from-a-different-repo">From a different repo</h4>
+A lot more often you might need to generate logs for a sub-repo when working with a huge multirepo folder which a lot of sub-modules and switching worktree for the changelog might not be something you wish to do.
+
+In cases like these the `-p` or `--path` flag can be used with the `generate`
+flag
+
+```sh
+$ commitlog g -p ./sub/module -s HEAD~3 
+# would return the commits from HEAD~3 to the next tag or end of all commits.
+```
+
+<h4 id="categorize">Categorize</h4>
+You wouldn't be using commitlog otherwise so this obviously has to exist.
+
+As for why is this turned off by default? I just don't use commit standards and
+mostly just need the commits between tags and very rarely need the categories to
+help me but doesn't change the fact that someone else might need it.
+
+So, how does commitlog categorize? using regex's , or more like comma seperated
+regex's.
+
+The implementation approach might bring some issue but I'm going to wait for
+them instead of over fixing something that might never really happen.
+
+Anyway, a simple example for a non-scoped commitlint styled categorization would
+look something like this .
+
+```sh
+$ commitlog g --categories="feat:,fix:"
+```
+
+**Output:**
+
+```md
+## feat:
+110c9b260e6de1e2be9af28b3592c373ab6fc501 feat: handling for pre increment
+
+9080580575d3579b3d11dd114830eb128f0c8130 feat: releaser base maj,min,patch setup
+
+b513e53cbbc30e5b667fbba373b9589911a47ac0 feat: generator subcommand implementation
+
+## fix:
+5bafe9d105298001707c7c816e60d3ef0257a816 fix: tag creation
+```
+
+This could be made a little more neater using a better regex like so
+
+```sh
+$ commitlog g --categories="^feat,^fix"
+```
+
+**Output**:
+
+```md
+## ^feat
+e0ce9c693c554158b7b4841b799524164d9c3e83 feat(releaser): add init and pre-tag handlers
+
+110c9b260e6de1e2be9af28b3592c373ab6fc501 feat: handling for pre increment
+
+9080580575d3579b3d11dd114830eb128f0c8130 feat: releaser base maj,min,patch setup
+
+b513e53cbbc30e5b667fbba373b9589911a47ac0 feat: generator subcommand implementation
+
+## ^fix
+5bafe9d105298001707c7c816e60d3ef0257a816 fix: tag creation
+
+540bb3d7419aab314fdb999dd57eeac3c53f5fad fix doc generation
+
+87d40ddbd463ad71b3af8b7edb8ac8176ecbf2f5 fix tests for new param
+```
+
+As visible, you find more commits in the 2nd one since the regex matches more
+cases and gives you more information. You are free to modify these to make them
+work with other patterns that you might follow.
+
+Also the titles are going to be the regex's you pass. A future version will add
+a way for you to add label's to the regex though that's a little harder to
+achieve without making the flags very verbose so I've avoided it for now.
+
+> **Note**: This is the initial implementation of this and might change in a
+> future major version since this flag feels a little more frictional than the
+> other approaches I have in mind. Feel free to recommend other ways to do this.
 
 <h3 id="cli">CLI</h3>
 

From 279ba7803143fdc4a453914d269ddb30604e1623 Mon Sep 17 00:00:00 2001
From: Reaper <ahoy@barelyhuman.dev>
Date: Sun, 26 Jun 2022 21:27:16 +0530
Subject: [PATCH 20/51] doc: fix redir link to manual page

---
 docs/index.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/docs/index.md b/docs/index.md
index 6184909..b4ba47c 100644
--- a/docs/index.md
+++ b/docs/index.md
@@ -17,7 +17,7 @@
 - [About](#about)
   - [Philosophy](#philosophy)
   - [Installation](#installation)
-- [Manual](#manual)
+- [Manual](/manual)
 - [License](#license)
 
 <h4 id="quick-start">Quick Start</h4>

From af791af3427a3872c4b92541d436dfcd9d3533b5 Mon Sep 17 00:00:00 2001
From: Reaper <ahoy@barelyhuman.dev>
Date: Mon, 27 Jun 2022 11:14:58 +0530
Subject: [PATCH 21/51] add generic api guide

---
 docs/api.md                 | 81 +++++++++++++++++++++++++++++++++++++
 docs/download.md            |  3 +-
 docs/index.md               |  6 +--
 docs/manual.md              |  4 +-
 docs/styles.css             |  4 +-
 scripts/get-release-urls.sh |  4 +-
 6 files changed, 92 insertions(+), 10 deletions(-)
 create mode 100644 docs/api.md

diff --git a/docs/api.md b/docs/api.md
new file mode 100644
index 0000000..9262899
--- /dev/null
+++ b/docs/api.md
@@ -0,0 +1,81 @@
+<!-- meta -->
+<title>
+    commitlog | manual
+</title>
+<meta name="description" content="commits to changelog generator">
+<!-- meta end -->
+
+### [commitlog](/)
+
+[Home](/) [Manual](/manual) [Download &darr;](/download) [API](/api)
+
+# API
+
+### General Guide
+
+commitlog also comes as a pkg that you could reuse to modify the behaviour of
+the commands and this is very limited at the moment since I'm still working on
+the best way to get plugins to work with the original CLI instead of having to
+write your own version of commitlog.
+
+The pkg contains the 2 base command's creators and behaviour modifiers, or more
+commonly known as the golang options pattern.
+
+Briefly put, You have one function that takes in unlimited amount of functions
+as parameter with each of these parameter functions being able to modify the
+behaviour of the returned instance.
+
+Easy way to explain this is with an example of the `releaser` API
+
+```go
+package main
+
+import (
+	"log"
+
+	"github.com/barelyhuman/commitlog/pkg"
+)
+
+func main() {
+	versionString := "v0.0.1"
+	releaser, _ := pkg.CreateNewReleaser(
+		versionString,
+		pkg.WithMajorIncrement(),
+	)
+
+	log.Println(releaser.String())
+
+}
+```
+
+here the `pkg.CreateNewReleaser` takes in one mandatory value which is the
+`versionString` and the 2nd parameter is optional here.
+
+Though, since we wish for the releaser to have a custom behaviour everytime the
+flags change, instead of writing entire functionalities inside various releaser
+functions, which would look like so
+
+```go
+releaser.IncrementMajor()
+releaser.IncrementMinor()
+```
+
+I'd be unable to expose the builders / option functions out to the public for
+them to write custom behaviours that work directly with the `struct` being used
+by commitlog itself and instead you'd be writing wrappers around existing
+functions. Thus, adding another layer of abstraction which isn't needed for
+something that wants to be extended.
+
+This approach gives me the ability to expose a selected few properties for you
+to modify while writing your own builder/option function.
+
+The only pointer functions that releaser has is the one's that'll help with
+printing or identifying the final version's state.
+
+Since, you now know how the API is written, the go doc for this module should be
+able to help you with the remaining.
+
+[godoc&nearr;](https://pkg.go.dev/github.com/barelyhuman/commitlog)
+
+> **Note**: if the go doc still hasn't been generated for v2.0.0, please go
+> through the source code to help you with the implementation details
diff --git a/docs/download.md b/docs/download.md
index 29e647e..a83fd94 100644
--- a/docs/download.md
+++ b/docs/download.md
@@ -7,8 +7,7 @@
 
 ### [commitlog](/)
 
-[Manual](/manual)\
-[Download &darr;](/download)
+[Home](/) [Manual](/manual) [Download &darr;](/download) [API](/api)
 
 #### Downloads
 
diff --git a/docs/index.md b/docs/index.md
index b4ba47c..6580969 100644
--- a/docs/index.md
+++ b/docs/index.md
@@ -7,8 +7,7 @@
 
 ### [commitlog](/)
 
-[Manual](/manual)\
-[Download &darr;](/download)
+[Home](/) [Manual](/manual) [Download &darr;](/download) [API](/api)
 
 #### Index
 
@@ -123,4 +122,5 @@ PATH variables
 
 <h4 id="license">License</h4>
 
-commitlog is MIT Licensed and you can read the entire license in the [source code](https://github.com/barelyhuman/commitlog)
+commitlog is MIT Licensed and you can read the entire license in the
+[source code](https://github.com/barelyhuman/commitlog)
diff --git a/docs/manual.md b/docs/manual.md
index 9eb5e2c..1e7986a 100644
--- a/docs/manual.md
+++ b/docs/manual.md
@@ -7,8 +7,7 @@
 
 ### [commitlog](/)
 
-[Manual](/manual)\
-[Download &darr;](/download)
+[Home](/) [Manual](/manual) [Download &darr;](/download) [API](/api)
 
 # Manual
 
@@ -20,6 +19,7 @@
   - [From a different repo](#from-a-different-repo)
   - [Categorize](#categorize)
 - [CLI](#cli)
+- [API](/api)
 
 <h3 id="basics">Basics</h3>
 
diff --git a/docs/styles.css b/docs/styles.css
index 650d401..490da3a 100644
--- a/docs/styles.css
+++ b/docs/styles.css
@@ -1,6 +1,5 @@
 @import url("https://fonts.googleapis.com/css2?family=Fira+Code:wght@400;600;700&display=swap");
 
-
 :root {
     --base: #fff;
     --surface: #efefef;
@@ -9,7 +8,7 @@
     --accent: dodgerblue;
 }
 
-@media (prefers-color-scheme:dark) {
+@media (prefers-color-scheme: dark) {
     :root {
         --base: #111;
         --surface: #333;
@@ -99,6 +98,7 @@ pre>code {
 
 a {
     color: inherit;
+    text-underline-offset: 4px;
 }
 
 a:hover {
diff --git a/scripts/get-release-urls.sh b/scripts/get-release-urls.sh
index 94696ae..923e734 100755
--- a/scripts/get-release-urls.sh
+++ b/scripts/get-release-urls.sh
@@ -1,3 +1,4 @@
+
 #!/usr/bin/env bash
 
 curl -sL https://api.github.com/repos/barelyhuman/commitlog/releases | jq '[ .[0].assets[] | {name:.name,url:.url} ]' > api_urls.json
@@ -12,8 +13,9 @@ cat >./docs/download.md<<EOF
 
 ### [commitlog](/)
 
-[Manual](/manual)       
+[Manual](/manual)
 [Download &darr;](/download)
+[API](/api)
 
 #### Downloads
 

From 721588ed24e3cddcc085c89e41b0839d43dd1d1f Mon Sep 17 00:00:00 2001
From: Reaper <ahoy@barelyhuman.dev>
Date: Mon, 27 Jun 2022 11:20:42 +0530
Subject: [PATCH 22/51] update blockquote style

---
 docs/api.md                 | 2 +-
 docs/download.md            | 2 +-
 docs/index.md               | 2 +-
 docs/manual.md              | 2 +-
 docs/styles.css             | 7 +++++++
 scripts/get-release-urls.sh | 4 +---
 6 files changed, 12 insertions(+), 7 deletions(-)

diff --git a/docs/api.md b/docs/api.md
index 9262899..ac931a4 100644
--- a/docs/api.md
+++ b/docs/api.md
@@ -7,7 +7,7 @@
 
 ### [commitlog](/)
 
-[Home](/) [Manual](/manual) [Download &darr;](/download) [API](/api)
+[Home](/) [Manual](/manual) [Download](/download) [API](/api)
 
 # API
 
diff --git a/docs/download.md b/docs/download.md
index a83fd94..1defd0c 100644
--- a/docs/download.md
+++ b/docs/download.md
@@ -7,7 +7,7 @@
 
 ### [commitlog](/)
 
-[Home](/) [Manual](/manual) [Download &darr;](/download) [API](/api)
+[Home](/) [Manual](/manual) [Download](/download) [API](/api)
 
 #### Downloads
 
diff --git a/docs/index.md b/docs/index.md
index 6580969..ada821f 100644
--- a/docs/index.md
+++ b/docs/index.md
@@ -7,7 +7,7 @@
 
 ### [commitlog](/)
 
-[Home](/) [Manual](/manual) [Download &darr;](/download) [API](/api)
+[Home](/) [Manual](/manual) [Download](/download) [API](/api)
 
 #### Index
 
diff --git a/docs/manual.md b/docs/manual.md
index 1e7986a..e3c79c8 100644
--- a/docs/manual.md
+++ b/docs/manual.md
@@ -7,7 +7,7 @@
 
 ### [commitlog](/)
 
-[Home](/) [Manual](/manual) [Download &darr;](/download) [API](/api)
+[Home](/) [Manual](/manual) [Download](/download) [API](/api)
 
 # Manual
 
diff --git a/docs/styles.css b/docs/styles.css
index 490da3a..8791f50 100644
--- a/docs/styles.css
+++ b/docs/styles.css
@@ -108,4 +108,11 @@ a:hover {
 hr {
     border: 0px;
     border-top: 1px solid var(--surface);
+}
+
+blockquote {
+    margin: 0px;
+    padding: 0px;
+    border-left: 2px solid var(--muted);
+    padding-left: 10px;
 }
\ No newline at end of file
diff --git a/scripts/get-release-urls.sh b/scripts/get-release-urls.sh
index 923e734..5bfa639 100755
--- a/scripts/get-release-urls.sh
+++ b/scripts/get-release-urls.sh
@@ -13,9 +13,7 @@ cat >./docs/download.md<<EOF
 
 ### [commitlog](/)
 
-[Manual](/manual)
-[Download &darr;](/download)
-[API](/api)
+[Home](/) [Manual](/manual) [Download](/download) [API](/api)
 
 #### Downloads
 

From 83c5ef6621bb2802e1b9bf2b1d47533c55599e06 Mon Sep 17 00:00:00 2001
From: Reaper <ahoy@barelyhuman.dev>
Date: Mon, 27 Jun 2022 11:25:05 +0530
Subject: [PATCH 23/51] chore: use the helper

---
 pkg/releaser.go | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/pkg/releaser.go b/pkg/releaser.go
index faa0521..17cf6b4 100644
--- a/pkg/releaser.go
+++ b/pkg/releaser.go
@@ -112,7 +112,7 @@ func WithPrereleaseIncrement() ReleaserMod {
 	return func(r *Releaser) {
 
 		// if a pre string already exists
-		if len(r.v.preString) > 0 {
+		if r.HasPrerelease() {
 			preParts := strings.Split(r.v.preString, ".")
 			prePointer, _ := strconv.Atoi(preParts[1])
 			prePointer += 1

From 25a9185d40ff7023024ea57de9c0847734a758f7 Mon Sep 17 00:00:00 2001
From: Reaper <ahoy@barelyhuman.dev>
Date: Mon, 19 Sep 2022 15:14:15 +0530
Subject: [PATCH 24/51] fix: pre release string resets

---
 .commitlog.release  |  2 +-
 commands/release.go | 11 ++++++++---
 main.go             |  7 ++++++-
 pkg/releaser.go     |  4 +++-
 4 files changed, 18 insertions(+), 6 deletions(-)

diff --git a/.commitlog.release b/.commitlog.release
index c2bdfd2..81ef58f 100755
--- a/.commitlog.release
+++ b/.commitlog.release
@@ -1 +1 @@
-v2.0.0-beta.0
\ No newline at end of file
+v2.0.1
\ No newline at end of file
diff --git a/commands/release.go b/commands/release.go
index 2a79d33..bd3f527 100644
--- a/commands/release.go
+++ b/commands/release.go
@@ -18,6 +18,11 @@ func Release(c *cli.Context) (err error) {
 	fileDir := c.String("path")
 	filePath := path.Join(fileDir, ".commitlog.release")
 
+	if !(c.Bool("init") || c.Bool("major") || c.Bool("minor") || c.Bool("patch") || c.Bool("pre")) {
+		err = fmt.Errorf("[commitlog] need at least one increment flag to move ahead")
+		return
+	}
+
 	if c.Bool("init") {
 		_, err = os.Stat(filePath)
 		if os.IsNotExist(err) {
@@ -54,15 +59,15 @@ func Release(c *cli.Context) (err error) {
 	}
 
 	if c.Bool("major") {
-		releaserOpts = append(releaserOpts, pkg.WithMajorIncrement(), pkg.WithMinorReset(), pkg.WithPatchReset())
+		releaserOpts = append(releaserOpts, pkg.WithClearPrerelease(), pkg.WithMajorIncrement(), pkg.WithMinorReset(), pkg.WithPatchReset())
 	}
 
 	if c.Bool("minor") {
-		releaserOpts = append(releaserOpts, pkg.WithMinorIncrement(), pkg.WithPatchReset())
+		releaserOpts = append(releaserOpts, pkg.WithClearPrerelease(), pkg.WithMinorIncrement(), pkg.WithPatchReset())
 	}
 
 	if c.Bool("patch") {
-		releaserOpts = append(releaserOpts, pkg.WithPatchIncrement())
+		releaserOpts = append(releaserOpts, pkg.WithClearPrerelease(), pkg.WithPatchIncrement())
 	}
 
 	if c.Bool("pre") {
diff --git a/main.go b/main.go
index f975fee..7d42821 100644
--- a/main.go
+++ b/main.go
@@ -81,6 +81,7 @@ func main() {
 				Flags: []cli.Flag{
 					&cli.BoolFlag{
 						Name:  "init",
+						Value: false,
 						Usage: "initialise commitlog release",
 					},
 					&cli.StringFlag{
@@ -91,7 +92,8 @@ func main() {
 							"(note: do not use `--commit` or `--push` if the file isn't in the root)",
 					},
 					&cli.BoolFlag{
-						Name: "pre",
+						Name:  "pre",
+						Value: false,
 						Usage: "create a pre-release version. will default to patch increment unless" +
 							"specified and not already a pre-release",
 					},
@@ -102,14 +104,17 @@ func main() {
 					},
 					&cli.BoolFlag{
 						Name:  "major",
+						Value: false,
 						Usage: "create a major version",
 					},
 					&cli.BoolFlag{
 						Name:  "minor",
+						Value: false,
 						Usage: "create a minor version",
 					},
 					&cli.BoolFlag{
 						Name:  "patch",
+						Value: false,
 						Usage: "create a patch version",
 					},
 					&cli.BoolFlag{
diff --git a/pkg/releaser.go b/pkg/releaser.go
index 17cf6b4..22997e3 100644
--- a/pkg/releaser.go
+++ b/pkg/releaser.go
@@ -172,7 +172,9 @@ func WithPrereleaseReset() ReleaserMod {
 		preParts := strings.Split(r.v.preString, ".")
 		// reset something like `beta.1` to `beta.0`
 		preParts[1] = strconv.Itoa(0)
-		r.next.preString = strings.Join(preParts[:], ".")
+		nextPreString := strings.Join(preParts[:], ".")
+		nextPreString = strings.TrimPrefix(nextPreString, "-")
+		r.next.preString = nextPreString
 	}
 }
 

From faf22fe8c91aaa8c0f8005298f8bd3fe43999961 Mon Sep 17 00:00:00 2001
From: Reaper <ahoy@barelyhuman.dev>
Date: Mon, 19 Sep 2022 15:15:56 +0530
Subject: [PATCH 25/51] chore: v2.0.2

---
 .commitlog.release | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/.commitlog.release b/.commitlog.release
index 81ef58f..b02d37b 100755
--- a/.commitlog.release
+++ b/.commitlog.release
@@ -1 +1 @@
-v2.0.1
\ No newline at end of file
+v2.0.2
\ No newline at end of file

From 9e7c7b33cdb217e84ea489dc235f50f09b4c0f0e Mon Sep 17 00:00:00 2001
From: Reaper <ahoy@barelyhuman.dev>
Date: Mon, 19 Sep 2022 15:21:59 +0530
Subject: [PATCH 26/51] ci: update changelog generation

---
 .github/workflows/changelog.yml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/.github/workflows/changelog.yml b/.github/workflows/changelog.yml
index bf3dac6..f7c4406 100644
--- a/.github/workflows/changelog.yml
+++ b/.github/workflows/changelog.yml
@@ -16,7 +16,7 @@ jobs:
         id: generate_log
         run: |
           curl -sSL https://bina.egoist.sh/barelyhuman/commitlog | sh
-          commitlog > CHANGELOG.md
+          commitlog g > CHANGELOG.md
       - uses: ncipollo/release-action@v1
         with:
           bodyFile: "CHANGELOG.md"

From bb7d5123e68a7ee65842cce8416d5bedc2c452df Mon Sep 17 00:00:00 2001
From: Reaper <ahoy@barelyhuman.dev>
Date: Mon, 19 Sep 2022 15:38:03 +0530
Subject: [PATCH 27/51] update download links

---
 docs/download.md | 29 +++++++++++++++--------------
 1 file changed, 15 insertions(+), 14 deletions(-)

diff --git a/docs/download.md b/docs/download.md
index 1defd0c..238671c 100644
--- a/docs/download.md
+++ b/docs/download.md
@@ -11,30 +11,31 @@
 
 #### Downloads
 
-[commitlog-v2.0.0-beta.0-darwin-amd64.tar.gz]("https://github.com/barelyhuman/commitlog/releases/download/v2.0.0-beta.0/commitlog-v2.0.0-beta.0-darwin-amd64.tar.gz")
+[commitlog-v2.0.2-darwin-amd64.tar.gz]("https://github.com/barelyhuman/commitlog/releases/download/v2.0.2/commitlog-v2.0.2-darwin-amd64.tar.gz")
 
-[commitlog-v2.0.0-beta.0-darwin-amd64.tar.gz.md5]("https://github.com/barelyhuman/commitlog/releases/download/v2.0.0-beta.0/commitlog-v2.0.0-beta.0-darwin-amd64.tar.gz.md5")
+[commitlog-v2.0.2-darwin-amd64.tar.gz.md5]("https://github.com/barelyhuman/commitlog/releases/download/v2.0.2/commitlog-v2.0.2-darwin-amd64.tar.gz.md5")  
 
-[commitlog-v2.0.0-beta.0-darwin-arm64.tar.gz]("https://github.com/barelyhuman/commitlog/releases/download/v2.0.0-beta.0/commitlog-v2.0.0-beta.0-darwin-arm64.tar.gz")
+[commitlog-v2.0.2-darwin-arm64.tar.gz]("https://github.com/barelyhuman/commitlog/releases/download/v2.0.2/commitlog-v2.0.2-darwin-arm64.tar.gz")
 
-[commitlog-v2.0.0-beta.0-darwin-arm64.tar.gz.md5]("https://github.com/barelyhuman/commitlog/releases/download/v2.0.0-beta.0/commitlog-v2.0.0-beta.0-darwin-arm64.tar.gz.md5")
+[commitlog-v2.0.2-darwin-arm64.tar.gz.md5]("https://github.com/barelyhuman/commitlog/releases/download/v2.0.2/commitlog-v2.0.2-darwin-arm64.tar.gz.md5")  
 
-[commitlog-v2.0.0-beta.0-linux-386.tar.gz]("https://github.com/barelyhuman/commitlog/releases/download/v2.0.0-beta.0/commitlog-v2.0.0-beta.0-linux-386.tar.gz")
+[commitlog-v2.0.2-linux-386.tar.gz]("https://github.com/barelyhuman/commitlog/releases/download/v2.0.2/commitlog-v2.0.2-linux-386.tar.gz")
 
-[commitlog-v2.0.0-beta.0-linux-386.tar.gz.md5]("https://github.com/barelyhuman/commitlog/releases/download/v2.0.0-beta.0/commitlog-v2.0.0-beta.0-linux-386.tar.gz.md5")
+[commitlog-v2.0.2-linux-386.tar.gz.md5]("https://github.com/barelyhuman/commitlog/releases/download/v2.0.2/commitlog-v2.0.2-linux-386.tar.gz.md5")  
 
-[commitlog-v2.0.0-beta.0-linux-amd64.tar.gz]("https://github.com/barelyhuman/commitlog/releases/download/v2.0.0-beta.0/commitlog-v2.0.0-beta.0-linux-amd64.tar.gz")
+[commitlog-v2.0.2-linux-amd64.tar.gz]("https://github.com/barelyhuman/commitlog/releases/download/v2.0.2/commitlog-v2.0.2-linux-amd64.tar.gz")
 
-[commitlog-v2.0.0-beta.0-linux-amd64.tar.gz.md5]("https://github.com/barelyhuman/commitlog/releases/download/v2.0.0-beta.0/commitlog-v2.0.0-beta.0-linux-amd64.tar.gz.md5")
+[commitlog-v2.0.2-linux-amd64.tar.gz.md5]("https://github.com/barelyhuman/commitlog/releases/download/v2.0.2/commitlog-v2.0.2-linux-amd64.tar.gz.md5") 
 
-[commitlog-v2.0.0-beta.0-linux-arm64.tar.gz]("https://github.com/barelyhuman/commitlog/releases/download/v2.0.0-beta.0/commitlog-v2.0.0-beta.0-linux-arm64.tar.gz")
+[commitlog-v2.0.2-linux-arm64.tar.gz]("https://github.com/barelyhuman/commitlog/releases/download/v2.0.2/commitlog-v2.0.2-linux-arm64.tar.gz")
 
-[commitlog-v2.0.0-beta.0-linux-arm64.tar.gz.md5]("https://github.com/barelyhuman/commitlog/releases/download/v2.0.0-beta.0/commitlog-v2.0.0-beta.0-linux-arm64.tar.gz.md5")
+[commitlog-v2.0.2-linux-arm64.tar.gz.md5]("https://github.com/barelyhuman/commitlog/releases/download/v2.0.2/commitlog-v2.0.2-linux-arm64.tar.gz.md5")  
 
-[commitlog-v2.0.0-beta.0-windows-386.zip]("https://github.com/barelyhuman/commitlog/releases/download/v2.0.0-beta.0/commitlog-v2.0.0-beta.0-windows-386.zip")
+[commitlog-v2.0.2-windows-386.zip]("https://github.com/barelyhuman/commitlog/releases/download/v2.0.2/commitlog-v2.0.2-windows-386.zip")  
 
-[commitlog-v2.0.0-beta.0-windows-386.zip.md5]("https://github.com/barelyhuman/commitlog/releases/download/v2.0.0-beta.0/commitlog-v2.0.0-beta.0-windows-386.zip.md5")
+[commitlog-v2.0.2-windows-386.zip.md5]("https://github.com/barelyhuman/commitlog/releases/download/v2.0.2/commitlog-v2.0.2-windows-386.zip.md5")  
 
-[commitlog-v2.0.0-beta.0-windows-amd64.zip]("https://github.com/barelyhuman/commitlog/releases/download/v2.0.0-beta.0/commitlog-v2.0.0-beta.0-windows-amd64.zip")
+[commitlog-v2.0.2-windows-amd64.zip]("https://github.com/barelyhuman/commitlog/releases/download/v2.0.2/commitlog-v2.0.2-windows-amd64.zip")  
+
+[commitlog-v2.0.2-windows-amd64.zip.md5]("https://github.com/barelyhuman/commitlog/releases/download/v2.0.2/commitlog-v2.0.2-windows-amd64.zip.md5")
 
-[commitlog-v2.0.0-beta.0-windows-amd64.zip.md5]("https://github.com/barelyhuman/commitlog/releases/download/v2.0.0-beta.0/commitlog-v2.0.0-beta.0-windows-amd64.zip.md5")

From d43b5f170e1e8de7ec197fe934163d72e4134fdc Mon Sep 17 00:00:00 2001
From: reaper <ahoy@barelyhuman.dev>
Date: Tue, 24 Jan 2023 23:01:38 +0530
Subject: [PATCH 28/51] update binaries

---
 docs/download.md            | 42 +++++++++++++------------------------
 scripts/get-release-urls.sh |  2 +-
 2 files changed, 15 insertions(+), 29 deletions(-)

diff --git a/docs/download.md b/docs/download.md
index 238671c..3ce1944 100644
--- a/docs/download.md
+++ b/docs/download.md
@@ -11,31 +11,17 @@
 
 #### Downloads
 
-[commitlog-v2.0.2-darwin-amd64.tar.gz]("https://github.com/barelyhuman/commitlog/releases/download/v2.0.2/commitlog-v2.0.2-darwin-amd64.tar.gz")
-
-[commitlog-v2.0.2-darwin-amd64.tar.gz.md5]("https://github.com/barelyhuman/commitlog/releases/download/v2.0.2/commitlog-v2.0.2-darwin-amd64.tar.gz.md5")  
-
-[commitlog-v2.0.2-darwin-arm64.tar.gz]("https://github.com/barelyhuman/commitlog/releases/download/v2.0.2/commitlog-v2.0.2-darwin-arm64.tar.gz")
-
-[commitlog-v2.0.2-darwin-arm64.tar.gz.md5]("https://github.com/barelyhuman/commitlog/releases/download/v2.0.2/commitlog-v2.0.2-darwin-arm64.tar.gz.md5")  
-
-[commitlog-v2.0.2-linux-386.tar.gz]("https://github.com/barelyhuman/commitlog/releases/download/v2.0.2/commitlog-v2.0.2-linux-386.tar.gz")
-
-[commitlog-v2.0.2-linux-386.tar.gz.md5]("https://github.com/barelyhuman/commitlog/releases/download/v2.0.2/commitlog-v2.0.2-linux-386.tar.gz.md5")  
-
-[commitlog-v2.0.2-linux-amd64.tar.gz]("https://github.com/barelyhuman/commitlog/releases/download/v2.0.2/commitlog-v2.0.2-linux-amd64.tar.gz")
-
-[commitlog-v2.0.2-linux-amd64.tar.gz.md5]("https://github.com/barelyhuman/commitlog/releases/download/v2.0.2/commitlog-v2.0.2-linux-amd64.tar.gz.md5") 
-
-[commitlog-v2.0.2-linux-arm64.tar.gz]("https://github.com/barelyhuman/commitlog/releases/download/v2.0.2/commitlog-v2.0.2-linux-arm64.tar.gz")
-
-[commitlog-v2.0.2-linux-arm64.tar.gz.md5]("https://github.com/barelyhuman/commitlog/releases/download/v2.0.2/commitlog-v2.0.2-linux-arm64.tar.gz.md5")  
-
-[commitlog-v2.0.2-windows-386.zip]("https://github.com/barelyhuman/commitlog/releases/download/v2.0.2/commitlog-v2.0.2-windows-386.zip")  
-
-[commitlog-v2.0.2-windows-386.zip.md5]("https://github.com/barelyhuman/commitlog/releases/download/v2.0.2/commitlog-v2.0.2-windows-386.zip.md5")  
-
-[commitlog-v2.0.2-windows-amd64.zip]("https://github.com/barelyhuman/commitlog/releases/download/v2.0.2/commitlog-v2.0.2-windows-amd64.zip")  
-
-[commitlog-v2.0.2-windows-amd64.zip.md5]("https://github.com/barelyhuman/commitlog/releases/download/v2.0.2/commitlog-v2.0.2-windows-amd64.zip.md5")
-
+[commitlog-v2.0.2-darwin-amd64.tar.gz](https://github.com/barelyhuman/commitlog/releases/download/v2.0.2/commitlog-v2.0.2-darwin-amd64.tar.gz)    
+[commitlog-v2.0.2-darwin-amd64.tar.gz.md5](https://github.com/barelyhuman/commitlog/releases/download/v2.0.2/commitlog-v2.0.2-darwin-amd64.tar.gz.md5)    
+[commitlog-v2.0.2-darwin-arm64.tar.gz](https://github.com/barelyhuman/commitlog/releases/download/v2.0.2/commitlog-v2.0.2-darwin-arm64.tar.gz)    
+[commitlog-v2.0.2-darwin-arm64.tar.gz.md5](https://github.com/barelyhuman/commitlog/releases/download/v2.0.2/commitlog-v2.0.2-darwin-arm64.tar.gz.md5)    
+[commitlog-v2.0.2-linux-386.tar.gz](https://github.com/barelyhuman/commitlog/releases/download/v2.0.2/commitlog-v2.0.2-linux-386.tar.gz)    
+[commitlog-v2.0.2-linux-386.tar.gz.md5](https://github.com/barelyhuman/commitlog/releases/download/v2.0.2/commitlog-v2.0.2-linux-386.tar.gz.md5)    
+[commitlog-v2.0.2-linux-amd64.tar.gz](https://github.com/barelyhuman/commitlog/releases/download/v2.0.2/commitlog-v2.0.2-linux-amd64.tar.gz)    
+[commitlog-v2.0.2-linux-amd64.tar.gz.md5](https://github.com/barelyhuman/commitlog/releases/download/v2.0.2/commitlog-v2.0.2-linux-amd64.tar.gz.md5)    
+[commitlog-v2.0.2-linux-arm64.tar.gz](https://github.com/barelyhuman/commitlog/releases/download/v2.0.2/commitlog-v2.0.2-linux-arm64.tar.gz)    
+[commitlog-v2.0.2-linux-arm64.tar.gz.md5](https://github.com/barelyhuman/commitlog/releases/download/v2.0.2/commitlog-v2.0.2-linux-arm64.tar.gz.md5)    
+[commitlog-v2.0.2-windows-386.zip](https://github.com/barelyhuman/commitlog/releases/download/v2.0.2/commitlog-v2.0.2-windows-386.zip)    
+[commitlog-v2.0.2-windows-386.zip.md5](https://github.com/barelyhuman/commitlog/releases/download/v2.0.2/commitlog-v2.0.2-windows-386.zip.md5)    
+[commitlog-v2.0.2-windows-amd64.zip](https://github.com/barelyhuman/commitlog/releases/download/v2.0.2/commitlog-v2.0.2-windows-amd64.zip)    
+[commitlog-v2.0.2-windows-amd64.zip.md5](https://github.com/barelyhuman/commitlog/releases/download/v2.0.2/commitlog-v2.0.2-windows-amd64.zip.md5)    
diff --git a/scripts/get-release-urls.sh b/scripts/get-release-urls.sh
index 5bfa639..959994f 100755
--- a/scripts/get-release-urls.sh
+++ b/scripts/get-release-urls.sh
@@ -22,6 +22,6 @@ EOF
 jq -c '.[]' api_urls.json | while read i; do
     url=$(echo $i | jq '.url' --raw-output)
     name=$(echo $i | jq '.name' --raw-output)
-    bdurl=$(curl -sL $url | jq '.browser_download_url')
+    bdurl=$(curl -sL $url | jq -r '.browser_download_url')
     echo "[$name]($bdurl)    " >> ./docs/download.md
 done
\ No newline at end of file

From 212c886da15e5c1b8dcb65520a43bd8bdb24d292 Mon Sep 17 00:00:00 2001
From: reaper <ahoy@barelyhuman.dev>
Date: Tue, 24 Jan 2023 23:15:14 +0530
Subject: [PATCH 29/51] docs: add styles for latest mudkip search

---
 docs/styles.css | 32 ++++++++++++++++++++++++++++++++
 1 file changed, 32 insertions(+)

diff --git a/docs/styles.css b/docs/styles.css
index 8791f50..96549ce 100644
--- a/docs/styles.css
+++ b/docs/styles.css
@@ -115,4 +115,36 @@ blockquote {
     padding: 0px;
     border-left: 2px solid var(--muted);
     padding-left: 10px;
+}
+
+#search-container {
+  display: block;
+  margin:0 auto;
+}
+
+#search-container > input[type="text"] {
+  width: 100%;
+  background: var(--base);
+  color: var(--text);
+  padding: 0.5rem;
+  border-radius: 4px;
+  border: 2px solid var(--surface);
+}
+
+#search-container > input[type="text"]:hover {
+  border-color: var(--text);
+}
+
+#search-results {
+  display: flex;
+  flex-direction: column;
+  align-items: flex-start;
+  justify-content: flex-start;
+  max-height: 200px;
+  overflow: auto;
+}
+
+.mudkip-search-item {
+  margin: 0.25rem;
+  display: block;
 }
\ No newline at end of file

From 2d8810b045c9297aa52680b186911ae56bd7a25c Mon Sep 17 00:00:00 2001
From: Reaper Gelera <ahoy@barelyhuman.dev>
Date: Mon, 21 Aug 2023 11:52:30 +0530
Subject: [PATCH 30/51] update docs

---
 docs/index.md | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/docs/index.md b/docs/index.md
index ada821f..23edff8 100644
--- a/docs/index.md
+++ b/docs/index.md
@@ -36,7 +36,7 @@ go get -u github.com/barelyhuman/commitlog
 3. Using goblin
 
 ```sh
-curl -sf https://goblin.barelyhuman.xyz/github.com/barelyhuman/commitlog | sh
+curl -sf https://goblin.run/github.com/barelyhuman/commitlog | sh
 ```
 
 Once installed you can just run `commitlog generate` or the shorter version
@@ -87,7 +87,7 @@ toolset. The closes one to this is the `git`'s own `shortlog` and `log` commands
 
 The installation is pretty straightforwad. You [download](/download) the binary
 from the download section of this website or use something like
-[goblin](https://goblin.barelyhuman.xyz) to build the binary for your specific
+[goblin](https://goblin.run) to build the binary for your specific
 system (rarely needed) since the releases actually accommodate the most used
 operating systems and architectures already.
 

From 430561d4c37f2ec88a801d75c8e635e61de1f6be Mon Sep 17 00:00:00 2001
From: Reaper Gelera <ahoy@barelyhuman.dev>
Date: Wed, 30 Aug 2023 23:07:51 +0530
Subject: [PATCH 31/51] chore: maintenance update

---
 go.mod  |   7 +-
 go.sum  | 201 ++++++++++++++++++++++++++++++++++++++++----------------
 main.go |  19 +++---
 3 files changed, 156 insertions(+), 71 deletions(-)

diff --git a/go.mod b/go.mod
index c6abd65..f652f51 100644
--- a/go.mod
+++ b/go.mod
@@ -3,8 +3,7 @@ module github.com/barelyhuman/commitlog
 go 1.16
 
 require (
-	github.com/go-git/go-git/v5 v5.2.0
-	github.com/urfave/cli/v2 v2.8.1
-	golang.org/x/mod v0.5.1
-	golang.org/x/sys v0.0.0-20220412211240-33da011f77ad // indirect
+	github.com/go-git/go-git/v5 v5.8.1
+	github.com/urfave/cli/v2 v2.25.7
+	golang.org/x/mod v0.12.0
 )
diff --git a/go.sum b/go.sum
index 516600b..45ab591 100644
--- a/go.sum
+++ b/go.sum
@@ -1,97 +1,186 @@
-github.com/BurntSushi/toml v1.1.0/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
-github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7 h1:uSoVVbwJiQipAclBbw+8quDsfcvFjOpI5iCf4p/cqCs=
-github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7/go.mod h1:6zEj6s6u/ghQa61ZWa/C2Aw3RkjiTBOix7dkqa1VLIs=
-github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239 h1:kFOfPq6dUM1hTo4JG6LR5AXSUEsOjtdm0kw0FtQtMJA=
-github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c=
+dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk=
+dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk=
+github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
+github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY=
+github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow=
+github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM=
+github.com/ProtonMail/go-crypto v0.0.0-20230717121422-5aa5874ade95 h1:KLq8BE0KwCL+mmXnjLWEAOYO+2l2AE4YMmqG1ZpZHBs=
+github.com/ProtonMail/go-crypto v0.0.0-20230717121422-5aa5874ade95/go.mod h1:EjAoLdwvbIOoOQr3ihjnSoLZRtE8azugULFRteWMNc0=
+github.com/acomagu/bufpipe v1.0.4 h1:e3H4WUzM3npvo5uv95QuJM3cQspFNtFBzvJ2oNjKIDQ=
+github.com/acomagu/bufpipe v1.0.4/go.mod h1:mxdxdup/WdsKVreO5GpW4+M/1CE2sMG4jeGJ2sYmHc4=
+github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be h1:9AeTilPcZAjCFIImctFaOjnTIavg87rW78vTPkQqLI8=
+github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be/go.mod h1:ySMOLuWl6zY27l47sB3qLNK6tF2fkHG55UZxx8oIVo4=
 github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio=
 github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs=
-github.com/cpuguy83/go-md2man/v2 v2.0.1 h1:r/myEWzV9lfsM1tFLgDyu0atFtJ1fXn261LKYj/3DxU=
-github.com/cpuguy83/go-md2man/v2 v2.0.1/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
+github.com/bwesterb/go-ristretto v1.2.3/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0=
+github.com/cloudflare/circl v1.3.3 h1:fE/Qz0QdIGqeWfnwq0RE0R7MI51s0M2E4Ga9kq5AEMs=
+github.com/cloudflare/circl v1.3.3/go.mod h1:5XYMA4rFBvNIrhs50XuiBJ15vF2pZn4nnUKZrLbUZFA=
+github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w=
+github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
 github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
 github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
 github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
-github.com/emirpasic/gods v1.12.0 h1:QAUIPSaCu4G+POclxeqb3F+WPpdKqFGlw36+yOzGlrg=
-github.com/emirpasic/gods v1.12.0/go.mod h1:YfzfFFoVP/catgzJb4IKIqXjX78Ha8FMSDh3ymbK86o=
-github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc=
-github.com/gliderlabs/ssh v0.2.2 h1:6zsha5zo/TWhRhwqCD3+EarCAgZ2yN28ipRnGPnwkI0=
-github.com/gliderlabs/ssh v0.2.2/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0=
-github.com/go-git/gcfg v1.5.0 h1:Q5ViNfGF8zFgyJWPqYwA7qGFoMTEiBmdlkcfRmpIMa4=
-github.com/go-git/gcfg v1.5.0/go.mod h1:5m20vg6GwYabIxaOonVkTdrILxQMpEShl1xiMF4ua+E=
-github.com/go-git/go-billy/v5 v5.0.0 h1:7NQHvd9FVid8VL4qVUMm8XifBK+2xCoZ2lSk0agRrHM=
-github.com/go-git/go-billy/v5 v5.0.0/go.mod h1:pmpqyWchKfYfrkb/UVH4otLvyi/5gJlGI4Hb3ZqZ3W0=
-github.com/go-git/go-git-fixtures/v4 v4.0.2-0.20200613231340-f56387b50c12 h1:PbKy9zOy4aAKrJ5pibIRpVO2BXnK1Tlcg+caKI7Ox5M=
-github.com/go-git/go-git-fixtures/v4 v4.0.2-0.20200613231340-f56387b50c12/go.mod h1:m+ICp2rF3jDhFgEZ/8yziagdT1C+ZpZcrJjappBCDSw=
-github.com/go-git/go-git/v5 v5.2.0 h1:YPBLG/3UK1we1ohRkncLjaXWLW+HKp5QNM/jTli2JgI=
-github.com/go-git/go-git/v5 v5.2.0/go.mod h1:kh02eMX+wdqqxgNMEyq8YgwlIOsDOa9homkUq1PoTMs=
-github.com/google/go-cmp v0.3.0 h1:crn/baboCvb5fXaQ0IJ1SGTsTVrWpDsCWC8EGETZijY=
-github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
-github.com/imdario/mergo v0.3.9 h1:UauaLniWCFHWd+Jp9oCEkTBj8VO/9DKg3PV3VCNMDIg=
-github.com/imdario/mergo v0.3.9/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
+github.com/elazarl/goproxy v0.0.0-20221015165544-a0805db90819 h1:RIB4cRk+lBqKK3Oy0r2gRX4ui7tuhiZq2SuTtTCi0/0=
+github.com/elazarl/goproxy v0.0.0-20221015165544-a0805db90819/go.mod h1:Ro8st/ElPeALwNFlcTpWmkr6IoMFfkjXAvTHpevnDsM=
+github.com/elazarl/goproxy/ext v0.0.0-20190711103511-473e67f1d7d2/go.mod h1:gNh8nYJoAm43RfaxurUnxr+N1PwuFV3ZMl/efxlIlY8=
+github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc=
+github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ=
+github.com/gliderlabs/ssh v0.3.5 h1:OcaySEmAQJgyYcArR+gGGTHCyE7nvhEMTlYY+Dp8CpY=
+github.com/gliderlabs/ssh v0.3.5/go.mod h1:8XB4KraRrX39qHhT6yxPsHedjA08I/uBVwj4xC+/+z4=
+github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 h1:+zs/tPmkDkHx3U66DAb0lQFJrpS6731Oaa12ikc+DiI=
+github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376/go.mod h1:an3vInlBmSxCcxctByoQdvwPiA7DTK7jaaFDBTtu0ic=
+github.com/go-git/go-billy/v5 v5.3.1/go.mod h1:pmpqyWchKfYfrkb/UVH4otLvyi/5gJlGI4Hb3ZqZ3W0=
+github.com/go-git/go-billy/v5 v5.4.1 h1:Uwp5tDRkPr+l/TnbHOQzp+tmJfLceOlbVucgpTz8ix4=
+github.com/go-git/go-billy/v5 v5.4.1/go.mod h1:vjbugF6Fz7JIflbVpl1hJsGjSHNltrSw45YK/ukIvQg=
+github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20230305113008-0c11038e723f h1:Pz0DHeFij3XFhoBRGUDPzSJ+w2UcK5/0JvF8DRI58r8=
+github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20230305113008-0c11038e723f/go.mod h1:8LHG1a3SRW71ettAD/jW13h8c6AqjVSeL11RAdgaqpo=
+github.com/go-git/go-git/v5 v5.8.1 h1:Zo79E4p7TRk0xoRgMq0RShiTHGKcKI4+DI6BfJc/Q+A=
+github.com/go-git/go-git/v5 v5.8.1/go.mod h1:FHFuoD6yGz5OSKEBK+aWN9Oah0q54Jxl0abmj6GnqAo=
+github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE=
+github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
+github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
+github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
 github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A=
 github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo=
-github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
-github.com/kevinburke/ssh_config v0.0.0-20190725054713-01f96b0aa0cd h1:Coekwdh0v2wtGp9Gmz1Ze3eVRAWJMLokvN3QjdzCHLY=
-github.com/kevinburke/ssh_config v0.0.0-20190725054713-01f96b0aa0cd/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM=
+github.com/jessevdk/go-flags v1.5.0/go.mod h1:Fw0T6WPc1dYxT4mKEZRfG5kJhaTDP9pj1c2EWnYs/m4=
+github.com/kevinburke/ssh_config v1.2.0 h1:x584FjTGwHzMwvHx18PXxbBVzfnxogHaAReU4gf13a4=
+github.com/kevinburke/ssh_config v1.2.0/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM=
 github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
+github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
+github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
+github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
 github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
 github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
 github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
 github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
-github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
-github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
-github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
+github.com/matryer/is v1.2.0 h1:92UTHpy8CDwaJ08GqLDzhhuixiBUUD1p3AU6PHddz4A=
+github.com/matryer/is v1.2.0/go.mod h1:2fLPjFQM9rhQ15aVEtbuwhJinnOqrmgXPNdZsdwlWXA=
+github.com/mmcloughlin/avo v0.5.0/go.mod h1:ChHFdoV7ql95Wi7vuq2YT1bwCJqiWdZrQ1im3VujLYM=
 github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
-github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
-github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
+github.com/pjbgf/sha1cd v0.3.0 h1:4D5XXmUUBUl/xQ6IjCkEAbqXskkq/4O7LmGn0AqMDs4=
+github.com/pjbgf/sha1cd v0.3.0/go.mod h1:nZ1rrWOcGJ5uZgEEVL1VUM9iRQiZvWdbZjkKyFzPPsI=
+github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
+github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
+github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
 github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
 github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+github.com/rogpeppe/go-charset v0.0.0-20180617210344-2471d30d28b4/go.mod h1:qgYeAmZ5ZIpBWTGllZSQnw97Dj+woV0toclVaRGI8pc=
+github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8=
+github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
 github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
 github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
 github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0=
 github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
+github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
+github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
+github.com/skeema/knownhosts v1.2.0 h1:h9r9cf0+u7wSE+M183ZtMGgOJKiL96brpaz5ekfJCpM=
+github.com/skeema/knownhosts v1.2.0/go.mod h1:g4fPeYpque7P0xefxtGzV81ihjC8sX2IqpAoNkjxbMo=
 github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
-github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
+github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
 github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
-github.com/urfave/cli/v2 v2.8.1 h1:CGuYNZF9IKZY/rfBe3lJpccSoIY1ytfvmgQT90cNOl4=
-github.com/urfave/cli/v2 v2.8.1/go.mod h1:Z41J9TPoffeoqP0Iza0YbAhGvymRdZAd2uPmZ5JxRdY=
-github.com/xanzy/ssh-agent v0.2.1 h1:TCbipTQL2JiiCprBWx9frJ2eJlCYT00NmctrHxVAr70=
-github.com/xanzy/ssh-agent v0.2.1/go.mod h1:mLlQY/MoOhWBj+gOGMQkOeiEvkx+8pJSI+0Bx9h2kr4=
+github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
+github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
+github.com/urfave/cli/v2 v2.25.7 h1:VAzn5oq403l5pHjc4OhD54+XGO9cdKVL/7lDjF+iKUs=
+github.com/urfave/cli/v2 v2.25.7/go.mod h1:8qnjx1vcq5s2/wpsqoZFndg2CE5tNFyrTvS6SinrnYQ=
+github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM=
+github.com/xanzy/ssh-agent v0.3.3/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI1Bc68Uw=
 github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 h1:bAn7/zixMGCfxrRTfdpNzjtPYqr8smhKouy9mxVdGPU=
 github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8=
-golang.org/x/crypto v0.0.0-20190219172222-a4c6cb3142f2/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
+github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
+golang.org/x/arch v0.1.0/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
 golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
-golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
-golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073 h1:xMPOj6Pz6UipU1wXLkrtqpHbR0AVFnyPEQq/wRWz9lM=
-golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
-golang.org/x/mod v0.5.1 h1:OJxoQ/rynoF0dcCdI7cLPktw/hR2cueqYfjm43oqK38=
-golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro=
-golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
+golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
+golang.org/x/crypto v0.0.0-20220826181053-bd7e27e6170d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
+golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw=
+golang.org/x/crypto v0.3.1-0.20221117191849-2c476679df9a/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4=
+golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU=
+golang.org/x/crypto v0.8.0/go.mod h1:mRqEX+O9/h5TFCrQhkgjo2yKi0yYA+9ecGkdQoHrywE=
+golang.org/x/crypto v0.11.0 h1:6Ewdq3tDic1mg5xRO4milcWCfMVQhI4NkqWWvqejpuA=
+golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio=
+golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
+golang.org/x/mod v0.6.0/go.mod h1:4mET923SAdbXp2ki8ey+zGs1SLqsuM2Y0uvdZR/fUNI=
+golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
+golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc=
+golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
 golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
-golang.org/x/net v0.0.0-20200301022130-244492dfa37a h1:GuSPYbZzB5/dcLNCwLQLsg3obCJtX9IJhpXkvY7kzk0=
-golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
+golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
+golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
+golang.org/x/net v0.0.0-20220826154423-83b083e8dc8b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=
+golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco=
+golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY=
+golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
+golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=
+golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns=
+golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
+golang.org/x/net v0.12.0 h1:cfawfvKITfUsFCeJIHJrbSxpeu/E81khclypR0GVT50=
+golang.org/x/net v0.12.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA=
 golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o=
+golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
-golang.org/x/sys v0.0.0-20190221075227-b4e8571b14e0/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
-golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20220412211240-33da011f77ad h1:ntjMns5wyP/fN65tdBD4g8J5w8n015+iIIs9rtjXkY0=
-golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220825204002-c680a09ffe64/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.10.0 h1:SqMFp9UcQJZa+pmYuAKjd9xq1f0j5rLcDIk0mj4qAsA=
+golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
+golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
+golang.org/x/term v0.0.0-20220722155259-a9ba230a4035/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
+golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
+golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc=
+golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
+golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U=
+golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY=
+golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
+golang.org/x/term v0.10.0 h1:3R7pNqamzBraeqj/Tj8qt1aQ2HpmlC+Cx/qL/7hn4/c=
+golang.org/x/term v0.10.0/go.mod h1:lpqdcUyK/oCiQxvxVrppt5ggO2KCZ5QblwqPnfZ6d5o=
 golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
-golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
-golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=
+golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
+golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
 golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
+golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
+golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
+golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
+golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
+golang.org/x/text v0.11.0 h1:LAntKIrcmeSKERyiOh0XMV39LXS8IE9UL2yP7+f5ij4=
+golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
 golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
 golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
+golang.org/x/tools v0.2.0/go.mod h1:y4OqIKeOV/fWJetJ8bXPU1sEVniLMIyDAZWeHdV+NTA=
+golang.org/x/tools v0.6.0 h1:BOw41kyTf3PuCW1pVQf8+Cyg8pMlkYB1oo9iJ6D/lKM=
+golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
 golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
-golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
 gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
-gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU=
 gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
+gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
 gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME=
 gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI=
 gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
 gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
-gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
-gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
+gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
+gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4=
diff --git a/main.go b/main.go
index 7d42821..dfa0a40 100644
--- a/main.go
+++ b/main.go
@@ -4,18 +4,20 @@ import (
 	_ "embed"
 	"fmt"
 	"os"
+	"time"
 
 	"github.com/barelyhuman/commitlog/commands"
 	"github.com/urfave/cli/v2"
 )
 
-// go:embed .commitlog.release
+//go:embed .commitlog.release
 var version string
 
 func main() {
 	app := &cli.App{
-		Name:  "commitlog",
-		Usage: "commits to changelogs",
+		Name:            "commitlog",
+		Usage:           "commits to changelogs",
+		CommandNotFound: cli.ShowCommandCompletions,
 		Action: func(c *cli.Context) error {
 			fmt.Println(
 				"[commitlog] we no longer support direct invocation, please use the subcommand `generate` to generate a log or `release` to manage your .commitlog.release",
@@ -23,6 +25,9 @@ func main() {
 
 			return nil
 		},
+		Version:     version,
+		Compiled:    time.Now(),
+		HideVersion: false,
 		Commands: []*cli.Command{
 			{
 				Name:    "generate",
@@ -132,14 +137,6 @@ func main() {
 		},
 	}
 
-	cli.VersionFlag = &cli.BoolFlag{
-		Name:    "version",
-		Aliases: []string{"v"},
-		Usage:   "print only the version",
-	}
-
-	app.Version = version
-
 	err := app.Run(os.Args)
 	if err != nil {
 		fmt.Fprintf(os.Stderr, "[commitlog] %v", err)

From b7f72b2967ebb33ecfb976a698fdc812c9a2140d Mon Sep 17 00:00:00 2001
From: Reaper Gelera <ahoy@barelyhuman.dev>
Date: Wed, 30 Aug 2023 23:08:18 +0530
Subject: [PATCH 32/51] chore: v2.0.3

---
 .commitlog.release | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/.commitlog.release b/.commitlog.release
index b02d37b..201271f 100755
--- a/.commitlog.release
+++ b/.commitlog.release
@@ -1 +1 @@
-v2.0.2
\ No newline at end of file
+v2.0.3
\ No newline at end of file

From 8fed5a24275d793257c0711a76e2cea1550cc075 Mon Sep 17 00:00:00 2001
From: Reaper Gelera <ahoy@barelyhuman.dev>
Date: Wed, 30 Aug 2023 23:10:57 +0530
Subject: [PATCH 33/51] ci: change to goblin.run

---
 .github/workflows/changelog.yml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/.github/workflows/changelog.yml b/.github/workflows/changelog.yml
index f7c4406..fa15c53 100644
--- a/.github/workflows/changelog.yml
+++ b/.github/workflows/changelog.yml
@@ -15,7 +15,7 @@ jobs:
       - name: Generate Change Log
         id: generate_log
         run: |
-          curl -sSL https://bina.egoist.sh/barelyhuman/commitlog | sh
+          curl -sSL https://goblin.run/github.com/barelyhuman/commitlog | sh
           commitlog g > CHANGELOG.md
       - uses: ncipollo/release-action@v1
         with:

From 71dc2e0b6854609148b805d79f7d685e6468d6ce Mon Sep 17 00:00:00 2001
From: Reaper Gelera <ahoy@barelyhuman.dev>
Date: Wed, 30 Aug 2023 23:11:37 +0530
Subject: [PATCH 34/51] chore: v2.0.4

---
 .commitlog.release | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/.commitlog.release b/.commitlog.release
index 201271f..7059afe 100755
--- a/.commitlog.release
+++ b/.commitlog.release
@@ -1 +1 @@
-v2.0.3
\ No newline at end of file
+v2.0.4
\ No newline at end of file

From 8794d22bcbcae550551805caa98751f4c91fc007 Mon Sep 17 00:00:00 2001
From: Reaper Gelera <ahoy@barelyhuman.dev>
Date: Wed, 30 Aug 2023 23:23:39 +0530
Subject: [PATCH 35/51] chore: update docs

---
 .gitignore               |  3 ++-
 docs/download.md         | 21 +++++++--------------
 scripts/cross-compile.sh | 39 +++++++++++++++++++++++++++++++++++++++
 3 files changed, 48 insertions(+), 15 deletions(-)
 create mode 100755 scripts/cross-compile.sh

diff --git a/.gitignore b/.gitignore
index 9af1d52..20fab68 100644
--- a/.gitignore
+++ b/.gitignore
@@ -4,4 +4,5 @@ CHANGELOG.md
 dist
 commitlog
 lab
-api_urls.json
\ No newline at end of file
+api_urls.json
+bin
\ No newline at end of file
diff --git a/docs/download.md b/docs/download.md
index 3ce1944..700585a 100644
--- a/docs/download.md
+++ b/docs/download.md
@@ -11,17 +11,10 @@
 
 #### Downloads
 
-[commitlog-v2.0.2-darwin-amd64.tar.gz](https://github.com/barelyhuman/commitlog/releases/download/v2.0.2/commitlog-v2.0.2-darwin-amd64.tar.gz)    
-[commitlog-v2.0.2-darwin-amd64.tar.gz.md5](https://github.com/barelyhuman/commitlog/releases/download/v2.0.2/commitlog-v2.0.2-darwin-amd64.tar.gz.md5)    
-[commitlog-v2.0.2-darwin-arm64.tar.gz](https://github.com/barelyhuman/commitlog/releases/download/v2.0.2/commitlog-v2.0.2-darwin-arm64.tar.gz)    
-[commitlog-v2.0.2-darwin-arm64.tar.gz.md5](https://github.com/barelyhuman/commitlog/releases/download/v2.0.2/commitlog-v2.0.2-darwin-arm64.tar.gz.md5)    
-[commitlog-v2.0.2-linux-386.tar.gz](https://github.com/barelyhuman/commitlog/releases/download/v2.0.2/commitlog-v2.0.2-linux-386.tar.gz)    
-[commitlog-v2.0.2-linux-386.tar.gz.md5](https://github.com/barelyhuman/commitlog/releases/download/v2.0.2/commitlog-v2.0.2-linux-386.tar.gz.md5)    
-[commitlog-v2.0.2-linux-amd64.tar.gz](https://github.com/barelyhuman/commitlog/releases/download/v2.0.2/commitlog-v2.0.2-linux-amd64.tar.gz)    
-[commitlog-v2.0.2-linux-amd64.tar.gz.md5](https://github.com/barelyhuman/commitlog/releases/download/v2.0.2/commitlog-v2.0.2-linux-amd64.tar.gz.md5)    
-[commitlog-v2.0.2-linux-arm64.tar.gz](https://github.com/barelyhuman/commitlog/releases/download/v2.0.2/commitlog-v2.0.2-linux-arm64.tar.gz)    
-[commitlog-v2.0.2-linux-arm64.tar.gz.md5](https://github.com/barelyhuman/commitlog/releases/download/v2.0.2/commitlog-v2.0.2-linux-arm64.tar.gz.md5)    
-[commitlog-v2.0.2-windows-386.zip](https://github.com/barelyhuman/commitlog/releases/download/v2.0.2/commitlog-v2.0.2-windows-386.zip)    
-[commitlog-v2.0.2-windows-386.zip.md5](https://github.com/barelyhuman/commitlog/releases/download/v2.0.2/commitlog-v2.0.2-windows-386.zip.md5)    
-[commitlog-v2.0.2-windows-amd64.zip](https://github.com/barelyhuman/commitlog/releases/download/v2.0.2/commitlog-v2.0.2-windows-amd64.zip)    
-[commitlog-v2.0.2-windows-amd64.zip.md5](https://github.com/barelyhuman/commitlog/releases/download/v2.0.2/commitlog-v2.0.2-windows-amd64.zip.md5)    
+[darwin-amd64.tgz](https://github.com/barelyhuman/commitlog/releases/download/v2.0.4/darwin-amd64.tgz)    
+[darwin-arm64.tgz](https://github.com/barelyhuman/commitlog/releases/download/v2.0.4/darwin-arm64.tgz)    
+[linux-amd64.tgz](https://github.com/barelyhuman/commitlog/releases/download/v2.0.4/linux-amd64.tgz)    
+[linux-arm.tgz](https://github.com/barelyhuman/commitlog/releases/download/v2.0.4/linux-arm.tgz)    
+[linux-arm64.tgz](https://github.com/barelyhuman/commitlog/releases/download/v2.0.4/linux-arm64.tgz)    
+[windows-386.tgz](https://github.com/barelyhuman/commitlog/releases/download/v2.0.4/windows-386.tgz)    
+[windows-amd64.tgz](https://github.com/barelyhuman/commitlog/releases/download/v2.0.4/windows-amd64.tgz)    
diff --git a/scripts/cross-compile.sh b/scripts/cross-compile.sh
new file mode 100755
index 0000000..3ac43fd
--- /dev/null
+++ b/scripts/cross-compile.sh
@@ -0,0 +1,39 @@
+#!/usr/bin/env bash
+
+set -euxo pipefail
+
+rm -rf ./bin
+
+build_commands=('
+    apk add make curl git \
+    ; GOOS=linux GOARCH=arm64 go build -ldflags="-s -w" -o bin/linux-arm64/alvu \
+    ; GOOS=linux GOARCH=amd64 go build -ldflags="-s -w" -o bin/linux-amd64/alvu \
+    ; GOOS=linux GOARCH=arm go build -ldflags="-s -w" -o bin/linux-arm/alvu \
+    ; GOOS=windows GOARCH=386 go build -ldflags="-s -w" -o bin/windows-386/alvu \
+    ; GOOS=windows GOARCH=amd64 go build -ldflags="-s -w" -o bin/windows-amd64/alvu \
+    ; GOOS=darwin GOARCH=amd64 go build -ldflags="-s -w" -o bin/darwin-amd64/alvu \
+    ; GOOS=darwin GOARCH=arm64 go build -ldflags="-s -w" -o bin/darwin-arm64/alvu 
+')
+
+# run a docker container with osxcross and cross compile everything
+docker run -it --rm -v $(pwd):/usr/local/src -w /usr/local/src \
+	golang:alpine3.16 \
+	sh -c "$build_commands"
+
+# create archives
+cd bin
+for dir in $(ls -d *);
+do
+    cp ../README.md $dir
+    cp ../LICENSE $dir
+    mkdir -p $dir/docs
+    cp -r ../docs/* $dir/docs
+    
+    # remove the download document and styles
+    rm -rf $dir/docs/download.md
+    rm -rf $dir/docs/styles.css
+
+    tar cfzv "$dir".tgz $dir
+    rm -rf $dir
+done
+cd ..
\ No newline at end of file

From 628f6b5ca93fdbe16a25020f051a797e25a433e6 Mon Sep 17 00:00:00 2001
From: Reaper Gelera <ahoy@barelyhuman.dev>
Date: Wed, 30 Aug 2023 23:25:50 +0530
Subject: [PATCH 36/51] fix: invalid token

---
 .github/workflows/create-binaries.yml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/.github/workflows/create-binaries.yml b/.github/workflows/create-binaries.yml
index e9e0c24..3d61ad5 100644
--- a/.github/workflows/create-binaries.yml
+++ b/.github/workflows/create-binaries.yml
@@ -22,7 +22,7 @@ jobs:
       - uses: actions/checkout@v2
       - uses: wangyoucao577/go-release-action@v1.18
         with:
-          github_token: ${{ secrets.GITHUB_TOKEN }}
+          github_token: ${{ secrets.GH_TOKEN }}
           goos: ${{ matrix.goos }}
           goarch: ${{ matrix.goarch }}
           ldflags: "-w -s"

From 24abf20bc834d7b99dcd9551c34174b59055269d Mon Sep 17 00:00:00 2001
From: Reaper Gelera <ahoy@barelyhuman.dev>
Date: Wed, 30 Aug 2023 23:25:53 +0530
Subject: [PATCH 37/51] chore: v2.0.5

---
 .commitlog.release | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/.commitlog.release b/.commitlog.release
index 7059afe..de87a17 100755
--- a/.commitlog.release
+++ b/.commitlog.release
@@ -1 +1 @@
-v2.0.4
\ No newline at end of file
+v2.0.5
\ No newline at end of file

From e23acb35aed53987de1a8fe8f5b1859c1a212abb Mon Sep 17 00:00:00 2001
From: Reaper Gelera <ahoy@barelyhuman.dev>
Date: Wed, 30 Aug 2023 23:32:07 +0530
Subject: [PATCH 38/51] ci: change binary build task

---
 .github/workflows/create-binaries.yml | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/.github/workflows/create-binaries.yml b/.github/workflows/create-binaries.yml
index 3d61ad5..5b9495d 100644
--- a/.github/workflows/create-binaries.yml
+++ b/.github/workflows/create-binaries.yml
@@ -19,8 +19,8 @@ jobs:
           - goarch: arm64
             goos: windows
     steps:
-      - uses: actions/checkout@v2
-      - uses: wangyoucao577/go-release-action@v1.18
+      - uses: actions/checkout@v3
+      - uses: wangyoucao577/go-release-action@v1
         with:
           github_token: ${{ secrets.GH_TOKEN }}
           goos: ${{ matrix.goos }}

From 84c8712cc6e6c30b2b4d2b541ecdfcff6ed5f3fd Mon Sep 17 00:00:00 2001
From: Reaper Gelera <ahoy@barelyhuman.dev>
Date: Wed, 30 Aug 2023 23:33:23 +0530
Subject: [PATCH 39/51] chore: v2.0.6-beta.0

---
 .commitlog.release | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/.commitlog.release b/.commitlog.release
index de87a17..d08bad0 100755
--- a/.commitlog.release
+++ b/.commitlog.release
@@ -1 +1 @@
-v2.0.5
\ No newline at end of file
+v2.0.6-beta.0
\ No newline at end of file

From 18ffe2fe61b71fb8574cbb259a701722c5e88aaa Mon Sep 17 00:00:00 2001
From: Reaper Gelera <ahoy@barelyhuman.dev>
Date: Wed, 30 Aug 2023 23:33:23 +0530
Subject: [PATCH 40/51] doc update

---
 docs/download.md | 21 ++++++++++++++-------
 1 file changed, 14 insertions(+), 7 deletions(-)

diff --git a/docs/download.md b/docs/download.md
index 700585a..ec017bf 100644
--- a/docs/download.md
+++ b/docs/download.md
@@ -11,10 +11,17 @@
 
 #### Downloads
 
-[darwin-amd64.tgz](https://github.com/barelyhuman/commitlog/releases/download/v2.0.4/darwin-amd64.tgz)    
-[darwin-arm64.tgz](https://github.com/barelyhuman/commitlog/releases/download/v2.0.4/darwin-arm64.tgz)    
-[linux-amd64.tgz](https://github.com/barelyhuman/commitlog/releases/download/v2.0.4/linux-amd64.tgz)    
-[linux-arm.tgz](https://github.com/barelyhuman/commitlog/releases/download/v2.0.4/linux-arm.tgz)    
-[linux-arm64.tgz](https://github.com/barelyhuman/commitlog/releases/download/v2.0.4/linux-arm64.tgz)    
-[windows-386.tgz](https://github.com/barelyhuman/commitlog/releases/download/v2.0.4/windows-386.tgz)    
-[windows-amd64.tgz](https://github.com/barelyhuman/commitlog/releases/download/v2.0.4/windows-amd64.tgz)    
+[commitlog-v2.0.6-beta.0-darwin-amd64.tar.gz](https://github.com/barelyhuman/commitlog/releases/download/v2.0.6-beta.0/commitlog-v2.0.6-beta.0-darwin-amd64.tar.gz)    
+[commitlog-v2.0.6-beta.0-darwin-amd64.tar.gz.md5](https://github.com/barelyhuman/commitlog/releases/download/v2.0.6-beta.0/commitlog-v2.0.6-beta.0-darwin-amd64.tar.gz.md5)    
+[commitlog-v2.0.6-beta.0-darwin-arm64.tar.gz](https://github.com/barelyhuman/commitlog/releases/download/v2.0.6-beta.0/commitlog-v2.0.6-beta.0-darwin-arm64.tar.gz)    
+[commitlog-v2.0.6-beta.0-darwin-arm64.tar.gz.md5](https://github.com/barelyhuman/commitlog/releases/download/v2.0.6-beta.0/commitlog-v2.0.6-beta.0-darwin-arm64.tar.gz.md5)    
+[commitlog-v2.0.6-beta.0-linux-386.tar.gz](https://github.com/barelyhuman/commitlog/releases/download/v2.0.6-beta.0/commitlog-v2.0.6-beta.0-linux-386.tar.gz)    
+[commitlog-v2.0.6-beta.0-linux-386.tar.gz.md5](https://github.com/barelyhuman/commitlog/releases/download/v2.0.6-beta.0/commitlog-v2.0.6-beta.0-linux-386.tar.gz.md5)    
+[commitlog-v2.0.6-beta.0-linux-amd64.tar.gz](https://github.com/barelyhuman/commitlog/releases/download/v2.0.6-beta.0/commitlog-v2.0.6-beta.0-linux-amd64.tar.gz)    
+[commitlog-v2.0.6-beta.0-linux-amd64.tar.gz.md5](https://github.com/barelyhuman/commitlog/releases/download/v2.0.6-beta.0/commitlog-v2.0.6-beta.0-linux-amd64.tar.gz.md5)    
+[commitlog-v2.0.6-beta.0-linux-arm64.tar.gz](https://github.com/barelyhuman/commitlog/releases/download/v2.0.6-beta.0/commitlog-v2.0.6-beta.0-linux-arm64.tar.gz)    
+[commitlog-v2.0.6-beta.0-linux-arm64.tar.gz.md5](https://github.com/barelyhuman/commitlog/releases/download/v2.0.6-beta.0/commitlog-v2.0.6-beta.0-linux-arm64.tar.gz.md5)    
+[commitlog-v2.0.6-beta.0-windows-386.zip](https://github.com/barelyhuman/commitlog/releases/download/v2.0.6-beta.0/commitlog-v2.0.6-beta.0-windows-386.zip)    
+[commitlog-v2.0.6-beta.0-windows-386.zip.md5](https://github.com/barelyhuman/commitlog/releases/download/v2.0.6-beta.0/commitlog-v2.0.6-beta.0-windows-386.zip.md5)    
+[commitlog-v2.0.6-beta.0-windows-amd64.zip](https://github.com/barelyhuman/commitlog/releases/download/v2.0.6-beta.0/commitlog-v2.0.6-beta.0-windows-amd64.zip)    
+[commitlog-v2.0.6-beta.0-windows-amd64.zip.md5](https://github.com/barelyhuman/commitlog/releases/download/v2.0.6-beta.0/commitlog-v2.0.6-beta.0-windows-amd64.zip.md5)    

From 2133a18fc157f756451f03c4fb48d91d64cdaec0 Mon Sep 17 00:00:00 2001
From: Reaper Gelera <ahoy@barelyhuman.dev>
Date: Thu, 31 Aug 2023 02:25:00 +0530
Subject: [PATCH 41/51] fix: semver

---
 commands/commitlog.go | 2 +-
 commands/release.go   | 4 ++--
 docs/api.md           | 2 +-
 go.mod                | 2 +-
 main.go               | 2 +-
 pkg/generator.go      | 2 +-
 6 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/commands/commitlog.go b/commands/commitlog.go
index b87b6a5..579fc6c 100644
--- a/commands/commitlog.go
+++ b/commands/commitlog.go
@@ -1,7 +1,7 @@
 package commands
 
 import (
-	"github.com/barelyhuman/commitlog/pkg"
+	"github.com/barelyhuman/commitlog/v2/pkg"
 	"github.com/urfave/cli/v2"
 )
 
diff --git a/commands/release.go b/commands/release.go
index bd3f527..3f49fee 100644
--- a/commands/release.go
+++ b/commands/release.go
@@ -6,8 +6,8 @@ import (
 	"os/exec"
 	"path"
 
-	"github.com/barelyhuman/commitlog/lib"
-	"github.com/barelyhuman/commitlog/pkg"
+	"github.com/barelyhuman/commitlog/v2/lib"
+	"github.com/barelyhuman/commitlog/v2/pkg"
 	"github.com/go-git/go-git/v5"
 	"github.com/go-git/go-git/v5/plumbing"
 	"github.com/urfave/cli/v2"
diff --git a/docs/api.md b/docs/api.md
index ac931a4..dac4771 100644
--- a/docs/api.md
+++ b/docs/api.md
@@ -33,7 +33,7 @@ package main
 import (
 	"log"
 
-	"github.com/barelyhuman/commitlog/pkg"
+	"github.com/barelyhuman/commitlog/v2/pkg"
 )
 
 func main() {
diff --git a/go.mod b/go.mod
index f652f51..cdc2476 100644
--- a/go.mod
+++ b/go.mod
@@ -1,4 +1,4 @@
-module github.com/barelyhuman/commitlog
+module github.com/barelyhuman/commitlog/v2
 
 go 1.16
 
diff --git a/main.go b/main.go
index dfa0a40..9fe22c7 100644
--- a/main.go
+++ b/main.go
@@ -6,7 +6,7 @@ import (
 	"os"
 	"time"
 
-	"github.com/barelyhuman/commitlog/commands"
+	"github.com/barelyhuman/commitlog/v2/commands"
 	"github.com/urfave/cli/v2"
 )
 
diff --git a/pkg/generator.go b/pkg/generator.go
index 26c49da..0c7aeba 100644
--- a/pkg/generator.go
+++ b/pkg/generator.go
@@ -8,7 +8,7 @@ import (
 	"regexp"
 	"strings"
 
-	"github.com/barelyhuman/commitlog/lib"
+	"github.com/barelyhuman/commitlog/v2/lib"
 	"github.com/go-git/go-git/v5"
 	"github.com/go-git/go-git/v5/plumbing/object"
 )

From a6f3a74ba88a934f08a2b6ad2c800833baff64c0 Mon Sep 17 00:00:00 2001
From: Reaper Gelera <ahoy@barelyhuman.dev>
Date: Thu, 31 Aug 2023 02:25:52 +0530
Subject: [PATCH 42/51] chore: v2.0.7

---
 .commitlog.release | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/.commitlog.release b/.commitlog.release
index d08bad0..12be384 100755
--- a/.commitlog.release
+++ b/.commitlog.release
@@ -1 +1 @@
-v2.0.6-beta.0
\ No newline at end of file
+v2.0.7
\ No newline at end of file

From 48470943c32b5fdc08d9706db3bde9fa5253bdff Mon Sep 17 00:00:00 2001
From: Reaper Gelera <ahoy@barelyhuman.dev>
Date: Thu, 31 Aug 2023 02:31:34 +0530
Subject: [PATCH 43/51] chore: v3.0.0

---
 .commitlog.release    | 2 +-
 commands/commitlog.go | 2 +-
 commands/release.go   | 4 ++--
 docs/api.md           | 2 +-
 go.mod                | 2 +-
 main.go               | 2 +-
 pkg/generator.go      | 2 +-
 7 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/.commitlog.release b/.commitlog.release
index 12be384..1c5ae58 100755
--- a/.commitlog.release
+++ b/.commitlog.release
@@ -1 +1 @@
-v2.0.7
\ No newline at end of file
+v3.0.0
\ No newline at end of file
diff --git a/commands/commitlog.go b/commands/commitlog.go
index 579fc6c..1ade19d 100644
--- a/commands/commitlog.go
+++ b/commands/commitlog.go
@@ -1,7 +1,7 @@
 package commands
 
 import (
-	"github.com/barelyhuman/commitlog/v2/pkg"
+	"github.com/barelyhuman/commitlog/v3/pkg"
 	"github.com/urfave/cli/v2"
 )
 
diff --git a/commands/release.go b/commands/release.go
index 3f49fee..99ce039 100644
--- a/commands/release.go
+++ b/commands/release.go
@@ -6,8 +6,8 @@ import (
 	"os/exec"
 	"path"
 
-	"github.com/barelyhuman/commitlog/v2/lib"
-	"github.com/barelyhuman/commitlog/v2/pkg"
+	"github.com/barelyhuman/commitlog/v3/lib"
+	"github.com/barelyhuman/commitlog/v3/pkg"
 	"github.com/go-git/go-git/v5"
 	"github.com/go-git/go-git/v5/plumbing"
 	"github.com/urfave/cli/v2"
diff --git a/docs/api.md b/docs/api.md
index dac4771..3f66656 100644
--- a/docs/api.md
+++ b/docs/api.md
@@ -33,7 +33,7 @@ package main
 import (
 	"log"
 
-	"github.com/barelyhuman/commitlog/v2/pkg"
+	"github.com/barelyhuman/commitlog/v3/pkg"
 )
 
 func main() {
diff --git a/go.mod b/go.mod
index cdc2476..a27a5ce 100644
--- a/go.mod
+++ b/go.mod
@@ -1,4 +1,4 @@
-module github.com/barelyhuman/commitlog/v2
+module github.com/barelyhuman/commitlog/v3
 
 go 1.16
 
diff --git a/main.go b/main.go
index 9fe22c7..87fed6b 100644
--- a/main.go
+++ b/main.go
@@ -6,7 +6,7 @@ import (
 	"os"
 	"time"
 
-	"github.com/barelyhuman/commitlog/v2/commands"
+	"github.com/barelyhuman/commitlog/v3/commands"
 	"github.com/urfave/cli/v2"
 )
 
diff --git a/pkg/generator.go b/pkg/generator.go
index 0c7aeba..3a8743f 100644
--- a/pkg/generator.go
+++ b/pkg/generator.go
@@ -8,7 +8,7 @@ import (
 	"regexp"
 	"strings"
 
-	"github.com/barelyhuman/commitlog/v2/lib"
+	"github.com/barelyhuman/commitlog/v3/lib"
 	"github.com/go-git/go-git/v5"
 	"github.com/go-git/go-git/v5/plumbing/object"
 )

From 1f38e25e3dbe14e45295d717e145ffcc6525534b Mon Sep 17 00:00:00 2001
From: Reaper Gelera <ahoy@barelyhuman.dev>
Date: Thu, 31 Aug 2023 02:48:10 +0530
Subject: [PATCH 44/51] fix: validate tag existence in new repos

---
 pkg/generator.go | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/pkg/generator.go b/pkg/generator.go
index 3a8743f..680e145 100644
--- a/pkg/generator.go
+++ b/pkg/generator.go
@@ -88,6 +88,11 @@ func (g *Generator) readCommitsInTags() (err error) {
 		}
 	}
 
+	if latestTagCommit == nil && previousTagCommit == nil {
+		err = fmt.Errorf("failed to get tags, check if you have at least one tag or provide commit references instead")
+		return
+	}
+
 	commitsIter, err = g.repo.Log(&git.LogOptions{From: latestTagCommit.Hash})
 
 	if err != nil {

From 632360f206a8132b4283f5122b9907cb73eaded1 Mon Sep 17 00:00:00 2001
From: Reaper Gelera <ahoy@barelyhuman.dev>
Date: Thu, 31 Aug 2023 03:19:43 +0530
Subject: [PATCH 45/51] update install docs

---
 docs/index.md | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/docs/index.md b/docs/index.md
index 23edff8..f607d74 100644
--- a/docs/index.md
+++ b/docs/index.md
@@ -91,9 +91,18 @@ from the download section of this website or use something like
 system (rarely needed) since the releases actually accommodate the most used
 operating systems and architectures already.
 
+**Goblin**
+
+If using something like goblin, you'll have to request for the latest go module based version
+which can be requested like so
+
+```sh
+curl -sf http://goblin.run/github.com/barelyhuman/commitlog/v3@v3 | sh
+```
+
 **Linux/Mac (Unix Systems)**
 
-Once downloaded, you can use the `install` command on *nix systems to link the
+Once downloaded, you can use the `install` command on \*nix systems to link the
 binary to a location that's already in your PATH variable.
 
 eg:

From d7b7bb1cab72c5f9b5240ed8449bfa55d1c7f9e8 Mon Sep 17 00:00:00 2001
From: Reaper Gelera <ahoy@barelyhuman.dev>
Date: Thu, 31 Aug 2023 03:24:24 +0530
Subject: [PATCH 46/51] docs: update

---
 docs/index.md | 13 ++-----------
 1 file changed, 2 insertions(+), 11 deletions(-)

diff --git a/docs/index.md b/docs/index.md
index f607d74..d4743fc 100644
--- a/docs/index.md
+++ b/docs/index.md
@@ -30,13 +30,13 @@ You can get the CLI in the following ways
 2. Using `go get`
 
 ```sh
-go get -u github.com/barelyhuman/commitlog
+go get -u github.com/barelyhuman/commitlog/v3
 ```
 
 3. Using goblin
 
 ```sh
-curl -sf https://goblin.run/github.com/barelyhuman/commitlog | sh
+curl -sf https://goblin.run/github.com/barelyhuman/commitlog/v3@v3 | sh
 ```
 
 Once installed you can just run `commitlog generate` or the shorter version
@@ -91,15 +91,6 @@ from the download section of this website or use something like
 system (rarely needed) since the releases actually accommodate the most used
 operating systems and architectures already.
 
-**Goblin**
-
-If using something like goblin, you'll have to request for the latest go module based version
-which can be requested like so
-
-```sh
-curl -sf http://goblin.run/github.com/barelyhuman/commitlog/v3@v3 | sh
-```
-
 **Linux/Mac (Unix Systems)**
 
 Once downloaded, you can use the `install` command on \*nix systems to link the

From c29eb24263dfa7183ded88cf40764dd030fe9f7b Mon Sep 17 00:00:00 2001
From: Reaper Gelera <ahoy@barelyhuman.dev>
Date: Thu, 31 Aug 2023 03:29:44 +0530
Subject: [PATCH 47/51] ci: move to v3

---
 .github/workflows/changelog.yml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/.github/workflows/changelog.yml b/.github/workflows/changelog.yml
index fa15c53..dd081a4 100644
--- a/.github/workflows/changelog.yml
+++ b/.github/workflows/changelog.yml
@@ -15,7 +15,7 @@ jobs:
       - name: Generate Change Log
         id: generate_log
         run: |
-          curl -sSL https://goblin.run/github.com/barelyhuman/commitlog | sh
+          curl -sSL https://goblin.run/github.com/barelyhuman/commitlog/v3@v3 | sh
           commitlog g > CHANGELOG.md
       - uses: ncipollo/release-action@v1
         with:

From 99dbd7135f5d7e62aa0b63b6c73874c7ffea623f Mon Sep 17 00:00:00 2001
From: Reaper Gelera <ahoy@barelyhuman.dev>
Date: Thu, 31 Aug 2023 03:32:00 +0530
Subject: [PATCH 48/51] chore: gitignore force root folder bin

---
 .gitignore | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/.gitignore b/.gitignore
index 20fab68..2cb6b8d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -5,4 +5,4 @@ dist
 commitlog
 lab
 api_urls.json
-bin
\ No newline at end of file
+/bin
\ No newline at end of file

From 06c305b9b72c6febbac0a6a1a56b1f13604b28f9 Mon Sep 17 00:00:00 2001
From: Reaper Gelera <ahoy@barelyhuman.dev>
Date: Thu, 31 Aug 2023 03:33:19 +0530
Subject: [PATCH 49/51] update docs

---
 docs/download.md | 28 ++++++++++++++--------------
 1 file changed, 14 insertions(+), 14 deletions(-)

diff --git a/docs/download.md b/docs/download.md
index ec017bf..989b599 100644
--- a/docs/download.md
+++ b/docs/download.md
@@ -11,17 +11,17 @@
 
 #### Downloads
 
-[commitlog-v2.0.6-beta.0-darwin-amd64.tar.gz](https://github.com/barelyhuman/commitlog/releases/download/v2.0.6-beta.0/commitlog-v2.0.6-beta.0-darwin-amd64.tar.gz)    
-[commitlog-v2.0.6-beta.0-darwin-amd64.tar.gz.md5](https://github.com/barelyhuman/commitlog/releases/download/v2.0.6-beta.0/commitlog-v2.0.6-beta.0-darwin-amd64.tar.gz.md5)    
-[commitlog-v2.0.6-beta.0-darwin-arm64.tar.gz](https://github.com/barelyhuman/commitlog/releases/download/v2.0.6-beta.0/commitlog-v2.0.6-beta.0-darwin-arm64.tar.gz)    
-[commitlog-v2.0.6-beta.0-darwin-arm64.tar.gz.md5](https://github.com/barelyhuman/commitlog/releases/download/v2.0.6-beta.0/commitlog-v2.0.6-beta.0-darwin-arm64.tar.gz.md5)    
-[commitlog-v2.0.6-beta.0-linux-386.tar.gz](https://github.com/barelyhuman/commitlog/releases/download/v2.0.6-beta.0/commitlog-v2.0.6-beta.0-linux-386.tar.gz)    
-[commitlog-v2.0.6-beta.0-linux-386.tar.gz.md5](https://github.com/barelyhuman/commitlog/releases/download/v2.0.6-beta.0/commitlog-v2.0.6-beta.0-linux-386.tar.gz.md5)    
-[commitlog-v2.0.6-beta.0-linux-amd64.tar.gz](https://github.com/barelyhuman/commitlog/releases/download/v2.0.6-beta.0/commitlog-v2.0.6-beta.0-linux-amd64.tar.gz)    
-[commitlog-v2.0.6-beta.0-linux-amd64.tar.gz.md5](https://github.com/barelyhuman/commitlog/releases/download/v2.0.6-beta.0/commitlog-v2.0.6-beta.0-linux-amd64.tar.gz.md5)    
-[commitlog-v2.0.6-beta.0-linux-arm64.tar.gz](https://github.com/barelyhuman/commitlog/releases/download/v2.0.6-beta.0/commitlog-v2.0.6-beta.0-linux-arm64.tar.gz)    
-[commitlog-v2.0.6-beta.0-linux-arm64.tar.gz.md5](https://github.com/barelyhuman/commitlog/releases/download/v2.0.6-beta.0/commitlog-v2.0.6-beta.0-linux-arm64.tar.gz.md5)    
-[commitlog-v2.0.6-beta.0-windows-386.zip](https://github.com/barelyhuman/commitlog/releases/download/v2.0.6-beta.0/commitlog-v2.0.6-beta.0-windows-386.zip)    
-[commitlog-v2.0.6-beta.0-windows-386.zip.md5](https://github.com/barelyhuman/commitlog/releases/download/v2.0.6-beta.0/commitlog-v2.0.6-beta.0-windows-386.zip.md5)    
-[commitlog-v2.0.6-beta.0-windows-amd64.zip](https://github.com/barelyhuman/commitlog/releases/download/v2.0.6-beta.0/commitlog-v2.0.6-beta.0-windows-amd64.zip)    
-[commitlog-v2.0.6-beta.0-windows-amd64.zip.md5](https://github.com/barelyhuman/commitlog/releases/download/v2.0.6-beta.0/commitlog-v2.0.6-beta.0-windows-amd64.zip.md5)    
+[commitlog-v3.0.0-darwin-amd64.tar.gz](https://github.com/barelyhuman/commitlog/releases/download/v3.0.0/commitlog-v3.0.0-darwin-amd64.tar.gz)    
+[commitlog-v3.0.0-darwin-amd64.tar.gz.md5](https://github.com/barelyhuman/commitlog/releases/download/v3.0.0/commitlog-v3.0.0-darwin-amd64.tar.gz.md5)    
+[commitlog-v3.0.0-darwin-arm64.tar.gz](https://github.com/barelyhuman/commitlog/releases/download/v3.0.0/commitlog-v3.0.0-darwin-arm64.tar.gz)    
+[commitlog-v3.0.0-darwin-arm64.tar.gz.md5](https://github.com/barelyhuman/commitlog/releases/download/v3.0.0/commitlog-v3.0.0-darwin-arm64.tar.gz.md5)    
+[commitlog-v3.0.0-linux-386.tar.gz](https://github.com/barelyhuman/commitlog/releases/download/v3.0.0/commitlog-v3.0.0-linux-386.tar.gz)    
+[commitlog-v3.0.0-linux-386.tar.gz.md5](https://github.com/barelyhuman/commitlog/releases/download/v3.0.0/commitlog-v3.0.0-linux-386.tar.gz.md5)    
+[commitlog-v3.0.0-linux-amd64.tar.gz](https://github.com/barelyhuman/commitlog/releases/download/v3.0.0/commitlog-v3.0.0-linux-amd64.tar.gz)    
+[commitlog-v3.0.0-linux-amd64.tar.gz.md5](https://github.com/barelyhuman/commitlog/releases/download/v3.0.0/commitlog-v3.0.0-linux-amd64.tar.gz.md5)    
+[commitlog-v3.0.0-linux-arm64.tar.gz](https://github.com/barelyhuman/commitlog/releases/download/v3.0.0/commitlog-v3.0.0-linux-arm64.tar.gz)    
+[commitlog-v3.0.0-linux-arm64.tar.gz.md5](https://github.com/barelyhuman/commitlog/releases/download/v3.0.0/commitlog-v3.0.0-linux-arm64.tar.gz.md5)    
+[commitlog-v3.0.0-windows-386.zip](https://github.com/barelyhuman/commitlog/releases/download/v3.0.0/commitlog-v3.0.0-windows-386.zip)    
+[commitlog-v3.0.0-windows-386.zip.md5](https://github.com/barelyhuman/commitlog/releases/download/v3.0.0/commitlog-v3.0.0-windows-386.zip.md5)    
+[commitlog-v3.0.0-windows-amd64.zip](https://github.com/barelyhuman/commitlog/releases/download/v3.0.0/commitlog-v3.0.0-windows-amd64.zip)    
+[commitlog-v3.0.0-windows-amd64.zip.md5](https://github.com/barelyhuman/commitlog/releases/download/v3.0.0/commitlog-v3.0.0-windows-amd64.zip.md5)    

From f986077bfea77513a45b077bf9d03100086524d1 Mon Sep 17 00:00:00 2001
From: reaper <ahoy@barelyhuman.dev>
Date: Fri, 3 May 2024 18:55:24 +0530
Subject: [PATCH 50/51] docs: update

---
 README.md     | 15 +++++++++++++++
 docs/index.md |  6 ++++--
 2 files changed, 19 insertions(+), 2 deletions(-)

diff --git a/README.md b/README.md
index 3ea1e3c..80b44e0 100644
--- a/README.md
+++ b/README.md
@@ -12,6 +12,21 @@
 - Handle release versioning of the project
 - Stay small
 
+## Installation
+
+
+### Using [goblin.run](https://goblin.run)
+```sh
+; curl -sfL https://goblin.run/github.com/barelyhuman/commitlog/v3 | sh
+```
+
+### go
+If you have go installed, you can use the below command
+
+```sh
+go install github.com/barelyhuman/commitlog/v3@latest
+```
+
 ## Why
 
 Every language has it's own isolated version of a tool like this, for someone who works with multiple languages, it's easier to
diff --git a/docs/index.md b/docs/index.md
index d4743fc..20dd520 100644
--- a/docs/index.md
+++ b/docs/index.md
@@ -27,16 +27,18 @@ You can get the CLI in the following ways
 
 1. You can get the binaries from the [download section](/download)
 
-2. Using `go get`
+2. Using `go`
 
 ```sh
 go get -u github.com/barelyhuman/commitlog/v3
+# or 
+go install github.com/barelyhuman/commitlog/v3@latest
 ```
 
 3. Using goblin
 
 ```sh
-curl -sf https://goblin.run/github.com/barelyhuman/commitlog/v3@v3 | sh
+curl -sf https://goblin.run/github.com/barelyhuman/commitlog/v3 | sh
 ```
 
 Once installed you can just run `commitlog generate` or the shorter version

From 4b7ea89c38ae2c0728f1f7ec263eb5d6e499a082 Mon Sep 17 00:00:00 2001
From: reaper <ahoy@barelyhuman.dev>
Date: Fri, 3 May 2024 18:57:41 +0530
Subject: [PATCH 51/51] docs: update

---
 docs/index.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/docs/index.md b/docs/index.md
index 20dd520..faf4305 100644
--- a/docs/index.md
+++ b/docs/index.md
@@ -38,7 +38,7 @@ go install github.com/barelyhuman/commitlog/v3@latest
 3. Using goblin
 
 ```sh
-curl -sf https://goblin.run/github.com/barelyhuman/commitlog/v3 | sh
+curl -sf https://goblin.run/github.com/barelyhuman/commitlog/v3 | OUT=commitlog sh
 ```
 
 Once installed you can just run `commitlog generate` or the shorter version
