...

Source file src/github.com/ory/x/configx/koanf_file.go

Documentation: github.com/ory/x/configx

     1  package configx
     2  
     3  import (
     4  	"context"
     5  	"io/ioutil"
     6  	"path/filepath"
     7  	"strings"
     8  
     9  	"github.com/knadh/koanf"
    10  	"github.com/knadh/koanf/parsers/json"
    11  	"github.com/knadh/koanf/parsers/toml"
    12  	"github.com/knadh/koanf/parsers/yaml"
    13  
    14  	"github.com/ory/x/stringslice"
    15  
    16  	"github.com/pkg/errors"
    17  
    18  	"github.com/ory/x/watcherx"
    19  )
    20  
    21  // KoanfFile implements a KoanfFile provider.
    22  type KoanfFile struct {
    23  	subKey string
    24  	path   string
    25  	ctx    context.Context
    26  	parser koanf.Parser
    27  }
    28  
    29  // Provider returns a file provider.
    30  func NewKoanfFile(ctx context.Context, path string) (*KoanfFile, error) {
    31  	return NewKoanfFileSubKey(ctx, path, "")
    32  }
    33  
    34  func NewKoanfFileSubKey(ctx context.Context, path, subKey string) (*KoanfFile, error) {
    35  	kf := &KoanfFile{
    36  		path:   filepath.Clean(path),
    37  		ctx:    ctx,
    38  		subKey: subKey,
    39  	}
    40  
    41  	switch e := filepath.Ext(path); e {
    42  	case ".toml":
    43  		kf.parser = toml.Parser()
    44  	case ".json":
    45  		kf.parser = json.Parser()
    46  	case ".yaml", ".yml":
    47  		kf.parser = yaml.Parser()
    48  	default:
    49  		return nil, errors.Errorf("unknown config file extension: %s", e)
    50  	}
    51  
    52  	return kf, nil
    53  }
    54  
    55  // ReadBytes reads the contents of a file on disk and returns the bytes.
    56  func (f *KoanfFile) ReadBytes() ([]byte, error) {
    57  	return nil, errors.New("file provider does not support this method")
    58  }
    59  
    60  // Read is not supported by the file provider.
    61  func (f *KoanfFile) Read() (map[string]interface{}, error) {
    62  	fc, err := ioutil.ReadFile(f.path)
    63  	if err != nil {
    64  		return nil, errors.WithStack(err)
    65  	}
    66  
    67  	v, err := f.parser.Unmarshal(fc)
    68  	if err != nil {
    69  		return nil, errors.WithStack(err)
    70  	}
    71  
    72  	if f.subKey == "" {
    73  		return v, nil
    74  	}
    75  
    76  	path := strings.Split(f.subKey, Delimiter)
    77  	for _, k := range stringslice.Reverse(path) {
    78  		v = map[string]interface{}{
    79  			k: v,
    80  		}
    81  	}
    82  
    83  	return v, nil
    84  }
    85  
    86  // WatchChannel watches the file and triggers a callback when it changes. It is a
    87  // blocking function that internally spawns a goroutine to watch for changes.
    88  func (f *KoanfFile) WatchChannel(c watcherx.EventChannel) (watcherx.Watcher, error) {
    89  	return watcherx.WatchFile(f.ctx, f.path, c)
    90  }
    91  

View as plain text