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  }