Merge pull request #44 from bkryza/v0.1.0

V0.1.0
This commit is contained in:
Bartek Kryza
2022-06-15 00:00:28 +02:00
committed by GitHub
34 changed files with 482 additions and 140 deletions

2
.gitignore vendored
View File

@@ -22,6 +22,8 @@ docs/diagrams
coverage*.info
packaging/_BUILD
packaging/conda/meta.yaml
# CLion

4
CHANGELOG.md Normal file
View File

@@ -0,0 +1,4 @@
# CHANGELOG
### 0.1.0
* Initial release

View File

@@ -1,4 +1,4 @@
cmake_minimum_required(VERSION 3.10)
cmake_minimum_required(VERSION 3.12)
project(clang-uml)
@@ -6,7 +6,7 @@ set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_INSTALL_PREFIX ${PROJECT_SOURCE_DIR})
set(CMAKE_VERBOSE_MAKEFILE ON)
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/")
@@ -17,12 +17,17 @@ set(UML_HEADERS_DIR ${PROJECT_SOURCE_DIR}/src/uml)
option(LLVM_CONFIG_PATH "Path to custom llvm-config executable")
option(GIT_VERSION "clang-uml version" "0.1.0")
if(LLVM_CONFIG_PATH)
message(STATUS "Using llvm-config from ${LLVM_CONFIG_PATH}")
set(LIBCLANG_LLVM_CONFIG_EXECUTABLE ${LLVM_CONFIG_PATH})
set(LLVM_CONFIG_BINARY ${LLVM_CONFIG_PATH})
endif(LLVM_CONFIG_PATH)
#set(THREADS_PREFER_PTHREAD_FLAG ON)
find_package(Threads REQUIRED)
message(STATUS "Checking for yaml-cpp...")
find_package(yaml-cpp REQUIRED)
@@ -45,6 +50,10 @@ find_package(LLVM REQUIRED CONFIG)
set(CLANG_INCLUDE_DIRS "llvm/clang/include")
set(CLANG_LIBS clang)
# Configure executable version
file(MAKE_DIRECTORY ${PROJECT_BINARY_DIR}/src/version)
configure_file(src/version.h.in ${PROJECT_BINARY_DIR}/src/version/version.h)
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
execute_process(COMMAND gcc --print-file-name=include
OUTPUT_STRIP_TRAILING_WHITESPACE
@@ -61,6 +70,8 @@ include_directories(${THIRDPARTY_HEADERS_DIR}/cppast/include)
include_directories(${THIRDPARTY_HEADERS_DIR}/cppast/external/type_safe/include)
include_directories(${THIRDPARTY_HEADERS_DIR}/cppast/external/type_safe/external/debug_assert)
include_directories(${PROJECT_SOURCE_DIR}/src/)
include_directories(${PROJECT_BINARY_DIR}/src/version)
file(GLOB_RECURSE SOURCES src/*.cc include/*.h)
set(MAIN_SOURCE_FILE ${CMAKE_CURRENT_SOURCE_DIR}/src/main.cc)
@@ -69,16 +80,15 @@ list(REMOVE_ITEM SOURCES ${MAIN_SOURCE_FILE})
add_library(clang-umllib OBJECT ${SOURCES})
add_executable(clang-uml ${MAIN_SOURCE_FILE})
install(TARGETS clang-uml DESTINATION ${CLANG_UML_INSTALL_BIN_DIR})
target_link_libraries(clang-uml ${LIBCLANG_LIBRARIES} ${YAML_CPP_LIBRARIES} cppast clang-umllib)
target_link_libraries(clang-uml ${LIBCLANG_LIBRARIES} ${YAML_CPP_LIBRARIES} cppast clang-umllib Threads::Threads)
target_compile_features(clang-uml PRIVATE cxx_std_17)
install(
FILES
# add include after DESTINATION, then it works
DESTINATION include ${CMAKE_INSTALL_INCLUDEDIR}
)
include(GNUInstallDirs)
install(TARGETS clang-uml DESTINATION ${CMAKE_INSTALL_BINDIR})
install(FILES LICENSE.md DESTINATION ${CMAKE_INSTALL_DOCDIR})
install(FILES README.md DESTINATION ${CMAKE_INSTALL_DOCDIR})
# Enable testing via CTest
enable_testing()

View File

@@ -26,12 +26,15 @@ LLVM_CONFIG_PATH ?=
CMAKE_CXX_FLAGS ?=
CMAKE_EXE_LINKER_FLAGS ?=
GIT_VERSION ?= $(shell git describe --tags --always --abbrev=7)
.PHONY: clean
clean:
rm -rf debug release
debug/CMakeLists.txt:
cmake -S . -B debug \
-DGIT_VERSION=$(GIT_VERSION) \
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache \
-DCMAKE_BUILD_TYPE=Debug \
-DCMAKE_CXX_FLAGS="$(CMAKE_CXX_FLAGS)" \
@@ -40,6 +43,7 @@ debug/CMakeLists.txt:
release/CMakeLists.txt:
cmake -S . -B release \
-DGIT_VERSION=$(GIT_VERSION) \
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_CXX_FLAGS="$(CMAKE_CXX_FLAGS)" \

View File

@@ -2,6 +2,7 @@
[![Build status](https://github.com/bkryza/clang-uml/actions/workflows/build.yml/badge.svg)](https://github.com/bkryza/clang-uml/actions)
[![Coverage](https://codecov.io/gh/bkryza/clang-uml/branch/master/graph/badge.svg)](https://codecov.io/gh/bkryza/clang-uml)
[![Version](https://img.shields.io/badge/version-0.1.0-blue)](https://github.com/bkryza/clang-uml/releases)
`clang-uml` is an automatic C++ to [PlantUML](https://plantuml.com) class, sequence
and package diagram generator, driven by YAML configuration files. The main idea behind the
@@ -34,17 +35,34 @@ To see what `clang-uml` can do so far, checkout the diagrams generated for unit
## Installation
### Distribution packages
#### Ubuntu
```bash
sudo add-apt-repository ppa:bkryza/clang-uml
sudo apt update
sudo apt install clang-uml
```
#### Conda
```bash
conda config --add channels conda-forge
conda config --set channel_priority strict
conda install -c bkryza/label/clang-uml clang-uml
```
### Building from source
Currently, the only method to install `clang-uml` is from source. First make sure
that you have the following dependencies installed:
First make sure that you have the following dependencies installed:
```bash
# Ubuntu
# Ubuntu (clang version will vary depending on Ubuntu version)
apt install ccache cmake libyaml-cpp-dev clang-12 libclang-12-dev libclang-cpp12-dev
# macos
brew install ccache cmake llvm yaml-cpp
```
> Please note that on macos this tool is not fully functional, i.e. several test cases fail. The build instructions are
> provided for development purposes only.
Then proceed with building the sources:

View File

@@ -57,7 +57,7 @@ if (NOT LIBCLANG_LLVM_CONFIG_EXECUTABLE)
find_program(LIBCLANG_LLVM_CONFIG_EXECUTABLE NAMES llvm-config PATHS "${BREW_LLVM_PATH}/bin")
else ()
set(llvm_config_names llvm-config)
foreach(major RANGE 13 3)
foreach(major RANGE 15 3)
list(APPEND llvm_config_names "llvm-config${major}" "llvm-config-${major}")
foreach(minor RANGE 9 0)
list(APPEND llvm_config_names "llvm-config${major}${minor}" "llvm-config-${major}.${minor}" "llvm-config-mp-${major}.${minor}")

105
packaging/Makefile Normal file
View File

@@ -0,0 +1,105 @@
# Makefile
#
# Copyright (c) 2021-2022 Bartek Kryza <bkryza@gmail.com>
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
SHELL := /bin/bash
.ONESHELL:
.PHONY: download deb clean conda
NAME ?= clang-uml
REBUILD ?= 1
MAINTAINER_NAME ?= Bartek Kryza
MAINTAINER_EMAIL ?= bkryza@gmail.com
GPG_KEY ?= 702014E322FE5CA9B5D920F66CDA4566635E93B1
OS ?= ubuntu
DIST ?= focal
TAR_EXT ?= gz
build_dir = _BUILD/$(OS)/$(DIST)
VERSION ?= $(shell git describe --tags --always --abbrev=7)
COMMIT ?= $(shell git rev-parse HEAD)
BRANCH ?= $(shell git rev-parse --abbrev-ref HEAD)
SOURCE_ARCHIVE ?= $(NAME)-$(VERSION).tar.$(TAR_EXT)
CONDA_TOKEN ?=
#
# Replace mustache template variable in all files in directory recursively,
# e.g.:
# $(call subst_template,VERSION,${VERSION},debian)
#
define subst_template_dir
find $(3) -type f -exec sed -i "s/{{$(1)}}/$(2)/g" {} \;
endef
define subst_conda_meta_yaml
find $(3) -name meta.yaml -exec sed -i "s/{{$(1)}}/$(2)/g" {} \;
endef
_BUILD/$(SOURCE_ARCHIVE):
echo "############################"
echo "Creating source archive from latest commit $(COMMIT) - $(SOURCE_ARCHIVE)"
echo "############################"
mkdir -p $(build_dir)
git-archive-all --prefix=$(NAME)-$(VERSION)/ _BUILD/$(SOURCE_ARCHIVE)
deb: _BUILD/$(SOURCE_ARCHIVE)
echo "############################"
echo "Creating deb source package for $(OS) $(DIST)"
echo "Creating directory: ", $(build_dir)/$(NAME)-$(VERSION)
echo "Extracting source archive..."
echo "############################"
rm -rf $(build_dir)
mkdir -p $(build_dir)
cp _BUILD/$(SOURCE_ARCHIVE) $(build_dir)
cd $(build_dir)
mkdir -p $(NAME)-$(VERSION)
tar xf $(SOURCE_ARCHIVE) -C $(NAME)-$(VERSION) --strip-components 1
cp -R ../../../debian $(NAME)-$(VERSION)/debian
cd $(NAME)-$(VERSION)
$(call subst_template_dir,DATETIME,$(shell date -R),debian)
$(call subst_template_dir,OS,${OS},debian)
$(call subst_template_dir,NAME,${NAME},debian)
$(call subst_template_dir,VERSION,${VERSION},debian)
$(call subst_template_dir,REBUILD,${REBUILD},debian)
$(call subst_template_dir,DISTRIBUTION,${DIST},debian)
$(call subst_template_dir,MAINTAINER_NAME,${MAINTAINER_NAME},debian)
$(call subst_template_dir,MAINTAINER_EMAIL,${MAINTAINER_EMAIL},debian)
$(call subst_template_dir,GIT_COMMIT,${COMMIT},debian)
$(call subst_template_dir,GIT_BRANCH,${BRANCH},debian)
mk-origtargz ../$(NAME)-$(VERSION).tar.$(TAR_EXT)
cp debian/control.$(DIST) debian/control
# BUILD SOURCE PACKAGE FOR LAUNCHPAD
debuild -S -sa -us -d -k$(GPG_KEY)
# BUILD LOCALLY BINARY PACKAGE
# debuild -us -uc
conda: _BUILD/$(SOURCE_ARCHIVE)
echo "############################"
echo "Creating conda archive from source file $(SOURCE_ARCHIVE)"
echo "############################"
conda config --add channels conda-forge
conda config --set channel_priority strict
mkdir -p _BUILD/conda
cp _BUILD/$(SOURCE_ARCHIVE) _BUILD/conda/
cp conda/meta.yaml.in conda/meta.yaml
$(call subst_conda_meta_yaml,PKG_VERSION,${VERSION},conda)
$(call subst_conda_meta_yaml,PKG_SOURCE,..\/_BUILD\/clang-uml-$(VERSION).tar.$(TAR_EXT),conda)
$(call subst_conda_meta_yaml,GIT_COMMIT,${COMMIT},conda)
$(call subst_conda_meta_yaml,GIT_BRANCH,${BRANCH},conda)
conda build --user bkryza --token $(CONDA_TOKEN) conda

28
packaging/README.md Normal file
View File

@@ -0,0 +1,28 @@
# Building releases
* Update CHANGELOG.md
* Tag the release commit, e.g. ```git tag 0.1.0```
## Ubuntu
```bash
cd packaging
make DIST=focal deb
make DIST=jammy deb
cd _BUILD/ubuntu/focal
dput ppa:bkryza/clang-uml *.changes
cd _BUILD/ubuntu/jammy
dput ppa:bkryza/clang-uml *.changes
```
## Anaconda
```bash
docker run --rm -v $PWD:$PWD continuum/miniconda3 bash
conda install conda-build
cd packaging
make conda
```

23
packaging/conda/build.sh Normal file
View File

@@ -0,0 +1,23 @@
#!/bin/bash
mkdir build && cd build
export PKG_CONFIG_PATH="$BUILD_PREFIX/lib/pkgconfig:$PKG_CONFIG_PATH"
export CLANGUML_GIT_TOPLEVEL_DIR=${SRC_DIR}
cmake -DCMAKE_BUILD_TYPE=Release \
-DGIT_VERSION=${GIT_VERSION} \
-DCODE_COVERAGE=OFF \
-DWITH_TESTS=ON \
-DLLVM_CONFIG_PATH=${BUILD_PREFIX}/bin/llvm-config \
-DCONDA_BUILD_PREFIX=${BUILD_PREFIX} \
-DCMAKE_INSTALL_PREFIX=${PREFIX} \
-DCMAKE_EXE_LINKER_FLAGS="-lyaml-cpp" \
..
CTEST_OUTPUT_ON_FAILURE=1 make -j${CPU_COUNT}
CTEST_OUTPUT_ON_FAILURE=1 ctest -j${CPU_COUNT}
make install

View File

@@ -0,0 +1,46 @@
{% set name = "clang-uml" %}
{% set version = "{{PKG_VERSION}}" %}
package:
name: {{ name|lower }}
version: {{ version|replace('-', '.') }}
source:
url: "{{PKG_SOURCE}}"
build:
binary_relocation: true
script_env:
- PKG_VERSION
- GIT_VERSION={{PKG_VERSION}}
- CLANGUML_GIT_REVISION={{PKG_VERSION}}
- CLANGUML_GIT_BRANCH={{GIT_BRANCH}}
- CLANGUML_GIT_COMMIT={{GIT_COMMIT}}
requirements:
build:
- {{ compiler('c') }}
- {{ compiler('cxx') }}
- conda-forge::pkg-config
- conda-forge::yaml-cpp 0.7.0
- conda-forge::clangdev 14.0.4
- conda-forge::libclang 14.0.4
- conda-forge::cmake
- conda-forge::git
- conda-forge::make # [unix]
run:
- conda-forge::yaml-cpp 0.7.0
- conda-forge::libclang 14.0.4
test:
commands:
- $PREFIX/bin/clang-uml --version
about:
home: https://github.com/bkryza/clang-uml
license: Apache 2.0
summary: clang-uml is an automatic C++ UML diagram generator based on Clang.
extra:
recipe-maintainers:
- bkryza

View File

@@ -0,0 +1,5 @@
clang-uml ({{VERSION}}-0{{OS}}{{REBUILD}}ppa1~{{DISTRIBUTION}}) {{DISTRIBUTION}}; urgency=low
* Initial release
-- Bartek Kryza <bkryza@gmail.com> {{DATETIME}}

1
packaging/debian/compat Normal file
View File

@@ -0,0 +1 @@
10

View File

@@ -0,0 +1,18 @@
Source: clang-uml
Maintainer: Bartek Kryza <bkryza@gmail.com>
Section: devel
Priority: optional
Build-Depends: debhelper, make, gcc-10, g++-10, cmake (>= 3.16), libyaml-cpp-dev, llvm-12, llvm-12-dev, clang-12, libclang-12-dev, libclang-cpp12-dev
Standards-Version: 4.3.0
Vcs-Browser: https://github.com/bkryza/clang-uml
Vcs-Git: https://github.com/bkryza/clang-uml.git
Homepage: https://github.com/bkryza/clang-uml
Package: clang-uml
Architecture: any
Section: utils
Depends: ${misc:Depends}, ${shlibs:Depends}
Pre-Depends: ${misc:Pre-Depends}
Description: Automatic C++ UML diagram generator based on Clang.
.
This package provides the clang-uml binary.

View File

@@ -0,0 +1,18 @@
Source: clang-uml
Maintainer: Bartek Kryza <bkryza@gmail.com>
Section: devel
Priority: optional
Build-Depends: debhelper, make, gcc-12, g++-12, cmake (>= 3.16), libyaml-cpp-dev, llvm-14, llvm-14-dev, clang-14, libclang-14-dev, libclang-cpp14-dev
Standards-Version: 4.3.0
Vcs-Browser: https://github.com/bkryza/clang-uml
Vcs-Git: https://github.com/bkryza/clang-uml.git
Homepage: https://github.com/bkryza/clang-uml
Package: clang-uml
Architecture: any
Section: utils
Depends: ${misc:Depends}, ${shlibs:Depends}
Pre-Depends: ${misc:Pre-Depends}
Description: Automatic C++ UML diagram generator based on Clang.
.
This package provides the clang-uml binary.

View File

@@ -0,0 +1,16 @@
Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
Upstream-Name: clang-uml
Source: https://github.com/bkryza/clang-uml
Files: *
Copyright: 2021-2022 Bartek Kryza <bkryza@gmail.com>
License: apache
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

14
packaging/debian/rules Executable file
View File

@@ -0,0 +1,14 @@
#!/usr/bin/make -f
export DH_VERBOSE=1
export CLANGUML_GIT_TOPLEVEL_DIR=$(CURDIR)
export CLANGUML_GIT_REVISION={{VERSION}}
export CLANGUML_GIT_BRANCH={{GIT_BRANCH}}
export CLANGUML_GIT_COMMIT={{GIT_COMMIT}}
override_dh_auto_configure:
dh_auto_configure --buildsystem=cmake -- -DCMAKE_BUILD_TYPE=release -DCMAKE_INSTALL_PREFIX=/usr -DGIT_VERSION={{VERSION}}
%:
dh $@

View File

@@ -0,0 +1 @@
3.0 (quilt)

3
packaging/debian/watch Normal file
View File

@@ -0,0 +1,3 @@
version=4
https://github.com/bkryza/clang-uml/releases .*/[relasymcp.-]*(\d\S*)\.tar\.gz

View File

@@ -30,6 +30,8 @@ public:
class_method(common::model::access_t access, const std::string &name,
const std::string &type);
virtual ~class_method() = default;
bool is_pure_virtual() const;
void is_pure_virtual(bool is_pure_virtual);

View File

@@ -30,9 +30,9 @@ public:
enum_(const common::model::namespace_ &using_namespaces);
enum_(const enum_ &) = delete;
enum_(enum_ &&) = default;
enum_(enum_ &&) = delete;
enum_ &operator=(const enum_ &) = delete;
enum_ &operator=(enum_ &&) = default;
enum_ &operator=(enum_ &&) = delete;
// TODO: Do we need this?
friend bool operator==(const enum_ &l, const enum_ &r);

View File

@@ -58,6 +58,8 @@ class filter_visitor {
public:
filter_visitor(filter_t type);
virtual ~filter_visitor() = default;
virtual tvl::value_t match(
const diagram &d, const common::model::element &e) const;
@@ -86,6 +88,8 @@ struct anyof_filter : public filter_visitor {
anyof_filter(
filter_t type, std::vector<std::unique_ptr<filter_visitor>> filters);
virtual ~anyof_filter() = default;
tvl::value_t match(
const diagram &d, const common::model::element &e) const override;
@@ -99,6 +103,8 @@ private:
struct namespace_filter : public filter_visitor {
namespace_filter(filter_t type, std::vector<namespace_> namespaces);
virtual ~namespace_filter() = default;
tvl::value_t match(const diagram &d, const namespace_ &ns) const override;
tvl::value_t match(const diagram &d, const element &e) const override;
@@ -110,6 +116,8 @@ private:
struct element_filter : public filter_visitor {
element_filter(filter_t type, std::vector<std::string> elements);
virtual ~element_filter() = default;
tvl::value_t match(const diagram &d, const element &e) const override;
private:
@@ -119,6 +127,8 @@ private:
struct subclass_filter : public filter_visitor {
subclass_filter(filter_t type, std::vector<std::string> roots);
virtual ~subclass_filter() = default;
tvl::value_t match(const diagram &d, const element &e) const override;
private:
@@ -137,6 +147,8 @@ struct edge_traversal_filter : public filter_visitor {
{
}
virtual ~edge_traversal_filter() = default;
tvl::value_t match(const diagram &d, const MatchOverrideT &e) const override
{
// This filter should only be run on the completely generated diagram
@@ -203,7 +215,7 @@ private:
decltype(matching_elements_) parents;
util::for_each(
matching_elements_, [this, &cd, &parents](const auto &element) {
matching_elements_, [&cd, &parents](const auto &element) {
auto parent = detail::get<ElementT, DiagramT>(
cd, element.get().path().to_string());
@@ -269,6 +281,8 @@ struct relationship_filter : public filter_visitor {
relationship_filter(
filter_t type, std::vector<relationship_t> relationships);
virtual ~relationship_filter() = default;
tvl::value_t match(
const diagram &d, const relationship_t &r) const override;
@@ -279,6 +293,8 @@ private:
struct access_filter : public filter_visitor {
access_filter(filter_t type, std::vector<access_t> access);
virtual ~access_filter() = default;
tvl::value_t match(const diagram &d, const access_t &a) const override;
private:
@@ -288,6 +304,8 @@ private:
struct context_filter : public filter_visitor {
context_filter(filter_t type, std::vector<std::string> context);
virtual ~context_filter() = default;
tvl::value_t match(const diagram &d, const element &r) const override;
private:
@@ -298,6 +316,8 @@ struct paths_filter : public filter_visitor {
paths_filter(filter_t type, const std::filesystem::path &root,
std::vector<std::filesystem::path> p);
virtual ~paths_filter() = default;
tvl::value_t match(
const diagram &d, const common::model::source_file &r) const override;

View File

@@ -41,11 +41,11 @@ public:
path(const path &right) { path_ = right.path_; }
path &operator=(const path &right) noexcept = default;
path &operator=(const path &right) = default;
path(path &&right) noexcept = default;
path &operator=(path &&right) noexcept = default;
path &operator=(path &&right) = default;
path(std::initializer_list<std::string> ns)
{

View File

@@ -46,11 +46,11 @@ void generator::generate_relationships(
else {
util::for_each_if(
f.relationships(),
[this, &f](const auto &r) {
[this](const auto &r) {
return m_model.should_include(r.type()) &&
util::contains(m_generated_aliases, r.destination());
},
[this, &f, &ostr](const auto &r) {
[&f, &ostr](const auto &r) {
ostr << f.alias() << " "
<< plantuml_common::to_plantuml(r.type(), r.style()) << " "
<< r.destination() << '\n';

View File

@@ -43,7 +43,7 @@ public:
common::model::diagram_t type() const override;
type_safe::optional_ref<const common::model::diagram_element> get(
const std::string &full_name) const;
const std::string &full_name) const override;
void add_file(std::unique_ptr<common::model::source_file> &&f);

View File

@@ -21,8 +21,8 @@
#include "include_diagram/generators/plantuml/include_diagram_generator.h"
#include "package_diagram/generators/plantuml/package_diagram_generator.h"
#include "sequence_diagram/generators/plantuml/sequence_diagram_generator.h"
#include "util/util.h"
#include "version.h"
#include <cli11/CLI11.hpp>
#include <cppast/libclang_parser.hpp>
@@ -38,6 +38,8 @@
using namespace clanguml;
using config::config;
void print_version();
void print_diagrams_list(const clanguml::config::config &cfg);
bool check_output_directory(const std::string &dir);
@@ -55,6 +57,7 @@ int main(int argc, const char *argv[])
std::vector<std::string> diagram_names{};
std::optional<std::string> output_directory;
unsigned int thread_count{0};
bool show_version{false};
bool verbose{false};
bool list_diagrams{false};
@@ -68,12 +71,18 @@ int main(int argc, const char *argv[])
"Override output directory specified in config file");
app.add_option("-t,--thread-count", thread_count,
"Thread pool size (0 = hardware concurrency)");
app.add_flag("-V,--version", show_version, "Print version and exit");
app.add_flag("-v,--verbose", verbose, "Verbose logging");
app.add_flag("-l,--list-diagrams", list_diagrams,
"Print list of diagrams defined in the config file");
CLI11_PARSE(app, argc, argv);
if (show_version) {
print_version();
return 0;
}
clanguml::util::setup_logging(verbose);
clanguml::config::config config;
@@ -223,6 +232,15 @@ bool check_output_directory(const std::string &dir)
return true;
}
void print_version()
{
std::cout << "clang-uml " << clanguml::version::CLANG_UML_VERSION << '\n';
std::cout << "Copyright (C) 2021-2022 Bartek Kryza <bkryza@gmail.com>"
<< '\n';
std::cout << "Built with libclang: "
<< clanguml::version::CLANG_UML_LIBCLANG_VERSION << std::endl;
}
void print_diagrams_list(const clanguml::config::config &cfg)
{
using std::cout;

View File

@@ -45,7 +45,7 @@ public:
packages() const;
type_safe::optional_ref<const common::model::diagram_element> get(
const std::string &full_name) const;
const std::string &full_name) const override;
void add_package(std::unique_ptr<common::model::package> &&p);

View File

@@ -37,7 +37,7 @@ public:
common::model::diagram_t type() const override;
type_safe::optional_ref<const common::model::diagram_element> get(
const std::string &full_name) const;
const std::string &full_name) const override;
std::string to_alias(const std::string &full_name) const;

View File

@@ -56,8 +56,23 @@ std::string get_process_output(const std::string &command)
return result;
}
std::string get_env(const std::string &name)
{
const char *value = std::getenv(name.c_str());
if (value == nullptr)
return {};
return std::string{value};
}
bool is_git_repository()
{
const auto env = get_env("CLANGUML_GIT_COMMIT");
if (!env.empty())
return true;
#if defined(_WIN32) || defined(_WIN64)
return false;
#else
@@ -69,21 +84,41 @@ bool is_git_repository()
std::string get_git_branch()
{
const auto env = get_env("CLANGUML_GIT_BRANCH");
if (!env.empty())
return env;
return trim(get_process_output("git rev-parse --abbrev-ref HEAD"));
}
std::string get_git_revision()
{
const auto env = get_env("CLANGUML_GIT_REVISION");
if (!env.empty())
return env;
return trim(get_process_output("git describe --tags --always"));
}
std::string get_git_commit()
{
const auto env = get_env("CLANGUML_GIT_COMMIT");
if (!env.empty())
return env;
return trim(get_process_output("git rev-parse HEAD"));
}
std::string get_git_toplevel_dir()
{
const auto env = get_env("CLANGUML_GIT_TOPLEVEL_DIR");
if (!env.empty())
return env;
return trim(get_process_output("git rev-parse --show-toplevel"));
}

View File

@@ -62,6 +62,8 @@ void setup_logging(bool verbose);
std::string get_process_output(const std::string &command);
std::string get_env(const std::string &name);
bool is_git_repository();
std::string get_git_branch();

23
src/version.h.in Normal file
View File

@@ -0,0 +1,23 @@
/**
* src/version.h
*
* Copyright (c) 2021-2022 Bartek Kryza <bkryza@gmail.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
namespace clanguml::version {
static constexpr auto CLANG_UML_VERSION = "@GIT_VERSION@";
static constexpr auto CLANG_UML_LIBCLANG_VERSION = "@LIBCLANG_VERSION_STRING@";
} // namespace clanguml::version

View File

@@ -1,139 +1,65 @@
cmake_minimum_required(VERSION 3.10)
cmake_minimum_required(VERSION 3.12)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_FLAGS "-std=c++17 ${LIBCLANG_CXXFLAGS}")
set(TEST_DISABLE_WARNINGS "-Wno-unused-parameter -Wno-unused-variable -Wno-attributes")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${LIBCLANG_CXXFLAGS} ${TEST_DISABLE_WARNINGS}")
file(GLOB_RECURSE TEST_CASE_SOURCES t*/*.cc)
file(GLOB_RECURSE TEST_CASE_CONFIGS t*/.clang-uml)
file(GLOB_RECURSE TEST_CONFIG_YMLS test_config_data/*.yml)
set(CLANG_UML_TEST_UTIL_SRC
test_util.cc
${TEST_UTIL_SOURCES}
)
set(CLANG_UML_TEST_UTIL_HEADER
catch.h
)
set(CLANG_UML_TEST_LIBRARIES
${LIBCLANG_LIBRARIES}
${YAML_CPP_LIBRARIES}
clang-umllib
cppast
Threads::Threads)
set(CLANG_UML_TEST_MODEL_SRC
test_model.cc
${TEST_MODEL_SOURCES}
)
set(CLANG_UML_TEST_MODEL_HEADER
catch.h
)
set(CLANG_UML_TEST_UTIL_SRC test_util.cc ${TEST_UTIL_SOURCES})
set(CLANG_UML_TEST_UTIL_HEADER catch.h)
set(CLANG_UML_TEST_CASES_SRC
test_cases.cc
${TEST_CASE_SOURCES}
)
set(CLANG_UML_TEST_CASES_HEADER
catch.h
)
set(CLANG_UML_TEST_MODEL_SRC test_model.cc ${TEST_MODEL_SOURCES})
set(CLANG_UML_TEST_MODEL_HEADER catch.h)
set(CLANG_UML_TEST_DECORATOR_PARSER_SRC
test_decorator_parser.cc
${TEST_UTIL_SOURCES}
)
set(CLANG_UML_TEST_DECORATOR_PARSER_HEADER
catch.h
)
set(CLANG_UML_TEST_CASES_SRC test_cases.cc ${TEST_CASE_SOURCES})
set(CLANG_UML_TEST_CASES_HEADER catch.h)
set(CLANG_UML_TEST_CONFIG_SRC
test_config.cc
${TEST_UTIL_SOURCES}
)
set(CLANG_UML_TEST_CONFIG_HEADER
catch.h
)
set(CLANG_UML_TEST_DECORATOR_PARSER_SRC test_decorator_parser.cc ${TEST_UTIL_SOURCES})
set(CLANG_UML_TEST_DECORATOR_PARSER_HEADER catch.h)
set(CLANG_UML_TEST_FILTERS_SRC
test_filters.cc
${TEST_FILTERS_SOURCES}
)
set(CLANG_UML_TEST_FILTERS_HEADER
catch.h
)
set(CLANG_UML_TEST_CONFIG_SRC test_config.cc ${TEST_UTIL_SOURCES})
set(CLANG_UML_TEST_CONFIG_HEADER catch.h)
set(CLANG_UML_TEST_THREAD_POOL_EXECUTOR_SRC
test_thread_pool_executor.cc
)
set(CLANG_UML_TEST_THREAD_POOL_EXECUTOR_HEADER
catch.h
)
set(CLANG_UML_TEST_FILTERS_SRC test_filters.cc ${TEST_FILTERS_SOURCES})
set(CLANG_UML_TEST_FILTERS_HEADER catch.h)
add_executable(test_util
${CLANG_UML_TEST_UTIL_SRC}
${CLANG_UML_TEST_UTIL_HEADER})
set(CLANG_UML_TEST_THREAD_POOL_EXECUTOR_SRC test_thread_pool_executor.cc)
set(CLANG_UML_TEST_THREAD_POOL_EXECUTOR_HEADER catch.h)
target_link_libraries(test_util
PRIVATE
${LIBCLANG_LIBRARIES}
${YAML_CPP_LIBRARIES}
clang-umllib cppast)
add_executable(test_util ${CLANG_UML_TEST_UTIL_SRC} ${CLANG_UML_TEST_UTIL_HEADER})
target_link_libraries(test_util PRIVATE ${CLANG_UML_TEST_LIBRARIES})
add_executable(test_model
${CLANG_UML_TEST_MODEL_SRC}
${CLANG_UML_TEST_MODEL_HEADER})
add_executable(test_model ${CLANG_UML_TEST_MODEL_SRC} ${CLANG_UML_TEST_MODEL_HEADER})
target_link_libraries(test_model PRIVATE ${CLANG_UML_TEST_LIBRARIES})
target_link_libraries(test_model
PRIVATE
${LIBCLANG_LIBRARIES}
${YAML_CPP_LIBRARIES}
clang-umllib cppast)
add_executable(test_decorator_parser ${CLANG_UML_TEST_DECORATOR_PARSER_SRC} ${CLANG_UML_TEST_DECORATOR_PARSER_HEADER})
target_link_libraries(test_decorator_parser PRIVATE ${CLANG_UML_TEST_LIBRARIES})
add_executable(test_decorator_parser
${CLANG_UML_TEST_DECORATOR_PARSER_SRC}
${CLANG_UML_TEST_DECORATOR_PARSER_HEADER})
add_executable(test_config ${CLANG_UML_TEST_CONFIG_SRC} ${CLANG_UML_TEST_CONFIG_HEADER})
target_link_libraries(test_config PRIVATE ${CLANG_UML_TEST_LIBRARIES})
target_link_libraries(test_decorator_parser
PRIVATE
${LIBCLANG_LIBRARIES}
${YAML_CPP_LIBRARIES}
clang-umllib cppast)
add_executable(test_filters ${CLANG_UML_TEST_FILTERS_SRC} ${CLANG_UML_TEST_FILTERS_HEADER})
target_link_libraries(test_filters PRIVATE ${CLANG_UML_TEST_LIBRARIES})
add_executable(test_config
${CLANG_UML_TEST_CONFIG_SRC}
${CLANG_UML_TEST_CONFIG_HEADER})
add_executable(test_thread_pool_executor ${CLANG_UML_TEST_THREAD_POOL_EXECUTOR_SRC} ${CLANG_UML_TEST_THREAD_POOL_EXECUTOR_HEADER})
target_link_libraries(test_thread_pool_executor PRIVATE ${CLANG_UML_TEST_LIBRARIES})
target_link_libraries(test_config
PRIVATE
${LIBCLANG_LIBRARIES}
${YAML_CPP_LIBRARIES}
clang-umllib cppast)
add_executable(test_filters
${CLANG_UML_TEST_FILTERS_SRC}
${CLANG_UML_TEST_FILTERS_HEADER})
target_link_libraries(test_filters
PRIVATE
${LIBCLANG_LIBRARIES}
${YAML_CPP_LIBRARIES}
clang-umllib cppast)
add_executable(test_thread_pool_executor
${CLANG_UML_TEST_THREAD_POOL_EXECUTOR_SRC}
${CLANG_UML_TEST_THREAD_POOL_EXECUTOR_HEADER})
target_link_libraries(test_thread_pool_executor
PRIVATE
${LIBCLANG_LIBRARIES}
${YAML_CPP_LIBRARIES}
clang-umllib cppast)
add_executable(test_cases
${CLANG_UML_TEST_CASES_SRC}
${CLANG_UML_TEST_CASES_HEADER})
target_link_libraries(test_cases
PRIVATE
${LIBCLANG_LIBRARIES}
${YAML_CPP_LIBRARIES}
clang-umllib cppast)
add_executable(test_cases ${CLANG_UML_TEST_CASES_SRC} ${CLANG_UML_TEST_CASES_HEADER})
target_link_libraries(test_cases PRIVATE ${CLANG_UML_TEST_LIBRARIES})
foreach(TEST_CASE_CONFIG ${TEST_CASE_CONFIGS})
file(RELATIVE_PATH

View File

@@ -1,6 +1,6 @@
#include <algorithm>
#include <array>
#include <map>
#include <numeric>
#include <string>
#include <variant>
#include <vector>

View File

@@ -55,7 +55,7 @@ generate_sequence_diagram(cppast::libclang_compilation_database &db,
diagram_config, diagram_visitor>(db, diagram->name,
dynamic_cast<clanguml::config::sequence_diagram &>(*diagram));
return std::move(model);
return model;
}
std::unique_ptr<clanguml::class_diagram::model::diagram> generate_class_diagram(
@@ -73,7 +73,7 @@ std::unique_ptr<clanguml::class_diagram::model::diagram> generate_class_diagram(
diagram_config, diagram_visitor>(
db, diagram->name, dynamic_cast<diagram_config &>(*diagram));
return std::move(model);
return model;
}
std::unique_ptr<clanguml::package_diagram::model::diagram>