Repository: iqlusioninc/abscissa (language: rust)

Issue:
Config paths that point to non-existing config files
After implementing `Configurable<FooConfig> for FooCommand` to have `config_path` return the application's config path (and tweaking things so this is actually called, see #79 for notes on my confusion), my application exits with a hard error if a config file does not exist at the supplied path.

Ideally I would like the application to attempt to load a config from a supplied path, or use a set of defaults if that file doesn't exist.  

The `config_path` documentation doesn't give details, but is it the responsibility of the `config_path` function to check whether the file exists and return `None` if not, or should it return the expected path for a config file, and have the config loading logic have responsibility for gracefully handling the case where the config is not supplied?


Discussion / hints:
This is a gross oversight in `abscissa::command::EntryPoint`. My apologies.

I agree it should attempt to source `config_path` from the underlying toplevel command it wraps unless one is provided explicitly as a command-line argument.

The intention is definitely that you can simply supply a path to load without checking it exists, and the framework will handle the file's absence by printing an error. If you would like to print a custom error rather than letting the framework handle it, you can check for the file's existence in advance (however note you won't get called in the event `-c` is passed).

Fix patch:
diff --git a/abscissa_generator/template/src/commands.rs.hbs b/abscissa_generator/template/src/commands.rs.hbs
index 08df0b05..18f1ea92 100644
--- a/abscissa_generator/template/src/commands.rs.hbs
+++ b/abscissa_generator/template/src/commands.rs.hbs
@@ -18,6 +18,9 @@ use crate::config::{{~config_type~}};
 use abscissa::{config::Override, Command, Configurable, FrameworkError, Help, Options, Runnable};
 use std::path::PathBuf;
 
+/// {{title}} Configuration Filename
+pub const CONFIG_FILE: &str = "{{name}}.toml";
+
 /// {{title}} Subcommands
 #[derive(Command, Debug, Options, Runnable)]
 pub enum {{command_type}} {
@@ -36,16 +39,25 @@ pub enum {{command_type}} {
 
 /// This trait allows you to define how application configuration is loaded.
 impl Configurable<{{~config_type~}}> for {{command_type}} {
-    // Have `config_path` return `Some(path)` in order to trigger the
-    // application configuration being loaded.
+    /// Location of the configuration file
     fn config_path(&self) -> Option<PathBuf> {
-        None
+        // Check if the config file exists, and if it does not, ignore it.
+        // If you'd like for a missing configuration file to be a hard error
+        // instead, always return `Some(CONFIG_FILE)` here.
+        let filename = PathBuf::from(CONFIG_FILE);
+
+        if filename.exists() {
+            Some(filename)
+        } else {
+            None
+        }
     }
 
-    // Apply changes to the config after it's been loaded, e.g. overriding
-    // values in a config file using command-line options.
-    //
-    // This can be safely deleted if you don't intend to use it.
+    /// Apply changes to the config after it's been loaded, e.g. overriding
+    /// values in a config file using command-line options.
+    ///
+    /// This can be safely deleted if you don't want to override config
+    /// settings from command-line options.
     fn process_config(
         &self,
         config: {{config_type}},


Test patch: