diff --git a/aperture.go b/aperture.go index 24aa3bf..b3d4ef1 100644 --- a/aperture.go +++ b/aperture.go @@ -102,8 +102,7 @@ func run() error { } // Next, parse configuration file and set up logging. - configFile := filepath.Join(apertureDataDir, defaultConfigFilename) - cfg, err := getConfig(configFile) + cfg, err := getConfig() if err != nil { return fmt.Errorf("unable to parse config file: %w", err) } @@ -319,15 +318,44 @@ func fileExists(name string) bool { // getConfig loads and parses the configuration file then checks it for valid // content. -func getConfig(configFile string) (*Config, error) { +func getConfig() (*Config, error) { + // Pre-parse command line flags to determine whether we've been pointed + // to a custom config file. cfg := &Config{} - b, err := ioutil.ReadFile(configFile) - if err != nil { + if _, err := flags.Parse(cfg); err != nil { return nil, err } - err = yaml.Unmarshal(b, cfg) - if err != nil { + + // If a custom config file is provided, we require that it exists. + var mustExist bool + + configFile := filepath.Join(apertureDataDir, defaultConfigFilename) + if cfg.ConfigFile != "" { + configFile = lnd.CleanAndExpandPath(cfg.ConfigFile) + mustExist = true + } + + // Read our config file, either from the custom path provided or our + // default location. + b, err := ioutil.ReadFile(configFile) + switch { + // If the file was found, unmarshal it. + case err == nil: + err = yaml.Unmarshal(b, cfg) + if err != nil { + return nil, err + } + + // If the error is unrelated to the existence of the file, we must + // always return it. + case !os.IsNotExist(err): return nil, err + + // If we require that the config file exists and we got an error + // related to file existence, we must fail. + case mustExist && os.IsNotExist(err): + return nil, fmt.Errorf("config file: %v must exist: %w", + configFile, err) } // Finally, parse the remaining command line options again to ensure diff --git a/config.go b/config.go index ed35d02..cfd9b69 100644 --- a/config.go +++ b/config.go @@ -104,6 +104,9 @@ type Config struct { // DebugLevel is a string defining the log level for the service either // for all subsystems the same or individual level by subsystem. DebugLevel string `long:"debuglevel" description:"Debug level for the Aperture application and its subsystems."` + + // ConfigFile points aperture to an alternative config file. + ConfigFile string `long:"configfile" description:"Custom path to a config file."` } func (c *Config) validate() error {