Skip to content

Commit

Permalink
Fix problems with reading config files using --config (apigee#1230)
Browse files Browse the repository at this point in the history
* Fix problems with reading config files using `--config`
* Add test to verify that we can read config files outside of ~/.config
  • Loading branch information
timburks authored Oct 12, 2023
1 parent be22021 commit f805290
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 9 deletions.
19 changes: 10 additions & 9 deletions pkg/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ var (
// `cmd.PersistentFlags().AddFlagSet(connection.Flags)`
Flags *pflag.FlagSet = CreateFlagSet()

// Directory is $HOME/config/registry
// Directory is $HOME/.config/registry
Directory string
ErrCannotDeleteActive = fmt.Errorf("cannot delete active configuration")
ErrReservedConfigName = fmt.Errorf("%q is reserved", ActivePointerFilename)
Expand Down Expand Up @@ -100,10 +100,6 @@ func ValidateName(name string) error {
if name == ActivePointerFilename {
return ErrReservedConfigName
}

if dir, _ := filepath.Split(name); dir != "" {
return fmt.Errorf("%q must not include a path", name)
}
return nil
}

Expand Down Expand Up @@ -199,9 +195,10 @@ func ReadValid(name string) (c Configuration, err error) {
}

// Read loads a Configuration from yaml file matching `name`. If name
// contains a path, the file will be read from that path, otherwise
// the path is assumed as: ~/.config/registry. Does a simple read from the
// file: does not bind to env vars or flags, resolve, or validate.
// contains a path or refers to a local file, the file will be read
// using name, otherwise the path is assumed as: ~/.config/registry.
// Does a simple read from the file: does not bind to env vars or flags,
// resolve, or validate.
// See also: ReadValid()
func Read(name string) (c Configuration, err error) {
if err = ValidateName(name); err != nil {
Expand All @@ -210,7 +207,11 @@ func Read(name string) (c Configuration, err error) {

dir, file := filepath.Split(name)
if dir == "" {
name = filepath.Join(Directory, file)
// If name refers to a local file, preferentially read the local file.
// Otherwise assume name refers to a file in the config directory.
if info, err := os.Stat(file); errors.Is(err, os.ErrNotExist) || info.IsDir() {
name = filepath.Join(Directory, file)
}
}
var r io.Reader
if r, err = os.Open(name); err != nil {
Expand Down
39 changes: 39 additions & 0 deletions pkg/config/configuration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
package config_test

import (
"log"
"os"
"path"
"path/filepath"
Expand All @@ -24,6 +25,7 @@ import (
"github.com/apigee/registry/pkg/config"
"github.com/apigee/registry/pkg/config/test"
"github.com/google/go-cmp/cmp"
"gopkg.in/yaml.v2"
)

func TestMissingDirectory(t *testing.T) {
Expand Down Expand Up @@ -476,3 +478,40 @@ func TestResolve(t *testing.T) {
t.Errorf("want: %s, got: %s", "hello", c.Registry.Token)
}
}

func TestReadExternalFile(t *testing.T) {
c := config.Configuration{
Registry: config.Registry{Address: "example.com:443"},
}
bytes, err := yaml.Marshal(c)
if err != nil {
t.Fatal(err)
}
f, err := os.CreateTemp(".", "tmpfile-")
if err != nil {
log.Fatal(err)
}
if _, err = f.Write(bytes); err != nil {
log.Fatal(err)
}
if err = f.Close(); err != nil {
log.Fatal(err)
}
defer os.Remove(f.Name())
// Verify that we can read a file using its full path name.
c2, err := config.Read(f.Name())
if err != nil {
t.Fatal(err)
}
if c2.Registry.Address != c.Registry.Address {
t.Errorf("want: %s, got: %s", c2.Registry.Address, c.Registry.Address)
}
// Verify that we can read a local file using its base name.
c3, err := config.Read(filepath.Base(f.Name()))
if err != nil {
t.Fatal(err)
}
if c3.Registry.Address != c.Registry.Address {
t.Errorf("want: %s, got: %s", c3.Registry.Address, c.Registry.Address)
}
}

0 comments on commit f805290

Please sign in to comment.