From 5761e03a993b07e2c9cee4cb9d67d8b15f18ca52 Mon Sep 17 00:00:00 2001 From: Matt Witherspoon <32485495+spoonincode@users.noreply.github.com> Date: Mon, 2 Apr 2018 18:10:00 -0400 Subject: [PATCH] Add option to print default configuration template Add an option to print the default configuration template. This could be useful to packagers (to create an /etc/ template without making /etc writable) or for users to see a diff of their config.ini compared to future defaults. --- application.cpp | 28 +++++++++++++++++++--------- include/appbase/application.hpp | 1 + 2 files changed, 20 insertions(+), 9 deletions(-) diff --git a/application.cpp b/application.cpp index 4b493aaaf..82344ddd7 100644 --- a/application.cpp +++ b/application.cpp @@ -95,6 +95,7 @@ void application::set_program_options() app_cli_opts.add_options() ("help,h", "Print this help message and exit.") ("version,v", "Print version information.") + ("print-default-config", "Print default configuration template") ("data-dir,d", bpo::value(), "Directory containing program runtime data") ("config-dir", bpo::value(), "Directory containing configuration files such as config.ini") ("config,c", bpo::value()->default_value( "config.ini" ), "Configuration file name relative to config-dir") @@ -121,6 +122,11 @@ bool application::initialize_impl(int argc, char** argv, vector(); if( data_dir.is_relative() ) @@ -220,6 +226,12 @@ void application::write_default_config(const bfs::path& cfg_file) { if(!bfs::exists(cfg_file.parent_path())) bfs::create_directories(cfg_file.parent_path()); + std::ofstream out_cfg( bfs::path(cfg_file).make_preferred().string()); + print_default_config(out_cfg); + out_cfg.close(); +} + +void application::print_default_config(std::ostream& os) { std::map option_to_plug; for(auto& plug : plugins) { boost::program_options::options_description plugin_cli_opts; @@ -230,34 +242,32 @@ void application::write_default_config(const bfs::path& cfg_file) { option_to_plug[opt->long_name()] = plug.second->name(); } - std::ofstream out_cfg( bfs::path(cfg_file).make_preferred().string()); for(const boost::shared_ptr od : my->_cfg_options.options()) { if(!od->description().empty()) { - out_cfg << "# " << od->description(); + os << "# " << od->description(); std::map::iterator it; if((it = option_to_plug.find(od->long_name())) != option_to_plug.end()) - out_cfg << " (" << it->second << ")"; - out_cfg << std::endl; + os << " (" << it->second << ")"; + os << std::endl; } boost::any store; if(!od->semantic()->apply_default(store)) - out_cfg << "# " << od->long_name() << " = " << std::endl; + os << "# " << od->long_name() << " = " << std::endl; else { auto example = od->format_parameter(); if(example.empty()) // This is a boolean switch - out_cfg << od->long_name() << " = " << "false" << std::endl; + os << od->long_name() << " = " << "false" << std::endl; else { // The string is formatted "arg (=)" example.erase(0, 6); example.erase(example.length()-1); - out_cfg << od->long_name() << " = " << example << std::endl; + os << od->long_name() << " = " << example << std::endl; } } - out_cfg << std::endl; + os << std::endl; } - out_cfg.close(); } abstract_plugin* application::find_plugin(const string& name)const diff --git a/include/appbase/application.hpp b/include/appbase/application.hpp index 1e79c2501..571d26492 100644 --- a/include/appbase/application.hpp +++ b/include/appbase/application.hpp @@ -124,6 +124,7 @@ namespace appbase { void set_program_options(); void write_default_config(const bfs::path& cfg_file); + void print_default_config(std::ostream& os); std::unique_ptr my; };