Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add delayed fetching of sources #17

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 71 additions & 0 deletions altsrc.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import (
"os"
"runtime"
"strings"

"github.com/urfave/cli/v3"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it possible to avoid this import? It seems needed only for cli.ValueSourceChain interface.

)

var (
Expand Down Expand Up @@ -80,3 +82,72 @@ func NestedVal(name string, tree map[any]any) (any, bool) {
}
return nil, false
}

type Sourcer interface {
SourceURI() string
}

type StringSourcer string

func (s StringSourcer) SourceURI() string {
return string(s)
}

type StringPtrSourcer struct {
ptr *string
}

func NewStringPtrSourcer(p *string) StringPtrSourcer {
return StringPtrSourcer{
ptr: p,
}
}

func (s StringPtrSourcer) SourceURI() string {
return *s.ptr
}

type valueSource struct {
key string
desc string
sourcer Sourcer
um func([]byte, any) error
}

func (vs *valueSource) Lookup() (string, bool) {
maafsc := NewMapAnyAnyURISourceCache(vs.sourcer.SourceURI(), vs.um)
if v, ok := NestedVal(vs.key, maafsc.Get()); ok {
return fmt.Sprintf("%[1]v", v), ok
}

return "", false
}

func (vs *valueSource) String() string {
return fmt.Sprintf("%s file %[2]q at key %[3]q", vs.desc, vs.sourcer.SourceURI(), vs.key)
}

func (vs *valueSource) GoString() string {
return fmt.Sprintf("%sValueSource{file:%[2]q,keyPath:%[3]q}", vs.desc, vs.sourcer.SourceURI(), vs.key)
}

func NewValueSource(f func([]byte, any) error, desc string, key string, uriSrc Sourcer) cli.ValueSource {
return &valueSource{
sourcer: uriSrc,
key: key,
desc: desc,
um: f,
}
}

func NewValueSourceChain(f func([]byte, any) error, desc string, key string, uris ...Sourcer) cli.ValueSourceChain {
vs := []cli.ValueSource{}

for _, uri := range uris {
vs = append(vs, NewValueSource(f, desc, key, uri))
}

return cli.ValueSourceChain{
Chain: vs,
}
}
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ require github.com/stretchr/testify v1.9.0
require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/urfave/cli/v3 v3.0.0-beta1 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)

Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/urfave/cli/v3 v3.0.0-beta1 h1:6DTaaUarcM0wX7qj5Hcvs+5Dm3dyUTBbEwIWAjcw9Zg=
github.com/urfave/cli/v3 v3.0.0-beta1/go.mod h1:FnIeEMYu+ko8zP1F9Ypr3xkZMIDqW3DR92yUtY39q1Y=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
Expand Down
6 changes: 3 additions & 3 deletions json/examples_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,9 @@ var (
)

func ExampleJSON() {
configFiles := []string{
filepath.Join(testdataDir, "config.json"),
filepath.Join(testdataDir, "alt-config.json"),
configFiles := []altsrc.Sourcer{
altsrc.StringSourcer(filepath.Join(testdataDir, "config.json")),
altsrc.StringSourcer(filepath.Join(testdataDir, "alt-config.json")),
}

app := &cli.Command{
Expand Down
5 changes: 3 additions & 2 deletions json/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,15 @@ go 1.23.2

require (
github.com/stretchr/testify v1.9.0
github.com/urfave/cli-altsrc/v3 v3.0.0-alpha9.3
github.com/urfave/cli-altsrc/yaml v0.0.1
github.com/urfave/cli/v3 v3.0.0-alpha9.3
github.com/urfave/cli/v3 v3.0.0-beta1
gopkg.in/yaml.v2 v2.4.0
)

require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/urfave/cli-altsrc/v3 v3.0.0-alpha9.3 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)

Expand Down
6 changes: 4 additions & 2 deletions json/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/urfave/cli/v3 v3.0.0-alpha9.3 h1:RfQlgUHMRxDMwEEmGsrHd+mXYJpWpXlcJM8w86cpjGs=
github.com/urfave/cli/v3 v3.0.0-alpha9.3/go.mod h1:FnIeEMYu+ko8zP1F9Ypr3xkZMIDqW3DR92yUtY39q1Y=
github.com/urfave/cli/v3 v3.0.0-beta1 h1:6DTaaUarcM0wX7qj5Hcvs+5Dm3dyUTBbEwIWAjcw9Zg=
github.com/urfave/cli/v3 v3.0.0-beta1/go.mod h1:FnIeEMYu+ko8zP1F9Ypr3xkZMIDqW3DR92yUtY39q1Y=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
7 changes: 4 additions & 3 deletions json/json_value_source.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
package json

import (
yaml "github.com/urfave/cli-altsrc/yaml"
altsrc "github.com/urfave/cli-altsrc/v3"
"github.com/urfave/cli/v3"
"gopkg.in/yaml.v2"
)

// JSON is a helper function that wraps the YAML helper function
// and loads via yaml.Unmarshal
func JSON(key string, paths ...string) cli.ValueSourceChain {
return yaml.YAML(key, paths...)
func JSON(key string, sources ...altsrc.Sourcer) cli.ValueSourceChain {
return altsrc.NewValueSourceChain(yaml.Unmarshal, "json", key, sources...)
}
8 changes: 4 additions & 4 deletions json/json_value_source_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,15 +28,15 @@ func TestJSON(t *testing.T) {

vsc := yaml.YAML(
"water_fountain.water",
"/dev/null/nonexistent.json",
configPath,
altConfigPath,
altsrc.StringSourcer("/dev/null/nonexistent.json"),
altsrc.StringSourcer(configPath),
altsrc.StringSourcer(altConfigPath),
)
v, ok := vsc.Lookup()
r.Equal("false", v)
r.True(ok)

yvs := vsc.Chain[0]
r.Equal("yaml file \"/dev/null/nonexistent.json\" at key \"water_fountain.water\"", yvs.String())
r.Equal("&yamlValueSource{file:\"/dev/null/nonexistent.json\",keyPath:\"water_fountain.water\"}", yvs.GoString())
r.Equal("yamlValueSource{file:\"/dev/null/nonexistent.json\",keyPath:\"water_fountain.water\"}", yvs.GoString())
}
6 changes: 3 additions & 3 deletions toml/examples_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,9 @@ var (
)

func ExampleTOML() {
configFiles := []string{
filepath.Join(testdataDir, "config.toml"),
filepath.Join(testdataDir, "alt-config.toml"),
configFiles := []altsrc.Sourcer{
altsrc.StringSourcer(filepath.Join(testdataDir, "config.toml")),
altsrc.StringSourcer(filepath.Join(testdataDir, "alt-config.toml")),
}

app := &cli.Command{
Expand Down
6 changes: 3 additions & 3 deletions toml/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ go 1.23.2
require (
github.com/BurntSushi/toml v1.4.0
github.com/stretchr/testify v1.9.0
github.com/urfave/cli/v3 v3.0.0-alpha9.3
github.com/urfave/cli-altsrc/v3 v3.0.0-alpha9
github.com/urfave/cli-altsrc/v3 v3.0.0-alpha9
github.com/urfave/cli/v3 v3.0.0-beta1
)

require (
Expand All @@ -15,4 +15,4 @@ require (
gopkg.in/yaml.v3 v3.0.1 // indirect
)

replace github.com/urfave/cli-altsrc/v3 v3.0.0-alpha9 => ../
replace github.com/urfave/cli-altsrc/v3 v3.0.0-alpha9 => ../
4 changes: 2 additions & 2 deletions toml/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/urfave/cli/v3 v3.0.0-alpha9.3 h1:RfQlgUHMRxDMwEEmGsrHd+mXYJpWpXlcJM8w86cpjGs=
github.com/urfave/cli/v3 v3.0.0-alpha9.3/go.mod h1:FnIeEMYu+ko8zP1F9Ypr3xkZMIDqW3DR92yUtY39q1Y=
github.com/urfave/cli/v3 v3.0.0-beta1 h1:6DTaaUarcM0wX7qj5Hcvs+5Dm3dyUTBbEwIWAjcw9Zg=
github.com/urfave/cli/v3 v3.0.0-beta1/go.mod h1:FnIeEMYu+ko8zP1F9Ypr3xkZMIDqW3DR92yUtY39q1Y=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
Expand Down
44 changes: 2 additions & 42 deletions toml/toml_value_source.go
Original file line number Diff line number Diff line change
@@ -1,53 +1,13 @@
package toml

import (
"fmt"

"github.com/BurntSushi/toml"
altsrc "github.com/urfave/cli-altsrc/v3"
"github.com/urfave/cli/v3"
)

type tomlMapFileSourceCache = altsrc.FileSourceCache[tomlMap]

// TOML is a helper function to encapsulate a number of
// tomlValueSource together as a cli.ValueSourceChain
func TOML(key string, paths ...string) cli.ValueSourceChain {
vsc := cli.ValueSourceChain{Chain: []cli.ValueSource{}}

for _, path := range paths {
vsc.Chain = append(
vsc.Chain,
&tomlValueSource{
file: path,
key: key,
tmc: *altsrc.NewFileSourceCache[tomlMap](path, toml.Unmarshal),
},
)
}

return vsc
}

type tomlValueSource struct {
file string
key string

tmc tomlMapFileSourceCache
}

func (tvs *tomlValueSource) Lookup() (string, bool) {
if v, ok := altsrc.NestedVal(tvs.key, tvs.tmc.Get().Map); ok {
return fmt.Sprintf("%[1]v", v), ok
}

return "", false
}

func (tvs *tomlValueSource) String() string {
return fmt.Sprintf("toml file %[1]q at key %[2]q", tvs.file, tvs.key)
}

func (tvs *tomlValueSource) GoString() string {
return fmt.Sprintf("&tomlValueSource{file:%[1]q,keyPath:%[2]q}", tvs.file, tvs.key)
func TOML(key string, sources ...altsrc.Sourcer) cli.ValueSourceChain {
return altsrc.NewValueSourceChain(toml.Unmarshal, "toml", key, sources...)
}
10 changes: 5 additions & 5 deletions toml/toml_value_source_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,15 @@ func TestTOML(t *testing.T) {

vsc := TOML(
"water_fountain.water",
"/dev/null/nonexistent.toml",
configPath,
altConfigPath,
altsrc.StringSourcer("/dev/null/nonexistent.toml"),
altsrc.StringSourcer(configPath),
altsrc.StringSourcer(altConfigPath),
)
v, ok := vsc.Lookup()
r.Equal("false", v)
r.True(ok)

tvs := vsc.Chain[0].(*tomlValueSource)
tvs := vsc.Chain[0]
r.Equal("toml file \"/dev/null/nonexistent.toml\" at key \"water_fountain.water\"", tvs.String())
r.Equal("&tomlValueSource{file:\"/dev/null/nonexistent.toml\",keyPath:\"water_fountain.water\"}", tvs.GoString())
r.Equal("tomlValueSource{file:\"/dev/null/nonexistent.toml\",keyPath:\"water_fountain.water\"}", tvs.GoString())
}
12 changes: 6 additions & 6 deletions uri_source_cache.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,25 +39,25 @@ func readURI(uriString string) ([]byte, error) {
}

type URISourceCache[T any] struct {
file string
uri string
m *T
unmarshaller func([]byte, any) error
}

func NewURISourceCache[T any](file string, f func([]byte, any) error) *URISourceCache[T] {
func NewURISourceCache[T any](uri string, f func([]byte, any) error) *URISourceCache[T] {
return &URISourceCache[T]{
file: file,
uri: uri,
unmarshaller: f,
}
}

func (fsc *URISourceCache[T]) Get() T {
if fsc.m == nil {
res := new(T)
if b, err := readURI(fsc.file); err != nil {
tracef("failed to read uri %[1]q: %[2]v", fsc.file, err)
if b, err := readURI(fsc.uri); err != nil {
tracef("failed to read uri %[1]q: %[2]v", fsc.uri, err)
} else if err := fsc.unmarshaller(b, res); err != nil {
tracef("failed to unmarshal from file %[1]q: %[2]v", fsc.file, err)
tracef("failed to unmarshal from file %[1]q: %[2]v", fsc.uri, err)
} else {
fsc.m = res
}
Expand Down
6 changes: 3 additions & 3 deletions yaml/examples_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,9 @@ var (
)

func ExampleYAML() {
configFiles := []string{
filepath.Join(testdataDir, "config.yaml"),
filepath.Join(testdataDir, "alt-config.yaml"),
configFiles := []altsrc.Sourcer{
altsrc.StringSourcer(filepath.Join(testdataDir, "config.yaml")),
altsrc.StringSourcer(filepath.Join(testdataDir, "alt-config.yaml")),
}

app := &cli.Command{
Expand Down
2 changes: 1 addition & 1 deletion yaml/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ go 1.23.2
require (
github.com/stretchr/testify v1.9.0
github.com/urfave/cli-altsrc/v3 v3.0.0-alpha2
github.com/urfave/cli/v3 v3.0.0-alpha9.3
github.com/urfave/cli/v3 v3.0.0-beta1
gopkg.in/yaml.v3 v3.0.1
)

Expand Down
4 changes: 2 additions & 2 deletions yaml/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/urfave/cli/v3 v3.0.0-alpha9.3 h1:RfQlgUHMRxDMwEEmGsrHd+mXYJpWpXlcJM8w86cpjGs=
github.com/urfave/cli/v3 v3.0.0-alpha9.3/go.mod h1:FnIeEMYu+ko8zP1F9Ypr3xkZMIDqW3DR92yUtY39q1Y=
github.com/urfave/cli/v3 v3.0.0-beta1 h1:6DTaaUarcM0wX7qj5Hcvs+5Dm3dyUTBbEwIWAjcw9Zg=
github.com/urfave/cli/v3 v3.0.0-beta1/go.mod h1:FnIeEMYu+ko8zP1F9Ypr3xkZMIDqW3DR92yUtY39q1Y=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
Expand Down
Loading