Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: Masterminds/sprig
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: v2.22.0
Choose a base ref
...
head repository: Masterminds/sprig
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: v3.0.0
Choose a head ref
Loading
Showing with 1,337 additions and 404 deletions.
  1. +5 −0 .github/ISSUE_TEMPLATE.md
  2. +3 −0 .github/PULL_REQUEST_TEMPLATE.md
  3. +2 −18 .travis.yml
  4. +28 −0 CHANGELOG.md
  5. +6 −10 Makefile
  6. +14 −1 README.md
  7. +0 −4 appveyor.yml
  8. +19 −26 crypto.go
  9. +1 −1 crypto_test.go
  10. +56 −0 date.go
  11. +13 −0 date_test.go
  12. +40 −1 defaults.go
  13. +10 −0 defaults_test.go
  14. +45 −4 dict.go
  15. +46 −5 dict_test.go
  16. +1 −1 doc.go
  17. +24 −4 docs/date.md
  18. +14 −3 docs/defaults.md
  19. +44 −4 docs/dicts.md
  20. +2 −2 docs/index.md
  21. +55 −11 docs/lists.md
  22. +12 −4 docs/math.md
  23. +11 −0 docs/network.md
  24. +1 −1 docs/os.md
  25. +5 −5 docs/paths.md
  26. +61 −34 docs/semver.md
  27. +40 −21 docs/strings.md
  28. +88 −51 functions.go
  29. +0 −17 glide.yaml
  30. +15 −0 go.mod
  31. +36 −0 go.sum
  32. +33 −0 issue_188_test.go
  33. +139 −31 list.go
  34. +154 −0 list_test.go
  35. +12 −0 network.go
  36. +18 −0 network_test.go
  37. +8 −63 numeric.go
  38. +1 −1 reflect_test.go
  39. +44 −0 regex.go
  40. +137 −0 regex_test.go
  41. +1 −1 semver.go
  42. +8 −5 strings.go
  43. +12 −0 strings_test.go
  44. +18 −18 url.go
  45. +55 −57 url_test.go
5 changes: 5 additions & 0 deletions .github/ISSUE_TEMPLATE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
Thank you for submitting an issue to sprig.

If you have a feature request than pull requests for those features are also appreciated.

Sprig is a maintained project. Triaging issue happens several times per year rather than daily or weekly.
3 changes: 3 additions & 0 deletions .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Thank you for submitting a pull request to sprig.

Sprig is a maintained project. Triaging and responding to pull requests happens several times per year rather than daily or weekly.
20 changes: 2 additions & 18 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,25 +1,9 @@
language: go

go:
- 1.9.x
- 1.10.x
- 1.11.x
- 1.12.x
- 1.13.x
- tip

# Setting sudo access to false will let Travis CI use containers rather than
# VMs to run the tests. For more details see:
# - http://docs.travis-ci.com/user/workers/container-based-infrastructure/
# - http://docs.travis-ci.com/user/workers/standard-infrastructure/
sudo: false

script:
- make setup test

notifications:
webhooks:
urls:
- https://webhooks.gitter.im/e/06e3328629952dabe3e0
on_success: change # options: [always|never|change] default: always
on_failure: always # options: [always|never|change] default: always
on_start: never # options: [always|never|change] default: always
- make test-cover
28 changes: 28 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,33 @@
# Changelog

## Release 3.0.0 (2019-10-02)

### Added

- #187: Added durationRound function (thanks @yjp20)
- #189: Added numerous template functions that return errors rather than panic (thanks @nrvnrvn)
- #193: Added toRawJson support (thanks @Dean-Coakley)
- #197: Added get support to dicts (thanks @Dean-Coakley)

### Changed

- #186: Moving dependency management to Go modules
- #186: Updated semver to v3. This has changes in the way ^ is handled
- #194: Updated documentation on merging and how it copies. Added example using deepCopy
- #196: trunc now supports negative values (thanks @Dean-Coakley)

## Release 2.22.0 (2019-10-02)

### Added

- #173: Added getHostByName function to resolve dns names to ips (thanks @fcgravalos)
- #195: Added deepCopy function for use with dicts

### Changed

- Updated merge and mergeOverwrite documentation to explain copying and how to
use deepCopy with it

## Release 2.21.0 (2019-09-18)

### Added
16 changes: 6 additions & 10 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,13 +1,9 @@

HAS_GLIDE := $(shell command -v glide;)

.PHONY: test
test:
go test -v .
@echo "==> Running tests"
GO111MODULE=on go test -v

.PHONY: setup
setup:
ifndef HAS_GLIDE
go get -u github.com/Masterminds/glide
endif
glide install
.PHONY: test-cover
test-cover:
@echo "==> Running Tests with coverage"
GO111MODULE=on go test -cover .
15 changes: 14 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# Sprig: Template functions for Go templates
# Sprig: Template functions for Go templates [![GoDoc](https://godoc.org/github.com/Masterminds/sprig?status.svg)](https://godoc.org/github.com/Masterminds/sprig) [![Go Report Card](https://goreportcard.com/badge/github.com/Masterminds/sprig)](https://goreportcard.com/report/github.com/Masterminds/sprig)

[![Stability: Sustained](https://masterminds.github.io/stability/sustained.svg)](https://masterminds.github.io/stability/sustained.html)
[![Build Status](https://travis-ci.org/Masterminds/sprig.svg?branch=master)](https://travis-ci.org/Masterminds/sprig)

@@ -11,6 +12,18 @@ It is inspired by the template functions found in
[Twig](http://twig.sensiolabs.org/documentation) and in various
JavaScript libraries, such as [underscore.js](http://underscorejs.org/).

## Package Versions

There are two active major versions of the `sprig` package.

* v3 is currently stable release series on the `master` branch. The Go API should
remain compatible with v2, the current stable version. Behavior change behind
some functions is the reason for the new major version.
* v2 is the previous stable release series. It has been more than three years since
the initial release of v2. You can read the documentation and see the code
on the [release-2](https://github.com/Masterminds/sprig/tree/release-2) branch.
Bug fixes to this major version will continue for some time.

## Usage

**Template developers**: Please use Sprig's [function documentation](http://masterminds.github.io/sprig/) for
4 changes: 0 additions & 4 deletions appveyor.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@

version: build-{build}.{branch}

clone_folder: C:\gopath\src\github.com\Masterminds\sprig
shallow_clone: true

environment:
@@ -11,13 +10,10 @@ platform:
- x64

install:
- go get -u github.com/Masterminds/glide
- set PATH=%GOPATH%\bin;%PATH%
- go version
- go env

build_script:
- glide install
- go install ./...

test_script:
45 changes: 19 additions & 26 deletions crypto.go
Original file line number Diff line number Diff line change
@@ -21,8 +21,8 @@ import (
"encoding/pem"
"errors"
"fmt"
"io"
"hash/adler32"
"io"
"math/big"
"net"
"time"
@@ -48,12 +48,12 @@ func adler32sum(input string) string {

// uuidv4 provides a safe and secure UUID v4 implementation
func uuidv4() string {
return fmt.Sprintf("%s", uuid.New())
return uuid.New().String()
}

var master_password_seed = "com.lyndir.masterpassword"
var masterPasswordSeed = "com.lyndir.masterpassword"

var password_type_templates = map[string][][]byte{
var passwordTypeTemplates = map[string][][]byte{
"maximum": {[]byte("anoxxxxxxxxxxxxxxxxx"), []byte("axxxxxxxxxxxxxxxxxno")},
"long": {[]byte("CvcvnoCvcvCvcv"), []byte("CvcvCvcvnoCvcv"), []byte("CvcvCvcvCvcvno"), []byte("CvccnoCvcvCvcv"), []byte("CvccCvcvnoCvcv"),
[]byte("CvccCvcvCvcvno"), []byte("CvcvnoCvccCvcv"), []byte("CvcvCvccnoCvcv"), []byte("CvcvCvccCvcvno"), []byte("CvcvnoCvcvCvcc"),
@@ -66,7 +66,7 @@ var password_type_templates = map[string][][]byte{
"pin": {[]byte("nnnn")},
}

var template_characters = map[byte]string{
var templateCharacters = map[byte]string{
'V': "AEIOU",
'C': "BCDFGHJKLMNPQRSTVWXYZ",
'v': "aeiou",
@@ -78,14 +78,14 @@ var template_characters = map[byte]string{
'x': "AEIOUaeiouBCDFGHJKLMNPQRSTVWXYZbcdfghjklmnpqrstvwxyz0123456789!@#$%^&*()",
}

func derivePassword(counter uint32, password_type, password, user, site string) string {
var templates = password_type_templates[password_type]
func derivePassword(counter uint32, passwordType, password, user, site string) string {
var templates = passwordTypeTemplates[passwordType]
if templates == nil {
return fmt.Sprintf("cannot find password template %s", password_type)
return fmt.Sprintf("cannot find password template %s", passwordType)
}

var buffer bytes.Buffer
buffer.WriteString(master_password_seed)
buffer.WriteString(masterPasswordSeed)
binary.Write(&buffer, binary.BigEndian, uint32(len(user)))
buffer.WriteString(user)

@@ -95,7 +95,7 @@ func derivePassword(counter uint32, password_type, password, user, site string)
return fmt.Sprintf("failed to derive password: %s", err)
}

buffer.Truncate(len(master_password_seed))
buffer.Truncate(len(masterPasswordSeed))
binary.Write(&buffer, binary.BigEndian, uint32(len(site)))
buffer.WriteString(site)
binary.Write(&buffer, binary.BigEndian, counter)
@@ -107,9 +107,9 @@ func derivePassword(counter uint32, password_type, password, user, site string)

buffer.Truncate(0)
for i, element := range temp {
pass_chars := template_characters[element]
pass_char := pass_chars[int(seed[i+1])%len(pass_chars)]
buffer.WriteByte(pass_char)
passChars := templateCharacters[element]
passChar := passChars[int(seed[i+1])%len(passChars)]
buffer.WriteByte(passChar)
}

return buffer.String()
@@ -143,6 +143,8 @@ func generatePrivateKey(typ string) string {
return string(pem.EncodeToMemory(pemBlockForKey(priv)))
}

// DSAKeyFormat stores the format for DSA keys.
// Used by pemBlockForKey
type DSAKeyFormat struct {
Version int
P, Q, G, Y, X *big.Int
@@ -237,11 +239,8 @@ func generateCertificateAuthority(
}

ca.Cert, ca.Key, err = getCertAndKey(template, priv, template, priv)
if err != nil {
return ca, err
}

return ca, nil
return ca, err
}

func generateSelfSignedCertificate(
@@ -263,11 +262,8 @@ func generateSelfSignedCertificate(
}

cert.Cert, cert.Key, err = getCertAndKey(template, priv, template, priv)
if err != nil {
return cert, err
}

return cert, nil
return cert, err
}

func generateSignedCertificate(
@@ -318,11 +314,8 @@ func generateSignedCertificate(
signerCert,
signerKey,
)
if err != nil {
return cert, err
}

return cert, nil
return cert, err
}

func getCertAndKey(
@@ -361,7 +354,7 @@ func getCertAndKey(
return "", "", fmt.Errorf("error pem-encoding key: %s", err)
}

return string(certBuffer.Bytes()), string(keyBuffer.Bytes()), nil
return certBuffer.String(), keyBuffer.String(), nil
}

func getBaseCertTemplate(
2 changes: 1 addition & 1 deletion crypto_test.go
Original file line number Diff line number Diff line change
@@ -106,7 +106,7 @@ func TestGenPrivateKey(t *testing.T) {
}
// ensure that we can base64 encode the string
tpl = `{{genPrivateKey "rsa" | b64enc}}`
out, err = runRaw(tpl, nil)
_, err = runRaw(tpl, nil)
if err != nil {
t.Error(err)
}
56 changes: 56 additions & 0 deletions date.go
Original file line number Diff line number Diff line change
@@ -55,6 +55,14 @@ func dateModify(fmt string, date time.Time) time.Time {
return date.Add(d)
}

func mustDateModify(fmt string, date time.Time) (time.Time, error) {
d, err := time.ParseDuration(fmt)
if err != nil {
return time.Time{}, err
}
return date.Add(d), nil
}

func dateAgo(date interface{}) string {
var t time.Time

@@ -73,11 +81,59 @@ func dateAgo(date interface{}) string {
return duration.String()
}

func durationRound(duration interface{}) string {
var d time.Duration
switch duration := duration.(type) {
default:
d = 0
case string:
d, _ = time.ParseDuration(duration)
case int64:
d = time.Duration(duration)
case time.Time:
d = time.Since(duration)
}

u := uint64(d)
neg := d < 0
if neg {
u = -u
}

var (
year = uint64(time.Hour) * 24 * 365
month = uint64(time.Hour) * 24 * 30
day = uint64(time.Hour) * 24
hour = uint64(time.Hour)
minute = uint64(time.Minute)
second = uint64(time.Second)
)
switch {
case u > year:
return strconv.FormatUint(u/year, 10) + "y"
case u > month:
return strconv.FormatUint(u/month, 10) + "mo"
case u > day:
return strconv.FormatUint(u/day, 10) + "d"
case u > hour:
return strconv.FormatUint(u/hour, 10) + "h"
case u > minute:
return strconv.FormatUint(u/minute, 10) + "m"
case u > second:
return strconv.FormatUint(u/second, 10) + "s"
}
return "0s"
}

func toDate(fmt, str string) time.Time {
t, _ := time.ParseInLocation(fmt, str, time.Local)
return t
}

func mustToDate(fmt, str string) (time.Time, error) {
return time.ParseInLocation(fmt, str, time.Local)
}

func unixEpoch(date time.Time) string {
return strconv.FormatInt(date.Unix(), 10)
}
13 changes: 13 additions & 0 deletions date_test.go
Original file line number Diff line number Diff line change
@@ -91,3 +91,16 @@ func TestDateInZone(t *testing.T) {
t.Error(err)
}
}

func TestDurationRound(t *testing.T) {
tpl := "{{ durationRound .Time }}"
if err := runtv(tpl, "2h", map[string]interface{}{"Time": "2h5s"}); err != nil {
t.Error(err)
}
if err := runtv(tpl, "1d", map[string]interface{}{"Time": "24h5s"}); err != nil {
t.Error(err)
}
if err := runtv(tpl, "3mo", map[string]interface{}{"Time": "2400h5s"}); err != nil {
t.Error(err)
}
}
Loading