github.com/blend/go-sdk@v1.20220411.3/cmd/semver/main.go (about) 1 /* 2 3 Copyright (c) 2022 - Present. Blend Labs, Inc. All rights reserved 4 Use of this source code is governed by a MIT license that can be found in the LICENSE file. 5 6 */ 7 8 package main 9 10 import ( 11 "fmt" 12 "io" 13 "os" 14 "strings" 15 16 "github.com/blend/go-sdk/semver" 17 ) 18 19 func usage() { 20 fmt.Fprint(os.Stdout, "version validates and manage versions from a given file\n") 21 fmt.Fprint(os.Stdout, "\ncommands:\n") 22 fmt.Fprint(os.Stdout, "\tvalidate\t\t\t\tvalidate a given version file\n") 23 fmt.Fprint(os.Stdout, "\tincrement major|minor|patch\t\tincrement a given version segment\n") 24 fmt.Fprint(os.Stdout, "\tsatisfies <version constraint>\t\tverify a version satisfies a constraint\n") 25 fmt.Fprint(os.Stdout, "\nusage:\n") 26 fmt.Fprint(os.Stdout, "\tversion [command] [args] -f [filename]\n") 27 } 28 29 func main() { 30 if len(os.Args) < 3 { 31 usage() 32 os.Exit(1) 33 } 34 35 command, args := os.Args[1], os.Args[2:] 36 37 switch command { 38 case "increment": 39 increment(args) 40 os.Exit(0) 41 case "satisfies": 42 satisfies(args) 43 os.Exit(0) 44 case "validate": 45 validate(args) 46 os.Exit(0) 47 default: 48 fmt.Fprintf(os.Stderr, "invalid command: %s\n", command) 49 os.Exit(1) 50 } 51 } 52 53 func readContents(path string) (contents []byte, err error) { 54 if strings.TrimSpace(path) == "-" { 55 contents, err = io.ReadAll(os.Stdin) 56 } else { 57 contents, err = os.ReadFile(path) 58 } 59 return 60 } 61 62 func increment(args []string) { 63 if len(args) < 2 { 64 fmt.Fprintf(os.Stderr, "must supply a semver segment and a file\n") 65 os.Exit(1) 66 } 67 68 segment := args[0] 69 filepath := args[1] 70 71 contents, err := readContents(filepath) 72 if err != nil { 73 fmt.Fprintf(os.Stderr, "%+v\n", err) 74 os.Exit(1) 75 } 76 77 version, err := semver.NewVersion(strings.TrimSpace(string(contents))) 78 if err != nil { 79 fmt.Fprintf(os.Stderr, "%+v\n", err) 80 os.Exit(1) 81 } 82 83 switch strings.ToLower(segment) { 84 case "patch": 85 version.BumpPatch() 86 case "minor": 87 version.BumpMinor() 88 case "major": 89 version.BumpMajor() 90 default: 91 fmt.Fprintf(os.Stderr, "invalid segment: %s\n", segment) 92 fmt.Fprintf(os.Stderr, "should be one of: 'major', 'minor', and 'patch'\n") 93 os.Exit(1) 94 } 95 96 fmt.Printf("%v\n", version) 97 } 98 99 func satisfies(args []string) { 100 if len(args) < 2 { 101 fmt.Fprintf(os.Stderr, "must supply a version constraint and a file\n") 102 os.Exit(1) 103 } 104 105 constraintValue := args[0] 106 filepath := args[1] 107 108 contents, err := readContents(filepath) 109 if err != nil { 110 fmt.Fprintf(os.Stderr, "%+v\n", err) 111 os.Exit(1) 112 } 113 114 version, err := semver.NewVersion(strings.TrimSpace(string(contents))) 115 if err != nil { 116 fmt.Fprintf(os.Stderr, "%+v\n", err) 117 os.Exit(1) 118 } 119 120 constraint, err := semver.NewConstraint(constraintValue) 121 if err != nil { 122 fmt.Fprintf(os.Stderr, "%+v\n", err) 123 os.Exit(1) 124 } 125 126 if !constraint.Check(version) { 127 fmt.Fprintf(os.Stderr, "`%s` does not satisfy `%s`\n", constraint.String(), version.String()) 128 os.Exit(1) 129 } 130 } 131 132 func validate(args []string) { 133 if len(args) == 0 { 134 fmt.Fprintf(os.Stderr, "must supply a file\n") 135 os.Exit(1) 136 } 137 filepath := args[0] 138 contents, err := readContents(filepath) 139 if err != nil { 140 fmt.Fprintf(os.Stderr, "%+v\n", err) 141 os.Exit(1) 142 } 143 _, err = semver.NewVersion(strings.TrimSpace(string(contents))) 144 if err != nil { 145 fmt.Fprintf(os.Stderr, "%+v\n", err) 146 os.Exit(1) 147 } 148 }