@@ -8,8 +8,10 @@ import (
88 "fmt"
99 "os"
1010 "os/signal"
11+ "path"
1112 "syscall"
1213
14+ "github.com/spf13/pflag"
1315 "github.com/spf13/viper"
1416
1517 "github.com/cloudoperators/cloudctl/cmd"
@@ -18,15 +20,69 @@ import (
1820)
1921
2022func main () {
23+ var (
24+ config string
25+ )
26+
27+ // It is assmued there that $HOME is always set to correct value
28+ home := os .Getenv ("HOME" )
29+
2130 // Optionally read environment variables, config files, etc.
2231 viper .SetEnvPrefix ("CLOUDCTL" )
2332 viper .AutomaticEnv ()
2433
34+ viper .BindPFlags (pflag .CommandLine )
35+
36+ pflag .StringVarP (& config , "config" , "c" , "" , "Path to configuration file" )
37+ pflag .Parse ()
38+
39+ viper .SetConfigType ("yaml" )
40+
41+ if len (config ) > 0 {
42+ // First we are trying config provided as command line parameter.
43+ viper .SetConfigFile (config )
44+ } else {
45+ // Then we are searching for ".cloudctl.yaml" in current or home directory
46+ viper .AddConfigPath ("." )
47+ viper .AddConfigPath (home )
48+ viper .SetConfigName (".cloudctl" )
49+ }
50+
51+ err := viper .ReadInConfig ()
52+ if _ , ok := err .(viper.ConfigFileNotFoundError ); ok {
53+ // If reading config in above described locations failed, we are looking for configuration
54+ // in these locations:
55+ // ./cloudctl.yaml
56+ // $HOME/cloudclt.yaml
57+ // $XDG_CONFIG_HOME/cloudctl/cloudctl.yaml
58+ // $XDG_CONFIG_HOME/cloudctl.yaml
59+ // $HOME/.config/cloudctl/cloudctl.yaml
60+ // $HOME/.config/cloudctl.yaml
61+ viper .SetConfigName ("cloudctl" )
62+ if xdgConfig := os .Getenv ("XDG_CONFIG_HOME" ); len (xdgConfig ) > 0 {
63+ viper .AddConfigPath (path .Join (xdgConfig , "cloudctl" ))
64+ viper .AddConfigPath (xdgConfig )
65+ } else {
66+ viper .AddConfigPath (path .Join (home , ".config" , "cloudctl" ))
67+ viper .AddConfigPath (path .Join (home , ".config" ))
68+ }
69+ err = viper .ReadInConfig ()
70+ if _ , ok := err .(viper.ConfigFileNotFoundError ); ok {
71+ err = nil
72+ }
73+ }
74+
75+ // Show error message and exit if config file was found but failed to read.
76+ if err != nil {
77+ fmt .Fprintln (os .Stderr , err )
78+ os .Exit (1 )
79+ }
80+
2581 // Graceful cancellation on SIGINT/SIGTERM
2682 ctx , stop := signal .NotifyContext (context .Background (), syscall .SIGINT , syscall .SIGTERM )
2783 defer stop ()
2884
29- if err : = cmd .Execute (ctx ); err != nil {
85+ if err = cmd .Execute (ctx ); err != nil {
3086 // Print errors to stderr
3187 fmt .Fprintln (os .Stderr , err )
3288 os .Exit (1 )
0 commit comments