From 8ba0239283aae6bf91ead6728025c606f726c5c8 Mon Sep 17 00:00:00 2001 From: Bartek Kryza Date: Sun, 5 Mar 2023 19:34:06 +0100 Subject: [PATCH] Added option to read config file from stdin (related #105) --- docs/configuration_file.md | 13 +++++++ src/config/yaml_decoders.cc | 28 ++++++++++++--- src/main.cc | 72 +++++++++++++++++++++++-------------- 3 files changed, 81 insertions(+), 32 deletions(-) diff --git a/docs/configuration_file.md b/docs/configuration_file.md index a13bd5d2..e1111913 100644 --- a/docs/configuration_file.md +++ b/docs/configuration_file.md @@ -5,6 +5,7 @@ * [Top level options](#top-level-options) * [Diagram options](#diagram-options) * [Example complete config](#example-complete-config) +* [Determining config file location](#determining-config-file-location) * [Paths](#paths) @@ -121,6 +122,18 @@ diagrams: - 'title clang-uml class diagram model' ``` +## Determining config file location + +If `-c,--config` option is not provided, `clang-uml` will try to open file +`.clang-uml` in the current directory and fail if it doesn't exist. + +With `-c,--config` option pointing to a valid `.clang-uml` file path, the file +configuration will be loaded from that file. + +Furthermore, when the value of `-c,--config` option is `-` - the entire config +will be read from `stdin`, which can be useful for scripting and generating +config Yaml documents on the fly. + ## Paths By default, all paths specified in the configuration file, including: diff --git a/src/config/yaml_decoders.cc b/src/config/yaml_decoders.cc index ddf59669..3b4cf962 100644 --- a/src/config/yaml_decoders.cc +++ b/src/config/yaml_decoders.cc @@ -609,14 +609,32 @@ config load( const std::string &config_file, std::optional paths_relative_to_pwd) { try { - YAML::Node doc = YAML::LoadFile(config_file); + YAML::Node doc; + std::filesystem::path config_file_path{}; + + if (config_file == "-") { + std::istreambuf_iterator stdin_stream_begin{std::cin}; + std::istreambuf_iterator stdin_stream_end{}; + std::string stdin_stream_str{stdin_stream_begin, stdin_stream_end}; + + doc = YAML::Load(stdin_stream_str); + } + else { + doc = YAML::LoadFile(config_file); + } // Store the parent path of the config_file to properly resolve // the include files paths - auto config_file_path = - std::filesystem::absolute(std::filesystem::path{config_file}); - doc.force_insert( - "__parent_path", config_file_path.parent_path().string()); + if (config_file == "-") { + config_file_path = std::filesystem::current_path(); + doc.force_insert("__parent_path", config_file_path.string()); + } + else { + config_file_path = + std::filesystem::absolute(std::filesystem::path{config_file}); + doc.force_insert( + "__parent_path", config_file_path.parent_path().string()); + } // // If no relative_to path is specified in the config, make all paths diff --git a/src/main.cc b/src/main.cc index 4c968022..8c730cc0 100644 --- a/src/main.cc +++ b/src/main.cc @@ -162,9 +162,9 @@ int main(int argc, const char *argv[]) std::optional compilation_database_dir{}; std::vector diagram_names{}; std::optional output_directory{}; - unsigned int thread_count{0}; + unsigned int thread_count{}; bool show_version{false}; - int verbose{0}; + int verbose{}; bool list_diagrams{false}; bool quiet{false}; bool initialize{false}; @@ -175,8 +175,8 @@ int main(int argc, const char *argv[]) bool dump_config{false}; std::optional paths_relative_to_pwd{}; - app.add_option( - "-c,--config", config_path, "Location of configuration file"); + app.add_option("-c,--config", config_path, + "Location of configuration file, when '-' read from stdin"); app.add_option("-d,--compile-database", compilation_database_dir, "Location of compilation database directory"); app.add_option("-n,--diagram-name", diagram_names, @@ -208,42 +208,60 @@ int main(int argc, const char *argv[]) CLI11_PARSE(app, argc, argv); + if (quiet || dump_config) + verbose = 0; + else + verbose++; + + clanguml::util::setup_logging(verbose); + if (show_version) { print_version(); return 0; } + if ((config_path == "-") && + (initialize || add_class_diagram.has_value() || + add_sequence_diagram.has_value() || + add_package_diagram.has_value() || + add_include_diagram.has_value())) { + + LOG_ERROR( + "ERROR: Cannot add a diagram config to configuration from stdin"); + + return 1; + } + if (initialize) { return create_config_file(); } - verbose++; + if (config_path != "-") { + if (add_class_diagram) { + return add_config_diagram( + clanguml::common::model::diagram_t::kClass, config_path, + *add_class_diagram); + } - if (quiet) - verbose = 0; + if (add_sequence_diagram) { + return add_config_diagram( + clanguml::common::model::diagram_t::kSequence, config_path, + *add_sequence_diagram); + } - if (add_class_diagram) { - return add_config_diagram(clanguml::common::model::diagram_t::kClass, - config_path, *add_class_diagram); + if (add_package_diagram) { + return add_config_diagram( + clanguml::common::model::diagram_t::kPackage, config_path, + *add_package_diagram); + } + + if (add_include_diagram) { + return add_config_diagram( + clanguml::common::model::diagram_t::kInclude, config_path, + *add_include_diagram); + } } - if (add_sequence_diagram) { - return add_config_diagram(clanguml::common::model::diagram_t::kSequence, - config_path, *add_sequence_diagram); - } - - if (add_package_diagram) { - return add_config_diagram(clanguml::common::model::diagram_t::kPackage, - config_path, *add_package_diagram); - } - - if (add_include_diagram) { - return add_config_diagram(clanguml::common::model::diagram_t::kInclude, - config_path, *add_include_diagram); - } - - clanguml::util::setup_logging(verbose); - clanguml::config::config config; try { config = clanguml::config::load(config_path, paths_relative_to_pwd);