diff --git a/.gitignore b/.gitignore index 06467242..2ec7b5e8 100644 --- a/.gitignore +++ b/.gitignore @@ -13,6 +13,9 @@ docs dist kafkactl +### Configs +kafkactl.yml + ### Snap snap.login diff --git a/CHANGELOG.md b/CHANGELOG.md index 4996f87e..b9571043 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +- [#159](https://github.com/deviceinsight/kafkactl/issues/159) Add ability to read config file from `$PWD/kafkactl.yml` + ## 3.2.0 - 2023-08-17 ## 3.1.0 - 2023-03-06 diff --git a/README.md b/README.md index f5b62a91..38bf25ba 100644 --- a/README.md +++ b/README.md @@ -156,9 +156,10 @@ current-context: default The config file location is resolved by -- checking for a provided commandline argument: `--config-file=$PATH_TO_CONFIG` -- or by evaluating the environment variable: `export KAFKA_CTL_CONFIG=$PATH_TO_CONFIG` -- or as default the config file is looked up from one of the following locations: +1. checking for a provided commandline argument: `--config-file=$PATH_TO_CONFIG` +2. evaluating the environment variable: `export KAFKA_CTL_CONFIG=$PATH_TO_CONFIG` +3. checking for a config file in the working directory i.e. `$PWD/kafkactl.yml` +4. as default the config file is looked up from one of the following locations: - `$HOME/.config/kafkactl/config.yml` - `$HOME/.kafkactl/config.yml` - `$SNAP_REAL_HOME/.kafkactl/config.yml` diff --git a/cmd/root.go b/cmd/root.go index 8338d38e..483d6dc0 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -31,7 +31,15 @@ var Verbose bool const defaultContextPrefix = "CONTEXTS_DEFAULT_" -var configPaths = []string{"$HOME/.config/kafkactl", "$HOME/.kafkactl", "$SNAP_REAL_HOME/.config/kafkactl", "$SNAP_DATA/kafkactl", "/etc/kafkactl"} +const localConfigName = "kafkactl.yml" + +var configPaths = []string{ + "$HOME/.config/kafkactl", + "$HOME/.kafkactl", + "$SNAP_REAL_HOME/.config/kafkactl", + "$SNAP_DATA/kafkactl", + "/etc/kafkactl", +} func NewKafkactlCommand(streams output.IOStreams) *cobra.Command { @@ -59,7 +67,8 @@ func NewKafkactlCommand(streams output.IOStreams) *cobra.Command { rootCmd.AddCommand(newDocsCmd()) // use upper-case letters for shorthand params to avoid conflicts with local flags - rootCmd.PersistentFlags().StringVarP(&cfgFile, "config-file", "C", "", fmt.Sprintf("config file. one of: %v", configPaths)) + rootCmd.PersistentFlags().StringVarP(&cfgFile, "config-file", "C", "", + fmt.Sprintf("config file. one of: %v", configPaths)) rootCmd.PersistentFlags().BoolVarP(&Verbose, "verbose", "V", false, "verbose output") k8s.KafkaCtlVersion = Version @@ -75,12 +84,16 @@ func initConfig() { viper.Reset() - if cfgFile != "" { - // Use config file from the flag. + localConfigFile := getConfigFileFromWorkingDir() + + switch { + case cfgFile != "": viper.SetConfigFile(cfgFile) - } else if os.Getenv("KAFKA_CTL_CONFIG") != "" { + case os.Getenv("KAFKA_CTL_CONFIG") != "": viper.SetConfigFile(os.Getenv("KAFKA_CTL_CONFIG")) - } else { + case localConfigFile != "": + viper.SetConfigFile(localConfigFile) + default: for _, path := range configPaths { viper.AddConfigPath(os.ExpandEnv(path)) } @@ -111,6 +124,14 @@ func initConfig() { } } +func getConfigFileFromWorkingDir() string { + if _, err := os.Stat(localConfigName); err != nil { + return "" + } + + return localConfigName +} + func mapEnvVariables() { for _, short := range env.Variables { long := defaultContextPrefix + short