├── vendor └── github.com │ ├── hashicorp │ └── go-version │ │ ├── go.mod │ │ ├── .travis.yml │ │ ├── version_collection.go │ │ ├── README.md │ │ ├── constraint.go │ │ ├── version.go │ │ └── LICENSE │ └── mitchellh │ └── ioprogress │ ├── LICENSE │ ├── README.md │ ├── reader.go │ └── draw.go ├── .gitignore ├── options.go ├── version_spec.go ├── Gopkg.lock ├── Gopkg.toml ├── README.md ├── updater.go └── LICENSE /vendor/github.com/hashicorp/go-version/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/hashicorp/go-version 2 | -------------------------------------------------------------------------------- /vendor/github.com/hashicorp/go-version/.travis.yml: -------------------------------------------------------------------------------- 1 | language: go 2 | 3 | go: 4 | - 1.0 5 | - 1.1 6 | - 1.2 7 | - 1.3 8 | - 1.4 9 | - 1.9 10 | - "1.10" 11 | 12 | script: 13 | - go test 14 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Binaries for programs and plugins 2 | *.exe 3 | *.exe~ 4 | *.dll 5 | *.so 6 | *.dylib 7 | 8 | # Test binary, build with `go test -c` 9 | *.test 10 | 11 | # Output of the go coverage tool, specifically when used with LiteIDE 12 | *.out 13 | /.idea 14 | -------------------------------------------------------------------------------- /vendor/github.com/hashicorp/go-version/version_collection.go: -------------------------------------------------------------------------------- 1 | package version 2 | 3 | // Collection is a type that implements the sort.Interface interface 4 | // so that versions can be sorted. 5 | type Collection []*Version 6 | 7 | func (v Collection) Len() int { 8 | return len(v) 9 | } 10 | 11 | func (v Collection) Less(i, j int) bool { 12 | return v[i].LessThan(v[j]) 13 | } 14 | 15 | func (v Collection) Swap(i, j int) { 16 | v[i], v[j] = v[j], v[i] 17 | } 18 | -------------------------------------------------------------------------------- /options.go: -------------------------------------------------------------------------------- 1 | package updater 2 | 3 | // Options defines options used in an Updater instance 4 | type Options struct { 5 | RemoteURL string 6 | VersionSpecsFilename string 7 | BinPattern string 8 | Channel string 9 | Silent bool 10 | } 11 | 12 | // VersionSpecsURL returns the full URL for the VersionSpecs file 13 | func (o *Options) VersionSpecsURL() string { 14 | return o.RemoteURL + o.VersionSpecsFilename 15 | } 16 | 17 | // BinURL returns the full URL pattern for the executable 18 | func (o *Options) BinURL() string { 19 | return o.RemoteURL + o.BinPattern 20 | } 21 | -------------------------------------------------------------------------------- /version_spec.go: -------------------------------------------------------------------------------- 1 | package updater 2 | 3 | import "fmt" 4 | 5 | // VersionSpec is a single version descriptor 6 | type VersionSpec struct { 7 | Version string `json:"version"` 8 | Channel string `json:"channel"` 9 | Force bool `json:"force"` 10 | } 11 | 12 | // VersionSpecs is a collection of VersionSpecs 13 | type VersionSpecs struct { 14 | Versions []*VersionSpec `json:"versions"` 15 | } 16 | 17 | // GetVersionByChannel returns the applicable version by a channel 18 | func (v *VersionSpecs) GetVersionByChannel(channel string) (*VersionSpec, error) { 19 | for idx, item := range v.Versions { 20 | if item.Channel == channel { 21 | return v.Versions[idx], nil 22 | } 23 | } 24 | 25 | return nil, fmt.Errorf("no version found for channel %s", channel) 26 | } 27 | -------------------------------------------------------------------------------- /Gopkg.lock: -------------------------------------------------------------------------------- 1 | # This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'. 2 | 3 | 4 | [[projects]] 5 | digest = "1:950caca7dfcf796419232ba996c9c3539d09f26af27ba848c4508e604c13efbb" 6 | name = "github.com/hashicorp/go-version" 7 | packages = ["."] 8 | pruneopts = "UT" 9 | revision = "d40cf49b3a77bba84a7afdbd7f1dc295d114efb1" 10 | version = "v1.1.0" 11 | 12 | [[projects]] 13 | branch = "master" 14 | digest = "1:3e09b51c8e509155d306b638cbf19289c3f13509fec1132472274b34143a5810" 15 | name = "github.com/mitchellh/ioprogress" 16 | packages = ["."] 17 | pruneopts = "UT" 18 | revision = "6a23b12fa88ea53e63d9b49f148fe6b29c30af6d" 19 | 20 | [solve-meta] 21 | analyzer-name = "dep" 22 | analyzer-version = 1 23 | input-imports = [ 24 | "github.com/hashicorp/go-version", 25 | "github.com/mitchellh/ioprogress", 26 | ] 27 | solver-name = "gps-cdcl" 28 | solver-version = 1 29 | -------------------------------------------------------------------------------- /Gopkg.toml: -------------------------------------------------------------------------------- 1 | # Gopkg.toml example 2 | # 3 | # Refer to https://golang.github.io/dep/docs/Gopkg.toml.html 4 | # for detailed Gopkg.toml documentation. 5 | # 6 | # required = ["github.com/user/thing/cmd/thing"] 7 | # ignored = ["github.com/user/project/pkgX", "bitbucket.org/user/project/pkgA/pkgY"] 8 | # 9 | # [[constraint]] 10 | # name = "github.com/user/project" 11 | # version = "1.0.0" 12 | # 13 | # [[constraint]] 14 | # name = "github.com/user/project2" 15 | # branch = "dev" 16 | # source = "github.com/myfork/project2" 17 | # 18 | # [[override]] 19 | # name = "github.com/x/y" 20 | # version = "2.4.0" 21 | # 22 | # [prune] 23 | # non-go = false 24 | # go-tests = true 25 | # unused-packages = true 26 | 27 | 28 | [[constraint]] 29 | name = "github.com/hashicorp/go-version" 30 | version = "1.1.0" 31 | 32 | [[constraint]] 33 | branch = "master" 34 | name = "github.com/mitchellh/ioprogress" 35 | 36 | [prune] 37 | go-tests = true 38 | unused-packages = true 39 | -------------------------------------------------------------------------------- /vendor/github.com/mitchellh/ioprogress/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Mitchell Hashimoto 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /vendor/github.com/mitchellh/ioprogress/README.md: -------------------------------------------------------------------------------- 1 | # ioprogress 2 | 3 | ioprogress is a Go (golang) library with implementations of `io.Reader` 4 | and `io.Writer` that draws progress bars. The primary use case for these 5 | are for CLI applications but alternate progress bar writers can be supplied 6 | for alternate environments. 7 | 8 | ## Example 9 | 10 | ![Progress](http://g.recordit.co/GO5HxT16QH.gif) 11 | 12 | ## Installation 13 | 14 | Standard `go get`: 15 | 16 | ``` 17 | $ go get github.com/mitchellh/ioprogress 18 | ``` 19 | 20 | ## Usage 21 | 22 | Here is an example of outputting a basic progress bar to the CLI as 23 | we're "downloading" from some other `io.Reader` (perhaps from a network 24 | connection): 25 | 26 | ```go 27 | // Imagine this came from some external source, such as a network connection, 28 | // and that we have the full size of it, such as from a Content-Length HTTP 29 | // header. 30 | var r io.Reader 31 | 32 | // Create the progress reader 33 | progressR := &ioprogress.Reader{ 34 | Reader: r, 35 | Size: rSize, 36 | } 37 | 38 | // Copy all of the reader to some local file f. As it copies, the 39 | // progressR will write progress to the terminal on os.Stdout. This is 40 | // customizable. 41 | io.Copy(f, progressR) 42 | ``` 43 | -------------------------------------------------------------------------------- /vendor/github.com/hashicorp/go-version/README.md: -------------------------------------------------------------------------------- 1 | # Versioning Library for Go 2 | [![Build Status](https://travis-ci.org/hashicorp/go-version.svg?branch=master)](https://travis-ci.org/hashicorp/go-version) 3 | 4 | go-version is a library for parsing versions and version constraints, 5 | and verifying versions against a set of constraints. go-version 6 | can sort a collection of versions properly, handles prerelease/beta 7 | versions, can increment versions, etc. 8 | 9 | Versions used with go-version must follow [SemVer](http://semver.org/). 10 | 11 | ## Installation and Usage 12 | 13 | Package documentation can be found on 14 | [GoDoc](http://godoc.org/github.com/hashicorp/go-version). 15 | 16 | Installation can be done with a normal `go get`: 17 | 18 | ``` 19 | $ go get github.com/hashicorp/go-version 20 | ``` 21 | 22 | #### Version Parsing and Comparison 23 | 24 | ```go 25 | v1, err := version.NewVersion("1.2") 26 | v2, err := version.NewVersion("1.5+metadata") 27 | 28 | // Comparison example. There is also GreaterThan, Equal, and just 29 | // a simple Compare that returns an int allowing easy >=, <=, etc. 30 | if v1.LessThan(v2) { 31 | fmt.Printf("%s is less than %s", v1, v2) 32 | } 33 | ``` 34 | 35 | #### Version Constraints 36 | 37 | ```go 38 | v1, err := version.NewVersion("1.2") 39 | 40 | // Constraints example. 41 | constraints, err := version.NewConstraint(">= 1.0, < 1.4") 42 | if constraints.Check(v1) { 43 | fmt.Printf("%s satisfies constraints %s", v1, constraints) 44 | } 45 | ``` 46 | 47 | #### Version Sorting 48 | 49 | ```go 50 | versionsRaw := []string{"1.1", "0.7.1", "1.4-beta", "1.4", "2"} 51 | versions := make([]*version.Version, len(versionsRaw)) 52 | for i, raw := range versionsRaw { 53 | v, _ := version.NewVersion(raw) 54 | versions[i] = v 55 | } 56 | 57 | // After this, the versions are properly sorted 58 | sort.Sort(version.Collection(versions)) 59 | ``` 60 | 61 | ## Issues and Contributing 62 | 63 | If you find an issue with this library, please report an issue. If you'd 64 | like, we welcome any contributions. Fork this library and submit a pull 65 | request. 66 | -------------------------------------------------------------------------------- /vendor/github.com/mitchellh/ioprogress/reader.go: -------------------------------------------------------------------------------- 1 | package ioprogress 2 | 3 | import ( 4 | "io" 5 | "time" 6 | ) 7 | 8 | // Reader is an implementation of io.Reader that draws the progress of 9 | // reading some data. 10 | type Reader struct { 11 | // Reader is the underlying reader to read from 12 | Reader io.Reader 13 | 14 | // Size is the total size of the data coming out of the reader. 15 | Size int64 16 | 17 | // DrawFunc is the callback to invoke to draw the progress bar. By 18 | // default, this will be DrawTerminal(os.Stdout). 19 | // 20 | // DrawInterval is the minimum time to wait between reads to update the 21 | // progress bar. 22 | DrawFunc DrawFunc 23 | DrawInterval time.Duration 24 | 25 | progress int64 26 | lastDraw time.Time 27 | } 28 | 29 | // Read reads from the underlying reader and invokes the DrawFunc if 30 | // appropriate. The DrawFunc is executed when there is data that is 31 | // read (progress is made) and at least DrawInterval time has passed. 32 | func (r *Reader) Read(p []byte) (int, error) { 33 | // If we haven't drawn before, initialize the progress bar 34 | if r.lastDraw.IsZero() { 35 | r.initProgress() 36 | } 37 | 38 | // Read from the underlying source 39 | n, err := r.Reader.Read(p) 40 | 41 | // Always increment the progress even if there was an error 42 | r.progress += int64(n) 43 | 44 | // If we don't have any errors, then draw the progress. If we are 45 | // at the end of the data, then finish the progress. 46 | if err == nil { 47 | // Only draw if we read data or we've never read data before (to 48 | // initialize the progress bar). 49 | if n > 0 { 50 | r.drawProgress() 51 | } 52 | } 53 | if err == io.EOF { 54 | r.finishProgress() 55 | } 56 | 57 | return n, err 58 | } 59 | 60 | func (r *Reader) drawProgress() { 61 | // If we've drawn before, then make sure that the draw interval 62 | // has passed before we draw again. 63 | interval := r.DrawInterval 64 | if interval == 0 { 65 | interval = time.Second 66 | } 67 | if !r.lastDraw.IsZero() { 68 | nextDraw := r.lastDraw.Add(interval) 69 | if time.Now().Before(nextDraw) { 70 | return 71 | } 72 | } 73 | 74 | // Draw 75 | f := r.drawFunc() 76 | f(r.progress, r.Size) 77 | 78 | // Record this draw so that we don't draw again really quickly 79 | r.lastDraw = time.Now() 80 | } 81 | 82 | func (r *Reader) finishProgress() { 83 | f := r.drawFunc() 84 | f(r.progress, r.Size) 85 | 86 | // Print a newline 87 | f(-1, -1) 88 | 89 | // Reset lastDraw so we don't finish again 90 | var zeroDraw time.Time 91 | r.lastDraw = zeroDraw 92 | } 93 | 94 | func (r *Reader) initProgress() { 95 | var zeroDraw time.Time 96 | r.lastDraw = zeroDraw 97 | r.drawProgress() 98 | r.lastDraw = zeroDraw 99 | } 100 | 101 | func (r *Reader) drawFunc() DrawFunc { 102 | if r.DrawFunc == nil { 103 | return defaultDrawFunc 104 | } 105 | 106 | return r.DrawFunc 107 | } 108 | -------------------------------------------------------------------------------- /vendor/github.com/mitchellh/ioprogress/draw.go: -------------------------------------------------------------------------------- 1 | package ioprogress 2 | 3 | import ( 4 | "fmt" 5 | "io" 6 | "os" 7 | "strings" 8 | ) 9 | 10 | // DrawFunc is the callback type for drawing progress. 11 | type DrawFunc func(int64, int64) error 12 | 13 | // DrawTextFormatFunc is a callback used by DrawFuncs that draw text in 14 | // order to format the text into some more human friendly format. 15 | type DrawTextFormatFunc func(int64, int64) string 16 | 17 | var defaultDrawFunc DrawFunc 18 | 19 | func init() { 20 | defaultDrawFunc = DrawTerminal(os.Stdout) 21 | } 22 | 23 | // DrawTerminal returns a DrawFunc that draws a progress bar to an io.Writer 24 | // that is assumed to be a terminal (and therefore respects carriage returns). 25 | func DrawTerminal(w io.Writer) DrawFunc { 26 | return DrawTerminalf(w, func(progress, total int64) string { 27 | return fmt.Sprintf("%d/%d", progress, total) 28 | }) 29 | } 30 | 31 | // DrawTerminalf returns a DrawFunc that draws a progress bar to an io.Writer 32 | // that is formatted with the given formatting function. 33 | func DrawTerminalf(w io.Writer, f DrawTextFormatFunc) DrawFunc { 34 | var maxLength int 35 | 36 | return func(progress, total int64) error { 37 | if progress == -1 && total == -1 { 38 | _, err := fmt.Fprintf(w, "\n") 39 | return err 40 | } 41 | 42 | // Make sure we pad it to the max length we've ever drawn so that 43 | // we don't have trailing characters. 44 | line := f(progress, total) 45 | if len(line) < maxLength { 46 | line = fmt.Sprintf( 47 | "%s%s", 48 | line, 49 | strings.Repeat(" ", maxLength-len(line))) 50 | } 51 | maxLength = len(line) 52 | 53 | _, err := fmt.Fprint(w, line+"\r") 54 | return err 55 | } 56 | } 57 | 58 | var byteUnits = []string{"B", "KB", "MB", "GB", "TB", "PB"} 59 | 60 | // DrawTextFormatBytes is a DrawTextFormatFunc that formats the progress 61 | // and total into human-friendly byte formats. 62 | func DrawTextFormatBytes(progress, total int64) string { 63 | return fmt.Sprintf("%s/%s", byteUnitStr(progress), byteUnitStr(total)) 64 | } 65 | 66 | // DrawTextFormatBar returns a DrawTextFormatFunc that draws a progress 67 | // bar with the given width (in characters). This can be used in conjunction 68 | // with another DrawTextFormatFunc to create a progress bar with bytes, for 69 | // example: 70 | // 71 | // bar := DrawTextFormatBar(20) 72 | // func(progress, total int64) string { 73 | // return fmt.Sprintf( 74 | // "%s %s", 75 | // bar(progress, total), 76 | // DrawTextFormatBytes(progress, total)) 77 | // } 78 | // 79 | func DrawTextFormatBar(width int64) DrawTextFormatFunc { 80 | width -= 2 81 | 82 | return func(progress, total int64) string { 83 | current := int64((float64(progress) / float64(total)) * float64(width)) 84 | return fmt.Sprintf( 85 | "[%s%s]", 86 | strings.Repeat("=", int(current)), 87 | strings.Repeat(" ", int(width-current))) 88 | } 89 | } 90 | 91 | func byteUnitStr(n int64) string { 92 | var unit string 93 | size := float64(n) 94 | for i := 1; i < len(byteUnits); i++ { 95 | if size < 1000 { 96 | unit = byteUnits[i-1] 97 | break 98 | } 99 | 100 | size = size / 1000 101 | } 102 | 103 | return fmt.Sprintf("%.3g %s", size, unit) 104 | } 105 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Updater 4 | A simple to use Go package for self updating binaries. It supports HTTP download, Semantic versioning, channels and remote forced updates. 5 | 6 | ## Install 7 | 8 | ```bash 9 | $ go get github.com/cloud66-oss/updater 10 | ``` 11 | 12 | ## Usage 13 | 14 | To use updater, you need to push your binaries somewhere they can be downloaded using HTTP (like an S3 bucket). You also need to construct a single JSON file to include details of your versions. By default this file is called `versions.json` and can look like this: 15 | 16 | ```json 17 | { 18 | "versions": [ 19 | { 20 | "version": "1.0.0-pre", 21 | "channel": "dev" 22 | }, 23 | { 24 | "version": "1.0.0", 25 | "channel": "stable" 26 | }, 27 | { 28 | "version": "1.0.0-pre-1-57dh54", 29 | "channel": "nightly", 30 | "force": true 31 | } 32 | ] 33 | } 34 | ``` 35 | 36 | Updater supports multiple OS and architectures. 37 | 38 | **NOTE**: 39 | 40 | Updater strictly requires SemVer compatible versions. 41 | 42 | This is an example code: 43 | 44 | 45 | ```go 46 | func update() { 47 | worker, err := updater.NewUpdater(utils.Version, &updater.Options{ 48 | RemoteURL: "https://s3.amazonaws.com/acme/myapp/", 49 | Channel: "dev", 50 | Silent: false, 51 | }) 52 | if err != nil { 53 | fmt.Println(err) 54 | } 55 | 56 | err = worker.Run(false) 57 | if err != nil { 58 | fmt.Println(err) 59 | } 60 | } 61 | ``` 62 | 63 | The code above updates the current executable if the local version is older than the remote version for the `dev` channel. 64 | 65 | ### Options 66 | 67 | `updater.Options` has the following fields: 68 | 69 | ```go 70 | RemoteURL string 71 | VersionSpecsFilename string 72 | BinPattern string 73 | Channel string 74 | Silent bool 75 | ``` 76 | 77 | **RemoteURL** 78 | 79 | The full URL of where the binaries and `versions.json` file can be found. An example could be `https://downloads.acme.org/`. Including the trailing `/` is not mandatory. 80 | 81 | **VersionSpecsFilename** 82 | 83 | This is the name of the JSON file. If not set, `versions.json` will be used which will mean the full URL for the JSON file will be `https://downloads.acme.org/versions.json` 84 | 85 | **BinPattern** 86 | 87 | This is the pattern used to find the relevant binary file to download. If not specified the default is `{{OS}}_{{ARCH}}_{{VERSION}}`. This means the updater will look for version `1.10.20` of the binary compiled for the OSX 64bit architecture at `https://downloads.acme.org/darwin_amd64_1.10.20` 88 | 89 | **Channel** 90 | 91 | This is the name of the channel to look for. Default is `dev`. Using channels you can choose to have different version tracks for your binaries. 92 | 93 | **Silent** 94 | 95 | If set to `false` the updater will print out progress of the update to the console (stdout). 96 | 97 | ### Updater 98 | 99 | The Updater itself, can be created using `NewUpdater` and run using the `Run` function. You can force updates by passing the `force` parameter into `Run`. If forced, the binary will be updated even if it's newer than the remote version. 100 | 101 | You can also remote force an update. This is useful when you need to rollback to an older version across all clients. To force an update remotely, set the `force` attribute to `true` in `versions.json` as per example above. 102 | 103 | ## Compiling 104 | 105 | Compiling your binaries and construction of the JSON file is up to you. You can use the following as helpers. 106 | 107 | ### Build 108 | 109 | This is an example build bash script: 110 | 111 | ```bash 112 | #!/bin/bash 113 | 114 | version=$(git describe --tags --always) 115 | 116 | if [ -z "$1" ] 117 | then 118 | echo "No channel supplied" 119 | exit 1 120 | fi 121 | 122 | channel=$1 123 | 124 | echo "Building $channel/$version" 125 | echo 126 | 127 | rm build/* 128 | curl -s http://s3.amazonaws.com/acme/versions.json | jq '.versions |= map(if (.channel == "'$channel'") then .version = "'$version'" else . end)' > build/versions.json 129 | echo "Current Versions" 130 | cat build/versions.json | jq -r '.versions | map([.channel, .version] | join(": ")) | .[]' 131 | echo 132 | 133 | gox -ldflags "-X github.com/acme/myapp/utils.Version=$version -X github.com/acme/myapp/utils.Channel=$channel" -os="darwin linux windows" -arch="amd64" -output "build/{{.OS}}_{{.Arch}}_$version" 134 | ``` 135 | 136 | The above example assumes 2 variables in `utils` package to hold the current version and the current channel for your application and sets them to the current git tag and the user input into the bash script. This means for the updater to work, you'd need to tag your code with a valid SemVer tag. 137 | 138 | It also requires [gox](https://github.com/mitchellh/gox) tool to allow cross compiling of the code. 139 | 140 | ### Publish 141 | 142 | To publish your binaries to S3 you can use something like this bash script: 143 | 144 | 145 | ```bash 146 | #!/bin/bash 147 | 148 | aws s3 cp build s3://acme/myapp --acl public-read --recursive 149 | ``` 150 | 151 | This script requires a configured AWS cli installed. 152 | -------------------------------------------------------------------------------- /updater.go: -------------------------------------------------------------------------------- 1 | package updater 2 | 3 | import ( 4 | "encoding/json" 5 | "errors" 6 | "fmt" 7 | "io/ioutil" 8 | "net/http" 9 | "os" 10 | "runtime" 11 | "strings" 12 | "time" 13 | 14 | "github.com/hashicorp/go-version" 15 | "github.com/mitchellh/ioprogress" 16 | ) 17 | 18 | // Updater is responsible for checking for updates and updating the running executable 19 | type Updater struct { 20 | CurrentVersion string 21 | 22 | currentVersion *version.Version 23 | options *Options 24 | } 25 | 26 | // NewUpdater returns a new updater instance 27 | func NewUpdater(currentVersion string, options *Options) (*Updater, error) { 28 | if options.RemoteURL == "" { 29 | panic("no RemoteURL") 30 | } 31 | if !strings.HasSuffix(options.RemoteURL, "/") { 32 | options.RemoteURL = options.RemoteURL + "/" 33 | } 34 | if options.VersionSpecsFilename == "" { 35 | options.VersionSpecsFilename = "versions.json" 36 | } 37 | if options.Channel == "" { 38 | options.Channel = "dev" 39 | } 40 | if options.BinPattern == "" { 41 | options.BinPattern = "{{OS}}_{{ARCH}}_{{VERSION}}" 42 | } 43 | 44 | v, err := version.NewVersion(currentVersion) 45 | if err != nil { 46 | return nil, err 47 | } 48 | 49 | return &Updater{ 50 | currentVersion: v, 51 | options: options, 52 | }, nil 53 | } 54 | 55 | // Run runs the updater 56 | func (u *Updater) Run(force bool) error { 57 | remoteVersion, err := u.getRemoteVersion() 58 | if err != nil { 59 | return err 60 | } 61 | 62 | rVersion, err := version.NewVersion(remoteVersion.Version) 63 | if err != nil { 64 | return fmt.Errorf("remote version is '%s'. %s", remoteVersion.Version, err) 65 | } 66 | 67 | if !u.options.Silent { 68 | fmt.Printf("Local Version %v - Remote Version: %v\n", u.currentVersion, rVersion) 69 | } 70 | 71 | if force || remoteVersion.Force || u.currentVersion.LessThan(rVersion) { 72 | err = u.downloadAndReplace(rVersion) 73 | if err != nil { 74 | return err 75 | } 76 | } 77 | 78 | return nil 79 | } 80 | 81 | func (u *Updater) downloadAndReplace(remoteVersion *version.Version) error { 82 | // fetch the new file 83 | binURL := generateURL(u.options.BinURL(), remoteVersion.String()) 84 | err := fileExists(binURL) 85 | if err != nil { 86 | return err 87 | } 88 | 89 | bodyResp, err := http.Get(binURL) 90 | if err != nil { 91 | return err 92 | } 93 | defer bodyResp.Body.Close() 94 | 95 | progressR := &ioprogress.Reader{ 96 | Reader: bodyResp.Body, 97 | Size: bodyResp.ContentLength, 98 | DrawInterval: 500 * time.Millisecond, 99 | DrawFunc: ioprogress.DrawTerminalf(os.Stdout, func(progress, total int64) string { 100 | bar := ioprogress.DrawTextFormatBar(40) 101 | return fmt.Sprintf("%s %20s", bar(progress, total), ioprogress.DrawTextFormatBytes(progress, total)) 102 | }), 103 | } 104 | 105 | var data []byte 106 | if !u.options.Silent { 107 | data, err = ioutil.ReadAll(progressR) 108 | if err != nil { 109 | return err 110 | } 111 | } else { 112 | data, err = ioutil.ReadAll(bodyResp.Body) 113 | if err != nil { 114 | return err 115 | } 116 | } 117 | 118 | dest, err := os.Executable() 119 | if err != nil { 120 | return err 121 | } 122 | 123 | // Move the old version to a backup path that we can recover from 124 | // in case the upgrade fails 125 | destBackup := dest + ".bak" 126 | if _, err := os.Stat(dest); err == nil { 127 | rErr := os.Rename(dest, destBackup) 128 | if rErr != nil { 129 | fmt.Println(rErr) 130 | } 131 | } 132 | 133 | if !u.options.Silent { 134 | fmt.Printf("Downloading the new version to %s\n", dest) 135 | } 136 | 137 | if err := ioutil.WriteFile(dest, data, 0755); err != nil { 138 | rErr := os.Rename(destBackup, dest) 139 | if rErr != nil { 140 | fmt.Println(rErr) 141 | } 142 | 143 | return err 144 | } 145 | 146 | // Removing backup 147 | rErr := os.Remove(destBackup) 148 | if rErr != nil { 149 | fmt.Println(rErr) 150 | } 151 | 152 | return nil 153 | } 154 | 155 | func (u *Updater) getRemoteVersion() (*VersionSpec, error) { 156 | err := fileExists(u.options.VersionSpecsURL()) 157 | if err != nil { 158 | return nil, err 159 | } 160 | 161 | response, err := http.Get(u.options.VersionSpecsURL()) 162 | if err != nil { 163 | return nil, err 164 | } 165 | defer response.Body.Close() 166 | 167 | if response.StatusCode != http.StatusOK { 168 | return nil, errors.New("invalid version specification file") 169 | } 170 | 171 | b, err := ioutil.ReadAll(response.Body) 172 | if err != nil { 173 | return nil, err 174 | } 175 | 176 | // get the version descriptor 177 | var versions VersionSpecs 178 | err = json.Unmarshal(b, &versions) 179 | if err != nil { 180 | return nil, err 181 | } 182 | 183 | return versions.GetVersionByChannel(u.options.Channel) 184 | } 185 | 186 | func generateURL(path string, version string) string { 187 | path = strings.Replace(path, "{{OS}}", runtime.GOOS, -1) 188 | path = strings.Replace(path, "{{ARCH}}", runtime.GOARCH, -1) 189 | path = strings.Replace(path, "{{VERSION}}", version, -1) 190 | 191 | return path 192 | } 193 | 194 | func fileExists(path string) error { 195 | resp, err := http.Head(path) 196 | if err != nil { 197 | return err 198 | } 199 | 200 | if resp.StatusCode != http.StatusOK { 201 | return fmt.Errorf("remote file not found at %s", path) 202 | } 203 | 204 | return nil 205 | 206 | } 207 | -------------------------------------------------------------------------------- /vendor/github.com/hashicorp/go-version/constraint.go: -------------------------------------------------------------------------------- 1 | package version 2 | 3 | import ( 4 | "fmt" 5 | "reflect" 6 | "regexp" 7 | "strings" 8 | ) 9 | 10 | // Constraint represents a single constraint for a version, such as 11 | // ">= 1.0". 12 | type Constraint struct { 13 | f constraintFunc 14 | check *Version 15 | original string 16 | } 17 | 18 | // Constraints is a slice of constraints. We make a custom type so that 19 | // we can add methods to it. 20 | type Constraints []*Constraint 21 | 22 | type constraintFunc func(v, c *Version) bool 23 | 24 | var constraintOperators map[string]constraintFunc 25 | 26 | var constraintRegexp *regexp.Regexp 27 | 28 | func init() { 29 | constraintOperators = map[string]constraintFunc{ 30 | "": constraintEqual, 31 | "=": constraintEqual, 32 | "!=": constraintNotEqual, 33 | ">": constraintGreaterThan, 34 | "<": constraintLessThan, 35 | ">=": constraintGreaterThanEqual, 36 | "<=": constraintLessThanEqual, 37 | "~>": constraintPessimistic, 38 | } 39 | 40 | ops := make([]string, 0, len(constraintOperators)) 41 | for k := range constraintOperators { 42 | ops = append(ops, regexp.QuoteMeta(k)) 43 | } 44 | 45 | constraintRegexp = regexp.MustCompile(fmt.Sprintf( 46 | `^\s*(%s)\s*(%s)\s*$`, 47 | strings.Join(ops, "|"), 48 | VersionRegexpRaw)) 49 | } 50 | 51 | // NewConstraint will parse one or more constraints from the given 52 | // constraint string. The string must be a comma-separated list of 53 | // constraints. 54 | func NewConstraint(v string) (Constraints, error) { 55 | vs := strings.Split(v, ",") 56 | result := make([]*Constraint, len(vs)) 57 | for i, single := range vs { 58 | c, err := parseSingle(single) 59 | if err != nil { 60 | return nil, err 61 | } 62 | 63 | result[i] = c 64 | } 65 | 66 | return Constraints(result), nil 67 | } 68 | 69 | // Check tests if a version satisfies all the constraints. 70 | func (cs Constraints) Check(v *Version) bool { 71 | for _, c := range cs { 72 | if !c.Check(v) { 73 | return false 74 | } 75 | } 76 | 77 | return true 78 | } 79 | 80 | // Returns the string format of the constraints 81 | func (cs Constraints) String() string { 82 | csStr := make([]string, len(cs)) 83 | for i, c := range cs { 84 | csStr[i] = c.String() 85 | } 86 | 87 | return strings.Join(csStr, ",") 88 | } 89 | 90 | // Check tests if a constraint is validated by the given version. 91 | func (c *Constraint) Check(v *Version) bool { 92 | return c.f(v, c.check) 93 | } 94 | 95 | func (c *Constraint) String() string { 96 | return c.original 97 | } 98 | 99 | func parseSingle(v string) (*Constraint, error) { 100 | matches := constraintRegexp.FindStringSubmatch(v) 101 | if matches == nil { 102 | return nil, fmt.Errorf("Malformed constraint: %s", v) 103 | } 104 | 105 | check, err := NewVersion(matches[2]) 106 | if err != nil { 107 | return nil, err 108 | } 109 | 110 | return &Constraint{ 111 | f: constraintOperators[matches[1]], 112 | check: check, 113 | original: v, 114 | }, nil 115 | } 116 | 117 | func prereleaseCheck(v, c *Version) bool { 118 | switch vPre, cPre := v.Prerelease() != "", c.Prerelease() != ""; { 119 | case cPre && vPre: 120 | // A constraint with a pre-release can only match a pre-release version 121 | // with the same base segments. 122 | return reflect.DeepEqual(c.Segments64(), v.Segments64()) 123 | 124 | case !cPre && vPre: 125 | // A constraint without a pre-release can only match a version without a 126 | // pre-release. 127 | return false 128 | 129 | case cPre && !vPre: 130 | // OK, except with the pessimistic operator 131 | case !cPre && !vPre: 132 | // OK 133 | } 134 | return true 135 | } 136 | 137 | //------------------------------------------------------------------- 138 | // Constraint functions 139 | //------------------------------------------------------------------- 140 | 141 | func constraintEqual(v, c *Version) bool { 142 | return v.Equal(c) 143 | } 144 | 145 | func constraintNotEqual(v, c *Version) bool { 146 | return !v.Equal(c) 147 | } 148 | 149 | func constraintGreaterThan(v, c *Version) bool { 150 | return prereleaseCheck(v, c) && v.Compare(c) == 1 151 | } 152 | 153 | func constraintLessThan(v, c *Version) bool { 154 | return prereleaseCheck(v, c) && v.Compare(c) == -1 155 | } 156 | 157 | func constraintGreaterThanEqual(v, c *Version) bool { 158 | return prereleaseCheck(v, c) && v.Compare(c) >= 0 159 | } 160 | 161 | func constraintLessThanEqual(v, c *Version) bool { 162 | return prereleaseCheck(v, c) && v.Compare(c) <= 0 163 | } 164 | 165 | func constraintPessimistic(v, c *Version) bool { 166 | // Using a pessimistic constraint with a pre-release, restricts versions to pre-releases 167 | if !prereleaseCheck(v, c) || (c.Prerelease() != "" && v.Prerelease() == "") { 168 | return false 169 | } 170 | 171 | // If the version being checked is naturally less than the constraint, then there 172 | // is no way for the version to be valid against the constraint 173 | if v.LessThan(c) { 174 | return false 175 | } 176 | // We'll use this more than once, so grab the length now so it's a little cleaner 177 | // to write the later checks 178 | cs := len(c.segments) 179 | 180 | // If the version being checked has less specificity than the constraint, then there 181 | // is no way for the version to be valid against the constraint 182 | if cs > len(v.segments) { 183 | return false 184 | } 185 | 186 | // Check the segments in the constraint against those in the version. If the version 187 | // being checked, at any point, does not have the same values in each index of the 188 | // constraints segments, then it cannot be valid against the constraint. 189 | for i := 0; i < c.si-1; i++ { 190 | if v.segments[i] != c.segments[i] { 191 | return false 192 | } 193 | } 194 | 195 | // Check the last part of the segment in the constraint. If the version segment at 196 | // this index is less than the constraints segment at this index, then it cannot 197 | // be valid against the constraint 198 | if c.segments[cs-1] > v.segments[cs-1] { 199 | return false 200 | } 201 | 202 | // If nothing has rejected the version by now, it's valid 203 | return true 204 | } 205 | -------------------------------------------------------------------------------- /vendor/github.com/hashicorp/go-version/version.go: -------------------------------------------------------------------------------- 1 | package version 2 | 3 | import ( 4 | "bytes" 5 | "fmt" 6 | "reflect" 7 | "regexp" 8 | "strconv" 9 | "strings" 10 | ) 11 | 12 | // The compiled regular expression used to test the validity of a version. 13 | var ( 14 | versionRegexp *regexp.Regexp 15 | semverRegexp *regexp.Regexp 16 | ) 17 | 18 | // The raw regular expression string used for testing the validity 19 | // of a version. 20 | const ( 21 | VersionRegexpRaw string = `v?([0-9]+(\.[0-9]+)*?)` + 22 | `(-([0-9]+[0-9A-Za-z\-~]*(\.[0-9A-Za-z\-~]+)*)|(-?([A-Za-z\-~]+[0-9A-Za-z\-~]*(\.[0-9A-Za-z\-~]+)*)))?` + 23 | `(\+([0-9A-Za-z\-~]+(\.[0-9A-Za-z\-~]+)*))?` + 24 | `?` 25 | 26 | // SemverRegexpRaw requires a separator between version and prerelease 27 | SemverRegexpRaw string = `v?([0-9]+(\.[0-9]+)*?)` + 28 | `(-([0-9]+[0-9A-Za-z\-~]*(\.[0-9A-Za-z\-~]+)*)|(-([A-Za-z\-~]+[0-9A-Za-z\-~]*(\.[0-9A-Za-z\-~]+)*)))?` + 29 | `(\+([0-9A-Za-z\-~]+(\.[0-9A-Za-z\-~]+)*))?` + 30 | `?` 31 | ) 32 | 33 | // Version represents a single version. 34 | type Version struct { 35 | metadata string 36 | pre string 37 | segments []int64 38 | si int 39 | original string 40 | } 41 | 42 | func init() { 43 | versionRegexp = regexp.MustCompile("^" + VersionRegexpRaw + "$") 44 | semverRegexp = regexp.MustCompile("^" + SemverRegexpRaw + "$") 45 | } 46 | 47 | // NewVersion parses the given version and returns a new 48 | // Version. 49 | func NewVersion(v string) (*Version, error) { 50 | return newVersion(v, versionRegexp) 51 | } 52 | 53 | // NewSemver parses the given version and returns a new 54 | // Version that adheres strictly to SemVer specs 55 | // https://semver.org/ 56 | func NewSemver(v string) (*Version, error) { 57 | return newVersion(v, semverRegexp) 58 | } 59 | 60 | func newVersion(v string, pattern *regexp.Regexp) (*Version, error) { 61 | matches := pattern.FindStringSubmatch(v) 62 | if matches == nil { 63 | return nil, fmt.Errorf("Malformed version: %s", v) 64 | } 65 | segmentsStr := strings.Split(matches[1], ".") 66 | segments := make([]int64, len(segmentsStr)) 67 | si := 0 68 | for i, str := range segmentsStr { 69 | val, err := strconv.ParseInt(str, 10, 64) 70 | if err != nil { 71 | return nil, fmt.Errorf( 72 | "Error parsing version: %s", err) 73 | } 74 | 75 | segments[i] = int64(val) 76 | si++ 77 | } 78 | 79 | // Even though we could support more than three segments, if we 80 | // got less than three, pad it with 0s. This is to cover the basic 81 | // default usecase of semver, which is MAJOR.MINOR.PATCH at the minimum 82 | for i := len(segments); i < 3; i++ { 83 | segments = append(segments, 0) 84 | } 85 | 86 | pre := matches[7] 87 | if pre == "" { 88 | pre = matches[4] 89 | } 90 | 91 | return &Version{ 92 | metadata: matches[10], 93 | pre: pre, 94 | segments: segments, 95 | si: si, 96 | original: v, 97 | }, nil 98 | } 99 | 100 | // Must is a helper that wraps a call to a function returning (*Version, error) 101 | // and panics if error is non-nil. 102 | func Must(v *Version, err error) *Version { 103 | if err != nil { 104 | panic(err) 105 | } 106 | 107 | return v 108 | } 109 | 110 | // Compare compares this version to another version. This 111 | // returns -1, 0, or 1 if this version is smaller, equal, 112 | // or larger than the other version, respectively. 113 | // 114 | // If you want boolean results, use the LessThan, Equal, 115 | // or GreaterThan methods. 116 | func (v *Version) Compare(other *Version) int { 117 | // A quick, efficient equality check 118 | if v.String() == other.String() { 119 | return 0 120 | } 121 | 122 | segmentsSelf := v.Segments64() 123 | segmentsOther := other.Segments64() 124 | 125 | // If the segments are the same, we must compare on prerelease info 126 | if reflect.DeepEqual(segmentsSelf, segmentsOther) { 127 | preSelf := v.Prerelease() 128 | preOther := other.Prerelease() 129 | if preSelf == "" && preOther == "" { 130 | return 0 131 | } 132 | if preSelf == "" { 133 | return 1 134 | } 135 | if preOther == "" { 136 | return -1 137 | } 138 | 139 | return comparePrereleases(preSelf, preOther) 140 | } 141 | 142 | // Get the highest specificity (hS), or if they're equal, just use segmentSelf length 143 | lenSelf := len(segmentsSelf) 144 | lenOther := len(segmentsOther) 145 | hS := lenSelf 146 | if lenSelf < lenOther { 147 | hS = lenOther 148 | } 149 | // Compare the segments 150 | // Because a constraint could have more/less specificity than the version it's 151 | // checking, we need to account for a lopsided or jagged comparison 152 | for i := 0; i < hS; i++ { 153 | if i > lenSelf-1 { 154 | // This means Self had the lower specificity 155 | // Check to see if the remaining segments in Other are all zeros 156 | if !allZero(segmentsOther[i:]) { 157 | // if not, it means that Other has to be greater than Self 158 | return -1 159 | } 160 | break 161 | } else if i > lenOther-1 { 162 | // this means Other had the lower specificity 163 | // Check to see if the remaining segments in Self are all zeros - 164 | if !allZero(segmentsSelf[i:]) { 165 | //if not, it means that Self has to be greater than Other 166 | return 1 167 | } 168 | break 169 | } 170 | lhs := segmentsSelf[i] 171 | rhs := segmentsOther[i] 172 | if lhs == rhs { 173 | continue 174 | } else if lhs < rhs { 175 | return -1 176 | } 177 | // Otherwis, rhs was > lhs, they're not equal 178 | return 1 179 | } 180 | 181 | // if we got this far, they're equal 182 | return 0 183 | } 184 | 185 | func allZero(segs []int64) bool { 186 | for _, s := range segs { 187 | if s != 0 { 188 | return false 189 | } 190 | } 191 | return true 192 | } 193 | 194 | func comparePart(preSelf string, preOther string) int { 195 | if preSelf == preOther { 196 | return 0 197 | } 198 | 199 | var selfInt int64 200 | selfNumeric := true 201 | selfInt, err := strconv.ParseInt(preSelf, 10, 64) 202 | if err != nil { 203 | selfNumeric = false 204 | } 205 | 206 | var otherInt int64 207 | otherNumeric := true 208 | otherInt, err = strconv.ParseInt(preOther, 10, 64) 209 | if err != nil { 210 | otherNumeric = false 211 | } 212 | 213 | // if a part is empty, we use the other to decide 214 | if preSelf == "" { 215 | if otherNumeric { 216 | return -1 217 | } 218 | return 1 219 | } 220 | 221 | if preOther == "" { 222 | if selfNumeric { 223 | return 1 224 | } 225 | return -1 226 | } 227 | 228 | if selfNumeric && !otherNumeric { 229 | return -1 230 | } else if !selfNumeric && otherNumeric { 231 | return 1 232 | } else if !selfNumeric && !otherNumeric && preSelf > preOther { 233 | return 1 234 | } else if selfInt > otherInt { 235 | return 1 236 | } 237 | 238 | return -1 239 | } 240 | 241 | func comparePrereleases(v string, other string) int { 242 | // the same pre release! 243 | if v == other { 244 | return 0 245 | } 246 | 247 | // split both pre releases for analyse their parts 248 | selfPreReleaseMeta := strings.Split(v, ".") 249 | otherPreReleaseMeta := strings.Split(other, ".") 250 | 251 | selfPreReleaseLen := len(selfPreReleaseMeta) 252 | otherPreReleaseLen := len(otherPreReleaseMeta) 253 | 254 | biggestLen := otherPreReleaseLen 255 | if selfPreReleaseLen > otherPreReleaseLen { 256 | biggestLen = selfPreReleaseLen 257 | } 258 | 259 | // loop for parts to find the first difference 260 | for i := 0; i < biggestLen; i = i + 1 { 261 | partSelfPre := "" 262 | if i < selfPreReleaseLen { 263 | partSelfPre = selfPreReleaseMeta[i] 264 | } 265 | 266 | partOtherPre := "" 267 | if i < otherPreReleaseLen { 268 | partOtherPre = otherPreReleaseMeta[i] 269 | } 270 | 271 | compare := comparePart(partSelfPre, partOtherPre) 272 | // if parts are equals, continue the loop 273 | if compare != 0 { 274 | return compare 275 | } 276 | } 277 | 278 | return 0 279 | } 280 | 281 | // Equal tests if two versions are equal. 282 | func (v *Version) Equal(o *Version) bool { 283 | return v.Compare(o) == 0 284 | } 285 | 286 | // GreaterThan tests if this version is greater than another version. 287 | func (v *Version) GreaterThan(o *Version) bool { 288 | return v.Compare(o) > 0 289 | } 290 | 291 | // LessThan tests if this version is less than another version. 292 | func (v *Version) LessThan(o *Version) bool { 293 | return v.Compare(o) < 0 294 | } 295 | 296 | // Metadata returns any metadata that was part of the version 297 | // string. 298 | // 299 | // Metadata is anything that comes after the "+" in the version. 300 | // For example, with "1.2.3+beta", the metadata is "beta". 301 | func (v *Version) Metadata() string { 302 | return v.metadata 303 | } 304 | 305 | // Prerelease returns any prerelease data that is part of the version, 306 | // or blank if there is no prerelease data. 307 | // 308 | // Prerelease information is anything that comes after the "-" in the 309 | // version (but before any metadata). For example, with "1.2.3-beta", 310 | // the prerelease information is "beta". 311 | func (v *Version) Prerelease() string { 312 | return v.pre 313 | } 314 | 315 | // Segments returns the numeric segments of the version as a slice of ints. 316 | // 317 | // This excludes any metadata or pre-release information. For example, 318 | // for a version "1.2.3-beta", segments will return a slice of 319 | // 1, 2, 3. 320 | func (v *Version) Segments() []int { 321 | segmentSlice := make([]int, len(v.segments)) 322 | for i, v := range v.segments { 323 | segmentSlice[i] = int(v) 324 | } 325 | return segmentSlice 326 | } 327 | 328 | // Segments64 returns the numeric segments of the version as a slice of int64s. 329 | // 330 | // This excludes any metadata or pre-release information. For example, 331 | // for a version "1.2.3-beta", segments will return a slice of 332 | // 1, 2, 3. 333 | func (v *Version) Segments64() []int64 { 334 | result := make([]int64, len(v.segments)) 335 | copy(result, v.segments) 336 | return result 337 | } 338 | 339 | // String returns the full version string included pre-release 340 | // and metadata information. 341 | // 342 | // This value is rebuilt according to the parsed segments and other 343 | // information. Therefore, ambiguities in the version string such as 344 | // prefixed zeroes (1.04.0 => 1.4.0), `v` prefix (v1.0.0 => 1.0.0), and 345 | // missing parts (1.0 => 1.0.0) will be made into a canonicalized form 346 | // as shown in the parenthesized examples. 347 | func (v *Version) String() string { 348 | var buf bytes.Buffer 349 | fmtParts := make([]string, len(v.segments)) 350 | for i, s := range v.segments { 351 | // We can ignore err here since we've pre-parsed the values in segments 352 | str := strconv.FormatInt(s, 10) 353 | fmtParts[i] = str 354 | } 355 | fmt.Fprintf(&buf, strings.Join(fmtParts, ".")) 356 | if v.pre != "" { 357 | fmt.Fprintf(&buf, "-%s", v.pre) 358 | } 359 | if v.metadata != "" { 360 | fmt.Fprintf(&buf, "+%s", v.metadata) 361 | } 362 | 363 | return buf.String() 364 | } 365 | 366 | // Original returns the original parsed version as-is, including any 367 | // potential whitespace, `v` prefix, etc. 368 | func (v *Version) Original() string { 369 | return v.original 370 | } 371 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /vendor/github.com/hashicorp/go-version/LICENSE: -------------------------------------------------------------------------------- 1 | Mozilla Public License, version 2.0 2 | 3 | 1. Definitions 4 | 5 | 1.1. “Contributor” 6 | 7 | means each individual or legal entity that creates, contributes to the 8 | creation of, or owns Covered Software. 9 | 10 | 1.2. “Contributor Version” 11 | 12 | means the combination of the Contributions of others (if any) used by a 13 | Contributor and that particular Contributor’s Contribution. 14 | 15 | 1.3. “Contribution” 16 | 17 | means Covered Software of a particular Contributor. 18 | 19 | 1.4. “Covered Software” 20 | 21 | means Source Code Form to which the initial Contributor has attached the 22 | notice in Exhibit A, the Executable Form of such Source Code Form, and 23 | Modifications of such Source Code Form, in each case including portions 24 | thereof. 25 | 26 | 1.5. “Incompatible With Secondary Licenses” 27 | means 28 | 29 | a. that the initial Contributor has attached the notice described in 30 | Exhibit B to the Covered Software; or 31 | 32 | b. that the Covered Software was made available under the terms of version 33 | 1.1 or earlier of the License, but not also under the terms of a 34 | Secondary License. 35 | 36 | 1.6. “Executable Form” 37 | 38 | means any form of the work other than Source Code Form. 39 | 40 | 1.7. “Larger Work” 41 | 42 | means a work that combines Covered Software with other material, in a separate 43 | file or files, that is not Covered Software. 44 | 45 | 1.8. “License” 46 | 47 | means this document. 48 | 49 | 1.9. “Licensable” 50 | 51 | means having the right to grant, to the maximum extent possible, whether at the 52 | time of the initial grant or subsequently, any and all of the rights conveyed by 53 | this License. 54 | 55 | 1.10. “Modifications” 56 | 57 | means any of the following: 58 | 59 | a. any file in Source Code Form that results from an addition to, deletion 60 | from, or modification of the contents of Covered Software; or 61 | 62 | b. any new file in Source Code Form that contains any Covered Software. 63 | 64 | 1.11. “Patent Claims” of a Contributor 65 | 66 | means any patent claim(s), including without limitation, method, process, 67 | and apparatus claims, in any patent Licensable by such Contributor that 68 | would be infringed, but for the grant of the License, by the making, 69 | using, selling, offering for sale, having made, import, or transfer of 70 | either its Contributions or its Contributor Version. 71 | 72 | 1.12. “Secondary License” 73 | 74 | means either the GNU General Public License, Version 2.0, the GNU Lesser 75 | General Public License, Version 2.1, the GNU Affero General Public 76 | License, Version 3.0, or any later versions of those licenses. 77 | 78 | 1.13. “Source Code Form” 79 | 80 | means the form of the work preferred for making modifications. 81 | 82 | 1.14. “You” (or “Your”) 83 | 84 | means an individual or a legal entity exercising rights under this 85 | License. For legal entities, “You” includes any entity that controls, is 86 | controlled by, or is under common control with You. For purposes of this 87 | definition, “control” means (a) the power, direct or indirect, to cause 88 | the direction or management of such entity, whether by contract or 89 | otherwise, or (b) ownership of more than fifty percent (50%) of the 90 | outstanding shares or beneficial ownership of such entity. 91 | 92 | 93 | 2. License Grants and Conditions 94 | 95 | 2.1. Grants 96 | 97 | Each Contributor hereby grants You a world-wide, royalty-free, 98 | non-exclusive license: 99 | 100 | a. under intellectual property rights (other than patent or trademark) 101 | Licensable by such Contributor to use, reproduce, make available, 102 | modify, display, perform, distribute, and otherwise exploit its 103 | Contributions, either on an unmodified basis, with Modifications, or as 104 | part of a Larger Work; and 105 | 106 | b. under Patent Claims of such Contributor to make, use, sell, offer for 107 | sale, have made, import, and otherwise transfer either its Contributions 108 | or its Contributor Version. 109 | 110 | 2.2. Effective Date 111 | 112 | The licenses granted in Section 2.1 with respect to any Contribution become 113 | effective for each Contribution on the date the Contributor first distributes 114 | such Contribution. 115 | 116 | 2.3. Limitations on Grant Scope 117 | 118 | The licenses granted in this Section 2 are the only rights granted under this 119 | License. No additional rights or licenses will be implied from the distribution 120 | or licensing of Covered Software under this License. Notwithstanding Section 121 | 2.1(b) above, no patent license is granted by a Contributor: 122 | 123 | a. for any code that a Contributor has removed from Covered Software; or 124 | 125 | b. for infringements caused by: (i) Your and any other third party’s 126 | modifications of Covered Software, or (ii) the combination of its 127 | Contributions with other software (except as part of its Contributor 128 | Version); or 129 | 130 | c. under Patent Claims infringed by Covered Software in the absence of its 131 | Contributions. 132 | 133 | This License does not grant any rights in the trademarks, service marks, or 134 | logos of any Contributor (except as may be necessary to comply with the 135 | notice requirements in Section 3.4). 136 | 137 | 2.4. Subsequent Licenses 138 | 139 | No Contributor makes additional grants as a result of Your choice to 140 | distribute the Covered Software under a subsequent version of this License 141 | (see Section 10.2) or under the terms of a Secondary License (if permitted 142 | under the terms of Section 3.3). 143 | 144 | 2.5. Representation 145 | 146 | Each Contributor represents that the Contributor believes its Contributions 147 | are its original creation(s) or it has sufficient rights to grant the 148 | rights to its Contributions conveyed by this License. 149 | 150 | 2.6. Fair Use 151 | 152 | This License is not intended to limit any rights You have under applicable 153 | copyright doctrines of fair use, fair dealing, or other equivalents. 154 | 155 | 2.7. Conditions 156 | 157 | Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted in 158 | Section 2.1. 159 | 160 | 161 | 3. Responsibilities 162 | 163 | 3.1. Distribution of Source Form 164 | 165 | All distribution of Covered Software in Source Code Form, including any 166 | Modifications that You create or to which You contribute, must be under the 167 | terms of this License. You must inform recipients that the Source Code Form 168 | of the Covered Software is governed by the terms of this License, and how 169 | they can obtain a copy of this License. You may not attempt to alter or 170 | restrict the recipients’ rights in the Source Code Form. 171 | 172 | 3.2. Distribution of Executable Form 173 | 174 | If You distribute Covered Software in Executable Form then: 175 | 176 | a. such Covered Software must also be made available in Source Code Form, 177 | as described in Section 3.1, and You must inform recipients of the 178 | Executable Form how they can obtain a copy of such Source Code Form by 179 | reasonable means in a timely manner, at a charge no more than the cost 180 | of distribution to the recipient; and 181 | 182 | b. You may distribute such Executable Form under the terms of this License, 183 | or sublicense it under different terms, provided that the license for 184 | the Executable Form does not attempt to limit or alter the recipients’ 185 | rights in the Source Code Form under this License. 186 | 187 | 3.3. Distribution of a Larger Work 188 | 189 | You may create and distribute a Larger Work under terms of Your choice, 190 | provided that You also comply with the requirements of this License for the 191 | Covered Software. If the Larger Work is a combination of Covered Software 192 | with a work governed by one or more Secondary Licenses, and the Covered 193 | Software is not Incompatible With Secondary Licenses, this License permits 194 | You to additionally distribute such Covered Software under the terms of 195 | such Secondary License(s), so that the recipient of the Larger Work may, at 196 | their option, further distribute the Covered Software under the terms of 197 | either this License or such Secondary License(s). 198 | 199 | 3.4. Notices 200 | 201 | You may not remove or alter the substance of any license notices (including 202 | copyright notices, patent notices, disclaimers of warranty, or limitations 203 | of liability) contained within the Source Code Form of the Covered 204 | Software, except that You may alter any license notices to the extent 205 | required to remedy known factual inaccuracies. 206 | 207 | 3.5. Application of Additional Terms 208 | 209 | You may choose to offer, and to charge a fee for, warranty, support, 210 | indemnity or liability obligations to one or more recipients of Covered 211 | Software. However, You may do so only on Your own behalf, and not on behalf 212 | of any Contributor. You must make it absolutely clear that any such 213 | warranty, support, indemnity, or liability obligation is offered by You 214 | alone, and You hereby agree to indemnify every Contributor for any 215 | liability incurred by such Contributor as a result of warranty, support, 216 | indemnity or liability terms You offer. You may include additional 217 | disclaimers of warranty and limitations of liability specific to any 218 | jurisdiction. 219 | 220 | 4. Inability to Comply Due to Statute or Regulation 221 | 222 | If it is impossible for You to comply with any of the terms of this License 223 | with respect to some or all of the Covered Software due to statute, judicial 224 | order, or regulation then You must: (a) comply with the terms of this License 225 | to the maximum extent possible; and (b) describe the limitations and the code 226 | they affect. Such description must be placed in a text file included with all 227 | distributions of the Covered Software under this License. Except to the 228 | extent prohibited by statute or regulation, such description must be 229 | sufficiently detailed for a recipient of ordinary skill to be able to 230 | understand it. 231 | 232 | 5. Termination 233 | 234 | 5.1. The rights granted under this License will terminate automatically if You 235 | fail to comply with any of its terms. However, if You become compliant, 236 | then the rights granted under this License from a particular Contributor 237 | are reinstated (a) provisionally, unless and until such Contributor 238 | explicitly and finally terminates Your grants, and (b) on an ongoing basis, 239 | if such Contributor fails to notify You of the non-compliance by some 240 | reasonable means prior to 60 days after You have come back into compliance. 241 | Moreover, Your grants from a particular Contributor are reinstated on an 242 | ongoing basis if such Contributor notifies You of the non-compliance by 243 | some reasonable means, this is the first time You have received notice of 244 | non-compliance with this License from such Contributor, and You become 245 | compliant prior to 30 days after Your receipt of the notice. 246 | 247 | 5.2. If You initiate litigation against any entity by asserting a patent 248 | infringement claim (excluding declaratory judgment actions, counter-claims, 249 | and cross-claims) alleging that a Contributor Version directly or 250 | indirectly infringes any patent, then the rights granted to You by any and 251 | all Contributors for the Covered Software under Section 2.1 of this License 252 | shall terminate. 253 | 254 | 5.3. In the event of termination under Sections 5.1 or 5.2 above, all end user 255 | license agreements (excluding distributors and resellers) which have been 256 | validly granted by You or Your distributors under this License prior to 257 | termination shall survive termination. 258 | 259 | 6. Disclaimer of Warranty 260 | 261 | Covered Software is provided under this License on an “as is” basis, without 262 | warranty of any kind, either expressed, implied, or statutory, including, 263 | without limitation, warranties that the Covered Software is free of defects, 264 | merchantable, fit for a particular purpose or non-infringing. The entire 265 | risk as to the quality and performance of the Covered Software is with You. 266 | Should any Covered Software prove defective in any respect, You (not any 267 | Contributor) assume the cost of any necessary servicing, repair, or 268 | correction. This disclaimer of warranty constitutes an essential part of this 269 | License. No use of any Covered Software is authorized under this License 270 | except under this disclaimer. 271 | 272 | 7. Limitation of Liability 273 | 274 | Under no circumstances and under no legal theory, whether tort (including 275 | negligence), contract, or otherwise, shall any Contributor, or anyone who 276 | distributes Covered Software as permitted above, be liable to You for any 277 | direct, indirect, special, incidental, or consequential damages of any 278 | character including, without limitation, damages for lost profits, loss of 279 | goodwill, work stoppage, computer failure or malfunction, or any and all 280 | other commercial damages or losses, even if such party shall have been 281 | informed of the possibility of such damages. This limitation of liability 282 | shall not apply to liability for death or personal injury resulting from such 283 | party’s negligence to the extent applicable law prohibits such limitation. 284 | Some jurisdictions do not allow the exclusion or limitation of incidental or 285 | consequential damages, so this exclusion and limitation may not apply to You. 286 | 287 | 8. Litigation 288 | 289 | Any litigation relating to this License may be brought only in the courts of 290 | a jurisdiction where the defendant maintains its principal place of business 291 | and such litigation shall be governed by laws of that jurisdiction, without 292 | reference to its conflict-of-law provisions. Nothing in this Section shall 293 | prevent a party’s ability to bring cross-claims or counter-claims. 294 | 295 | 9. Miscellaneous 296 | 297 | This License represents the complete agreement concerning the subject matter 298 | hereof. If any provision of this License is held to be unenforceable, such 299 | provision shall be reformed only to the extent necessary to make it 300 | enforceable. Any law or regulation which provides that the language of a 301 | contract shall be construed against the drafter shall not be used to construe 302 | this License against a Contributor. 303 | 304 | 305 | 10. Versions of the License 306 | 307 | 10.1. New Versions 308 | 309 | Mozilla Foundation is the license steward. Except as provided in Section 310 | 10.3, no one other than the license steward has the right to modify or 311 | publish new versions of this License. Each version will be given a 312 | distinguishing version number. 313 | 314 | 10.2. Effect of New Versions 315 | 316 | You may distribute the Covered Software under the terms of the version of 317 | the License under which You originally received the Covered Software, or 318 | under the terms of any subsequent version published by the license 319 | steward. 320 | 321 | 10.3. Modified Versions 322 | 323 | If you create software not governed by this License, and you want to 324 | create a new license for such software, you may create and use a modified 325 | version of this License if you rename the license and remove any 326 | references to the name of the license steward (except to note that such 327 | modified license differs from this License). 328 | 329 | 10.4. Distributing Source Code Form that is Incompatible With Secondary Licenses 330 | If You choose to distribute Source Code Form that is Incompatible With 331 | Secondary Licenses under the terms of this version of the License, the 332 | notice described in Exhibit B of this License must be attached. 333 | 334 | Exhibit A - Source Code Form License Notice 335 | 336 | This Source Code Form is subject to the 337 | terms of the Mozilla Public License, v. 338 | 2.0. If a copy of the MPL was not 339 | distributed with this file, You can 340 | obtain one at 341 | http://mozilla.org/MPL/2.0/. 342 | 343 | If it is not possible or desirable to put the notice in a particular file, then 344 | You may include the notice in a location (such as a LICENSE file in a relevant 345 | directory) where a recipient would be likely to look for such a notice. 346 | 347 | You may add additional accurate notices of copyright ownership. 348 | 349 | Exhibit B - “Incompatible With Secondary Licenses” Notice 350 | 351 | This Source Code Form is “Incompatible 352 | With Secondary Licenses”, as defined by 353 | the Mozilla Public License, v. 2.0. 354 | 355 | --------------------------------------------------------------------------------