Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
go: [ '1.17', '1.16', '1.15' ]
go: [ '1.17', '1.16' ]
steps:
- uses: actions/checkout@v2
- uses: actions/setup-go@v2
Expand All @@ -32,7 +32,7 @@ jobs:
runs-on: macos-latest
strategy:
matrix:
go: [ '1.17', '1.16', '1.15' ]
go: [ '1.17', '1.16' ]
steps:
- uses: actions/checkout@v2
- uses: actions/setup-go@v2
Expand All @@ -41,14 +41,14 @@ jobs:
- name: Install libgit2
run: |
brew install libssh2
brew install libgit2
brew install carlsberg/tap/libgit2@1.1.0
- run: go build

# build-windows:
# runs-on: windows-latest
# strategy:
# matrix:
# go: [ '1.17', '1.16', '1.15' ]
# go: [ '1.17', '1.16' ]
# steps:
# - uses: actions/checkout@v2
# - uses: actions/setup-go@v2
Expand Down Expand Up @@ -78,4 +78,4 @@ jobs:
# export PATH="/c/msys64/:/c/msys64/usr/:/c/msys64/usr/bin:$PATH"
# go get -v ./...
# ./make.bat build
# - run: go build
# - run: go build
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# git-semver

[![Build](https://github.com/crqra/git-semver/actions/workflows/build.yml/badge.svg)](https://github.com/crqra/git-semver/actions/workflows/build.yml) [![LoC](https://tokei.rs/b1/github/crqra/git-semver)](https://github.com/crqra/git-semver)
[![Build](https://github.com/carlsberg/git-semver/actions/workflows/build.yml/badge.svg)](https://github.com/carlsberg/git-semver/actions/workflows/build.yml) [![LoC](https://tokei.rs/b1/github/crqra/git-semver)](https://github.com/crqra/git-semver)


> Git extension to easily manage your project's version based on [Semantic Versioning][semver] and [Conventional Commits][conventional-commits]
Expand Down
23 changes: 23 additions & 0 deletions cmd/git-semver/git-semver.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package git_semver
import (
"fmt"
"log"
"strings"

"github.com/Masterminds/semver"
git_semver "github.com/crqra/git-semver/internal/git-semver"
Expand Down Expand Up @@ -61,6 +62,26 @@ var bumpCmd = &cobra.Command{

nextVersion := git_semver.BumpVersion(*latestVersion, increment)

versionFiles := make([]git_semver.VersionFile, 0)
versionFilenamesAndKeys, err := cmd.Flags().GetStringArray("version-file")
if err != nil {
log.Fatal(err)
}

for _, filenameAndKey := range versionFilenamesAndKeys {
slice := strings.Split(filenameAndKey, ":")

if len(slice) != 2 {
log.Fatalf("%s is not correctly formatted. Should be `filename:key`", filenameAndKey)
}

versionFiles = append(versionFiles, git_semver.VersionFile{Filename: slice[0], Key: slice[1]})
}

if err := git_semver.UpdateVersionFiles(repo, versionFiles, *latestVersion, nextVersion); err != nil {
log.Fatal(err)
}

if err := git_semver.TagVersion(repo, nextVersion); err != nil {
log.Fatal(err)
}
Expand Down Expand Up @@ -148,4 +169,6 @@ func init() {
rootCmd.AddCommand(bumpCmd)
rootCmd.AddCommand(nextCmd)
rootCmd.AddCommand(latestCmd)

bumpCmd.Flags().StringArrayP("version-file", "f", make([]string, 0), "Specify version files to be updated with the new version in the format `filename:key` (i.e. `package.json:\"version\"`)")
}
101 changes: 101 additions & 0 deletions internal/git-semver/mod.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ package git_semver

import (
"fmt"
"io/fs"
"io/ioutil"
"log"
"regexp"
"sort"
Expand All @@ -13,6 +15,10 @@ import (

type Increment int64
type Change string
type VersionFile struct {
Filename string
Key string
}

const (
Major Increment = 4
Expand Down Expand Up @@ -63,6 +69,54 @@ func ListVersions(repo *git.Repository) ([]*semver.Version, error) {
return versions, nil
}

func CreateCommit(repo *git.Repository, message string) error {
sig, err := repo.DefaultSignature()
if err != nil {
return err
}

head, err := repo.Head()
if err != nil {
return err
}

idx, err := repo.Index()
if err != nil {
return err
}

idx.AddAll(make([]string, 0), git.IndexAddDefault, func(_, _ string) int {
return 0
})

treeId, err := idx.WriteTree()
if err != nil {
return err
}

err = idx.Write()
if err != nil {
return err
}

tree, err := repo.LookupTree(treeId)
if err != nil {
return err
}

commitTarget, err := repo.LookupCommit(head.Target())
if err != nil {
return err
}

_, err = repo.CreateCommit("refs/heads/main", sig, sig, message, tree, commitTarget)
if err != nil {
return err
}

return nil
}

func ListCommits(repo *git.Repository) ([]*git.Commit, error) {
revwalk, err := repo.Walk()
if err != nil {
Expand Down Expand Up @@ -195,3 +249,50 @@ func PushVersionTagToRemotes(repo *git.Repository, version semver.Version) error

return nil
}

func UpdateVersionFiles(repo *git.Repository, versionFiles []VersionFile, currentVersion semver.Version, nextVersion semver.Version) error {
if len(versionFiles) == 0 {
return nil
}

for _, versionFile := range versionFiles {
err := updateVersionFileVersion(versionFile, currentVersion, nextVersion)
if err != nil {
return err
}
}

err := CreateCommit(repo, fmt.Sprintf("bump: %s -> %s", currentVersion.String(), nextVersion.String()))
if err != nil {
return err
}

return nil
}

func regexForVersionFileKey(key string, currentVersion semver.Version) (*regexp.Regexp, error) {
return regexp.Compile(fmt.Sprintf("%s(.{1,})?%s", key, currentVersion.String()))
}

func updateVersionFileVersion(versionFile VersionFile, currentVersion semver.Version, nextVersion semver.Version) error {
r, err := regexForVersionFileKey(versionFile.Key, currentVersion)
if err != nil {
return err
}

contents, err := ioutil.ReadFile(versionFile.Filename)
if err != nil {
return err
}

match := string(r.Find(contents))
newVersionString := strings.Replace(match, currentVersion.String(), nextVersion.String(), 1)
newContents := strings.Replace(string(contents), match, newVersionString, 1)

err = ioutil.WriteFile(versionFile.Filename, []byte(newContents), fs.ModePerm)
if err != nil {
return err
}

return nil
}