diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index f4d2de8..5f0faa6 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -25,6 +25,17 @@ jobs: with: token: ${{ secrets.CODECOV_TOKEN }} codecov_yml_path: .github/codecov.yml + lint: + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v4 + - name: Install Task + uses: arduino/setup-task@v2 + with: + repo-token: ${{ secrets.GITHUB_TOKEN }} + - name: Lint + run: task lint compatibility: name: Backward compatibility with Sprig v3 (template output) runs-on: ubuntu-latest diff --git a/.golangci.yaml b/.golangci.yaml index 3172e53..4a3e42a 100644 --- a/.golangci.yaml +++ b/.golangci.yaml @@ -5,11 +5,12 @@ linters: - gocritic - gofumpt - misspell - - nonamedreturns - testifylint - errcheck linters-settings: + gofumpt: + module-path: github.com/go-sprout/sprout errorlint: # Check whether fmt.Errorf uses the %w verb for formatting errors. # See the https://github.com/polyfloyd/go-errorlint for caveats. diff --git a/docs/migration-from-sprig.md b/docs/migration-from-sprig.md index 61551d7..d767d18 100644 --- a/docs/migration-from-sprig.md +++ b/docs/migration-from-sprig.md @@ -262,7 +262,7 @@ Move critical operations outside of templates to maintain security. Perform cryptographic operations (listed in `crypto` package) outside of templates. {% endhint %} -All deprecated features are flagged with `//! DEPRECATED` in codebase. \ +All deprecated features are flagged with `// ! DEPRECATED` in codebase. \ A complete list will be available here when the v1 of Sprout are released. ## Conclusion diff --git a/handler.go b/handler.go index 8fdef67..c0fd154 100644 --- a/handler.go +++ b/handler.go @@ -111,7 +111,7 @@ func (dh *DefaultHandler) Build() FunctionMap { // If safe functions are enabled, wrap all functions with a safe wrapper // that logs any errors that occur during function execution. if dh.wantSafeFuncs { - var safeFuncs = make(FunctionMap) + safeFuncs := make(FunctionMap) for funcName, fn := range dh.cachedFuncsMap { safeFuncs[safeFuncName(funcName)] = dh.safeWrapper(funcName, fn) } diff --git a/registry/_example/_example.go b/registry/_example/_example.go index 9596611..3672779 100644 --- a/registry/_example/_example.go +++ b/registry/_example/_example.go @@ -16,7 +16,7 @@ func NewRegistry() *ExampleRegistry { // Uid returns the unique identifier of the registry. func (or *ExampleRegistry) Uid() string { - return "example" //! Must be unique and in camel case + return "example" // ! Must be unique and in camel case } // LinkHandler links the handler to the registry at runtime. diff --git a/registry/backward/backward.go b/registry/backward/backward.go index f349ac2..2142a15 100644 --- a/registry/backward/backward.go +++ b/registry/backward/backward.go @@ -36,7 +36,7 @@ func NewRegistry() *BackwardCompatibilityRegistry { // Uid returns the unique identifier of the registry. func (bcr *BackwardCompatibilityRegistry) Uid() string { - return "backwardCompatibilityWithSprig" //! Must be unique and in camel case + return "backwardCompatibilityWithSprig" // ! Must be unique and in camel case } // LinkHandler links the handler to the registry at runtime. diff --git a/registry/checksum/functions_test.go b/registry/checksum/functions_test.go index ba78ce5..38c7a86 100644 --- a/registry/checksum/functions_test.go +++ b/registry/checksum/functions_test.go @@ -19,7 +19,7 @@ func TestSha1Sum(t *testing.T) { soloHash := sha1.Sum([]byte("a")) multiHash := sha1.Sum([]byte("hello world")) - var tc = []pesticide.TestCase{ + tc := []pesticide.TestCase{ {Name: "TestEmptyInput", Input: `{{sha1Sum ""}}`, ExpectedOutput: hex.EncodeToString(noHash[:])}, {Name: "TestSingleByteInput", Input: `{{sha1Sum "a"}}`, ExpectedOutput: hex.EncodeToString(soloHash[:])}, {Name: "TestMultiByteInput", Input: `{{sha1Sum "hello world"}}`, ExpectedOutput: hex.EncodeToString(multiHash[:])}, @@ -32,7 +32,7 @@ func TestSha256Sum(t *testing.T) { soloHash := sha256.Sum256([]byte("a")) multiHash := sha256.Sum256([]byte("hello world")) - var tc = []pesticide.TestCase{ + tc := []pesticide.TestCase{ {Name: "TestEmptyInput", Input: `{{sha256Sum ""}}`, ExpectedOutput: hex.EncodeToString(noHash[:])}, {Name: "TestSingleByteInput", Input: `{{sha256Sum "a"}}`, ExpectedOutput: hex.EncodeToString(soloHash[:])}, {Name: "TestMultiByteInput", Input: `{{sha256Sum "hello world"}}`, ExpectedOutput: hex.EncodeToString(multiHash[:])}, @@ -45,7 +45,7 @@ func TestSha512sum(t *testing.T) { soloHash := sha512.Sum512([]byte("a")) multiHash := sha512.Sum512([]byte("hello world")) - var tc = []pesticide.TestCase{ + tc := []pesticide.TestCase{ {Name: "TestEmptyInput", Input: `{{sha512Sum ""}}`, ExpectedOutput: hex.EncodeToString(noHash[:])}, {Name: "TestSingleByteInput", Input: `{{sha512Sum "a"}}`, ExpectedOutput: hex.EncodeToString(soloHash[:])}, {Name: "TestMultiByteInput", Input: `{{sha512Sum "hello world"}}`, ExpectedOutput: hex.EncodeToString(multiHash[:])}, @@ -58,7 +58,7 @@ func TestAdler32Sum(t *testing.T) { soloHash := adler32.Checksum([]byte("a")) multiHash := adler32.Checksum([]byte("hello world")) - var tc = []pesticide.TestCase{ + tc := []pesticide.TestCase{ {Name: "TestEmptyInput", Input: `{{adler32Sum ""}}`, ExpectedOutput: fmt.Sprint(noHash)}, {Name: "TestSingleByteInput", Input: `{{adler32Sum "a"}}`, ExpectedOutput: fmt.Sprint(soloHash)}, {Name: "TestMultiByteInput", Input: `{{adler32Sum "hello world"}}`, ExpectedOutput: fmt.Sprint(multiHash)}, @@ -71,7 +71,7 @@ func TestMD5Sum(t *testing.T) { soloHash := md5.Sum([]byte("a")) multiHash := md5.Sum([]byte("hello world")) - var tc = []pesticide.TestCase{ + tc := []pesticide.TestCase{ {Name: "TestEmptyInput", Input: `{{md5Sum ""}}`, ExpectedOutput: hex.EncodeToString(noHash[:])}, {Name: "TestSingleByteInput", Input: `{{md5Sum "a"}}`, ExpectedOutput: hex.EncodeToString(soloHash[:])}, {Name: "TestMultiByteInput", Input: `{{md5Sum "hello world"}}`, ExpectedOutput: hex.EncodeToString(multiHash[:])}, diff --git a/registry/conversion/functions_test.go b/registry/conversion/functions_test.go index 527061a..7ac0117 100644 --- a/registry/conversion/functions_test.go +++ b/registry/conversion/functions_test.go @@ -9,7 +9,7 @@ import ( ) func TestToBool(t *testing.T) { - var tc = []pesticide.TestCase{ + tc := []pesticide.TestCase{ {Name: "TestBool", Input: `{{$v := toBool .V }}{{kindOf $v}}-{{$v}}`, ExpectedOutput: "bool-true", Data: map[string]any{"V": true}}, {Name: "TestInt", Input: `{{$v := toBool .V }}{{kindOf $v}}-{{$v}}`, ExpectedOutput: "bool-true", Data: map[string]any{"V": 1}}, {Name: "TestInt32", Input: `{{$v := toBool .V }}{{kindOf $v}}-{{$v}}`, ExpectedOutput: "bool-true", Data: map[string]any{"V": int32(1)}}, @@ -23,7 +23,7 @@ func TestToBool(t *testing.T) { } func TestToInt(t *testing.T) { - var tc = []pesticide.TestCase{ + tc := []pesticide.TestCase{ {Name: "TestInt", Input: `{{$v := toInt .V }}{{kindOf $v}}-{{$v}}`, ExpectedOutput: "int-1", Data: map[string]any{"V": 1}}, {Name: "TestInt32", Input: `{{$v := toInt .V }}{{kindOf $v}}-{{$v}}`, ExpectedOutput: "int-1", Data: map[string]any{"V": int32(1)}}, {Name: "TestFloat64", Input: `{{$v := toInt .V }}{{kindOf $v}}-{{$v}}`, ExpectedOutput: "int-1", Data: map[string]any{"V": float64(1.42)}}, @@ -36,7 +36,7 @@ func TestToInt(t *testing.T) { } func TestToInt64(t *testing.T) { - var tc = []pesticide.TestCase{ + tc := []pesticide.TestCase{ {Name: "TestInt", Input: `{{$v := toInt64 .V }}{{typeOf $v}}-{{$v}}`, ExpectedOutput: "int64-1", Data: map[string]any{"V": 1}}, {Name: "TestInt32", Input: `{{$v := toInt64 .V }}{{typeOf $v}}-{{$v}}`, ExpectedOutput: "int64-1", Data: map[string]any{"V": int32(1)}}, {Name: "TestFloat64", Input: `{{$v := toInt64 .V }}{{typeOf $v}}-{{$v}}`, ExpectedOutput: "int64-1", Data: map[string]any{"V": float64(1.42)}}, @@ -49,7 +49,7 @@ func TestToInt64(t *testing.T) { } func TestToUint(t *testing.T) { - var tc = []pesticide.TestCase{ + tc := []pesticide.TestCase{ {Name: "TestInt", Input: `{{$v := toUint .V }}{{kindOf $v}}-{{$v}}`, ExpectedOutput: "uint-1", Data: map[string]any{"V": 1}}, {Name: "TestInt32", Input: `{{$v := toUint .V }}{{kindOf $v}}-{{$v}}`, ExpectedOutput: "uint-1", Data: map[string]any{"V": int32(1)}}, {Name: "TestFloat64", Input: `{{$v := toUint .V }}{{kindOf $v}}-{{$v}}`, ExpectedOutput: "uint-1", Data: map[string]any{"V": float64(1.42)}}, @@ -62,7 +62,7 @@ func TestToUint(t *testing.T) { } func TestToUint64(t *testing.T) { - var tc = []pesticide.TestCase{ + tc := []pesticide.TestCase{ {Name: "TestInt", Input: `{{$v := toUint64 .V }}{{typeOf $v}}-{{$v}}`, ExpectedOutput: "uint64-1", Data: map[string]any{"V": 1}}, {Name: "TestInt32", Input: `{{$v := toUint64 .V }}{{typeOf $v}}-{{$v}}`, ExpectedOutput: "uint64-1", Data: map[string]any{"V": int32(1)}}, {Name: "TestFloat64", Input: `{{$v := toUint64 .V }}{{typeOf $v}}-{{$v}}`, ExpectedOutput: "uint64-1", Data: map[string]any{"V": float64(1.42)}}, @@ -75,7 +75,7 @@ func TestToUint64(t *testing.T) { } func TestToFloat64(t *testing.T) { - var tc = []pesticide.TestCase{ + tc := []pesticide.TestCase{ {Name: "TestInt", Input: `{{$v := toFloat64 .V }}{{typeOf $v}}-{{$v}}`, ExpectedOutput: "float64-1", Data: map[string]any{"V": 1}}, {Name: "TestInt32", Input: `{{$v := toFloat64 .V }}{{typeOf $v}}-{{$v}}`, ExpectedOutput: "float64-1", Data: map[string]any{"V": int32(1)}}, {Name: "TestFloat64", Input: `{{$v := toFloat64 .V }}{{typeOf $v}}-{{$v}}`, ExpectedOutput: "float64-1.42", Data: map[string]any{"V": float64(1.42)}}, @@ -88,7 +88,7 @@ func TestToFloat64(t *testing.T) { } func TestToOctal(t *testing.T) { - var tc = []pesticide.TestCase{ + tc := []pesticide.TestCase{ {Name: "TestInt", Input: `{{$v := toOctal .V }}{{typeOf $v}}-{{$v}}`, ExpectedOutput: "int64-511", Data: map[string]any{"V": 777}}, {Name: "TestInt32", Input: `{{$v := toOctal .V }}{{typeOf $v}}-{{$v}}`, ExpectedOutput: "int64-504", Data: map[string]any{"V": int32(770)}}, {Name: "TestString", Input: `{{$v := toOctal .V }}{{typeOf $v}}-{{$v}}`, ExpectedOutput: "int64-1", Data: map[string]any{"V": "1"}}, @@ -105,8 +105,7 @@ func (s testStringer) String() string { } func TestToString(t *testing.T) { - - var tc = []pesticide.TestCase{ + tc := []pesticide.TestCase{ {Name: "TestInt", Input: `{{$v := toString .V }}{{typeOf $v}}-{{$v}}`, ExpectedOutput: "string-1", Data: map[string]any{"V": 1}}, {Name: "TestInt32", Input: `{{$v := toString .V }}{{typeOf $v}}-{{$v}}`, ExpectedOutput: "string-1", Data: map[string]any{"V": int32(1)}}, {Name: "TestFloat64", Input: `{{$v := toString .V }}{{typeOf $v}}-{{$v}}`, ExpectedOutput: "string-1.42", Data: map[string]any{"V": float64(1.42)}}, @@ -121,7 +120,7 @@ func TestToString(t *testing.T) { } func TestToDate(t *testing.T) { - var tc = []pesticide.TestCase{ + tc := []pesticide.TestCase{ { Name: "TestDate", Input: `{{$v := toDate "2006-01-02" .V }}{{typeOf $v}}-{{$v}}`, @@ -152,7 +151,7 @@ func TestToDate(t *testing.T) { } func TestToDuration(t *testing.T) { - var tc = []pesticide.TestCase{ + tc := []pesticide.TestCase{ {Name: "TestInt", Input: `{{$v := toDuration .V }}{{typeOf $v}}-{{$v}}`, ExpectedOutput: "time.Duration-1ns", Data: map[string]any{"V": 1}}, {Name: "TestInt32", Input: `{{$v := toDuration .V }}{{typeOf $v}}-{{$v}}`, ExpectedOutput: "time.Duration-1µs", Data: map[string]any{"V": int32(1000)}}, {Name: "TestFloat64", Input: `{{$v := toDuration .V }}{{typeOf $v}}-{{$v}}`, ExpectedOutput: "time.Duration-1.00042ms", Data: map[string]any{"V": float64(1000 * 1000.42)}}, diff --git a/registry/crypto/functions.go b/registry/crypto/functions.go index ec0d0b8..2eaafd9 100644 --- a/registry/crypto/functions.go +++ b/registry/crypto/functions.go @@ -4,7 +4,7 @@ import ( "bytes" "crypto/aes" "crypto/cipher" - "crypto/dsa" + "crypto/dsa" //nolint:staticcheck "crypto/ecdsa" "crypto/ed25519" "crypto/elliptic" @@ -36,7 +36,7 @@ import ( func (ch *CryptoRegistry) Bcrypt(input string) (string, error) { hash, err := bcrypt_lib.GenerateFromPassword([]byte(input), bcrypt_lib.DefaultCost) if err != nil { - return "", fmt.Errorf("failed to encrypt string with bcrypt: %s", err) + return "", fmt.Errorf("failed to encrypt string with bcrypt: %w", err) } return string(hash), nil @@ -88,7 +88,7 @@ func (ch *CryptoRegistry) DerivePassword(counter uint32, passwordType, password, salt := buffer.Bytes() key, err := scrypt.Key([]byte(password), salt, 32768, 8, 2, 64) if err != nil { - return "", fmt.Errorf("failed to derive password: %s", err) + return "", fmt.Errorf("failed to derive password: %w", err) } buffer.Truncate(len(masterPasswordSeed)) @@ -101,7 +101,7 @@ func (ch *CryptoRegistry) DerivePassword(counter uint32, passwordType, password, seed := hmacv.Sum(nil) temp := templates[int(seed[0])%len(templates)] - buffer.Truncate(0) + buffer.Reset() for i, element := range temp { passChars := templateCharacters[element] passChar := passChars[int(seed[i+1])%len(passChars)] @@ -130,7 +130,7 @@ func (ch *CryptoRegistry) GeneratePrivateKey(typ string) (string, error) { key := new(dsa.PrivateKey) // again, good enough for government work if err = dsa.GenerateParameters(&key.Parameters, cryptorand.Reader, dsa.L2048N256); err != nil { - return "", fmt.Errorf("failed to generate dsa params: %s", err) + return "", fmt.Errorf("failed to generate dsa params: %w", err) } err = dsa.GenerateKey(key, cryptorand.Reader) priv = key @@ -143,7 +143,7 @@ func (ch *CryptoRegistry) GeneratePrivateKey(typ string) (string, error) { return "", fmt.Errorf("Unknown type %s", typ) } if err != nil { - return "", fmt.Errorf("failed to generate private key: %s", err) + return "", fmt.Errorf("failed to generate private key: %w", err) } return string(pem.EncodeToMemory(ch.pemBlockForKey(priv))), nil @@ -178,17 +178,14 @@ func (ch *CryptoRegistry) BuildCustomCertificate(b64cert string, b64key string) _, err = x509.ParseCertificate(decodedCert.Bytes) if err != nil { return crt, fmt.Errorf( - "error parsing certificate: decodedCert.Bytes: %s", + "error parsing certificate: decodedCert.Bytes: %w", err, ) } _, err = ch.parsePrivateKeyPEM(string(key)) if err != nil { - return crt, fmt.Errorf( - "error parsing private key: %s", - err, - ) + return crt, fmt.Errorf("error parsing private key: %w", err) } crt.Cert = string(cert) @@ -216,7 +213,7 @@ func (ch *CryptoRegistry) GenerateCertificateAuthority( ) (Certificate, error) { priv, err := rsa.GenerateKey(cryptorand.Reader, 2048) if err != nil { - return Certificate{}, fmt.Errorf("error generating rsa key: %s", err) + return Certificate{}, fmt.Errorf("error generating rsa key: %w", err) } return ch.generateCertificateAuthorityWithKeyInternal(cn, daysValid, priv) @@ -243,7 +240,7 @@ func (ch *CryptoRegistry) GenerateCertificateAuthorityWithPEMKey( ) (Certificate, error) { priv, err := ch.parsePrivateKeyPEM(privPEM) if err != nil { - return Certificate{}, fmt.Errorf("parsing private key: %s", err) + return Certificate{}, fmt.Errorf("parsing private key: %w", err) } return ch.generateCertificateAuthorityWithKeyInternal(cn, daysValid, priv) } @@ -271,7 +268,7 @@ func (ch *CryptoRegistry) GenerateSelfSignedCertificate( ) (Certificate, error) { priv, err := rsa.GenerateKey(cryptorand.Reader, 2048) if err != nil { - return Certificate{}, fmt.Errorf("error generating rsa key: %s", err) + return Certificate{}, fmt.Errorf("error generating rsa key: %w", err) } return ch.generateSelfSignedCertificateWithKeyInternal(cn, ips, alternateDNS, daysValid, priv) } @@ -301,7 +298,7 @@ func (ch *CryptoRegistry) GenerateSelfSignedCertificateWithPEMKey( ) (Certificate, error) { priv, err := ch.parsePrivateKeyPEM(privPEM) if err != nil { - return Certificate{}, fmt.Errorf("parsing private key: %s", err) + return Certificate{}, fmt.Errorf("parsing private key: %w", err) } return ch.generateSelfSignedCertificateWithKeyInternal(cn, ips, alternateDNS, daysValid, priv) } @@ -331,7 +328,7 @@ func (ch *CryptoRegistry) GenerateSignedCertificate( ) (Certificate, error) { priv, err := rsa.GenerateKey(cryptorand.Reader, 2048) if err != nil { - return Certificate{}, fmt.Errorf("error generating rsa key: %s", err) + return Certificate{}, fmt.Errorf("error generating rsa key: %w", err) } return ch.generateSignedCertificateWithKeyInternal(cn, ips, alternateDNS, daysValid, ca, priv) } @@ -363,7 +360,7 @@ func (ch *CryptoRegistry) GenerateSignedCertificateWithPEMKey( ) (Certificate, error) { priv, err := ch.parsePrivateKeyPEM(privPEM) if err != nil { - return Certificate{}, fmt.Errorf("parsing private key: %s", err) + return Certificate{}, fmt.Errorf("parsing private key: %w", err) } return ch.generateSignedCertificateWithKeyInternal(cn, ips, alternateDNS, daysValid, ca, priv) } diff --git a/registry/crypto/helpers.go b/registry/crypto/helpers.go index ff1ea18..09a2482 100644 --- a/registry/crypto/helpers.go +++ b/registry/crypto/helpers.go @@ -3,7 +3,7 @@ package crypto import ( "bytes" "crypto" - "crypto/dsa" + "crypto/dsa" //nolint:staticcheck "crypto/ecdsa" cryptorand "crypto/rand" "crypto/rsa" @@ -131,7 +131,7 @@ func (ch *CryptoRegistry) parsePrivateKeyPEM(pemBlock string) (crypto.PrivateKey if block.Type == "PRIVATE KEY" { priv, err := x509.ParsePKCS8PrivateKey(block.Bytes) if err != nil { - return nil, fmt.Errorf("decoding PEM as PKCS#8: %s", err) + return nil, fmt.Errorf("decoding PEM as PKCS#8: %w", err) } return priv, nil } else if !strings.HasSuffix(block.Type, " PRIVATE KEY") { @@ -142,20 +142,20 @@ func (ch *CryptoRegistry) parsePrivateKeyPEM(pemBlock string) (crypto.PrivateKey case "RSA": priv, err := x509.ParsePKCS1PrivateKey(block.Bytes) if err != nil { - return nil, fmt.Errorf("parsing RSA private key from PEM: %s", err) + return nil, fmt.Errorf("parsing RSA private key from PEM: %w", err) } return priv, nil case "EC": priv, err := x509.ParseECPrivateKey(block.Bytes) if err != nil { - return nil, fmt.Errorf("parsing EC private key from PEM: %s", err) + return nil, fmt.Errorf("parsing EC private key from PEM: %w", err) } return priv, nil case "DSA": var k DSAKeyFormat _, err := asn1.Unmarshal(block.Bytes, &k) if err != nil { - return nil, fmt.Errorf("parsing DSA private key from PEM: %s", err) + return nil, fmt.Errorf("parsing DSA private key from PEM: %w", err) } priv := &dsa.PrivateKey{ PublicKey: dsa.PublicKey{ @@ -241,14 +241,14 @@ func (ch *CryptoRegistry) generateSignedCertificateWithKeyInternal( signerCert, err := x509.ParseCertificate(decodedSignerCert.Bytes) if err != nil { return cert, fmt.Errorf( - "error parsing certificate: decodedSignerCert.Bytes: %s", + "error parsing certificate: decodedSignerCert.Bytes: %w", err, ) } signerKey, err := ch.parsePrivateKeyPEM(ca.Key) if err != nil { return cert, fmt.Errorf( - "error parsing private key: %s", + "error parsing private key: %w", err, ) } @@ -276,7 +276,7 @@ func (ch *CryptoRegistry) getCertAndKey( ) (string, string, error) { signeePubKey, err := ch.getPublicKey(signeeKey) if err != nil { - return "", "", fmt.Errorf("error retrieving public key from signee key: %s", err) + return "", "", fmt.Errorf("error retrieving public key from signee key: %w", err) } derBytes, err := x509.CreateCertificate( cryptorand.Reader, @@ -286,7 +286,7 @@ func (ch *CryptoRegistry) getCertAndKey( signingKey, ) if err != nil { - return "", "", fmt.Errorf("error creating certificate: %s", err) + return "", "", fmt.Errorf("error creating certificate: %w", err) } certBuffer := bytes.Buffer{} @@ -294,7 +294,7 @@ func (ch *CryptoRegistry) getCertAndKey( &certBuffer, &pem.Block{Type: "CERTIFICATE", Bytes: derBytes}, ); err != nil { - return "", "", fmt.Errorf("error pem-encoding certificate: %s", err) + return "", "", fmt.Errorf("error pem-encoding certificate: %w", err) } keyBuffer := bytes.Buffer{} @@ -302,7 +302,7 @@ func (ch *CryptoRegistry) getCertAndKey( &keyBuffer, ch.pemBlockForKey(signeeKey), ); err != nil { - return "", "", fmt.Errorf("error pem-encoding key: %s", err) + return "", "", fmt.Errorf("error pem-encoding key: %w", err) } return certBuffer.String(), keyBuffer.String(), nil diff --git a/registry/maps/functions.go b/registry/maps/functions.go index 68aff66..049ed06 100644 --- a/registry/maps/functions.go +++ b/registry/maps/functions.go @@ -56,11 +56,11 @@ func (mr *MapsRegistry) Dict(values ...any) map[string]any { // // {{ {"key": "value"} | get "key" }} // Output: "value" func (mr *MapsRegistry) Get(args ...any) (any, error) { - //! BACKWARDS COMPATIBILITY: deprecated in v1.0 and removed in v1.1 - //! Due to change in signature, this function still supports the old signature - //! to let users transition to the new signature. - //* Old signature: Get(map[string]any, string) - //* New signature: Get(string, map[string]any) + // ! BACKWARDS COMPATIBILITY: deprecated in v1.0 and removed in v1.1 + // ! Due to change in signature, this function still supports the old signature + // ! to let users transition to the new signature. + // * Old signature: Get(map[string]any, string) + // * New signature: Get(string, map[string]any) if len(args) != 2 { return "", deprecated.ErrArgsCount(2, len(args)) } @@ -98,11 +98,11 @@ func (mr *MapsRegistry) Get(args ...any) (any, error) { // // {{ {"key": "oldValue"} | set "key", "newValue" }} // Output: {"key": "newValue"} func (mr *MapsRegistry) Set(args ...any) (map[string]any, error) { - //! BACKWARDS COMPATIBILITY: deprecated in v1.0 and removed in v1.1 - //! Due to change in signature, this function still supports the old signature - //! to let users transition to the new signature. - //* Old signature: Set(map[string]any, string, string) - //* New signature: Set(string, any, map[string]any) + // ! BACKWARDS COMPATIBILITY: deprecated in v1.0 and removed in v1.1 + // ! Due to change in signature, this function still supports the old signature + // ! to let users transition to the new signature. + // * Old signature: Set(map[string]any, string, string) + // * New signature: Set(string, any, map[string]any) if len(args) != 3 { return nil, deprecated.ErrArgsCount(3, len(args)) } @@ -140,11 +140,11 @@ func (mr *MapsRegistry) Set(args ...any) (map[string]any, error) { // // {{ {"key": "value"} | unset "key" }} // Output: {} func (mr *MapsRegistry) Unset(args ...any) (map[string]any, error) { - //! BACKWARDS COMPATIBILITY: deprecated in v1.0 and removed in v1.1 - //! Due to change in signature, this function still supports the old signature - //! to let users transition to the new signature. - //* Old signature: Unset(map[string]any, string) - //* New signature: Unset(string, map[string]any) + // ! BACKWARDS COMPATIBILITY: deprecated in v1.0 and removed in v1.1 + // ! Due to change in signature, this function still supports the old signature + // ! to let users transition to the new signature. + // * Old signature: Unset(map[string]any, string) + // * New signature: Unset(string, map[string]any) if len(args) != 2 { return nil, deprecated.ErrArgsCount(2, len(args)) } @@ -271,11 +271,11 @@ func (mr *MapsRegistry) Pluck(key string, dicts ...map[string]any) []any { // {{ $d := dict "key1" "value1" "key2" "value2" "key3" "value3" }} // {{ $d | pick "key1" "key3" }} // Output: {"key1": "value1", "key3": "value3"} func (mr *MapsRegistry) Pick(args ...any) (map[string]any, error) { - //! BACKWARDS COMPATIBILITY: deprecated in v1.0 and removed in v1.1 - //! Due to change in signature, this function still supports the old signature - //! to let users transition to the new signature. - //* Old signature: Pick(map[string]any, ...string) - //* New signature: Pick(...string, map[string]any) + // ! BACKWARDS COMPATIBILITY: deprecated in v1.0 and removed in v1.1 + // ! Due to change in signature, this function still supports the old signature + // ! to let users transition to the new signature. + // * Old signature: Pick(map[string]any, ...string) + // * New signature: Pick(...string, map[string]any) if len(args) < 2 { return nil, deprecated.ErrArgsCount(2, len(args)) } @@ -328,11 +328,11 @@ func (mr *MapsRegistry) Pick(args ...any) (map[string]any, error) { // {{ $d := dict "key1" "value1" "key2" "value2" "key3" "value3" }} // {{ omit $d "key1" "key3" }} // Output: {"key2": "value2"} func (mr *MapsRegistry) Omit(args ...any) (map[string]any, error) { - //! BACKWARDS COMPATIBILITY: deprecated in v1.0 and removed in v1.1 - //! Due to change in signature, this function still supports the old signature - //! to let users transition to the new signature. - //* Old signature: Omit(map[string]any, ...string) - //* New signature: Omit(...string, map[string]any) + // ! BACKWARDS COMPATIBILITY: deprecated in v1.0 and removed in v1.1 + // ! Due to change in signature, this function still supports the old signature + // ! to let users transition to the new signature. + // * Old signature: Omit(map[string]any, ...string) + // * New signature: Omit(...string, map[string]any) if len(args) < 2 { return nil, deprecated.ErrArgsCount(2, len(args)) } @@ -422,11 +422,11 @@ func (mr *MapsRegistry) Dig(args ...any) (any, error) { // // {{ {"key": "value"} | hasKey "key" }} // Output: true func (mr *MapsRegistry) HasKey(args ...any) (bool, error) { - //! BACKWARDS COMPATIBILITY: deprecated in v1.0 and removed in v1.1 - //! Due to change in signature, this function still supports the old signature - //! to let users transition to the new signature. - //* Old signature: HasKey(dict map[string]any, key string) - //* New signature: HasKey(key string, map[string]any) + // ! BACKWARDS COMPATIBILITY: deprecated in v1.0 and removed in v1.1 + // ! Due to change in signature, this function still supports the old signature + // ! to let users transition to the new signature. + // * Old signature: HasKey(dict map[string]any, key string) + // * New signature: HasKey(key string, map[string]any) if len(args) != 2 { return false, deprecated.ErrArgsCount(2, len(args)) } diff --git a/registry/maps/functions_test.go b/registry/maps/functions_test.go index 00a45fe..34a4002 100644 --- a/registry/maps/functions_test.go +++ b/registry/maps/functions_test.go @@ -8,7 +8,7 @@ import ( ) func TestDict(t *testing.T) { - var tc = []pesticide.TestCase{ + tc := []pesticide.TestCase{ {Name: "TestEmpty", Input: `{{dict}}`, ExpectedOutput: "map[]"}, {Name: "TestWithEvenKeyPair", Input: `{{dict "a" 1 "b" 2}}`, ExpectedOutput: "map[a:1 b:2]"}, {Name: "TestWithOddKeyPair", Input: `{{dict "a" 1 "b" 2 "c" 3 "d"}}`, ExpectedOutput: "map[a:1 b:2 c:3 d:]"}, @@ -19,7 +19,7 @@ func TestDict(t *testing.T) { } func TestGet(t *testing.T) { - var tc = []pesticide.TestCase{ + tc := []pesticide.TestCase{ {Name: "TestEmpty", Input: `{{get "a" . }}`, ExpectedOutput: ""}, {Name: "TestWithKey", Input: `{{get "a" . }}`, ExpectedOutput: "1", Data: map[string]any{"a": 1}}, {Name: "TestWithNestedKeyNotFound", Input: `{{get "b" . }}`, ExpectedOutput: "", Data: map[string]any{"a": 1}}, @@ -29,7 +29,7 @@ func TestGet(t *testing.T) { } func TestSet(t *testing.T) { - var tc = []pesticide.TestCase{ + tc := []pesticide.TestCase{ {Name: "TestWithKey", Input: `{{$d := set "a" 2 .}}{{$d}}`, ExpectedOutput: "map[a:2]", Data: map[string]any{"a": 1}}, {Name: "TestWithNewKey", Input: `{{$d := set "b" 3 .}}{{$d}}`, ExpectedOutput: "map[a:1 b:3]", Data: map[string]any{"a": 1}}, {Name: "TestWithNilValue", Input: `{{$d := .V | set "a" .Nil}}{{$d}}`, ExpectedOutput: "map[a:]", Data: map[string]any{"V": map[string]any{"a": 1}, "Nil": nil}}, @@ -39,7 +39,7 @@ func TestSet(t *testing.T) { } func TestUnset(t *testing.T) { - var tc = []pesticide.TestCase{ + tc := []pesticide.TestCase{ {Name: "TestWithKey", Input: `{{$d := unset "a" . }}{{$d}}`, ExpectedOutput: "map[]", Data: map[string]any{"a": 1}}, {Name: "TestWithNestedKeyNotFound", Input: `{{$d := unset "b" . }}{{$d}}`, ExpectedOutput: "map[a:1]", Data: map[string]any{"a": 1}}, } @@ -48,7 +48,7 @@ func TestUnset(t *testing.T) { } func TestKeys(t *testing.T) { - var tc = []pesticide.TestCase{ + tc := []pesticide.TestCase{ {Name: "TestEmpty", Input: `{{keys .}}`, ExpectedOutput: "[]"}, {Name: "TestWithKeys", Input: `{{keys . | sortAlpha}}`, ExpectedOutput: `[a b]`, Data: map[string]any{"a": 1, "b": 2}}, {Name: "TestWithMultiplesMaps", Input: `{{keys .A .B | sortAlpha}}`, ExpectedOutput: `[a b c d]`, Data: map[string]any{"A": map[string]any{"a": 1, "b": 2}, "B": map[string]any{"c": 3, "d": 4}}}, @@ -58,7 +58,7 @@ func TestKeys(t *testing.T) { } func TestValues(t *testing.T) { - var tc = []pesticide.TestCase{ + tc := []pesticide.TestCase{ {Name: "TestEmpty", Input: `{{values .}}`, ExpectedOutput: "[]"}, {Name: "TestWithValues", Input: `{{values . | sortAlpha}}`, ExpectedOutput: "[1 foo]", Data: map[string]any{"a": 1, "b": "foo"}}, } @@ -67,7 +67,7 @@ func TestValues(t *testing.T) { } func TestPluck(t *testing.T) { - var tc = []pesticide.TestCase{ + tc := []pesticide.TestCase{ {Name: "TestEmpty", Input: `{{pluck "a" .}}`, ExpectedOutput: "[]"}, {Name: "TestWithOneMap", Input: `{{. | pluck "a"}}`, ExpectedOutput: "[1]", Data: map[string]any{"a": 1, "b": 2}}, {Name: "TestWithTwoMaps", Input: `{{pluck "a" .A .B }}`, ExpectedOutput: "[1 3]", Data: map[string]any{"A": map[string]any{"a": 1, "b": 2}, "B": map[string]any{"a": 3, "b": 4}}}, @@ -77,7 +77,7 @@ func TestPluck(t *testing.T) { } func TestPick(t *testing.T) { - var tc = []pesticide.TestCase{ + tc := []pesticide.TestCase{ {Name: "TestEmpty", Input: `{{ . | pick "a"}}`, ExpectedOutput: "map[]"}, {Name: "TestWithOneValue", Input: `{{ . | pick "a"}}`, ExpectedOutput: "map[a:1]", Data: map[string]any{"a": 1, "b": 2}}, {Name: "TestWithTwoValues", Input: `{{ . | pick "a" "b"}}`, ExpectedOutput: "map[a:1 b:2]", Data: map[string]any{"a": 1, "b": 2}}, @@ -89,7 +89,7 @@ func TestPick(t *testing.T) { } func TestOmit(t *testing.T) { - var tc = []pesticide.TestCase{ + tc := []pesticide.TestCase{ {Name: "TestEmpty", Input: `{{ . | omit "a"}}`, ExpectedOutput: "map[]"}, {Name: "TestWithOneValue", Input: `{{ . | omit "a"}}`, ExpectedOutput: "map[b:2]", Data: map[string]any{"a": 1, "b": 2}}, {Name: "TestWithTwoValues", Input: `{{ . | omit "a" "b"}}`, ExpectedOutput: "map[]", Data: map[string]any{"a": 1, "b": 2}}, @@ -103,7 +103,7 @@ func TestOmit(t *testing.T) { } func TestDig(t *testing.T) { - var tc = []pesticide.TestCase{ + tc := []pesticide.TestCase{ {Name: "TestEmpty", Input: `{{dig "a" .}}`, ExpectedOutput: ""}, {Name: "TestWithOneValue", Input: `{{dig "a" .}}`, ExpectedOutput: "1", Data: map[string]any{"a": 1, "b": 2}}, {Name: "TestWithNestedKey", Input: `{{dig "a" "b" .}}`, ExpectedOutput: "2", Data: map[string]any{"a": map[string]any{"b": 2}}}, @@ -119,7 +119,7 @@ func TestDig(t *testing.T) { } func TestHasKey(t *testing.T) { - var tc = []pesticide.TestCase{ + tc := []pesticide.TestCase{ {Name: "TestEmpty", Input: `{{. | hasKey "a"}}`, ExpectedOutput: "false"}, {Name: "TestWithKey", Input: `{{. | hasKey "a"}}`, ExpectedOutput: "true", Data: map[string]any{"a": 1}}, {Name: "TestWithNestedKeyNotFound", Input: `{{. | hasKey "b"}}`, ExpectedOutput: "false", Data: map[string]any{"a": 1}}, @@ -131,7 +131,7 @@ func TestHasKey(t *testing.T) { func TestMerge(t *testing.T) { var dest map[string]any - var tc = []pesticide.TestCase{ + tc := []pesticide.TestCase{ {Name: "TestEmpty", Input: `{{merge .}}`, ExpectedOutput: "map[]"}, {Name: "TestWithOneMap", Input: `{{merge .}}`, ExpectedOutput: "map[a:1 b:2]", Data: map[string]any{"a": 1, "b": 2}}, {Name: "TestWithTwoMaps", Input: `{{merge .Dest .Src1}}`, ExpectedOutput: "map[a:1 b:2 c:3 d:4]", Data: map[string]any{"Dest": map[string]any{"a": 1, "b": 2}, "Src1": map[string]any{"c": 3, "d": 4}}}, @@ -147,7 +147,7 @@ func TestMerge(t *testing.T) { func TestMergeOverwrite(t *testing.T) { var dest map[string]any - var tc = []pesticide.TestCase{ + tc := []pesticide.TestCase{ {Name: "TestEmpty", Input: `{{mergeOverwrite .}}`, ExpectedOutput: "map[]"}, {Name: "TestWithOneMap", Input: `{{mergeOverwrite .}}`, ExpectedOutput: "map[a:1 b:2]", Data: map[string]any{"a": 1, "b": 2}}, {Name: "TestWithTwoMaps", Input: `{{mergeOverwrite .Dest .Src1}}`, ExpectedOutput: "map[a:1 b:2 c:3 d:4]", Data: map[string]any{"Dest": map[string]any{"a": 1, "b": 2}, "Src1": map[string]any{"c": 3, "d": 4}}}, diff --git a/registry/numeric/functions.go b/registry/numeric/functions.go index 837b18c..b6292fa 100644 --- a/registry/numeric/functions.go +++ b/registry/numeric/functions.go @@ -226,7 +226,7 @@ func (nr *NumericRegistry) DivInt(values ...any) (int64, error) { // // {{ 30.0, 3.0, 2.0 | divf }} // Output: 5.0 func (nr *NumericRegistry) Divf(values ...any) (any, error) { - //FIXME: Special manipulation to force float operation + // FIXME: Special manipulation to force float operation // This is a workaround to ensure that the result is a float to allow // BACKWARDS COMPATIBILITY with previous versions of Sprig. if len(values) > 0 { diff --git a/registry/random/random.go b/registry/random/random.go index 10e4ec6..7b2aa03 100644 --- a/registry/random/random.go +++ b/registry/random/random.go @@ -1,11 +1,6 @@ package random import ( - cryptorand "crypto/rand" - "math/big" - mathrand "math/rand" - "time" - "github.com/go-sprout/sprout" ) @@ -38,20 +33,6 @@ type randomOpts struct { withChars []rune } -// randSource is a global variable that provides a source of randomness seeded with -// a cryptographically secure random number. This source is used throughout various -// random generation functions to ensure that randomness is both fast and non-repetitive. -var randSource mathrand.Source - -// init is an initialization function that seeds the global random source used -// in random string generation. It retrieves a secure timestamp-based seed from -// crypto/rand and uses it to initialize math/rand's source, ensuring that random -// values are not predictable across program restarts. -func init() { - index, _ := cryptorand.Int(cryptorand.Reader, big.NewInt(time.Now().UnixNano())) - randSource = mathrand.NewSource(index.Int64()) -} - type RandomRegistry struct { handler sprout.Handler // Embedding Handler for shared functionality } diff --git a/registry/reflect/functions_test.go b/registry/reflect/functions_test.go index 48fc53f..bb92ac9 100644 --- a/registry/reflect/functions_test.go +++ b/registry/reflect/functions_test.go @@ -3,19 +3,22 @@ package reflect_test import ( "testing" - "github.com/go-sprout/sprout/pesticide" - "github.com/go-sprout/sprout/registry/reflect" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + + "github.com/go-sprout/sprout/pesticide" + "github.com/go-sprout/sprout/registry/reflect" ) -var nilPointer *int = nil -var nilInterface interface{} +var ( + nilPointer *int = nil + nilInterface interface{} +) func TestTypeIs(t *testing.T) { type testStruct struct{} - var tc = []pesticide.TestCase{ + tc := []pesticide.TestCase{ {Name: "TestTypeIsInt", Input: `{{typeIs "int" 42}}`, ExpectedOutput: "true"}, {Name: "TestTypeIsString", Input: `{{42 | typeIs "string"}}`, ExpectedOutput: "false"}, {Name: "TestTypeIsVariable", Input: `{{$var := 42}}{{typeIs "string" $var}}`, ExpectedOutput: "false"}, @@ -28,7 +31,7 @@ func TestTypeIs(t *testing.T) { func TestTypeIsLike(t *testing.T) { type testStruct struct{} - var tc = []pesticide.TestCase{ + tc := []pesticide.TestCase{ {Name: "TestTypeIsLikeInt", Input: `{{typeIsLike "int" 42}}`, ExpectedOutput: "true"}, {Name: "TestTypeIsLikeString", Input: `{{42 | typeIsLike "string"}}`, ExpectedOutput: "false"}, {Name: "TestTypeIsLikeVariable", Input: `{{$var := 42}}{{typeIsLike "string" $var}}`, ExpectedOutput: "false"}, @@ -42,7 +45,7 @@ func TestTypeIsLike(t *testing.T) { func TestTypeOf(t *testing.T) { type testStruct struct{} - var tc = []pesticide.TestCase{ + tc := []pesticide.TestCase{ {Name: "TestTypeOfInt", Input: `{{typeOf 42}}`, ExpectedOutput: "int"}, {Name: "TestTypeOfString", Input: `{{typeOf "42"}}`, ExpectedOutput: "string"}, {Name: "TestTypeOfVariable", Input: `{{$var := 42}}{{typeOf $var}}`, ExpectedOutput: "int"}, @@ -55,7 +58,7 @@ func TestTypeOf(t *testing.T) { func TestKindIs(t *testing.T) { type testStruct struct{} - var tc = []pesticide.TestCase{ + tc := []pesticide.TestCase{ {Name: "TestKindIsInt", Input: `{{kindIs "int" 42}}`, ExpectedOutput: "true"}, {Name: "TestKindIsString", Input: `{{42 | kindIs "string"}}`, ExpectedOutput: "false"}, {Name: "TestKindIsVariable", Input: `{{$var := 42}}{{kindIs "string" $var}}`, ExpectedOutput: "false"}, @@ -69,7 +72,7 @@ func TestKindIs(t *testing.T) { func TestKindOf(t *testing.T) { type testStruct struct{} - var tc = []pesticide.TestCase{ + tc := []pesticide.TestCase{ {Name: "TestKindOfInt", Input: `{{kindOf 42}}`, ExpectedOutput: "int"}, {Name: "TestKindOfString", Input: `{{kindOf "42"}}`, ExpectedOutput: "string"}, {Name: "TestKindOfSlice", Input: `{{kindOf .var}}`, ExpectedOutput: "slice", Data: map[string]any{"var": []int{}}}, @@ -92,7 +95,7 @@ func TestHasField(t *testing.T) { Bar string } - var tc = []pesticide.TestCase{ + tc := []pesticide.TestCase{ {Name: "TestHasFieldStructPointerTrue", Input: `{{ .V | hasField "Foo" }}`, ExpectedOutput: "true", Data: map[string]any{"V": &A{Foo: "bar"}}}, {Name: "TestHasFieldStructPointerFalse", Input: `{{ .V | hasField "Foo" }}`, ExpectedOutput: "false", Data: map[string]any{"V": &B{Bar: "boo"}}}, {Name: "TestHasFieldStructTrue", Input: `{{ .V | hasField "Foo" }}`, ExpectedOutput: "true", Data: map[string]any{"V": A{Foo: "bar"}}}, @@ -108,7 +111,7 @@ func TestHasField(t *testing.T) { } func TestDeepEqual(t *testing.T) { - var tc = []pesticide.TestCase{ + tc := []pesticide.TestCase{ {Name: "TestDeepEqualInt", Input: `{{deepEqual 42 42}}`, ExpectedOutput: "true"}, {Name: "TestDeepEqualString", Input: `{{deepEqual "42" "42"}}`, ExpectedOutput: "true"}, {Name: "TestDeepEqualSlice", Input: `{{deepEqual .a .b}}`, ExpectedOutput: "true", Data: map[string]any{"a": []int{1, 2, 3}, "b": []int{1, 2, 3}}}, @@ -127,7 +130,7 @@ func TestDeepCopy(t *testing.T) { A int } - var tc = []pesticide.TestCase{ + tc := []pesticide.TestCase{ {Name: "TestDeepCopyInt", Input: `{{$a := 42}}{{$b := deepCopy $a}}{{$b}}`, ExpectedOutput: "42"}, {Name: "TestDeepCopyString", Input: `{{$a := "42"}}{{$b := deepCopy $a}}{{$b}}`, ExpectedOutput: "42"}, {Name: "TestDeepCopySlice", Input: `{{$a := .a}}{{$b := deepCopy $a}}{{$b}}`, ExpectedOutput: "[1 2 3]", Data: map[string]any{"a": []int{1, 2, 3}}}, diff --git a/registry/slices/functions.go b/registry/slices/functions.go index 1f724af..3e9d149 100644 --- a/registry/slices/functions.go +++ b/registry/slices/functions.go @@ -46,11 +46,11 @@ func (sr *SlicesRegistry) List(values ...any) []any { // // {{ ["a", "b"] | append "c" }} // Output: ["a", "b", "c"], nil func (sr *SlicesRegistry) Append(args ...any) ([]any, error) { - //! BACKWARDS COMPATIBILITY: deprecated in v1.0 and removed in v1.1 - //! Due to change in signature, this function still supports the old signature - //! to let users transition to the new signature. - //* Old signature: Append(list any, v any) - //* New signature: Append(v any, list any) + // ! BACKWARDS COMPATIBILITY: deprecated in v1.0 and removed in v1.1 + // ! Due to change in signature, this function still supports the old signature + // ! to let users transition to the new signature. + // * Old signature: Append(list any, v any) + // * New signature: Append(v any, list any) if len(args) != 2 { return []any{}, deprecated.ErrArgsCount(2, len(args)) } @@ -116,11 +116,11 @@ func (sr *SlicesRegistry) Append(args ...any) ([]any, error) { // // {{ ["b", "c"] | prepend "a" }} // Output: ["a", "b", "c"], nil func (sr *SlicesRegistry) Prepend(args ...any) ([]any, error) { - //! BACKWARDS COMPATIBILITY: deprecated in v1.0 and removed in v1.1 - //! Due to change in signature, this function still supports the old signature - //! to let users transition to the new signature. - //* Old signature: Prepend(list any, v any) - //* New signature: Prepend(v any, list any) + // ! BACKWARDS COMPATIBILITY: deprecated in v1.0 and removed in v1.1 + // ! Due to change in signature, this function still supports the old signature + // ! to let users transition to the new signature. + // * Old signature: Prepend(list any, v any) + // * New signature: Prepend(v any, list any) if len(args) != 2 { return []any{}, deprecated.ErrArgsCount(2, len(args)) } @@ -362,11 +362,11 @@ func (sr *SlicesRegistry) Compact(list any) ([]any, error) { // // {{ [1, 2, 3, 4, 5] | slice 1, 3 }} // Output: [2, 3], nil func (sr *SlicesRegistry) Slice(args ...any) (any, error) { - //! BACKWARDS COMPATIBILITY: deprecated in v1.0 and removed in v1.1 - //! Due to change in signature, this function still supports the old signature - //! to let users transition to the new signature. - //* Old signature: Slice(list any, indices ...any) - //* New signature: Slice(indices ...any, list any) + // ! BACKWARDS COMPATIBILITY: deprecated in v1.0 and removed in v1.1 + // ! Due to change in signature, this function still supports the old signature + // ! to let users transition to the new signature. + // * Old signature: Slice(list any, indices ...any) + // * New signature: Slice(indices ...any, list any) if len(args) < 1 { return []any{}, deprecated.ErrArgsCount(2, len(args)) } @@ -481,11 +481,11 @@ func (sr *SlicesRegistry) Has(element any, list any) (bool, error) { // // {{ [1, 2, 3, 4] | without 2, 4 }} // Output: [1, 3], nil func (sr *SlicesRegistry) Without(args ...any) ([]any, error) { - //! BACKWARDS COMPATIBILITY: deprecated in v1.0 and removed in v1.1 - //! Due to change in signature, this function still supports the old signature - //! to let users transition to the new signature. - //* Old signature: Without(list any, omit ...any) - //* New signature: Without(omit ...any, list any) + // ! BACKWARDS COMPATIBILITY: deprecated in v1.0 and removed in v1.1 + // ! Due to change in signature, this function still supports the old signature + // ! to let users transition to the new signature. + // * Old signature: Without(list any, omit ...any) + // * New signature: Without(omit ...any, list any) if len(args) < 2 { return []any{}, deprecated.ErrArgsCount(2, len(args)) } diff --git a/registry/strings/functions.go b/registry/strings/functions.go index 69b8992..675570f 100644 --- a/registry/strings/functions.go +++ b/registry/strings/functions.go @@ -6,9 +6,10 @@ import ( "strings" "unicode" - "github.com/go-sprout/sprout/internal/helpers" "golang.org/x/text/cases" "golang.org/x/text/language" + + "github.com/go-sprout/sprout/internal/helpers" ) // Nospace removes all whitespace characters from the provided string. @@ -210,7 +211,7 @@ func (sr *StringsRegistry) ToUpper(str string) string { // // {{ "banana" | replace "a", "o" }} // Output: "bonono" func (sr *StringsRegistry) Replace(old, new, src string) string { - return strings.Replace(src, old, new, -1) + return strings.ReplaceAll(src, old, new) } // Repeat repeats the string 'str' for 'count' times. diff --git a/registry/strings/functions_test.go b/registry/strings/functions_test.go index edfdfd8..7ca44a2 100644 --- a/registry/strings/functions_test.go +++ b/registry/strings/functions_test.go @@ -8,7 +8,7 @@ import ( ) func TestNoSpace(t *testing.T) { - var tc = []pesticide.TestCase{ + tc := []pesticide.TestCase{ {Name: "TestEmpty", Input: `{{ "" | nospace }}`, ExpectedOutput: ""}, {Name: "TestSpaceOnly", Input: `{{ " " | nospace }}`, ExpectedOutput: ""}, {Name: "TestLeadingSpace", Input: `{{ " foo" | nospace }}`, ExpectedOutput: "foo"}, @@ -21,7 +21,7 @@ func TestNoSpace(t *testing.T) { } func TestTrim(t *testing.T) { - var tc = []pesticide.TestCase{ + tc := []pesticide.TestCase{ {Name: "TestEmpty", Input: `{{ "" | trim }}`, ExpectedOutput: ""}, {Name: "TestSpaceOnly", Input: `{{ " " | trim }}`, ExpectedOutput: ""}, {Name: "TestLeadingSpace", Input: `{{ " foo" | trim }}`, ExpectedOutput: "foo"}, @@ -34,7 +34,7 @@ func TestTrim(t *testing.T) { } func TestTrimAll(t *testing.T) { - var tc = []pesticide.TestCase{ + tc := []pesticide.TestCase{ {Name: "TestEmpty", Input: `{{ "" | trimAll "-" }}`, ExpectedOutput: ""}, {Name: "TestAllDashes", Input: `{{ "---------" | trimAll "-" }}`, ExpectedOutput: ""}, {Name: "TestNoDashes", Input: `{{ "foo" | trimAll "-" }}`, ExpectedOutput: "foo"}, @@ -46,7 +46,7 @@ func TestTrimAll(t *testing.T) { } func TestTrimPrefix(t *testing.T) { - var tc = []pesticide.TestCase{ + tc := []pesticide.TestCase{ {Name: "TestEmpty", Input: `{{ "" | trimPrefix "-" }}`, ExpectedOutput: ""}, {Name: "TestDoubleDash", Input: `{{ "--" | trimPrefix "-" }}`, ExpectedOutput: "-"}, {Name: "TestNoPrefix", Input: `{{ "foo" | trimPrefix "-" }}`, ExpectedOutput: "foo"}, @@ -58,7 +58,7 @@ func TestTrimPrefix(t *testing.T) { } func TestTrimSuffix(t *testing.T) { - var tc = []pesticide.TestCase{ + tc := []pesticide.TestCase{ {Name: "TestEmpty", Input: `{{ "" | trimSuffix "-" }}`, ExpectedOutput: ""}, {Name: "TestDoubleDash", Input: `{{ "--" | trimSuffix "-" }}`, ExpectedOutput: "-"}, {Name: "TestNoSuffix", Input: `{{ "foo" | trimSuffix "-" }}`, ExpectedOutput: "foo"}, @@ -70,7 +70,7 @@ func TestTrimSuffix(t *testing.T) { } func TestContains(t *testing.T) { - var tc = []pesticide.TestCase{ + tc := []pesticide.TestCase{ {Name: "TestEmpty", Input: `{{ "" | contains "-" }}`, ExpectedOutput: "false"}, {Name: "TestContains", Input: `{{ "foo" | contains "o" }}`, ExpectedOutput: "true"}, {Name: "TestNotContains", Input: `{{ "foo" | contains "x" }}`, ExpectedOutput: "false"}, @@ -80,7 +80,7 @@ func TestContains(t *testing.T) { } func TestHasPrefix(t *testing.T) { - var tc = []pesticide.TestCase{ + tc := []pesticide.TestCase{ {Name: "TestEmpty", Input: `{{ "" | hasPrefix "-" }}`, ExpectedOutput: "false"}, {Name: "TestHasPrefix", Input: `{{ "foo" | hasPrefix "f" }}`, ExpectedOutput: "true"}, {Name: "TestNotHasPrefix", Input: `{{ "foo" | hasPrefix "o" }}`, ExpectedOutput: "false"}, @@ -90,7 +90,7 @@ func TestHasPrefix(t *testing.T) { } func TestHasSuffix(t *testing.T) { - var tc = []pesticide.TestCase{ + tc := []pesticide.TestCase{ {Name: "TestEmpty", Input: `{{ "" | hasSuffix "-" }}`, ExpectedOutput: "false"}, {Name: "TestHasSuffix", Input: `{{ "foo" | hasSuffix "o" }}`, ExpectedOutput: "true"}, {Name: "TestNotHasSuffix", Input: `{{ "foo" | hasSuffix "f" }}`, ExpectedOutput: "false"}, @@ -100,7 +100,7 @@ func TestHasSuffix(t *testing.T) { } func TestToLower(t *testing.T) { - var tc = []pesticide.TestCase{ + tc := []pesticide.TestCase{ {Name: "TestEmpty", Input: `{{ "" | toLower }}`, ExpectedOutput: ""}, {Name: "TestLower", Input: `{{ "foo" | toLower }}`, ExpectedOutput: "foo"}, {Name: "TestUpper", Input: `{{ "FOO" | toLower }}`, ExpectedOutput: "foo"}, @@ -110,7 +110,7 @@ func TestToLower(t *testing.T) { } func TestToUpper(t *testing.T) { - var tc = []pesticide.TestCase{ + tc := []pesticide.TestCase{ {Name: "TestEmpty", Input: `{{ "" | toUpper }}`, ExpectedOutput: ""}, {Name: "TestLower", Input: `{{ "foo" | toUpper }}`, ExpectedOutput: "FOO"}, {Name: "TestUpper", Input: `{{ "FOO" | toUpper }}`, ExpectedOutput: "FOO"}, @@ -120,7 +120,7 @@ func TestToUpper(t *testing.T) { } func TestReplace(t *testing.T) { - var tc = []pesticide.TestCase{ + tc := []pesticide.TestCase{ {Name: "TestEmpty", Input: `{{ "" | replace "-" "x" }}`, ExpectedOutput: ""}, {Name: "TestReplace", Input: `{{ "foo" | replace "o" "x" }}`, ExpectedOutput: "fxx"}, {Name: "TestNotReplace", Input: `{{ "foo" | replace "x" "y" }}`, ExpectedOutput: "foo"}, @@ -131,7 +131,7 @@ func TestReplace(t *testing.T) { } func TestRepeat(t *testing.T) { - var tc = []pesticide.TestCase{ + tc := []pesticide.TestCase{ {Name: "TestEmpty", Input: `{{ "" | repeat 3 }}`, ExpectedOutput: ""}, {Name: "TestRepeat", Input: `{{ "foo" | repeat 3 }}`, ExpectedOutput: "foofoofoo"}, {Name: "TestRepeatZero", Input: `{{ "foo" | repeat 0 }}`, ExpectedOutput: ""}, @@ -141,7 +141,7 @@ func TestRepeat(t *testing.T) { } func TestJoin(t *testing.T) { - var tc = []pesticide.TestCase{ + tc := []pesticide.TestCase{ {Name: "TestNil", Input: `{{ .nil | join "-" }}`, ExpectedOutput: "", Data: map[string]any{"nil": nil}}, {Name: "TestIntSlice", Input: `{{ .test | join "-" }}`, ExpectedOutput: "1-2-3", Data: map[string]any{"test": []int{1, 2, 3}}}, {Name: "TestStringSlice", Input: `{{ .test | join "-" }}`, ExpectedOutput: "a-b-c", Data: map[string]any{"test": []string{"a", "b", "c"}}}, @@ -153,7 +153,7 @@ func TestJoin(t *testing.T) { } func TestTrunc(t *testing.T) { - var tc = []pesticide.TestCase{ + tc := []pesticide.TestCase{ {Name: "TestEmpty", Input: `{{ "" | trunc 3 }}`, ExpectedOutput: ""}, {Name: "TestTruncate", Input: `{{ "foooooo" | trunc 3 }}`, ExpectedOutput: "foo"}, {Name: "TestNegativeTruncate", Input: `{{ "foobar" | trunc -3 }}`, ExpectedOutput: "bar"}, @@ -165,7 +165,7 @@ func TestTrunc(t *testing.T) { } func TestShuffle(t *testing.T) { - var tc = []pesticide.RegexpTestCase{ + tc := []pesticide.RegexpTestCase{ {Template: `{{ shuffle "" }}`, Length: 0, Regexp: `^$`}, {Template: `{{ shuffle "hey" }}`, Length: 3, Regexp: `^[hey]{3}$`}, {Template: `{{ shuffle "foo bar baz" }}`, Length: 11, Regexp: `^[\sfobazr]{11}$`}, @@ -175,7 +175,7 @@ func TestShuffle(t *testing.T) { } func TestEllipsis(t *testing.T) { - var tc = []pesticide.TestCase{ + tc := []pesticide.TestCase{ {Name: "TestEmpty", Input: `{{ "" | ellipsis 3 }}`, ExpectedOutput: ""}, {Name: "TestShort", Input: `{{ "foo" | ellipsis 5 }}`, ExpectedOutput: "foo"}, {Name: "TestTruncate", Input: `{{ "foooooo" | ellipsis 6 }}`, ExpectedOutput: "foo..."}, @@ -186,7 +186,7 @@ func TestEllipsis(t *testing.T) { } func TestEllipsisBoth(t *testing.T) { - var tc = []pesticide.TestCase{ + tc := []pesticide.TestCase{ {Name: "TestEmpty", Input: `{{ "" | ellipsisBoth 3 5 }}`, ExpectedOutput: ""}, {Name: "TestShort", Input: `{{ "foo" | ellipsisBoth 5 4 }}`, ExpectedOutput: "foo"}, {Name: "TestTruncate", Input: `{{ "foooboooooo" | ellipsisBoth 4 9 }}`, ExpectedOutput: "...boo..."}, @@ -197,7 +197,7 @@ func TestEllipsisBoth(t *testing.T) { } func TestInitials(t *testing.T) { - var tc = []pesticide.TestCase{ + tc := []pesticide.TestCase{ {Name: "TestEmpty", Input: `{{ "" | initials }}`, ExpectedOutput: ""}, {Name: "TestSingle", Input: `{{ "f" | initials }}`, ExpectedOutput: "f"}, {Name: "TestTwo", Input: `{{ "foo" | initials }}`, ExpectedOutput: "f"}, @@ -210,7 +210,7 @@ func TestInitials(t *testing.T) { } func TestPlural(t *testing.T) { - var tc = []pesticide.TestCase{ + tc := []pesticide.TestCase{ {Name: "TestZero", Input: `{{ 0 | plural "single" "many" }}`, ExpectedOutput: "many"}, {Name: "TestSingle", Input: `{{ 1 | plural "single" "many" }}`, ExpectedOutput: "single"}, {Name: "TestMultiple", Input: `{{ 2 | plural "single" "many" }}`, ExpectedOutput: "many"}, @@ -221,7 +221,7 @@ func TestPlural(t *testing.T) { } func TestWrap(t *testing.T) { - var tc = []pesticide.TestCase{ + tc := []pesticide.TestCase{ {Name: "TestEmpty", Input: `{{ "" | wrap 10 }}`, ExpectedOutput: ""}, {Name: "TestNegativeWrap", Input: `{{ wrap -1 "With a negative wrap." }}`, ExpectedOutput: "With\na\nnegative\nwrap."}, {Name: "TestWrap", Input: `{{ "This is a long string that needs to be wrapped." | wrap 10 }}`, ExpectedOutput: "This is a\nlong\nstring\nthat needs\nto be\nwrapped."}, @@ -231,7 +231,7 @@ func TestWrap(t *testing.T) { } func TestWrapWith(t *testing.T) { - var tc = []pesticide.TestCase{ + tc := []pesticide.TestCase{ {Name: "TestEmpty", Input: `{{ "" | wrapWith 10 "\t" }}`, ExpectedOutput: ""}, {Name: "TestWrap", Input: `{{ "This is a long string that needs to be wrapped." | wrapWith 10 "\t" }}`, ExpectedOutput: "This is a\tlong\tstring\tthat needs\tto be\twrapped."}, {Name: "TestWrapWithLongWord", Input: `{{ "This is a long string that needs to be wrapped with a looooooooooooooooooooooooooooooooooooong word." | wrapWith 10 "\t" }}`, ExpectedOutput: "This is a\tlong\tstring\tthat needs\tto be\twrapped\twith a\tlooooooooo\toooooooooo\toooooooooo\toooooooong\tword."}, @@ -241,7 +241,7 @@ func TestWrapWith(t *testing.T) { } func TestQuote(t *testing.T) { - var tc = []pesticide.TestCase{ + tc := []pesticide.TestCase{ {Name: "TestEmpty", Input: `{{ "" | quote }}`, ExpectedOutput: `""`}, {Name: "TestNil", Input: `{{ quote .nil }}`, ExpectedOutput: ``, Data: map[string]any{"nil": nil}}, {Name: "TestQuote", Input: `{{ "foo" | quote }}`, ExpectedOutput: `"foo"`}, @@ -257,7 +257,7 @@ func TestQuote(t *testing.T) { } func TestSquote(t *testing.T) { - var tc = []pesticide.TestCase{ + tc := []pesticide.TestCase{ {Name: "TestEmpty", Input: `{{ "" | squote }}`, ExpectedOutput: "''"}, {Name: "TestNil", Input: `{{ squote .nil }}`, ExpectedOutput: "", Data: map[string]any{"nil": nil}}, {Name: "TestQuote", Input: `{{ "foo" | squote }}`, ExpectedOutput: "'foo'"}, @@ -273,7 +273,7 @@ func TestSquote(t *testing.T) { } func TestToCamelCase(t *testing.T) { - var tc = []pesticide.TestCase{ + tc := []pesticide.TestCase{ {Name: "TestEmpty", Input: `{{ "" | toCamelCase }}`, ExpectedOutput: ""}, {Name: "TestCamelCase", Input: `{{ "foo bar" | toCamelCase }}`, ExpectedOutput: "fooBar"}, {Name: "TestCamelCaseWithUpperCase", Input: `{{ "FoO bar" | toCamelCase }}`, ExpectedOutput: "fooBar"}, @@ -292,7 +292,7 @@ func TestToCamelCase(t *testing.T) { } func TestToKebakCase(t *testing.T) { - var tc = []pesticide.TestCase{ + tc := []pesticide.TestCase{ {Name: "TestEmpty", Input: `{{ "" | toKebabCase }}`, ExpectedOutput: ""}, {Name: "TestKebabCase", Input: `{{ "foo bar" | toKebabCase }}`, ExpectedOutput: "foo-bar"}, {Name: "TestKebabCaseWithSpace", Input: `{{ "foo bar" | toKebabCase }}`, ExpectedOutput: "foo-bar"}, @@ -311,7 +311,7 @@ func TestToKebakCase(t *testing.T) { } func TestToPascalCase(t *testing.T) { - var tc = []pesticide.TestCase{ + tc := []pesticide.TestCase{ {Name: "TestEmpty", Input: `{{ "" | toPascalCase }}`, ExpectedOutput: ""}, {Name: "TestPascalCase", Input: `{{ "foo bar" | toPascalCase }}`, ExpectedOutput: "FooBar"}, {Name: "TestPascalCaseWithSpace", Input: `{{ "foo bar" | toPascalCase }}`, ExpectedOutput: "FooBar"}, @@ -324,7 +324,7 @@ func TestToPascalCase(t *testing.T) { } func TestToDotCase(t *testing.T) { - var tc = []pesticide.TestCase{ + tc := []pesticide.TestCase{ {Name: "TestEmpty", Input: `{{ "" | toDotCase }}`, ExpectedOutput: ""}, {Name: "TestDotCase", Input: `{{ "foo bar" | toDotCase }}`, ExpectedOutput: "foo.bar"}, {Name: "TestDotCaseWithSpace", Input: `{{ "foo bar" | toDotCase }}`, ExpectedOutput: "foo.bar"}, @@ -337,7 +337,7 @@ func TestToDotCase(t *testing.T) { } func TestToPathCase(t *testing.T) { - var tc = []pesticide.TestCase{ + tc := []pesticide.TestCase{ {Name: "TestEmpty", Input: `{{ "" | toPathCase }}`, ExpectedOutput: ""}, {Name: "TestPathCase", Input: `{{ "foo bar" | toPathCase }}`, ExpectedOutput: "foo/bar"}, {Name: "TestPathCaseWithSpace", Input: `{{ "foo bar" | toPathCase }}`, ExpectedOutput: "foo/bar"}, @@ -350,7 +350,7 @@ func TestToPathCase(t *testing.T) { } func TestToConstantCase(t *testing.T) { - var tc = []pesticide.TestCase{ + tc := []pesticide.TestCase{ {Name: "TestEmpty", Input: `{{ "" | toConstantCase }}`, ExpectedOutput: ""}, {Name: "TestConstantCase", Input: `{{ "foo bar" | toConstantCase }}`, ExpectedOutput: "FOO_BAR"}, {Name: "TestConstantCaseWithSpace", Input: `{{ "foo bar" | toConstantCase }}`, ExpectedOutput: "FOO_BAR"}, @@ -363,7 +363,7 @@ func TestToConstantCase(t *testing.T) { } func TestToSnakeCase(t *testing.T) { - var tc = []pesticide.TestCase{ + tc := []pesticide.TestCase{ {Name: "TestEmpty", Input: `{{ "" | toSnakeCase }}`, ExpectedOutput: ""}, {Name: "TestSnakeCase", Input: `{{ "foo bar" | toSnakeCase }}`, ExpectedOutput: "foo_bar"}, {Name: "TestSnakeCaseWithSpace", Input: `{{ "foo bar" | toSnakeCase }}`, ExpectedOutput: "foo_bar"}, @@ -386,7 +386,7 @@ func TestToSnakeCase(t *testing.T) { } func TestToTitleCase(t *testing.T) { - var tc = []pesticide.TestCase{ + tc := []pesticide.TestCase{ {Name: "TestEmpty", Input: `{{ "" | toTitleCase }}`, ExpectedOutput: ""}, {Name: "TestTitleCase", Input: `{{ "foo bar" | toTitleCase }}`, ExpectedOutput: "Foo Bar"}, {Name: "TestTitleCaseWithSpace", Input: `{{ "foo bar" | toTitleCase }}`, ExpectedOutput: "Foo Bar"}, @@ -399,7 +399,7 @@ func TestToTitleCase(t *testing.T) { } func TestUntitle(t *testing.T) { - var tc = []pesticide.TestCase{ + tc := []pesticide.TestCase{ {Name: "TestEmpty", Input: `{{ "" | untitle }}`, ExpectedOutput: ""}, {Name: "TestUnTitle", Input: `{{ "Foo Bar" | untitle }}`, ExpectedOutput: "foo bar"}, {Name: "TestUnTitleWithSpace", Input: `{{ "Foo Bar" | untitle }}`, ExpectedOutput: "foo bar"}, @@ -412,7 +412,7 @@ func TestUntitle(t *testing.T) { } func TestSwapCase(t *testing.T) { - var tc = []pesticide.TestCase{ + tc := []pesticide.TestCase{ {Name: "TestEmpty", Input: `{{ "" | swapCase }}`, ExpectedOutput: ""}, {Name: "TestSwapCase", Input: `{{ "Foo Bar" | swapCase }}`, ExpectedOutput: "fOO bAR"}, {Name: "TestSwapCaseWithSpace", Input: `{{ "Foo Bar" | swapCase }}`, ExpectedOutput: "fOO bAR"}, @@ -425,7 +425,7 @@ func TestSwapCase(t *testing.T) { } func TestCapitalize(t *testing.T) { - var tc = []pesticide.TestCase{ + tc := []pesticide.TestCase{ {Name: "TestEmpty", Input: `{{ "" | capitalize }}`, ExpectedOutput: ""}, {Name: "CapitalizeAlreadyUpper", Input: `{{ "Foo Bar" | capitalize }}`, ExpectedOutput: "Foo Bar"}, {Name: "CapitalizeWithSpace", Input: `{{ " fe bar" | capitalize }}`, ExpectedOutput: " Fe bar"}, @@ -440,7 +440,7 @@ func TestCapitalize(t *testing.T) { } func TestUncapitalize(t *testing.T) { - var tc = []pesticide.TestCase{ + tc := []pesticide.TestCase{ {Name: "TestEmpty", Input: `{{ "" | uncapitalize }}`, ExpectedOutput: ""}, {Name: "UncapitalizeAlreadyLower", Input: `{{ "foo bar" | uncapitalize }}`, ExpectedOutput: "foo bar"}, {Name: "UncapitalizeWithSpace", Input: `{{ " Foo bar" | uncapitalize }}`, ExpectedOutput: " foo bar"}, @@ -455,7 +455,7 @@ func TestUncapitalize(t *testing.T) { } func TestSplit(t *testing.T) { - var tc = []pesticide.TestCase{ + tc := []pesticide.TestCase{ {Name: "TestEmpty", Input: `{{ $v := ("" | split "-") }}{{$v._0}}`, ExpectedOutput: ""}, {Name: "TestSplit", Input: `{{ $v := ("foo$bar$baz" | split "$") }}{{$v._0}} {{$v._1}} {{$v._2}}`, ExpectedOutput: "foo bar baz"}, {Name: "TestSplitWithEmpty", Input: `{{ $v := ("foo$bar$" | split "$") }}{{$v._0}} {{$v._1}} {{$v._2}}`, ExpectedOutput: "foo bar "}, @@ -465,7 +465,7 @@ func TestSplit(t *testing.T) { } func TestSplitn(t *testing.T) { - var tc = []pesticide.TestCase{ + tc := []pesticide.TestCase{ {Name: "TestEmpty", Input: `{{ $v := ("" | splitn "-" 3) }}{{$v._0}}`, ExpectedOutput: ""}, {Name: "TestSplit", Input: `{{ $v := ("foo$bar$baz" | splitn "$" 2) }}{{$v._0}} {{$v._1}}`, ExpectedOutput: "foo bar$baz"}, {Name: "TestSplitWithEmpty", Input: `{{ $v := ("foo$bar$" | splitn "$" 2) }}{{$v._0}} {{$v._1}}`, ExpectedOutput: "foo bar$"}, @@ -475,7 +475,7 @@ func TestSplitn(t *testing.T) { } func TestSubstring(t *testing.T) { - var tc = []pesticide.TestCase{ + tc := []pesticide.TestCase{ {Name: "TestEmpty", Input: `{{ "" | substr 0 3 }}`, ExpectedOutput: ""}, {Name: "TestEmptyWithNegativeValue", Input: `{{ "" | substr -1 -4 }}`, ExpectedOutput: ""}, {Name: "TestSubstring", Input: `{{ "foobar" | substr 0 3 }}`, ExpectedOutput: "foo"}, @@ -489,7 +489,7 @@ func TestSubstring(t *testing.T) { } func TestIndent(t *testing.T) { - var tc = []pesticide.TestCase{ + tc := []pesticide.TestCase{ {Name: "TestEmpty", Input: `{{ "" | indent 3 }}`, ExpectedOutput: " "}, {Name: "TestIndent", Input: `{{ "foo\nbar" | indent 3 }}`, ExpectedOutput: " foo\n bar"}, {Name: "TestIndentWithSpace", Input: `{{ "foo\n bar" | indent 3 }}`, ExpectedOutput: " foo\n bar"}, @@ -500,7 +500,7 @@ func TestIndent(t *testing.T) { } func TestNindent(t *testing.T) { - var tc = []pesticide.TestCase{ + tc := []pesticide.TestCase{ {Name: "TestEmpty", Input: `{{ "" | nindent 3 }}`, ExpectedOutput: "\n "}, {Name: "TestIndent", Input: `{{ "foo\nbar" | nindent 3 }}`, ExpectedOutput: "\n foo\n bar"}, {Name: "TestIndentWithSpace", Input: `{{ "foo\n bar" | nindent 3 }}`, ExpectedOutput: "\n foo\n bar"}, @@ -511,7 +511,7 @@ func TestNindent(t *testing.T) { } func TestSeq(t *testing.T) { - var tc = []pesticide.TestCase{ + tc := []pesticide.TestCase{ {Input: `{{ seq 0 1 3 }}`, ExpectedOutput: "0 1 2 3"}, {Input: `{{ seq 0 3 10 }}`, ExpectedOutput: "0 3 6 9"}, {Input: `{{ seq 3 3 2 }}`, ExpectedOutput: ""}, diff --git a/registry/strings/helpers.go b/registry/strings/helpers.go index 3dc07ca..1b30cee 100644 --- a/registry/strings/helpers.go +++ b/registry/strings/helpers.go @@ -68,7 +68,7 @@ func (sr *StringsRegistry) initials(str string, delimiters string) string { } words := strings.FieldsFunc(str, isDelimiter) - var runes = make([]rune, len(words)) + runes := make([]rune, len(words)) for i, word := range strings.FieldsFunc(str, isDelimiter) { if i == 0 || unicode.IsLetter(rune(word[0])) { runes[i] = rune(word[0]) @@ -113,7 +113,7 @@ func (sr *StringsRegistry) transformString(style caseStyle, str string) string { var result strings.Builder result.Grow(len(str) + 10) // Allocate a bit more for potential separators - var capitalizeNext = style.CapitalizeNext + capitalizeNext := style.CapitalizeNext var lastRune, lastLetter, nextRune rune = 0, 0, 0 if !style.CapitalizeFirst { @@ -147,14 +147,15 @@ func (sr *StringsRegistry) transformString(style caseStyle, str string) string { result.WriteRune(style.Separator) } - if capitalizeNext && style.CapitalizeNext { + switch { + case capitalizeNext && style.CapitalizeNext: result.WriteRune(unicode.ToUpper(r)) capitalizeNext = false - } else if style.ForceLowercase { + case style.ForceLowercase: result.WriteRune(unicode.ToLower(r)) - } else if style.ForceUppercase { + case style.ForceUppercase: result.WriteRune(unicode.ToUpper(r)) - } else { + default: result.WriteRune(r) } diff --git a/sprigin/sprig_backward_compatibility.go b/sprigin/sprig_backward_compatibility.go index 5693993..2224437 100644 --- a/sprigin/sprig_backward_compatibility.go +++ b/sprigin/sprig_backward_compatibility.go @@ -32,45 +32,45 @@ import ( // The following functions are provided for backwards compatibility with the // original sprig methods. They are not recommended for use in new code. var bc_registerSprigFuncs = sprout.FunctionAliasMap{ - "dateModify": []string{"date_modify"}, //! Deprecated: Should use dateModify instead - "dateInZone": []string{"date_in_zone"}, //! Deprecated: Should use dateInZone instead - "mustDateModify": []string{"must_date_modify"}, //! Deprecated: Should use mustDateModify instead - "ellipsis": []string{"abbrev"}, //! Deprecated: Should use ellipsis instead - "ellipsisBoth": []string{"abbrevboth"}, //! Deprecated: Should use ellipsisBoth instead - "trimAll": []string{"trimall"}, //! Deprecated: Should use trimAll instead - "append": []string{"push"}, //! Deprecated: Should use append instead - "mustAppend": []string{"mustPush"}, //! Deprecated: Should use mustAppend instead + "dateModify": []string{"date_modify"}, // ! Deprecated: Should use dateModify instead + "dateInZone": []string{"date_in_zone"}, // ! Deprecated: Should use dateInZone instead + "mustDateModify": []string{"must_date_modify"}, // ! Deprecated: Should use mustDateModify instead + "ellipsis": []string{"abbrev"}, // ! Deprecated: Should use ellipsis instead + "ellipsisBoth": []string{"abbrevboth"}, // ! Deprecated: Should use ellipsisBoth instead + "trimAll": []string{"trimall"}, // ! Deprecated: Should use trimAll instead + "append": []string{"push"}, // ! Deprecated: Should use append instead + "mustAppend": []string{"mustPush"}, // ! Deprecated: Should use mustAppend instead "list": []string{"tuple"}, // FIXME: with the addition of append/prepend these are no longer immutable. - "max": []string{"biggest"}, //! Deprecated: Should use max instead - "toUpper": []string{"upper", "toupper", "uppercase"}, //! Deprecated: Should use toUpper instead - "toLower": []string{"lower", "tolower", "lowercase"}, //! Deprecated: Should use toLower instead - "add": []string{"addf"}, //! Deprecated: Should use add instead - "add1": []string{"add1f"}, //! Deprecated: Should use add1 instead - "sub": []string{"subf"}, //! Deprecated: Should use sub instead - "toTitleCase": []string{"title", "titlecase"}, //! Deprecated: Should use toTitleCase instead - "toPascalCase": []string{"camelcase"}, //! Deprecated: Should use toPascalCase instead - "toSnakeCase": []string{"snake", "snakecase"}, //! Deprecated: Should use toSnakeCase instead - "toKebabCase": []string{"kebab", "kebabcase"}, //! Deprecated: Should use toKebabCase instead - "swapCase": []string{"swapcase"}, //! Deprecated: Should use swapCase instead - "base64Encode": []string{"b64enc"}, //! Deprecated: Should use base64Encode instead - "base64Decode": []string{"b64dec"}, //! Deprecated: Should use base64Decode instead - "base32Encode": []string{"b32enc"}, //! Deprecated: Should use base32Encode instead - "base32Decode": []string{"b32dec"}, //! Deprecated: Should use base32Decode instead - "pathBase": []string{"base"}, //! Deprecated: Should use pathBase instead - "pathDir": []string{"dir"}, //! Deprecated: Should use pathDir instead - "pathExt": []string{"ext"}, //! Deprecated: Should use pathExt instead - "pathClean": []string{"clean"}, //! Deprecated: Should use pathClean instead - "pathIsAbs": []string{"isAbs"}, //! Deprecated: Should use pathIsAbs instead - "expandEnv": []string{"expandenv"}, //! Deprecated: Should use expandEnv instead - "dateAgo": []string{"ago"}, //! Deprecated: Should use dateAgo instead - "strSlice": []string{"toStrings"}, //! Deprecated: Should use strSlice instead - "toInt": []string{"int", "atoi"}, //! Deprecated: Should use toInt instead - "toInt64": []string{"int64"}, //! Deprecated: Should use toInt64 instead - "toFloat64": []string{"float64"}, //! Deprecated: Should use toFloat64 instead - "toOctal": []string{"toDecimal"}, //! Deprecated: Should use toOctal instead + "max": []string{"biggest"}, // ! Deprecated: Should use max instead + "toUpper": []string{"upper", "toupper", "uppercase"}, // ! Deprecated: Should use toUpper instead + "toLower": []string{"lower", "tolower", "lowercase"}, // ! Deprecated: Should use toLower instead + "add": []string{"addf"}, // ! Deprecated: Should use add instead + "add1": []string{"add1f"}, // ! Deprecated: Should use add1 instead + "sub": []string{"subf"}, // ! Deprecated: Should use sub instead + "toTitleCase": []string{"title", "titlecase"}, // ! Deprecated: Should use toTitleCase instead + "toPascalCase": []string{"camelcase"}, // ! Deprecated: Should use toPascalCase instead + "toSnakeCase": []string{"snake", "snakecase"}, // ! Deprecated: Should use toSnakeCase instead + "toKebabCase": []string{"kebab", "kebabcase"}, // ! Deprecated: Should use toKebabCase instead + "swapCase": []string{"swapcase"}, // ! Deprecated: Should use swapCase instead + "base64Encode": []string{"b64enc"}, // ! Deprecated: Should use base64Encode instead + "base64Decode": []string{"b64dec"}, // ! Deprecated: Should use base64Decode instead + "base32Encode": []string{"b32enc"}, // ! Deprecated: Should use base32Encode instead + "base32Decode": []string{"b32dec"}, // ! Deprecated: Should use base32Decode instead + "pathBase": []string{"base"}, // ! Deprecated: Should use pathBase instead + "pathDir": []string{"dir"}, // ! Deprecated: Should use pathDir instead + "pathExt": []string{"ext"}, // ! Deprecated: Should use pathExt instead + "pathClean": []string{"clean"}, // ! Deprecated: Should use pathClean instead + "pathIsAbs": []string{"isAbs"}, // ! Deprecated: Should use pathIsAbs instead + "expandEnv": []string{"expandenv"}, // ! Deprecated: Should use expandEnv instead + "dateAgo": []string{"ago"}, // ! Deprecated: Should use dateAgo instead + "strSlice": []string{"toStrings"}, // ! Deprecated: Should use strSlice instead + "toInt": []string{"int", "atoi"}, // ! Deprecated: Should use toInt instead + "toInt64": []string{"int64"}, // ! Deprecated: Should use toInt64 instead + "toFloat64": []string{"float64"}, // ! Deprecated: Should use toFloat64 instead + "toOctal": []string{"toDecimal"}, // ! Deprecated: Should use toOctal instead } -//\ BACKWARDS COMPATIBILITY +// \ BACKWARDS COMPATIBILITY // These functions are not guaranteed to evaluate to the same result for given input, because they // refer to the environment or global state. @@ -189,7 +189,7 @@ func (sh *SprigHandler) Build() sprout.FunctionMap { } } } - //\ BACKWARDS COMPATIBILITY + // \ BACKWARDS COMPATIBILITY sprout.AssignAliases(sh) sprout.AssignNotices(sh) @@ -204,7 +204,7 @@ func (sh *SprigHandler) Build() sprout.FunctionMap { } } } - //\ BACKWARDS COMPATIBILITY + // \ BACKWARDS COMPATIBILITY return sh.funcsMap } diff --git a/sprout.go b/sprout.go index bfb5f0f..f2ab31b 100644 --- a/sprout.go +++ b/sprout.go @@ -46,7 +46,7 @@ func New(opts ...HandlerOption[*DefaultHandler]) *DefaultHandler { return dh } -// DEPRECATED: NewFunctionHandler creates a new function handler with the +// Deprecated: NewFunctionHandler creates a new function handler with the // default values. It is deprecated and should not be used. Use `New` instead. func NewFunctionHandler(opts ...HandlerOption[*DefaultHandler]) *DefaultHandler { slog.Warn("NewFunctionHandler are deprecated. Use `New` instead") diff --git a/taskfile.yml b/taskfile.yml index 7cf1721..f043bbe 100644 --- a/taskfile.yml +++ b/taskfile.yml @@ -6,6 +6,14 @@ vars: GREETING: Hello, World! tasks: + lint: + aliases: [linter, linters, l] + desc: Run linters on the project code + summary: | + Run linters on the project code and generate a report with the results. + cmds: + - go install github.com/Antonboom/testifylint@v1.4.0 + - golangci-lint run test: aliases: [tests, t] desc: Run tests with coverage