mirror of
https://github.com/sablierapp/sablier.git
synced 2025-12-21 13:23:03 +01:00
feat(config): add --configFile argument to specify custom config file
It will also look by default to `/etc/sablier/` then `$XDG_CONFIG_HOME` then `$HOME/.config/` and then `.`. Closes #91
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@@ -1,3 +1,3 @@
|
|||||||
.devcontainer
|
.devcontainer
|
||||||
config.yaml
|
sablier.yaml
|
||||||
./plugins/traefik/e2e/kubeconfig.yaml
|
./plugins/traefik/e2e/kubeconfig.yaml
|
||||||
@@ -16,9 +16,9 @@ RUN make ${TARGETOS}/${TARGETARCH}
|
|||||||
|
|
||||||
FROM alpine
|
FROM alpine
|
||||||
|
|
||||||
COPY --from=build /go/src/sablier/sablier* /go/bin/sablier
|
COPY --from=build /go/src/sablier/sablier* /etc/sablier/sablier
|
||||||
|
|
||||||
EXPOSE 10000
|
EXPOSE 10000
|
||||||
|
|
||||||
ENTRYPOINT [ "/go/bin/sablier" ]
|
ENTRYPOINT [ "/etc/sablier/sablier" ]
|
||||||
CMD [ "start", "--provider.name=docker"]
|
CMD [ "start", "--provider.name=docker"]
|
||||||
17
cmd/root.go
17
cmd/root.go
@@ -15,10 +15,11 @@ import (
|
|||||||
|
|
||||||
const (
|
const (
|
||||||
// The name of our config file, without the file extension because viper supports many different config file languages.
|
// The name of our config file, without the file extension because viper supports many different config file languages.
|
||||||
defaultConfigFilename = "config"
|
defaultConfigFilename = "sablier"
|
||||||
)
|
)
|
||||||
|
|
||||||
var conf = config.NewConfig()
|
var conf = config.NewConfig()
|
||||||
|
var cfgFile string
|
||||||
|
|
||||||
func Execute() {
|
func Execute() {
|
||||||
cmd := NewRootCommand()
|
cmd := NewRootCommand()
|
||||||
@@ -39,6 +40,8 @@ It provides an integrations with multiple reverse proxies and different loading
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rootCmd.PersistentFlags().StringVar(&cfgFile, "configFile", "", "Config file path. If not defined, looks for sablier.(yml|yaml|toml) in /etc/sablier/ > $XDG_CONFIG_HOME > $HOME/.config/ and current directory")
|
||||||
|
|
||||||
startCmd := newStartCommand()
|
startCmd := newStartCommand()
|
||||||
// Provider flags
|
// Provider flags
|
||||||
startCmd.Flags().StringVar(&conf.Provider.Name, "provider.name", "docker", fmt.Sprintf("Provider to use to manage containers %v", config.GetProviders()))
|
startCmd.Flags().StringVar(&conf.Provider.Name, "provider.name", "docker", fmt.Sprintf("Provider to use to manage containers %v", config.GetProviders()))
|
||||||
@@ -85,10 +88,15 @@ func initializeConfig(cmd *cobra.Command) error {
|
|||||||
// Set the base name of the config file, without the file extension.
|
// Set the base name of the config file, without the file extension.
|
||||||
v.SetConfigName(defaultConfigFilename)
|
v.SetConfigName(defaultConfigFilename)
|
||||||
|
|
||||||
// Set as many paths as you like where viper should look for the
|
v.AddConfigPath("/etc/sablier/")
|
||||||
// config file. We are only looking in the current working directory.
|
v.AddConfigPath("$XDG_CONFIG_HOME")
|
||||||
|
v.AddConfigPath("$HOME/.config/")
|
||||||
v.AddConfigPath(".")
|
v.AddConfigPath(".")
|
||||||
|
|
||||||
|
if cfgFile != "" {
|
||||||
|
v.SetConfigFile(cfgFile)
|
||||||
|
}
|
||||||
|
|
||||||
// Attempt to read the config file, gracefully ignoring errors
|
// Attempt to read the config file, gracefully ignoring errors
|
||||||
// caused by a config file not being found. Return an error
|
// caused by a config file not being found. Return an error
|
||||||
// if we cannot parse the config file.
|
// if we cannot parse the config file.
|
||||||
@@ -96,6 +104,9 @@ func initializeConfig(cmd *cobra.Command) error {
|
|||||||
// It's okay if there isn't a config file
|
// It's okay if there isn't a config file
|
||||||
if _, ok := err.(viper.ConfigFileNotFoundError); !ok {
|
if _, ok := err.(viper.ConfigFileNotFoundError); !ok {
|
||||||
return err
|
return err
|
||||||
|
} else if cfgFile != "" {
|
||||||
|
// But if we explicitely defined the config file it should return the error
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -18,24 +18,13 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func TestPrecedence(t *testing.T) {
|
func TestPrecedence(t *testing.T) {
|
||||||
// Run the tests in a temporary directory
|
|
||||||
tmpDir := os.TempDir()
|
|
||||||
testDir, err := os.Getwd()
|
testDir, err := os.Getwd()
|
||||||
require.NoError(t, err, "error getting the current working directory")
|
require.NoError(t, err, "error getting the current working directory")
|
||||||
defer os.Chdir(testDir)
|
|
||||||
err = os.Chdir(tmpDir)
|
|
||||||
require.NoError(t, err, "error changing to the temporary test directory")
|
|
||||||
|
|
||||||
// CHANGE `startCmd` behavior to only print the config, this is for testing purposes only
|
// CHANGE `startCmd` behavior to only print the config, this is for testing purposes only
|
||||||
newStartCommand = mockStartCommand
|
newStartCommand = mockStartCommand
|
||||||
|
|
||||||
t.Run("config file", func(t *testing.T) {
|
t.Run("config file", func(t *testing.T) {
|
||||||
configB, err := os.ReadFile(filepath.Join(testDir, "testdata", "config.yml"))
|
|
||||||
require.NoError(t, err, "error reading test config file")
|
|
||||||
err = ioutil.WriteFile(filepath.Join(tmpDir, "config.yml"), configB, 0644)
|
|
||||||
require.NoError(t, err, "error writing test config file")
|
|
||||||
defer os.Remove(filepath.Join(tmpDir, "config.yml"))
|
|
||||||
|
|
||||||
wantConfig, err := ioutil.ReadFile(filepath.Join(testDir, "testdata", "config_yaml_wanted.json"))
|
wantConfig, err := ioutil.ReadFile(filepath.Join(testDir, "testdata", "config_yaml_wanted.json"))
|
||||||
require.NoError(t, err, "error reading test config file")
|
require.NoError(t, err, "error reading test config file")
|
||||||
|
|
||||||
@@ -43,7 +32,10 @@ func TestPrecedence(t *testing.T) {
|
|||||||
cmd := NewRootCommand()
|
cmd := NewRootCommand()
|
||||||
output := &bytes.Buffer{}
|
output := &bytes.Buffer{}
|
||||||
cmd.SetOut(output)
|
cmd.SetOut(output)
|
||||||
cmd.SetArgs([]string{"start"})
|
cmd.SetArgs([]string{
|
||||||
|
"--configFile", filepath.Join(testDir, "testdata", "config.yml"),
|
||||||
|
"start",
|
||||||
|
})
|
||||||
cmd.Execute()
|
cmd.Execute()
|
||||||
|
|
||||||
gotOutput := output.String()
|
gotOutput := output.String()
|
||||||
@@ -52,13 +44,6 @@ func TestPrecedence(t *testing.T) {
|
|||||||
})
|
})
|
||||||
|
|
||||||
t.Run("env var", func(t *testing.T) {
|
t.Run("env var", func(t *testing.T) {
|
||||||
// 1. Load Config file for precedence assertions
|
|
||||||
configB, err := os.ReadFile(filepath.Join(testDir, "testdata", "config.yml"))
|
|
||||||
require.NoError(t, err, "error reading test config file")
|
|
||||||
err = ioutil.WriteFile(filepath.Join(tmpDir, "config.yml"), configB, 0644)
|
|
||||||
require.NoError(t, err, "error writing test config file")
|
|
||||||
defer os.Remove(filepath.Join(tmpDir, "config.yml"))
|
|
||||||
|
|
||||||
setEnvsFromFile(filepath.Join(testDir, "testdata", "config.env"))
|
setEnvsFromFile(filepath.Join(testDir, "testdata", "config.env"))
|
||||||
defer unsetEnvsFromFile(filepath.Join(testDir, "testdata", "config.env"))
|
defer unsetEnvsFromFile(filepath.Join(testDir, "testdata", "config.env"))
|
||||||
|
|
||||||
@@ -69,7 +54,10 @@ func TestPrecedence(t *testing.T) {
|
|||||||
cmd := NewRootCommand()
|
cmd := NewRootCommand()
|
||||||
output := &bytes.Buffer{}
|
output := &bytes.Buffer{}
|
||||||
cmd.SetOut(output)
|
cmd.SetOut(output)
|
||||||
cmd.SetArgs([]string{"start"})
|
cmd.SetArgs([]string{
|
||||||
|
"--configFile", filepath.Join(testDir, "testdata", "config.yml"),
|
||||||
|
"start",
|
||||||
|
})
|
||||||
cmd.Execute()
|
cmd.Execute()
|
||||||
|
|
||||||
gotOutput := output.String()
|
gotOutput := output.String()
|
||||||
@@ -78,14 +66,6 @@ func TestPrecedence(t *testing.T) {
|
|||||||
})
|
})
|
||||||
|
|
||||||
t.Run("flag", func(t *testing.T) {
|
t.Run("flag", func(t *testing.T) {
|
||||||
// 1. Load Config file for precedence assertions
|
|
||||||
configB, err := os.ReadFile(filepath.Join(testDir, "testdata", "config.yml"))
|
|
||||||
require.NoError(t, err, "error reading test config file")
|
|
||||||
err = ioutil.WriteFile(filepath.Join(tmpDir, "config.yml"), configB, 0644)
|
|
||||||
require.NoError(t, err, "error writing test config file")
|
|
||||||
defer os.Remove(filepath.Join(tmpDir, "config.yml"))
|
|
||||||
|
|
||||||
// 2. Load envs variable for precedence assertions
|
|
||||||
setEnvsFromFile(filepath.Join(testDir, "testdata", "config.env"))
|
setEnvsFromFile(filepath.Join(testDir, "testdata", "config.env"))
|
||||||
defer unsetEnvsFromFile(filepath.Join(testDir, "testdata", "config.env"))
|
defer unsetEnvsFromFile(filepath.Join(testDir, "testdata", "config.env"))
|
||||||
|
|
||||||
@@ -97,6 +77,7 @@ func TestPrecedence(t *testing.T) {
|
|||||||
conf = config.NewConfig()
|
conf = config.NewConfig()
|
||||||
cmd.SetOut(output)
|
cmd.SetOut(output)
|
||||||
cmd.SetArgs([]string{
|
cmd.SetArgs([]string{
|
||||||
|
"--configFile", filepath.Join(testDir, "testdata", "config.yml"),
|
||||||
"start",
|
"start",
|
||||||
"--provider.name", "cli",
|
"--provider.name", "cli",
|
||||||
"--server.port", "3333",
|
"--server.port", "3333",
|
||||||
|
|||||||
Reference in New Issue
Block a user