From 9f831eb4de1d1edfbbee0c3cbd9ad4b032cb7d2f Mon Sep 17 00:00:00 2001 From: Manfred Touron Date: Tue, 19 Dec 2017 14:00:29 +0100 Subject: [PATCH] Bump sprig@v2.14.1 --- .../github.com/Masterminds/sprig/CHANGELOG.md | 121 ++++++++- vendor/github.com/Masterminds/sprig/crypto.go | 232 ++++++++++++++++ vendor/github.com/Masterminds/sprig/date.go | 23 ++ vendor/github.com/Masterminds/sprig/dict.go | 10 +- vendor/github.com/Masterminds/sprig/doc.go | 7 +- .../github.com/Masterminds/sprig/functions.go | 23 +- vendor/github.com/Masterminds/sprig/list.go | 248 ++++++++++++++---- .../github.com/Masterminds/sprig/numeric.go | 30 +++ vendor/github.com/Masterminds/sprig/regex.go | 35 +++ .../github.com/Masterminds/sprig/strings.go | 4 + vendor/vendor.json | 7 +- 11 files changed, 678 insertions(+), 62 deletions(-) create mode 100644 vendor/github.com/Masterminds/sprig/regex.go diff --git a/vendor/github.com/Masterminds/sprig/CHANGELOG.md b/vendor/github.com/Masterminds/sprig/CHANGELOG.md index 1caedc9..6154db8 100644 --- a/vendor/github.com/Masterminds/sprig/CHANGELOG.md +++ b/vendor/github.com/Masterminds/sprig/CHANGELOG.md @@ -1,16 +1,131 @@ -# Release 1.2.0 (2016-02-01) +# Changelog + +## Release 2.14.1 (2017-12-01) + +### Fixed + +- #60: Fix typo in function name documentation (thanks @neil-ca-moore) +- #61: Removing line with {{ due to blocking github pages genertion +- #64: Update the list functions to handle int, string, and other slices for compatibility + +## Release 2.14.0 (2017-10-06) + +This new version of Sprig adds a set of functions for generating and working with SSL certificates. + +- `genCA` generates an SSL Certificate Authority +- `genSelfSignedCert` generates an SSL self-signed certificate +- `genSignedCert` generates an SSL certificate and key based on a given CA + +## Release 2.13.0 (2017-09-18) + +This release adds new functions, including: + +- `regexMatch`, `regexFindAll`, `regexFind`, `regexReplaceAll`, `regexReplaceAllLiteral`, and `regexSplit` to work with regular expressions +- `floor`, `ceil`, and `round` math functions +- `toDate` converts a string to a date +- `nindent` is just like `indent` but also prepends a new line +- `ago` returns the time from `time.Now` + +### Added + +- #40: Added basic regex functionality (thanks @alanquillin) +- #41: Added ceil floor and round functions (thanks @alanquillin) +- #48: Added toDate function (thanks @andreynering) +- #50: Added nindent function (thanks @binoculars) +- #46: Added ago function (thanks @slayer) + +### Changed + +- #51: Updated godocs to include new string functions (thanks @curtisallen) +- #49: Added ability to merge multiple dicts (thanks @binoculars) + +## Release 2.12.0 (2017-05-17) + +- `snakecase`, `camelcase`, and `shuffle` are three new string functions +- `fail` allows you to bail out of a template render when conditions are not met + +## Release 2.11.0 (2017-05-02) + +- Added `toJson` and `toPrettyJson` +- Added `merge` +- Refactored documentation + +## Release 2.10.0 (2017-03-15) + +- Added `semver` and `semverCompare` for Semantic Versions +- `list` replaces `tuple` +- Fixed issue with `join` +- Added `first`, `last`, `intial`, `rest`, `prepend`, `append`, `toString`, `toStrings`, `sortAlpha`, `reverse`, `coalesce`, `pluck`, `pick`, `compact`, `keys`, `omit`, `uniq`, `has`, `without` + +## Release 2.9.0 (2017-02-23) + +- Added `splitList` to split a list +- Added crypto functions of `genPrivateKey` and `derivePassword` + +## Release 2.8.0 (2016-12-21) + +- Added access to several path functions (`base`, `dir`, `clean`, `ext`, and `abs`) +- Added functions for _mutating_ dictionaries (`set`, `unset`, `hasKey`) + +## Release 2.7.0 (2016-12-01) + +- Added `sha256sum` to generate a hash of an input +- Added functions to convert a numeric or string to `int`, `int64`, `float64` + +## Release 2.6.0 (2016-10-03) + +- Added a `uuidv4` template function for generating UUIDs inside of a template. + +## Release 2.5.0 (2016-08-19) + +- New `trimSuffix`, `trimPrefix`, `hasSuffix`, and `hasPrefix` functions +- New aliases have been added for a few functions that didn't follow the naming conventions (`trimAll` and `abbrevBoth`) +- `trimall` and `abbrevboth` (notice the case) are deprecated and will be removed in 3.0.0 + +## Release 2.4.0 (2016-08-16) + +- Adds two functions: `until` and `untilStep` + +## Release 2.3.0 (2016-06-21) + +- cat: Concatenate strings with whitespace separators. +- replace: Replace parts of a string: `replace " " "-" "Me First"` renders "Me-First" +- plural: Format plurals: `len "foo" | plural "one foo" "many foos"` renders "many foos" +- indent: Indent blocks of text in a way that is sensitive to "\n" characters. + +## Release 2.2.0 (2016-04-21) + +- Added a `genPrivateKey` function (Thanks @bacongobbler) + +## Release 2.1.0 (2016-03-30) + +- `default` now prints the default value when it does not receive a value down the pipeline. It is much safer now to do `{{.Foo | default "bar"}}`. +- Added accessors for "hermetic" functions. These return only functions that, when given the same input, produce the same output. + +## Release 2.0.0 (2016-03-29) + +Because we switched from `int` to `int64` as the return value for all integer math functions, the library's major version number has been incremented. + +- `min` complements `max` (formerly `biggest`) +- `empty` indicates that a value is the empty value for its type +- `tuple` creates a tuple inside of a template: `{{$t := tuple "a", "b" "c"}}` +- `dict` creates a dictionary inside of a template `{{$d := dict "key1" "val1" "key2" "val2"}}` +- Date formatters have been added for HTML dates (as used in `date` input fields) +- Integer math functions can convert from a number of types, including `string` (via `strconv.ParseInt`). + +## Release 1.2.0 (2016-02-01) - Added quote and squote - Added b32enc and b32dec - add now takes varargs - biggest now takes varargs -# Release 1.1.0 (2015-12-29) +## Release 1.1.0 (2015-12-29) - Added #4: Added contains function. strings.Contains, but with the arguments switched to simplify common pipelines. (thanks krancour) - Added Travis-CI testing support -# Release 1.0.0 (2015-12-23) +## Release 1.0.0 (2015-12-23) - Initial release diff --git a/vendor/github.com/Masterminds/sprig/crypto.go b/vendor/github.com/Masterminds/sprig/crypto.go index a935b6c..d1b4650 100644 --- a/vendor/github.com/Masterminds/sprig/crypto.go +++ b/vendor/github.com/Masterminds/sprig/crypto.go @@ -10,12 +10,16 @@ import ( "crypto/rsa" "crypto/sha256" "crypto/x509" + "crypto/x509/pkix" "encoding/asn1" "encoding/binary" "encoding/hex" "encoding/pem" + "errors" "fmt" "math/big" + "net" + "time" uuid "github.com/satori/go.uuid" "golang.org/x/crypto/scrypt" @@ -146,3 +150,231 @@ func pemBlockForKey(priv interface{}) *pem.Block { return nil } } + +type certificate struct { + Cert string + Key string +} + +func generateCertificateAuthority( + cn string, + daysValid int, +) (certificate, error) { + ca := certificate{} + + template, err := getBaseCertTemplate(cn, nil, nil, daysValid) + if err != nil { + return ca, err + } + // Override KeyUsage and IsCA + template.KeyUsage = x509.KeyUsageKeyEncipherment | + x509.KeyUsageDigitalSignature | + x509.KeyUsageCertSign + template.IsCA = true + + priv, err := rsa.GenerateKey(rand.Reader, 2048) + if err != nil { + return ca, fmt.Errorf("error generating rsa key: %s", err) + } + + ca.Cert, ca.Key, err = getCertAndKey(template, priv, template, priv) + if err != nil { + return ca, err + } + + return ca, nil +} + +func generateSelfSignedCertificate( + cn string, + ips []interface{}, + alternateDNS []interface{}, + daysValid int, +) (certificate, error) { + cert := certificate{} + + template, err := getBaseCertTemplate(cn, ips, alternateDNS, daysValid) + if err != nil { + return cert, err + } + + priv, err := rsa.GenerateKey(rand.Reader, 2048) + if err != nil { + return cert, fmt.Errorf("error generating rsa key: %s", err) + } + + cert.Cert, cert.Key, err = getCertAndKey(template, priv, template, priv) + if err != nil { + return cert, err + } + + return cert, nil +} + +func generateSignedCertificate( + cn string, + ips []interface{}, + alternateDNS []interface{}, + daysValid int, + ca certificate, +) (certificate, error) { + cert := certificate{} + + decodedSignerCert, _ := pem.Decode([]byte(ca.Cert)) + if decodedSignerCert == nil { + return cert, errors.New("unable to decode certificate") + } + signerCert, err := x509.ParseCertificate(decodedSignerCert.Bytes) + if err != nil { + return cert, fmt.Errorf( + "error parsing certificate: decodedSignerCert.Bytes: %s", + err, + ) + } + decodedSignerKey, _ := pem.Decode([]byte(ca.Key)) + if decodedSignerKey == nil { + return cert, errors.New("unable to decode key") + } + signerKey, err := x509.ParsePKCS1PrivateKey(decodedSignerKey.Bytes) + if err != nil { + return cert, fmt.Errorf( + "error parsing prive key: decodedSignerKey.Bytes: %s", + err, + ) + } + + template, err := getBaseCertTemplate(cn, ips, alternateDNS, daysValid) + if err != nil { + return cert, err + } + + priv, err := rsa.GenerateKey(rand.Reader, 2048) + if err != nil { + return cert, fmt.Errorf("error generating rsa key: %s", err) + } + + cert.Cert, cert.Key, err = getCertAndKey( + template, + priv, + signerCert, + signerKey, + ) + if err != nil { + return cert, err + } + + return cert, nil +} + +func getCertAndKey( + template *x509.Certificate, + signeeKey *rsa.PrivateKey, + parent *x509.Certificate, + signingKey *rsa.PrivateKey, +) (string, string, error) { + derBytes, err := x509.CreateCertificate( + rand.Reader, + template, + parent, + &signeeKey.PublicKey, + signingKey, + ) + if err != nil { + return "", "", fmt.Errorf("error creating certificate: %s", err) + } + + certBuffer := bytes.Buffer{} + if err := pem.Encode( + &certBuffer, + &pem.Block{Type: "CERTIFICATE", Bytes: derBytes}, + ); err != nil { + return "", "", fmt.Errorf("error pem-encoding certificate: %s", err) + } + + keyBuffer := bytes.Buffer{} + if err := pem.Encode( + &keyBuffer, + &pem.Block{ + Type: "RSA PRIVATE KEY", + Bytes: x509.MarshalPKCS1PrivateKey(signeeKey), + }, + ); err != nil { + return "", "", fmt.Errorf("error pem-encoding key: %s", err) + } + + return string(certBuffer.Bytes()), string(keyBuffer.Bytes()), nil +} + +func getBaseCertTemplate( + cn string, + ips []interface{}, + alternateDNS []interface{}, + daysValid int, +) (*x509.Certificate, error) { + ipAddresses, err := getNetIPs(ips) + if err != nil { + return nil, err + } + dnsNames, err := getAlternateDNSStrs(alternateDNS) + if err != nil { + return nil, err + } + return &x509.Certificate{ + SerialNumber: big.NewInt(1), + Subject: pkix.Name{ + CommonName: cn, + }, + IPAddresses: ipAddresses, + DNSNames: dnsNames, + NotBefore: time.Now(), + NotAfter: time.Now().Add(time.Hour * 24 * time.Duration(daysValid)), + KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature, + ExtKeyUsage: []x509.ExtKeyUsage{ + x509.ExtKeyUsageServerAuth, + x509.ExtKeyUsageClientAuth, + }, + BasicConstraintsValid: true, + }, nil +} + +func getNetIPs(ips []interface{}) ([]net.IP, error) { + if ips == nil { + return []net.IP{}, nil + } + var ipStr string + var ok bool + var netIP net.IP + netIPs := make([]net.IP, len(ips)) + for i, ip := range ips { + ipStr, ok = ip.(string) + if !ok { + return nil, fmt.Errorf("error parsing ip: %v is not a string", ip) + } + netIP = net.ParseIP(ipStr) + if netIP == nil { + return nil, fmt.Errorf("error parsing ip: %s", ipStr) + } + netIPs[i] = netIP + } + return netIPs, nil +} + +func getAlternateDNSStrs(alternateDNS []interface{}) ([]string, error) { + if alternateDNS == nil { + return []string{}, nil + } + var dnsStr string + var ok bool + alternateDNSStrs := make([]string, len(alternateDNS)) + for i, dns := range alternateDNS { + dnsStr, ok = dns.(string) + if !ok { + return nil, fmt.Errorf( + "error processing alternate dns name: %v is not a string", + dns, + ) + } + alternateDNSStrs[i] = dnsStr + } + return alternateDNSStrs, nil +} diff --git a/vendor/github.com/Masterminds/sprig/date.go b/vendor/github.com/Masterminds/sprig/date.go index dc5263f..90bde03 100644 --- a/vendor/github.com/Masterminds/sprig/date.go +++ b/vendor/github.com/Masterminds/sprig/date.go @@ -51,3 +51,26 @@ func dateModify(fmt string, date time.Time) time.Time { } return date.Add(d) } + +func dateAgo(date interface{}) string { + var t time.Time + + switch date := date.(type) { + default: + t = time.Now() + case time.Time: + t = date + case int64: + t = time.Unix(date, 0) + case int: + t = time.Unix(int64(date), 0) + } + // Drop resolution to seconds + duration := time.Since(t) / time.Second * time.Second + return duration.String() +} + +func toDate(fmt, str string) time.Time { + t, _ := time.ParseInLocation(fmt, str, time.Local) + return t +} diff --git a/vendor/github.com/Masterminds/sprig/dict.go b/vendor/github.com/Masterminds/sprig/dict.go index 46692d1..fabc736 100644 --- a/vendor/github.com/Masterminds/sprig/dict.go +++ b/vendor/github.com/Masterminds/sprig/dict.go @@ -75,10 +75,12 @@ func dict(v ...interface{}) map[string]interface{} { return dict } -func merge(dst map[string]interface{}, src map[string]interface{}) interface{} { - if err := mergo.Merge(&dst, src); err != nil { - // Swallow errors inside of a template. - return "" +func merge(dst map[string]interface{}, srcs ...map[string]interface{}) interface{} { + for _, src := range srcs { + if err := mergo.Merge(&dst, src); err != nil { + // Swallow errors inside of a template. + return "" + } } return dst } diff --git a/vendor/github.com/Masterminds/sprig/doc.go b/vendor/github.com/Masterminds/sprig/doc.go index 0eac8e2..91ba4dc 100644 --- a/vendor/github.com/Masterminds/sprig/doc.go +++ b/vendor/github.com/Masterminds/sprig/doc.go @@ -48,6 +48,10 @@ String Functions - randAlpha: Given a length, generate an alphabetic string - randAscii: Given a length, generate a random ASCII string (symbols included) - randNumeric: Given a length, generate a string of digits. + - swapcase: SwapCase swaps the case of a string using a word based algorithm. see https://godoc.org/github.com/Masterminds/goutils#SwapCase + - shuffle: Shuffle randomizes runes in a string and returns the result. It uses default random source in `math/rand` + - snakecase: convert all upper case characters in a string to underscore format. + - camelcase: convert all lower case characters behind underscores to upper case character - wrap: Force a line wrap at the given width. `wrap 80 "imagine a longer string"` - wrapWith: Wrap a line at the given length, but using 'sep' instead of a newline. `wrapWith 50, "
", $html` - contains: strings.Contains, but with the arguments switched: `contains substr str`. (This simplifies common pipelines) @@ -57,6 +61,7 @@ String Functions - squote: Wrap string(s) in double quotation marks, does not escape content. - cat: Concatenate strings, separating them by spaces. `cat $a $b $c`. - indent: Indent a string using space characters. `indent 4 "foo\nbar"` produces " foo\n bar" + - nindent: Indent a string using space characters and prepend a new line. `indent 4 "foo\nbar"` produces "\n foo\n bar" - replace: Replace an old with a new in a string: `$name | replace " " "-"` - plural: Choose singular or plural based on length: `len $fish | plural "one anchovy" "many anchovies"` - sha256sum: Generate a hex encoded sha256 hash of the input @@ -84,7 +89,7 @@ Integer Slice Functions: Conversions: - atoi: Convert a string to an integer. 0 if the integer could not be parsed. - - in64: Convert a string or another numeric type to an int64. + - int64: Convert a string or another numeric type to an int64. - int: Convert a string or another numeric type to an int. - float64: Convert a string or another numeric type to a float64. diff --git a/vendor/github.com/Masterminds/sprig/functions.go b/vendor/github.com/Masterminds/sprig/functions.go index e7b3068..c36dc55 100644 --- a/vendor/github.com/Masterminds/sprig/functions.go +++ b/vendor/github.com/Masterminds/sprig/functions.go @@ -98,6 +98,8 @@ var genericMap = map[string]interface{}{ "htmlDateInZone": htmlDateInZone, "dateInZone": dateInZone, "dateModify": dateModify, + "ago": dateAgo, + "toDate": toDate, // Strings "abbrev": abbrev, @@ -137,6 +139,7 @@ var genericMap = map[string]interface{}{ "squote": squote, "cat": cat, "indent": indent, + "nindent": nindent, "replace": replace, "plural": plural, "sha256sum": sha256sum, @@ -183,6 +186,9 @@ var genericMap = map[string]interface{}{ "biggest": max, "max": max, "min": min, + "ceil": ceil, + "floor": floor, + "round": round, // string slices. Note that we reverse the order b/c that's better // for template processing. @@ -243,11 +249,14 @@ var genericMap = map[string]interface{}{ "reverse": reverse, "uniq": uniq, "without": without, - "has": func(needle interface{}, haystack []interface{}) bool { return inList(haystack, needle) }, + "has": has, // Crypto: - "genPrivateKey": generatePrivateKey, - "derivePassword": derivePassword, + "genPrivateKey": generatePrivateKey, + "derivePassword": derivePassword, + "genCA": generateCertificateAuthority, + "genSelfSignedCert": generateSelfSignedCertificate, + "genSignedCert": generateSignedCertificate, // UUIDs: "uuidv4": uuidv4, @@ -258,4 +267,12 @@ var genericMap = map[string]interface{}{ // Flow Control: "fail": func(msg string) (string, error) { return "", errors.New(msg) }, + + // Regex + "regexMatch": regexMatch, + "regexFindAll": regexFindAll, + "regexFind": regexFind, + "regexReplaceAll": regexReplaceAll, + "regexReplaceAllLiteral": regexReplaceAllLiteral, + "regexSplit": regexSplit, } diff --git a/vendor/github.com/Masterminds/sprig/list.go b/vendor/github.com/Masterminds/sprig/list.go index 0c47b8c..1860549 100644 --- a/vendor/github.com/Masterminds/sprig/list.go +++ b/vendor/github.com/Masterminds/sprig/list.go @@ -1,50 +1,135 @@ package sprig import ( + "fmt" "reflect" "sort" ) +// Reflection is used in these functions so that slices and arrays of strings, +// ints, and other types not implementing []interface{} can be worked with. +// For example, this is useful if you need to work on the output of regexs. + func list(v ...interface{}) []interface{} { return v } -func push(list []interface{}, v interface{}) []interface{} { - return append(list, v) -} +func push(list interface{}, v interface{}) []interface{} { + tp := reflect.TypeOf(list).Kind() + switch tp { + case reflect.Slice, reflect.Array: + l2 := reflect.ValueOf(list) -func prepend(list []interface{}, v interface{}) []interface{} { - return append([]interface{}{v}, list...) -} + l := l2.Len() + nl := make([]interface{}, l) + for i := 0; i < l; i++ { + nl[i] = l2.Index(i).Interface() + } -func last(list []interface{}) interface{} { - l := len(list) - if l == 0 { - return nil + return append(nl, v) + + default: + panic(fmt.Sprintf("Cannot push on type %s", tp)) } - return list[l-1] } -func first(list []interface{}) interface{} { - if len(list) == 0 { - return nil +func prepend(list interface{}, v interface{}) []interface{} { + //return append([]interface{}{v}, list...) + + tp := reflect.TypeOf(list).Kind() + switch tp { + case reflect.Slice, reflect.Array: + l2 := reflect.ValueOf(list) + + l := l2.Len() + nl := make([]interface{}, l) + for i := 0; i < l; i++ { + nl[i] = l2.Index(i).Interface() + } + + return append([]interface{}{v}, nl...) + + default: + panic(fmt.Sprintf("Cannot prepend on type %s", tp)) } - return list[0] } -func rest(list []interface{}) []interface{} { - if len(list) == 0 { - return list +func last(list interface{}) interface{} { + tp := reflect.TypeOf(list).Kind() + switch tp { + case reflect.Slice, reflect.Array: + l2 := reflect.ValueOf(list) + + l := l2.Len() + if l == 0 { + return nil + } + + return l2.Index(l - 1).Interface() + default: + panic(fmt.Sprintf("Cannot find last on type %s", tp)) } - return list[1:] } -func initial(list []interface{}) []interface{} { - l := len(list) - if l == 0 { - return list +func first(list interface{}) interface{} { + tp := reflect.TypeOf(list).Kind() + switch tp { + case reflect.Slice, reflect.Array: + l2 := reflect.ValueOf(list) + + l := l2.Len() + if l == 0 { + return nil + } + + return l2.Index(0).Interface() + default: + panic(fmt.Sprintf("Cannot find first on type %s", tp)) + } +} + +func rest(list interface{}) []interface{} { + tp := reflect.TypeOf(list).Kind() + switch tp { + case reflect.Slice, reflect.Array: + l2 := reflect.ValueOf(list) + + l := l2.Len() + if l == 0 { + return nil + } + + nl := make([]interface{}, l-1) + for i := 1; i < l; i++ { + nl[i-1] = l2.Index(i).Interface() + } + + return nl + default: + panic(fmt.Sprintf("Cannot find rest on type %s", tp)) + } +} + +func initial(list interface{}) []interface{} { + tp := reflect.TypeOf(list).Kind() + switch tp { + case reflect.Slice, reflect.Array: + l2 := reflect.ValueOf(list) + + l := l2.Len() + if l == 0 { + return nil + } + + nl := make([]interface{}, l-1) + for i := 0; i < l-1; i++ { + nl[i] = l2.Index(i).Interface() + } + + return nl + default: + panic(fmt.Sprintf("Cannot find initial on type %s", tp)) } - return list[:l-1] } func sortAlpha(list interface{}) []string { @@ -59,34 +144,67 @@ func sortAlpha(list interface{}) []string { return []string{strval(list)} } -func reverse(v []interface{}) []interface{} { - // We do not sort in place because the incomming array should not be altered. - l := len(v) - c := make([]interface{}, l) - for i := 0; i < l; i++ { - c[l-i-1] = v[i] +func reverse(v interface{}) []interface{} { + tp := reflect.TypeOf(v).Kind() + switch tp { + case reflect.Slice, reflect.Array: + l2 := reflect.ValueOf(v) + + l := l2.Len() + // We do not sort in place because the incoming array should not be altered. + nl := make([]interface{}, l) + for i := 0; i < l; i++ { + nl[l-i-1] = l2.Index(i).Interface() + } + + return nl + default: + panic(fmt.Sprintf("Cannot find reverse on type %s", tp)) } - return c } -func compact(list []interface{}) []interface{} { - res := []interface{}{} - for _, item := range list { - if !empty(item) { - res = append(res, item) +func compact(list interface{}) []interface{} { + tp := reflect.TypeOf(list).Kind() + switch tp { + case reflect.Slice, reflect.Array: + l2 := reflect.ValueOf(list) + + l := l2.Len() + nl := []interface{}{} + var item interface{} + for i := 0; i < l; i++ { + item = l2.Index(i).Interface() + if !empty(item) { + nl = append(nl, item) + } } + + return nl + default: + panic(fmt.Sprintf("Cannot compact on type %s", tp)) } - return res } -func uniq(list []interface{}) []interface{} { - dest := []interface{}{} - for _, item := range list { - if !inList(dest, item) { - dest = append(dest, item) +func uniq(list interface{}) []interface{} { + tp := reflect.TypeOf(list).Kind() + switch tp { + case reflect.Slice, reflect.Array: + l2 := reflect.ValueOf(list) + + l := l2.Len() + dest := []interface{}{} + var item interface{} + for i := 0; i < l; i++ { + item = l2.Index(i).Interface() + if !inList(dest, item) { + dest = append(dest, item) + } } + + return dest + default: + panic(fmt.Sprintf("Cannot find uniq on type %s", tp)) } - return dest } func inList(haystack []interface{}, needle interface{}) bool { @@ -98,12 +216,44 @@ func inList(haystack []interface{}, needle interface{}) bool { return false } -func without(list []interface{}, omit ...interface{}) []interface{} { - res := []interface{}{} - for _, i := range list { - if !inList(omit, i) { - res = append(res, i) +func without(list interface{}, omit ...interface{}) []interface{} { + tp := reflect.TypeOf(list).Kind() + switch tp { + case reflect.Slice, reflect.Array: + l2 := reflect.ValueOf(list) + + l := l2.Len() + res := []interface{}{} + var item interface{} + for i := 0; i < l; i++ { + item = l2.Index(i).Interface() + if !inList(omit, item) { + res = append(res, item) + } } + + return res + default: + panic(fmt.Sprintf("Cannot find without on type %s", tp)) + } +} + +func has(needle interface{}, haystack interface{}) bool { + tp := reflect.TypeOf(haystack).Kind() + switch tp { + case reflect.Slice, reflect.Array: + l2 := reflect.ValueOf(haystack) + var item interface{} + l := l2.Len() + for i := 0; i < l; i++ { + item = l2.Index(i).Interface() + if reflect.DeepEqual(needle, item) { + return true + } + } + + return false + default: + panic(fmt.Sprintf("Cannot find has on type %s", tp)) } - return res } diff --git a/vendor/github.com/Masterminds/sprig/numeric.go b/vendor/github.com/Masterminds/sprig/numeric.go index 191e3b9..209c62e 100644 --- a/vendor/github.com/Masterminds/sprig/numeric.go +++ b/vendor/github.com/Masterminds/sprig/numeric.go @@ -127,3 +127,33 @@ func untilStep(start, stop, step int) []int { } return v } + +func floor(a interface{}) float64 { + aa := toFloat64(a) + return math.Floor(aa) +} + +func ceil(a interface{}) float64 { + aa := toFloat64(a) + return math.Ceil(aa) +} + +func round(a interface{}, p int, r_opt ...float64) float64 { + roundOn := .5 + if len(r_opt) > 0 { + roundOn = r_opt[0] + } + val := toFloat64(a) + places := toFloat64(p) + + var round float64 + pow := math.Pow(10, places) + digit := pow * val + _, div := math.Modf(digit) + if div >= roundOn { + round = math.Ceil(digit) + } else { + round = math.Floor(digit) + } + return round / pow +} \ No newline at end of file diff --git a/vendor/github.com/Masterminds/sprig/regex.go b/vendor/github.com/Masterminds/sprig/regex.go new file mode 100644 index 0000000..9fe033a --- /dev/null +++ b/vendor/github.com/Masterminds/sprig/regex.go @@ -0,0 +1,35 @@ +package sprig + +import ( + "regexp" +) + +func regexMatch(regex string, s string) bool { + match, _ := regexp.MatchString(regex, s) + return match +} + +func regexFindAll(regex string, s string, n int) []string { + r := regexp.MustCompile(regex) + return r.FindAllString(s, n) +} + +func regexFind(regex string, s string) string { + r := regexp.MustCompile(regex) + return r.FindString(s) +} + +func regexReplaceAll(regex string, s string, repl string) string { + r := regexp.MustCompile(regex) + return r.ReplaceAllString(s, repl) +} + +func regexReplaceAllLiteral(regex string, s string, repl string) string { + r := regexp.MustCompile(regex) + return r.ReplaceAllLiteralString(s, repl) +} + +func regexSplit(regex string, s string, n int) []string { + r := regexp.MustCompile(regex) + return r.Split(s, n) +} \ No newline at end of file diff --git a/vendor/github.com/Masterminds/sprig/strings.go b/vendor/github.com/Masterminds/sprig/strings.go index 69bcd98..f6afa2f 100644 --- a/vendor/github.com/Masterminds/sprig/strings.go +++ b/vendor/github.com/Masterminds/sprig/strings.go @@ -106,6 +106,10 @@ func indent(spaces int, v string) string { return pad + strings.Replace(v, "\n", "\n"+pad, -1) } +func nindent(spaces int, v string) string { + return "\n" + indent(spaces, v) +} + func replace(old, new, src string) string { return strings.Replace(src, old, new, -1) } diff --git a/vendor/vendor.json b/vendor/vendor.json index 381250d..abcb15e 100644 --- a/vendor/vendor.json +++ b/vendor/vendor.json @@ -8,9 +8,12 @@ "revision": "59c29afe1a994eacb71c833025ca7acf874bb1da" }, { - "checksumSHA1": "93uQlRcUdWLxcNPDnxAFsM4/zCI=", + "checksumSHA1": "HQ1JY9GVh1XndI1v/SLztYDVA/I=", "path": "github.com/Masterminds/sprig", - "revision": "2f4371ac162f912989f01cc2b6af4ba6660e6a30" + "revision": "b217b9c388de2cacde4354c536e520c52c055563", + "revisionTime": "2017-12-01T20:06:51Z", + "version": "v2.14.1", + "versionExact": "v2.14.1" }, { "checksumSHA1": "oLdNE7TyNIKK+ZYVPvEwhLmVb98=",