Skip to content
This repository has been archived by the owner on Mar 26, 2023. It is now read-only.

Commit

Permalink
Merge pull request #1 from jcmuller/implement-semver
Browse files Browse the repository at this point in the history
Implement semver
  • Loading branch information
jcmuller committed Mar 1, 2023
2 parents e0b0a73 + f43e9ae commit 3a2ae5c
Show file tree
Hide file tree
Showing 10 changed files with 260 additions and 1 deletion.
45 changes: 45 additions & 0 deletions .github/workflows/lint.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
name: lint
on:
push:
tags:
- v*
branches:
- main
pull_request:
permissions:
contents: read
# Optional: allow read access to pull request. Use with `only-new-issues` option.
# pull-requests: read
jobs:
golangci:
name: lint
runs-on: ubuntu-latest
steps:
- uses: actions/setup-go@v3
with:
go-version: '1.20'
- uses: actions/checkout@v3
- name: golangci-lint
uses: golangci/golangci-lint-action@v3
with:
# Optional: version of golangci-lint to use in form of v1.2 or v1.2.3 or `latest` to use the latest version
version: v1.51

# Optional: working directory, useful for monorepos
# working-directory: somedir

# Optional: golangci-lint command line arguments.
# args: --issues-exit-code=0

# Optional: show only new issues if it's a pull request. The default value is `false`.
# only-new-issues: true

# Optional: if set to true then the all caching functionality will be complete disabled,
# takes precedence over all other caching options.
# skip-cache: true

# Optional: if set to true then the action don't cache or restore ~/go/pkg.
# skip-pkg-cache: true

# Optional: if set to true then the action don't cache or restore ~/.cache/go-build.
# skip-build-cache: true
18 changes: 18 additions & 0 deletions .github/workflows/test.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
name: test
on:
push:
tags:
- v*
branches:
- main
pull_request:
permissions:
contents: read
jobs:
golangci:
name: test
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-go@v3
- uses: n8maninger/action-golang-test@v1
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,4 @@
*.out

# Dependency directories (remove the comment below to include it)
# vendor/
vendor/
1 change: 1 addition & 0 deletions .go-version
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
1.20.1
29 changes: 29 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,31 @@
# semver

A semantic version bumper

## Installation

```
go install github.com/jcmuller/semver@latest
```

## Usage

```
$ semver v1.2.3
v1.2.4
```

```
# latest tag is v2.1.4
$ git tag --list 'v*' --sort=version:refname --merged | tail -n1 | semver --increment minor
v2.2.0
```

```
$ semver --help
Usage of semver:
-i, --increment string Increment [major|minor|patch]. Default level is patch (default "patch")
-m, --metadata string Set metadata version
-p, --pre-release string Set pre-release version
-s, --show Show passed in version and exit
-v, --version Show semver's version and exit
21 changes: 21 additions & 0 deletions flags.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package main

import "github.com/spf13/pflag"

var (
increment = "patch"
prerelease string
metadata string
show bool
showVersion bool
)

func setupFlags() {
pflag.StringVarP(&increment, "increment", "i", increment, "Increment [major|minor|patch]. Default level is patch")
pflag.StringVarP(&prerelease, "pre-release", "p", "", "Set pre-release version")
pflag.StringVarP(&metadata, "metadata", "m", "", "Set metadata version")
pflag.BoolVarP(&show, "show", "s", false, "Show passed in version and exit")
pflag.BoolVarP(&showVersion, "version", "v", false, "Show semver's version and exit")

pflag.Parse()
}
8 changes: 8 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
module github.com/jcmuller/semver

go 1.20

require (
github.com/Masterminds/semver/v3 v3.2.0
github.com/spf13/pflag v1.0.5
)
4 changes: 4 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
github.com/Masterminds/semver/v3 v3.2.0 h1:3MEsd0SM6jqZojhjLWWeBY+Kcjy9i6MQAeY7YgDP83g=
github.com/Masterminds/semver/v3 v3.2.0/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ=
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
118 changes: 118 additions & 0 deletions main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
package main

import (
"bufio"
"bytes"
"fmt"
"io"
"os"

semver "github.com/Masterminds/semver/v3"
"github.com/spf13/pflag"
)

func main() {
setupFlags()

if showVersion {
printProgramVersion()
os.Exit(0)
}

version, err := getVersion(pflag.Args())
if err != nil {
err = fmt.Errorf("error getting version: %w", err)
fail(err)
}

ver, err := semver.NewVersion(version)
if err != nil {
err = fmt.Errorf("error parsing version: %w", err)
fail(err)
}

if !show {
err := bumpVersion(ver)
if err != nil {
fail(err)
}
}

fmt.Printf("v%s\n", ver.String())
}

func fail(i any) {
fmt.Fprintln(os.Stderr, i)
os.Exit(1)
}

func getVersion(args []string) (string, error) {
var version string
var readFromStdin bool

switch len(args) {
case 0:
readFromStdin = true
case 1:
version = args[0]
readFromStdin = version == "-"
default:
return "", fmt.Errorf("invalid version supplied. Either pass it in as STDIN, or as the only argument to this program")
}

if readFromStdin {
v, err := readInput(os.Stdin)
if err != nil {
err = fmt.Errorf("error reading stdin: %w", err)
return "", err
}

version = string(v)
}

return version, nil
}

func bumpVersion(ver *semver.Version) error {
switch increment {
case "major":
*ver = ver.IncMajor()
case "minor":
*ver = ver.IncMinor()
case "patch":
*ver = ver.IncPatch()
}

var err error

*ver, err = ver.SetMetadata(metadata)
if err != nil {
err = fmt.Errorf("error setting metadata: %w", err)
return err
}
*ver, err = ver.SetPrerelease(prerelease)
if err != nil {
err = fmt.Errorf("error setting pre-release: %w", err)
return err
}

return nil
}

func readInput(reader io.Reader) ([]byte, error) {
buf := new(bytes.Buffer)
scanner := bufio.NewScanner(reader)
for scanner.Scan() {
if _, err := buf.Write(scanner.Bytes()); err != nil {
err = fmt.Errorf("error writing to buffer: %w", err)
return nil, err
}
}

if err := scanner.Err(); err != nil {
err = fmt.Errorf("error scanning: %w", err)
return nil, err
}

return buf.Bytes(), nil
}
15 changes: 15 additions & 0 deletions version.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package main

import (
"fmt"
"runtime/debug"
)

func printProgramVersion() {
info, ok := debug.ReadBuildInfo()
if !ok {
panic("could not read build info")
}

fmt.Printf("semver %s\n", info.Main.Version)
}

0 comments on commit 3a2ae5c

Please sign in to comment.