diff --git a/.circleci/config.yml b/.circleci/config.yml index 9a6291a..23568c8 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -18,7 +18,6 @@ jobs: command: | make build-in-docker [[ -d build ]] && sudo chown -R circleci:circleci build - [[ -d vendor ]] && sudo chown -R circleci:circleci vendor - run: command: | ls -lah diff --git a/Dockerfile.build b/Dockerfile.build index 1ec2700..d1d5f18 100644 --- a/Dockerfile.build +++ b/Dockerfile.build @@ -1,4 +1,4 @@ -FROM golang:1.10.3-stretch +FROM golang:1.12.0-stretch RUN apt-get update \ && apt install apt-transport-https build-essential curl gnupg2 lintian rpm rsync rubygems-integration ruby-dev ruby -qy \ @@ -7,4 +7,4 @@ RUN apt-get update \ RUN gem install --no-ri --no-rdoc --quiet rake fpm package_cloud -RUN curl -s https://raw.githubusercontent.com/golang/dep/master/install.sh | INSTALL_DIRECTORY=/usr/local/bin sh +WORKDIR /src diff --git a/Gopkg.lock b/Gopkg.lock deleted file mode 100644 index 6f1a324..0000000 --- a/Gopkg.lock +++ /dev/null @@ -1,27 +0,0 @@ -# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'. - - -[[projects]] - branch = "master" - name = "github.com/akamensky/argparse" - packages = ["."] - revision = "95911c018170ab2092b96d15985030390b4535af" - -[[projects]] - branch = "master" - name = "github.com/andrew-d/go-termutil" - packages = ["."] - revision = "009166a695a2f516c749a26b4ac1f183d89aa336" - -[[projects]] - name = "github.com/joho/godotenv" - packages = ["."] - revision = "a79fa1e548e2c689c241d10173efd51e5d689d5b" - version = "v1.2.0" - -[solve-meta] - analyzer-name = "dep" - analyzer-version = 1 - inputs-digest = "fa803d0b0878c5b19eaced9d34b34fb26c817a9c5d1e3aa2277dfa68b2f5c0a5" - solver-name = "gps-cdcl" - solver-version = 1 diff --git a/Gopkg.toml b/Gopkg.toml deleted file mode 100644 index a43f06c..0000000 --- a/Gopkg.toml +++ /dev/null @@ -1,42 +0,0 @@ -# Gopkg.toml example -# -# Refer to https://golang.github.io/dep/docs/Gopkg.toml.html -# for detailed Gopkg.toml documentation. -# -# required = ["github.com/user/thing/cmd/thing"] -# ignored = ["github.com/user/project/pkgX", "bitbucket.org/user/project/pkgA/pkgY"] -# -# [[constraint]] -# name = "github.com/user/project" -# version = "1.0.0" -# -# [[constraint]] -# name = "github.com/user/project2" -# branch = "dev" -# source = "github.com/myfork/project2" -# -# [[override]] -# name = "github.com/x/y" -# version = "2.4.0" -# -# [prune] -# non-go = false -# go-tests = true -# unused-packages = true - - -[prune] - go-tests = true - unused-packages = true - -[[constraint]] - name = "github.com/joho/godotenv" - version = "1.2.0" - -[[constraint]] - branch = "master" - name = "github.com/akamensky/argparse" - -[[constraint]] - branch = "master" - name = "github.com/andrew-d/go-termutil" diff --git a/Makefile b/Makefile index dcbabea..a687996 100644 --- a/Makefile +++ b/Makefile @@ -4,7 +4,8 @@ MAINTAINER = josegonzalez MAINTAINER_NAME = Jose Diaz-Gonzalez REPOSITORY = go-procfile-util HARDWARE = $(shell uname -m) -BASE_VERSION ?= 0.4.0 +SYSTEM_NAME = $(shell uname -s | tr '[:upper:]' '[:lower:]') +BASE_VERSION ?= 0.5.0 IMAGE_NAME ?= $(MAINTAINER)/$(REPOSITORY) PACKAGECLOUD_REPOSITORY ?= dokku/dokku-betafish @@ -42,7 +43,6 @@ targets = $(addsuffix -in-docker, $(LIST)) @echo "VERSION=$(VERSION)" >> .env.docker build: - @$(MAKE) deps @$(MAKE) build/darwin/$(NAME) @$(MAKE) build/linux/$(NAME) @$(MAKE) build/deb/$(NAME)_$(VERSION)_amd64.deb @@ -57,19 +57,19 @@ $(targets): %-in-docker: .env.docker --rm \ --volume /var/lib/docker:/var/lib/docker \ --volume /var/run/docker.sock:/var/run/docker.sock:ro \ - --volume ${PWD}:/go/src/github.com/$(MAINTAINER)/$(REPOSITORY) \ - --workdir /go/src/github.com/$(MAINTAINER)/$(REPOSITORY) \ + --volume ${PWD}:/src/github.com/$(MAINTAINER)/$(REPOSITORY) \ + --workdir /src/github.com/$(MAINTAINER)/$(REPOSITORY) \ $(IMAGE_NAME):build make -e $(@:-in-docker=) build/darwin/$(NAME): mkdir -p build/darwin - CGO_ENABLED=0 GOOS=darwin go build -a -asmflags=-trimpath=/go/src -gcflags=-trimpath=/go/src \ + CGO_ENABLED=0 GOOS=darwin go build -a -asmflags=-trimpath=/src -gcflags=-trimpath=/src \ -ldflags "-s -w -X main.Version=$(VERSION)" \ -o build/darwin/$(NAME) build/linux/$(NAME): mkdir -p build/linux - CGO_ENABLED=0 GOOS=linux go build -a -asmflags=-trimpath=/go/src -gcflags=-trimpath=/go/src \ + CGO_ENABLED=0 GOOS=linux go build -a -asmflags=-trimpath=/src -gcflags=-trimpath=/src \ -ldflags "-s -w -X main.Version=$(VERSION)" \ -o build/linux/$(NAME) @@ -121,20 +121,22 @@ circleci: docker version rm -f ~/.gitconfig -deps: - dep ensure -vendor-only - docker-image: docker build --rm -q -f Dockerfile.hub -t $(IMAGE_NAME):$(DOCKER_VERSION) . -release: build - go get -u github.com/progrium/gh-release/... +gh-release: + mkdir -p build + curl -o build/gh-release.tgz -sL https://github.com/progrium/gh-release/releases/download/v2.2.1/gh-release_2.2.1_$(SYSTEM_NAME)_$(HARDWARE).tgz + tar xf build/gh-release.tgz -C build + chmod +x build/gh-release + +release: build gh-release rm -rf release && mkdir release tar -zcf release/$(NAME)_$(VERSION)_linux_$(HARDWARE).tgz -C build/linux $(NAME) tar -zcf release/$(NAME)_$(VERSION)_darwin_$(HARDWARE).tgz -C build/darwin $(NAME) cp build/deb/$(NAME)_$(VERSION)_amd64.deb release/$(NAME)_$(VERSION)_amd64.deb cp build/rpm/$(NAME)-$(VERSION)-1.x86_64.rpm release/$(NAME)-$(VERSION)-1.x86_64.rpm - gh-release create $(MAINTAINER)/$(REPOSITORY) $(VERSION) $(shell git rev-parse --abbrev-ref HEAD) + build/gh-release create $(MAINTAINER)/$(REPOSITORY) $(VERSION) $(shell git rev-parse --abbrev-ref HEAD) release-packagecloud: @$(MAKE) release-packagecloud-deb diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..c4672ee --- /dev/null +++ b/go.mod @@ -0,0 +1,9 @@ +module procfile-util + +go 1.12 + +require ( + github.com/akamensky/argparse v0.0.0-20180405044306-95911c018170 + github.com/andrew-d/go-termutil v0.0.0-20150726205930-009166a695a2 + github.com/joho/godotenv v1.2.0 +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..60acdd4 --- /dev/null +++ b/go.sum @@ -0,0 +1,6 @@ +github.com/akamensky/argparse v0.0.0-20180405044306-95911c018170 h1:JuYOgmyY+ckpAAfYbiToLlgcjidpLKgjVbu+7J09FI4= +github.com/akamensky/argparse v0.0.0-20180405044306-95911c018170/go.mod h1:pdh+2piXurh466J9tqIqq39/9GO2Y8nZt6Cxzu18T9A= +github.com/andrew-d/go-termutil v0.0.0-20150726205930-009166a695a2 h1:axBiC50cNZOs7ygH5BgQp4N+aYrZ2DNpWZ1KG3VOSOM= +github.com/andrew-d/go-termutil v0.0.0-20150726205930-009166a695a2/go.mod h1:jnzFpU88PccN/tPPhCpnNU8mZphvKxYM9lLNkd8e+os= +github.com/joho/godotenv v1.2.0 h1:vGTvz69FzUFp+X4/bAkb0j5BoLC+9bpqTWY8mjhA9pc= +github.com/joho/godotenv v1.2.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg= diff --git a/main.go b/main.go index 1296fb8..ad346d9 100644 --- a/main.go +++ b/main.go @@ -72,7 +72,8 @@ func getProcfile(path string) (string, error) { func parseProcfile(path string, delimiter string) ([]procfileEntry, error) { var entries []procfileEntry - re, _ := regexp.Compile(`^([A-Za-z0-9_]+)` + delimiter + `\s*(.+)$`) + reCmd, _ := regexp.Compile(`^([A-Za-z0-9_]+)` + delimiter + `\s*(.+)$`) + reComment, _ := regexp.Compile(`^(.*)\s#.+$`) text, err := getProcfile(path) if err != nil { @@ -87,7 +88,7 @@ func parseProcfile(path string, delimiter string) ([]procfileEntry, error) { continue } - params := re.FindStringSubmatch(line) + params := reCmd.FindStringSubmatch(line) if len(params) != 3 { debugMessage(fmt.Sprintf("No matching params in line: %v", line)) continue @@ -100,6 +101,11 @@ func parseProcfile(path string, delimiter string) ([]procfileEntry, error) { } names[name] = true + commentParams := reComment.FindStringSubmatch(cmd) + if len(commentParams) == 2 { + cmd = commentParams[1] + } + entries = append(entries, procfileEntry{name, cmd}) } diff --git a/vendor/github.com/akamensky/argparse/.gitignore b/vendor/github.com/akamensky/argparse/.gitignore deleted file mode 100644 index f479089..0000000 --- a/vendor/github.com/akamensky/argparse/.gitignore +++ /dev/null @@ -1,16 +0,0 @@ -# Binaries for programs and plugins -*.exe -*.dll -*.so -*.dylib - -# Test binary, build with `go test -c` -*.test - -# Output of the go coverage tool, specifically when used with LiteIDE -*.out - -# Project-local glide cache, RE: https://github.com/Masterminds/glide/issues/736 -.glide/ - -.idea/ \ No newline at end of file diff --git a/vendor/github.com/akamensky/argparse/.travis.yml b/vendor/github.com/akamensky/argparse/.travis.yml deleted file mode 100644 index af004a0..0000000 --- a/vendor/github.com/akamensky/argparse/.travis.yml +++ /dev/null @@ -1,5 +0,0 @@ -language: go -go: - - "1.8" - - "1.9" - - "1.10" diff --git a/vendor/github.com/akamensky/argparse/LICENSE b/vendor/github.com/akamensky/argparse/LICENSE deleted file mode 100644 index f1831c5..0000000 --- a/vendor/github.com/akamensky/argparse/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2017 Alexey Kamenskiy - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/vendor/github.com/akamensky/argparse/README.md b/vendor/github.com/akamensky/argparse/README.md deleted file mode 100644 index a249a71..0000000 --- a/vendor/github.com/akamensky/argparse/README.md +++ /dev/null @@ -1,129 +0,0 @@ -# Golang argparse - -[![GoDoc](https://godoc.org/github.com/akamensky/argparse?status.svg)](https://godoc.org/github.com/akamensky/argparse) [![Go Report Card](https://goreportcard.com/badge/github.com/akamensky/argparse)](https://goreportcard.com/report/github.com/akamensky/argparse) [![cover.run go](https://cover.run/go/github.com/akamensky/argparse.svg)](https://cover.run/go/github.com/akamensky/argparse) [![Build Status](https://travis-ci.org/akamensky/argparse.svg?branch=master)](https://travis-ci.org/akamensky/argparse) - -Let's be honest -- Go's standard command line arguments parser `flag` terribly sucks. -It cannot come anywhere close to the Python's `argparse` module. This is why this project exists. - -The goal of this project is to bring ease of use and flexibility of `argparse` to Go. -Which is where the name of this package comes from. - -#### Installation - -To install and start using argparse simply do: - -``` -$ go get -u -v github.com/akamensky/argparse -``` - -You are good to go to write your first command line tool! -See Usage and Examples sections for information how you can use it - -#### Usage - -To start using argparse in Go see above instructions on how to install. -From here on you can start writing your first program. -Please check out examples from `examples/` directory to see how to use it in various ways. - -Here is basic example of print command (from `examples/print/` directory): -```go -package main - -import ( - "fmt" - "github.com/akamensky/argparse" - "os" -) - -func main() { - // Create new parser object - parser := argparse.NewParser("print", "Prints provided string to stdout") - // Create string flag - s := parser.String("s", "string", &argparse.Options{Required: true, Help: "String to print"}) - // Parse input - err := parser.Parse(os.Args) - if err != nil { - // In case of error print error and print usage - // This can also be done by passing -h or --help flags - fmt.Print(parser.Usage(err)) - } - // Finally print the collected string - fmt.Println(*s) -} -``` - -#### Basic options - -Create your parser instance and pass it program name and program description. -Program name if empty will be taken from `os.Args[0]` (which is okay in most cases). -Description can be as long as you wish and will be used in `--help` output -```go -parser := argparse.NewParser("progname", "Description of my awesome program. It can be as long as I wish it to be") -``` - -String will allow you to get a string from arguments, such as `$ progname --string "String content"` -```go -var myString *string = parser.String("s", "string", ...) -``` - -Flag will tell you if a simple flag was set on command line (true is set, false is not). -For example `$ progname --force` -```go -var myFlag *bool = parser.Flag("f", "force", ...) -``` - -List allows to collect multiple values into the slice of strings by repeating same flag multiple times. -Such as `$ progname --host hostname1 --host hostname2 -H hostname3` -```go -var myList *[]string = parser.List("H", "hostname", ...) -``` - -Selector works same as a string, except that it will only allow specific values. -For example like this `$ progname --debug-level WARN` -```go -var mySelector *string = parser.Selector("d", "debug-level", []string{"INFO", "DEBUG", "WARN"}, ...) -``` - -File will validate that file exists and will attempt to open it with provided privileges. -To be used like this `$ progname --log-file /path/to/file.log` -```go -var myLogFile *os.File = parser.File("l", "log-file", os.O_RDWR, 0600, ...) -``` - -You can implement sub-commands in your CLI using `parser.NewCommand()` or go even deeper with `command.NewCommand()`. -Since parser inherits from command, every command supports exactly same options as parser itself, -thus allowing to add arguments specific to that command or more global arguments added on parser itself! - -#### Caveats - -There are a few caveats (or more like design choices) to know about: -* Shorthand arguments MUST be a single character. Shorthand arguments are prepended with single dash `"-"` -* If not convenient shorthand argument can be completely skipped by passing empty string `""` as first argument -* Shorthand arguments ONLY for `parser.Flag()` can be combined into single argument same as `ps -aux` or `rm -rf` -* Long arguments are required and cannot be empty. They are prepended with double dash `"--"` -* You cannot define two same arguments. Only first one will be used. For example doing `parser.Flag("t", "test", nil)` followed by `parser.String("t", "test2", nil)` will not work as second `String` argument will be ignored (note that both have `"t"` as shorthand argument). However since it is case-sensitive library, you can work arounf it by capitalizing one of the arguments -* There is a pre-defined argument for `-h|--help`, so from above attempting to define any argument using `h` as shorthand will fail -* `parser.Parse()` returns error in case of something going wrong, but it is not expected to cover ALL cases -* Any arguments that left un-parsed will be regarded as error - - -#### Contributing - -Can you write in Go? Then this projects needs your help! - -Take a look at open issues, specially the ones tagged as `help-wanted`. -If you have any improvements to offer, please open an issue first to ensure this improvement is discussed. - -There are following tasks to be done: -* Add more examples -* Improve code quality (it is messy right now and could use a major revamp to improve gocyclo report) -* Add more argument options (such as numbers parsing) -* Improve test coverage -* Write a wiki for this project - -However note that the logic outlined in method comments must be preserved -as the the library must stick with backward compatibility promise! - -#### Acknowledgments - -Thanks to Python developers for making a great `argparse` which inspired this package to match for greatness of Go diff --git a/vendor/github.com/akamensky/argparse/argparse.go b/vendor/github.com/akamensky/argparse/argparse.go deleted file mode 100644 index 65248df..0000000 --- a/vendor/github.com/akamensky/argparse/argparse.go +++ /dev/null @@ -1,396 +0,0 @@ -// Package argparse provides users with more flexible and configurable option for command line arguments parsing. -package argparse - -import ( - "errors" - "fmt" - "os" - "strings" -) - -// Command is a basic type for this package. It represents top level Parser as well as any commands and sub-commands -// Command MUST NOT ever be created manually. Instead one should call NewCommand method of Parser or Command, -// which will setup appropriate fields and call methods that have to be called when creating new command. -type Command struct { - name string - description string - args []*arg - commands []*Command - parsed bool - parent *Command -} - -// Parser is a top level object of argparse. It MUST NOT ever be created manually. Instead one should use -// argparse.NewParser() method that will create new parser, propagate necessary private fields and call needed -// functions. -type Parser struct { - Command -} - -// Options are specific options for every argument. They can be provided if necessary. -// Possible fields are: -// -// Options.Required - tells Parser that this argument is required to be provided. -// useful when specific Command requires some data provided. -// -// Options.Validate - is a validation function. Using this field anyone can implement a custom validation for argument. -// If provided and argument is present, then function is called. If argument also consumes any following values -// (e.g. as String does), then these are provided as args to function. If validation fails the error must be returned, -// which will be the output of `Parser.Parse` method. -// -// Options.Help - A help message to be displayed in Usage output. Can be of any length as the message will be -// formatted to fit max screen width of 100 characters. -// -// Options.Default - A default value for an argument. This value will be assigned to the argument at the end of parsing -// in case if this argument was not supplied on command line. File default value is a string which it will be open with -// provided options. In case if provided value type does not match expected, the error will be returned on run-time. -type Options struct { - Required bool - Validate func(args []string) error - Help string - Default interface{} -} - -// NewParser creates new Parser object that will allow to add arguments for parsing -// It takes program name and description which will be used as part of Usage output -// Returns pointer to Parser object -func NewParser(name string, description string) *Parser { - p := &Parser{} - - p.name = name - p.description = description - - p.args = make([]*arg, 0) - p.commands = make([]*Command, 0) - - p.help() - - return p -} - -// NewCommand will create a sub-command and propagate all necessary fields. -// All commands are always at the beginning of the arguments. -// Parser can have commands and those commands can have sub-commands, -// which allows for very flexible workflow. -// All commands are considered as required and all commands can have their own argument set. -// Commands are processed Parser -> Command -> sub-Command. -// Arguments will be processed in order of sub-Command -> Command -> Parser. -func (o *Command) NewCommand(name string, description string) *Command { - c := new(Command) - c.name = name - c.description = description - c.parsed = false - c.parent = o - - c.help() - - if o.commands == nil { - o.commands = make([]*Command, 0) - } - - o.commands = append(o.commands, c) - - return c -} - -// Flag Creates new flag type of argument, which is boolean value showing if argument was provided or not. -// Takes short name, long name and pointer to options (optional). -// Short name must be single character, but can be omitted by giving empty string. -// Long name is required. -// Returns pointer to boolean with starting value `false`. If Parser finds the flag -// provided on Command line arguments, then the value is changed to true. -// Only for Flag shorthand arguments can be combined together such as `rm -rf` -func (o *Command) Flag(short string, long string, opts *Options) *bool { - var result bool - - a := &arg{ - result: &result, - sname: short, - lname: long, - size: 1, - opts: opts, - unique: true, - } - - o.addArg(a) - - return &result -} - -// String creates new string argument, which will return whatever follows the argument on CLI. -// Takes as arguments short name (must be single character or an empty string) -// long name and (optional) options -func (o *Command) String(short string, long string, opts *Options) *string { - var result string - - a := &arg{ - result: &result, - sname: short, - lname: long, - size: 2, - opts: opts, - unique: true, - } - - o.addArg(a) - - return &result -} - -// Int creates new int argument, which will attempt to parse following argument as int. -// Takes as arguments short name (must be single character or an empty string) -// long name and (optional) options. -// If parsing fails parser.Parse() will return an error. -func (o *Command) Int(short string, long string, opts *Options) *int { - var result int - - a := &arg{ - result: &result, - sname: short, - lname: long, - size: 2, - opts: opts, - unique: true, - } - - o.addArg(a) - - return &result -} - -// Float creates new float argument, which will attempt to parse following argument as float64. -// Takes as arguments short name (must be single character or an empty string) -// long name and (optional) options. -// If parsing fails parser.Parse() will return an error. -func (o *Command) Float(short string, long string, opts *Options) *float64 { - var result float64 - - a := &arg{ - result: &result, - sname: short, - lname: long, - size: 2, - opts: opts, - unique: true, - } - - o.addArg(a) - - return &result -} - -// File creates new file argument, which is when provided will check if file exists or attempt to create it -// depending on provided flags (same as for os.OpenFile). -// It takes same as all other arguments short and long names, additionally it takes flags that specify -// in which mode the file should be open (see os.OpenFile for details on that), file permissions that -// will be applied to a file and argument options. -// Returns a pointer to os.File which will be set to opened file on success. On error the Parser.Parse -// will return error and the pointer might be nil. -func (o *Command) File(short string, long string, flag int, perm os.FileMode, opts *Options) *os.File { - var result os.File - - a := &arg{ - result: &result, - sname: short, - lname: long, - size: 2, - opts: opts, - unique: true, - fileFlag: flag, - filePerm: perm, - } - - o.addArg(a) - - return &result -} - -// List creates new list argument. This is the argument that is allowed to be present multiple times on CLI. -// All appearances of this argument on CLI will be collected into the list of strings. If no argument -// provided, then the list is empty. Takes same parameters as String -// Returns a pointer the list of strings. -func (o *Command) List(short string, long string, opts *Options) *[]string { - result := make([]string, 0) - - a := &arg{ - result: &result, - sname: short, - lname: long, - size: 2, - opts: opts, - unique: false, - } - - o.addArg(a) - - return &result -} - -// Selector creates a selector argument. Selector argument works in the same way as String argument, with -// the difference that the string value must be from the list of options provided by the program. -// Takes short and long names, argument options and a slice of strings which are allowed values -// for CLI argument. -// Returns a pointer to a string. If argument is not required (as in argparse.Options.Required), -// and argument was not provided, then the string is empty. -func (o *Command) Selector(short string, long string, options []string, opts *Options) *string { - var result string - - a := &arg{ - result: &result, - sname: short, - lname: long, - size: 2, - opts: opts, - unique: true, - selector: &options, - } - - o.addArg(a) - - return &result -} - -// Happened shows whether Command was specified on CLI arguments or not. If Command did not "happen", then -// all its descendant commands and arguments are not parsed. Returns a boolean value. -func (o *Command) Happened() bool { - return o.parsed -} - -// Usage returns a multiline string that is the same as a help message for this Parser or Command. -// Since Parser is a Command as well, they work in exactly same way. Meaning that usage string -// can be retrieved for any level of commands. It will only include information about this Command, -// its sub-commands, current Command arguments and arguments of all preceding commands (if any) -func (o *Command) Usage(err interface{}) string { - // Stay classy - maxWidth := 80 - // List of arguments from all preceding commands - arguments := make([]*arg, 0) - // First get line of commands until root - var chain []string - current := o - if err != nil { - switch err.(type) { - case subCommandError: - fmt.Println(err.(error).Error()) - if err.(subCommandError).cmd != nil { - return err.(subCommandError).cmd.Usage(nil) - } - case error: - fmt.Println(err.(error).Error()) - } - } - for current != nil { - chain = append(chain, current.name) - // Also add arguments - if current.args != nil { - arguments = append(arguments, current.args...) - } - current = current.parent - } - // Reverse the slice - last := len(chain) - 1 - for i := 0; i < len(chain)/2; i++ { - chain[i], chain[last-i] = chain[last-i], chain[i] - } - // If this Command has sub-commands we need their list - commands := make([]Command, 0) - if o.commands != nil && len(o.commands) > 0 { - chain = append(chain, "") - for _, v := range o.commands { - commands = append(commands, *v) - } - } - - // Build result description - var result = "usage:" - leftPadding := len("usage: " + chain[0] + "") - // Add preceding commands - for _, v := range chain { - result = addToLastLine(result, v, maxWidth, leftPadding, true) - } - // Add arguments from this and all preceding commands - for _, v := range arguments { - result = addToLastLine(result, v.usage(), maxWidth, leftPadding, true) - } - - // Add program/Command description to the result - result = result + "\n\n" + strings.Repeat(" ", leftPadding) - result = addToLastLine(result, o.description, maxWidth, leftPadding, true) - result = result + "\n\n" - - // Add list of sub-commands to the result - if len(commands) > 0 { - cmdContent := "Commands:\n\n" - // Get biggest padding - var cmdPadding int - for _, com := range commands { - if len(" "+com.name+" ") > cmdPadding { - cmdPadding = len(" " + com.name + " ") - } - } - // Now add commands with known padding - for _, com := range commands { - cmd := " " + com.name - cmd = cmd + strings.Repeat(" ", cmdPadding-len(cmd)-1) - cmd = addToLastLine(cmd, com.description, maxWidth, cmdPadding, true) - cmdContent = cmdContent + cmd + "\n" - } - result = result + cmdContent + "\n" - } - - // Add list of arguments to the result - if len(arguments) > 0 { - argContent := "Arguments:\n\n" - // Get biggest padding - var argPadding int - // Find biggest padding - for _, argument := range arguments { - if len(argument.lname)+9 > argPadding { - argPadding = len(argument.lname) + 9 - } - } - // Now add args with padding - for _, argument := range arguments { - arg := " " - if argument.sname != "" { - arg = arg + "-" + argument.sname + " " - } else { - arg = arg + " " - } - arg = arg + "--" + argument.lname - arg = arg + strings.Repeat(" ", argPadding-len(arg)) - if argument.opts != nil && argument.opts.Help != "" { - arg = addToLastLine(arg, argument.getHelpMessage(), maxWidth, argPadding, true) - } - argContent = argContent + arg + "\n" - } - result = result + argContent + "\n" - } - - return result -} - -// Parse method can be applied only on Parser. It takes a slice of strings (as in os.Args) -// and it will process this slice as arguments of CLI (the original slice is not modified). -// Returns error on any failure. In case of failure recommended course of action is to -// print received error alongside with usage information (might want to check which Command -// was active when error happened and print that specific Command usage). -// In case no error returned all arguments should be safe to use. Safety of using arguments -// before Parse operation is complete is not guaranteed. -func (o *Parser) Parse(args []string) error { - subargs := make([]string, len(args)) - copy(subargs, args) - - result := o.parse(&subargs) - unparsed := make([]string, 0) - for _, v := range subargs { - if v != "" { - unparsed = append(unparsed, v) - } - } - if result == nil && len(unparsed) > 0 { - return errors.New("too many arguments") - } - - return result -} diff --git a/vendor/github.com/akamensky/argparse/argument.go b/vendor/github.com/akamensky/argparse/argument.go deleted file mode 100644 index 5986070..0000000 --- a/vendor/github.com/akamensky/argparse/argument.go +++ /dev/null @@ -1,296 +0,0 @@ -package argparse - -import ( - "fmt" - "os" - "strconv" - "strings" -) - -type arg struct { - result interface{} // Pointer to the resulting value - opts *Options // Options - sname string // Short name (in Parser will start with "-" - lname string // Long name (in Parser will start with "--" - size int // Size defines how many args after match will need to be consumed - unique bool // Specifies whether flag should be present only ones - parsed bool // Specifies whether flag has been parsed already - fileFlag int // File mode to open file with - filePerm os.FileMode // File permissions to set a file - selector *[]string // Used in Selector type to allow to choose only one from list of options - parent *Command // Used to get access to specific Command -} - -type help struct{} - -func (o *arg) check(argument string) bool { - // Shortcut to showing help - if argument == "-h" || argument == "--help" { - helpText := o.parent.Usage(nil) - fmt.Print(helpText) - os.Exit(0) - } - - // Check for long name only if not empty - if o.lname != "" { - // If argument begins with "--" and next is not "-" then it is a long name - if len(argument) > 2 && strings.HasPrefix(argument, "--") && argument[2] != '-' { - if argument[2:] == o.lname { - return true - } - } - } - // Check for short name only if not empty - if o.sname != "" { - // If argument begins with "-" and next is not "-" then it is a short name - if len(argument) > 1 && strings.HasPrefix(argument, "-") && argument[1] != '-' { - switch o.result.(type) { - case *bool: - // For flags we allow multiple shorthand in one - if strings.Contains(argument[1:], o.sname) { - return true - } - default: - // For all other types it must be separate argument - if argument[1:] == o.sname { - return true - } - } - } - } - - return false -} - -func (o *arg) reduce(position int, args *[]string) { - argument := (*args)[position] - // Check for long name only if not empty - if o.lname != "" { - // If argument begins with "--" and next is not "-" then it is a long name - if len(argument) > 2 && strings.HasPrefix(argument, "--") && argument[2] != '-' { - if argument[2:] == o.lname { - for i := position; i < position+o.size; i++ { - (*args)[i] = "" - } - } - } - } - // Check for short name only if not empty - if o.sname != "" { - // If argument begins with "-" and next is not "-" then it is a short name - if len(argument) > 1 && strings.HasPrefix(argument, "-") && argument[1] != '-' { - switch o.result.(type) { - case *bool: - // For flags we allow multiple shorthand in one - if strings.Contains(argument[1:], o.sname) { - (*args)[position] = strings.Replace(argument, o.sname, "", -1) - if (*args)[position] == "-" { - (*args)[position] = "" - } - } - default: - // For all other types it must be separate argument - if argument[1:] == o.sname { - for i := position; i < position+o.size; i++ { - (*args)[i] = "" - } - } - } - } - } -} - -func (o *arg) parse(args []string) error { - // If unique do not allow more than one time - if o.unique && o.parsed { - return fmt.Errorf("[%s] can only be present once", o.name()) - } - - // If validation function provided -- execute, on error return it immediately - if o.opts != nil && o.opts.Validate != nil { - err := o.opts.Validate(args) - if err != nil { - return err - } - } - - switch o.result.(type) { - case *help: - helpText := o.parent.Usage(nil) - fmt.Print(helpText) - os.Exit(0) - case *bool: - *o.result.(*bool) = true - o.parsed = true - case *int: - if len(args) < 1 { - return fmt.Errorf("[%s] must be followed by an integer", o.name()) - } - if len(args) > 1 { - return fmt.Errorf("[%s] followed by too many arguments", o.name()) - } - val, err := strconv.Atoi(args[0]) - if err != nil { - return fmt.Errorf("[%s] bad interger value [%s]", o.name(), args[0]) - } - *o.result.(*int) = val - o.parsed = true - case *float64: - if len(args) < 1 { - return fmt.Errorf("[%s] must be followed by a floating point number", o.name()) - } - if len(args) > 1 { - return fmt.Errorf("[%s] followed by too many arguments", o.name()) - } - val, err := strconv.ParseFloat(args[0], 64) - if err != nil { - return fmt.Errorf("[%s] bad floating point value [%s]", o.name(), args[0]) - } - *o.result.(*float64) = val - o.parsed = true - case *string: - if len(args) < 1 { - return fmt.Errorf("[%s] must be followed by a string", o.name()) - } - if len(args) > 1 { - return fmt.Errorf("[%s] followed by too many arguments", o.name()) - } - // Selector case - if o.selector != nil { - match := false - for _, v := range *o.selector { - if args[0] == v { - match = true - } - } - if !match { - return fmt.Errorf("bad value for [%s]. Allowed values are %v", o.name(), *o.selector) - } - } - *o.result.(*string) = args[0] - o.parsed = true - case *os.File: - if len(args) < 1 { - return fmt.Errorf("[%s] must be followed by a path to file", o.name()) - } - if len(args) > 1 { - return fmt.Errorf("[%s] followed by too many arguments", o.name()) - } - f, err := os.OpenFile(args[0], o.fileFlag, o.filePerm) - if err != nil { - return err - } - *o.result.(*os.File) = *f - o.parsed = true - case *[]string: - if len(args) < 1 { - return fmt.Errorf("[%s] must be followed by a string", o.name()) - } - if len(args) > 1 { - return fmt.Errorf("[%s] followed by too many arguments", o.name()) - } - *o.result.(*[]string) = append(*o.result.(*[]string), args[0]) - o.parsed = true - default: - return fmt.Errorf("unsupported type [%t]", o.result) - } - return nil -} - -func (o *arg) name() string { - var name string - if o.lname == "" { - name = "-" + o.sname - } else if o.sname == "" { - name = "--" + o.lname - } else { - name = "-" + o.sname + "|" + "--" + o.lname - } - return name -} - -func (o *arg) usage() string { - var result string - result = o.name() - switch o.result.(type) { - case *bool: - break - case *int: - result = result + " " - case *float64: - result = result + " " - case *string: - if o.selector != nil { - result = result + " (" + strings.Join(*o.selector, "|") + ")" - } else { - result = result + " \"\"" - } - case *os.File: - result = result + " " - case *[]string: - result = result + " \"\"" + " [" + result + " \"\" ...]" - default: - break - } - if o.opts == nil || o.opts.Required == false { - result = "[" + result + "]" - } - return result -} - -func (o *arg) getHelpMessage() string { - message := "" - if len(o.opts.Help) > 0 { - message += o.opts.Help - if !o.opts.Required && o.opts.Default != nil { - message += fmt.Sprintf(". Default: %v", o.opts.Default) - } - } - return message -} - -func (o *arg) setDefault() error { - // Only set default if it was not parsed, and default value was defined - if !o.parsed && o.opts != nil && o.opts.Default != nil { - switch o.result.(type) { - case *bool: - if _, ok := o.opts.Default.(bool); !ok { - return fmt.Errorf("cannot use default type [%T] as type [bool]", o.opts.Default) - } - *o.result.(*bool) = o.opts.Default.(bool) - case *int: - if _, ok := o.opts.Default.(int); !ok { - return fmt.Errorf("cannot use default type [%T] as type [int]", o.opts.Default) - } - *o.result.(*int) = o.opts.Default.(int) - case *float64: - if _, ok := o.opts.Default.(float64); !ok { - return fmt.Errorf("cannot use default type [%T] as type [float64]", o.opts.Default) - } - *o.result.(*float64) = o.opts.Default.(float64) - case *string: - if _, ok := o.opts.Default.(string); !ok { - return fmt.Errorf("cannot use default type [%T] as type [string]", o.opts.Default) - } - *o.result.(*string) = o.opts.Default.(string) - case *os.File: - // In case of File we should get string as default value - if v, ok := o.opts.Default.(string); ok { - f, err := os.OpenFile(v, o.fileFlag, o.filePerm) - if err != nil { - return err - } - *o.result.(*os.File) = *f - } else { - return fmt.Errorf("cannot use default type [%T] as type [string]", o.opts.Default) - } - case *[]string: - if _, ok := o.opts.Default.([]string); !ok { - return fmt.Errorf("cannot use default type [%T] as type [[]string]", o.opts.Default) - } - *o.result.(*[]string) = o.opts.Default.([]string) - } - } - - return nil -} diff --git a/vendor/github.com/akamensky/argparse/command.go b/vendor/github.com/akamensky/argparse/command.go deleted file mode 100644 index 3fbe400..0000000 --- a/vendor/github.com/akamensky/argparse/command.go +++ /dev/null @@ -1,122 +0,0 @@ -package argparse - -import ( - "fmt" -) - -func (o *Command) help() { - result := &help{} - - a := &arg{ - result: &result, - sname: "h", - lname: "help", - size: 1, - opts: &Options{Help: "Print help information"}, - unique: true, - } - - o.addArg(a) -} - -func (o *Command) addArg(a *arg) { - if a.lname != "" { - if a.sname == "" || len(a.sname) == 1 { - // Search parents for overlapping commands and fail silently if any - current := o - for current != nil { - if current.args != nil { - for _, v := range current.args { - if (a.sname != "" && a.sname == v.sname) || a.lname == v.lname { - return - } - } - } - current = current.parent - } - a.parent = o - o.args = append(o.args, a) - } - } -} - -// Will parse provided list of arguments -// common usage would be to pass directly os.Args -func (o *Command) parse(args *[]string) error { - // If we already been parsed do nothing - if o.parsed { - return nil - } - - // If no arguments left to parse do nothing - if len(*args) < 1 { - return nil - } - - // Parse only matching commands - // But we always have to parse top level - if o.name == "" { - o.name = (*args)[0] - } else { - if o.name != (*args)[0] && o.parent != nil { - return nil - } - } - - // Reduce arguments by removing Command name - *args = (*args)[1:] - - // Parse subcommands if any - if o.commands != nil && len(o.commands) > 0 { - // If we have subcommands and 0 args left - // that is an error of SubCommandError type - if len(*args) < 1 { - return newSubCommandError(o) - } - for _, v := range o.commands { - err := v.parse(args) - if err != nil { - return err - } - } - } - - // Iterate over the args - for i := 0; i < len(o.args); i++ { - oarg := o.args[i] - for j := 0; j < len(*args); j++ { - arg := (*args)[j] - if arg == "" { - continue - } - if oarg.check(arg) { - if len(*args) < j+oarg.size { - return fmt.Errorf("not enough arguments for %s", oarg.name()) - } - err := oarg.parse((*args)[j+1 : j+oarg.size]) - if err != nil { - return err - } - oarg.reduce(j, args) - continue - } - } - - // Check if arg is required and not provided - if oarg.opts != nil && oarg.opts.Required && !oarg.parsed { - return fmt.Errorf("[%s] is required", oarg.name()) - } - - // Check for argument default value and if provided try to type cast and assign - if oarg.opts != nil && oarg.opts.Default != nil && !oarg.parsed { - err := oarg.setDefault() - if err != nil { - return err - } - } - } - - // Set parsed status to true and return quietly - o.parsed = true - return nil -} diff --git a/vendor/github.com/akamensky/argparse/errors.go b/vendor/github.com/akamensky/argparse/errors.go deleted file mode 100644 index 3f5d461..0000000 --- a/vendor/github.com/akamensky/argparse/errors.go +++ /dev/null @@ -1,14 +0,0 @@ -package argparse - -type subCommandError struct { - error - cmd *Command -} - -func (e subCommandError) Error() string { - return "[sub]Command required" -} - -func newSubCommandError(cmd *Command) error { - return subCommandError{cmd: cmd} -} diff --git a/vendor/github.com/akamensky/argparse/extras.go b/vendor/github.com/akamensky/argparse/extras.go deleted file mode 100644 index fbc7d5a..0000000 --- a/vendor/github.com/akamensky/argparse/extras.go +++ /dev/null @@ -1,25 +0,0 @@ -package argparse - -import "strings" - -func getLastLine(input string) string { - slice := strings.Split(input, "\n") - return slice[len(slice)-1] -} - -func addToLastLine(base string, add string, width int, padding int, canSplit bool) string { - // If last line has less than 10% space left, do not try to fill in by splitting else just try to split - hasTen := (width - len(getLastLine(base))) > width/10 - if len(getLastLine(base)+" "+add) >= width { - if hasTen && canSplit { - adds := strings.Split(add, " ") - for _, v := range adds { - base = addToLastLine(base, v, width, padding, false) - } - return base - } - base = base + "\n" + strings.Repeat(" ", padding) - } - base = base + " " + add - return base -} diff --git a/vendor/github.com/andrew-d/go-termutil/LICENSE b/vendor/github.com/andrew-d/go-termutil/LICENSE deleted file mode 100644 index 0920a8a..0000000 --- a/vendor/github.com/andrew-d/go-termutil/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2013-2014 Andrew Dunham - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. diff --git a/vendor/github.com/andrew-d/go-termutil/README.md b/vendor/github.com/andrew-d/go-termutil/README.md deleted file mode 100644 index a557645..0000000 --- a/vendor/github.com/andrew-d/go-termutil/README.md +++ /dev/null @@ -1,15 +0,0 @@ -# go-termutil - -This package exposes some very basic, useful functions: - - Isatty(file *os.File) bool - -This function will return whether or not the given file is a TTY, attempting to use native -operations when possible. It wil fall back to using the `isatty()` function from `unistd.h` -through cgo if on an unknown platform. - - GetPass(prompt string, prompt_fd, input_fd uintptr) ([]byte, error) - -This function will print the `prompt` string to the file identified by `prompt_fd`, prompt the user -for a password without echoing the password to the terminal, print a newline, and then return the -given password to the user. NOTE: not yet tested on anything except Linux & OS X. diff --git a/vendor/github.com/andrew-d/go-termutil/const_bsd.go b/vendor/github.com/andrew-d/go-termutil/const_bsd.go deleted file mode 100644 index a40adaa..0000000 --- a/vendor/github.com/andrew-d/go-termutil/const_bsd.go +++ /dev/null @@ -1,8 +0,0 @@ -// +build darwin freebsd - -package termutil - -import "syscall" - -const ioctlReadTermios = syscall.TIOCGETA -const ioctlWriteTermios = syscall.TIOCSETA diff --git a/vendor/github.com/andrew-d/go-termutil/const_linux.go b/vendor/github.com/andrew-d/go-termutil/const_linux.go deleted file mode 100644 index 8e20871..0000000 --- a/vendor/github.com/andrew-d/go-termutil/const_linux.go +++ /dev/null @@ -1,8 +0,0 @@ -// +build linux - -package termutil - -import "syscall" - -const ioctlReadTermios = syscall.TCGETS -const ioctlWriteTermios = syscall.TCSETS diff --git a/vendor/github.com/andrew-d/go-termutil/getpass.go b/vendor/github.com/andrew-d/go-termutil/getpass.go deleted file mode 100644 index a8651cf..0000000 --- a/vendor/github.com/andrew-d/go-termutil/getpass.go +++ /dev/null @@ -1,7 +0,0 @@ -// +build !windows,!linux,!darwin,!freebsd - -package termutil - -func GetPass(prompt string, prompt_fd, input_fd uintptr) ([]byte, error) { - panic("not implemented") -} diff --git a/vendor/github.com/andrew-d/go-termutil/getpass_nix.go b/vendor/github.com/andrew-d/go-termutil/getpass_nix.go deleted file mode 100644 index 2c2fcbe..0000000 --- a/vendor/github.com/andrew-d/go-termutil/getpass_nix.go +++ /dev/null @@ -1,90 +0,0 @@ -// +build linux darwin freebsd - -package termutil - -import ( - "io" - "syscall" - "unsafe" -) - -func GetPass(prompt string, prompt_fd, input_fd uintptr) ([]byte, error) { - // Firstly, print the prompt. - written := 0 - buf := []byte(prompt) - for written < len(prompt) { - n, err := syscall.Write(int(prompt_fd), buf[written:]) - if err != nil { - return nil, err - } - if n == 0 { - return nil, io.EOF - } - - written += n - } - - // Write a newline after we're done, since it won't be echoed when the - // user presses 'Enter'. - defer syscall.Write(int(prompt_fd), []byte("\n")) - - // Get the current state of the terminal - var oldState syscall.Termios - if _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, - uintptr(input_fd), - ioctlReadTermios, - uintptr(unsafe.Pointer(&oldState)), - 0, 0, 0); err != 0 { - return nil, err - } - - // Turn off echo and write the new state. - newState := oldState - newState.Lflag &^= syscall.ECHO - newState.Lflag |= syscall.ICANON | syscall.ISIG - newState.Iflag |= syscall.ICRNL - if _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, - uintptr(input_fd), - ioctlWriteTermios, - uintptr(unsafe.Pointer(&newState)), - 0, 0, 0); err != 0 { - return nil, err - } - - // Regardless of how we exit, we need to restore the old state. - defer func() { - syscall.Syscall6(syscall.SYS_IOCTL, - uintptr(input_fd), - ioctlWriteTermios, - uintptr(unsafe.Pointer(&oldState)), - 0, 0, 0) - }() - - // Read in increments of 16 bytes. - var readBuf [16]byte - var ret []byte - for { - n, err := syscall.Read(int(input_fd), readBuf[:]) - if err != nil { - return nil, err - } - if n == 0 { - if len(ret) == 0 { - return nil, io.EOF - } - break - } - - // Trim the trailing newline. - if readBuf[n-1] == '\n' { - n-- - } - - ret = append(ret, readBuf[:n]...) - if n < len(readBuf) { - break - } - } - - return ret, nil -} diff --git a/vendor/github.com/andrew-d/go-termutil/getpass_windows.go b/vendor/github.com/andrew-d/go-termutil/getpass_windows.go deleted file mode 100644 index 9797e2d..0000000 --- a/vendor/github.com/andrew-d/go-termutil/getpass_windows.go +++ /dev/null @@ -1,59 +0,0 @@ -// +build windows - -package termutil - -import ( - "syscall" - "io" - "errors" -) - -var ( - f_getwch uintptr // wint_t _getwch(void) -) - -func init() { - f_getwch = syscall.MustLoadDLL("msvcrt.dll").MustFindProc("_getwch").Addr() -} - -func GetPass(prompt string, prompt_fd, input_fd uintptr) ([]byte, error) { - // Firstly, print the prompt. - written := 0 - buf := []byte(prompt) - for written < len(prompt) { - n, err := syscall.Write(syscall.Handle(prompt_fd), buf[written:]) - if err != nil { - return nil, err - } - if n == 0 { - return nil, io.EOF - } - - written += n - } - - // Write a newline after we're done, since it won't be echoed when the - // user presses 'Enter'. - defer syscall.Write(syscall.Handle(prompt_fd), []byte("\r\n")) - - // Read the characters - var chars []uint16 - for { - ret, _, _ := syscall.Syscall(f_getwch, 0, 0, 0, 0) - if ret == 0x000A || ret == 0x000D { - break - } else if ret == 0x0003 { - return nil, errors.New("Input has been interrupted by user.") - } else if ret == 0x0008 { - chars = chars[0:len(chars)-2] - } else { - chars = append(chars, uint16(ret)) - } - } - - // Convert to string... - s := syscall.UTF16ToString(chars) - - // ... and back to UTF-8 bytes. - return []byte(s), nil -} diff --git a/vendor/github.com/andrew-d/go-termutil/isatty-c.go b/vendor/github.com/andrew-d/go-termutil/isatty-c.go deleted file mode 100644 index 0affbc0..0000000 --- a/vendor/github.com/andrew-d/go-termutil/isatty-c.go +++ /dev/null @@ -1,14 +0,0 @@ -// +build !windows,!linux,!darwin,!freebsd,cgo - -package termutil - -/* -#include -*/ -import "C" - -import "os" - -func Isatty(fd uintptr) bool { - return int(C.isatty(C.int(fd))) != 0 -} diff --git a/vendor/github.com/andrew-d/go-termutil/isatty.go b/vendor/github.com/andrew-d/go-termutil/isatty.go deleted file mode 100644 index f1ad904..0000000 --- a/vendor/github.com/andrew-d/go-termutil/isatty.go +++ /dev/null @@ -1,7 +0,0 @@ -// +build !windows,!linux,!darwin,!freebsd,!cgo - -package termutil - -func Isatty(fd uintptr) bool { - panic("Not implemented") -} diff --git a/vendor/github.com/andrew-d/go-termutil/isatty_nix.go b/vendor/github.com/andrew-d/go-termutil/isatty_nix.go deleted file mode 100644 index cf69315..0000000 --- a/vendor/github.com/andrew-d/go-termutil/isatty_nix.go +++ /dev/null @@ -1,20 +0,0 @@ -// +build linux darwin freebsd - -package termutil - -import ( - "syscall" - "unsafe" -) - -func Isatty(fd uintptr) bool { - var termios syscall.Termios - - _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, fd, - uintptr(ioctlReadTermios), - uintptr(unsafe.Pointer(&termios)), - 0, - 0, - 0) - return err == 0 -} diff --git a/vendor/github.com/andrew-d/go-termutil/isatty_windows.go b/vendor/github.com/andrew-d/go-termutil/isatty_windows.go deleted file mode 100644 index ab861b8..0000000 --- a/vendor/github.com/andrew-d/go-termutil/isatty_windows.go +++ /dev/null @@ -1,34 +0,0 @@ -// +build windows - -package termutil - -import ( - "syscall" - "unsafe" -) - -var ( - kernel32 = syscall.MustLoadDLL("kernel32.dll") - fGetConsoleMode = kernel32.MustFindProc("GetConsoleMode") -) - -func Isatty(fd uintptr) bool { - var x uint32 - return getConsoleMode(syscall.Handle(fd), &x) == nil -} - -func getConsoleMode(hConsoleHandle syscall.Handle, lpMode *uint32) error { - ret, _, err := syscall.Syscall(fGetConsoleMode.Addr(), 2, - uintptr(hConsoleHandle), - uintptr(unsafe.Pointer(lpMode)), - 0) - - if int(ret) == 0 { - if err != 0 { - return error(err) - } else { - return syscall.EINVAL - } - } - return nil -} diff --git a/vendor/github.com/joho/godotenv/.gitignore b/vendor/github.com/joho/godotenv/.gitignore deleted file mode 100644 index e43b0f9..0000000 --- a/vendor/github.com/joho/godotenv/.gitignore +++ /dev/null @@ -1 +0,0 @@ -.DS_Store diff --git a/vendor/github.com/joho/godotenv/.travis.yml b/vendor/github.com/joho/godotenv/.travis.yml deleted file mode 100644 index df65350..0000000 --- a/vendor/github.com/joho/godotenv/.travis.yml +++ /dev/null @@ -1,8 +0,0 @@ -language: go - -go: - - 1.8 - -os: - - linux - - osx diff --git a/vendor/github.com/joho/godotenv/LICENCE b/vendor/github.com/joho/godotenv/LICENCE deleted file mode 100644 index e7ddd51..0000000 --- a/vendor/github.com/joho/godotenv/LICENCE +++ /dev/null @@ -1,23 +0,0 @@ -Copyright (c) 2013 John Barton - -MIT License - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - diff --git a/vendor/github.com/joho/godotenv/README.md b/vendor/github.com/joho/godotenv/README.md deleted file mode 100644 index 1a20c78..0000000 --- a/vendor/github.com/joho/godotenv/README.md +++ /dev/null @@ -1,163 +0,0 @@ -# GoDotEnv [![Build Status](https://travis-ci.org/joho/godotenv.svg?branch=master)](https://travis-ci.org/joho/godotenv) [![Build status](https://ci.appveyor.com/api/projects/status/9v40vnfvvgde64u4?svg=true)](https://ci.appveyor.com/project/joho/godotenv) [![Go Report Card](https://goreportcard.com/badge/github.com/joho/godotenv)](https://goreportcard.com/report/github.com/joho/godotenv) - -A Go (golang) port of the Ruby dotenv project (which loads env vars from a .env file) - -From the original Library: - -> Storing configuration in the environment is one of the tenets of a twelve-factor app. Anything that is likely to change between deployment environments–such as resource handles for databases or credentials for external services–should be extracted from the code into environment variables. -> -> But it is not always practical to set environment variables on development machines or continuous integration servers where multiple projects are run. Dotenv load variables from a .env file into ENV when the environment is bootstrapped. - -It can be used as a library (for loading in env for your own daemons etc) or as a bin command. - -There is test coverage and CI for both linuxish and windows environments, but I make no guarantees about the bin version working on windows. - -## Installation - -As a library - -```shell -go get github.com/joho/godotenv -``` - -or if you want to use it as a bin command -```shell -go get github.com/joho/godotenv/cmd/godotenv -``` - -## Usage - -Add your application configuration to your `.env` file in the root of your project: - -```shell -S3_BUCKET=YOURS3BUCKET -SECRET_KEY=YOURSECRETKEYGOESHERE -``` - -Then in your Go app you can do something like - -```go -package main - -import ( - "github.com/joho/godotenv" - "log" - "os" -) - -func main() { - err := godotenv.Load() - if err != nil { - log.Fatal("Error loading .env file") - } - - s3Bucket := os.Getenv("S3_BUCKET") - secretKey := os.Getenv("SECRET_KEY") - - // now do something with s3 or whatever -} -``` - -If you're even lazier than that, you can just take advantage of the autoload package which will read in `.env` on import - -```go -import _ "github.com/joho/godotenv/autoload" -``` - -While `.env` in the project root is the default, you don't have to be constrained, both examples below are 100% legit - -```go -_ = godotenv.Load("somerandomfile") -_ = godotenv.Load("filenumberone.env", "filenumbertwo.env") -``` - -If you want to be really fancy with your env file you can do comments and exports (below is a valid env file) - -```shell -# I am a comment and that is OK -SOME_VAR=someval -FOO=BAR # comments at line end are OK too -export BAR=BAZ -``` - -Or finally you can do YAML(ish) style - -```yaml -FOO: bar -BAR: baz -``` - -as a final aside, if you don't want godotenv munging your env you can just get a map back instead - -```go -var myEnv map[string]string -myEnv, err := godotenv.Read() - -s3Bucket := myEnv["S3_BUCKET"] -``` - -... or from an `io.Reader` instead of a local file - -```go -reader := getRemoteFile() -myEnv, err := godotenv.Parse(reader) -``` - -... or from a `string` if you so desire - -```go -content := getRemoteFileContent() -myEnv, err := godotenv.Unmarshal(content) -``` - -### Command Mode - -Assuming you've installed the command as above and you've got `$GOPATH/bin` in your `$PATH` - -``` -godotenv -f /some/path/to/.env some_command with some args -``` - -If you don't specify `-f` it will fall back on the default of loading `.env` in `PWD` - -### Writing Env Files - -Godotenv can also write a map representing the environment to a correctly-formatted and escaped file - -```go -env, err := godotenv.Unmarshal("KEY=value") -err := godotenv.Write(env, "./.env") -``` - -... or to a string - -```go -env, err := godotenv.Unmarshal("KEY=value") -content, err := godotenv.Marshal(env) -``` - -## Contributing - -Contributions are most welcome! The parser itself is pretty stupidly naive and I wouldn't be surprised if it breaks with edge cases. - -*code changes without tests will not be accepted* - -1. Fork it -2. Create your feature branch (`git checkout -b my-new-feature`) -3. Commit your changes (`git commit -am 'Added some feature'`) -4. Push to the branch (`git push origin my-new-feature`) -5. Create new Pull Request - -## Releases - -Releases should follow [Semver](http://semver.org/) though the first couple of releases are `v1` and `v1.1`. - -Use [annotated tags for all releases](https://github.com/joho/godotenv/issues/30). Example `git tag -a v1.2.1` - -## CI - -Linux: [![Build Status](https://travis-ci.org/joho/godotenv.svg?branch=master)](https://travis-ci.org/joho/godotenv) Windows: [![Build status](https://ci.appveyor.com/api/projects/status/9v40vnfvvgde64u4)](https://ci.appveyor.com/project/joho/godotenv) - -## Who? - -The original library [dotenv](https://github.com/bkeepers/dotenv) was written by [Brandon Keepers](http://opensoul.org/), and this port was done by [John Barton](http://whoisjohnbarton.com) based off the tests/fixtures in the original library. diff --git a/vendor/github.com/joho/godotenv/godotenv.go b/vendor/github.com/joho/godotenv/godotenv.go deleted file mode 100644 index 48ae78c..0000000 --- a/vendor/github.com/joho/godotenv/godotenv.go +++ /dev/null @@ -1,314 +0,0 @@ -// Package godotenv is a go port of the ruby dotenv library (https://github.com/bkeepers/dotenv) -// -// Examples/readme can be found on the github page at https://github.com/joho/godotenv -// -// The TL;DR is that you make a .env file that looks something like -// -// SOME_ENV_VAR=somevalue -// -// and then in your go code you can call -// -// godotenv.Load() -// -// and all the env vars declared in .env will be available through os.Getenv("SOME_ENV_VAR") -package godotenv - -import ( - "bufio" - "errors" - "fmt" - "io" - "os" - "os/exec" - "regexp" - "sort" - "strings" -) - -const doubleQuoteSpecialChars = "\\\n\r\"!$`" - -// Load will read your env file(s) and load them into ENV for this process. -// -// Call this function as close as possible to the start of your program (ideally in main) -// -// If you call Load without any args it will default to loading .env in the current path -// -// You can otherwise tell it which files to load (there can be more than one) like -// -// godotenv.Load("fileone", "filetwo") -// -// It's important to note that it WILL NOT OVERRIDE an env variable that already exists - consider the .env file to set dev vars or sensible defaults -func Load(filenames ...string) (err error) { - filenames = filenamesOrDefault(filenames) - - for _, filename := range filenames { - err = loadFile(filename, false) - if err != nil { - return // return early on a spazout - } - } - return -} - -// Overload will read your env file(s) and load them into ENV for this process. -// -// Call this function as close as possible to the start of your program (ideally in main) -// -// If you call Overload without any args it will default to loading .env in the current path -// -// You can otherwise tell it which files to load (there can be more than one) like -// -// godotenv.Overload("fileone", "filetwo") -// -// It's important to note this WILL OVERRIDE an env variable that already exists - consider the .env file to forcefilly set all vars. -func Overload(filenames ...string) (err error) { - filenames = filenamesOrDefault(filenames) - - for _, filename := range filenames { - err = loadFile(filename, true) - if err != nil { - return // return early on a spazout - } - } - return -} - -// Read all env (with same file loading semantics as Load) but return values as -// a map rather than automatically writing values into env -func Read(filenames ...string) (envMap map[string]string, err error) { - filenames = filenamesOrDefault(filenames) - envMap = make(map[string]string) - - for _, filename := range filenames { - individualEnvMap, individualErr := readFile(filename) - - if individualErr != nil { - err = individualErr - return // return early on a spazout - } - - for key, value := range individualEnvMap { - envMap[key] = value - } - } - - return -} - -// Parse reads an env file from io.Reader, returning a map of keys and values. -func Parse(r io.Reader) (envMap map[string]string, err error) { - envMap = make(map[string]string) - - var lines []string - scanner := bufio.NewScanner(r) - for scanner.Scan() { - lines = append(lines, scanner.Text()) - } - - if err = scanner.Err(); err != nil { - return - } - - for _, fullLine := range lines { - if !isIgnoredLine(fullLine) { - var key, value string - key, value, err = parseLine(fullLine) - - if err != nil { - return - } - envMap[key] = value - } - } - return -} - -//Unmarshal reads an env file from a string, returning a map of keys and values. -func Unmarshal(str string) (envMap map[string]string, err error) { - return Parse(strings.NewReader(str)) -} - -// Exec loads env vars from the specified filenames (empty map falls back to default) -// then executes the cmd specified. -// -// Simply hooks up os.Stdin/err/out to the command and calls Run() -// -// If you want more fine grained control over your command it's recommended -// that you use `Load()` or `Read()` and the `os/exec` package yourself. -func Exec(filenames []string, cmd string, cmdArgs []string) error { - Load(filenames...) - - command := exec.Command(cmd, cmdArgs...) - command.Stdin = os.Stdin - command.Stdout = os.Stdout - command.Stderr = os.Stderr - return command.Run() -} - -// Write serializes the given environment and writes it to a file -func Write(envMap map[string]string, filename string) error { - content, error := Marshal(envMap) - if error != nil { - return error - } - file, error := os.Create(filename) - if error != nil { - return error - } - _, err := file.WriteString(content) - return err -} - -// Marshal outputs the given environment as a dotenv-formatted environment file. -// Each line is in the format: KEY="VALUE" where VALUE is backslash-escaped. -func Marshal(envMap map[string]string) (string, error) { - lines := make([]string, 0, len(envMap)) - for k, v := range envMap { - lines = append(lines, fmt.Sprintf(`%s="%s"`, k, doubleQuoteEscape(v))) - } - sort.Strings(lines) - return strings.Join(lines, "\n"), nil -} - -func filenamesOrDefault(filenames []string) []string { - if len(filenames) == 0 { - return []string{".env"} - } - return filenames -} - -func loadFile(filename string, overload bool) error { - envMap, err := readFile(filename) - if err != nil { - return err - } - - currentEnv := map[string]bool{} - rawEnv := os.Environ() - for _, rawEnvLine := range rawEnv { - key := strings.Split(rawEnvLine, "=")[0] - currentEnv[key] = true - } - - for key, value := range envMap { - if !currentEnv[key] || overload { - os.Setenv(key, value) - } - } - - return nil -} - -func readFile(filename string) (envMap map[string]string, err error) { - file, err := os.Open(filename) - if err != nil { - return - } - defer file.Close() - - return Parse(file) -} - -func parseLine(line string) (key string, value string, err error) { - if len(line) == 0 { - err = errors.New("zero length string") - return - } - - // ditch the comments (but keep quoted hashes) - if strings.Contains(line, "#") { - segmentsBetweenHashes := strings.Split(line, "#") - quotesAreOpen := false - var segmentsToKeep []string - for _, segment := range segmentsBetweenHashes { - if strings.Count(segment, "\"") == 1 || strings.Count(segment, "'") == 1 { - if quotesAreOpen { - quotesAreOpen = false - segmentsToKeep = append(segmentsToKeep, segment) - } else { - quotesAreOpen = true - } - } - - if len(segmentsToKeep) == 0 || quotesAreOpen { - segmentsToKeep = append(segmentsToKeep, segment) - } - } - - line = strings.Join(segmentsToKeep, "#") - } - - firstEquals := strings.Index(line, "=") - firstColon := strings.Index(line, ":") - splitString := strings.SplitN(line, "=", 2) - if firstColon != -1 && (firstColon < firstEquals || firstEquals == -1) { - //this is a yaml-style line - splitString = strings.SplitN(line, ":", 2) - } - - if len(splitString) != 2 { - err = errors.New("Can't separate key from value") - return - } - - // Parse the key - key = splitString[0] - if strings.HasPrefix(key, "export") { - key = strings.TrimPrefix(key, "export") - } - key = strings.Trim(key, " ") - - // Parse the value - value = parseValue(splitString[1]) - return -} - -func parseValue(value string) string { - - // trim - value = strings.Trim(value, " ") - - // check if we've got quoted values or possible escapes - if len(value) > 1 { - first := string(value[0:1]) - last := string(value[len(value)-1:]) - if first == last && strings.ContainsAny(first, `"'`) { - // pull the quotes off the edges - value = value[1 : len(value)-1] - // handle escapes - escapeRegex := regexp.MustCompile(`\\.`) - value = escapeRegex.ReplaceAllStringFunc(value, func(match string) string { - c := strings.TrimPrefix(match, `\`) - switch c { - case "n": - return "\n" - case "r": - return "\r" - default: - return c - } - }) - } - } - - return value -} - -func isIgnoredLine(line string) bool { - trimmedLine := strings.Trim(line, " \n\t") - return len(trimmedLine) == 0 || strings.HasPrefix(trimmedLine, "#") -} - -func doubleQuoteEscape(line string) string { - for _, c := range doubleQuoteSpecialChars { - toReplace := "\\" + string(c) - if c == '\n' { - toReplace = `\n` - } - if c == '\r' { - toReplace = `\r` - } - line = strings.Replace(line, string(c), toReplace, -1) - } - return line -}