30
30
// debug indicates if the `debug` flag has been set to enable configure the logging for the debug scope.
31
31
debug bool
32
32
// explicitConfigFilePath stores the path to the application configuration file when the `config` flag is specified.
33
+ // It takes precedence over the default application configuration paths.
33
34
explicitConfigFilePath string
35
+ // snowblockBaseDirs stores the comma-separated paths to the snowblock directories when the `basedirs` flag is
36
+ // specified.
37
+ // It takes precedence over the path of the application configuration file(s).
38
+ snowblockBaseDirs []string
34
39
)
35
40
36
41
// rootCmd is the root command of the application.
@@ -48,7 +53,7 @@ var rootCmd = &cobra.Command{
48
53
// Run is the main application function that adds all child commands to the root command and sets flags appropriately.
49
54
// This is called by `main.main()` and only needs to be run once for the root command.
50
55
func Run () {
51
- // Disable verbose errors to provide custom formatted CLI output via application-wide printer .
56
+ // Disable cobra's verbose errors and replace with custom formatted CLI logger from the `pkg/prt` package .
52
57
rootCmd .SilenceErrors = true
53
58
54
59
// Run the application with the given commands, flags and arguments and exit on any (downstream) error.
@@ -60,35 +65,39 @@ func Run() {
60
65
61
66
func init () {
62
67
// Specify the functions to be run before each command gets executed.
63
- cobra .OnInitialize (initDebugScope , initConfig , initPrinter )
68
+ cobra .OnInitialize (initDebugScope , initConfig , initPrinter , mergeConfigValues )
64
69
65
70
// Define global application flags.
66
- rootCmd .PersistentFlags ().StringVar (& explicitConfigFilePath , "config" , "" , "set the configuration file" )
71
+ rootCmd .PersistentFlags ().StringVar (& explicitConfigFilePath , "config" , "" , "path to the configuration file" )
67
72
rootCmd .PersistentFlags ().BoolVar (& debug , "debug" , false , "enable debug information output" )
73
+ rootCmd .PersistentFlags ().StringSliceVarP (
74
+ & snowblockBaseDirs , "basedirs" , "b" , config .AppConfig .Snowblocks .Paths ,
75
+ "comma-separated paths to snowblock base directories" )
68
76
69
77
// Set the app version information for the automatically generated `version` flag.
70
78
rootCmd .Version = color .CyanString (config .Version )
71
79
rootCmd .SetVersionTemplate (`{{printf "%s\n" .Version}}` )
72
80
73
81
// Create and register all subcommands.
74
82
rootCmd .AddCommand (info .NewInfoCmd ())
83
+ rootCmd .AddCommand (bootstrap .NewBootstrapCmd ())
75
84
}
76
85
77
86
// initConfig searches and loads either the default application configuration file paths or the explicit file at the
78
87
// given path specified through the global `config` flag.
79
88
func initConfig () {
80
89
if explicitConfigFilePath != "" {
81
- if err := builder .Load (file .NewFile (explicitConfigFilePath )).Into (& config .AppConfig ); err != nil {
82
- prt .Errorf ("while loading custom application configuration file:\n %v" , err )
90
+ if err := builder .Load (file .NewFile (explicitConfigFilePath )).Into (& config .AppConfig , false ); err != nil {
91
+ prt .Errorf ("Failed to load application configuration file: %v" , err )
83
92
os .Exit (1 )
84
93
}
85
94
} else {
86
95
b := builder .Load (config .AppConfigPaths ... )
87
96
if len (b .Files ) == 0 {
88
- prt .Debugf ("No configuration files found, using default application configuration ." )
97
+ prt .Debugf ("No configuration files found, using application defaults ." )
89
98
}
90
- if err := b .Into (& config .AppConfig ); err != nil {
91
- prt .Errorf ("while loading application configuration files: \n %v" , err )
99
+ if err := b .Into (& config .AppConfig , true ); err != nil {
100
+ prt .Errorf ("Failed to load application configuration file(s): %v" , err )
92
101
os .Exit (1 )
93
102
}
94
103
}
@@ -103,13 +112,36 @@ func initDebugScope() {
103
112
104
113
// setPrinterVerbosityLevel configures the global CLI printer like the verbosity level.
105
114
func initPrinter () {
106
- lvl , err := prt .ParseVerbosityLevel (strings .ToUpper (config .AppConfig .LogLevel ))
107
- if err != nil {
108
- prt .Debugf ("Error while parsing log level from configuration: %v" , err )
109
- prt .Debugf ("Using default INFO level as fallback" )
110
- prt .SetVerbosityLevel (prt .InfoVerbosity )
111
- } else {
112
- prt .Debugf ("Using configured logger level: %s" , strings .ToUpper (config .AppConfig .LogLevel ))
113
- prt .SetVerbosityLevel (lvl )
115
+ // The `debug` flag always takes precedence and overrides the application configuration value.
116
+ if ! debug {
117
+ lvl , err := prt .ParseVerbosityLevel (strings .ToUpper (config .AppConfig .LogLevel ))
118
+ if err != nil {
119
+ prt .Debugf ("Error while parsing log level from configuration: %v" , err )
120
+ prt .Debugf ("Using default INFO level as fallback" )
121
+ prt .SetVerbosityLevel (prt .InfoVerbosity )
122
+ } else {
123
+ prt .Debugf ("Using configured logger level: %s" , strings .ToUpper (config .AppConfig .LogLevel ))
124
+ prt .SetVerbosityLevel (lvl )
125
+ }
126
+ }
127
+ }
128
+
129
+ // mergeConfigValues merges the specified (global) flags and merges the corresponding values with the default
130
+ // application configuration values.
131
+ // Since flags have the highest precedence their value will override application defaults as well as value from
132
+ // loaded application configuration files.
133
+ func mergeConfigValues () {
134
+ // Use configured or individual snowblock base directories if specified, otherwise fall back to the default directory.
135
+ if len (config .AppConfig .Snowblocks .BaseDirs ) == 0 {
136
+ config .AppConfig .Snowblocks .BaseDirs = append (
137
+ config .AppConfig .Snowblocks .BaseDirs , config .DefaultSnowblocksBaseDirectoryName )
138
+ }
139
+ if len (snowblockBaseDirs ) > 0 {
140
+ config .AppConfig .Snowblocks .BaseDirs = snowblockBaseDirs
141
+ }
142
+
143
+ // If the logging level has not been specified fall back to the default level.
144
+ if config .AppConfig .LogLevel == "" {
145
+ config .AppConfig .LogLevel = config .DefaultLoggingLevel
114
146
}
115
147
}
0 commit comments