mirror of
https://github.com/strongdm/comply
synced 2024-11-17 13:24:53 +00:00
127 lines
2.9 KiB
Go
127 lines
2.9 KiB
Go
|
package main
|
||
|
|
||
|
import (
|
||
|
"flag"
|
||
|
"fmt"
|
||
|
"gopkg.in/blang/semver.v1"
|
||
|
"io/ioutil"
|
||
|
"log"
|
||
|
"os"
|
||
|
"path/filepath"
|
||
|
"strings"
|
||
|
)
|
||
|
|
||
|
func commitMessage(message, version string) string {
|
||
|
if strings.Contains(message, "%s") {
|
||
|
return fmt.Sprintf(message, version)
|
||
|
}
|
||
|
return message
|
||
|
}
|
||
|
|
||
|
func getCurrentVersion(path string) (*semver.Version, error) {
|
||
|
if _, err := os.Stat(path); os.IsNotExist(err) {
|
||
|
return &semver.Version{}, nil
|
||
|
}
|
||
|
contents, err := ioutil.ReadFile(path)
|
||
|
if err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
return semver.New(strings.TrimSpace(string(contents)))
|
||
|
}
|
||
|
|
||
|
const versionFileName = "VERSION"
|
||
|
|
||
|
func exitWithError(message string) {
|
||
|
fmt.Fprintf(os.Stderr, message+"\n\n")
|
||
|
flag.Usage()
|
||
|
os.Exit(1)
|
||
|
}
|
||
|
|
||
|
func bump(old *semver.Version, part string) *semver.Version {
|
||
|
// We don't want to mutate the input, but there's no Clone or Copy method on a semver.Version,
|
||
|
// so we make a new one by parsing the string version of the old one.
|
||
|
// We ignore any errors because we know it's valid semver.
|
||
|
new, _ := semver.New(old.String())
|
||
|
switch part {
|
||
|
case "major":
|
||
|
new.Major++
|
||
|
new.Minor = 0
|
||
|
new.Patch = 0
|
||
|
case "minor":
|
||
|
new.Minor++
|
||
|
new.Patch = 0
|
||
|
case "patch":
|
||
|
new.Patch++
|
||
|
}
|
||
|
return new
|
||
|
}
|
||
|
|
||
|
func main() {
|
||
|
flag.Usage = func() {
|
||
|
fmt.Fprintf(os.Stderr, "Usage of %s: [options] version\n\n", os.Args[0])
|
||
|
fmt.Fprintf(os.Stderr, "version can be one of: newversion | patch | minor | major\n\n")
|
||
|
fmt.Fprintf(os.Stderr, "options:\n")
|
||
|
flag.PrintDefaults()
|
||
|
}
|
||
|
message := flag.String("m", "%s", "commit message for version commit")
|
||
|
help := flag.Bool("h", false, "print usage and exit")
|
||
|
shouldTag := flag.Bool("tag", true, "whether or not to make a tag at the version commit")
|
||
|
flag.Parse()
|
||
|
|
||
|
if *help {
|
||
|
flag.Usage()
|
||
|
os.Exit(0)
|
||
|
}
|
||
|
|
||
|
if *message == "" {
|
||
|
exitWithError("missing message")
|
||
|
}
|
||
|
|
||
|
if clean, err := isRepoClean(); err != nil {
|
||
|
log.Fatal(err)
|
||
|
} else if !clean {
|
||
|
log.Fatal("repo isn't clean")
|
||
|
}
|
||
|
|
||
|
root, err := repoRoot()
|
||
|
if err != nil {
|
||
|
log.Fatal(err)
|
||
|
}
|
||
|
versionFile := filepath.Join(root, versionFileName)
|
||
|
version, err := getCurrentVersion(versionFile)
|
||
|
if err != nil {
|
||
|
log.Fatal(err)
|
||
|
}
|
||
|
if len(flag.Args()) != 1 {
|
||
|
exitWithError("gitsem takes exactly one non-flag argument: version")
|
||
|
}
|
||
|
|
||
|
newVersion := flag.Args()[0]
|
||
|
switch newVersion {
|
||
|
case "patch", "minor", "major":
|
||
|
version = bump(version, newVersion)
|
||
|
default:
|
||
|
if version, err = semver.New(newVersion); err != nil {
|
||
|
log.Fatalf("failed to parse %s as semver: %s", newVersion, err.Error())
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if err := ioutil.WriteFile(versionFile, []byte(version.String()), 0666); err != nil {
|
||
|
log.Fatal(err)
|
||
|
}
|
||
|
if err := addFile(versionFile); err != nil {
|
||
|
log.Fatal(err)
|
||
|
}
|
||
|
versionString := "v" + version.String()
|
||
|
*message = commitMessage(*message, versionString)
|
||
|
if err := commit(*message); err != nil {
|
||
|
log.Fatal(err)
|
||
|
}
|
||
|
if *shouldTag {
|
||
|
if err := tag(versionString); err != nil {
|
||
|
log.Fatal(err)
|
||
|
}
|
||
|
}
|
||
|
fmt.Println(versionString)
|
||
|
}
|