From dad8100da89862172ba224f4bfc1477dcf25c1a5 Mon Sep 17 00:00:00 2001 From: Damien Nozay Date: Tue, 15 Oct 2019 15:08:41 -0700 Subject: [PATCH 1/5] fix for #548 --- cmd/sops/common/common.go | 32 ++++++++++++++++++++++++++++++++ cmd/sops/main.go | 32 ++------------------------------ decrypt/decrypt.go | 36 ++++++++++++++++-------------------- 3 files changed, 50 insertions(+), 50 deletions(-) diff --git a/cmd/sops/common/common.go b/cmd/sops/common/common.go index 6c5ae413c..465a4d002 100644 --- a/cmd/sops/common/common.go +++ b/cmd/sops/common/common.go @@ -139,6 +139,24 @@ func IsIniFile(path string) bool { return strings.HasSuffix(path, ".ini") } +// DefaultStoreForFormat returns the correct format-specific implementation +// of the Store interface given the format string +func DefaultStoreForFormat(format string) Store { + switch format { + case "yaml": + return &yaml.Store{} + case "json": + return &json.Store{} + case "dotenv": + return &dotenv.Store{} + case "ini": + return &ini.Store{} + case "binary": + return &json.BinaryStore{} + } + return &json.BinaryStore{} +} + // DefaultStoreForPath returns the correct format-specific implementation // of the Store interface given the path to a file func DefaultStoreForPath(path string) Store { @@ -154,6 +172,20 @@ func DefaultStoreForPath(path string) Store { return &json.BinaryStore{} } +// DefaultStoreForPathOrFormat returns the correct format-specific implementation +// of the Store interface given the format if specified, or the path to a file +func DefaultStoreForPathOrFormat(path, format string) Store { + switch format { + case "yaml": + case "json": + case "dotenv": + case "ini": + case "binary": + return DefaultStoreForFormat(format) + } + return DefaultStoreForPath(path) +} + // KMS_ENC_CTX_BUG_FIXED_VERSION represents the SOPS version in which the // encryption context bug was fixed const KMS_ENC_CTX_BUG_FIXED_VERSION = "3.3.0" diff --git a/cmd/sops/main.go b/cmd/sops/main.go index 3599dfdea..338bb26e6 100644 --- a/cmd/sops/main.go +++ b/cmd/sops/main.go @@ -32,9 +32,7 @@ import ( "go.mozilla.org/sops/logging" "go.mozilla.org/sops/pgp" "go.mozilla.org/sops/stores/dotenv" - "go.mozilla.org/sops/stores/ini" "go.mozilla.org/sops/stores/json" - yamlstores "go.mozilla.org/sops/stores/yaml" "go.mozilla.org/sops/version" "google.golang.org/grpc" "gopkg.in/urfave/cli.v1" @@ -875,37 +873,11 @@ func keyservices(c *cli.Context) (svcs []keyservice.KeyServiceClient) { } func inputStore(context *cli.Context, path string) common.Store { - switch context.String("input-type") { - case "yaml": - return &yamlstores.Store{} - case "json": - return &json.Store{} - case "dotenv": - return &dotenv.Store{} - case "ini": - return &ini.Store{} - case "binary": - return &json.BinaryStore{} - default: - return common.DefaultStoreForPath(path) - } + return common.DefaultStoreForPathOrFormat(path, context.String("input-type")) } func outputStore(context *cli.Context, path string) common.Store { - switch context.String("output-type") { - case "yaml": - return &yamlstores.Store{} - case "json": - return &json.Store{} - case "dotenv": - return &dotenv.Store{} - case "ini": - return &ini.Store{} - case "binary": - return &json.BinaryStore{} - default: - return common.DefaultStoreForPath(path) - } + return common.DefaultStoreForPathOrFormat(path, context.String("output-type")) } func parseTreePath(arg string) ([]interface{}, error) { diff --git a/decrypt/decrypt.go b/decrypt/decrypt.go index c1d110a80..16031f377 100644 --- a/decrypt/decrypt.go +++ b/decrypt/decrypt.go @@ -11,9 +11,7 @@ import ( "go.mozilla.org/sops" "go.mozilla.org/sops/aes" - sopsdotenv "go.mozilla.org/sops/stores/dotenv" - sopsjson "go.mozilla.org/sops/stores/json" - sopsyaml "go.mozilla.org/sops/stores/yaml" + "go.mozilla.org/sops/cmd/sops/common" ) // File is a wrapper around Data that reads a local encrypted @@ -24,26 +22,15 @@ func File(path, format string) (cleartext []byte, err error) { if err != nil { return nil, fmt.Errorf("Failed to read %q: %v", path, err) } - return Data(encryptedData, format) + + store := common.DefaultStoreForPathOrFormat(path, format) + return DataWithStore(encryptedData, store) } -// Data is a helper that takes encrypted data and a format string, +// DataWithStore is a helper that takes encrypted data, and a store, // decrypts the data and returns its cleartext in an []byte. -// The format string can be `json`, `yaml`, `dotenv` or `binary`. -// If the format string is empty, binary format is assumed. -func Data(data []byte, format string) (cleartext []byte, err error) { - // Initialize a Sops JSON store - var store sops.Store - switch format { - case "json": - store = &sopsjson.Store{} - case "yaml": - store = &sopsyaml.Store{} - case "dotenv": - store = &sopsdotenv.Store{} - default: - store = &sopsjson.BinaryStore{} - } +func DataWithStore(data []byte, store sops.Store) (cleartext []byte, err error) { + // Load SOPS file and access the data key tree, err := store.LoadEncryptedFile(data) if err != nil { @@ -75,3 +62,12 @@ func Data(data []byte, format string) (cleartext []byte, err error) { return store.EmitPlainFile(tree.Branches) } + +// Data is a helper that takes encrypted data and a format string, +// decrypts the data and returns its cleartext in an []byte. +// The format string can be `json`, `yaml`, `ini`, `dotenv` or `binary`. +// If the format string is empty, binary format is assumed. +func Data(data []byte, format string) (cleartext []byte, err error) { + store := common.DefaultStoreForFormat(format) + return DataWithStore(data, store) +} From a40c6a208f10c479395fe791ebf04477a543dda0 Mon Sep 17 00:00:00 2001 From: Damien Nozay Date: Thu, 17 Oct 2019 09:25:09 -0700 Subject: [PATCH 2/5] use map --- cmd/sops/common/common.go | 68 +++++++++++++++++++++++++-------------- 1 file changed, 44 insertions(+), 24 deletions(-) diff --git a/cmd/sops/common/common.go b/cmd/sops/common/common.go index 465a4d002..2094dc789 100644 --- a/cmd/sops/common/common.go +++ b/cmd/sops/common/common.go @@ -36,6 +36,37 @@ type Store interface { ExampleFileEmitter } +type storeConstructor = func() Store + +func newBinaryStore() Store { + return &json.BinaryStore{} +} + +func newDotenvStore() Store { + return &dotenv.Store{} +} + +func newIniStore() Store { + return &ini.Store{} +} + +func newJsonStore() Store { + return &json.Store{} +} + +func newYamlStore() Store { + return &yaml.Store{} +} + +// StoreConstructors is a mapping of formats to constructors. +var StoreConstructors = map[string]storeConstructor{ + "binary": newBinaryStore, + "dotenv": newDotenvStore, + "ini": newIniStore, + "json": newJsonStore, + "yaml": newYamlStore, +} + // DecryptTreeOpts are the options needed to decrypt a tree type DecryptTreeOpts struct { // Tree is the tree to be decrypted @@ -142,46 +173,35 @@ func IsIniFile(path string) bool { // DefaultStoreForFormat returns the correct format-specific implementation // of the Store interface given the format string func DefaultStoreForFormat(format string) Store { - switch format { - case "yaml": - return &yaml.Store{} - case "json": - return &json.Store{} - case "dotenv": - return &dotenv.Store{} - case "ini": - return &ini.Store{} - case "binary": - return &json.BinaryStore{} + storeConst, found := StoreConstructors[format] + if !found { + storeConst = StoreConstructors["binary"] // default } - return &json.BinaryStore{} + return storeConst() } // DefaultStoreForPath returns the correct format-specific implementation // of the Store interface given the path to a file func DefaultStoreForPath(path string) Store { + storeConst := StoreConstructors["binary"] // default if IsYAMLFile(path) { - return &yaml.Store{} + storeConst = StoreConstructors["yaml"] } else if IsJSONFile(path) { - return &json.Store{} + storeConst = StoreConstructors["json"] } else if IsEnvFile(path) { - return &dotenv.Store{} + storeConst = StoreConstructors["dotenv"] } else if IsIniFile(path) { - return &ini.Store{} + storeConst = StoreConstructors["ini"] } - return &json.BinaryStore{} + return storeConst() } // DefaultStoreForPathOrFormat returns the correct format-specific implementation // of the Store interface given the format if specified, or the path to a file func DefaultStoreForPathOrFormat(path, format string) Store { - switch format { - case "yaml": - case "json": - case "dotenv": - case "ini": - case "binary": - return DefaultStoreForFormat(format) + storeConst, found := StoreConstructors[format] + if found { + return storeConst() } return DefaultStoreForPath(path) } From a03712f0862123ce47a1f7b12d443aeaaadd44d1 Mon Sep 17 00:00:00 2001 From: Damien Nozay Date: Tue, 22 Oct 2019 08:14:20 -0700 Subject: [PATCH 3/5] use enum --- cmd/sops/common/common.go | 88 +++++++++++++++++++++++++++------------ decrypt/decrypt.go | 4 +- 2 files changed, 64 insertions(+), 28 deletions(-) diff --git a/cmd/sops/common/common.go b/cmd/sops/common/common.go index 2094dc789..ac2776fca 100644 --- a/cmd/sops/common/common.go +++ b/cmd/sops/common/common.go @@ -24,6 +24,24 @@ import ( "gopkg.in/urfave/cli.v1" ) +type Format int + +const ( + Binary Format = iota + Dotenv + Ini + Json + Yaml +) + +var stringToFormat = map[string]Format{ + "binary": Binary, + "dotenv": Dotenv, + "ini": Ini, + "json": Json, + "yaml": Yaml, +} + // ExampleFileEmitter emits example files. This is used by the `sops` binary // whenever a new file is created, in order to present the user with a non-empty file type ExampleFileEmitter interface { @@ -58,13 +76,12 @@ func newYamlStore() Store { return &yaml.Store{} } -// StoreConstructors is a mapping of formats to constructors. -var StoreConstructors = map[string]storeConstructor{ - "binary": newBinaryStore, - "dotenv": newDotenvStore, - "ini": newIniStore, - "json": newJsonStore, - "yaml": newYamlStore, +var storeConstructors = map[Format]storeConstructor{ + Binary: newBinaryStore, + Dotenv: newDotenvStore, + Ini: newIniStore, + Json: newJsonStore, + Yaml: newYamlStore, } // DecryptTreeOpts are the options needed to decrypt a tree @@ -170,40 +187,57 @@ func IsIniFile(path string) bool { return strings.HasSuffix(path, ".ini") } -// DefaultStoreForFormat returns the correct format-specific implementation -// of the Store interface given the format string -func DefaultStoreForFormat(format string) Store { - storeConst, found := StoreConstructors[format] +// FormatFromString returns a Format from a string. +// This is used for converting string cli options. +func FormatFromString(formatString string) Format { + format, found := stringToFormat[formatString] if !found { - storeConst = StoreConstructors["binary"] // default + return Binary } - return storeConst() + return format } -// DefaultStoreForPath returns the correct format-specific implementation -// of the Store interface given the path to a file -func DefaultStoreForPath(path string) Store { - storeConst := StoreConstructors["binary"] // default +// FormatForPath returns the correct format given the path to a file +func FormatForPath(path string) Format { + format := Binary // default if IsYAMLFile(path) { - storeConst = StoreConstructors["yaml"] + format = Yaml } else if IsJSONFile(path) { - storeConst = StoreConstructors["json"] + format = Json } else if IsEnvFile(path) { - storeConst = StoreConstructors["dotenv"] + format = Dotenv } else if IsIniFile(path) { - storeConst = StoreConstructors["ini"] + format = Ini + } + return format +} + +// StoreForFormat returns the correct format-specific implementation +// of the Store interface given the format. +func StoreForFormat(format Format) Store { + storeConst, found := storeConstructors[format] + if !found { + storeConst = storeConstructors[Binary] // default } return storeConst() } +// DefaultStoreForPath returns the correct format-specific implementation +// of the Store interface given the path to a file +func DefaultStoreForPath(path string) Store { + format := FormatForPath(path) + return StoreForFormat(format) +} + // DefaultStoreForPathOrFormat returns the correct format-specific implementation -// of the Store interface given the format if specified, or the path to a file -func DefaultStoreForPathOrFormat(path, format string) Store { - storeConst, found := StoreConstructors[format] - if found { - return storeConst() +// of the Store interface given the formatString if specified, or the path to a file. +// This is to support the cli, where both are provided. +func DefaultStoreForPathOrFormat(path, formatString string) Store { + format, found := stringToFormat[formatString] + if !found { + format = FormatForPath(path) } - return DefaultStoreForPath(path) + return StoreForFormat(format) } // KMS_ENC_CTX_BUG_FIXED_VERSION represents the SOPS version in which the diff --git a/decrypt/decrypt.go b/decrypt/decrypt.go index 16031f377..6ae3fe699 100644 --- a/decrypt/decrypt.go +++ b/decrypt/decrypt.go @@ -23,7 +23,9 @@ func File(path, format string) (cleartext []byte, err error) { return nil, fmt.Errorf("Failed to read %q: %v", path, err) } + // uses same logic as cli. store := common.DefaultStoreForPathOrFormat(path, format) + return DataWithStore(encryptedData, store) } @@ -68,6 +70,6 @@ func DataWithStore(data []byte, store sops.Store) (cleartext []byte, err error) // The format string can be `json`, `yaml`, `ini`, `dotenv` or `binary`. // If the format string is empty, binary format is assumed. func Data(data []byte, format string) (cleartext []byte, err error) { - store := common.DefaultStoreForFormat(format) + store := common.StoreForFormat(common.FormatFromString(format)) return DataWithStore(data, store) } From 559b27c01f83b7944bb64c9bb5025dfd2e74c6af Mon Sep 17 00:00:00 2001 From: Damien Nozay Date: Tue, 22 Oct 2019 11:52:35 -0700 Subject: [PATCH 4/5] mv formats around --- cmd/sops/common/common.go | 74 +++------------------------------------ decrypt/decrypt.go | 17 ++++----- 2 files changed, 13 insertions(+), 78 deletions(-) diff --git a/cmd/sops/common/common.go b/cmd/sops/common/common.go index ac2776fca..84e904d6e 100644 --- a/cmd/sops/common/common.go +++ b/cmd/sops/common/common.go @@ -5,13 +5,13 @@ import ( "io/ioutil" "os" "path/filepath" - "strings" "time" "github.com/fatih/color" wordwrap "github.com/mitchellh/go-wordwrap" "go.mozilla.org/sops" "go.mozilla.org/sops/cmd/sops/codes" + . "go.mozilla.org/sops/cmd/sops/formats" "go.mozilla.org/sops/keys" "go.mozilla.org/sops/keyservice" "go.mozilla.org/sops/kms" @@ -24,24 +24,6 @@ import ( "gopkg.in/urfave/cli.v1" ) -type Format int - -const ( - Binary Format = iota - Dotenv - Ini - Json - Yaml -) - -var stringToFormat = map[string]Format{ - "binary": Binary, - "dotenv": Dotenv, - "ini": Ini, - "json": Json, - "yaml": Yaml, -} - // ExampleFileEmitter emits example files. This is used by the `sops` binary // whenever a new file is created, in order to present the user with a non-empty file type ExampleFileEmitter interface { @@ -167,51 +149,6 @@ func NewExitError(i interface{}, exitCode int) *cli.ExitError { return cli.NewExitError(i, exitCode) } -// IsYAMLFile returns true if a given file path corresponds to a YAML file -func IsYAMLFile(path string) bool { - return strings.HasSuffix(path, ".yaml") || strings.HasSuffix(path, ".yml") -} - -// IsJSONFile returns true if a given file path corresponds to a JSON file -func IsJSONFile(path string) bool { - return strings.HasSuffix(path, ".json") -} - -// IsEnvFile returns true if a given file path corresponds to a .env file -func IsEnvFile(path string) bool { - return strings.HasSuffix(path, ".env") -} - -// IsIniFile returns true if a given file path corresponds to a INI file -func IsIniFile(path string) bool { - return strings.HasSuffix(path, ".ini") -} - -// FormatFromString returns a Format from a string. -// This is used for converting string cli options. -func FormatFromString(formatString string) Format { - format, found := stringToFormat[formatString] - if !found { - return Binary - } - return format -} - -// FormatForPath returns the correct format given the path to a file -func FormatForPath(path string) Format { - format := Binary // default - if IsYAMLFile(path) { - format = Yaml - } else if IsJSONFile(path) { - format = Json - } else if IsEnvFile(path) { - format = Dotenv - } else if IsIniFile(path) { - format = Ini - } - return format -} - // StoreForFormat returns the correct format-specific implementation // of the Store interface given the format. func StoreForFormat(format Format) Store { @@ -232,12 +169,9 @@ func DefaultStoreForPath(path string) Store { // DefaultStoreForPathOrFormat returns the correct format-specific implementation // of the Store interface given the formatString if specified, or the path to a file. // This is to support the cli, where both are provided. -func DefaultStoreForPathOrFormat(path, formatString string) Store { - format, found := stringToFormat[formatString] - if !found { - format = FormatForPath(path) - } - return StoreForFormat(format) +func DefaultStoreForPathOrFormat(path, format string) Store { + formatFmt := FormatForPathOrString(path, format) + return StoreForFormat(formatFmt) } // KMS_ENC_CTX_BUG_FIXED_VERSION represents the SOPS version in which the diff --git a/decrypt/decrypt.go b/decrypt/decrypt.go index 6ae3fe699..aa9cda78d 100644 --- a/decrypt/decrypt.go +++ b/decrypt/decrypt.go @@ -9,9 +9,9 @@ import ( "io/ioutil" "time" - "go.mozilla.org/sops" "go.mozilla.org/sops/aes" "go.mozilla.org/sops/cmd/sops/common" + . "go.mozilla.org/sops/cmd/sops/formats" // Re-export ) // File is a wrapper around Data that reads a local encrypted @@ -24,14 +24,15 @@ func File(path, format string) (cleartext []byte, err error) { } // uses same logic as cli. - store := common.DefaultStoreForPathOrFormat(path, format) - - return DataWithStore(encryptedData, store) + format := FormatForPathOrString(path, format) + return DataWithFormat(encryptedData, format) } -// DataWithStore is a helper that takes encrypted data, and a store, +// DataWithFormat is a helper that takes encrypted data, and a format enum value, // decrypts the data and returns its cleartext in an []byte. -func DataWithStore(data []byte, store sops.Store) (cleartext []byte, err error) { +func DataWithFormat(data []byte, format Format) (cleartext []byte, err error) { + + store := common.StoreForFormat(format) // Load SOPS file and access the data key tree, err := store.LoadEncryptedFile(data) @@ -70,6 +71,6 @@ func DataWithStore(data []byte, store sops.Store) (cleartext []byte, err error) // The format string can be `json`, `yaml`, `ini`, `dotenv` or `binary`. // If the format string is empty, binary format is assumed. func Data(data []byte, format string) (cleartext []byte, err error) { - store := common.StoreForFormat(common.FormatFromString(format)) - return DataWithStore(data, store) + format := FormatFromString(format) + return DataWithFormat(data, format) } From 4376ac973c2333d883d75e0530b856b6ae0bcd02 Mon Sep 17 00:00:00 2001 From: Damien Nozay Date: Tue, 22 Oct 2019 12:19:59 -0700 Subject: [PATCH 5/5] add formats --- cmd/sops/formats/formats.go | 78 ++++++++++++++++++++++++++++++++ cmd/sops/formats/formats_test.go | 39 ++++++++++++++++ decrypt/decrypt.go | 8 ++-- 3 files changed, 121 insertions(+), 4 deletions(-) create mode 100644 cmd/sops/formats/formats.go create mode 100644 cmd/sops/formats/formats_test.go diff --git a/cmd/sops/formats/formats.go b/cmd/sops/formats/formats.go new file mode 100644 index 000000000..83c5391e2 --- /dev/null +++ b/cmd/sops/formats/formats.go @@ -0,0 +1,78 @@ +package formats + +import "strings" + +// Format is an enum type +type Format int + +const ( + Binary Format = iota + Dotenv + Ini + Json + Yaml +) + +var stringToFormat = map[string]Format{ + "binary": Binary, + "dotenv": Dotenv, + "ini": Ini, + "json": Json, + "yaml": Yaml, +} + +// FormatFromString returns a Format from a string. +// This is used for converting string cli options. +func FormatFromString(formatString string) Format { + format, found := stringToFormat[formatString] + if !found { + return Binary + } + return format +} + +// IsYAMLFile returns true if a given file path corresponds to a YAML file +func IsYAMLFile(path string) bool { + return strings.HasSuffix(path, ".yaml") || strings.HasSuffix(path, ".yml") +} + +// IsJSONFile returns true if a given file path corresponds to a JSON file +func IsJSONFile(path string) bool { + return strings.HasSuffix(path, ".json") +} + +// IsEnvFile returns true if a given file path corresponds to a .env file +func IsEnvFile(path string) bool { + return strings.HasSuffix(path, ".env") +} + +// IsIniFile returns true if a given file path corresponds to a INI file +func IsIniFile(path string) bool { + return strings.HasSuffix(path, ".ini") +} + +// FormatForPath returns the correct format given the path to a file +func FormatForPath(path string) Format { + format := Binary // default + if IsYAMLFile(path) { + format = Yaml + } else if IsJSONFile(path) { + format = Json + } else if IsEnvFile(path) { + format = Dotenv + } else if IsIniFile(path) { + format = Ini + } + return format +} + +// FormatForPathOrString returns the correct format-specific implementation +// of the Store interface given the formatString if specified, or the path to a file. +// This is to support the cli, where both are provided. +func FormatForPathOrString(path, format string) Format { + formatFmt, found := stringToFormat[format] + if !found { + formatFmt = FormatForPath(path) + } + return formatFmt +} diff --git a/cmd/sops/formats/formats_test.go b/cmd/sops/formats/formats_test.go new file mode 100644 index 000000000..7bc6477fa --- /dev/null +++ b/cmd/sops/formats/formats_test.go @@ -0,0 +1,39 @@ +package formats + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestFormatFromString(t *testing.T) { + assert.Equal(t, Binary, FormatFromString("foobar")) + assert.Equal(t, Dotenv, FormatFromString("dotenv")) + assert.Equal(t, Ini, FormatFromString("ini")) + assert.Equal(t, Yaml, FormatFromString("yaml")) + assert.Equal(t, Json, FormatFromString("json")) +} + +func TestFormatForPath(t *testing.T) { + assert.Equal(t, Binary, FormatForPath("/path/to/foobar")) + assert.Equal(t, Dotenv, FormatForPath("/path/to/foobar.env")) + assert.Equal(t, Ini, FormatForPath("/path/to/foobar.ini")) + assert.Equal(t, Json, FormatForPath("/path/to/foobar.json")) + assert.Equal(t, Yaml, FormatForPath("/path/to/foobar.yml")) + assert.Equal(t, Yaml, FormatForPath("/path/to/foobar.yaml")) +} + +func TestFormatForPathOrString(t *testing.T) { + assert.Equal(t, Binary, FormatForPathOrString("/path/to/foobar", "")) + assert.Equal(t, Dotenv, FormatForPathOrString("/path/to/foobar", "dotenv")) + assert.Equal(t, Dotenv, FormatForPathOrString("/path/to/foobar.env", "")) + assert.Equal(t, Ini, FormatForPathOrString("/path/to/foobar", "ini")) + assert.Equal(t, Ini, FormatForPathOrString("/path/to/foobar.ini", "")) + assert.Equal(t, Json, FormatForPathOrString("/path/to/foobar", "json")) + assert.Equal(t, Json, FormatForPathOrString("/path/to/foobar.json", "")) + assert.Equal(t, Yaml, FormatForPathOrString("/path/to/foobar", "yaml")) + assert.Equal(t, Yaml, FormatForPathOrString("/path/to/foobar.yml", "")) + + assert.Equal(t, Ini, FormatForPathOrString("/path/to/foobar.yml", "ini")) + assert.Equal(t, Binary, FormatForPathOrString("/path/to/foobar.yml", "binary")) +} diff --git a/decrypt/decrypt.go b/decrypt/decrypt.go index aa9cda78d..3b4944842 100644 --- a/decrypt/decrypt.go +++ b/decrypt/decrypt.go @@ -24,8 +24,8 @@ func File(path, format string) (cleartext []byte, err error) { } // uses same logic as cli. - format := FormatForPathOrString(path, format) - return DataWithFormat(encryptedData, format) + formatFmt := FormatForPathOrString(path, format) + return DataWithFormat(encryptedData, formatFmt) } // DataWithFormat is a helper that takes encrypted data, and a format enum value, @@ -71,6 +71,6 @@ func DataWithFormat(data []byte, format Format) (cleartext []byte, err error) { // The format string can be `json`, `yaml`, `ini`, `dotenv` or `binary`. // If the format string is empty, binary format is assumed. func Data(data []byte, format string) (cleartext []byte, err error) { - format := FormatFromString(format) - return DataWithFormat(data, format) + formatFmt := FormatFromString(format) + return DataWithFormat(data, formatFmt) }