github.com/inflatablewoman/deis@v1.0.1-0.20141111034523-a4511c46a6ce/contrib/bumpver/bump.go (about) 1 package main 2 3 import ( 4 "bytes" 5 "fmt" 6 "io/ioutil" 7 "os" 8 "regexp" 9 "strings" 10 11 docopt "github.com/docopt/docopt-go" 12 ) 13 14 // Command processes command-line arguments according to a usage string specification. 15 func Command(argv []string) (returnCode int) { 16 usage := ` 17 Updates the current semantic version number to a new one in the specified 18 source and doc files. 19 20 Usage: 21 bumpver [-f <current>] <version> <files>... 22 23 Options: 24 -f --from=<current> An explicit version string to replace. Otherwise, use 25 the first semantic version found in the first file. 26 ` 27 argv = parseArgs(argv) 28 // parse command-line arguments 29 args, err := docopt.Parse(usage, argv, true, "bumpversion 0.1.0", true, false) 30 if err != nil { 31 return 1 32 } 33 if len(args) == 0 { 34 return 0 35 } 36 re := regexp.MustCompile(`(\d{1,3}\.\d{1,3}\.\d{1,3})`) 37 // validate that <version> is a proper semver string 38 version := (args["<version>"].(string)) 39 if version != re.FindString(version) { 40 return onError(fmt.Errorf("Error: '%s' is not a valid semantic version string", version)) 41 } 42 files := args["<files>"].([]string) 43 var from []byte 44 var data []byte 45 if args["--from"] != nil { 46 from = []byte(args["--from"].(string)) 47 } 48 for _, name := range files { 49 src, err := ioutil.ReadFile(name) 50 if err != nil { 51 return onError(err) 52 } 53 if len(from) == 0 { 54 // find the first semver match in the file, if any 55 from = re.Find(src) 56 if from = re.Find(src); len(from) == 0 { 57 fmt.Printf("Skipped %s\n", name) 58 continue 59 } 60 } 61 // replace the first occurrence in source files 62 count := 1 63 if strings.HasSuffix(name, ".md") || strings.HasSuffix(name, ".rst") { 64 // replace all occurrences in docs 65 count = -1 66 } 67 data = bytes.Replace(src, from, []byte(version), count) 68 f, err := os.Create(name) 69 if err != nil { 70 return onError(err) 71 } 72 if _, err = f.Write(data); err != nil { 73 return onError(err) 74 } 75 fmt.Printf("Bumped %s\n", name) 76 } 77 return 0 78 } 79 80 func onError(err error) int { 81 fmt.Println(err.Error()) 82 return 1 83 } 84 85 func parseArgs(argv []string) []string { 86 if argv == nil { 87 argv = os.Args[1:] 88 } 89 90 if len(argv) > 0 { 91 // parse "help <command>" as "command> --help" 92 if argv[0] == "help" { 93 argv = append(argv[1:], "--help") 94 } 95 } 96 return argv 97 }