-
-
Notifications
You must be signed in to change notification settings - Fork 19
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add basic support for diagrams and dot files generation #99
base: main
Are you sure you want to change the base?
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Large diffs are not rendered by default.
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -64,6 +64,17 @@ def save(self, path: str, output: str): | |
with open(os.path.join(self.tempDoxyDir, pathRel), "w", encoding="utf-8") as file: | ||
file.write(output) | ||
|
||
def save_image(self, path: str, image_source_link: str): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. issue (complexity): Consider refactoring the file copying logic in The addition of the
By addressing these points, the code would not only become cleaner and more maintainable but also potentially more robust against common file operation errors. |
||
# copy image from image_source_link to mkdocs | ||
source = os.path.join(self.tempDoxyDir, "html", image_source_link) | ||
if not os.path.exists(source): | ||
return | ||
destination = os.path.join(self.siteDir, self.apiPath, path, image_source_link) | ||
os.makedirs(os.path.dirname(destination), exist_ok=True) | ||
with open(source, "rb") as fsrc: | ||
with open(destination, "wb") as fdst: | ||
fdst.write(fsrc.read()) | ||
|
||
def fullDoc(self, defaultTemplateConfig: dict): | ||
self.annotated(self.doxygen.root.children, defaultTemplateConfig) | ||
self.fileindex(self.doxygen.files.children, defaultTemplateConfig) | ||
|
@@ -246,6 +257,14 @@ def hierarchy(self, nodes: [Node], config: dict = None): | |
|
||
def member(self, node: Node, config: dict = None): | ||
path = node.filename | ||
refid = node.refid | ||
|
||
if node.has_inheritance_graph: | ||
self.save_image(refid, node.inheritance_graph) | ||
if node.has_collaboration_graph: | ||
self.save_image(refid, node.collaboration_graph) | ||
# if node.has_directory_dependency: | ||
# self.save_image(refid, node.directory_dependency) | ||
|
||
output = self.generatorBase.member(node, config) | ||
self.save(path, output) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,6 +6,7 @@ | |
from jinja2 import Template | ||
from jinja2.exceptions import TemplateError | ||
from mkdocs import exceptions | ||
from pprint import pformat | ||
|
||
import mkdoxy | ||
from mkdoxy.constants import Kind | ||
|
@@ -94,10 +95,30 @@ def render(self, tmpl: Template, data: dict) -> str: | |
@param data (dict): Data to render the template. | ||
@return (str): Rendered template. | ||
""" | ||
|
||
def print_node_content(node: Node, level=0, max_depth=1): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. issue (complexity): Consider simplifying the The refactoring introduces a more complex approach by removing the use of Moreover, the method now passes additional functions ( A more maintainable approach would be to keep the use of an This approach would not only simplify the current implementation but also enhance the maintainability and readability of the code by clearly separating concerns and utilizing Jinja2 features more effectively. |
||
if level > max_depth: | ||
return "" # Stop recursion when max depth is exceeded | ||
|
||
indent = "\n" + " " * (level * 4) + "- " # Indentation for better readability | ||
# node_representation = f"{indent}Node at Level {level}: {pformat(vars(node))}\n" | ||
node_representation = f"{indent}Node at Level {level}: {node.name}\n" | ||
# print all attributes of the node | ||
for key, value in vars(node).items(): | ||
if key == "children": | ||
continue | ||
node_representation += f"{indent} {key}: {pformat(value)}\n" | ||
|
||
# Assuming each node has a list or iterable of child nodes in an attribute like `children` | ||
for child in getattr(node, "children", []): | ||
node_representation += print_node_content(child, level + 1, max_depth) | ||
|
||
return node_representation | ||
Comment on lines
+111
to
+128
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. suggestion (performance): Consider limiting the recursion depth for large node trees. The print_node_content function recursively prints node content. For very large node trees, consider adding a mechanism to limit the recursion depth to prevent potential stack overflow. |
||
|
||
try: | ||
# if self.debug: | ||
# print('Generating', path) # TODO: add path to data | ||
rendered: str = tmpl.render(data) | ||
rendered: str = tmpl.render(data, pformat=pformat, vars=vars, print_node_content=print_node_content) | ||
return rendered | ||
except TemplateError as e: | ||
raise Exception(str(e)) from e | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -87,6 +87,9 @@ def __init__( | |
self._initializer = Property.Initializer(self._xml, parser, self._kind) | ||
self._definition = Property.Definition(self._xml, parser, self._kind) | ||
self._programlisting = Property.Programlisting(self._xml, parser, self._kind) | ||
self._inheritancegraph = Property.InheritanceGraph(self._xml, parser, self._kind) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. issue (complexity): Consider encapsulating the new graph-related functionality into a separate class. The introduction of Consider encapsulating the new graph-related functionality into a separate class. This would streamline the responsibilities of the original class, making it easier to understand and maintain, while also providing a dedicated space for managing graph properties and any future expansions in this area. Encapsulation would also address the issue of the commented-out code by providing a clear context for its inclusion or future development. A separate |
||
self._collaborationgraph = Property.CollaborationGraph(self._xml, parser, self._kind) | ||
# self._directorydependency = Property.DirectoryDependency(self._xml, parser, self._kind) | ||
|
||
def __repr__(self): | ||
return f"Node: {self.name} refid: {self._refid}" | ||
|
@@ -828,6 +831,30 @@ def has_programlisting(self) -> bool: | |
def programlisting(self) -> str: | ||
return self._programlisting.md() | ||
|
||
@property | ||
def has_inheritance_graph(self) -> bool: | ||
return self._inheritancegraph.has() | ||
|
||
@property | ||
def inheritance_graph(self) -> str: | ||
return self._inheritancegraph.md() | ||
|
||
@property | ||
def has_collaboration_graph(self) -> bool: | ||
return self._collaborationgraph.has() | ||
|
||
@property | ||
def collaboration_graph(self) -> str: | ||
return self._collaborationgraph.md() | ||
|
||
# @property | ||
# def has_directory_dependency(self) -> bool: | ||
# return self._directorydependency.has() | ||
# | ||
# @property | ||
# def directory_dependency(self) -> str: | ||
# return self._directorydependency.md() | ||
|
||
@property | ||
def is_resolved(self) -> bool: | ||
return True | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -344,3 +344,52 @@ def md(self, plain: bool = False) -> str: | |
|
||
def has(self) -> bool: | ||
return self.xml.find("programlisting") is not None | ||
|
||
class InheritanceGraph: | ||
def __init__(self, xml: Element, parser: XmlParser, kind: Kind): | ||
self.xml = xml | ||
self.parser = parser | ||
self.kind = kind | ||
self.refid = self.xml.attrib.get("id") if self.xml is not None else None | ||
Comment on lines
+348
to
+352
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. suggestion (code_refinement): Consider extracting common initialization logic to a base class. Both InheritanceGraph and CollaborationGraph classes have similar init methods. Extracting this to a base class could reduce code duplication. |
||
|
||
def md(self, plain: bool = False) -> str: | ||
return f"{self.refid}__inherit__graph.svg" | ||
|
||
def plain(self) -> str: | ||
return self.md(plain=True) | ||
|
||
def has(self) -> bool: | ||
return self.kind.is_class() and self.refid is not None and self.xml.find("inheritancegraph") is not None | ||
|
||
class CollaborationGraph: | ||
def __init__(self, xml: Element, parser: XmlParser, kind: Kind): | ||
self.xml = xml | ||
self.parser = parser | ||
self.kind = kind | ||
self.refid = self.xml.attrib.get("id") if self.xml is not None else None | ||
|
||
def md(self, plain: bool = False) -> str: | ||
return f"{self.refid}__coll__graph.svg" | ||
|
||
def plain(self) -> str: | ||
return self.md(plain=True) | ||
|
||
def has(self) -> bool: | ||
return self.kind.is_class() and self.refid is not None and self.xml.find("collaborationgraph") is not None | ||
|
||
# class DirectoryDependency: | ||
# def __init__(self, xml: Element, parser: XmlParser, kind: Kind): | ||
# self.xml = xml | ||
# self.parser = parser | ||
# self.kind = kind | ||
# self.refid = self.xml.attrib.get("id") if self.xml is not None else None | ||
# | ||
# def md(self, plain: bool = False) -> str: | ||
# return f"{self.refid}_dep.svg" | ||
# | ||
# def plain(self) -> str: | ||
# return self.md(plain=True) | ||
# | ||
# def has(self) -> bool: | ||
# return (self.refid is not None and | ||
# (self.kind.is_dir())) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
issue (code-quality): Low code quality found in Doxygen.__init__ - 23% (
low-code-quality
)Explanation
The quality score for this function is below the quality threshold of 25%.This score is a combination of the method length, cognitive complexity and working memory.
How can you solve this?
It might be worth refactoring this function to make it shorter and more readable.
their own functions. This is the most important thing you can do - ideally a
function should be less than 10 lines.
sits together within the function rather than being scattered.