...

Source file src/github.com/urfave/cli/v2/altsrc/yaml_file_loader.go

Documentation: github.com/urfave/cli/v2/altsrc

     1  package altsrc
     2  
     3  import (
     4  	"fmt"
     5  	"io"
     6  	"net/http"
     7  	"net/url"
     8  	"os"
     9  	"runtime"
    10  	"strings"
    11  
    12  	"github.com/urfave/cli/v2"
    13  
    14  	"gopkg.in/yaml.v3"
    15  )
    16  
    17  type yamlSourceContext struct {
    18  	FilePath string
    19  }
    20  
    21  // NewYamlSourceFromFile creates a new Yaml InputSourceContext from a filepath.
    22  func NewYamlSourceFromFile(file string) (InputSourceContext, error) {
    23  	ysc := &yamlSourceContext{FilePath: file}
    24  	var results map[interface{}]interface{}
    25  	err := readCommandYaml(ysc.FilePath, &results)
    26  	if err != nil {
    27  		return nil, fmt.Errorf("Unable to load Yaml file '%s': inner error: \n'%v'", ysc.FilePath, err.Error())
    28  	}
    29  
    30  	return &MapInputSource{file: file, valueMap: results}, nil
    31  }
    32  
    33  // NewYamlSourceFromFlagFunc creates a new Yaml InputSourceContext from a provided flag name and source context.
    34  func NewYamlSourceFromFlagFunc(flagFileName string) func(cCtx *cli.Context) (InputSourceContext, error) {
    35  	return func(cCtx *cli.Context) (InputSourceContext, error) {
    36  		if filePath := cCtx.String(flagFileName); filePath != "" {
    37  			return NewYamlSourceFromFile(filePath)
    38  		}
    39  		return defaultInputSource()
    40  	}
    41  }
    42  
    43  func readCommandYaml(filePath string, container interface{}) (err error) {
    44  	b, err := loadDataFrom(filePath)
    45  	if err != nil {
    46  		return err
    47  	}
    48  
    49  	err = yaml.Unmarshal(b, container)
    50  	if err != nil {
    51  		return err
    52  	}
    53  
    54  	err = nil
    55  	return
    56  }
    57  
    58  func loadDataFrom(filePath string) ([]byte, error) {
    59  	u, err := url.Parse(filePath)
    60  	if err != nil {
    61  		return nil, err
    62  	}
    63  
    64  	if u.Host != "" { // i have a host, now do i support the scheme?
    65  		switch u.Scheme {
    66  		case "http", "https":
    67  			res, err := http.Get(filePath)
    68  			if err != nil {
    69  				return nil, err
    70  			}
    71  			return io.ReadAll(res.Body)
    72  		default:
    73  			return nil, fmt.Errorf("scheme of %s is unsupported", filePath)
    74  		}
    75  	} else if u.Path != "" { // i dont have a host, but I have a path. I am a local file.
    76  		if _, notFoundFileErr := os.Stat(filePath); notFoundFileErr != nil {
    77  			return nil, fmt.Errorf("Cannot read from file: '%s' because it does not exist.", filePath)
    78  		}
    79  		return os.ReadFile(filePath)
    80  	} else if runtime.GOOS == "windows" && strings.Contains(u.String(), "\\") {
    81  		// on Windows systems u.Path is always empty, so we need to check the string directly.
    82  		if _, notFoundFileErr := os.Stat(filePath); notFoundFileErr != nil {
    83  			return nil, fmt.Errorf("Cannot read from file: '%s' because it does not exist.", filePath)
    84  		}
    85  		return os.ReadFile(filePath)
    86  	}
    87  
    88  	return nil, fmt.Errorf("unable to determine how to load from path %s", filePath)
    89  }
    90  

View as plain text