Added diagram metadata to PlantUML and JSON generators

This commit is contained in:
Bartek Kryza
2023-04-07 00:21:50 +02:00
parent a682aab21d
commit 2a6f515b47
18 changed files with 76 additions and 5 deletions

View File

@@ -1,5 +1,6 @@
# CHANGELOG # CHANGELOG
* Added diagram metadata to PlantUML and JSON generators (#27)
* Improved template specialization matching for variadic and function * Improved template specialization matching for variadic and function
template parameters (#118) template parameters (#118)
* Fixed compilation and tests on LLVM 16 (#108) * Fixed compilation and tests on LLVM 16 (#108)

View File

@@ -126,6 +126,8 @@ void generator::generate(std::ostream &ostr) const
generate_relationships(json_); generate_relationships(json_);
generate_metadata(json_);
ostr << json_; ostr << json_;
} }

View File

@@ -765,6 +765,8 @@ void generator::generate(std::ostream &ostr) const
generate_plantuml_directives(ostr, m_config.puml().after); generate_plantuml_directives(ostr, m_config.puml().after);
generate_metadata(ostr);
ostr << "@enduml" << '\n'; ostr << "@enduml" << '\n';
} }

View File

@@ -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, app.add_flag("--paths-relative-to-pwd", paths_relative_to_pwd,
"If true, all paths in configuration files are relative to the $PWD " "If true, all paths in configuration files are relative to the $PWD "
"instead of actual location of `.clang-uml` file."); "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 { try {
app.parse(argc, argv); app.parse(argc, argv);
@@ -201,7 +203,8 @@ cli_flow_t cli_handler::handle_pre_config_options()
cli_flow_t cli_handler::load_config() cli_flow_t cli_handler::load_config()
{ {
try { 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; return cli_flow_t::kContinue;
} }
catch (std::runtime_error &e) { catch (std::runtime_error &e) {

View File

@@ -130,6 +130,7 @@ public:
std::optional<bool> paths_relative_to_pwd{}; std::optional<bool> paths_relative_to_pwd{};
std::vector<std::string> template_variables{}; std::vector<std::string> template_variables{};
bool list_templates{false}; bool list_templates{false};
std::optional<bool> no_metadata{};
std::optional<std::string> show_template; std::optional<std::string> show_template;
std::vector<clanguml::common::generator_type_t> generators{ std::vector<clanguml::common::generator_type_t> generators{
clanguml::common::generator_type_t::plantuml}; clanguml::common::generator_type_t::plantuml};

View File

@@ -79,5 +79,4 @@ void to_json(nlohmann::json &j, const relationship &c)
if (const auto &comment = c.comment(); comment) if (const auto &comment = c.comment(); comment)
j["comment"] = comment.value(); j["comment"] = comment.value();
} }
} // namespace clanguml::common::model } // namespace clanguml::common::model

View File

@@ -21,7 +21,9 @@
#include "config/config.h" #include "config/config.h"
#include "util/error.h" #include "util/error.h"
#include "util/util.h" #include "util/util.h"
#include "version.h"
#include <clang/Basic/Version.h>
#include <clang/Frontend/CompilerInstance.h> #include <clang/Frontend/CompilerInstance.h>
#include <clang/Tooling/CompilationDatabase.h> #include <clang/Tooling/CompilationDatabase.h>
#include <clang/Tooling/Tooling.h> #include <clang/Tooling/Tooling.h>
@@ -81,6 +83,13 @@ public:
*/ */
virtual void generate(std::ostream &ostr) const = 0; 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: private:
protected: protected:
ConfigType &m_config; ConfigType &m_config;
@@ -95,4 +104,16 @@ std::ostream &operator<<(
return os; return os;
} }
template <typename C, typename D>
void generator<C, D>::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 } // namespace clanguml::common::generators::json

View File

@@ -21,7 +21,9 @@
#include "config/config.h" #include "config/config.h"
#include "util/error.h" #include "util/error.h"
#include "util/util.h" #include "util/util.h"
#include "version.h"
#include <clang/Basic/Version.h>
#include <clang/Frontend/CompilerInstance.h> #include <clang/Frontend/CompilerInstance.h>
#include <clang/Tooling/CompilationDatabase.h> #include <clang/Tooling/CompilationDatabase.h>
#include <clang/Tooling/Tooling.h> #include <clang/Tooling/Tooling.h>
@@ -110,6 +112,13 @@ public:
void generate_notes( void generate_notes(
std::ostream &ostr, const model::element &element) const; 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 * @brief Generate hyper link to element
* *
@@ -375,6 +384,17 @@ void generator<C, D>::generate_notes(
} }
} }
template <typename C, typename D>
void generator<C, D>::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 <typename C, typename D> template <typename C, typename D>
template <typename E> template <typename E>
void generator<C, D>::generate_link(std::ostream &ostr, const E &e) const void generator<C, D>::generate_link(std::ostream &ostr, const E &e) const

View File

@@ -116,6 +116,7 @@ void inheritable_diagram_options::inherit(
combine_free_functions_into_file_participants.override( combine_free_functions_into_file_participants.override(
combine_free_functions_into_file_participants); combine_free_functions_into_file_participants);
debug_mode.override(parent.debug_mode); debug_mode.override(parent.debug_mode);
generate_metadata.override(parent.generate_metadata);
} }
std::string inheritable_diagram_options::simplify_template_type( std::string inheritable_diagram_options::simplify_template_type(

View File

@@ -170,6 +170,7 @@ struct inheritable_diagram_options {
"combine_free_functions_into_file_participants", false}; "combine_free_functions_into_file_participants", false};
option<std::vector<std::string>> participants_order{"participants_order"}; option<std::vector<std::string>> participants_order{"participants_order"};
option<bool> debug_mode{"debug_mode", false}; option<bool> debug_mode{"debug_mode", false};
option<bool> generate_metadata{"generate_metadata", true};
void inherit(const inheritable_diagram_options &parent); void inherit(const inheritable_diagram_options &parent);
@@ -292,7 +293,8 @@ YAML::Emitter &operator<<(YAML::Emitter &out, const option<T> &o)
} }
config load(const std::string &config_file, config load(const std::string &config_file,
std::optional<bool> paths_relative_to_pwd = {}); std::optional<bool> paths_relative_to_pwd = {},
std::optional<bool> no_metadata = {});
config load_plain(const std::string &config_file); config load_plain(const std::string &config_file);
} // namespace config } // namespace config

View File

@@ -381,6 +381,7 @@ template <typename T> bool decode_diagram(const Node &node, T &rhs)
get_option(node, rhs.type_aliases); get_option(node, rhs.type_aliases);
get_option(node, rhs.comment_parser); get_option(node, rhs.comment_parser);
get_option(node, rhs.debug_mode); get_option(node, rhs.debug_mode);
get_option(node, rhs.generate_metadata);
return true; return true;
} }
@@ -595,6 +596,7 @@ template <> struct convert<config> {
get_option(node, rhs.generate_system_headers); get_option(node, rhs.generate_system_headers);
get_option(node, rhs.git); get_option(node, rhs.git);
get_option(node, rhs.debug_mode); get_option(node, rhs.debug_mode);
get_option(node, rhs.generate_metadata);
rhs.base_directory.set(node["__parent_path"].as<std::string>()); rhs.base_directory.set(node["__parent_path"].as<std::string>());
get_option(node, rhs.relative_to); get_option(node, rhs.relative_to);
@@ -676,8 +678,8 @@ void resolve_option_path(YAML::Node &doc, const std::string &option)
} }
} // namespace } // namespace
config load( config load(const std::string &config_file,
const std::string &config_file, std::optional<bool> paths_relative_to_pwd) std::optional<bool> paths_relative_to_pwd, std::optional<bool> no_metadata)
{ {
try { try {
YAML::Node doc; YAML::Node doc;
@@ -727,6 +729,10 @@ config load(
doc["relative_to"] = std::filesystem::current_path().string(); 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` // Resolve common path-like config options relative to `relative_to`
// //

View File

@@ -100,6 +100,8 @@ void generator::generate(std::ostream &ostr) const
generate_relationships(dynamic_cast<source_file &>(*f), json_); generate_relationships(dynamic_cast<source_file &>(*f), json_);
}); });
generate_metadata(json_);
ostr << json_; ostr << json_;
} }
} // namespace clanguml::include_diagram::generators::json } // namespace clanguml::include_diagram::generators::json

View File

@@ -120,6 +120,8 @@ void generator::generate(std::ostream &ostr) const
if (m_config.puml) if (m_config.puml)
generate_plantuml_directives(ostr, m_config.puml().after); generate_plantuml_directives(ostr, m_config.puml().after);
generate_metadata(ostr);
ostr << "@enduml" << '\n'; ostr << "@enduml" << '\n';
} }
} // namespace clanguml::include_diagram::generators::plantuml } // namespace clanguml::include_diagram::generators::plantuml

View File

@@ -98,6 +98,8 @@ void generator::generate(std::ostream &ostr) const
generate_relationships(dynamic_cast<package &>(*p), json_); generate_relationships(dynamic_cast<package &>(*p), json_);
} }
generate_metadata(json_);
ostr << json_; ostr << json_;
} }

View File

@@ -147,6 +147,8 @@ void generator::generate(std::ostream &ostr) const
generate_plantuml_directives(ostr, m_config.puml().after); generate_plantuml_directives(ostr, m_config.puml().after);
generate_metadata(ostr);
ostr << "@enduml" << '\n'; ostr << "@enduml" << '\n';
} }

View File

@@ -660,6 +660,8 @@ void generator::generate(std::ostream &ostr) const
} }
} }
generate_metadata(json_);
ostr << json_; ostr << json_;
} }
} // namespace clanguml::sequence_diagram::generators::json } // namespace clanguml::sequence_diagram::generators::json

View File

@@ -470,6 +470,8 @@ void generator::generate(std::ostream &ostr) const
generate_plantuml_directives(ostr, m_config.puml().after); generate_plantuml_directives(ostr, m_config.puml().after);
generate_metadata(ostr);
ostr << "@enduml" << std::endl; ostr << "@enduml" << std::endl;
} }

View File

@@ -18,6 +18,7 @@
#pragma once #pragma once
namespace clanguml::version { 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_VERSION = "@GIT_VERSION@";
static constexpr auto CLANG_UML_LIBCLANG_VERSION = "@LIBCLANG_VERSION_STRING@"; static constexpr auto CLANG_UML_LIBCLANG_VERSION = "@LIBCLANG_VERSION_STRING@";
} // namespace clanguml::version } // namespace clanguml::version