144 lines
4.1 KiB
Go
144 lines
4.1 KiB
Go
package main
|
|
|
|
import (
|
|
"flag"
|
|
"fmt"
|
|
"os"
|
|
"strconv"
|
|
"strings"
|
|
)
|
|
|
|
type VERSION struct {
|
|
Filename string
|
|
Major, Minor, Patch, Revision uint64
|
|
HasMajor, HasMinor, HasPatch, HasRevision bool
|
|
}
|
|
|
|
func (v *VERSION) Flush() error {
|
|
return os.WriteFile(v.Filename, []byte(v.String()), 0664)
|
|
}
|
|
|
|
func (v VERSION) String() string {
|
|
var buffer strings.Builder
|
|
if v.HasMajor || v.HasMinor || v.HasPatch || v.HasRevision {
|
|
buffer.WriteString(fmt.Sprintf("%d", v.Major))
|
|
}
|
|
if v.HasMinor || v.HasPatch || v.HasRevision {
|
|
buffer.WriteString(fmt.Sprintf(".%d", v.Minor))
|
|
}
|
|
if v.HasPatch || v.HasRevision {
|
|
buffer.WriteString(fmt.Sprintf(".%d", v.Patch))
|
|
}
|
|
if v.HasRevision {
|
|
buffer.WriteString(fmt.Sprintf("-%d", v.Revision))
|
|
}
|
|
return buffer.String()
|
|
}
|
|
|
|
func NewVersion(filename string) (VERSION, error) {
|
|
f, err := os.ReadFile(filename)
|
|
if err != nil {
|
|
return VERSION{}, fmt.Errorf("error reading %s: %w", filename, err)
|
|
}
|
|
fields := strings.FieldsFunc(strings.TrimSpace(string(f)), func(r rune) bool { return r == '.' || r == '-' })
|
|
if len(fields) > 4 {
|
|
return VERSION{}, fmt.Errorf("invalid VERSION file format - %d fields (expected 0-4)", len(fields))
|
|
}
|
|
results := VERSION{
|
|
Filename: filename,
|
|
}
|
|
if len(fields) > 0 {
|
|
results.Major, err = strconv.ParseUint(fields[0], 10, 64)
|
|
if err != nil {
|
|
return VERSION{}, fmt.Errorf("error parsing major version: %w", err)
|
|
}
|
|
results.HasMajor = true
|
|
}
|
|
if len(fields) > 1 {
|
|
results.Minor, err = strconv.ParseUint(fields[1], 10, 64)
|
|
if err != nil {
|
|
return VERSION{}, fmt.Errorf("error parsing minor version: %w", err)
|
|
}
|
|
results.HasMinor = true
|
|
}
|
|
if len(fields) > 2 {
|
|
results.Patch, err = strconv.ParseUint(fields[2], 10, 64)
|
|
if err != nil {
|
|
return VERSION{}, fmt.Errorf("error parsing patch version: %w", err)
|
|
}
|
|
results.HasPatch = true
|
|
}
|
|
if len(fields) > 3 {
|
|
results.Revision, err = strconv.ParseUint(fields[3], 10, 64)
|
|
if err != nil {
|
|
return VERSION{}, fmt.Errorf("error parsing revision: %w", err)
|
|
}
|
|
results.HasRevision = true
|
|
}
|
|
return results, nil
|
|
}
|
|
|
|
func IncrementVersion(version VERSION, major, minor, patch, revision bool) VERSION {
|
|
if major {
|
|
version.Major++
|
|
version.HasMajor = true
|
|
}
|
|
if minor {
|
|
version.Minor++
|
|
version.HasMinor = true
|
|
}
|
|
if patch {
|
|
version.Patch++
|
|
version.HasPatch = true
|
|
}
|
|
if revision {
|
|
version.Revision++
|
|
version.HasRevision = true
|
|
}
|
|
return version
|
|
}
|
|
|
|
func main() {
|
|
flag.Usage = func() {
|
|
fmt.Println("usage: increment_version <path to VERSION file>")
|
|
fmt.Println(" increment_version <optional flags> <path to VERSION file>")
|
|
fmt.Println("increment_version increments the version of a given VERSION file.")
|
|
fmt.Println("It accepts the following formats:")
|
|
fmt.Println("\t<major>.<minor>.<patch>-<revision>")
|
|
fmt.Println("\t<major>.<minor>.<patch>")
|
|
fmt.Println("\t<major>.<minor>")
|
|
fmt.Println("\t<major>")
|
|
fmt.Println("the following flags are used to determine which fields to increment.")
|
|
fmt.Println("using a flag without a corresponding value in the VERSION file will result")
|
|
fmt.Println("in that field, along with all the necessary fields to the left being")
|
|
fmt.Println("created inside that file.")
|
|
}
|
|
var major, minor, patch, revision, dry bool
|
|
flag.BoolVar(&major, "major", false, "increment major version")
|
|
flag.BoolVar(&minor, "minor", false, "increment minor version")
|
|
flag.BoolVar(&patch, "patch", false, "increment patch version")
|
|
flag.BoolVar(&revision, "revision", false, "increment revision")
|
|
flag.BoolVar(&dry, "dry", true, "do not change the file (just print the new version)")
|
|
flag.Parse()
|
|
args := flag.Args()
|
|
if len(args) == 0 {
|
|
fmt.Println("requires path to VERSION file")
|
|
flag.Usage()
|
|
os.Exit(1)
|
|
}
|
|
filename := strings.Join(args, " ")
|
|
oldversion, err := NewVersion(filename)
|
|
if err != nil {
|
|
fmt.Printf("error loading version file %s: %v\n", filename, err)
|
|
os.Exit(1)
|
|
}
|
|
newversion := IncrementVersion(oldversion, major, minor, patch, revision)
|
|
fmt.Printf("'%s' => '%s'\n", oldversion, newversion)
|
|
if !dry {
|
|
err = newversion.Flush()
|
|
if err != nil {
|
|
fmt.Printf("error writing updated VERSION to %s: %v\n", filename, err)
|
|
}
|
|
}
|
|
}
|