From 2a6f515b47235a6c9500a168db3228506693021b Mon Sep 17 00:00:00 2001 From: Bartek Kryza Date: Fri, 7 Apr 2023 00:21:50 +0200 Subject: [PATCH] Added diagram metadata to PlantUML and JSON generators --- CHANGELOG.md | 1 + .../json/class_diagram_generator.cc | 2 ++ .../plantuml/class_diagram_generator.cc | 2 ++ src/cli/cli_handler.cc | 5 ++++- src/cli/cli_handler.h | 1 + src/common/generators/json/generator.cc | 1 - src/common/generators/json/generator.h | 21 +++++++++++++++++++ src/common/generators/plantuml/generator.h | 20 ++++++++++++++++++ src/config/config.cc | 1 + src/config/config.h | 4 +++- src/config/yaml_decoders.cc | 10 +++++++-- .../json/include_diagram_generator.cc | 2 ++ .../plantuml/include_diagram_generator.cc | 2 ++ .../json/package_diagram_generator.cc | 2 ++ .../plantuml/package_diagram_generator.cc | 2 ++ .../json/sequence_diagram_generator.cc | 2 ++ .../plantuml/sequence_diagram_generator.cc | 2 ++ src/version.h.in | 1 + 18 files changed, 76 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f727d7a1..2f96db4c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,6 @@ # CHANGELOG + * Added diagram metadata to PlantUML and JSON generators (#27) * Improved template specialization matching for variadic and function template parameters (#118) * Fixed compilation and tests on LLVM 16 (#108) diff --git a/src/class_diagram/generators/json/class_diagram_generator.cc b/src/class_diagram/generators/json/class_diagram_generator.cc index a15c88b8..f6ac941b 100644 --- a/src/class_diagram/generators/json/class_diagram_generator.cc +++ b/src/class_diagram/generators/json/class_diagram_generator.cc @@ -126,6 +126,8 @@ void generator::generate(std::ostream &ostr) const generate_relationships(json_); + generate_metadata(json_); + ostr << json_; } diff --git a/src/class_diagram/generators/plantuml/class_diagram_generator.cc b/src/class_diagram/generators/plantuml/class_diagram_generator.cc index 76917f83..34f5ff37 100644 --- a/src/class_diagram/generators/plantuml/class_diagram_generator.cc +++ b/src/class_diagram/generators/plantuml/class_diagram_generator.cc @@ -765,6 +765,8 @@ void generator::generate(std::ostream &ostr) const generate_plantuml_directives(ostr, m_config.puml().after); + generate_metadata(ostr); + ostr << "@enduml" << '\n'; } diff --git a/src/cli/cli_handler.cc b/src/cli/cli_handler.cc index 44385153..33632151 100644 --- a/src/cli/cli_handler.cc +++ b/src/cli/cli_handler.cc @@ -104,6 +104,8 @@ cli_flow_t cli_handler::parse(int argc, const char **argv) app.add_flag("--paths-relative-to-pwd", paths_relative_to_pwd, "If true, all paths in configuration files are relative to the $PWD " "instead of actual location of `.clang-uml` file."); + app.add_flag("--no-metadata", no_metadata, + "Skip metadata (e.g. clang-uml version) from diagrams"); try { app.parse(argc, argv); @@ -201,7 +203,8 @@ cli_flow_t cli_handler::handle_pre_config_options() cli_flow_t cli_handler::load_config() { try { - config = clanguml::config::load(config_path, paths_relative_to_pwd); + config = clanguml::config::load( + config_path, paths_relative_to_pwd, no_metadata); return cli_flow_t::kContinue; } catch (std::runtime_error &e) { diff --git a/src/cli/cli_handler.h b/src/cli/cli_handler.h index 2581ec9c..575a113c 100644 --- a/src/cli/cli_handler.h +++ b/src/cli/cli_handler.h @@ -130,6 +130,7 @@ public: std::optional paths_relative_to_pwd{}; std::vector template_variables{}; bool list_templates{false}; + std::optional no_metadata{}; std::optional show_template; std::vector generators{ clanguml::common::generator_type_t::plantuml}; diff --git a/src/common/generators/json/generator.cc b/src/common/generators/json/generator.cc index 3f00666f..1a5f8b0c 100644 --- a/src/common/generators/json/generator.cc +++ b/src/common/generators/json/generator.cc @@ -79,5 +79,4 @@ void to_json(nlohmann::json &j, const relationship &c) if (const auto &comment = c.comment(); comment) j["comment"] = comment.value(); } - } // namespace clanguml::common::model diff --git a/src/common/generators/json/generator.h b/src/common/generators/json/generator.h index 0d2f143d..96ffef36 100644 --- a/src/common/generators/json/generator.h +++ b/src/common/generators/json/generator.h @@ -21,7 +21,9 @@ #include "config/config.h" #include "util/error.h" #include "util/util.h" +#include "version.h" +#include #include #include #include @@ -81,6 +83,13 @@ public: */ virtual void generate(std::ostream &ostr) const = 0; + /** + * @brief Generate metadata element with diagram metadata + * + * @param parent Root JSON object + */ + void generate_metadata(nlohmann::json &parent) const; + private: protected: ConfigType &m_config; @@ -95,4 +104,16 @@ std::ostream &operator<<( return os; } +template +void generator::generate_metadata(nlohmann::json &parent) const +{ + if (m_config.generate_metadata()) { + parent["metadata"]["clang_uml_version"] = + clanguml::version::CLANG_UML_VERSION; + parent["metadata"]["schema_version"] = + clanguml::version::CLANG_UML_JSON_GENERATOR_SCHEMA_VERSION; + parent["metadata"]["llvm_version"] = clang::getClangFullVersion(); + } +} + } // namespace clanguml::common::generators::json \ No newline at end of file diff --git a/src/common/generators/plantuml/generator.h b/src/common/generators/plantuml/generator.h index e6663061..32de2fa8 100644 --- a/src/common/generators/plantuml/generator.h +++ b/src/common/generators/plantuml/generator.h @@ -21,7 +21,9 @@ #include "config/config.h" #include "util/error.h" #include "util/util.h" +#include "version.h" +#include #include #include #include @@ -110,6 +112,13 @@ public: void generate_notes( std::ostream &ostr, const model::element &element) const; + /** + * @brief Generate comment with diagram metadata + * + * @param ostr Output stream + */ + void generate_metadata(std::ostream &ostr) const; + /** * @brief Generate hyper link to element * @@ -375,6 +384,17 @@ void generator::generate_notes( } } +template +void generator::generate_metadata(std::ostream &ostr) const +{ + if (m_config.generate_metadata()) { + ostr << '\n' + << "'Generated with clang-uml, version " + << clanguml::version::CLANG_UML_VERSION << '\n' + << "'LLVM version " << clang::getClangFullVersion() << '\n'; + } +} + template template void generator::generate_link(std::ostream &ostr, const E &e) const diff --git a/src/config/config.cc b/src/config/config.cc index d00a3333..c2cd7a8e 100644 --- a/src/config/config.cc +++ b/src/config/config.cc @@ -116,6 +116,7 @@ void inheritable_diagram_options::inherit( combine_free_functions_into_file_participants.override( combine_free_functions_into_file_participants); debug_mode.override(parent.debug_mode); + generate_metadata.override(parent.generate_metadata); } std::string inheritable_diagram_options::simplify_template_type( diff --git a/src/config/config.h b/src/config/config.h index 20f2cc09..dcb8427a 100644 --- a/src/config/config.h +++ b/src/config/config.h @@ -170,6 +170,7 @@ struct inheritable_diagram_options { "combine_free_functions_into_file_participants", false}; option> participants_order{"participants_order"}; option debug_mode{"debug_mode", false}; + option generate_metadata{"generate_metadata", true}; void inherit(const inheritable_diagram_options &parent); @@ -292,7 +293,8 @@ YAML::Emitter &operator<<(YAML::Emitter &out, const option &o) } config load(const std::string &config_file, - std::optional paths_relative_to_pwd = {}); + std::optional paths_relative_to_pwd = {}, + std::optional no_metadata = {}); config load_plain(const std::string &config_file); } // namespace config diff --git a/src/config/yaml_decoders.cc b/src/config/yaml_decoders.cc index 69a5addb..2cca89eb 100644 --- a/src/config/yaml_decoders.cc +++ b/src/config/yaml_decoders.cc @@ -381,6 +381,7 @@ template bool decode_diagram(const Node &node, T &rhs) get_option(node, rhs.type_aliases); get_option(node, rhs.comment_parser); get_option(node, rhs.debug_mode); + get_option(node, rhs.generate_metadata); return true; } @@ -595,6 +596,7 @@ template <> struct convert { get_option(node, rhs.generate_system_headers); get_option(node, rhs.git); get_option(node, rhs.debug_mode); + get_option(node, rhs.generate_metadata); rhs.base_directory.set(node["__parent_path"].as()); get_option(node, rhs.relative_to); @@ -676,8 +678,8 @@ void resolve_option_path(YAML::Node &doc, const std::string &option) } } // namespace -config load( - const std::string &config_file, std::optional paths_relative_to_pwd) +config load(const std::string &config_file, + std::optional paths_relative_to_pwd, std::optional no_metadata) { try { YAML::Node doc; @@ -727,6 +729,10 @@ config load( doc["relative_to"] = std::filesystem::current_path().string(); } + if (no_metadata.has_value()) { + doc["generate_metadata"] = !no_metadata.value(); + } + // // Resolve common path-like config options relative to `relative_to` // diff --git a/src/include_diagram/generators/json/include_diagram_generator.cc b/src/include_diagram/generators/json/include_diagram_generator.cc index 675adb2b..02a5c53f 100644 --- a/src/include_diagram/generators/json/include_diagram_generator.cc +++ b/src/include_diagram/generators/json/include_diagram_generator.cc @@ -100,6 +100,8 @@ void generator::generate(std::ostream &ostr) const generate_relationships(dynamic_cast(*f), json_); }); + generate_metadata(json_); + ostr << json_; } } // namespace clanguml::include_diagram::generators::json diff --git a/src/include_diagram/generators/plantuml/include_diagram_generator.cc b/src/include_diagram/generators/plantuml/include_diagram_generator.cc index cdf94f4e..d803ca1e 100644 --- a/src/include_diagram/generators/plantuml/include_diagram_generator.cc +++ b/src/include_diagram/generators/plantuml/include_diagram_generator.cc @@ -120,6 +120,8 @@ void generator::generate(std::ostream &ostr) const if (m_config.puml) generate_plantuml_directives(ostr, m_config.puml().after); + generate_metadata(ostr); + ostr << "@enduml" << '\n'; } } // namespace clanguml::include_diagram::generators::plantuml diff --git a/src/package_diagram/generators/json/package_diagram_generator.cc b/src/package_diagram/generators/json/package_diagram_generator.cc index 05c12f0c..f6dc23fb 100644 --- a/src/package_diagram/generators/json/package_diagram_generator.cc +++ b/src/package_diagram/generators/json/package_diagram_generator.cc @@ -98,6 +98,8 @@ void generator::generate(std::ostream &ostr) const generate_relationships(dynamic_cast(*p), json_); } + generate_metadata(json_); + ostr << json_; } diff --git a/src/package_diagram/generators/plantuml/package_diagram_generator.cc b/src/package_diagram/generators/plantuml/package_diagram_generator.cc index b97ebe5c..10be4b5c 100644 --- a/src/package_diagram/generators/plantuml/package_diagram_generator.cc +++ b/src/package_diagram/generators/plantuml/package_diagram_generator.cc @@ -147,6 +147,8 @@ void generator::generate(std::ostream &ostr) const generate_plantuml_directives(ostr, m_config.puml().after); + generate_metadata(ostr); + ostr << "@enduml" << '\n'; } diff --git a/src/sequence_diagram/generators/json/sequence_diagram_generator.cc b/src/sequence_diagram/generators/json/sequence_diagram_generator.cc index d69f12b3..46e75723 100644 --- a/src/sequence_diagram/generators/json/sequence_diagram_generator.cc +++ b/src/sequence_diagram/generators/json/sequence_diagram_generator.cc @@ -660,6 +660,8 @@ void generator::generate(std::ostream &ostr) const } } + generate_metadata(json_); + ostr << json_; } } // namespace clanguml::sequence_diagram::generators::json diff --git a/src/sequence_diagram/generators/plantuml/sequence_diagram_generator.cc b/src/sequence_diagram/generators/plantuml/sequence_diagram_generator.cc index c2d226b6..e1284905 100644 --- a/src/sequence_diagram/generators/plantuml/sequence_diagram_generator.cc +++ b/src/sequence_diagram/generators/plantuml/sequence_diagram_generator.cc @@ -470,6 +470,8 @@ void generator::generate(std::ostream &ostr) const generate_plantuml_directives(ostr, m_config.puml().after); + generate_metadata(ostr); + ostr << "@enduml" << std::endl; } diff --git a/src/version.h.in b/src/version.h.in index 75c2b0fd..524c6fe4 100644 --- a/src/version.h.in +++ b/src/version.h.in @@ -18,6 +18,7 @@ #pragma once namespace clanguml::version { +static constexpr auto CLANG_UML_JSON_GENERATOR_SCHEMA_VERSION = 1U; static constexpr auto CLANG_UML_VERSION = "@GIT_VERSION@"; static constexpr auto CLANG_UML_LIBCLANG_VERSION = "@LIBCLANG_VERSION_STRING@"; } // namespace clanguml::version \ No newline at end of file