diff --git a/aes/cipher.go b/aes/cipher.go index e1009f2a5b..9ed323986f 100644 --- a/aes/cipher.go +++ b/aes/cipher.go @@ -35,7 +35,7 @@ const nonceSize int = 32 type stashKey struct { additionalData string - plaintext interface{} + plaintext any } // Cipher encrypts and decrypts data keys with AES GCM 256 @@ -77,7 +77,7 @@ func parse(value string) (*encryptedValue, error) { } // Decrypt takes a sops-format value string and a key and returns the decrypted value and a stash value -func (c Cipher) Decrypt(ciphertext string, key []byte, additionalData string) (plaintext interface{}, err error) { +func (c Cipher) Decrypt(ciphertext string, key []byte, additionalData string) (plaintext any, err error) { if isEmpty(ciphertext) { return "", nil } @@ -124,7 +124,7 @@ func (c Cipher) Decrypt(ciphertext string, key []byte, additionalData string) (p return plaintext, err } -func isEmpty(value interface{}) bool { +func isEmpty(value any) bool { switch value := value.(type) { case string: return value == "" @@ -138,7 +138,7 @@ func isEmpty(value interface{}) bool { } // Encrypt takes one of (string, int, float, bool) and encrypts it with the provided key and additional auth data, returning a sops-format encrypted string. -func (c Cipher) Encrypt(plaintext interface{}, key []byte, additionalData string) (ciphertext string, err error) { +func (c Cipher) Encrypt(plaintext any, key []byte, additionalData string) (ciphertext string, err error) { if isEmpty(plaintext) { return "", nil } diff --git a/age/keysource.go b/age/keysource.go index 9c928d86aa..5a043b6a84 100644 --- a/age/keysource.go +++ b/age/keysource.go @@ -227,7 +227,7 @@ func formatError(msg string, err error, errs errSet, unusedLocations []string) e } else if count == 2 { unusedSuffix = fmt.Sprintf("s '%s' and '%s'", unusedLocations[0], unusedLocations[1]) } else { - unusedSuffix = fmt.Sprintf("s '%s', and '%s'", strings.Join(unusedLocations[:count - 1], "', '"), unusedLocations[count - 1]) + unusedSuffix = fmt.Sprintf("s '%s', and '%s'", strings.Join(unusedLocations[:count-1], "', '"), unusedLocations[count-1]) } unusedSuffix = fmt.Sprintf(". Did not find keys in location%s.", unusedSuffix) } @@ -282,8 +282,8 @@ func (key *MasterKey) ToString() string { } // ToMap converts the MasterKey to a map for serialization purposes. -func (key *MasterKey) ToMap() map[string]interface{} { - out := make(map[string]interface{}) +func (key *MasterKey) ToMap() map[string]any { + out := make(map[string]any) out["recipient"] = key.Recipient out["enc"] = key.EncryptedKey return out diff --git a/age/keysource_test.go b/age/keysource_test.go index da315d1a40..03edc1586e 100644 --- a/age/keysource_test.go +++ b/age/keysource_test.go @@ -356,7 +356,7 @@ func TestMasterKey_ToMap(t *testing.T) { Recipient: mockRecipient, EncryptedKey: "some-encrypted-key", } - assert.Equal(t, map[string]interface{}{ + assert.Equal(t, map[string]any{ "recipient": mockRecipient, "enc": key.EncryptedKey, }, key.ToMap()) diff --git a/age/tui.go b/age/tui.go index ba475f449e..5851145a6e 100644 --- a/age/tui.go +++ b/age/tui.go @@ -7,11 +7,11 @@ import ( var testOnlyAgePassword string -func printf(format string, v ...interface{}) { +func printf(format string, v ...any) { log.Printf("age: "+format, v...) } -func warningf(format string, v ...interface{}) { +func warningf(format string, v ...any) { log.Printf("age: warning: "+format, v...) } @@ -27,7 +27,7 @@ var pluginTerminalUI = &plugin.ClientUI{ if testing.Testing() && testOnlyAgePassword != "" { return testOnlyAgePassword, nil } - return pluginTerminalUIImpl.RequestValue(name, message, isSecret); + return pluginTerminalUIImpl.RequestValue(name, message, isSecret) }, Confirm: func(name, message, yes, no string) (choseYes bool, err error) { return pluginTerminalUIImpl.Confirm(name, message, yes, no) diff --git a/audit/audit.go b/audit/audit.go index 39989fb6b8..fab99a73a4 100644 --- a/audit/audit.go +++ b/audit/audit.go @@ -70,7 +70,7 @@ type config struct { var auditors []Auditor // SubmitEvent handles an event for all auditors -func SubmitEvent(event interface{}) { +func SubmitEvent(event any) { for _, auditor := range auditors { auditor.Handle(event) } @@ -87,7 +87,7 @@ type Auditor interface { // Handle() takes an audit event and attempts to persists it; // how it is persisted and how errors are handled is up to the // implementation of this interface. - Handle(event interface{}) + Handle(event any) } // DecryptEvent contains fields relevant to a decryption event @@ -133,7 +133,7 @@ func NewPostgresAuditor(connStr string) (*PostgresAuditor, error) { // Handle persists the audit event by writing a row to the // 'audit_event' postgres table -func (p *PostgresAuditor) Handle(event interface{}) { +func (p *PostgresAuditor) Handle(event any) { u, err := user.Current() if err != nil { log.Fatalf("Error getting current user for auditing: %s", err) diff --git a/azkv/keysource.go b/azkv/keysource.go index d7a73547f5..cb7c192686 100644 --- a/azkv/keysource.go +++ b/azkv/keysource.go @@ -119,7 +119,7 @@ func MasterKeysFromURLs(urls string) ([]*MasterKey, error) { if urls == "" { return keys, nil } - for _, s := range strings.Split(urls, ",") { + for s := range strings.SplitSeq(urls, ",") { k, err := NewMasterKeyFromURL(s) if err != nil { return nil, err @@ -171,7 +171,7 @@ func (key *MasterKey) Encrypt(dataKey []byte) error { } func (key *MasterKey) ensureKeyHasVersion(ctx context.Context) error { - if (key.Version != "") { + if key.Version != "" { // Nothing to do return nil } @@ -301,8 +301,8 @@ func (key *MasterKey) ToString() string { } // ToMap converts the MasterKey to a map for serialization purposes. -func (key MasterKey) ToMap() map[string]interface{} { - out := make(map[string]interface{}) +func (key MasterKey) ToMap() map[string]any { + out := make(map[string]any) out["vaultUrl"] = key.VaultURL out["key"] = key.Name out["version"] = key.Version diff --git a/azkv/keysource_test.go b/azkv/keysource_test.go index cc636f4366..b154e9deba 100644 --- a/azkv/keysource_test.go +++ b/azkv/keysource_test.go @@ -201,7 +201,7 @@ func TestMasterKey_ToMap(t *testing.T) { Version: "1", EncryptedKey: "this is encrypted", } - assert.Equal(t, map[string]interface{}{ + assert.Equal(t, map[string]any{ "vaultUrl": key.VaultURL, "key": key.Name, "version": key.Version, diff --git a/cmd/sops/common/common.go b/cmd/sops/common/common.go index 6d6fa0751a..65fccbf613 100644 --- a/cmd/sops/common/common.go +++ b/cmd/sops/common/common.go @@ -162,7 +162,7 @@ func LoadEncryptedFile(loader sops.EncryptedFileLoader, inputPath string) (*sops // NewExitError returns a cli.ExitError given an error (wrapped in a generic interface{}) // and an exit code to represent the failure -func NewExitError(i interface{}, exitCode int) *cli.ExitError { +func NewExitError(i any, exitCode int) *cli.ExitError { if userErr, ok := i.(sops.UserError); ok { return NewExitError(userErr.UserError(), exitCode) } @@ -365,7 +365,7 @@ func RecoverDataKeyFromBuggyKMS(opts GenericDecryptOpts, tree *sops.Tree) []byte keyToEdit := *originalKey - encCtxVals := map[string]interface{}{} + encCtxVals := map[string]any{} for _, v := range keyToEdit.EncryptionContext { encCtxVals[*v] = "" } @@ -406,13 +406,6 @@ type Diff struct { Removed []keys.MasterKey } -func max(a, b int) int { - if a > b { - return a - } - return b -} - // DiffKeyGroups returns the list of diffs found in two sops.keyGroup slices func DiffKeyGroups(ours, theirs []sops.KeyGroup) []Diff { var diffs []Diff diff --git a/cmd/sops/decrypt.go b/cmd/sops/decrypt.go index d0da0ddf18..c178bc005c 100644 --- a/cmd/sops/decrypt.go +++ b/cmd/sops/decrypt.go @@ -21,7 +21,7 @@ type decryptOpts struct { InputPath string ReadFromStdin bool IgnoreMAC bool - Extract []interface{} + Extract []any KeyServices []keyservice.KeyServiceClient DecryptionOrder []string } @@ -72,7 +72,7 @@ func decrypt(opts decryptOpts) (decryptedFile []byte, err error) { return decryptedFile, err } -func extract(tree *sops.Tree, path []interface{}, outputStore sops.Store) (output []byte, err error) { +func extract(tree *sops.Tree, path []any, outputStore sops.Store) (output []byte, err error) { v, err := tree.Branches[0].Truncate(path) if err != nil { return nil, fmt.Errorf("error truncating tree: %s", err) diff --git a/cmd/sops/main.go b/cmd/sops/main.go index 330c3bc8eb..2cab1b46e6 100644 --- a/cmd/sops/main.go +++ b/cmd/sops/main.go @@ -869,7 +869,7 @@ func main() { return toExitError(err) } - var extract []interface{} + var extract []any extract, err = parseTreePath(c.String("extract")) if err != nil { return common.NewExitError(fmt.Errorf("error parsing --extract path: %s", err), codes.InvalidTreePathFormat) @@ -1988,7 +1988,7 @@ func main() { } if isDecryptMode { - var extract []interface{} + var extract []any extract, err = parseTreePath(c.String("extract")) if err != nil { return common.NewExitError(fmt.Errorf("error parsing --extract path: %s", err), codes.InvalidTreePathFormat) @@ -2019,8 +2019,8 @@ func main() { } if isSetMode { - var path []interface{} - var value interface{} + var path []any + var value any path, value, err = extractSetArguments(c.String("set")) if err != nil { return toExitError(err) @@ -2398,10 +2398,10 @@ func outputStore(context *cli.Context, path string) (common.Store, error) { return common.DefaultStoreForPathOrFormat(storesConf, path, context.String("output-type")), nil } -func parseTreePath(arg string) ([]interface{}, error) { - var path []interface{} - components := strings.Split(arg, "[") - for _, component := range components { +func parseTreePath(arg string) ([]any, error) { + var path []any + components := strings.SplitSeq(arg, "[") + for component := range components { if component == "" { continue } @@ -2554,8 +2554,8 @@ func shamirThreshold(c *cli.Context, file string, optionalConfig *config.Config) return conf.ShamirThreshold, nil } -func jsonValueToTreeInsertableValue(jsonValue string) (interface{}, error) { - var valueToInsert interface{} +func jsonValueToTreeInsertableValue(jsonValue string) (any, error) { + var valueToInsert any err := encodingjson.Unmarshal([]byte(jsonValue), &valueToInsert) if err != nil { return nil, common.NewExitError("Value for --set is not valid JSON", codes.ErrorInvalidSetFormat) @@ -2581,7 +2581,7 @@ func jsonValueToTreeInsertableValue(jsonValue string) (interface{}, error) { return values[0], nil } -func extractSetArguments(set string) (path []interface{}, valueToInsert interface{}, err error) { +func extractSetArguments(set string) (path []any, valueToInsert any, err error) { // Set is a string with the format "python-dict-index json-value" // Since python-dict-index has to end with ], we split at "] " to get the two parts pathValuePair := strings.SplitAfterN(set, "] ", 2) diff --git a/cmd/sops/set.go b/cmd/sops/set.go index 7c56f77757..8318d31af8 100644 --- a/cmd/sops/set.go +++ b/cmd/sops/set.go @@ -15,8 +15,8 @@ type setOpts struct { OutputStore sops.Store InputPath string IgnoreMAC bool - TreePath []interface{} - Value interface{} + TreePath []any + Value any KeyServices []keyservice.KeyServiceClient DecryptionOrder []string } diff --git a/cmd/sops/subcommand/exec/exec.go b/cmd/sops/subcommand/exec/exec.go index 35f519c3cc..864382f5d8 100644 --- a/cmd/sops/subcommand/exec/exec.go +++ b/cmd/sops/subcommand/exec/exec.go @@ -139,8 +139,8 @@ func ExecWithEnv(opts ExecOpts) error { env = os.Environ() } - lines := bytes.Split(opts.Plaintext, []byte("\n")) - for _, line := range lines { + lines := bytes.SplitSeq(opts.Plaintext, []byte("\n")) + for line := range lines { if len(line) == 0 { continue } diff --git a/cmd/sops/subcommand/exec/exec_unix.go b/cmd/sops/subcommand/exec/exec_unix.go index f36d6326af..e987e168cf 100644 --- a/cmd/sops/subcommand/exec/exec_unix.go +++ b/cmd/sops/subcommand/exec/exec_unix.go @@ -1,5 +1,4 @@ //go:build !windows -// +build !windows package exec diff --git a/cmd/sops/subcommand/publish/publish.go b/cmd/sops/subcommand/publish/publish.go index aed1118de5..a910cefe49 100644 --- a/cmd/sops/subcommand/publish/publish.go +++ b/cmd/sops/subcommand/publish/publish.go @@ -74,7 +74,7 @@ func Run(opts Opts) error { return err } - data := map[string]interface{}{} + data := map[string]any{} switch conf.Destination.(type) { case *publish.S3Destination, *publish.GCSDestination: diff --git a/cmd/sops/subcommand/updatekeys/updatekeys.go b/cmd/sops/subcommand/updatekeys/updatekeys.go index 9dec066a67..33d65d5a44 100644 --- a/cmd/sops/subcommand/updatekeys/updatekeys.go +++ b/cmd/sops/subcommand/updatekeys/updatekeys.go @@ -124,10 +124,3 @@ func updateFile(opts Opts) error { log.Printf("File %s synced with new keys", opts.InputPath) return nil } - -func min(a, b int) int { - if a < b { - return a - } - return b -} diff --git a/cmd/sops/unset.go b/cmd/sops/unset.go index bb369748c3..52d3d1dee8 100644 --- a/cmd/sops/unset.go +++ b/cmd/sops/unset.go @@ -15,7 +15,7 @@ type unsetOpts struct { OutputStore sops.Store InputPath string IgnoreMAC bool - TreePath []interface{} + TreePath []any KeyServices []keyservice.KeyServiceClient DecryptionOrder []string } diff --git a/config/config.go b/config/config.go index 511df1bc15..66bb6b46e3 100644 --- a/config/config.go +++ b/config/config.go @@ -56,7 +56,7 @@ func LookupConfigFile(start string) (ConfigFileResult, error) { filepath := path.Dir(start) var foundAlternatePath string - for i := 0; i < maxDepth; i++ { + for range maxDepth { configPath := path.Join(filepath, configFileName) _, err := fs.Stat(configPath) if err == nil { @@ -176,24 +176,24 @@ type destinationRule struct { } type creationRule struct { - PathRegex string `yaml:"path_regex"` - KMS interface{} `yaml:"kms"` // string or []string - AwsProfile string `yaml:"aws_profile"` - Age interface{} `yaml:"age"` // string or []string - PGP interface{} `yaml:"pgp"` // string or []string - GCPKMS interface{} `yaml:"gcp_kms"` // string or []string - HCKms []string `yaml:"hckms"` - AzureKeyVault interface{} `yaml:"azure_keyvault"` // string or []string - VaultURI interface{} `yaml:"hc_vault_transit_uri"` // string or []string - KeyGroups []keyGroup `yaml:"key_groups"` - ShamirThreshold int `yaml:"shamir_threshold"` - UnencryptedSuffix string `yaml:"unencrypted_suffix"` - EncryptedSuffix string `yaml:"encrypted_suffix"` - UnencryptedRegex string `yaml:"unencrypted_regex"` - EncryptedRegex string `yaml:"encrypted_regex"` - UnencryptedCommentRegex string `yaml:"unencrypted_comment_regex"` - EncryptedCommentRegex string `yaml:"encrypted_comment_regex"` - MACOnlyEncrypted bool `yaml:"mac_only_encrypted"` + PathRegex string `yaml:"path_regex"` + KMS any `yaml:"kms"` // string or []string + AwsProfile string `yaml:"aws_profile"` + Age any `yaml:"age"` // string or []string + PGP any `yaml:"pgp"` // string or []string + GCPKMS any `yaml:"gcp_kms"` // string or []string + HCKms []string `yaml:"hckms"` + AzureKeyVault any `yaml:"azure_keyvault"` // string or []string + VaultURI any `yaml:"hc_vault_transit_uri"` // string or []string + KeyGroups []keyGroup `yaml:"key_groups"` + ShamirThreshold int `yaml:"shamir_threshold"` + UnencryptedSuffix string `yaml:"unencrypted_suffix"` + EncryptedSuffix string `yaml:"encrypted_suffix"` + UnencryptedRegex string `yaml:"unencrypted_regex"` + EncryptedRegex string `yaml:"encrypted_regex"` + UnencryptedCommentRegex string `yaml:"unencrypted_comment_regex"` + EncryptedCommentRegex string `yaml:"encrypted_comment_regex"` + MACOnlyEncrypted bool `yaml:"mac_only_encrypted"` } // Helper methods to safely extract keys as []string @@ -222,7 +222,7 @@ func (c *creationRule) GetVaultURIs() ([]string, error) { } // Utility function to handle both string and []string -func parseKeyField(field interface{}, fieldName string) ([]string, error) { +func parseKeyField(field any, fieldName string) ([]string, error) { if field == nil { return []string{}, nil } @@ -242,7 +242,7 @@ func parseKeyField(field interface{}, fieldName string) ([]string, error) { } } return result, nil - case []interface{}: + case []any: result := make([]string, len(v)) for i, item := range v { if str, ok := item.(string); ok { diff --git a/gcpkms/keysource.go b/gcpkms/keysource.go index 2acbdd9c0c..30bab0fb37 100644 --- a/gcpkms/keysource.go +++ b/gcpkms/keysource.go @@ -102,7 +102,7 @@ func MasterKeysFromResourceIDString(resourceID string) []*MasterKey { if resourceID == "" { return keys } - for _, s := range strings.Split(resourceID, ",") { + for s := range strings.SplitSeq(resourceID, ",") { keys = append(keys, NewMasterKeyFromResourceID(s)) } return keys @@ -270,8 +270,8 @@ func (key *MasterKey) ToString() string { } // ToMap converts the MasterKey to a map for serialization purposes. -func (key MasterKey) ToMap() map[string]interface{} { - out := make(map[string]interface{}) +func (key MasterKey) ToMap() map[string]any { + out := make(map[string]any) out["resource_id"] = key.ResourceID out["created_at"] = key.CreationDate.UTC().Format(time.RFC3339) out["enc"] = key.EncryptedKey diff --git a/gcpkms/keysource_test.go b/gcpkms/keysource_test.go index fa50b6bb87..d8b9b2d301 100644 --- a/gcpkms/keysource_test.go +++ b/gcpkms/keysource_test.go @@ -120,7 +120,7 @@ func TestMasterKey_ToMap(t *testing.T) { ResourceID: testResourceID, EncryptedKey: "this is encrypted", } - assert.Equal(t, map[string]interface{}{ + assert.Equal(t, map[string]any{ "resource_id": testResourceID, "enc": "this is encrypted", "created_at": "2016-10-31T10:00:00Z", diff --git a/hckms/keysource.go b/hckms/keysource.go index 32f897086a..9df87d8449 100644 --- a/hckms/keysource.go +++ b/hckms/keysource.go @@ -81,7 +81,7 @@ func NewMasterKeyFromKeyIDString(keyID string) ([]*MasterKey, error) { if keyID == "" { return keys, nil } - for _, s := range strings.Split(keyID, ",") { + for s := range strings.SplitSeq(keyID, ",") { s = strings.TrimSpace(s) if s == "" { continue @@ -245,8 +245,8 @@ func (key *MasterKey) ToString() string { } // ToMap converts the MasterKey to a map for serialization purposes. -func (key MasterKey) ToMap() map[string]interface{} { - out := make(map[string]interface{}) +func (key MasterKey) ToMap() map[string]any { + out := make(map[string]any) out["key_id"] = key.KeyID out["created_at"] = key.CreationDate.UTC().Format(time.RFC3339) out["enc"] = key.EncryptedKey diff --git a/hcvault/keysource.go b/hcvault/keysource.go index c60e11cfcb..c6de3daf44 100644 --- a/hcvault/keysource.go +++ b/hcvault/keysource.go @@ -150,7 +150,7 @@ func NewMasterKeysFromURIs(uris string) ([]*MasterKey, error) { if uris == "" { return keys, nil } - for _, uri := range strings.Split(uris, ",") { + for uri := range strings.SplitSeq(uris, ",") { if uri == "" { continue } @@ -313,8 +313,8 @@ func (key *MasterKey) ToString() string { } // ToMap converts the MasterKey to a map for serialization purposes. -func (key MasterKey) ToMap() map[string]interface{} { - out := make(map[string]interface{}) +func (key MasterKey) ToMap() map[string]any { + out := make(map[string]any) out["vault_address"] = key.VaultAddress out["key_name"] = key.KeyName out["engine_path"] = key.EnginePath @@ -339,9 +339,9 @@ func (key *MasterKey) decryptPath() string { } // encryptPayload returns the payload for an encrypt request of the dataKey. -func encryptPayload(dataKey []byte) map[string]interface{} { +func encryptPayload(dataKey []byte) map[string]any { encoded := base64.StdEncoding.EncodeToString(dataKey) - return map[string]interface{}{ + return map[string]any{ "plaintext": encoded, } } @@ -365,8 +365,8 @@ func encryptedKeyFromSecret(secret *api.Secret) (string, error) { // decryptPayload returns the payload for a decrypt request of the // encryptedKey. -func decryptPayload(encryptedKey string) map[string]interface{} { - return map[string]interface{}{ +func decryptPayload(encryptedKey string) map[string]any { + return map[string]any{ "ciphertext": encryptedKey, } } diff --git a/hcvault/keysource_test.go b/hcvault/keysource_test.go index 8059ed9ae8..b2f23ff5b9 100644 --- a/hcvault/keysource_test.go +++ b/hcvault/keysource_test.go @@ -316,7 +316,7 @@ func TestMasterKey_ToMap(t *testing.T) { VaultAddress: testVaultAddress, EncryptedKey: "some-encrypted-key", } - assert.Equal(t, map[string]interface{}{ + assert.Equal(t, map[string]any{ "vault_address": key.VaultAddress, "key_name": key.KeyName, "engine_path": key.EnginePath, @@ -334,9 +334,9 @@ func Test_encryptedKeyFromSecret(t *testing.T) { }{ {name: "nil secret", secret: nil, wantErr: true}, {name: "secret with nil data", secret: &api.Secret{Data: nil}, wantErr: true}, - {name: "secret without ciphertext data", secret: &api.Secret{Data: map[string]interface{}{"other": true}}, wantErr: true}, - {name: "ciphertext non string", secret: &api.Secret{Data: map[string]interface{}{"ciphertext": 123}}, wantErr: true}, - {name: "ciphertext data", secret: &api.Secret{Data: map[string]interface{}{"ciphertext": "secret string"}}, want: "secret string"}, + {name: "secret without ciphertext data", secret: &api.Secret{Data: map[string]any{"other": true}}, wantErr: true}, + {name: "ciphertext non string", secret: &api.Secret{Data: map[string]any{"ciphertext": 123}}, wantErr: true}, + {name: "ciphertext data", secret: &api.Secret{Data: map[string]any{"ciphertext": "secret string"}}, want: "secret string"}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { @@ -361,10 +361,10 @@ func Test_dataKeyFromSecret(t *testing.T) { }{ {name: "nil secret", secret: nil, wantErr: true}, {name: "secret with nil data", secret: &api.Secret{Data: nil}, wantErr: true}, - {name: "secret without plaintext data", secret: &api.Secret{Data: map[string]interface{}{"other": true}}, wantErr: true}, - {name: "plaintext non string", secret: &api.Secret{Data: map[string]interface{}{"plaintext": 123}}, wantErr: true}, - {name: "plaintext non base64", secret: &api.Secret{Data: map[string]interface{}{"plaintext": "notbase64"}}, wantErr: true}, - {name: "plaintext base64 data", secret: &api.Secret{Data: map[string]interface{}{"plaintext": "Zm9v"}}, want: []byte("foo")}, + {name: "secret without plaintext data", secret: &api.Secret{Data: map[string]any{"other": true}}, wantErr: true}, + {name: "plaintext non string", secret: &api.Secret{Data: map[string]any{"plaintext": 123}}, wantErr: true}, + {name: "plaintext non base64", secret: &api.Secret{Data: map[string]any{"plaintext": "notbase64"}}, wantErr: true}, + {name: "plaintext base64 data", secret: &api.Secret{Data: map[string]any{"plaintext": "Zm9v"}}, want: []byte("foo")}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { @@ -533,7 +533,7 @@ func createVaultKey(key *MasterKey) error { } p := path.Join(key.EnginePath, "keys", key.KeyName) - payload := make(map[string]interface{}) + payload := make(map[string]any) payload["type"] = "rsa-4096" if _, err = client.Logical().Write(p, payload); err != nil { return err diff --git a/keys/keys.go b/keys/keys.go index 06f67141d5..d9b0c2678c 100644 --- a/keys/keys.go +++ b/keys/keys.go @@ -9,6 +9,6 @@ type MasterKey interface { Decrypt() ([]byte, error) NeedsRotation() bool ToString() string - ToMap() map[string]interface{} + ToMap() map[string]any TypeToIdentifier() string } diff --git a/keyservice/client.go b/keyservice/client.go index f0a29fd06a..74302623b1 100644 --- a/keyservice/client.go +++ b/keyservice/client.go @@ -1,7 +1,7 @@ package keyservice import ( - "golang.org/x/net/context" + "context" "google.golang.org/grpc" ) diff --git a/keyservice/server.go b/keyservice/server.go index c1f1e8ce86..bdfadd2fb8 100644 --- a/keyservice/server.go +++ b/keyservice/server.go @@ -1,6 +1,7 @@ package keyservice import ( + "context" "fmt" "github.com/getsops/sops/v3/age" @@ -10,7 +11,6 @@ import ( "github.com/getsops/sops/v3/hcvault" "github.com/getsops/sops/v3/kms" "github.com/getsops/sops/v3/pgp" - "golang.org/x/net/context" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) diff --git a/keyservice/server_test.go b/keyservice/server_test.go index cc29c45280..55b9fa1987 100644 --- a/keyservice/server_test.go +++ b/keyservice/server_test.go @@ -1,6 +1,8 @@ package keyservice import ( + "maps" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "testing" @@ -49,9 +51,7 @@ func TestKmsKeyToMasterKey(t *testing.T) { t.Run(c.description, func(t *testing.T) { inputCtx := make(map[string]string) - for k, v := range c.expectedCtx { - inputCtx[k] = v - } + maps.Copy(inputCtx, c.expectedCtx) key := &KmsKey{ Arn: c.expectedArn, diff --git a/kms/keysource.go b/kms/keysource.go index b24b5ac3fa..a598f2bf4f 100644 --- a/kms/keysource.go +++ b/kms/keysource.go @@ -131,7 +131,7 @@ func MasterKeysFromArnString(arn string, context map[string]*string, awsProfile if arn == "" { return keys } - for _, s := range strings.Split(arn, ",") { + for s := range strings.SplitSeq(arn, ",") { keys = append(keys, NewMasterKeyFromArn(s, context, awsProfile)) } return keys @@ -139,11 +139,11 @@ func MasterKeysFromArnString(arn string, context map[string]*string, awsProfile // ParseKMSContext takes either a KMS context map or a comma-separated list of // KMS context key:value pairs, and returns a map. -func ParseKMSContext(in interface{}) map[string]*string { +func ParseKMSContext(in any) map[string]*string { const nonStringValueWarning = "Encryption context contains a non-string value, context will not be used" out := make(map[string]*string) switch in := in.(type) { - case map[string]interface{}: + case map[string]any: if len(in) == 0 { return nil } @@ -155,7 +155,7 @@ func ParseKMSContext(in interface{}) map[string]*string { } out[k] = &value } - case map[interface{}]interface{}: + case map[any]any: if len(in) == 0 { return nil } @@ -176,7 +176,7 @@ func ParseKMSContext(in interface{}) map[string]*string { if in == "" { return nil } - for _, kv := range strings.Split(in, ",") { + for kv := range strings.SplitSeq(in, ",") { kv := strings.Split(kv, ":") if len(kv) != 2 { log.Warn(nonStringValueWarning) @@ -364,8 +364,8 @@ func (key *MasterKey) ToString() string { } // ToMap converts the MasterKey to a map for serialization purposes. -func (key MasterKey) ToMap() map[string]interface{} { - out := make(map[string]interface{}) +func (key MasterKey) ToMap() map[string]any { + out := make(map[string]any) out["arn"] = key.Arn if key.Role != "" { out["role"] = key.Role diff --git a/kms/keysource_test.go b/kms/keysource_test.go index d4fde1ce81..79d0f6aa25 100644 --- a/kms/keysource_test.go +++ b/kms/keysource_test.go @@ -193,7 +193,7 @@ func TestParseKMSContext(t *testing.T) { value1 := "value1" value2 := "value2" // map from YAML - var yamlmap = map[interface{}]interface{}{ + var yamlmap = map[any]any{ "key1": value1, "key2": value2, } @@ -201,15 +201,15 @@ func TestParseKMSContext(t *testing.T) { "key1": &value1, "key2": &value2, }) - assert.Nil(t, ParseKMSContext(map[interface{}]interface{}{})) - assert.Nil(t, ParseKMSContext(map[interface{}]interface{}{ + assert.Nil(t, ParseKMSContext(map[any]any{})) + assert.Nil(t, ParseKMSContext(map[any]any{ "key1": 1, })) - assert.Nil(t, ParseKMSContext(map[interface{}]interface{}{ + assert.Nil(t, ParseKMSContext(map[any]any{ 1: "value", })) // map from JSON - var jsonmap = map[string]interface{}{ + var jsonmap = map[string]any{ "key1": value1, "key2": value2, } @@ -217,8 +217,8 @@ func TestParseKMSContext(t *testing.T) { "key1": &value1, "key2": &value2, }) - assert.Nil(t, ParseKMSContext(map[string]interface{}{})) - assert.Nil(t, ParseKMSContext(map[string]interface{}{ + assert.Nil(t, ParseKMSContext(map[string]any{})) + assert.Nil(t, ParseKMSContext(map[string]any{ "key1": 1, })) // sops 2.0.x formatted encryption context as a comma-separated list of key:value pairs @@ -420,7 +420,7 @@ func TestMasterKey_ToMap(t *testing.T) { "key2": &value2, }, } - assert.Equal(t, map[string]interface{}{ + assert.Equal(t, map[string]any{ "arn": "foo", "role": "bar", "enc": "this is encrypted", diff --git a/logging/logging.go b/logging/logging.go index 1e89c85ee9..d8902709d3 100644 --- a/logging/logging.go +++ b/logging/logging.go @@ -21,7 +21,7 @@ type TextFormatter struct { func (f *TextFormatter) Format(entry *logrus.Entry) ([]byte, error) { bytes, err := f.TextFormatter.Format(entry) name := color.New(color.Bold).Sprintf("[%s]", f.LoggerName) - return []byte(fmt.Sprintf("%s\t %s", name, bytes)), err + return fmt.Appendf(nil, "%s\t %s", name, bytes), err } // NewLogger is the constructor for a new Logger object with the given name diff --git a/pgp/keysource.go b/pgp/keysource.go index 63e31027ce..76ef4118cb 100644 --- a/pgp/keysource.go +++ b/pgp/keysource.go @@ -105,7 +105,7 @@ func MasterKeysFromFingerprintString(fingerprint string) []*MasterKey { if fingerprint == "" { return keys } - for _, s := range strings.Split(fingerprint, ",") { + for s := range strings.SplitSeq(fingerprint, ",") { keys = append(keys, NewMasterKeyFromFingerprint(s)) } return keys @@ -481,8 +481,8 @@ func (key *MasterKey) ToString() string { } // ToMap converts the MasterKey into a map for serialization purposes. -func (key MasterKey) ToMap() map[string]interface{} { - out := make(map[string]interface{}) +func (key MasterKey) ToMap() map[string]any { + out := make(map[string]any) out["fp"] = key.Fingerprint out["created_at"] = key.CreationDate.UTC().Format(time.RFC3339) out["enc"] = key.EncryptedKey diff --git a/pgp/keysource_test.go b/pgp/keysource_test.go index a35dab18c3..4c346168ee 100644 --- a/pgp/keysource_test.go +++ b/pgp/keysource_test.go @@ -546,7 +546,7 @@ func TestMasterKey_ToString(t *testing.T) { func TestMasterKey_ToMap(t *testing.T) { key := NewMasterKeyFromFingerprint(mockFingerprint) key.EncryptedKey = "data" - assert.Equal(t, map[string]interface{}{ + assert.Equal(t, map[string]any{ "fp": mockFingerprint, "created_at": key.CreationDate.UTC().Format(time.RFC3339), "enc": key.EncryptedKey, diff --git a/publish/gcs.go b/publish/gcs.go index 8bc5130faf..59c8935cbc 100644 --- a/publish/gcs.go +++ b/publish/gcs.go @@ -40,6 +40,6 @@ func (gcsd *GCSDestination) Upload(fileContents []byte, fileName string) error { } // Returns NotImplementedError -func (gcsd *GCSDestination) UploadUnencrypted(data map[string]interface{}, fileName string) error { +func (gcsd *GCSDestination) UploadUnencrypted(data map[string]any, fileName string) error { return &NotImplementedError{"GCS does not support uploading the unencrypted file contents."} } diff --git a/publish/publish.go b/publish/publish.go index 3301c60711..0277ed60b0 100644 --- a/publish/publish.go +++ b/publish/publish.go @@ -6,7 +6,7 @@ import "fmt" // must implement in order to be used by SOPS type Destination interface { Upload(fileContents []byte, fileName string) error - UploadUnencrypted(data map[string]interface{}, fileName string) error + UploadUnencrypted(data map[string]any, fileName string) error Path(fileName string) string } diff --git a/publish/s3.go b/publish/s3.go index 3fec2a7760..6273672862 100644 --- a/publish/s3.go +++ b/publish/s3.go @@ -46,6 +46,6 @@ func (s3d *S3Destination) Upload(fileContents []byte, fileName string) error { } // Returns NotImplementedError -func (s3d *S3Destination) UploadUnencrypted(data map[string]interface{}, fileName string) error { +func (s3d *S3Destination) UploadUnencrypted(data map[string]any, fileName string) error { return &NotImplementedError{"S3 does not support uploading the unencrypted file contents."} } diff --git a/publish/vault.go b/publish/vault.go index 4167ec8081..6543bd90d5 100644 --- a/publish/vault.go +++ b/publish/vault.go @@ -63,7 +63,7 @@ func (vaultd *VaultDestination) Upload(fileContents []byte, fileName string) err return &NotImplementedError{"Vault does not support uploading encrypted sops files directly."} } -func (vaultd *VaultDestination) UploadUnencrypted(data map[string]interface{}, fileName string) error { +func (vaultd *VaultDestination) UploadUnencrypted(data map[string]any, fileName string) error { client, err := vault.NewClient(nil) if err != nil { return err @@ -85,7 +85,7 @@ func (vaultd *VaultDestination) UploadUnencrypted(data map[string]interface{}, f return nil } - secretsData := make(map[string]interface{}) + secretsData := make(map[string]any) if vaultd.kvVersion == 1 { secretsData = data diff --git a/shamir/shamir.go b/shamir/shamir.go index e9b9e59f6f..e6b32104aa 100644 --- a/shamir/shamir.go +++ b/shamir/shamir.go @@ -73,9 +73,9 @@ func (p *polynomial) evaluate(x uint8) uint8 { func interpolatePolynomial(xSamples, ySamples []uint8, x uint8) uint8 { limit := len(xSamples) var result, basis uint8 - for i := 0; i < limit; i++ { + for i := range limit { basis = 1 - for j := 0; j < limit; j++ { + for j := range limit { if i == j { continue } @@ -237,7 +237,7 @@ func Split(secret []byte, parts, threshold int) ([][]byte, error) { // Generate a `parts` number of (x,y) pairs // We cheat by encoding the x value once as the final index, // so that it only needs to be stored once. - for i := 0; i < parts; i++ { + for i := range parts { // Add 1 to the xCoordinate because if it's 0, // then the result of p.evaluate(x) will be our secret x := uint8(i) + 1 diff --git a/shamir/shamir_test.go b/shamir/shamir_test.go index f2fa1f9090..7056fb7367 100644 --- a/shamir/shamir_test.go +++ b/shamir/shamir_test.go @@ -91,12 +91,12 @@ func TestCombine(t *testing.T) { // There is 5*4*3 possible choices, // we will just brute force try them all - for i := 0; i < 5; i++ { - for j := 0; j < 5; j++ { + for i := range 5 { + for j := range 5 { if j == i { continue } - for k := 0; k < 5; k++ { + for k := range 5 { if k == i || k == j { continue } @@ -198,7 +198,7 @@ func TestPolynomial_Eval(t *testing.T) { } func TestInterpolate_Rand(t *testing.T) { - for i := 0; i < 256; i++ { + for i := range 256 { p, err := makePolynomial(uint8(i), 2) if err != nil { t.Fatalf("err: %v", err) diff --git a/sops.go b/sops.go index c20959cffc..21dd012900 100644 --- a/sops.go +++ b/sops.go @@ -37,6 +37,7 @@ ordering. package sops // import "github.com/getsops/sops/v3" import ( + "context" "crypto/rand" "crypto/sha512" "fmt" @@ -49,7 +50,6 @@ import ( "time" "github.com/sirupsen/logrus" - "golang.org/x/net/context" "github.com/getsops/sops/v3/age" "github.com/getsops/sops/v3/audit" @@ -78,7 +78,7 @@ const MacMismatch = sopsError("MAC mismatch") const MetadataNotFound = sopsError("sops metadata not found") type SopsKeyNotFound struct { - Key interface{} + Key any Msg string } @@ -103,10 +103,10 @@ func init() { type Cipher interface { // Encrypt takes a plaintext, a key and additional data and returns the plaintext encrypted with the key, using the // additional data for authentication - Encrypt(plaintext interface{}, key []byte, additionalData string) (ciphertext string, err error) + Encrypt(plaintext any, key []byte, additionalData string) (ciphertext string, err error) // Encrypt takes a ciphertext, a key and additional data and returns the ciphertext encrypted with the key, using // the additional data for authentication - Decrypt(ciphertext string, key []byte, additionalData string) (plaintext interface{}, err error) + Decrypt(ciphertext string, key []byte, additionalData string) (plaintext any, err error) } // Comment represents a comment in the sops tree for the file formats that actually support them. @@ -117,8 +117,8 @@ type Comment struct { // TreeItem is an item inside sops's tree type TreeItem struct { - Key interface{} - Value interface{} + Key any + Value any } // TreeBranch is a branch inside sops's tree. It is a slice of TreeItems and is therefore ordered @@ -128,7 +128,7 @@ type TreeBranch []TreeItem // Trees usually have more than one branch type TreeBranches []TreeBranch -func equals(oneBranch interface{}, otherBranch interface{}) bool { +func equals(oneBranch any, otherBranch any) bool { switch oneBranch := oneBranch.(type) { case TreeBranch: otherBranch, ok := otherBranch.(TreeBranch) @@ -142,8 +142,8 @@ func equals(oneBranch interface{}, otherBranch interface{}) bool { } } return true - case []interface{}: - otherBranch, ok := otherBranch.([]interface{}) + case []any: + otherBranch, ok := otherBranch.([]any) if !ok || len(oneBranch) != len(otherBranch) { return false } @@ -170,15 +170,15 @@ func (branch TreeBranch) Equals(other TreeBranch) bool { return equals(branch, other) } -func valueFromPathAndLeaf(path []interface{}, leaf interface{}) interface{} { +func valueFromPathAndLeaf(path []any, leaf any) any { switch component := path[0].(type) { case int: if len(path) == 1 { - return []interface{}{ + return []any{ leaf, } } - return []interface{}{ + return []any{ valueFromPathAndLeaf(path[1:], leaf), } default: @@ -199,7 +199,7 @@ func valueFromPathAndLeaf(path []interface{}, leaf interface{}) interface{} { } } -func set(branch interface{}, path []interface{}, value interface{}) (interface{}, bool) { +func set(branch any, path []any, value any) (any, bool) { switch branch := branch.(type) { case TreeBranch: for i, item := range branch { @@ -220,7 +220,7 @@ func set(branch interface{}, path []interface{}, value interface{}) (interface{} return append(branch, newBranch[0]), true } return branch, true - case []interface{}: + case []any: position := path[0].(int) var changed bool if len(path) == 1 { @@ -245,12 +245,12 @@ func set(branch interface{}, path []interface{}, value interface{}) (interface{} } // Set sets a value on a given tree for the specified path -func (branch TreeBranch) Set(path []interface{}, value interface{}) (TreeBranch, bool) { +func (branch TreeBranch) Set(path []any, value any) (TreeBranch, bool) { v, changed := set(branch, path, value) return v.(TreeBranch), changed } -func unset(branch interface{}, path []interface{}) (interface{}, error) { +func unset(branch any, path []any) (any, error) { switch branch := branch.(type) { case TreeBranch: for i, item := range branch { @@ -268,7 +268,7 @@ func unset(branch interface{}, path []interface{}) (interface{}, error) { } } return nil, &SopsKeyNotFound{Msg: "Key not found: %s", Key: path[0]} - case []interface{}: + case []any: position := path[0].(int) if position >= len(branch) { return nil, &SopsKeyNotFound{Msg: "Index %d out of bounds", Key: path[0]} @@ -289,7 +289,7 @@ func unset(branch interface{}, path []interface{}) (interface{}, error) { } // Unset removes a value on a given tree from the specified path -func (branch TreeBranch) Unset(path []interface{}) (TreeBranch, error) { +func (branch TreeBranch) Unset(path []any) (TreeBranch, error) { v, err := unset(branch, path) if err != nil { return nil, err @@ -306,9 +306,9 @@ type Tree struct { } // Truncate truncates the tree to the path specified -func (branch TreeBranch) Truncate(path []interface{}) (interface{}, error) { +func (branch TreeBranch) Truncate(path []any) (any, error) { log.WithField("path", path).Info("Truncating tree") - var current interface{} = branch + var current any = branch for _, component := range path { switch component := component.(type) { case string: @@ -336,7 +336,7 @@ func (branch TreeBranch) Truncate(path []interface{}) (interface{}, error) { return current, nil } -func (branch TreeBranch) walkValue(in interface{}, path []string, commentsStack [][]string, onLeaves func(in interface{}, path []string, commentsStack [][]string) (interface{}, error)) (interface{}, error) { +func (branch TreeBranch) walkValue(in any, path []string, commentsStack [][]string, onLeaves func(in any, path []string, commentsStack [][]string) (any, error)) (any, error) { switch in := in.(type) { case string: return onLeaves(in, path, commentsStack) @@ -354,7 +354,7 @@ func (branch TreeBranch) walkValue(in interface{}, path []string, commentsStack return onLeaves(in, path, commentsStack) case TreeBranch: return branch.walkBranch(in, path, commentsStack, onLeaves) - case []interface{}: + case []any: return branch.walkSlice(in, path, commentsStack, onLeaves) case nil: // the value returned remains the same since it doesn't make @@ -365,7 +365,7 @@ func (branch TreeBranch) walkValue(in interface{}, path []string, commentsStack } } -func (branch TreeBranch) walkSlice(in []interface{}, path []string, commentsStack [][]string, onLeaves func(in interface{}, path []string, commentsStack [][]string) (interface{}, error)) ([]interface{}, error) { +func (branch TreeBranch) walkSlice(in []any, path []string, commentsStack [][]string, onLeaves func(in any, path []string, commentsStack [][]string) (any, error)) ([]any, error) { // Because append returns a new slice, the original stack is not changed. commentsStack = append(commentsStack, []string{}) for i, v := range in { @@ -388,7 +388,7 @@ func (branch TreeBranch) walkSlice(in []interface{}, path []string, commentsStac return in, nil } -func (branch TreeBranch) walkBranch(in TreeBranch, path []string, commentsStack [][]string, onLeaves func(in interface{}, path []string, commentsStack [][]string) (interface{}, error)) (TreeBranch, error) { +func (branch TreeBranch) walkBranch(in TreeBranch, path []string, commentsStack [][]string, onLeaves func(in any, path []string, commentsStack [][]string) (any, error)) (TreeBranch, error) { // Because append returns a new slice, the original stack is not changed. commentsStack = append(commentsStack, []string{}) for i, item := range in { @@ -531,7 +531,7 @@ func (tree Tree) Encrypt(key []byte, cipher Cipher) (string, error) { hash.Write(MACOnlyEncryptedInitialization) } walk := func(branch TreeBranch) error { - _, err := branch.walkBranch(branch, make([]string, 0), make([][]string, 0), func(in interface{}, path []string, commentsStack [][]string) (interface{}, error) { + _, err := branch.walkBranch(branch, make([]string, 0), make([][]string, 0), func(in any, path []string, commentsStack [][]string) (any, error) { _, ok := in.(Comment) encrypted := tree.shouldBeEncrypted(path, commentsStack, ok) if !tree.Metadata.MACOnlyEncrypted || encrypted { @@ -594,10 +594,10 @@ func (tree Tree) Decrypt(key []byte, cipher Cipher) (string, error) { hash.Write(MACOnlyEncryptedInitialization) } walk := func(branch TreeBranch) error { - _, err := branch.walkBranch(branch, make([]string, 0), make([][]string, 0), func(in interface{}, path []string, commentsStack [][]string) (interface{}, error) { + _, err := branch.walkBranch(branch, make([]string, 0), make([][]string, 0), func(in any, path []string, commentsStack [][]string) (any, error) { c, ok := in.(Comment) encrypted := tree.shouldBeEncrypted(path, commentsStack, ok) - var v interface{} + var v any if encrypted { var err error pathString := strings.Join(path, ":") + ":" @@ -718,7 +718,7 @@ type PlainFileEmitter interface { // ValueEmitter is the interface for emitting a value. It provides a way to emit // values from the internal SOPS representation so that they can be shown type ValueEmitter interface { - EmitValue(interface{}) ([]byte, error) + EmitValue(any) ([]byte, error) } // CheckEncrypted is the interface for testing whether a branch contains sops @@ -902,7 +902,7 @@ func sortKeyGroupIndices(group KeyGroup, decryptionOrder []string) []int { // initialize indices n := len(group) indices := make([]int, n) - for i := 0; i < n; i++ { + for i := range n { indices[i] = i } sort.SliceStable(indices, func(i, j int) bool { @@ -963,7 +963,7 @@ func (m Metadata) GetDataKey() ([]byte, error) { } // ToBytes converts a string, int, float or bool to a byte representation. -func ToBytes(in interface{}) ([]byte, error) { +func ToBytes(in any) ([]byte, error) { switch in := in.(type) { case string: return []byte(in), nil @@ -991,8 +991,8 @@ func ToBytes(in interface{}) ([]byte, error) { // EmitAsMap will emit the tree branches as a map. This is used by the publish // command for writing decrypted trees to various destinations. Should only be // used for outputting to data structures in code. -func EmitAsMap(in TreeBranches) (map[string]interface{}, error) { - data := map[string]interface{}{} +func EmitAsMap(in TreeBranches) (map[string]any, error) { + data := map[string]any{} for _, branch := range in { for _, item := range branch { @@ -1010,7 +1010,7 @@ func EmitAsMap(in TreeBranches) (map[string]interface{}, error) { return data, nil } -func encodeValueForMap(v interface{}) (interface{}, error) { +func encodeValueForMap(v any) (any, error) { switch v := v.(type) { case TreeBranch: return EmitAsMap([]TreeBranch{v}) diff --git a/sops_test.go b/sops_test.go index bbdc7aaf26..69c7405783 100644 --- a/sops_test.go +++ b/sops_test.go @@ -25,14 +25,14 @@ func reverse(s string) string { return string(r) } -func (c reverseCipher) Encrypt(value interface{}, key []byte, path string) (string, error) { +func (c reverseCipher) Encrypt(value any, key []byte, path string) (string, error) { b, err := ToBytes(value) if err != nil { return "", err } return reverse(string(b)), nil } -func (c reverseCipher) Decrypt(value string, key []byte, path string) (plaintext interface{}, err error) { +func (c reverseCipher) Decrypt(value string, key []byte, path string) (plaintext any, err error) { if value == "error" { return nil, fmt.Errorf("Error") } @@ -41,14 +41,14 @@ func (c reverseCipher) Decrypt(value string, key []byte, path string) (plaintext type encPrefixCipher struct{} -func (c encPrefixCipher) Encrypt(value interface{}, key []byte, path string) (string, error) { +func (c encPrefixCipher) Encrypt(value any, key []byte, path string) (string, error) { b, err := ToBytes(value) if err != nil { return "", err } return "ENC:" + string(b), nil } -func (c encPrefixCipher) Decrypt(value string, key []byte, path string) (plaintext interface{}, err error) { +func (c encPrefixCipher) Decrypt(value string, key []byte, path string) (plaintext any, err error) { v, ok := strings.CutPrefix(value, "ENC:") if !ok { return nil, fmt.Errorf("String not prefixed with 'ENC:'") @@ -382,7 +382,7 @@ func TestEncryptedCommentRegex(t *testing.T) { }, TreeItem{ Key: "array", - Value: []interface{}{ + Value: []any{ "bar", Comment{Value: "sops:enc"}, "baz", @@ -398,7 +398,7 @@ func TestEncryptedCommentRegex(t *testing.T) { }, TreeItem{ Key: "encarray", - Value: []interface{}{ + Value: []any{ "bar", "baz", }, @@ -438,7 +438,7 @@ func TestEncryptedCommentRegex(t *testing.T) { }, TreeItem{ Key: "array", - Value: []interface{}{ + Value: []any{ "bar", Comment{Value: "sops:enc"}, "zab", @@ -454,7 +454,7 @@ func TestEncryptedCommentRegex(t *testing.T) { }, TreeItem{ Key: "encarray", - Value: []interface{}{ + Value: []any{ "rab", "zab", }, @@ -474,9 +474,9 @@ func TestEncryptedCommentRegex(t *testing.T) { } expected[1].Value = "bar" expected[2].Value.(TreeBranch)[3].Value = "bar" - expected[3].Value.([]interface{})[2] = "baz" + expected[3].Value.([]any)[2] = "baz" expected[5].Key = Comment{Value: "after"} - expected[6].Value = []interface{}{ + expected[6].Value = []any{ "bar", "baz", } @@ -519,7 +519,7 @@ func TestUnencryptedCommentRegex(t *testing.T) { }, TreeItem{ Key: "array", - Value: []interface{}{ + Value: []any{ "bar", Comment{Value: "sops:noenc"}, "baz", @@ -535,7 +535,7 @@ func TestUnencryptedCommentRegex(t *testing.T) { }, TreeItem{ Key: "notencarray", - Value: []interface{}{ + Value: []any{ "bar", "baz", }, @@ -575,7 +575,7 @@ func TestUnencryptedCommentRegex(t *testing.T) { }, TreeItem{ Key: "array", - Value: []interface{}{ + Value: []any{ "rab", Comment{Value: "sops:noenc"}, "baz", @@ -591,7 +591,7 @@ func TestUnencryptedCommentRegex(t *testing.T) { }, TreeItem{ Key: "notencarray", - Value: []interface{}{ + Value: []any{ "bar", "baz", }, @@ -611,7 +611,7 @@ func TestUnencryptedCommentRegex(t *testing.T) { } expected[2].Value.(TreeBranch)[0].Value = "bar" expected[2].Value.(TreeBranch)[1].Key = Comment{Value: "before"} - expected[3].Value.([]interface{})[0] = "bar" + expected[3].Value.([]any)[0] = "bar" if !reflect.DeepEqual(tree.Branches[0], expected) { t.Errorf("Trees don't match: \ngot\t\t\t%+v,\nexpected\t\t%+v", tree.Branches[0], expected) } @@ -638,11 +638,11 @@ func TestUnencryptedCommentRegexFail(t *testing.T) { type MockCipher struct{} -func (m MockCipher) Encrypt(value interface{}, key []byte, path string) (string, error) { +func (m MockCipher) Encrypt(value any, key []byte, path string) (string, error) { return "a", nil } -func (m MockCipher) Decrypt(value string, key []byte, path string) (interface{}, error) { +func (m MockCipher) Decrypt(value string, key []byte, path string) (any, error) { return "a", nil } @@ -883,7 +883,7 @@ func TestTruncateTree(t *testing.T) { }, } expected := 3 - result, err := tree.Truncate([]interface{}{ + result, err := tree.Truncate([]any{ "bar", "foobar", 2, @@ -899,7 +899,7 @@ func TestTruncateTreeNotFound(t *testing.T) { Value: 2, }, } - result, err := tree.Truncate([]interface{}{"baz"}) + result, err := tree.Truncate([]any{"baz"}) assert.ErrorContains(t, err, "baz") assert.Nil(t, result, "Truncate result was not nil upon %s", err) } @@ -911,7 +911,7 @@ func TestTruncateTreeNotArray(t *testing.T) { Value: 2, }, } - result, err := tree.Truncate([]interface{}{"foo", 99}) + result, err := tree.Truncate([]any{"foo", 99}) assert.ErrorContains(t, err, "99") assert.Nil(t, result, "Truncate result was not nil upon %s", err) } @@ -920,13 +920,13 @@ func TestTruncateTreeArrayOutOfBounds(t *testing.T) { tree := TreeBranch{ TreeItem{ Key: "foo", - Value: []interface{}{ + Value: []any{ "one", "two", }, }, } - result, err := tree.Truncate([]interface{}{"foo", 99}) + result, err := tree.Truncate([]any{"foo", 99}) assert.ErrorContains(t, err, "99") assert.Nil(t, result, "Truncate result was not nil upon %s", err) } @@ -941,7 +941,7 @@ func TestEncryptComments(t *testing.T) { }, TreeItem{ Key: "list", - Value: []interface{}{ + Value: []any{ "1", Comment{Value: "bar"}, "2", @@ -955,7 +955,7 @@ func TestEncryptComments(t *testing.T) { } tree.Encrypt(bytes.Repeat([]byte{'f'}, 32), reverseCipher{}) assert.Equal(t, "oof", tree.Branches[0][0].Key.(Comment).Value) - assert.Equal(t, "rab", tree.Branches[0][1].Value.([]interface{})[1]) + assert.Equal(t, "rab", tree.Branches[0][1].Value.([]any)[1]) } func TestDecryptComments(t *testing.T) { @@ -968,7 +968,7 @@ func TestDecryptComments(t *testing.T) { }, TreeItem{ Key: "list", - Value: []interface{}{ + Value: []any{ "1", Comment{Value: "rab"}, "2", @@ -986,7 +986,7 @@ func TestDecryptComments(t *testing.T) { } tree.Decrypt(bytes.Repeat([]byte{'f'}, 32), reverseCipher{}) assert.Equal(t, "foo", tree.Branches[0][0].Key.(Comment).Value) - assert.Equal(t, "bar", tree.Branches[0][1].Value.([]interface{})[1]) + assert.Equal(t, "bar", tree.Branches[0][1].Value.([]any)[1]) } func TestDecryptUnencryptedComments(t *testing.T) { @@ -1023,7 +1023,7 @@ func TestSetNewKey(t *testing.T) { }, }, } - set, changed := branch.Set([]interface{}{"foo", "bar", "foo"}, "hello") + set, changed := branch.Set([]any{"foo", "bar", "foo"}, "hello") assert.Equal(t, true, changed) assert.Equal(t, "hello", set[0].Value.(TreeBranch)[0].Value.(TreeBranch)[1].Value) } @@ -1045,7 +1045,7 @@ func TestSetNewKeyUnchanged(t *testing.T) { }, }, } - set, changed := branch.Set([]interface{}{"foo", "bar", "baz"}, "foobar") + set, changed := branch.Set([]any{"foo", "bar", "baz"}, "foobar") assert.Equal(t, false, changed) assert.Equal(t, "foobar", set[0].Value.(TreeBranch)[0].Value.(TreeBranch)[0].Value) } @@ -1057,7 +1057,7 @@ func TestSetNewBranch(t *testing.T) { Value: "value", }, } - set, changed := branch.Set([]interface{}{"foo", "bar", "baz"}, "hello") + set, changed := branch.Set([]any{"foo", "bar", "baz"}, "hello") assert.Equal(t, true, changed) assert.Equal(t, TreeBranch{ TreeItem{ @@ -1085,15 +1085,15 @@ func TestSetArrayDeepNew(t *testing.T) { branch := TreeBranch{ TreeItem{ Key: "foo", - Value: []interface{}{ + Value: []any{ "one", "two", }, }, } - set, changed := branch.Set([]interface{}{"foo", 2, "bar"}, "hello") + set, changed := branch.Set([]any{"foo", 2, "bar"}, "hello") assert.Equal(t, true, changed) - assert.Equal(t, "hello", set[0].Value.([]interface{})[2].(TreeBranch)[0].Value) + assert.Equal(t, "hello", set[0].Value.([]any)[2].(TreeBranch)[0].Value) } func TestSetNewKeyDeep(t *testing.T) { @@ -1103,14 +1103,14 @@ func TestSetNewKeyDeep(t *testing.T) { Value: "bar", }, } - set, changed := branch.Set([]interface{}{"foo", "bar", "baz"}, "hello") + set, changed := branch.Set([]any{"foo", "bar", "baz"}, "hello") assert.Equal(t, true, changed) assert.Equal(t, "hello", set[0].Value.(TreeBranch)[0].Value.(TreeBranch)[0].Value) } func TestSetNewKeyOnEmptyBranch(t *testing.T) { branch := TreeBranch{} - set, changed := branch.Set([]interface{}{"foo", "bar", "baz"}, "hello") + set, changed := branch.Set([]any{"foo", "bar", "baz"}, "hello") assert.Equal(t, true, changed) assert.Equal(t, "hello", set[0].Value.(TreeBranch)[0].Value.(TreeBranch)[0].Value) } @@ -1119,23 +1119,23 @@ func TestSetArray(t *testing.T) { branch := TreeBranch{ TreeItem{ Key: "foo", - Value: []interface{}{ + Value: []any{ "one", "two", "three", }, }, } - set, changed := branch.Set([]interface{}{"foo", 0}, "uno") + set, changed := branch.Set([]any{"foo", 0}, "uno") assert.Equal(t, true, changed) - assert.Equal(t, "uno", set[0].Value.([]interface{})[0]) + assert.Equal(t, "uno", set[0].Value.([]any)[0]) } func TestSetArrayNew(t *testing.T) { branch := TreeBranch{} - set, changed := branch.Set([]interface{}{"foo", 0, 0}, "uno") + set, changed := branch.Set([]any{"foo", 0, 0}, "uno") assert.Equal(t, true, changed) - assert.Equal(t, "uno", set[0].Value.([]interface{})[0].([]interface{})[0]) + assert.Equal(t, "uno", set[0].Value.([]any)[0].([]any)[0]) } func TestSetExisting(t *testing.T) { @@ -1145,7 +1145,7 @@ func TestSetExisting(t *testing.T) { Value: "foobar", }, } - set, changed := branch.Set([]interface{}{"foo"}, "bar") + set, changed := branch.Set([]any{"foo"}, "bar") assert.Equal(t, true, changed) assert.Equal(t, "bar", set[0].Value) } @@ -1154,15 +1154,15 @@ func TestSetArrayLeafNewItem(t *testing.T) { branch := TreeBranch{ TreeItem{ Key: "array", - Value: []interface{}{}, + Value: []any{}, }, } - set, changed := branch.Set([]interface{}{"array", 2}, "hello") + set, changed := branch.Set([]any{"array", 2}, "hello") assert.Equal(t, true, changed) assert.Equal(t, TreeBranch{ TreeItem{ Key: "array", - Value: []interface{}{ + Value: []any{ "hello", }, }, @@ -1173,17 +1173,17 @@ func TestSetArrayNonLeaf(t *testing.T) { branch := TreeBranch{ TreeItem{ Key: "array", - Value: []interface{}{ + Value: []any{ 1, }, }, } - set, changed := branch.Set([]interface{}{"array", 0, "hello"}, "hello") + set, changed := branch.Set([]any{"array", 0, "hello"}, "hello") assert.Equal(t, true, changed) assert.Equal(t, TreeBranch{ TreeItem{ Key: "array", - Value: []interface{}{ + Value: []any{ TreeBranch{ TreeItem{ Key: "hello", @@ -1206,7 +1206,7 @@ func TestUnsetKeyRootLeaf(t *testing.T) { Value: "foofoo", }, } - unset, err := branch.Unset([]interface{}{"foofoo"}) + unset, err := branch.Unset([]any{"foofoo"}) assert.NoError(t, err) assert.Equal(t, TreeBranch{ TreeItem{ @@ -1232,7 +1232,7 @@ func TestUnsetKeyBranchLeaf(t *testing.T) { }, }, } - unset, err := branch.Unset([]interface{}{"foo", "barbar"}) + unset, err := branch.Unset([]any{"foo", "barbar"}) assert.NoError(t, err) assert.Equal(t, TreeBranch{ TreeItem{ @@ -1263,7 +1263,7 @@ func TestUnsetKeyBranch(t *testing.T) { }, }, } - unset, err := branch.Unset([]interface{}{"foofoo"}) + unset, err := branch.Unset([]any{"foofoo"}) assert.NoError(t, err) assert.Equal(t, TreeBranch{ TreeItem{ @@ -1280,7 +1280,7 @@ func TestUnsetKeyRootLastLeaf(t *testing.T) { Value: "foo", }, } - unset, err := branch.Unset([]interface{}{"foo"}) + unset, err := branch.Unset([]any{"foo"}) assert.NoError(t, err) assert.Equal(t, TreeBranch{}, unset) } @@ -1297,7 +1297,7 @@ func TestUnsetKeyBranchLastLeaf(t *testing.T) { }, }, } - unset, err := branch.Unset([]interface{}{"foo", "bar"}) + unset, err := branch.Unset([]any{"foo", "bar"}) assert.NoError(t, err) assert.Equal(t, TreeBranch{ TreeItem{ @@ -1314,7 +1314,7 @@ func TestUnsetKeyArray(t *testing.T) { Value: TreeBranch{ TreeItem{ Key: "bar", - Value: []interface{}{ + Value: []any{ TreeBranch{ TreeItem{ Key: "baz", @@ -1326,7 +1326,7 @@ func TestUnsetKeyArray(t *testing.T) { }, }, } - unset, err := branch.Unset([]interface{}{"foo", "bar"}) + unset, err := branch.Unset([]any{"foo", "bar"}) assert.NoError(t, err) assert.Equal(t, TreeBranch{ TreeItem{ @@ -1340,7 +1340,7 @@ func TestUnsetArrayItem(t *testing.T) { branch := TreeBranch{ TreeItem{ Key: "foo", - Value: []interface{}{ + Value: []any{ TreeBranch{ TreeItem{ Key: "bar", @@ -1356,12 +1356,12 @@ func TestUnsetArrayItem(t *testing.T) { }, }, } - unset, err := branch.Unset([]interface{}{"foo", 1}) + unset, err := branch.Unset([]any{"foo", 1}) assert.NoError(t, err) assert.Equal(t, TreeBranch{ TreeItem{ Key: "foo", - Value: []interface{}{ + Value: []any{ TreeBranch{ TreeItem{ Key: "bar", @@ -1377,7 +1377,7 @@ func TestUnsetKeyInArrayItem(t *testing.T) { branch := TreeBranch{ TreeItem{ Key: "foo", - Value: []interface{}{ + Value: []any{ TreeBranch{ TreeItem{ Key: "bar", @@ -1391,12 +1391,12 @@ func TestUnsetKeyInArrayItem(t *testing.T) { }, }, } - unset, err := branch.Unset([]interface{}{"foo", 0, "barbar"}) + unset, err := branch.Unset([]any{"foo", 0, "barbar"}) assert.NoError(t, err) assert.Equal(t, TreeBranch{ TreeItem{ Key: "foo", - Value: []interface{}{ + Value: []any{ TreeBranch{ TreeItem{ Key: "bar", @@ -1412,7 +1412,7 @@ func TestUnsetArrayLastItem(t *testing.T) { branch := TreeBranch{ TreeItem{ Key: "foo", - Value: []interface{}{ + Value: []any{ TreeBranch{ TreeItem{ Key: "bar", @@ -1422,12 +1422,12 @@ func TestUnsetArrayLastItem(t *testing.T) { }, }, } - unset, err := branch.Unset([]interface{}{"foo", 0}) + unset, err := branch.Unset([]any{"foo", 0}) assert.NoError(t, err) assert.Equal(t, TreeBranch{ TreeItem{ Key: "foo", - Value: []interface{}{}, + Value: []any{}, }, }, unset) } @@ -1444,7 +1444,7 @@ func TestUnsetKeyNotFound(t *testing.T) { }, }, } - unset, err := branch.Unset([]interface{}{"foo", "unknown-value"}) + unset, err := branch.Unset([]any{"foo", "unknown-value"}) assert.Equal(t, err.(*SopsKeyNotFound).Key, "unknown-value") assert.ErrorContains(t, err, "unknown-value") assert.Nil(t, unset, "Unset result was not nil upon %s", err) @@ -1454,7 +1454,7 @@ func TestUnsetKeyInArrayNotFound(t *testing.T) { branch := TreeBranch{ TreeItem{ Key: "foo", - Value: []interface{}{ + Value: []any{ TreeBranch{ TreeItem{ Key: "bar", @@ -1464,7 +1464,7 @@ func TestUnsetKeyInArrayNotFound(t *testing.T) { }, }, } - unset, err := branch.Unset([]interface{}{"foo", 0, "unknown"}) + unset, err := branch.Unset([]any{"foo", 0, "unknown"}) assert.Equal(t, err.(*SopsKeyNotFound).Key, "unknown") assert.Nil(t, unset, "Unset result was not nil upon %s", err) } @@ -1473,7 +1473,7 @@ func TestUnsetArrayItemOutOfBounds(t *testing.T) { branch := TreeBranch{ TreeItem{ Key: "foo", - Value: []interface{}{ + Value: []any{ TreeBranch{ TreeItem{ Key: "bar", @@ -1483,7 +1483,7 @@ func TestUnsetArrayItemOutOfBounds(t *testing.T) { }, }, } - unset, err := branch.Unset([]interface{}{"foo", 99}) + unset, err := branch.Unset([]any{"foo", 99}) assert.Equal(t, err.(*SopsKeyNotFound).Key, 99) assert.Nil(t, unset, "Unset result was not nil upon %s", err) } @@ -1495,17 +1495,17 @@ func TestUnsetKeyNotABranch(t *testing.T) { Value: 99, }, } - unset, err := branch.Unset([]interface{}{"foo", "bar"}) + unset, err := branch.Unset([]any{"foo", "bar"}) assert.ErrorContains(t, err, "Unsupported type") assert.Nil(t, unset, "Unset result was not nil upon %s", err) } func TestEmitAsMap(t *testing.T) { - expected := map[string]interface{}{ + expected := map[string]any{ "foobar": "barfoo", "number": 42, - "foo": map[string]interface{}{ - "bar": map[string]interface{}{ + "foo": map[string]any{ + "bar": map[string]any{ "baz": "foobar", }, }, diff --git a/stores/dotenv/store.go b/stores/dotenv/store.go index 991b582c91..bdd18ab1f2 100644 --- a/stores/dotenv/store.go +++ b/stores/dotenv/store.go @@ -35,7 +35,7 @@ func (store *Store) LoadEncryptedFile(in []byte) (sops.Tree, error) { } var resultBranch sops.TreeBranch - mdMap := make(map[string]interface{}) + mdMap := make(map[string]any) for _, item := range branches[0] { switch key := item.Key.(type) { case string: @@ -83,7 +83,7 @@ func (store *Store) LoadPlainFile(in []byte) (sops.TreeBranches, error) { var branches sops.TreeBranches var branch sops.TreeBranch - for _, line := range bytes.Split(in, []byte("\n")) { + for line := range bytes.SplitSeq(in, []byte("\n")) { if len(line) == 0 { continue } @@ -93,13 +93,13 @@ func (store *Store) LoadPlainFile(in []byte) (sops.TreeBranches, error) { Value: nil, }) } else { - pos := bytes.Index(line, []byte("=")) - if pos == -1 { + before, after, ok := bytes.Cut(line, []byte("=")) + if !ok { return nil, fmt.Errorf("invalid dotenv input line: %s", line) } branch = append(branch, sops.TreeItem{ - Key: string(line[:pos]), - Value: strings.Replace(string(line[pos+1:]), "\\n", "\n", -1), + Key: string(before), + Value: strings.Replace(string(after), "\\n", "\n", -1), }) } } @@ -163,7 +163,7 @@ func (store *Store) EmitPlainFile(in sops.TreeBranches) ([]byte, error) { } // EmitValue returns a single value as bytes -func (Store) EmitValue(v interface{}) ([]byte, error) { +func (Store) EmitValue(v any) ([]byte, error) { if s, ok := v.(string); ok { return []byte(s), nil } @@ -180,7 +180,7 @@ func (store *Store) EmitExample() []byte { } // Deprecated: use stores.IsComplexValue() instead! -func IsComplexValue(v interface{}) bool { +func IsComplexValue(v any) bool { return stores.IsComplexValue(v) } diff --git a/stores/flatten.go b/stores/flatten.go index f961d74d00..ce1114e62b 100644 --- a/stores/flatten.go +++ b/stores/flatten.go @@ -12,9 +12,9 @@ const listSeparator = "__list_" // flattenAndMerge flattens the provided value and merges into the // into map using prefix -func flattenAndMerge(into map[string]interface{}, prefix string, value interface{}) { +func flattenAndMerge(into map[string]any, prefix string, value any) { flattenedValue := flattenValue(value) - if flattenedValue, ok := flattenedValue.(map[string]interface{}); ok { + if flattenedValue, ok := flattenedValue.(map[string]any); ok { for flatK, flatV := range flattenedValue { into[prefix+flatK] = flatV } @@ -23,17 +23,17 @@ func flattenAndMerge(into map[string]interface{}, prefix string, value interface } } -func flattenValue(value interface{}) interface{} { - var output interface{} +func flattenValue(value any) any { + var output any switch value := value.(type) { - case map[string]interface{}: - newMap := make(map[string]interface{}) + case map[string]any: + newMap := make(map[string]any) for k, v := range value { flattenAndMerge(newMap, mapSeparator+k, v) } output = newMap - case []interface{}: - newMap := make(map[string]interface{}) + case []any: + newMap := make(map[string]any) for i, v := range value { flattenAndMerge(newMap, listSeparator+fmt.Sprintf("%d", i), v) } @@ -47,10 +47,10 @@ func flattenValue(value interface{}) interface{} { // Flatten flattens a map with potentially nested maps into a flat // map. Only string keys are allowed on both the top-level map and // child maps. -func Flatten(in map[string]interface{}) map[string]interface{} { - newMap := make(map[string]interface{}) +func Flatten(in map[string]any) map[string]any { + newMap := make(map[string]any) for k, v := range in { - if flat, ok := flattenValue(v).(map[string]interface{}); ok { + if flat, ok := flattenValue(v).(map[string]any); ok { for flatK, flatV := range flat { newMap[k+flatK] = flatV } @@ -62,8 +62,8 @@ func Flatten(in map[string]interface{}) map[string]interface{} { } // FlattenMetadata flattens a Metadata struct into a flat map. -func FlattenMetadata(md Metadata) (map[string]interface{}, error) { - var mdMap map[string]interface{} +func FlattenMetadata(md Metadata) (map[string]any, error) { + var mdMap map[string]any jsonBytes, err := json.Marshal(md) if err != nil { return nil, err @@ -77,7 +77,7 @@ func FlattenMetadata(md Metadata) (map[string]interface{}, error) { return flat, nil } -type token interface{} +type token any type mapToken struct { key string @@ -134,25 +134,25 @@ func tokenize(path string) []token { // and populates currentNode such that currentToken can be considered // processed. It inspects nextToken to decide what type to allocate // and assign under currentNode. -func unflatten(currentNode interface{}, currentToken, nextToken token, value interface{}) interface{} { +func unflatten(currentNode any, currentToken, nextToken token, value any) any { switch currentToken := currentToken.(type) { case mapToken: - currentNode := currentNode.(map[string]interface{}) + currentNode := currentNode.(map[string]any) switch nextToken := nextToken.(type) { case mapToken: if _, ok := currentNode[currentToken.key]; !ok { - currentNode[currentToken.key] = make(map[string]interface{}) + currentNode[currentToken.key] = make(map[string]any) } - next := currentNode[currentToken.key].(map[string]interface{}) + next := currentNode[currentToken.key].(map[string]any) return next case listToken: if _, ok := currentNode[currentToken.key]; !ok { - currentNode[currentToken.key] = make([]interface{}, nextToken.position+1) + currentNode[currentToken.key] = make([]any, nextToken.position+1) } - next := currentNode[currentToken.key].([]interface{}) + next := currentNode[currentToken.key].([]any) if nextToken.position >= len(next) { // Grow the slice and reassign it - newNext := make([]interface{}, nextToken.position+1) + newNext := make([]any, nextToken.position+1) copy(newNext, next) next = newNext currentNode[currentToken.key] = next @@ -162,22 +162,22 @@ func unflatten(currentNode interface{}, currentToken, nextToken token, value int currentNode[currentToken.key] = value } case listToken: - currentNode := currentNode.([]interface{}) + currentNode := currentNode.([]any) switch nextToken := nextToken.(type) { case mapToken: if currentNode[currentToken.position] == nil { - currentNode[currentToken.position] = make(map[string]interface{}) + currentNode[currentToken.position] = make(map[string]any) } - next := currentNode[currentToken.position].(map[string]interface{}) + next := currentNode[currentToken.position].(map[string]any) return next case listToken: if currentNode[currentToken.position] == nil { - currentNode[currentToken.position] = make([]interface{}, nextToken.position+1) + currentNode[currentToken.position] = make([]any, nextToken.position+1) } - next := currentNode[currentToken.position].([]interface{}) + next := currentNode[currentToken.position].([]any) if nextToken.position >= len(next) { // Grow the slice and reassign it - newNext := make([]interface{}, nextToken.position+1) + newNext := make([]any, nextToken.position+1) copy(newNext, next) next = newNext currentNode[currentToken.position] = next @@ -191,10 +191,10 @@ func unflatten(currentNode interface{}, currentToken, nextToken token, value int } // Unflatten unflattens a map flattened by Flatten -func Unflatten(in map[string]interface{}) map[string]interface{} { - newMap := make(map[string]interface{}) +func Unflatten(in map[string]any) map[string]any { + newMap := make(map[string]any) for k, v := range in { - var current interface{} = newMap + var current any = newMap tokens := append(tokenize(k), nil) for i := 0; i < len(tokens)-1; i++ { current = unflatten(current, tokens[i], tokens[i+1], v) @@ -204,7 +204,7 @@ func Unflatten(in map[string]interface{}) map[string]interface{} { } // UnflattenMetadata unflattens a map flattened by FlattenMetadata into Metadata -func UnflattenMetadata(in map[string]interface{}) (Metadata, error) { +func UnflattenMetadata(in map[string]any) (Metadata, error) { m := Unflatten(in) var md Metadata jsonBytes, err := json.Marshal(m) @@ -217,7 +217,7 @@ func UnflattenMetadata(in map[string]interface{}) (Metadata, error) { // DecodeNewLines replaces \\n with \n for all string values in the map. // Used by config stores that do not handle multi-line values (ini, dotenv). -func DecodeNewLines(m map[string]interface{}) { +func DecodeNewLines(m map[string]any) { for k, v := range m { if s, ok := v.(string); ok { m[k] = strings.Replace(s, "\\n", "\n", -1) @@ -227,7 +227,7 @@ func DecodeNewLines(m map[string]interface{}) { // EncodeNewLines replaces \n with \\n for all string values in the map. // Used by config stores that do not handle multi-line values (ini, dotenv). -func EncodeNewLines(m map[string]interface{}) { +func EncodeNewLines(m map[string]any) { for k, v := range m { if s, ok := v.(string); ok { m[k] = strings.Replace(s, "\n", "\\n", -1) @@ -236,7 +236,7 @@ func EncodeNewLines(m map[string]interface{}) { } // DecodeNonStrings will look for known metadata keys that are not strings and decode to the appropriate type -func DecodeNonStrings(m map[string]interface{}) error { +func DecodeNonStrings(m map[string]any) error { if v, ok := m["mac_only_encrypted"]; ok { m["mac_only_encrypted"] = false if v == "true" { @@ -268,7 +268,7 @@ func DecodeNonStrings(m map[string]interface{}) error { } // EncodeNonStrings will look for known metadata keys that are not strings and will encode it to strings -func EncodeNonStrings(m map[string]interface{}) { +func EncodeNonStrings(m map[string]any) { if v, found := m["mac_only_encrypted"]; found { if vBool, ok := v.(bool); ok { m["mac_only_encrypted"] = "false" diff --git a/stores/flatten_test.go b/stores/flatten_test.go index 6c75da3d19..acf0c12207 100644 --- a/stores/flatten_test.go +++ b/stores/flatten_test.go @@ -7,10 +7,10 @@ import ( ) func TestFlat(t *testing.T) { - input := map[string]interface{}{ + input := map[string]any{ "foo": "bar", } - expected := map[string]interface{}{ + expected := map[string]any{ "foo": "bar", } flattened := Flatten(input) @@ -20,13 +20,13 @@ func TestFlat(t *testing.T) { } func TestMap(t *testing.T) { - input := map[string]interface{}{ - "foo": map[string]interface{}{ + input := map[string]any{ + "foo": map[string]any{ "bar": 0, "baz": 0, }, } - expected := map[string]interface{}{ + expected := map[string]any{ "foo" + mapSeparator + "bar": 0, "foo" + mapSeparator + "baz": 0, } @@ -37,14 +37,14 @@ func TestMap(t *testing.T) { } func TestFlattenMapMoreNesting(t *testing.T) { - input := map[string]interface{}{ - "foo": map[string]interface{}{ - "bar": map[string]interface{}{ + input := map[string]any{ + "foo": map[string]any{ + "bar": map[string]any{ "baz": 0, }, }, } - expected := map[string]interface{}{ + expected := map[string]any{ "foo" + mapSeparator + "bar" + mapSeparator + "baz": 0, } flattened := Flatten(input) @@ -54,12 +54,12 @@ func TestFlattenMapMoreNesting(t *testing.T) { } func TestFlattenList(t *testing.T) { - input := map[string]interface{}{ - "foo": []interface{}{ + input := map[string]any{ + "foo": []any{ 0, }, } - expected := map[string]interface{}{ + expected := map[string]any{ "foo" + listSeparator + "0": 0, } flattened := Flatten(input) @@ -69,14 +69,14 @@ func TestFlattenList(t *testing.T) { } func TestFlattenListWithMap(t *testing.T) { - input := map[string]interface{}{ - "foo": []interface{}{ - map[string]interface{}{ + input := map[string]any{ + "foo": []any{ + map[string]any{ "bar": 0, }, }, } - expected := map[string]interface{}{ + expected := map[string]any{ "foo" + listSeparator + "0" + mapSeparator + "bar": 0, } flattened := Flatten(input) @@ -86,19 +86,19 @@ func TestFlattenListWithMap(t *testing.T) { } func TestFlatten(t *testing.T) { - input := map[string]interface{}{ + input := map[string]any{ "foo": "bar", - "baz": map[string]interface{}{ + "baz": map[string]any{ "foo": 2, - "bar": map[string]interface{}{ + "bar": map[string]any{ "foo": 2, }, }, - "qux": []interface{}{ + "qux": []any{ "hello", 1, 2, }, } - expected := map[string]interface{}{ + expected := map[string]any{ "foo": "bar", "baz" + mapSeparator + "foo": 2, "baz" + mapSeparator + "bar" + mapSeparator + "foo": 2, @@ -143,12 +143,12 @@ func TestTokenizeNested(t *testing.T) { func TestFlattenMetadata(t *testing.T) { tests := []struct { input Metadata - want map[string]interface{} + want map[string]any }{ - {Metadata{MACOnlyEncrypted: false}, map[string]interface{}{"mac_only_encrypted": nil}}, - {Metadata{MACOnlyEncrypted: true}, map[string]interface{}{"mac_only_encrypted": true}}, - {Metadata{MessageAuthenticationCode: "line1\nline2"}, map[string]interface{}{"mac": "line1\nline2"}}, - {Metadata{MessageAuthenticationCode: "line1\n\n\nline2\n\nline3"}, map[string]interface{}{"mac": "line1\n\n\nline2\n\nline3"}}, + {Metadata{MACOnlyEncrypted: false}, map[string]any{"mac_only_encrypted": nil}}, + {Metadata{MACOnlyEncrypted: true}, map[string]any{"mac_only_encrypted": true}}, + {Metadata{MessageAuthenticationCode: "line1\nline2"}, map[string]any{"mac": "line1\nline2"}}, + {Metadata{MessageAuthenticationCode: "line1\n\n\nline2\n\nline3"}, map[string]any{"mac": "line1\n\n\nline2\n\nline3"}}, } for _, tt := range tests { @@ -182,11 +182,11 @@ func TestFlattenMetadataToUnflattenMetadata(t *testing.T) { func TestDecodeNewLines(t *testing.T) { tests := []struct { - input map[string]interface{} - want map[string]interface{} + input map[string]any + want map[string]any }{ - {map[string]interface{}{"mac": "line1\\nline2"}, map[string]interface{}{"mac": "line1\nline2"}}, - {map[string]interface{}{"mac": "line1\\n\\n\\nline2\\n\\nline3"}, map[string]interface{}{"mac": "line1\n\n\nline2\n\nline3"}}, + {map[string]any{"mac": "line1\\nline2"}, map[string]any{"mac": "line1\nline2"}}, + {map[string]any{"mac": "line1\\n\\n\\nline2\\n\\nline3"}, map[string]any{"mac": "line1\n\n\nline2\n\nline3"}}, } for _, tt := range tests { @@ -199,11 +199,11 @@ func TestDecodeNewLines(t *testing.T) { func TestEncodeNewLines(t *testing.T) { tests := []struct { - input map[string]interface{} - want map[string]interface{} + input map[string]any + want map[string]any }{ - {map[string]interface{}{"mac": "line1\nline2"}, map[string]interface{}{"mac": "line1\\nline2"}}, - {map[string]interface{}{"mac": "line1\n\n\nline2\n\nline3"}, map[string]interface{}{"mac": "line1\\n\\n\\nline2\\n\\nline3"}}, + {map[string]any{"mac": "line1\nline2"}, map[string]any{"mac": "line1\\nline2"}}, + {map[string]any{"mac": "line1\n\n\nline2\n\nline3"}, map[string]any{"mac": "line1\\n\\n\\nline2\\n\\nline3"}}, } for _, tt := range tests { @@ -216,16 +216,16 @@ func TestEncodeNewLines(t *testing.T) { func TestDecodeNonStrings(t *testing.T) { tests := []struct { - input map[string]interface{} - want map[string]interface{} + input map[string]any + want map[string]any }{ - {map[string]interface{}{"mac_only_encrypted": "false"}, map[string]interface{}{"mac_only_encrypted": false}}, - {map[string]interface{}{"mac_only_encrypted": "true"}, map[string]interface{}{"mac_only_encrypted": true}}, - {map[string]interface{}{"mac_only_encrypted": "something-else"}, map[string]interface{}{"mac_only_encrypted": false}}, - {map[string]interface{}{"shamir_threshold": "2"}, map[string]interface{}{"shamir_threshold": 2}}, - {map[string]interface{}{"shamir_threshold": "002"}, map[string]interface{}{"shamir_threshold": 2}}, - {map[string]interface{}{"shamir_threshold": "123"}, map[string]interface{}{"shamir_threshold": 123}}, - {map[string]interface{}{"shamir_threshold": 123}, map[string]interface{}{"shamir_threshold": 123}}, + {map[string]any{"mac_only_encrypted": "false"}, map[string]any{"mac_only_encrypted": false}}, + {map[string]any{"mac_only_encrypted": "true"}, map[string]any{"mac_only_encrypted": true}}, + {map[string]any{"mac_only_encrypted": "something-else"}, map[string]any{"mac_only_encrypted": false}}, + {map[string]any{"shamir_threshold": "2"}, map[string]any{"shamir_threshold": 2}}, + {map[string]any{"shamir_threshold": "002"}, map[string]any{"shamir_threshold": 2}}, + {map[string]any{"shamir_threshold": "123"}, map[string]any{"shamir_threshold": 123}}, + {map[string]any{"shamir_threshold": 123}, map[string]any{"shamir_threshold": 123}}, } for _, tt := range tests { @@ -237,11 +237,11 @@ func TestDecodeNonStrings(t *testing.T) { func TestDecodeNonStringsErrors(t *testing.T) { tests := []struct { - input map[string]interface{} + input map[string]any want string }{ - {map[string]interface{}{"shamir_threshold": "foo"}, "shamir_threshold is not an integer: strconv.Atoi: parsing \"foo\": invalid syntax"}, - {map[string]interface{}{"shamir_threshold": true}, "shamir_threshold is neither a string nor an integer, but bool"}, + {map[string]any{"shamir_threshold": "foo"}, "shamir_threshold is not an integer: strconv.Atoi: parsing \"foo\": invalid syntax"}, + {map[string]any{"shamir_threshold": true}, "shamir_threshold is neither a string nor an integer, but bool"}, } for _, tt := range tests { @@ -253,13 +253,13 @@ func TestDecodeNonStringsErrors(t *testing.T) { func TestEncodeNonStrings(t *testing.T) { tests := []struct { - input map[string]interface{} - want map[string]interface{} + input map[string]any + want map[string]any }{ - {map[string]interface{}{"mac_only_encrypted": false}, map[string]interface{}{"mac_only_encrypted": "false"}}, - {map[string]interface{}{"mac_only_encrypted": true}, map[string]interface{}{"mac_only_encrypted": "true"}}, - {map[string]interface{}{"shamir_threshold": 2}, map[string]interface{}{"shamir_threshold": "2"}}, - {map[string]interface{}{"shamir_threshold": 123}, map[string]interface{}{"shamir_threshold": "123"}}, + {map[string]any{"mac_only_encrypted": false}, map[string]any{"mac_only_encrypted": "false"}}, + {map[string]any{"mac_only_encrypted": true}, map[string]any{"mac_only_encrypted": "true"}}, + {map[string]any{"shamir_threshold": 2}, map[string]any{"shamir_threshold": "2"}}, + {map[string]any{"shamir_threshold": 123}, map[string]any{"shamir_threshold": "123"}}, } for _, tt := range tests { diff --git a/stores/ini/store.go b/stores/ini/store.go index 79dd85eb36..4058192289 100644 --- a/stores/ini/store.go +++ b/stores/ini/store.go @@ -173,7 +173,7 @@ func (store *Store) LoadEncryptedFile(in []byte) (sops.Tree, error) { } func (store *Store) iniSectionToMetadata(sopsSection *ini.Section) (stores.Metadata, error) { - metadataHash := make(map[string]interface{}) + metadataHash := make(map[string]any) for k, v := range sopsSection.KeysHash() { metadataHash[k] = v } @@ -242,7 +242,7 @@ func (store *Store) EmitPlainFile(in sops.TreeBranches) ([]byte, error) { return out, nil } -func (store Store) encodeValue(v interface{}) ([]byte, error) { +func (store Store) encodeValue(v any) ([]byte, error) { switch v := v.(type) { case sops.TreeBranches: return store.encodeTree(v) @@ -252,7 +252,7 @@ func (store Store) encodeValue(v interface{}) ([]byte, error) { } // EmitValue returns a single value encoded in a generic interface{} as bytes -func (store *Store) EmitValue(v interface{}) ([]byte, error) { +func (store *Store) EmitValue(v any) ([]byte, error) { return store.encodeValue(v) } diff --git a/stores/ini/store_test.go b/stores/ini/store_test.go index b1aff6cf9a..8c471b2eb0 100644 --- a/stores/ini/store_test.go +++ b/stores/ini/store_test.go @@ -132,7 +132,7 @@ func TestEncodeIniWithDuplicateSections(t *testing.T) { sops.TreeBranch{ sops.TreeItem{ Key: "DEFAULT", - Value: interface{}(sops.TreeBranch(nil)), + Value: any(sops.TreeBranch(nil)), }, sops.TreeItem{ Key: "foo", diff --git a/stores/json/store.go b/stores/json/store.go index 16b0c03ea8..9330e3fde6 100644 --- a/stores/json/store.go +++ b/stores/json/store.go @@ -92,7 +92,7 @@ func (store BinaryStore) EmitPlainFile(in sops.TreeBranches) ([]byte, error) { // EmitValue extracts a value from a generic interface{} object representing a structured set // of binary files -func (store BinaryStore) EmitValue(v interface{}) ([]byte, error) { +func (store BinaryStore) EmitValue(v any) ([]byte, error) { return nil, fmt.Errorf("Binary files are not structured and extracting a single value is not possible") } @@ -101,8 +101,8 @@ func (store BinaryStore) EmitExample() []byte { return []byte("Welcome to SOPS! Edit this file as you please!") } -func (store Store) sliceFromJSONDecoder(dec *json.Decoder) ([]interface{}, error) { - var slice []interface{} +func (store Store) sliceFromJSONDecoder(dec *json.Decoder) ([]any, error) { + var slice []any for { t, err := dec.Token() if err != nil { @@ -186,47 +186,49 @@ func (store Store) treeBranchFromJSONDecoder(dec *json.Decoder) (sops.TreeBranch } } -func (store Store) encodeValue(v interface{}) ([]byte, error) { +func (store Store) encodeValue(v any) ([]byte, error) { switch v := v.(type) { case sops.TreeBranch: return store.encodeTree(v) - case []interface{}: + case []any: return store.encodeArray(v) default: return json.Marshal(v) } } -func (store Store) encodeArray(array []interface{}) ([]byte, error) { - out := "[" +func (store Store) encodeArray(array []any) ([]byte, error) { + var out strings.Builder + out.WriteString("[") empty := true for _, item := range array { if _, ok := item.(sops.Comment); ok { continue } if !empty { - out += "," + out.WriteString(",") } v, err := store.encodeValue(item) if err != nil { return nil, err } - out += string(v) + out.WriteString(string(v)) empty = false } - out += "]" - return []byte(out), nil + out.WriteString("]") + return []byte(out.String()), nil } func (store Store) encodeTree(tree sops.TreeBranch) ([]byte, error) { - out := "{" + var out strings.Builder + out.WriteString("{") empty := true for _, item := range tree { if _, ok := item.Key.(sops.Comment); ok { continue } if !empty { - out += "," + out.WriteString(",") } v, err := store.encodeValue(item.Value) if err != nil { @@ -236,10 +238,10 @@ func (store Store) encodeTree(tree sops.TreeBranch) ([]byte, error) { if err != nil { return nil, fmt.Errorf("Error encoding key %s: %s", k, err) } - out += string(k) + `: ` + string(v) + out.WriteString(string(k) + `: ` + string(v)) empty = false } - return []byte(out + "}"), nil + return []byte(out.String() + "}"), nil } func (store Store) jsonFromTreeBranch(branch sops.TreeBranch) ([]byte, error) { @@ -360,7 +362,7 @@ func (store *Store) EmitPlainFile(in sops.TreeBranches) ([]byte, error) { // EmitValue returns bytes corresponding to a single encoded value // in a generic interface{} object -func (store *Store) EmitValue(v interface{}) ([]byte, error) { +func (store *Store) EmitValue(v any) ([]byte, error) { s, err := store.encodeValue(v) if err != nil { return nil, err diff --git a/stores/json/store_test.go b/stores/json/store_test.go index 288a7f2404..a5c2bbf067 100644 --- a/stores/json/store_test.go +++ b/stores/json/store_test.go @@ -86,7 +86,7 @@ func TestDecodeJSON(t *testing.T) { }, sops.TreeItem{ Key: "GlossSeeAlso", - Value: []interface{}{ + Value: []any{ "GML", "XML", }, @@ -175,7 +175,7 @@ func TestDecodeJSONWithArray(t *testing.T) { Value: sops.TreeBranch{ sops.TreeItem{ Key: "foo", - Value: []interface{}{1.0, 2.0, 3.0}, + Value: []any{1.0, 2.0, 3.0}, }, }, }, @@ -194,7 +194,7 @@ func TestDecodeJSONArrayOfObjects(t *testing.T) { expected := sops.TreeBranch{ sops.TreeItem{ Key: "foo", - Value: []interface{}{ + Value: []any{ sops.TreeBranch{ sops.TreeItem{ Key: "bar", @@ -220,9 +220,9 @@ func TestDecodeJSONArrayOfArrays(t *testing.T) { expected := sops.TreeBranch{ sops.TreeItem{ Key: "foo", - Value: []interface{}{ - []interface{}{ - []interface{}{ + Value: []any{ + []any{ + []any{ "foo", sops.TreeBranch{ sops.TreeItem{ @@ -288,7 +288,7 @@ func TestEncodeJSONArrayOfObjects(t *testing.T) { sops.TreeBranch{ sops.TreeItem{ Key: "foo", - Value: []interface{}{ + Value: []any{ sops.TreeBranch{ sops.TreeItem{ Key: "foo", @@ -423,7 +423,7 @@ func TestIndentTwoSpaces(t *testing.T) { sops.TreeBranch{ sops.TreeItem{ Key: "foo", - Value: []interface{}{ + Value: []any{ sops.TreeBranch{ sops.TreeItem{ Key: "foo", @@ -466,7 +466,7 @@ func TestIndentDefault(t *testing.T) { sops.TreeBranch{ sops.TreeItem{ Key: "foo", - Value: []interface{}{ + Value: []any{ sops.TreeBranch{ sops.TreeItem{ Key: "foo", @@ -509,7 +509,7 @@ func TestNoIndent(t *testing.T) { sops.TreeBranch{ sops.TreeItem{ Key: "foo", - Value: []interface{}{ + Value: []any{ sops.TreeBranch{ sops.TreeItem{ Key: "foo", @@ -574,7 +574,7 @@ func TestComments(t *testing.T) { sops.TreeBranch{ sops.TreeItem{ Key: "foo", - Value: []interface{}{ + Value: []any{ sops.Comment{Value: " comment 0"}, sops.TreeBranch{ sops.TreeItem{ diff --git a/stores/stores.go b/stores/stores.go index 11e362a5da..3d67554cd3 100644 --- a/stores/stores.go +++ b/stores/stores.go @@ -503,7 +503,7 @@ var ExampleComplexTree = sops.Tree{ }, sops.TreeItem{ Key: "example_array", - Value: []interface{}{ + Value: []any{ "example_value1", "example_value2", }, @@ -514,7 +514,7 @@ var ExampleComplexTree = sops.Tree{ }, sops.TreeItem{ Key: "example_booleans", - Value: []interface{}{true, false}, + Value: []any{true, false}, }, }, }, @@ -582,9 +582,9 @@ func HasSopsTopLevelKey(branch sops.TreeBranch) bool { } // IsComplexValue returns true if the given value is an array or dictionary/hash. -func IsComplexValue(v interface{}) bool { +func IsComplexValue(v any) bool { switch v.(type) { - case []interface{}: + case []any: return true case sops.TreeBranch: return true @@ -594,7 +594,7 @@ func IsComplexValue(v interface{}) bool { // ValToString converts a simple value to a string. // It does not handle complex values (arrays and mappings). -func ValToString(v interface{}) string { +func ValToString(v any) string { switch v := v.(type) { case float64: result := strconv.FormatFloat(v, 'G', -1, 64) diff --git a/stores/stores_test.go b/stores/stores_test.go index 31ced210aa..c7c928e917 100644 --- a/stores/stores_test.go +++ b/stores/stores_test.go @@ -7,18 +7,17 @@ import ( "github.com/stretchr/testify/assert" ) - func TestValToString(t *testing.T) { assert.Equal(t, "1", ValToString(1)) assert.Equal(t, "1.0", ValToString(1.0)) assert.Equal(t, "1.1", ValToString(1.10)) assert.Equal(t, "1.23", ValToString(1.23)) assert.Equal(t, "1.2345678901234567", ValToString(1.234567890123456789)) - assert.Equal(t, "200000.0", ValToString(2E5)) - assert.Equal(t, "-2E+10", ValToString(-2E10)) - assert.Equal(t, "2E-10", ValToString(2E-10)) - assert.Equal(t, "1.2345E+100", ValToString(1.2345E100)) - assert.Equal(t, "1.2345E-100", ValToString(1.2345E-100)) + assert.Equal(t, "200000.0", ValToString(2e5)) + assert.Equal(t, "-2E+10", ValToString(-2e10)) + assert.Equal(t, "2E-10", ValToString(2e-10)) + assert.Equal(t, "1.2345E+100", ValToString(1.2345e100)) + assert.Equal(t, "1.2345E-100", ValToString(1.2345e-100)) assert.Equal(t, "true", ValToString(true)) assert.Equal(t, "false", ValToString(false)) ts, _ := time.Parse(time.RFC3339, "2025-01-02T03:04:05Z") diff --git a/stores/yaml/store.go b/stores/yaml/store.go index 4d48e2c486..5fede762a1 100644 --- a/stores/yaml/store.go +++ b/stores/yaml/store.go @@ -28,17 +28,17 @@ func (store *Store) Name() string { return "yaml" } -func (store Store) appendCommentToList(comment string, list []interface{}) []interface{} { +func (store Store) appendCommentToList(comment string, list []any) []any { return store.appendCommentToListWithInline(comment, list, false) } -func (store Store) appendInlineCommentToList(comment string, list []interface{}) []interface{} { +func (store Store) appendInlineCommentToList(comment string, list []any) []any { return store.appendCommentToListWithInline(comment, list, true) } -func (store Store) appendCommentToListWithInline(comment string, list []interface{}, inline bool) []interface{} { +func (store Store) appendCommentToListWithInline(comment string, list []any, inline bool) []any { if comment != "" { - for _, commentLine := range strings.Split(comment, "\n") { + for commentLine := range strings.SplitSeq(comment, "\n") { if commentLine != "" { list = append(list, sops.Comment{ Value: commentLine[1:], @@ -60,7 +60,7 @@ func (store Store) appendInlineCommentToMap(comment string, branch sops.TreeBran func (store Store) appendCommentToMapWithInline(comment string, branch sops.TreeBranch, inline bool) sops.TreeBranch { if comment != "" { - for _, commentLine := range strings.Split(comment, "\n") { + for commentLine := range strings.SplitSeq(comment, "\n") { if commentLine != "" { branch = append(branch, sops.TreeItem{ Key: sops.Comment{ @@ -75,12 +75,12 @@ func (store Store) appendCommentToMapWithInline(comment string, branch sops.Tree return branch } -func (store Store) nodeToTreeValue(node *yaml.Node, commentsWereHandled bool) (interface{}, error) { +func (store Store) nodeToTreeValue(node *yaml.Node, commentsWereHandled bool) (any, error) { switch node.Kind { case yaml.DocumentNode: panic("documents should never be passed here") case yaml.SequenceNode: - var result []interface{} + var result []any if !commentsWereHandled { result = store.appendCommentToList(node.HeadComment, result) result = store.appendCommentToList(node.LineComment, result) @@ -103,7 +103,7 @@ func (store Store) nodeToTreeValue(node *yaml.Node, commentsWereHandled bool) (i branch := make(sops.TreeBranch, 0) return store.appendYamlNodeToTreeBranch(node, branch, commentsWereHandled) case yaml.ScalarNode: - var result interface{} + var result any node.Decode(&result) return result, nil case yaml.AliasNode: @@ -139,7 +139,7 @@ func (store Store) appendYamlNodeToTreeBranch(node *yaml.Node, branch sops.TreeB branch = store.appendCommentToMap(value.HeadComment, branch) branch = store.appendInlineCommentToMap(value.LineComment, branch) } - var keyValue interface{} + var keyValue any key.Decode(&keyValue) valueTV, err := store.nodeToTreeValue(value, handleValueComments) if err != nil { @@ -214,14 +214,14 @@ func (store *Store) addCommentsLine(node *yaml.Node, comments []string) []string return nil } -func (store *Store) treeValueToNode(in interface{}) *yaml.Node { +func (store *Store) treeValueToNode(in any) *yaml.Node { switch in := in.(type) { case sops.TreeBranch: var mapping = &yaml.Node{} mapping.Kind = yaml.MappingNode store.appendTreeBranch(in, mapping) return mapping - case []interface{}: + case []any: var sequence = &yaml.Node{} sequence.Kind = yaml.SequenceNode store.appendSequence(in, sequence) @@ -233,7 +233,7 @@ func (store *Store) treeValueToNode(in interface{}) *yaml.Node { } } -func (store *Store) appendSequence(in []interface{}, sequence *yaml.Node) { +func (store *Store) appendSequence(in []any, sequence *yaml.Node) { var headComments []string var inlineComments []string var beginning bool = true @@ -354,7 +354,7 @@ func (store *Store) LoadPlainFile(in []byte) (sops.TreeBranches, error) { if len(in) > 0 { // This is needed to make the yaml-decoder check for uniqueness of keys // Can probably be removed when https://github.com/go-yaml/yaml/issues/814 is merged. - if err := yaml.NewDecoder(bytes.NewReader(in)).Decode(make(map[string]interface{})); err != nil { + if err := yaml.NewDecoder(bytes.NewReader(in)).Decode(make(map[string]any)); err != nil { return nil, err } } @@ -455,7 +455,7 @@ func (store *Store) EmitPlainFile(branches sops.TreeBranches) ([]byte, error) { // EmitValue returns bytes corresponding to a single encoded value // in a generic interface{} object -func (store *Store) EmitValue(v interface{}) ([]byte, error) { +func (store *Store) EmitValue(v any) ([]byte, error) { n := store.treeValueToNode(v) return yaml.Marshal(n) } diff --git a/stores/yaml/store_test.go b/stores/yaml/store_test.go index 42445ae809..f6b9185c64 100644 --- a/stores/yaml/store_test.go +++ b/stores/yaml/store_test.go @@ -63,13 +63,13 @@ var ALIASES_BRANCHES = sops.TreeBranches{ sops.TreeBranch{ sops.TreeItem{ Key: "key1", - Value: []interface{}{ + Value: []any{ "foo", }, }, sops.TreeItem{ Key: "key2", - Value: []interface{}{ + Value: []any{ "foo", }, }, @@ -156,7 +156,7 @@ var COMMENT_6_BRANCHES = sops.TreeBranches{ sops.TreeBranch{ sops.TreeItem{ Key: "a", - Value: []interface{}{ + Value: []any{ "a", sops.Comment{Value: " I no longer get duplicated"}, sops.TreeBranch{}, @@ -197,7 +197,7 @@ var COMMENT_7_BRANCHES = sops.TreeBranches{ }, sops.TreeItem{ Key: "e", - Value: []interface{}{ + Value: []any{ "f", }, }, diff --git a/version/version.go b/version/version.go index 940f227b86..fd76c116d6 100644 --- a/version/version.go +++ b/version/version.go @@ -191,8 +191,8 @@ func (f releaseFetcher) LatestReleaseUsingRedirect(repository string) (tag, url } tagMarker := "releases/tag/" - if tagIndex := strings.Index(location, tagMarker); tagIndex != -1 { - return location[tagIndex+len(tagMarker):], location, nil + if _, after, ok := strings.Cut(location, tagMarker); ok { + return after, location, nil } return "", "", fmt.Errorf("unexpected Location header: %s", location) } diff --git a/version/version_test.go b/version/version_test.go index 54f6340e3d..b08431c327 100644 --- a/version/version_test.go +++ b/version/version_test.go @@ -2,6 +2,7 @@ package version import ( "fmt" + "maps" "net/http" "net/http/httptest" "testing" @@ -251,9 +252,7 @@ func (m *mockServer) start() *httptest.Server { return } - for key, values := range m.header { - w.Header()[key] = values - } + maps.Copy(w.Header(), m.header) w.Header().Set("Content-Type", "application/json") w.WriteHeader(m.statusCode) fmt.Fprintln(w, m.response)