@@ -17,8 +17,10 @@ import (
1717 "github.com/kr/pretty"
1818)
1919
20+ // Version is the CLI version or release number. To be overriden at build time.
2021var Version = "unknown"
2122
23+ // Run hkmgr
2224func Run () error {
2325 var upSubcommand * flaggy.Subcommand
2426 var downSubcommand * flaggy.Subcommand
@@ -28,7 +30,8 @@ func Run() error {
2830 var statusSubcommand * flaggy.Subcommand
2931 var consoleSubcommand * flaggy.Subcommand
3032
31- configPath := "hkmgr.toml"
33+ //
34+ var cliConfigPaths []string
3235 var debug bool
3336 var dryRun bool
3437 var vmName string
@@ -37,8 +40,8 @@ func Run() error {
3740 flaggy .SetDescription ("VM manager for hyperkit" )
3841
3942 flaggy .DefaultParser .AdditionalHelpPrepend = "http://github.com/bensallen/hkmgr"
43+ flaggy .StringSlice (& cliConfigPaths , "c" , "config" , "Path to configuration TOML file or directory of TOML files" )
4044
41- flaggy .String (& configPath , "c" , "config" , "Path to configuration TOML file" )
4245 flaggy .Bool (& debug , "d" , "debug" , "Enable debug output" )
4346 flaggy .Bool (& dryRun , "n" , "dry-run" , "Don't execute any commands that affect change, just show what will be run" )
4447
@@ -89,23 +92,57 @@ func Run() error {
8992 debug = true
9093 }
9194
92- cfgStat , err := os .Stat (configPath )
95+ // Default to look for configs hkmgr.toml and hkmgr.d/*.toml
96+ if len (cliConfigPaths ) == 0 {
97+ cliConfigPaths = []string {"hkmgr.toml" , "hkmgr.d" }
98+ }
99+
100+ cfgPaths := []string {}
101+ var firstCfgPath string
102+ for _ , cliConfigPath := range cliConfigPaths {
103+ cfgStat , err := os .Stat (cliConfigPath )
93104
94- if os .IsNotExist (err ) {
95- return fmt .Errorf ("configuration file %s not found" , configPath )
105+ if os .IsNotExist (err ) {
106+ continue
107+ }
108+ if cfgStat .IsDir () {
109+ globPaths , err := filepath .Glob (cliConfigPath + "/*.toml" )
110+
111+ if err != nil {
112+ fmt .Printf ("configuration path %s is a directory and failed with %v" , cliConfigPath , err )
113+ continue
114+ }
115+
116+ if len (globPaths ) == 0 {
117+ continue
118+ }
119+ cfgPaths = append (cfgPaths , globPaths ... )
120+ } else {
121+ cfgPaths = append (cfgPaths , cliConfigPath )
122+ }
123+ // Record the first valid path so that it can be used to resolve relative paths
124+ if firstCfgPath == "" {
125+ firstCfgPath = cliConfigPath
126+ }
96127 }
97- if cfgStat .IsDir () {
98- return fmt .Errorf ("configuration file %s is a directory" , configPath )
128+ fmt .Printf ("%#v\n " , cfgPaths )
129+
130+ if len (cfgPaths ) == 0 {
131+ return fmt .Errorf ("no configuration files found" )
99132 }
100133
101134 var config config.Config
102- if _ , err := toml .DecodeFile (configPath , & config ); err != nil {
103- return err
135+ for _ , cfgPath := range cfgPaths {
136+ if _ , err := toml .DecodeFile (cfgPath , & config ); err != nil {
137+ return err
138+ }
104139 }
105140
106- if config .Path , err = filepath .Abs (configPath ); err != nil {
141+ absPath , err := filepath .Abs (firstCfgPath )
142+ if err != nil {
107143 return err
108144 }
145+ config .Path = absPath
109146
110147 if err := config .Defaults (); err != nil {
111148 return err
0 commit comments