Skip to content

Commit

Permalink
Refactor to support proper types; add tests
Browse files Browse the repository at this point in the history
  • Loading branch information
danhunsaker committed Mar 15, 2023
1 parent 1f7c941 commit bd44aba
Show file tree
Hide file tree
Showing 12 changed files with 567 additions and 254 deletions.
6 changes: 4 additions & 2 deletions altsrc/default_input_source.go
@@ -1,6 +1,8 @@
package altsrc

// defaultInputSource creates a default InputSourceContext.
func defaultInputSource() (InputSourceContext, error) {
import "github.com/urfave/cli/v2"

// defaultInputSource creates a default cli.InputSourceContext.
func defaultInputSource() (cli.InputSourceContext, error) {
return &MapInputSource{file: "", valueMap: map[interface{}]interface{}{}}, nil
}
38 changes: 12 additions & 26 deletions altsrc/detect_input_source.go
Expand Up @@ -3,22 +3,23 @@ package altsrc
import (
"fmt"
"path/filepath"
"sort"

"github.com/urfave/cli/v2"
)

// defaultSources is a read-only map, making it concurrency-safe
var defaultSources = map[string]func(string) func(*cli.Context) (InputSourceContext, error){
var defaultSources = map[string]func(string) func(*cli.Context) (cli.InputSourceContext, error){
".conf": NewTomlSourceFromFlagFunc,
".json": NewJSONSourceFromFlagFunc,
".toml": NewTomlSourceFromFlagFunc,
".yaml": NewYamlSourceFromFlagFunc,
".yml": NewYamlSourceFromFlagFunc,
}

// DetectNewSourceFromFlagFunc creates a new InputSourceContext from a provided flag name and source context.
func DetectNewSourceFromFlagFunc(flagFileName string) func(*cli.Context) (InputSourceContext, error) {
return func(cCtx *cli.Context) (InputSourceContext, error) {
// DetectNewSourceFromFlagFunc creates a new cli.InputSourceContext from a provided flag name and source context.
func DetectNewSourceFromFlagFunc(flagFileName string) func(*cli.Context) (cli.InputSourceContext, error) {
return func(cCtx *cli.Context) (cli.InputSourceContext, error) {
detectableSources := cCtx.App.GetDetectableSources()

if fileFullPath := cCtx.String(flagFileName); fileFullPath != "" {
Expand All @@ -28,17 +29,7 @@ func DetectNewSourceFromFlagFunc(flagFileName string) func(*cli.Context) (InputS

// Check if the App contains a handler for this extension first, allowing it to override the defaults
if handler, ok := detectableSources[fileExt]; ok {
source, err := handler(flagFileName)(cCtx)
if err != nil {
return nil, err
}

switch source := source.(type) {
case InputSourceContext:
return source, nil
default:
typeError = fmt.Errorf("Unable to parse config file. The type handler for %s is incorrectly implemented.", fileExt)
}
return handler(flagFileName)(cCtx)
}

// Fall back to the default sources implemented by the library itself
Expand All @@ -57,17 +48,10 @@ func DetectNewSourceFromFlagFunc(flagFileName string) func(*cli.Context) (InputS
}
}

func detectableExtensions(detectableSources map[string]func(string) func(*cli.Context) (interface{}, error)) []string {
detectLen := len(detectableSources)
defaultLen := len(defaultSources)

largerLen := defaultLen
if detectLen > defaultLen {
largerLen = detectLen
}

// The App might override some file extensions, so set size to fit the larger of the two lists, with capacity for both in case it's needed
extensions := make([]string, largerLen, detectLen+defaultLen)
func detectableExtensions(detectableSources map[string]func(string) func(*cli.Context) (cli.InputSourceContext, error)) []string {
// We don't preallocate because this generates empty space in the output
// It's less efficient, but this is for error messaging only at the moment
var extensions []string

for ext := range detectableSources {
extensions = append(extensions, ext)
Expand All @@ -79,5 +63,7 @@ func detectableExtensions(detectableSources map[string]func(string) func(*cli.Co
}
}

sort.Strings(extensions)

return extensions
}

0 comments on commit bd44aba

Please sign in to comment.