summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDave Henderson <dhenderson@gmail.com>2024-09-30 11:16:28 -0400
committerGitHub <noreply@github.com>2024-09-30 11:16:28 -0400
commit18791a4e6e08de406e9c1e257cc4be2a85f29eea (patch)
tree0a32b7b821a229e0bbdf11775f3e66c2fce24217
parent69d3e0c46e34a57e6cfcb58d36b28c6f0beb134e (diff)
feat(config): Allow avoiding reading default config file (#2227)
Signed-off-by: Dave Henderson <dhenderson@gmail.com>
-rw-r--r--.github/workflows/docs.yml2
-rw-r--r--docs/content/usage.md2
-rw-r--r--env/env.go10
-rw-r--r--internal/cmd/config.go26
-rw-r--r--internal/cmd/config_test.go28
-rw-r--r--internal/datafs/getenv.go20
-rw-r--r--internal/tests/integration/config_test.go14
-rw-r--r--internal/tests/integration/datasources_consul_test.go3
8 files changed, 85 insertions, 20 deletions
diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml
index 89d376b7..76b0113a 100644
--- a/.github/workflows/docs.yml
+++ b/.github/workflows/docs.yml
@@ -52,5 +52,7 @@ jobs:
--exclude="https://docs\.aws.*" \
--exclude="https://linux.die\.net.*" \
--exclude="https://jqplay\.org.*" \
+ --exclude="https://json\.org.*" \
+ --exclude="https://goessner\.net.*"
kill %1
diff --git a/docs/content/usage.md b/docs/content/usage.md
index df59d345..280778fe 100644
--- a/docs/content/usage.md
+++ b/docs/content/usage.md
@@ -21,7 +21,7 @@ Hello, hairyhenderson
### `--config`
-Specify the path to a [gomplate config file](../config). The default is `.gomplate.yaml`. Can also be set with the `GOMPLATE_CONFIG` environment variable.
+Specify the path to a [gomplate config file](../config). The default is `.gomplate.yaml`. Can also be set with the `GOMPLATE_CONFIG` environment variable. Setting `--config` or `GOMPLATE_CONFIG` to an empty string (`--config=""` or `export GOMPLATE_CONFIG=""`) will disable the use of a config file, skipping the default `.gomplate.yaml` file.
For example:
diff --git a/env/env.go b/env/env.go
index 598361bf..16e121fc 100644
--- a/env/env.go
+++ b/env/env.go
@@ -20,3 +20,13 @@ func ExpandEnv(s string) string {
fsys := datafs.WrapWdFS(osfs.NewFS())
return datafs.ExpandEnvFsys(fsys, s)
}
+
+// LookupEnv - retrieves the value of the environment variable named by the key.
+// If the variable is unset, but the same variable ending in `_FILE` is set, the
+// referenced file will be read into the value. If the key is not set, the
+// second return value will be false.
+// Otherwise the provided default (or an emptry string) is returned.
+func LookupEnv(key string) (string, bool) {
+ fsys := datafs.WrapWdFS(osfs.NewFS())
+ return datafs.LookupEnvFsys(fsys, key)
+}
diff --git a/internal/cmd/config.go b/internal/cmd/config.go
index 683c78dd..11886bba 100644
--- a/internal/cmd/config.go
+++ b/internal/cmd/config.go
@@ -57,22 +57,34 @@ func loadConfig(ctx context.Context, cmd *cobra.Command, args []string) (*gompla
return cfg, nil
}
-func pickConfigFile(cmd *cobra.Command) (cfgFile string, required bool) {
+func pickConfigFile(cmd *cobra.Command) (cfgFile string, required, skip bool) {
cfgFile = defaultConfigFile
- if c := env.Getenv("GOMPLATE_CONFIG"); c != "" {
+ if c, found := env.LookupEnv("GOMPLATE_CONFIG"); found {
cfgFile = c
- required = true
+ if cfgFile == "" {
+ skip = true
+ } else {
+ required = true
+ }
}
- if cmd.Flags().Changed("config") && cmd.Flag("config").Value.String() != "" {
+ if cmd.Flags().Changed("config") {
// Use config file from the flag if specified
cfgFile = cmd.Flag("config").Value.String()
- required = true
+ if cfgFile == "" {
+ skip = true
+ } else {
+ required = true
+ }
}
- return cfgFile, required
+ return cfgFile, required, skip
}
func readConfigFile(ctx context.Context, cmd *cobra.Command) (*gomplate.Config, error) {
- cfgFile, configRequired := pickConfigFile(cmd)
+ cfgFile, configRequired, skip := pickConfigFile(cmd)
+ if skip {
+ // --config was specified with an empty value
+ return nil, nil
+ }
// we only support loading configs from the local filesystem for now
fsys, err := datafs.FSysForPath(ctx, cfgFile)
diff --git a/internal/cmd/config_test.go b/internal/cmd/config_test.go
index ce59f027..760766fd 100644
--- a/internal/cmd/config_test.go
+++ b/internal/cmd/config_test.go
@@ -188,29 +188,49 @@ func TestPickConfigFile(t *testing.T) {
cmd.Flags().String("config", defaultConfigFile, "foo")
t.Run("default", func(t *testing.T) {
- cf, req := pickConfigFile(cmd)
+ cf, req, skip := pickConfigFile(cmd)
assert.False(t, req)
+ assert.False(t, skip)
assert.Equal(t, defaultConfigFile, cf)
})
t.Run("GOMPLATE_CONFIG env var", func(t *testing.T) {
t.Setenv("GOMPLATE_CONFIG", "foo.yaml")
- cf, req := pickConfigFile(cmd)
+ cf, req, skip := pickConfigFile(cmd)
assert.True(t, req)
+ assert.False(t, skip)
assert.Equal(t, "foo.yaml", cf)
})
t.Run("--config flag", func(t *testing.T) {
cmd.ParseFlags([]string{"--config", "config.file"})
- cf, req := pickConfigFile(cmd)
+ cf, req, skip := pickConfigFile(cmd)
assert.True(t, req)
+ assert.False(t, skip)
assert.Equal(t, "config.file", cf)
t.Setenv("GOMPLATE_CONFIG", "ignored.yaml")
- cf, req = pickConfigFile(cmd)
+ cf, req, skip = pickConfigFile(cmd)
assert.True(t, req)
+ assert.False(t, skip)
assert.Equal(t, "config.file", cf)
})
+
+ t.Run("--config flag with empty value should skip reading", func(t *testing.T) {
+ cmd.ParseFlags([]string{"--config", ""})
+ cf, req, skip := pickConfigFile(cmd)
+ assert.False(t, req)
+ assert.True(t, skip)
+ assert.Equal(t, "", cf)
+ })
+
+ t.Run("GOMPLATE_CONFIG env var with empty value should skip reading", func(t *testing.T) {
+ t.Setenv("GOMPLATE_CONFIG", "")
+ cf, req, skip := pickConfigFile(cmd)
+ assert.False(t, req)
+ assert.True(t, skip)
+ assert.Equal(t, "", cf)
+ })
}
func TestApplyEnvVars(t *testing.T) {
diff --git a/internal/datafs/getenv.go b/internal/datafs/getenv.go
index 5f9761d4..6af03508 100644
--- a/internal/datafs/getenv.go
+++ b/internal/datafs/getenv.go
@@ -15,7 +15,7 @@ func ExpandEnvFsys(fsys fs.FS, s string) string {
// GetenvFsys - a convenience function intended for internal use only!
func GetenvFsys(fsys fs.FS, key string, def ...string) string {
- val := getenvFile(fsys, key)
+ val, _ := getenvFile(fsys, key)
if val == "" && len(def) > 0 {
return def[0]
}
@@ -23,22 +23,28 @@ func GetenvFsys(fsys fs.FS, key string, def ...string) string {
return val
}
-func getenvFile(fsys fs.FS, key string) string {
- val := os.Getenv(key)
+// LookupEnvFsys - a convenience function intended for internal use only!
+func LookupEnvFsys(fsys fs.FS, key string) (string, bool) {
+ return getenvFile(fsys, key)
+}
+
+func getenvFile(fsys fs.FS, key string) (string, bool) {
+ val, found := os.LookupEnv(key)
if val != "" {
- return val
+ return val, true
}
p := os.Getenv(key + "_FILE")
if p != "" {
val, err := readFile(fsys, p)
if err != nil {
- return ""
+ return "", false
}
- return strings.TrimSpace(val)
+
+ return strings.TrimSpace(val), true
}
- return ""
+ return "", found
}
func readFile(fsys fs.FS, p string) (string, error) {
diff --git a/internal/tests/integration/config_test.go b/internal/tests/integration/config_test.go
index 1ae19e00..80c9d904 100644
--- a/internal/tests/integration/config_test.go
+++ b/internal/tests/integration/config_test.go
@@ -153,6 +153,20 @@ func TestConfig_EnvConfigFile(t *testing.T) {
assertSuccess(t, o, e, err, "yet another alternate config")
}
+func TestConfig_SkipConfigFile(t *testing.T) {
+ tmpDir := setupConfigTest(t)
+
+ // first set a poisoned default config to prove that it's not being read
+ writeFile(t, tmpDir, ".gomplate.yaml", `badyaml`)
+
+ o, e, err := cmd(t, "--config", "", "--in", "foo").withDir(tmpDir.Path()).run()
+ assertSuccess(t, o, e, err, "foo")
+
+ o, e, err = cmd(t, "--in", "foo").withDir(tmpDir.Path()).
+ withEnv("GOMPLATE_CONFIG", "").run()
+ assertSuccess(t, o, e, err, "foo")
+}
+
func TestConfig_ConfigOverridesEnvDelim(t *testing.T) {
if isWindows {
t.Skip()
diff --git a/internal/tests/integration/datasources_consul_test.go b/internal/tests/integration/datasources_consul_test.go
index f04d5020..741f91df 100644
--- a/internal/tests/integration/datasources_consul_test.go
+++ b/internal/tests/integration/datasources_consul_test.go
@@ -42,7 +42,8 @@ func setupDatasourcesConsulTest(t *testing.T) (string, *vaultClient) {
"serf_lan": `+strconv.Itoa(serfLanPort)+`,
"serf_wan": -1,
"dns": -1,
- "grpc": -1
+ "grpc": -1,
+ "grpc_tls": -1
},
"connect": { "enabled": false }
}`,