*: switch from glide to go mod
Signed-off-by: Vincent Batts <vbatts@hashbangbash.com>
This commit is contained in:
parent
e409d983eb
commit
23a85a16c1
19 changed files with 15 additions and 2318 deletions
3
Makefile
3
Makefile
|
@ -21,5 +21,4 @@ clean:
|
||||||
|
|
||||||
.PHONY: vendor
|
.PHONY: vendor
|
||||||
vendor:
|
vendor:
|
||||||
$(Q)glide update --strip-vendor
|
$(Q)go mod vendor
|
||||||
$(Q)glide-vc --use-lock-file --no-tests --only-code
|
|
||||||
|
|
13
glide.lock
generated
13
glide.lock
generated
|
@ -1,13 +0,0 @@
|
||||||
hash: a0dc2989b3602eb009ca448d7c52c4503ce9a616b73cd0f7e4348d9e9336c041
|
|
||||||
updated: 2017-11-30T12:55:15.176689511-08:00
|
|
||||||
imports:
|
|
||||||
- name: github.com/blang/semver
|
|
||||||
version: 2ee87856327ba09384cabd113bc6b5d174e9ec0f
|
|
||||||
- name: github.com/satori/go.uuid
|
|
||||||
version: 879c5887cd475cd7864858769793b2ceb0d44feb
|
|
||||||
testImports:
|
|
||||||
- name: github.com/kylelemons/godebug
|
|
||||||
version: d65d576e9348f5982d7f6d83682b694e731a45c6
|
|
||||||
subpackages:
|
|
||||||
- diff
|
|
||||||
- pretty
|
|
11
glide.yaml
11
glide.yaml
|
@ -1,11 +0,0 @@
|
||||||
package: github.com/coreos/go-omaha
|
|
||||||
import:
|
|
||||||
- package: github.com/blang/semver
|
|
||||||
version: ~3.5.1
|
|
||||||
- package: github.com/satori/go.uuid
|
|
||||||
version: ~1.1.0
|
|
||||||
testImport:
|
|
||||||
- package: github.com/kylelemons/godebug
|
|
||||||
subpackages:
|
|
||||||
- diff
|
|
||||||
- pretty
|
|
9
go.mod
Normal file
9
go.mod
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
module github.com/kinvolk/go-omaha
|
||||||
|
|
||||||
|
go 1.15
|
||||||
|
|
||||||
|
require (
|
||||||
|
git.thisco.de/vbatts/go-omaha v0.0.0-20180327202221-e409d983eb60 // indirect
|
||||||
|
github.com/blang/semver v3.5.1+incompatible
|
||||||
|
github.com/satori/go.uuid v1.1.0
|
||||||
|
)
|
5
go.sum
Normal file
5
go.sum
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
git.thisco.de/vbatts/go-omaha v0.0.0-20180327202221-e409d983eb60 h1:lqjtEFY5RgNgWJWOv0KUW0Llvh0+Ved7nWIqFEssY34=
|
||||||
|
git.thisco.de/vbatts/go-omaha v0.0.0-20180327202221-e409d983eb60/go.mod h1:w+Vl1DisYu3l2h88jvqZDV414oSIcTY8YrZLOa/vLME=
|
||||||
|
github.com/blang/semver v3.5.1+incompatible h1:cQNTCjp13qL8KC3Nbxr/y2Bqb63oX6wdnnjpJbkM4JQ=
|
||||||
|
github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk=
|
||||||
|
github.com/satori/go.uuid v1.1.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
|
22
vendor/github.com/blang/semver/LICENSE
generated
vendored
22
vendor/github.com/blang/semver/LICENSE
generated
vendored
|
@ -1,22 +0,0 @@
|
||||||
The MIT License
|
|
||||||
|
|
||||||
Copyright (c) 2014 Benedikt Lang <github at benediktlang.de>
|
|
||||||
|
|
||||||
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.
|
|
||||||
|
|
23
vendor/github.com/blang/semver/json.go
generated
vendored
23
vendor/github.com/blang/semver/json.go
generated
vendored
|
@ -1,23 +0,0 @@
|
||||||
package semver
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/json"
|
|
||||||
)
|
|
||||||
|
|
||||||
// MarshalJSON implements the encoding/json.Marshaler interface.
|
|
||||||
func (v Version) MarshalJSON() ([]byte, error) {
|
|
||||||
return json.Marshal(v.String())
|
|
||||||
}
|
|
||||||
|
|
||||||
// UnmarshalJSON implements the encoding/json.Unmarshaler interface.
|
|
||||||
func (v *Version) UnmarshalJSON(data []byte) (err error) {
|
|
||||||
var versionString string
|
|
||||||
|
|
||||||
if err = json.Unmarshal(data, &versionString); err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
*v, err = Parse(versionString)
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
416
vendor/github.com/blang/semver/range.go
generated
vendored
416
vendor/github.com/blang/semver/range.go
generated
vendored
|
@ -1,416 +0,0 @@
|
||||||
package semver
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
"unicode"
|
|
||||||
)
|
|
||||||
|
|
||||||
type wildcardType int
|
|
||||||
|
|
||||||
const (
|
|
||||||
noneWildcard wildcardType = iota
|
|
||||||
majorWildcard wildcardType = 1
|
|
||||||
minorWildcard wildcardType = 2
|
|
||||||
patchWildcard wildcardType = 3
|
|
||||||
)
|
|
||||||
|
|
||||||
func wildcardTypefromInt(i int) wildcardType {
|
|
||||||
switch i {
|
|
||||||
case 1:
|
|
||||||
return majorWildcard
|
|
||||||
case 2:
|
|
||||||
return minorWildcard
|
|
||||||
case 3:
|
|
||||||
return patchWildcard
|
|
||||||
default:
|
|
||||||
return noneWildcard
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
type comparator func(Version, Version) bool
|
|
||||||
|
|
||||||
var (
|
|
||||||
compEQ comparator = func(v1 Version, v2 Version) bool {
|
|
||||||
return v1.Compare(v2) == 0
|
|
||||||
}
|
|
||||||
compNE = func(v1 Version, v2 Version) bool {
|
|
||||||
return v1.Compare(v2) != 0
|
|
||||||
}
|
|
||||||
compGT = func(v1 Version, v2 Version) bool {
|
|
||||||
return v1.Compare(v2) == 1
|
|
||||||
}
|
|
||||||
compGE = func(v1 Version, v2 Version) bool {
|
|
||||||
return v1.Compare(v2) >= 0
|
|
||||||
}
|
|
||||||
compLT = func(v1 Version, v2 Version) bool {
|
|
||||||
return v1.Compare(v2) == -1
|
|
||||||
}
|
|
||||||
compLE = func(v1 Version, v2 Version) bool {
|
|
||||||
return v1.Compare(v2) <= 0
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
type versionRange struct {
|
|
||||||
v Version
|
|
||||||
c comparator
|
|
||||||
}
|
|
||||||
|
|
||||||
// rangeFunc creates a Range from the given versionRange.
|
|
||||||
func (vr *versionRange) rangeFunc() Range {
|
|
||||||
return Range(func(v Version) bool {
|
|
||||||
return vr.c(v, vr.v)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// Range represents a range of versions.
|
|
||||||
// A Range can be used to check if a Version satisfies it:
|
|
||||||
//
|
|
||||||
// range, err := semver.ParseRange(">1.0.0 <2.0.0")
|
|
||||||
// range(semver.MustParse("1.1.1") // returns true
|
|
||||||
type Range func(Version) bool
|
|
||||||
|
|
||||||
// OR combines the existing Range with another Range using logical OR.
|
|
||||||
func (rf Range) OR(f Range) Range {
|
|
||||||
return Range(func(v Version) bool {
|
|
||||||
return rf(v) || f(v)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// AND combines the existing Range with another Range using logical AND.
|
|
||||||
func (rf Range) AND(f Range) Range {
|
|
||||||
return Range(func(v Version) bool {
|
|
||||||
return rf(v) && f(v)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// ParseRange parses a range and returns a Range.
|
|
||||||
// If the range could not be parsed an error is returned.
|
|
||||||
//
|
|
||||||
// Valid ranges are:
|
|
||||||
// - "<1.0.0"
|
|
||||||
// - "<=1.0.0"
|
|
||||||
// - ">1.0.0"
|
|
||||||
// - ">=1.0.0"
|
|
||||||
// - "1.0.0", "=1.0.0", "==1.0.0"
|
|
||||||
// - "!1.0.0", "!=1.0.0"
|
|
||||||
//
|
|
||||||
// A Range can consist of multiple ranges separated by space:
|
|
||||||
// Ranges can be linked by logical AND:
|
|
||||||
// - ">1.0.0 <2.0.0" would match between both ranges, so "1.1.1" and "1.8.7" but not "1.0.0" or "2.0.0"
|
|
||||||
// - ">1.0.0 <3.0.0 !2.0.3-beta.2" would match every version between 1.0.0 and 3.0.0 except 2.0.3-beta.2
|
|
||||||
//
|
|
||||||
// Ranges can also be linked by logical OR:
|
|
||||||
// - "<2.0.0 || >=3.0.0" would match "1.x.x" and "3.x.x" but not "2.x.x"
|
|
||||||
//
|
|
||||||
// AND has a higher precedence than OR. It's not possible to use brackets.
|
|
||||||
//
|
|
||||||
// Ranges can be combined by both AND and OR
|
|
||||||
//
|
|
||||||
// - `>1.0.0 <2.0.0 || >3.0.0 !4.2.1` would match `1.2.3`, `1.9.9`, `3.1.1`, but not `4.2.1`, `2.1.1`
|
|
||||||
func ParseRange(s string) (Range, error) {
|
|
||||||
parts := splitAndTrim(s)
|
|
||||||
orParts, err := splitORParts(parts)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
expandedParts, err := expandWildcardVersion(orParts)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
var orFn Range
|
|
||||||
for _, p := range expandedParts {
|
|
||||||
var andFn Range
|
|
||||||
for _, ap := range p {
|
|
||||||
opStr, vStr, err := splitComparatorVersion(ap)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
vr, err := buildVersionRange(opStr, vStr)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("Could not parse Range %q: %s", ap, err)
|
|
||||||
}
|
|
||||||
rf := vr.rangeFunc()
|
|
||||||
|
|
||||||
// Set function
|
|
||||||
if andFn == nil {
|
|
||||||
andFn = rf
|
|
||||||
} else { // Combine with existing function
|
|
||||||
andFn = andFn.AND(rf)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if orFn == nil {
|
|
||||||
orFn = andFn
|
|
||||||
} else {
|
|
||||||
orFn = orFn.OR(andFn)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
return orFn, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// splitORParts splits the already cleaned parts by '||'.
|
|
||||||
// Checks for invalid positions of the operator and returns an
|
|
||||||
// error if found.
|
|
||||||
func splitORParts(parts []string) ([][]string, error) {
|
|
||||||
var ORparts [][]string
|
|
||||||
last := 0
|
|
||||||
for i, p := range parts {
|
|
||||||
if p == "||" {
|
|
||||||
if i == 0 {
|
|
||||||
return nil, fmt.Errorf("First element in range is '||'")
|
|
||||||
}
|
|
||||||
ORparts = append(ORparts, parts[last:i])
|
|
||||||
last = i + 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if last == len(parts) {
|
|
||||||
return nil, fmt.Errorf("Last element in range is '||'")
|
|
||||||
}
|
|
||||||
ORparts = append(ORparts, parts[last:])
|
|
||||||
return ORparts, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// buildVersionRange takes a slice of 2: operator and version
|
|
||||||
// and builds a versionRange, otherwise an error.
|
|
||||||
func buildVersionRange(opStr, vStr string) (*versionRange, error) {
|
|
||||||
c := parseComparator(opStr)
|
|
||||||
if c == nil {
|
|
||||||
return nil, fmt.Errorf("Could not parse comparator %q in %q", opStr, strings.Join([]string{opStr, vStr}, ""))
|
|
||||||
}
|
|
||||||
v, err := Parse(vStr)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("Could not parse version %q in %q: %s", vStr, strings.Join([]string{opStr, vStr}, ""), err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return &versionRange{
|
|
||||||
v: v,
|
|
||||||
c: c,
|
|
||||||
}, nil
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// inArray checks if a byte is contained in an array of bytes
|
|
||||||
func inArray(s byte, list []byte) bool {
|
|
||||||
for _, el := range list {
|
|
||||||
if el == s {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
// splitAndTrim splits a range string by spaces and cleans whitespaces
|
|
||||||
func splitAndTrim(s string) (result []string) {
|
|
||||||
last := 0
|
|
||||||
var lastChar byte
|
|
||||||
excludeFromSplit := []byte{'>', '<', '='}
|
|
||||||
for i := 0; i < len(s); i++ {
|
|
||||||
if s[i] == ' ' && !inArray(lastChar, excludeFromSplit) {
|
|
||||||
if last < i-1 {
|
|
||||||
result = append(result, s[last:i])
|
|
||||||
}
|
|
||||||
last = i + 1
|
|
||||||
} else if s[i] != ' ' {
|
|
||||||
lastChar = s[i]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if last < len(s)-1 {
|
|
||||||
result = append(result, s[last:])
|
|
||||||
}
|
|
||||||
|
|
||||||
for i, v := range result {
|
|
||||||
result[i] = strings.Replace(v, " ", "", -1)
|
|
||||||
}
|
|
||||||
|
|
||||||
// parts := strings.Split(s, " ")
|
|
||||||
// for _, x := range parts {
|
|
||||||
// if s := strings.TrimSpace(x); len(s) != 0 {
|
|
||||||
// result = append(result, s)
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// splitComparatorVersion splits the comparator from the version.
|
|
||||||
// Input must be free of leading or trailing spaces.
|
|
||||||
func splitComparatorVersion(s string) (string, string, error) {
|
|
||||||
i := strings.IndexFunc(s, unicode.IsDigit)
|
|
||||||
if i == -1 {
|
|
||||||
return "", "", fmt.Errorf("Could not get version from string: %q", s)
|
|
||||||
}
|
|
||||||
return strings.TrimSpace(s[0:i]), s[i:], nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// getWildcardType will return the type of wildcard that the
|
|
||||||
// passed version contains
|
|
||||||
func getWildcardType(vStr string) wildcardType {
|
|
||||||
parts := strings.Split(vStr, ".")
|
|
||||||
nparts := len(parts)
|
|
||||||
wildcard := parts[nparts-1]
|
|
||||||
|
|
||||||
possibleWildcardType := wildcardTypefromInt(nparts)
|
|
||||||
if wildcard == "x" {
|
|
||||||
return possibleWildcardType
|
|
||||||
}
|
|
||||||
|
|
||||||
return noneWildcard
|
|
||||||
}
|
|
||||||
|
|
||||||
// createVersionFromWildcard will convert a wildcard version
|
|
||||||
// into a regular version, replacing 'x's with '0's, handling
|
|
||||||
// special cases like '1.x.x' and '1.x'
|
|
||||||
func createVersionFromWildcard(vStr string) string {
|
|
||||||
// handle 1.x.x
|
|
||||||
vStr2 := strings.Replace(vStr, ".x.x", ".x", 1)
|
|
||||||
vStr2 = strings.Replace(vStr2, ".x", ".0", 1)
|
|
||||||
parts := strings.Split(vStr2, ".")
|
|
||||||
|
|
||||||
// handle 1.x
|
|
||||||
if len(parts) == 2 {
|
|
||||||
return vStr2 + ".0"
|
|
||||||
}
|
|
||||||
|
|
||||||
return vStr2
|
|
||||||
}
|
|
||||||
|
|
||||||
// incrementMajorVersion will increment the major version
|
|
||||||
// of the passed version
|
|
||||||
func incrementMajorVersion(vStr string) (string, error) {
|
|
||||||
parts := strings.Split(vStr, ".")
|
|
||||||
i, err := strconv.Atoi(parts[0])
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
parts[0] = strconv.Itoa(i + 1)
|
|
||||||
|
|
||||||
return strings.Join(parts, "."), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// incrementMajorVersion will increment the minor version
|
|
||||||
// of the passed version
|
|
||||||
func incrementMinorVersion(vStr string) (string, error) {
|
|
||||||
parts := strings.Split(vStr, ".")
|
|
||||||
i, err := strconv.Atoi(parts[1])
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
parts[1] = strconv.Itoa(i + 1)
|
|
||||||
|
|
||||||
return strings.Join(parts, "."), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// expandWildcardVersion will expand wildcards inside versions
|
|
||||||
// following these rules:
|
|
||||||
//
|
|
||||||
// * when dealing with patch wildcards:
|
|
||||||
// >= 1.2.x will become >= 1.2.0
|
|
||||||
// <= 1.2.x will become < 1.3.0
|
|
||||||
// > 1.2.x will become >= 1.3.0
|
|
||||||
// < 1.2.x will become < 1.2.0
|
|
||||||
// != 1.2.x will become < 1.2.0 >= 1.3.0
|
|
||||||
//
|
|
||||||
// * when dealing with minor wildcards:
|
|
||||||
// >= 1.x will become >= 1.0.0
|
|
||||||
// <= 1.x will become < 2.0.0
|
|
||||||
// > 1.x will become >= 2.0.0
|
|
||||||
// < 1.0 will become < 1.0.0
|
|
||||||
// != 1.x will become < 1.0.0 >= 2.0.0
|
|
||||||
//
|
|
||||||
// * when dealing with wildcards without
|
|
||||||
// version operator:
|
|
||||||
// 1.2.x will become >= 1.2.0 < 1.3.0
|
|
||||||
// 1.x will become >= 1.0.0 < 2.0.0
|
|
||||||
func expandWildcardVersion(parts [][]string) ([][]string, error) {
|
|
||||||
var expandedParts [][]string
|
|
||||||
for _, p := range parts {
|
|
||||||
var newParts []string
|
|
||||||
for _, ap := range p {
|
|
||||||
if strings.Index(ap, "x") != -1 {
|
|
||||||
opStr, vStr, err := splitComparatorVersion(ap)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
versionWildcardType := getWildcardType(vStr)
|
|
||||||
flatVersion := createVersionFromWildcard(vStr)
|
|
||||||
|
|
||||||
var resultOperator string
|
|
||||||
var shouldIncrementVersion bool
|
|
||||||
switch opStr {
|
|
||||||
case ">":
|
|
||||||
resultOperator = ">="
|
|
||||||
shouldIncrementVersion = true
|
|
||||||
case ">=":
|
|
||||||
resultOperator = ">="
|
|
||||||
case "<":
|
|
||||||
resultOperator = "<"
|
|
||||||
case "<=":
|
|
||||||
resultOperator = "<"
|
|
||||||
shouldIncrementVersion = true
|
|
||||||
case "", "=", "==":
|
|
||||||
newParts = append(newParts, ">="+flatVersion)
|
|
||||||
resultOperator = "<"
|
|
||||||
shouldIncrementVersion = true
|
|
||||||
case "!=", "!":
|
|
||||||
newParts = append(newParts, "<"+flatVersion)
|
|
||||||
resultOperator = ">="
|
|
||||||
shouldIncrementVersion = true
|
|
||||||
}
|
|
||||||
|
|
||||||
var resultVersion string
|
|
||||||
if shouldIncrementVersion {
|
|
||||||
switch versionWildcardType {
|
|
||||||
case patchWildcard:
|
|
||||||
resultVersion, _ = incrementMinorVersion(flatVersion)
|
|
||||||
case minorWildcard:
|
|
||||||
resultVersion, _ = incrementMajorVersion(flatVersion)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
resultVersion = flatVersion
|
|
||||||
}
|
|
||||||
|
|
||||||
ap = resultOperator + resultVersion
|
|
||||||
}
|
|
||||||
newParts = append(newParts, ap)
|
|
||||||
}
|
|
||||||
expandedParts = append(expandedParts, newParts)
|
|
||||||
}
|
|
||||||
|
|
||||||
return expandedParts, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func parseComparator(s string) comparator {
|
|
||||||
switch s {
|
|
||||||
case "==":
|
|
||||||
fallthrough
|
|
||||||
case "":
|
|
||||||
fallthrough
|
|
||||||
case "=":
|
|
||||||
return compEQ
|
|
||||||
case ">":
|
|
||||||
return compGT
|
|
||||||
case ">=":
|
|
||||||
return compGE
|
|
||||||
case "<":
|
|
||||||
return compLT
|
|
||||||
case "<=":
|
|
||||||
return compLE
|
|
||||||
case "!":
|
|
||||||
fallthrough
|
|
||||||
case "!=":
|
|
||||||
return compNE
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// MustParseRange is like ParseRange but panics if the range cannot be parsed.
|
|
||||||
func MustParseRange(s string) Range {
|
|
||||||
r, err := ParseRange(s)
|
|
||||||
if err != nil {
|
|
||||||
panic(`semver: ParseRange(` + s + `): ` + err.Error())
|
|
||||||
}
|
|
||||||
return r
|
|
||||||
}
|
|
418
vendor/github.com/blang/semver/semver.go
generated
vendored
418
vendor/github.com/blang/semver/semver.go
generated
vendored
|
@ -1,418 +0,0 @@
|
||||||
package semver
|
|
||||||
|
|
||||||
import (
|
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
numbers string = "0123456789"
|
|
||||||
alphas = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-"
|
|
||||||
alphanum = alphas + numbers
|
|
||||||
)
|
|
||||||
|
|
||||||
// SpecVersion is the latest fully supported spec version of semver
|
|
||||||
var SpecVersion = Version{
|
|
||||||
Major: 2,
|
|
||||||
Minor: 0,
|
|
||||||
Patch: 0,
|
|
||||||
}
|
|
||||||
|
|
||||||
// Version represents a semver compatible version
|
|
||||||
type Version struct {
|
|
||||||
Major uint64
|
|
||||||
Minor uint64
|
|
||||||
Patch uint64
|
|
||||||
Pre []PRVersion
|
|
||||||
Build []string //No Precendence
|
|
||||||
}
|
|
||||||
|
|
||||||
// Version to string
|
|
||||||
func (v Version) String() string {
|
|
||||||
b := make([]byte, 0, 5)
|
|
||||||
b = strconv.AppendUint(b, v.Major, 10)
|
|
||||||
b = append(b, '.')
|
|
||||||
b = strconv.AppendUint(b, v.Minor, 10)
|
|
||||||
b = append(b, '.')
|
|
||||||
b = strconv.AppendUint(b, v.Patch, 10)
|
|
||||||
|
|
||||||
if len(v.Pre) > 0 {
|
|
||||||
b = append(b, '-')
|
|
||||||
b = append(b, v.Pre[0].String()...)
|
|
||||||
|
|
||||||
for _, pre := range v.Pre[1:] {
|
|
||||||
b = append(b, '.')
|
|
||||||
b = append(b, pre.String()...)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(v.Build) > 0 {
|
|
||||||
b = append(b, '+')
|
|
||||||
b = append(b, v.Build[0]...)
|
|
||||||
|
|
||||||
for _, build := range v.Build[1:] {
|
|
||||||
b = append(b, '.')
|
|
||||||
b = append(b, build...)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return string(b)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Equals checks if v is equal to o.
|
|
||||||
func (v Version) Equals(o Version) bool {
|
|
||||||
return (v.Compare(o) == 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
// EQ checks if v is equal to o.
|
|
||||||
func (v Version) EQ(o Version) bool {
|
|
||||||
return (v.Compare(o) == 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
// NE checks if v is not equal to o.
|
|
||||||
func (v Version) NE(o Version) bool {
|
|
||||||
return (v.Compare(o) != 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
// GT checks if v is greater than o.
|
|
||||||
func (v Version) GT(o Version) bool {
|
|
||||||
return (v.Compare(o) == 1)
|
|
||||||
}
|
|
||||||
|
|
||||||
// GTE checks if v is greater than or equal to o.
|
|
||||||
func (v Version) GTE(o Version) bool {
|
|
||||||
return (v.Compare(o) >= 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
// GE checks if v is greater than or equal to o.
|
|
||||||
func (v Version) GE(o Version) bool {
|
|
||||||
return (v.Compare(o) >= 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
// LT checks if v is less than o.
|
|
||||||
func (v Version) LT(o Version) bool {
|
|
||||||
return (v.Compare(o) == -1)
|
|
||||||
}
|
|
||||||
|
|
||||||
// LTE checks if v is less than or equal to o.
|
|
||||||
func (v Version) LTE(o Version) bool {
|
|
||||||
return (v.Compare(o) <= 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
// LE checks if v is less than or equal to o.
|
|
||||||
func (v Version) LE(o Version) bool {
|
|
||||||
return (v.Compare(o) <= 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Compare compares Versions v to o:
|
|
||||||
// -1 == v is less than o
|
|
||||||
// 0 == v is equal to o
|
|
||||||
// 1 == v is greater than o
|
|
||||||
func (v Version) Compare(o Version) int {
|
|
||||||
if v.Major != o.Major {
|
|
||||||
if v.Major > o.Major {
|
|
||||||
return 1
|
|
||||||
}
|
|
||||||
return -1
|
|
||||||
}
|
|
||||||
if v.Minor != o.Minor {
|
|
||||||
if v.Minor > o.Minor {
|
|
||||||
return 1
|
|
||||||
}
|
|
||||||
return -1
|
|
||||||
}
|
|
||||||
if v.Patch != o.Patch {
|
|
||||||
if v.Patch > o.Patch {
|
|
||||||
return 1
|
|
||||||
}
|
|
||||||
return -1
|
|
||||||
}
|
|
||||||
|
|
||||||
// Quick comparison if a version has no prerelease versions
|
|
||||||
if len(v.Pre) == 0 && len(o.Pre) == 0 {
|
|
||||||
return 0
|
|
||||||
} else if len(v.Pre) == 0 && len(o.Pre) > 0 {
|
|
||||||
return 1
|
|
||||||
} else if len(v.Pre) > 0 && len(o.Pre) == 0 {
|
|
||||||
return -1
|
|
||||||
}
|
|
||||||
|
|
||||||
i := 0
|
|
||||||
for ; i < len(v.Pre) && i < len(o.Pre); i++ {
|
|
||||||
if comp := v.Pre[i].Compare(o.Pre[i]); comp == 0 {
|
|
||||||
continue
|
|
||||||
} else if comp == 1 {
|
|
||||||
return 1
|
|
||||||
} else {
|
|
||||||
return -1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// If all pr versions are the equal but one has further prversion, this one greater
|
|
||||||
if i == len(v.Pre) && i == len(o.Pre) {
|
|
||||||
return 0
|
|
||||||
} else if i == len(v.Pre) && i < len(o.Pre) {
|
|
||||||
return -1
|
|
||||||
} else {
|
|
||||||
return 1
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// Validate validates v and returns error in case
|
|
||||||
func (v Version) Validate() error {
|
|
||||||
// Major, Minor, Patch already validated using uint64
|
|
||||||
|
|
||||||
for _, pre := range v.Pre {
|
|
||||||
if !pre.IsNum { //Numeric prerelease versions already uint64
|
|
||||||
if len(pre.VersionStr) == 0 {
|
|
||||||
return fmt.Errorf("Prerelease can not be empty %q", pre.VersionStr)
|
|
||||||
}
|
|
||||||
if !containsOnly(pre.VersionStr, alphanum) {
|
|
||||||
return fmt.Errorf("Invalid character(s) found in prerelease %q", pre.VersionStr)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, build := range v.Build {
|
|
||||||
if len(build) == 0 {
|
|
||||||
return fmt.Errorf("Build meta data can not be empty %q", build)
|
|
||||||
}
|
|
||||||
if !containsOnly(build, alphanum) {
|
|
||||||
return fmt.Errorf("Invalid character(s) found in build meta data %q", build)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// New is an alias for Parse and returns a pointer, parses version string and returns a validated Version or error
|
|
||||||
func New(s string) (vp *Version, err error) {
|
|
||||||
v, err := Parse(s)
|
|
||||||
vp = &v
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Make is an alias for Parse, parses version string and returns a validated Version or error
|
|
||||||
func Make(s string) (Version, error) {
|
|
||||||
return Parse(s)
|
|
||||||
}
|
|
||||||
|
|
||||||
// ParseTolerant allows for certain version specifications that do not strictly adhere to semver
|
|
||||||
// specs to be parsed by this library. It does so by normalizing versions before passing them to
|
|
||||||
// Parse(). It currently trims spaces, removes a "v" prefix, and adds a 0 patch number to versions
|
|
||||||
// with only major and minor components specified
|
|
||||||
func ParseTolerant(s string) (Version, error) {
|
|
||||||
s = strings.TrimSpace(s)
|
|
||||||
s = strings.TrimPrefix(s, "v")
|
|
||||||
|
|
||||||
// Split into major.minor.(patch+pr+meta)
|
|
||||||
parts := strings.SplitN(s, ".", 3)
|
|
||||||
if len(parts) < 3 {
|
|
||||||
if strings.ContainsAny(parts[len(parts)-1], "+-") {
|
|
||||||
return Version{}, errors.New("Short version cannot contain PreRelease/Build meta data")
|
|
||||||
}
|
|
||||||
for len(parts) < 3 {
|
|
||||||
parts = append(parts, "0")
|
|
||||||
}
|
|
||||||
s = strings.Join(parts, ".")
|
|
||||||
}
|
|
||||||
|
|
||||||
return Parse(s)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Parse parses version string and returns a validated Version or error
|
|
||||||
func Parse(s string) (Version, error) {
|
|
||||||
if len(s) == 0 {
|
|
||||||
return Version{}, errors.New("Version string empty")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Split into major.minor.(patch+pr+meta)
|
|
||||||
parts := strings.SplitN(s, ".", 3)
|
|
||||||
if len(parts) != 3 {
|
|
||||||
return Version{}, errors.New("No Major.Minor.Patch elements found")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Major
|
|
||||||
if !containsOnly(parts[0], numbers) {
|
|
||||||
return Version{}, fmt.Errorf("Invalid character(s) found in major number %q", parts[0])
|
|
||||||
}
|
|
||||||
if hasLeadingZeroes(parts[0]) {
|
|
||||||
return Version{}, fmt.Errorf("Major number must not contain leading zeroes %q", parts[0])
|
|
||||||
}
|
|
||||||
major, err := strconv.ParseUint(parts[0], 10, 64)
|
|
||||||
if err != nil {
|
|
||||||
return Version{}, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Minor
|
|
||||||
if !containsOnly(parts[1], numbers) {
|
|
||||||
return Version{}, fmt.Errorf("Invalid character(s) found in minor number %q", parts[1])
|
|
||||||
}
|
|
||||||
if hasLeadingZeroes(parts[1]) {
|
|
||||||
return Version{}, fmt.Errorf("Minor number must not contain leading zeroes %q", parts[1])
|
|
||||||
}
|
|
||||||
minor, err := strconv.ParseUint(parts[1], 10, 64)
|
|
||||||
if err != nil {
|
|
||||||
return Version{}, err
|
|
||||||
}
|
|
||||||
|
|
||||||
v := Version{}
|
|
||||||
v.Major = major
|
|
||||||
v.Minor = minor
|
|
||||||
|
|
||||||
var build, prerelease []string
|
|
||||||
patchStr := parts[2]
|
|
||||||
|
|
||||||
if buildIndex := strings.IndexRune(patchStr, '+'); buildIndex != -1 {
|
|
||||||
build = strings.Split(patchStr[buildIndex+1:], ".")
|
|
||||||
patchStr = patchStr[:buildIndex]
|
|
||||||
}
|
|
||||||
|
|
||||||
if preIndex := strings.IndexRune(patchStr, '-'); preIndex != -1 {
|
|
||||||
prerelease = strings.Split(patchStr[preIndex+1:], ".")
|
|
||||||
patchStr = patchStr[:preIndex]
|
|
||||||
}
|
|
||||||
|
|
||||||
if !containsOnly(patchStr, numbers) {
|
|
||||||
return Version{}, fmt.Errorf("Invalid character(s) found in patch number %q", patchStr)
|
|
||||||
}
|
|
||||||
if hasLeadingZeroes(patchStr) {
|
|
||||||
return Version{}, fmt.Errorf("Patch number must not contain leading zeroes %q", patchStr)
|
|
||||||
}
|
|
||||||
patch, err := strconv.ParseUint(patchStr, 10, 64)
|
|
||||||
if err != nil {
|
|
||||||
return Version{}, err
|
|
||||||
}
|
|
||||||
|
|
||||||
v.Patch = patch
|
|
||||||
|
|
||||||
// Prerelease
|
|
||||||
for _, prstr := range prerelease {
|
|
||||||
parsedPR, err := NewPRVersion(prstr)
|
|
||||||
if err != nil {
|
|
||||||
return Version{}, err
|
|
||||||
}
|
|
||||||
v.Pre = append(v.Pre, parsedPR)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Build meta data
|
|
||||||
for _, str := range build {
|
|
||||||
if len(str) == 0 {
|
|
||||||
return Version{}, errors.New("Build meta data is empty")
|
|
||||||
}
|
|
||||||
if !containsOnly(str, alphanum) {
|
|
||||||
return Version{}, fmt.Errorf("Invalid character(s) found in build meta data %q", str)
|
|
||||||
}
|
|
||||||
v.Build = append(v.Build, str)
|
|
||||||
}
|
|
||||||
|
|
||||||
return v, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// MustParse is like Parse but panics if the version cannot be parsed.
|
|
||||||
func MustParse(s string) Version {
|
|
||||||
v, err := Parse(s)
|
|
||||||
if err != nil {
|
|
||||||
panic(`semver: Parse(` + s + `): ` + err.Error())
|
|
||||||
}
|
|
||||||
return v
|
|
||||||
}
|
|
||||||
|
|
||||||
// PRVersion represents a PreRelease Version
|
|
||||||
type PRVersion struct {
|
|
||||||
VersionStr string
|
|
||||||
VersionNum uint64
|
|
||||||
IsNum bool
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewPRVersion creates a new valid prerelease version
|
|
||||||
func NewPRVersion(s string) (PRVersion, error) {
|
|
||||||
if len(s) == 0 {
|
|
||||||
return PRVersion{}, errors.New("Prerelease is empty")
|
|
||||||
}
|
|
||||||
v := PRVersion{}
|
|
||||||
if containsOnly(s, numbers) {
|
|
||||||
if hasLeadingZeroes(s) {
|
|
||||||
return PRVersion{}, fmt.Errorf("Numeric PreRelease version must not contain leading zeroes %q", s)
|
|
||||||
}
|
|
||||||
num, err := strconv.ParseUint(s, 10, 64)
|
|
||||||
|
|
||||||
// Might never be hit, but just in case
|
|
||||||
if err != nil {
|
|
||||||
return PRVersion{}, err
|
|
||||||
}
|
|
||||||
v.VersionNum = num
|
|
||||||
v.IsNum = true
|
|
||||||
} else if containsOnly(s, alphanum) {
|
|
||||||
v.VersionStr = s
|
|
||||||
v.IsNum = false
|
|
||||||
} else {
|
|
||||||
return PRVersion{}, fmt.Errorf("Invalid character(s) found in prerelease %q", s)
|
|
||||||
}
|
|
||||||
return v, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsNumeric checks if prerelease-version is numeric
|
|
||||||
func (v PRVersion) IsNumeric() bool {
|
|
||||||
return v.IsNum
|
|
||||||
}
|
|
||||||
|
|
||||||
// Compare compares two PreRelease Versions v and o:
|
|
||||||
// -1 == v is less than o
|
|
||||||
// 0 == v is equal to o
|
|
||||||
// 1 == v is greater than o
|
|
||||||
func (v PRVersion) Compare(o PRVersion) int {
|
|
||||||
if v.IsNum && !o.IsNum {
|
|
||||||
return -1
|
|
||||||
} else if !v.IsNum && o.IsNum {
|
|
||||||
return 1
|
|
||||||
} else if v.IsNum && o.IsNum {
|
|
||||||
if v.VersionNum == o.VersionNum {
|
|
||||||
return 0
|
|
||||||
} else if v.VersionNum > o.VersionNum {
|
|
||||||
return 1
|
|
||||||
} else {
|
|
||||||
return -1
|
|
||||||
}
|
|
||||||
} else { // both are Alphas
|
|
||||||
if v.VersionStr == o.VersionStr {
|
|
||||||
return 0
|
|
||||||
} else if v.VersionStr > o.VersionStr {
|
|
||||||
return 1
|
|
||||||
} else {
|
|
||||||
return -1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// PreRelease version to string
|
|
||||||
func (v PRVersion) String() string {
|
|
||||||
if v.IsNum {
|
|
||||||
return strconv.FormatUint(v.VersionNum, 10)
|
|
||||||
}
|
|
||||||
return v.VersionStr
|
|
||||||
}
|
|
||||||
|
|
||||||
func containsOnly(s string, set string) bool {
|
|
||||||
return strings.IndexFunc(s, func(r rune) bool {
|
|
||||||
return !strings.ContainsRune(set, r)
|
|
||||||
}) == -1
|
|
||||||
}
|
|
||||||
|
|
||||||
func hasLeadingZeroes(s string) bool {
|
|
||||||
return len(s) > 1 && s[0] == '0'
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewBuildVersion creates a new valid build version
|
|
||||||
func NewBuildVersion(s string) (string, error) {
|
|
||||||
if len(s) == 0 {
|
|
||||||
return "", errors.New("Buildversion is empty")
|
|
||||||
}
|
|
||||||
if !containsOnly(s, alphanum) {
|
|
||||||
return "", fmt.Errorf("Invalid character(s) found in build meta data %q", s)
|
|
||||||
}
|
|
||||||
return s, nil
|
|
||||||
}
|
|
28
vendor/github.com/blang/semver/sort.go
generated
vendored
28
vendor/github.com/blang/semver/sort.go
generated
vendored
|
@ -1,28 +0,0 @@
|
||||||
package semver
|
|
||||||
|
|
||||||
import (
|
|
||||||
"sort"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Versions represents multiple versions.
|
|
||||||
type Versions []Version
|
|
||||||
|
|
||||||
// Len returns length of version collection
|
|
||||||
func (s Versions) Len() int {
|
|
||||||
return len(s)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Swap swaps two versions inside the collection by its indices
|
|
||||||
func (s Versions) Swap(i, j int) {
|
|
||||||
s[i], s[j] = s[j], s[i]
|
|
||||||
}
|
|
||||||
|
|
||||||
// Less checks if version at index i is less than version at index j
|
|
||||||
func (s Versions) Less(i, j int) bool {
|
|
||||||
return s[i].LT(s[j])
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sort sorts a slice of versions
|
|
||||||
func Sort(versions []Version) {
|
|
||||||
sort.Sort(Versions(versions))
|
|
||||||
}
|
|
30
vendor/github.com/blang/semver/sql.go
generated
vendored
30
vendor/github.com/blang/semver/sql.go
generated
vendored
|
@ -1,30 +0,0 @@
|
||||||
package semver
|
|
||||||
|
|
||||||
import (
|
|
||||||
"database/sql/driver"
|
|
||||||
"fmt"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Scan implements the database/sql.Scanner interface.
|
|
||||||
func (v *Version) Scan(src interface{}) (err error) {
|
|
||||||
var str string
|
|
||||||
switch src := src.(type) {
|
|
||||||
case string:
|
|
||||||
str = src
|
|
||||||
case []byte:
|
|
||||||
str = string(src)
|
|
||||||
default:
|
|
||||||
return fmt.Errorf("Version.Scan: cannot convert %T to string.", src)
|
|
||||||
}
|
|
||||||
|
|
||||||
if t, err := Parse(str); err == nil {
|
|
||||||
*v = t
|
|
||||||
}
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Value implements the database/sql/driver.Valuer interface.
|
|
||||||
func (v Version) Value() (driver.Value, error) {
|
|
||||||
return v.String(), nil
|
|
||||||
}
|
|
202
vendor/github.com/kylelemons/godebug/LICENSE
generated
vendored
202
vendor/github.com/kylelemons/godebug/LICENSE
generated
vendored
|
@ -1,202 +0,0 @@
|
||||||
|
|
||||||
Apache License
|
|
||||||
Version 2.0, January 2004
|
|
||||||
http://www.apache.org/licenses/
|
|
||||||
|
|
||||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
|
||||||
|
|
||||||
1. Definitions.
|
|
||||||
|
|
||||||
"License" shall mean the terms and conditions for use, reproduction,
|
|
||||||
and distribution as defined by Sections 1 through 9 of this document.
|
|
||||||
|
|
||||||
"Licensor" shall mean the copyright owner or entity authorized by
|
|
||||||
the copyright owner that is granting the License.
|
|
||||||
|
|
||||||
"Legal Entity" shall mean the union of the acting entity and all
|
|
||||||
other entities that control, are controlled by, or are under common
|
|
||||||
control with that entity. For the purposes of this definition,
|
|
||||||
"control" means (i) the power, direct or indirect, to cause the
|
|
||||||
direction or management of such entity, whether by contract or
|
|
||||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
|
||||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
|
||||||
|
|
||||||
"You" (or "Your") shall mean an individual or Legal Entity
|
|
||||||
exercising permissions granted by this License.
|
|
||||||
|
|
||||||
"Source" form shall mean the preferred form for making modifications,
|
|
||||||
including but not limited to software source code, documentation
|
|
||||||
source, and configuration files.
|
|
||||||
|
|
||||||
"Object" form shall mean any form resulting from mechanical
|
|
||||||
transformation or translation of a Source form, including but
|
|
||||||
not limited to compiled object code, generated documentation,
|
|
||||||
and conversions to other media types.
|
|
||||||
|
|
||||||
"Work" shall mean the work of authorship, whether in Source or
|
|
||||||
Object form, made available under the License, as indicated by a
|
|
||||||
copyright notice that is included in or attached to the work
|
|
||||||
(an example is provided in the Appendix below).
|
|
||||||
|
|
||||||
"Derivative Works" shall mean any work, whether in Source or Object
|
|
||||||
form, that is based on (or derived from) the Work and for which the
|
|
||||||
editorial revisions, annotations, elaborations, or other modifications
|
|
||||||
represent, as a whole, an original work of authorship. For the purposes
|
|
||||||
of this License, Derivative Works shall not include works that remain
|
|
||||||
separable from, or merely link (or bind by name) to the interfaces of,
|
|
||||||
the Work and Derivative Works thereof.
|
|
||||||
|
|
||||||
"Contribution" shall mean any work of authorship, including
|
|
||||||
the original version of the Work and any modifications or additions
|
|
||||||
to that Work or Derivative Works thereof, that is intentionally
|
|
||||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
|
||||||
or by an individual or Legal Entity authorized to submit on behalf of
|
|
||||||
the copyright owner. For the purposes of this definition, "submitted"
|
|
||||||
means any form of electronic, verbal, or written communication sent
|
|
||||||
to the Licensor or its representatives, including but not limited to
|
|
||||||
communication on electronic mailing lists, source code control systems,
|
|
||||||
and issue tracking systems that are managed by, or on behalf of, the
|
|
||||||
Licensor for the purpose of discussing and improving the Work, but
|
|
||||||
excluding communication that is conspicuously marked or otherwise
|
|
||||||
designated in writing by the copyright owner as "Not a Contribution."
|
|
||||||
|
|
||||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
|
||||||
on behalf of whom a Contribution has been received by Licensor and
|
|
||||||
subsequently incorporated within the Work.
|
|
||||||
|
|
||||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
|
||||||
this License, each Contributor hereby grants to You a perpetual,
|
|
||||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
||||||
copyright license to reproduce, prepare Derivative Works of,
|
|
||||||
publicly display, publicly perform, sublicense, and distribute the
|
|
||||||
Work and such Derivative Works in Source or Object form.
|
|
||||||
|
|
||||||
3. Grant of Patent License. Subject to the terms and conditions of
|
|
||||||
this License, each Contributor hereby grants to You a perpetual,
|
|
||||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
||||||
(except as stated in this section) patent license to make, have made,
|
|
||||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
|
||||||
where such license applies only to those patent claims licensable
|
|
||||||
by such Contributor that are necessarily infringed by their
|
|
||||||
Contribution(s) alone or by combination of their Contribution(s)
|
|
||||||
with the Work to which such Contribution(s) was submitted. If You
|
|
||||||
institute patent litigation against any entity (including a
|
|
||||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
|
||||||
or a Contribution incorporated within the Work constitutes direct
|
|
||||||
or contributory patent infringement, then any patent licenses
|
|
||||||
granted to You under this License for that Work shall terminate
|
|
||||||
as of the date such litigation is filed.
|
|
||||||
|
|
||||||
4. Redistribution. You may reproduce and distribute copies of the
|
|
||||||
Work or Derivative Works thereof in any medium, with or without
|
|
||||||
modifications, and in Source or Object form, provided that You
|
|
||||||
meet the following conditions:
|
|
||||||
|
|
||||||
(a) You must give any other recipients of the Work or
|
|
||||||
Derivative Works a copy of this License; and
|
|
||||||
|
|
||||||
(b) You must cause any modified files to carry prominent notices
|
|
||||||
stating that You changed the files; and
|
|
||||||
|
|
||||||
(c) You must retain, in the Source form of any Derivative Works
|
|
||||||
that You distribute, all copyright, patent, trademark, and
|
|
||||||
attribution notices from the Source form of the Work,
|
|
||||||
excluding those notices that do not pertain to any part of
|
|
||||||
the Derivative Works; and
|
|
||||||
|
|
||||||
(d) If the Work includes a "NOTICE" text file as part of its
|
|
||||||
distribution, then any Derivative Works that You distribute must
|
|
||||||
include a readable copy of the attribution notices contained
|
|
||||||
within such NOTICE file, excluding those notices that do not
|
|
||||||
pertain to any part of the Derivative Works, in at least one
|
|
||||||
of the following places: within a NOTICE text file distributed
|
|
||||||
as part of the Derivative Works; within the Source form or
|
|
||||||
documentation, if provided along with the Derivative Works; or,
|
|
||||||
within a display generated by the Derivative Works, if and
|
|
||||||
wherever such third-party notices normally appear. The contents
|
|
||||||
of the NOTICE file are for informational purposes only and
|
|
||||||
do not modify the License. You may add Your own attribution
|
|
||||||
notices within Derivative Works that You distribute, alongside
|
|
||||||
or as an addendum to the NOTICE text from the Work, provided
|
|
||||||
that such additional attribution notices cannot be construed
|
|
||||||
as modifying the License.
|
|
||||||
|
|
||||||
You may add Your own copyright statement to Your modifications and
|
|
||||||
may provide additional or different license terms and conditions
|
|
||||||
for use, reproduction, or distribution of Your modifications, or
|
|
||||||
for any such Derivative Works as a whole, provided Your use,
|
|
||||||
reproduction, and distribution of the Work otherwise complies with
|
|
||||||
the conditions stated in this License.
|
|
||||||
|
|
||||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
|
||||||
any Contribution intentionally submitted for inclusion in the Work
|
|
||||||
by You to the Licensor shall be under the terms and conditions of
|
|
||||||
this License, without any additional terms or conditions.
|
|
||||||
Notwithstanding the above, nothing herein shall supersede or modify
|
|
||||||
the terms of any separate license agreement you may have executed
|
|
||||||
with Licensor regarding such Contributions.
|
|
||||||
|
|
||||||
6. Trademarks. This License does not grant permission to use the trade
|
|
||||||
names, trademarks, service marks, or product names of the Licensor,
|
|
||||||
except as required for reasonable and customary use in describing the
|
|
||||||
origin of the Work and reproducing the content of the NOTICE file.
|
|
||||||
|
|
||||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
|
||||||
agreed to in writing, Licensor provides the Work (and each
|
|
||||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
|
||||||
implied, including, without limitation, any warranties or conditions
|
|
||||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
|
||||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
|
||||||
appropriateness of using or redistributing the Work and assume any
|
|
||||||
risks associated with Your exercise of permissions under this License.
|
|
||||||
|
|
||||||
8. Limitation of Liability. In no event and under no legal theory,
|
|
||||||
whether in tort (including negligence), contract, or otherwise,
|
|
||||||
unless required by applicable law (such as deliberate and grossly
|
|
||||||
negligent acts) or agreed to in writing, shall any Contributor be
|
|
||||||
liable to You for damages, including any direct, indirect, special,
|
|
||||||
incidental, or consequential damages of any character arising as a
|
|
||||||
result of this License or out of the use or inability to use the
|
|
||||||
Work (including but not limited to damages for loss of goodwill,
|
|
||||||
work stoppage, computer failure or malfunction, or any and all
|
|
||||||
other commercial damages or losses), even if such Contributor
|
|
||||||
has been advised of the possibility of such damages.
|
|
||||||
|
|
||||||
9. Accepting Warranty or Additional Liability. While redistributing
|
|
||||||
the Work or Derivative Works thereof, You may choose to offer,
|
|
||||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
|
||||||
or other liability obligations and/or rights consistent with this
|
|
||||||
License. However, in accepting such obligations, You may act only
|
|
||||||
on Your own behalf and on Your sole responsibility, not on behalf
|
|
||||||
of any other Contributor, and only if You agree to indemnify,
|
|
||||||
defend, and hold each Contributor harmless for any liability
|
|
||||||
incurred by, or claims asserted against, such Contributor by reason
|
|
||||||
of your accepting any such warranty or additional liability.
|
|
||||||
|
|
||||||
END OF TERMS AND CONDITIONS
|
|
||||||
|
|
||||||
APPENDIX: How to apply the Apache License to your work.
|
|
||||||
|
|
||||||
To apply the Apache License to your work, attach the following
|
|
||||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
|
||||||
replaced with your own identifying information. (Don't include
|
|
||||||
the brackets!) The text should be enclosed in the appropriate
|
|
||||||
comment syntax for the file format. We also recommend that a
|
|
||||||
file or class name and description of purpose be included on the
|
|
||||||
same "printed page" as the copyright notice for easier
|
|
||||||
identification within third-party archives.
|
|
||||||
|
|
||||||
Copyright [yyyy] [name of copyright owner]
|
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
you may not use this file except in compliance with the License.
|
|
||||||
You may obtain a copy of the License at
|
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
See the License for the specific language governing permissions and
|
|
||||||
limitations under the License.
|
|
186
vendor/github.com/kylelemons/godebug/diff/diff.go
generated
vendored
186
vendor/github.com/kylelemons/godebug/diff/diff.go
generated
vendored
|
@ -1,186 +0,0 @@
|
||||||
// Copyright 2013 Google Inc. All rights reserved.
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
// Package diff implements a linewise diff algorithm.
|
|
||||||
package diff
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"fmt"
|
|
||||||
"strings"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Chunk represents a piece of the diff. A chunk will not have both added and
|
|
||||||
// deleted lines. Equal lines are always after any added or deleted lines.
|
|
||||||
// A Chunk may or may not have any lines in it, especially for the first or last
|
|
||||||
// chunk in a computation.
|
|
||||||
type Chunk struct {
|
|
||||||
Added []string
|
|
||||||
Deleted []string
|
|
||||||
Equal []string
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *Chunk) empty() bool {
|
|
||||||
return len(c.Added) == 0 && len(c.Deleted) == 0 && len(c.Equal) == 0
|
|
||||||
}
|
|
||||||
|
|
||||||
// Diff returns a string containing a line-by-line unified diff of the linewise
|
|
||||||
// changes required to make A into B. Each line is prefixed with '+', '-', or
|
|
||||||
// ' ' to indicate if it should be added, removed, or is correct respectively.
|
|
||||||
func Diff(A, B string) string {
|
|
||||||
aLines := strings.Split(A, "\n")
|
|
||||||
bLines := strings.Split(B, "\n")
|
|
||||||
|
|
||||||
chunks := DiffChunks(aLines, bLines)
|
|
||||||
|
|
||||||
buf := new(bytes.Buffer)
|
|
||||||
for _, c := range chunks {
|
|
||||||
for _, line := range c.Added {
|
|
||||||
fmt.Fprintf(buf, "+%s\n", line)
|
|
||||||
}
|
|
||||||
for _, line := range c.Deleted {
|
|
||||||
fmt.Fprintf(buf, "-%s\n", line)
|
|
||||||
}
|
|
||||||
for _, line := range c.Equal {
|
|
||||||
fmt.Fprintf(buf, " %s\n", line)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return strings.TrimRight(buf.String(), "\n")
|
|
||||||
}
|
|
||||||
|
|
||||||
// DiffChunks uses an O(D(N+M)) shortest-edit-script algorithm
|
|
||||||
// to compute the edits required from A to B and returns the
|
|
||||||
// edit chunks.
|
|
||||||
func DiffChunks(a, b []string) []Chunk {
|
|
||||||
// algorithm: http://www.xmailserver.org/diff2.pdf
|
|
||||||
|
|
||||||
// We'll need these quantities a lot.
|
|
||||||
alen, blen := len(a), len(b) // M, N
|
|
||||||
|
|
||||||
// At most, it will require len(a) deletions and len(b) additions
|
|
||||||
// to transform a into b.
|
|
||||||
maxPath := alen + blen // MAX
|
|
||||||
if maxPath == 0 {
|
|
||||||
// degenerate case: two empty lists are the same
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Store the endpoint of the path for diagonals.
|
|
||||||
// We store only the a index, because the b index on any diagonal
|
|
||||||
// (which we know during the loop below) is aidx-diag.
|
|
||||||
// endpoint[maxPath] represents the 0 diagonal.
|
|
||||||
//
|
|
||||||
// Stated differently:
|
|
||||||
// endpoint[d] contains the aidx of a furthest reaching path in diagonal d
|
|
||||||
endpoint := make([]int, 2*maxPath+1) // V
|
|
||||||
|
|
||||||
saved := make([][]int, 0, 8) // Vs
|
|
||||||
save := func() {
|
|
||||||
dup := make([]int, len(endpoint))
|
|
||||||
copy(dup, endpoint)
|
|
||||||
saved = append(saved, dup)
|
|
||||||
}
|
|
||||||
|
|
||||||
var editDistance int // D
|
|
||||||
dLoop:
|
|
||||||
for editDistance = 0; editDistance <= maxPath; editDistance++ {
|
|
||||||
// The 0 diag(onal) represents equality of a and b. Each diagonal to
|
|
||||||
// the left is numbered one lower, to the right is one higher, from
|
|
||||||
// -alen to +blen. Negative diagonals favor differences from a,
|
|
||||||
// positive diagonals favor differences from b. The edit distance to a
|
|
||||||
// diagonal d cannot be shorter than d itself.
|
|
||||||
//
|
|
||||||
// The iterations of this loop cover either odds or evens, but not both,
|
|
||||||
// If odd indices are inputs, even indices are outputs and vice versa.
|
|
||||||
for diag := -editDistance; diag <= editDistance; diag += 2 { // k
|
|
||||||
var aidx int // x
|
|
||||||
switch {
|
|
||||||
case diag == -editDistance:
|
|
||||||
// This is a new diagonal; copy from previous iter
|
|
||||||
aidx = endpoint[maxPath-editDistance+1] + 0
|
|
||||||
case diag == editDistance:
|
|
||||||
// This is a new diagonal; copy from previous iter
|
|
||||||
aidx = endpoint[maxPath+editDistance-1] + 1
|
|
||||||
case endpoint[maxPath+diag+1] > endpoint[maxPath+diag-1]:
|
|
||||||
// diagonal d+1 was farther along, so use that
|
|
||||||
aidx = endpoint[maxPath+diag+1] + 0
|
|
||||||
default:
|
|
||||||
// diagonal d-1 was farther (or the same), so use that
|
|
||||||
aidx = endpoint[maxPath+diag-1] + 1
|
|
||||||
}
|
|
||||||
// On diagonal d, we can compute bidx from aidx.
|
|
||||||
bidx := aidx - diag // y
|
|
||||||
// See how far we can go on this diagonal before we find a difference.
|
|
||||||
for aidx < alen && bidx < blen && a[aidx] == b[bidx] {
|
|
||||||
aidx++
|
|
||||||
bidx++
|
|
||||||
}
|
|
||||||
// Store the end of the current edit chain.
|
|
||||||
endpoint[maxPath+diag] = aidx
|
|
||||||
// If we've found the end of both inputs, we're done!
|
|
||||||
if aidx >= alen && bidx >= blen {
|
|
||||||
save() // save the final path
|
|
||||||
break dLoop
|
|
||||||
}
|
|
||||||
}
|
|
||||||
save() // save the current path
|
|
||||||
}
|
|
||||||
if editDistance == 0 {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
chunks := make([]Chunk, editDistance+1)
|
|
||||||
|
|
||||||
x, y := alen, blen
|
|
||||||
for d := editDistance; d > 0; d-- {
|
|
||||||
endpoint := saved[d]
|
|
||||||
diag := x - y
|
|
||||||
insert := diag == -d || (diag != d && endpoint[maxPath+diag-1] < endpoint[maxPath+diag+1])
|
|
||||||
|
|
||||||
x1 := endpoint[maxPath+diag]
|
|
||||||
var x0, xM, kk int
|
|
||||||
if insert {
|
|
||||||
kk = diag + 1
|
|
||||||
x0 = endpoint[maxPath+kk]
|
|
||||||
xM = x0
|
|
||||||
} else {
|
|
||||||
kk = diag - 1
|
|
||||||
x0 = endpoint[maxPath+kk]
|
|
||||||
xM = x0 + 1
|
|
||||||
}
|
|
||||||
y0 := x0 - kk
|
|
||||||
|
|
||||||
var c Chunk
|
|
||||||
if insert {
|
|
||||||
c.Added = b[y0:][:1]
|
|
||||||
} else {
|
|
||||||
c.Deleted = a[x0:][:1]
|
|
||||||
}
|
|
||||||
if xM < x1 {
|
|
||||||
c.Equal = a[xM:][:x1-xM]
|
|
||||||
}
|
|
||||||
|
|
||||||
x, y = x0, y0
|
|
||||||
chunks[d] = c
|
|
||||||
}
|
|
||||||
if x > 0 {
|
|
||||||
chunks[0].Equal = a[:x]
|
|
||||||
}
|
|
||||||
if chunks[0].empty() {
|
|
||||||
chunks = chunks[1:]
|
|
||||||
}
|
|
||||||
if len(chunks) == 0 {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return chunks
|
|
||||||
}
|
|
25
vendor/github.com/kylelemons/godebug/pretty/doc.go
generated
vendored
25
vendor/github.com/kylelemons/godebug/pretty/doc.go
generated
vendored
|
@ -1,25 +0,0 @@
|
||||||
// Copyright 2013 Google Inc. All rights reserved.
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
// Package pretty pretty-prints Go structures.
|
|
||||||
//
|
|
||||||
// This package uses reflection to examine a Go value and can
|
|
||||||
// print out in a nice, aligned fashion. It supports three
|
|
||||||
// modes (normal, compact, and extended) for advanced use.
|
|
||||||
//
|
|
||||||
// See the Reflect and Print examples for what the output looks like.
|
|
||||||
package pretty
|
|
||||||
|
|
||||||
// TODO:
|
|
||||||
// - Catch cycles
|
|
153
vendor/github.com/kylelemons/godebug/pretty/public.go
generated
vendored
153
vendor/github.com/kylelemons/godebug/pretty/public.go
generated
vendored
|
@ -1,153 +0,0 @@
|
||||||
// Copyright 2013 Google Inc. All rights reserved.
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
package pretty
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"fmt"
|
|
||||||
"io"
|
|
||||||
"net"
|
|
||||||
"reflect"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/kylelemons/godebug/diff"
|
|
||||||
)
|
|
||||||
|
|
||||||
// A Config represents optional configuration parameters for formatting.
|
|
||||||
//
|
|
||||||
// Some options, notably ShortList, dramatically increase the overhead
|
|
||||||
// of pretty-printing a value.
|
|
||||||
type Config struct {
|
|
||||||
// Verbosity options
|
|
||||||
Compact bool // One-line output. Overrides Diffable.
|
|
||||||
Diffable bool // Adds extra newlines for more easily diffable output.
|
|
||||||
|
|
||||||
// Field and value options
|
|
||||||
IncludeUnexported bool // Include unexported fields in output
|
|
||||||
PrintStringers bool // Call String on a fmt.Stringer
|
|
||||||
PrintTextMarshalers bool // Call MarshalText on an encoding.TextMarshaler
|
|
||||||
SkipZeroFields bool // Skip struct fields that have a zero value.
|
|
||||||
|
|
||||||
// Output transforms
|
|
||||||
ShortList int // Maximum character length for short lists if nonzero.
|
|
||||||
|
|
||||||
// Type-specific overrides
|
|
||||||
//
|
|
||||||
// Formatter maps a type to a function that will provide a one-line string
|
|
||||||
// representation of the input value. Conceptually:
|
|
||||||
// Formatter[reflect.TypeOf(v)](v) = "v as a string"
|
|
||||||
//
|
|
||||||
// Note that the first argument need not explicitly match the type, it must
|
|
||||||
// merely be callable with it.
|
|
||||||
//
|
|
||||||
// When processing an input value, if its type exists as a key in Formatter:
|
|
||||||
// 1) If the value is nil, no stringification is performed.
|
|
||||||
// This allows overriding of PrintStringers and PrintTextMarshalers.
|
|
||||||
// 2) The value will be called with the input as its only argument.
|
|
||||||
// The function must return a string as its first return value.
|
|
||||||
//
|
|
||||||
// In addition to func literals, two common values for this will be:
|
|
||||||
// fmt.Sprint (function) func Sprint(...interface{}) string
|
|
||||||
// Type.String (method) func (Type) String() string
|
|
||||||
//
|
|
||||||
// Note that neither of these work if the String method is a pointer
|
|
||||||
// method and the input will be provided as a value. In that case,
|
|
||||||
// use a function that calls .String on the formal value parameter.
|
|
||||||
Formatter map[reflect.Type]interface{}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Default Config objects
|
|
||||||
var (
|
|
||||||
// DefaultFormatter is the default set of overrides for stringification.
|
|
||||||
DefaultFormatter = map[reflect.Type]interface{}{
|
|
||||||
reflect.TypeOf(time.Time{}): fmt.Sprint,
|
|
||||||
reflect.TypeOf(net.IP{}): fmt.Sprint,
|
|
||||||
reflect.TypeOf((*error)(nil)).Elem(): fmt.Sprint,
|
|
||||||
}
|
|
||||||
|
|
||||||
// CompareConfig is the default configuration used for Compare.
|
|
||||||
CompareConfig = &Config{
|
|
||||||
Diffable: true,
|
|
||||||
IncludeUnexported: true,
|
|
||||||
Formatter: DefaultFormatter,
|
|
||||||
}
|
|
||||||
|
|
||||||
// DefaultConfig is the default configuration used for all other top-level functions.
|
|
||||||
DefaultConfig = &Config{
|
|
||||||
Formatter: DefaultFormatter,
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
func (cfg *Config) fprint(buf *bytes.Buffer, vals ...interface{}) {
|
|
||||||
for i, val := range vals {
|
|
||||||
if i > 0 {
|
|
||||||
buf.WriteByte('\n')
|
|
||||||
}
|
|
||||||
cfg.val2node(reflect.ValueOf(val)).WriteTo(buf, "", cfg)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Print writes the DefaultConfig representation of the given values to standard output.
|
|
||||||
func Print(vals ...interface{}) {
|
|
||||||
DefaultConfig.Print(vals...)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Print writes the configured presentation of the given values to standard output.
|
|
||||||
func (cfg *Config) Print(vals ...interface{}) {
|
|
||||||
fmt.Println(cfg.Sprint(vals...))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sprint returns a string representation of the given value according to the DefaultConfig.
|
|
||||||
func Sprint(vals ...interface{}) string {
|
|
||||||
return DefaultConfig.Sprint(vals...)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sprint returns a string representation of the given value according to cfg.
|
|
||||||
func (cfg *Config) Sprint(vals ...interface{}) string {
|
|
||||||
buf := new(bytes.Buffer)
|
|
||||||
cfg.fprint(buf, vals...)
|
|
||||||
return buf.String()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fprint writes the representation of the given value to the writer according to the DefaultConfig.
|
|
||||||
func Fprint(w io.Writer, vals ...interface{}) (n int64, err error) {
|
|
||||||
return DefaultConfig.Fprint(w, vals...)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fprint writes the representation of the given value to the writer according to the cfg.
|
|
||||||
func (cfg *Config) Fprint(w io.Writer, vals ...interface{}) (n int64, err error) {
|
|
||||||
buf := new(bytes.Buffer)
|
|
||||||
cfg.fprint(buf, vals...)
|
|
||||||
return buf.WriteTo(w)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Compare returns a string containing a line-by-line unified diff of the
|
|
||||||
// values in a and b, using the CompareConfig.
|
|
||||||
//
|
|
||||||
// Each line in the output is prefixed with '+', '-', or ' ' to indicate which
|
|
||||||
// side it's from. Lines from the a side are marked with '-', lines from the
|
|
||||||
// b side are marked with '+' and lines that are the same on both sides are
|
|
||||||
// marked with ' '.
|
|
||||||
func Compare(a, b interface{}) string {
|
|
||||||
return CompareConfig.Compare(a, b)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Compare returns a string containing a line-by-line unified diff of the
|
|
||||||
// values in got and want according to the cfg.
|
|
||||||
func (cfg *Config) Compare(a, b interface{}) string {
|
|
||||||
diffCfg := *cfg
|
|
||||||
diffCfg.Diffable = true
|
|
||||||
return diff.Diff(cfg.Sprint(a), cfg.Sprint(b))
|
|
||||||
}
|
|
121
vendor/github.com/kylelemons/godebug/pretty/reflect.go
generated
vendored
121
vendor/github.com/kylelemons/godebug/pretty/reflect.go
generated
vendored
|
@ -1,121 +0,0 @@
|
||||||
// Copyright 2013 Google Inc. All rights reserved.
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
package pretty
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding"
|
|
||||||
"fmt"
|
|
||||||
"reflect"
|
|
||||||
"sort"
|
|
||||||
)
|
|
||||||
|
|
||||||
func isZeroVal(val reflect.Value) bool {
|
|
||||||
if !val.CanInterface() {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
z := reflect.Zero(val.Type()).Interface()
|
|
||||||
return reflect.DeepEqual(val.Interface(), z)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *Config) val2node(val reflect.Value) node {
|
|
||||||
// TODO(kevlar): pointer tracking?
|
|
||||||
|
|
||||||
if !val.IsValid() {
|
|
||||||
return rawVal("nil")
|
|
||||||
}
|
|
||||||
|
|
||||||
if val.CanInterface() {
|
|
||||||
v := val.Interface()
|
|
||||||
if formatter, ok := c.Formatter[val.Type()]; ok {
|
|
||||||
if formatter != nil {
|
|
||||||
res := reflect.ValueOf(formatter).Call([]reflect.Value{val})
|
|
||||||
return rawVal(res[0].Interface().(string))
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if s, ok := v.(fmt.Stringer); ok && c.PrintStringers {
|
|
||||||
return stringVal(s.String())
|
|
||||||
}
|
|
||||||
if t, ok := v.(encoding.TextMarshaler); ok && c.PrintTextMarshalers {
|
|
||||||
if raw, err := t.MarshalText(); err == nil { // if NOT an error
|
|
||||||
return stringVal(string(raw))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
switch kind := val.Kind(); kind {
|
|
||||||
case reflect.Ptr, reflect.Interface:
|
|
||||||
if val.IsNil() {
|
|
||||||
return rawVal("nil")
|
|
||||||
}
|
|
||||||
return c.val2node(val.Elem())
|
|
||||||
case reflect.String:
|
|
||||||
return stringVal(val.String())
|
|
||||||
case reflect.Slice, reflect.Array:
|
|
||||||
n := list{}
|
|
||||||
length := val.Len()
|
|
||||||
for i := 0; i < length; i++ {
|
|
||||||
n = append(n, c.val2node(val.Index(i)))
|
|
||||||
}
|
|
||||||
return n
|
|
||||||
case reflect.Map:
|
|
||||||
n := keyvals{}
|
|
||||||
keys := val.MapKeys()
|
|
||||||
for _, key := range keys {
|
|
||||||
// TODO(kevlar): Support arbitrary type keys?
|
|
||||||
n = append(n, keyval{compactString(c.val2node(key)), c.val2node(val.MapIndex(key))})
|
|
||||||
}
|
|
||||||
sort.Sort(n)
|
|
||||||
return n
|
|
||||||
case reflect.Struct:
|
|
||||||
n := keyvals{}
|
|
||||||
typ := val.Type()
|
|
||||||
fields := typ.NumField()
|
|
||||||
for i := 0; i < fields; i++ {
|
|
||||||
sf := typ.Field(i)
|
|
||||||
if !c.IncludeUnexported && sf.PkgPath != "" {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
field := val.Field(i)
|
|
||||||
if c.SkipZeroFields && isZeroVal(field) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
n = append(n, keyval{sf.Name, c.val2node(field)})
|
|
||||||
}
|
|
||||||
return n
|
|
||||||
case reflect.Bool:
|
|
||||||
if val.Bool() {
|
|
||||||
return rawVal("true")
|
|
||||||
}
|
|
||||||
return rawVal("false")
|
|
||||||
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
|
||||||
return rawVal(fmt.Sprintf("%d", val.Int()))
|
|
||||||
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
|
|
||||||
return rawVal(fmt.Sprintf("%d", val.Uint()))
|
|
||||||
case reflect.Uintptr:
|
|
||||||
return rawVal(fmt.Sprintf("0x%X", val.Uint()))
|
|
||||||
case reflect.Float32, reflect.Float64:
|
|
||||||
return rawVal(fmt.Sprintf("%v", val.Float()))
|
|
||||||
case reflect.Complex64, reflect.Complex128:
|
|
||||||
return rawVal(fmt.Sprintf("%v", val.Complex()))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fall back to the default %#v if we can
|
|
||||||
if val.CanInterface() {
|
|
||||||
return rawVal(fmt.Sprintf("%#v", val.Interface()))
|
|
||||||
}
|
|
||||||
|
|
||||||
return rawVal(val.String())
|
|
||||||
}
|
|
160
vendor/github.com/kylelemons/godebug/pretty/structure.go
generated
vendored
160
vendor/github.com/kylelemons/godebug/pretty/structure.go
generated
vendored
|
@ -1,160 +0,0 @@
|
||||||
// Copyright 2013 Google Inc. All rights reserved.
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
package pretty
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
)
|
|
||||||
|
|
||||||
type node interface {
|
|
||||||
WriteTo(w *bytes.Buffer, indent string, cfg *Config)
|
|
||||||
}
|
|
||||||
|
|
||||||
func compactString(n node) string {
|
|
||||||
switch k := n.(type) {
|
|
||||||
case stringVal:
|
|
||||||
return string(k)
|
|
||||||
case rawVal:
|
|
||||||
return string(k)
|
|
||||||
}
|
|
||||||
|
|
||||||
buf := new(bytes.Buffer)
|
|
||||||
n.WriteTo(buf, "", &Config{Compact: true})
|
|
||||||
return buf.String()
|
|
||||||
}
|
|
||||||
|
|
||||||
type stringVal string
|
|
||||||
|
|
||||||
func (str stringVal) WriteTo(w *bytes.Buffer, indent string, cfg *Config) {
|
|
||||||
w.WriteString(strconv.Quote(string(str)))
|
|
||||||
}
|
|
||||||
|
|
||||||
type rawVal string
|
|
||||||
|
|
||||||
func (r rawVal) WriteTo(w *bytes.Buffer, indent string, cfg *Config) {
|
|
||||||
w.WriteString(string(r))
|
|
||||||
}
|
|
||||||
|
|
||||||
type keyval struct {
|
|
||||||
key string
|
|
||||||
val node
|
|
||||||
}
|
|
||||||
|
|
||||||
type keyvals []keyval
|
|
||||||
|
|
||||||
func (l keyvals) Len() int { return len(l) }
|
|
||||||
func (l keyvals) Swap(i, j int) { l[i], l[j] = l[j], l[i] }
|
|
||||||
func (l keyvals) Less(i, j int) bool { return l[i].key < l[j].key }
|
|
||||||
|
|
||||||
func (l keyvals) WriteTo(w *bytes.Buffer, indent string, cfg *Config) {
|
|
||||||
w.WriteByte('{')
|
|
||||||
|
|
||||||
switch {
|
|
||||||
case cfg.Compact:
|
|
||||||
// All on one line:
|
|
||||||
for i, kv := range l {
|
|
||||||
if i > 0 {
|
|
||||||
w.WriteByte(',')
|
|
||||||
}
|
|
||||||
w.WriteString(kv.key)
|
|
||||||
w.WriteByte(':')
|
|
||||||
kv.val.WriteTo(w, indent, cfg)
|
|
||||||
}
|
|
||||||
case cfg.Diffable:
|
|
||||||
w.WriteByte('\n')
|
|
||||||
inner := indent + " "
|
|
||||||
// Each value gets its own line:
|
|
||||||
for _, kv := range l {
|
|
||||||
w.WriteString(inner)
|
|
||||||
w.WriteString(kv.key)
|
|
||||||
w.WriteString(": ")
|
|
||||||
kv.val.WriteTo(w, inner, cfg)
|
|
||||||
w.WriteString(",\n")
|
|
||||||
}
|
|
||||||
w.WriteString(indent)
|
|
||||||
default:
|
|
||||||
keyWidth := 0
|
|
||||||
for _, kv := range l {
|
|
||||||
if kw := len(kv.key); kw > keyWidth {
|
|
||||||
keyWidth = kw
|
|
||||||
}
|
|
||||||
}
|
|
||||||
alignKey := indent + " "
|
|
||||||
alignValue := strings.Repeat(" ", keyWidth)
|
|
||||||
inner := alignKey + alignValue + " "
|
|
||||||
// First and last line shared with bracket:
|
|
||||||
for i, kv := range l {
|
|
||||||
if i > 0 {
|
|
||||||
w.WriteString(",\n")
|
|
||||||
w.WriteString(alignKey)
|
|
||||||
}
|
|
||||||
w.WriteString(kv.key)
|
|
||||||
w.WriteString(": ")
|
|
||||||
w.WriteString(alignValue[len(kv.key):])
|
|
||||||
kv.val.WriteTo(w, inner, cfg)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
w.WriteByte('}')
|
|
||||||
}
|
|
||||||
|
|
||||||
type list []node
|
|
||||||
|
|
||||||
func (l list) WriteTo(w *bytes.Buffer, indent string, cfg *Config) {
|
|
||||||
if max := cfg.ShortList; max > 0 {
|
|
||||||
short := compactString(l)
|
|
||||||
if len(short) <= max {
|
|
||||||
w.WriteString(short)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
w.WriteByte('[')
|
|
||||||
|
|
||||||
switch {
|
|
||||||
case cfg.Compact:
|
|
||||||
// All on one line:
|
|
||||||
for i, v := range l {
|
|
||||||
if i > 0 {
|
|
||||||
w.WriteByte(',')
|
|
||||||
}
|
|
||||||
v.WriteTo(w, indent, cfg)
|
|
||||||
}
|
|
||||||
case cfg.Diffable:
|
|
||||||
w.WriteByte('\n')
|
|
||||||
inner := indent + " "
|
|
||||||
// Each value gets its own line:
|
|
||||||
for _, v := range l {
|
|
||||||
w.WriteString(inner)
|
|
||||||
v.WriteTo(w, inner, cfg)
|
|
||||||
w.WriteString(",\n")
|
|
||||||
}
|
|
||||||
w.WriteString(indent)
|
|
||||||
default:
|
|
||||||
inner := indent + " "
|
|
||||||
// First and last line shared with bracket:
|
|
||||||
for i, v := range l {
|
|
||||||
if i > 0 {
|
|
||||||
w.WriteString(",\n")
|
|
||||||
w.WriteString(inner)
|
|
||||||
}
|
|
||||||
v.WriteTo(w, inner, cfg)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
w.WriteByte(']')
|
|
||||||
}
|
|
20
vendor/github.com/satori/go.uuid/LICENSE
generated
vendored
20
vendor/github.com/satori/go.uuid/LICENSE
generated
vendored
|
@ -1,20 +0,0 @@
|
||||||
Copyright (C) 2013-2016 by Maxim Bublis <b@codemonkey.ru>
|
|
||||||
|
|
||||||
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.
|
|
488
vendor/github.com/satori/go.uuid/uuid.go
generated
vendored
488
vendor/github.com/satori/go.uuid/uuid.go
generated
vendored
|
@ -1,488 +0,0 @@
|
||||||
// Copyright (C) 2013-2015 by Maxim Bublis <b@codemonkey.ru>
|
|
||||||
//
|
|
||||||
// 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.
|
|
||||||
|
|
||||||
// Package uuid provides implementation of Universally Unique Identifier (UUID).
|
|
||||||
// Supported versions are 1, 3, 4 and 5 (as specified in RFC 4122) and
|
|
||||||
// version 2 (as specified in DCE 1.1).
|
|
||||||
package uuid
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"crypto/md5"
|
|
||||||
"crypto/rand"
|
|
||||||
"crypto/sha1"
|
|
||||||
"database/sql/driver"
|
|
||||||
"encoding/binary"
|
|
||||||
"encoding/hex"
|
|
||||||
"fmt"
|
|
||||||
"hash"
|
|
||||||
"net"
|
|
||||||
"os"
|
|
||||||
"sync"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
// UUID layout variants.
|
|
||||||
const (
|
|
||||||
VariantNCS = iota
|
|
||||||
VariantRFC4122
|
|
||||||
VariantMicrosoft
|
|
||||||
VariantFuture
|
|
||||||
)
|
|
||||||
|
|
||||||
// UUID DCE domains.
|
|
||||||
const (
|
|
||||||
DomainPerson = iota
|
|
||||||
DomainGroup
|
|
||||||
DomainOrg
|
|
||||||
)
|
|
||||||
|
|
||||||
// Difference in 100-nanosecond intervals between
|
|
||||||
// UUID epoch (October 15, 1582) and Unix epoch (January 1, 1970).
|
|
||||||
const epochStart = 122192928000000000
|
|
||||||
|
|
||||||
// Used in string method conversion
|
|
||||||
const dash byte = '-'
|
|
||||||
|
|
||||||
// UUID v1/v2 storage.
|
|
||||||
var (
|
|
||||||
storageMutex sync.Mutex
|
|
||||||
storageOnce sync.Once
|
|
||||||
epochFunc = unixTimeFunc
|
|
||||||
clockSequence uint16
|
|
||||||
lastTime uint64
|
|
||||||
hardwareAddr [6]byte
|
|
||||||
posixUID = uint32(os.Getuid())
|
|
||||||
posixGID = uint32(os.Getgid())
|
|
||||||
)
|
|
||||||
|
|
||||||
// String parse helpers.
|
|
||||||
var (
|
|
||||||
urnPrefix = []byte("urn:uuid:")
|
|
||||||
byteGroups = []int{8, 4, 4, 4, 12}
|
|
||||||
)
|
|
||||||
|
|
||||||
func initClockSequence() {
|
|
||||||
buf := make([]byte, 2)
|
|
||||||
safeRandom(buf)
|
|
||||||
clockSequence = binary.BigEndian.Uint16(buf)
|
|
||||||
}
|
|
||||||
|
|
||||||
func initHardwareAddr() {
|
|
||||||
interfaces, err := net.Interfaces()
|
|
||||||
if err == nil {
|
|
||||||
for _, iface := range interfaces {
|
|
||||||
if len(iface.HardwareAddr) >= 6 {
|
|
||||||
copy(hardwareAddr[:], iface.HardwareAddr)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Initialize hardwareAddr randomly in case
|
|
||||||
// of real network interfaces absence
|
|
||||||
safeRandom(hardwareAddr[:])
|
|
||||||
|
|
||||||
// Set multicast bit as recommended in RFC 4122
|
|
||||||
hardwareAddr[0] |= 0x01
|
|
||||||
}
|
|
||||||
|
|
||||||
func initStorage() {
|
|
||||||
initClockSequence()
|
|
||||||
initHardwareAddr()
|
|
||||||
}
|
|
||||||
|
|
||||||
func safeRandom(dest []byte) {
|
|
||||||
if _, err := rand.Read(dest); err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Returns difference in 100-nanosecond intervals between
|
|
||||||
// UUID epoch (October 15, 1582) and current time.
|
|
||||||
// This is default epoch calculation function.
|
|
||||||
func unixTimeFunc() uint64 {
|
|
||||||
return epochStart + uint64(time.Now().UnixNano()/100)
|
|
||||||
}
|
|
||||||
|
|
||||||
// UUID representation compliant with specification
|
|
||||||
// described in RFC 4122.
|
|
||||||
type UUID [16]byte
|
|
||||||
|
|
||||||
// NullUUID can be used with the standard sql package to represent a
|
|
||||||
// UUID value that can be NULL in the database
|
|
||||||
type NullUUID struct {
|
|
||||||
UUID UUID
|
|
||||||
Valid bool
|
|
||||||
}
|
|
||||||
|
|
||||||
// The nil UUID is special form of UUID that is specified to have all
|
|
||||||
// 128 bits set to zero.
|
|
||||||
var Nil = UUID{}
|
|
||||||
|
|
||||||
// Predefined namespace UUIDs.
|
|
||||||
var (
|
|
||||||
NamespaceDNS, _ = FromString("6ba7b810-9dad-11d1-80b4-00c04fd430c8")
|
|
||||||
NamespaceURL, _ = FromString("6ba7b811-9dad-11d1-80b4-00c04fd430c8")
|
|
||||||
NamespaceOID, _ = FromString("6ba7b812-9dad-11d1-80b4-00c04fd430c8")
|
|
||||||
NamespaceX500, _ = FromString("6ba7b814-9dad-11d1-80b4-00c04fd430c8")
|
|
||||||
)
|
|
||||||
|
|
||||||
// And returns result of binary AND of two UUIDs.
|
|
||||||
func And(u1 UUID, u2 UUID) UUID {
|
|
||||||
u := UUID{}
|
|
||||||
for i := 0; i < 16; i++ {
|
|
||||||
u[i] = u1[i] & u2[i]
|
|
||||||
}
|
|
||||||
return u
|
|
||||||
}
|
|
||||||
|
|
||||||
// Or returns result of binary OR of two UUIDs.
|
|
||||||
func Or(u1 UUID, u2 UUID) UUID {
|
|
||||||
u := UUID{}
|
|
||||||
for i := 0; i < 16; i++ {
|
|
||||||
u[i] = u1[i] | u2[i]
|
|
||||||
}
|
|
||||||
return u
|
|
||||||
}
|
|
||||||
|
|
||||||
// Equal returns true if u1 and u2 equals, otherwise returns false.
|
|
||||||
func Equal(u1 UUID, u2 UUID) bool {
|
|
||||||
return bytes.Equal(u1[:], u2[:])
|
|
||||||
}
|
|
||||||
|
|
||||||
// Version returns algorithm version used to generate UUID.
|
|
||||||
func (u UUID) Version() uint {
|
|
||||||
return uint(u[6] >> 4)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Variant returns UUID layout variant.
|
|
||||||
func (u UUID) Variant() uint {
|
|
||||||
switch {
|
|
||||||
case (u[8] & 0x80) == 0x00:
|
|
||||||
return VariantNCS
|
|
||||||
case (u[8]&0xc0)|0x80 == 0x80:
|
|
||||||
return VariantRFC4122
|
|
||||||
case (u[8]&0xe0)|0xc0 == 0xc0:
|
|
||||||
return VariantMicrosoft
|
|
||||||
}
|
|
||||||
return VariantFuture
|
|
||||||
}
|
|
||||||
|
|
||||||
// Bytes returns bytes slice representation of UUID.
|
|
||||||
func (u UUID) Bytes() []byte {
|
|
||||||
return u[:]
|
|
||||||
}
|
|
||||||
|
|
||||||
// Returns canonical string representation of UUID:
|
|
||||||
// xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx.
|
|
||||||
func (u UUID) String() string {
|
|
||||||
buf := make([]byte, 36)
|
|
||||||
|
|
||||||
hex.Encode(buf[0:8], u[0:4])
|
|
||||||
buf[8] = dash
|
|
||||||
hex.Encode(buf[9:13], u[4:6])
|
|
||||||
buf[13] = dash
|
|
||||||
hex.Encode(buf[14:18], u[6:8])
|
|
||||||
buf[18] = dash
|
|
||||||
hex.Encode(buf[19:23], u[8:10])
|
|
||||||
buf[23] = dash
|
|
||||||
hex.Encode(buf[24:], u[10:])
|
|
||||||
|
|
||||||
return string(buf)
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetVersion sets version bits.
|
|
||||||
func (u *UUID) SetVersion(v byte) {
|
|
||||||
u[6] = (u[6] & 0x0f) | (v << 4)
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetVariant sets variant bits as described in RFC 4122.
|
|
||||||
func (u *UUID) SetVariant() {
|
|
||||||
u[8] = (u[8] & 0xbf) | 0x80
|
|
||||||
}
|
|
||||||
|
|
||||||
// MarshalText implements the encoding.TextMarshaler interface.
|
|
||||||
// The encoding is the same as returned by String.
|
|
||||||
func (u UUID) MarshalText() (text []byte, err error) {
|
|
||||||
text = []byte(u.String())
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// UnmarshalText implements the encoding.TextUnmarshaler interface.
|
|
||||||
// Following formats are supported:
|
|
||||||
// "6ba7b810-9dad-11d1-80b4-00c04fd430c8",
|
|
||||||
// "{6ba7b810-9dad-11d1-80b4-00c04fd430c8}",
|
|
||||||
// "urn:uuid:6ba7b810-9dad-11d1-80b4-00c04fd430c8"
|
|
||||||
func (u *UUID) UnmarshalText(text []byte) (err error) {
|
|
||||||
if len(text) < 32 {
|
|
||||||
err = fmt.Errorf("uuid: UUID string too short: %s", text)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
t := text[:]
|
|
||||||
braced := false
|
|
||||||
|
|
||||||
if bytes.Equal(t[:9], urnPrefix) {
|
|
||||||
t = t[9:]
|
|
||||||
} else if t[0] == '{' {
|
|
||||||
braced = true
|
|
||||||
t = t[1:]
|
|
||||||
}
|
|
||||||
|
|
||||||
b := u[:]
|
|
||||||
|
|
||||||
for i, byteGroup := range byteGroups {
|
|
||||||
if i > 0 && t[0] == '-' {
|
|
||||||
t = t[1:]
|
|
||||||
} else if i > 0 && t[0] != '-' {
|
|
||||||
err = fmt.Errorf("uuid: invalid string format")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if i == 2 {
|
|
||||||
if !bytes.Contains([]byte("012345"), []byte{t[0]}) {
|
|
||||||
err = fmt.Errorf("uuid: invalid version number: %s", t[0])
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(t) < byteGroup {
|
|
||||||
err = fmt.Errorf("uuid: UUID string too short: %s", text)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if i == 4 && len(t) > byteGroup &&
|
|
||||||
((braced && t[byteGroup] != '}') || len(t[byteGroup:]) > 1 || !braced) {
|
|
||||||
err = fmt.Errorf("uuid: UUID string too long: %s", t)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err = hex.Decode(b[:byteGroup/2], t[:byteGroup])
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
t = t[byteGroup:]
|
|
||||||
b = b[byteGroup/2:]
|
|
||||||
}
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// MarshalBinary implements the encoding.BinaryMarshaler interface.
|
|
||||||
func (u UUID) MarshalBinary() (data []byte, err error) {
|
|
||||||
data = u.Bytes()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// UnmarshalBinary implements the encoding.BinaryUnmarshaler interface.
|
|
||||||
// It will return error if the slice isn't 16 bytes long.
|
|
||||||
func (u *UUID) UnmarshalBinary(data []byte) (err error) {
|
|
||||||
if len(data) != 16 {
|
|
||||||
err = fmt.Errorf("uuid: UUID must be exactly 16 bytes long, got %d bytes", len(data))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
copy(u[:], data)
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Value implements the driver.Valuer interface.
|
|
||||||
func (u UUID) Value() (driver.Value, error) {
|
|
||||||
return u.String(), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Scan implements the sql.Scanner interface.
|
|
||||||
// A 16-byte slice is handled by UnmarshalBinary, while
|
|
||||||
// a longer byte slice or a string is handled by UnmarshalText.
|
|
||||||
func (u *UUID) Scan(src interface{}) error {
|
|
||||||
switch src := src.(type) {
|
|
||||||
case []byte:
|
|
||||||
if len(src) == 16 {
|
|
||||||
return u.UnmarshalBinary(src)
|
|
||||||
}
|
|
||||||
return u.UnmarshalText(src)
|
|
||||||
|
|
||||||
case string:
|
|
||||||
return u.UnmarshalText([]byte(src))
|
|
||||||
}
|
|
||||||
|
|
||||||
return fmt.Errorf("uuid: cannot convert %T to UUID", src)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Value implements the driver.Valuer interface.
|
|
||||||
func (u NullUUID) Value() (driver.Value, error) {
|
|
||||||
if !u.Valid {
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
// Delegate to UUID Value function
|
|
||||||
return u.UUID.Value()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Scan implements the sql.Scanner interface.
|
|
||||||
func (u *NullUUID) Scan(src interface{}) error {
|
|
||||||
if src == nil {
|
|
||||||
u.UUID, u.Valid = Nil, false
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Delegate to UUID Scan function
|
|
||||||
u.Valid = true
|
|
||||||
return u.UUID.Scan(src)
|
|
||||||
}
|
|
||||||
|
|
||||||
// FromBytes returns UUID converted from raw byte slice input.
|
|
||||||
// It will return error if the slice isn't 16 bytes long.
|
|
||||||
func FromBytes(input []byte) (u UUID, err error) {
|
|
||||||
err = u.UnmarshalBinary(input)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// FromBytesOrNil returns UUID converted from raw byte slice input.
|
|
||||||
// Same behavior as FromBytes, but returns a Nil UUID on error.
|
|
||||||
func FromBytesOrNil(input []byte) UUID {
|
|
||||||
uuid, err := FromBytes(input)
|
|
||||||
if err != nil {
|
|
||||||
return Nil
|
|
||||||
}
|
|
||||||
return uuid
|
|
||||||
}
|
|
||||||
|
|
||||||
// FromString returns UUID parsed from string input.
|
|
||||||
// Input is expected in a form accepted by UnmarshalText.
|
|
||||||
func FromString(input string) (u UUID, err error) {
|
|
||||||
err = u.UnmarshalText([]byte(input))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// FromStringOrNil returns UUID parsed from string input.
|
|
||||||
// Same behavior as FromString, but returns a Nil UUID on error.
|
|
||||||
func FromStringOrNil(input string) UUID {
|
|
||||||
uuid, err := FromString(input)
|
|
||||||
if err != nil {
|
|
||||||
return Nil
|
|
||||||
}
|
|
||||||
return uuid
|
|
||||||
}
|
|
||||||
|
|
||||||
// Returns UUID v1/v2 storage state.
|
|
||||||
// Returns epoch timestamp, clock sequence, and hardware address.
|
|
||||||
func getStorage() (uint64, uint16, []byte) {
|
|
||||||
storageOnce.Do(initStorage)
|
|
||||||
|
|
||||||
storageMutex.Lock()
|
|
||||||
defer storageMutex.Unlock()
|
|
||||||
|
|
||||||
timeNow := epochFunc()
|
|
||||||
// Clock changed backwards since last UUID generation.
|
|
||||||
// Should increase clock sequence.
|
|
||||||
if timeNow <= lastTime {
|
|
||||||
clockSequence++
|
|
||||||
}
|
|
||||||
lastTime = timeNow
|
|
||||||
|
|
||||||
return timeNow, clockSequence, hardwareAddr[:]
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewV1 returns UUID based on current timestamp and MAC address.
|
|
||||||
func NewV1() UUID {
|
|
||||||
u := UUID{}
|
|
||||||
|
|
||||||
timeNow, clockSeq, hardwareAddr := getStorage()
|
|
||||||
|
|
||||||
binary.BigEndian.PutUint32(u[0:], uint32(timeNow))
|
|
||||||
binary.BigEndian.PutUint16(u[4:], uint16(timeNow>>32))
|
|
||||||
binary.BigEndian.PutUint16(u[6:], uint16(timeNow>>48))
|
|
||||||
binary.BigEndian.PutUint16(u[8:], clockSeq)
|
|
||||||
|
|
||||||
copy(u[10:], hardwareAddr)
|
|
||||||
|
|
||||||
u.SetVersion(1)
|
|
||||||
u.SetVariant()
|
|
||||||
|
|
||||||
return u
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewV2 returns DCE Security UUID based on POSIX UID/GID.
|
|
||||||
func NewV2(domain byte) UUID {
|
|
||||||
u := UUID{}
|
|
||||||
|
|
||||||
timeNow, clockSeq, hardwareAddr := getStorage()
|
|
||||||
|
|
||||||
switch domain {
|
|
||||||
case DomainPerson:
|
|
||||||
binary.BigEndian.PutUint32(u[0:], posixUID)
|
|
||||||
case DomainGroup:
|
|
||||||
binary.BigEndian.PutUint32(u[0:], posixGID)
|
|
||||||
}
|
|
||||||
|
|
||||||
binary.BigEndian.PutUint16(u[4:], uint16(timeNow>>32))
|
|
||||||
binary.BigEndian.PutUint16(u[6:], uint16(timeNow>>48))
|
|
||||||
binary.BigEndian.PutUint16(u[8:], clockSeq)
|
|
||||||
u[9] = domain
|
|
||||||
|
|
||||||
copy(u[10:], hardwareAddr)
|
|
||||||
|
|
||||||
u.SetVersion(2)
|
|
||||||
u.SetVariant()
|
|
||||||
|
|
||||||
return u
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewV3 returns UUID based on MD5 hash of namespace UUID and name.
|
|
||||||
func NewV3(ns UUID, name string) UUID {
|
|
||||||
u := newFromHash(md5.New(), ns, name)
|
|
||||||
u.SetVersion(3)
|
|
||||||
u.SetVariant()
|
|
||||||
|
|
||||||
return u
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewV4 returns random generated UUID.
|
|
||||||
func NewV4() UUID {
|
|
||||||
u := UUID{}
|
|
||||||
safeRandom(u[:])
|
|
||||||
u.SetVersion(4)
|
|
||||||
u.SetVariant()
|
|
||||||
|
|
||||||
return u
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewV5 returns UUID based on SHA-1 hash of namespace UUID and name.
|
|
||||||
func NewV5(ns UUID, name string) UUID {
|
|
||||||
u := newFromHash(sha1.New(), ns, name)
|
|
||||||
u.SetVersion(5)
|
|
||||||
u.SetVariant()
|
|
||||||
|
|
||||||
return u
|
|
||||||
}
|
|
||||||
|
|
||||||
// Returns UUID based on hashing of namespace UUID and name.
|
|
||||||
func newFromHash(h hash.Hash, ns UUID, name string) UUID {
|
|
||||||
u := UUID{}
|
|
||||||
h.Write(ns[:])
|
|
||||||
h.Write([]byte(name))
|
|
||||||
copy(u[:], h.Sum(nil))
|
|
||||||
|
|
||||||
return u
|
|
||||||
}
|
|
Loading…
Reference in a new issue