diff --git a/README.md b/README.md
index e906b353..daa0be8c 100644
--- a/README.md
+++ b/README.md
@@ -48,10 +48,20 @@ for the supported Ansible version.
## Installation
-```shell script
+```shell
pip install ansible-playbook-grapher
```
+You can also install the unpublished version from GitHub direction. Examples:
+
+```shell
+# Install the version from the main branch
+pip install "ansible-playbook-grapher @ git+https://github.com/haidaraM/ansible-playbook-grapher"
+
+# Install the version from a specific branch
+pip install "ansible-playbook-grapher @ git+https://github.com/haidaraM/ansible-playbook-grapher@specific-branch"
+```
+
### Renderers
At the time of writing, two renderers are supported:
diff --git a/ansibleplaybookgrapher/__init__.py b/ansibleplaybookgrapher/__init__.py
index ccd20efa..20c62ea2 100644
--- a/ansibleplaybookgrapher/__init__.py
+++ b/ansibleplaybookgrapher/__init__.py
@@ -1,77 +1,2 @@
-# Copyright (C) 2023 Mohamed El Mouctar HAIDARA
-#
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see .
-
-from typing import Dict, List, Set, Tuple
-
-from ansible.utils.display import Display
-
-from ansibleplaybookgrapher.graph_model import (
- PlaybookNode,
- RoleNode,
- PlayNode,
-)
-from ansibleplaybookgrapher.parser import PlaybookParser
-from ansibleplaybookgrapher.utils import merge_dicts
-from .graph_model import PlaybookNode, PlayNode, TaskNode, RoleNode, BlockNode
-from .parser import PlaybookParser
-
-__version__ = "2.1.2"
+__version__ = "2.2.0.dev0"
__prog__ = "ansible-playbook-grapher"
-
-display = Display()
-
-
-class Grapher:
- def __init__(self, playbook_filenames: List[str]):
- """
- :param playbook_filenames: List of playbooks to graph
- """
- self.playbook_filenames = playbook_filenames
-
- def parse(
- self,
- include_role_tasks: bool = False,
- tags: List[str] = None,
- skip_tags: List[str] = None,
- group_roles_by_name: bool = False,
- ) -> Tuple[List[PlaybookNode], Dict[RoleNode, Set[PlayNode]]]:
- """
- Parses all the provided playbooks
- :param include_role_tasks: Should we include the role tasks
- :param tags: Only add plays and tasks tagged with these values
- :param skip_tags: Only add plays and tasks whose tags do not match these values
- :param group_roles_by_name: Group roles by name instead of considering them as separate nodes with different IDs
- :return: Tuple of the list of playbook nodes and the dictionary of the role usages: the key is the role and the
- value is the set of plays that use the role.
- """
- playbook_nodes = []
- roles_usage: Dict[RoleNode, Set[PlayNode]] = {}
-
- for playbook_file in self.playbook_filenames:
- display.display(f"Parsing playbook {playbook_file}")
- playbook_parser = PlaybookParser(
- playbook_filename=playbook_file,
- tags=tags,
- skip_tags=skip_tags,
- include_role_tasks=include_role_tasks,
- group_roles_by_name=group_roles_by_name,
- )
- playbook_node = playbook_parser.parse()
- playbook_nodes.append(playbook_node)
-
- # Update the usage of the roles
- roles_usage = merge_dicts(roles_usage, playbook_node.roles_usage())
-
- return playbook_nodes, roles_usage
diff --git a/ansibleplaybookgrapher/cli.py b/ansibleplaybookgrapher/cli.py
index acef4571..b6d9d515 100644
--- a/ansibleplaybookgrapher/cli.py
+++ b/ansibleplaybookgrapher/cli.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2023 Mohamed El Mouctar HAIDARA
+# Copyright (C) 2024 Mohamed El Mouctar HAIDARA
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -23,7 +23,8 @@
from ansible.release import __version__ as ansible_version
from ansible.utils.display import Display
-from ansibleplaybookgrapher import __prog__, __version__, Grapher
+from ansibleplaybookgrapher.grapher import Grapher
+from ansibleplaybookgrapher import __prog__, __version__
from ansibleplaybookgrapher.renderer import OPEN_PROTOCOL_HANDLERS
from ansibleplaybookgrapher.renderer.graphviz import GraphvizRenderer
from ansibleplaybookgrapher.renderer.mermaid import (
diff --git a/ansibleplaybookgrapher/grapher.py b/ansibleplaybookgrapher/grapher.py
new file mode 100644
index 00000000..81967798
--- /dev/null
+++ b/ansibleplaybookgrapher/grapher.py
@@ -0,0 +1,67 @@
+# Copyright (C) 2024 Mohamed El Mouctar HAIDARA
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see .
+
+from typing import Dict, List, Set, Tuple
+
+from ansibleplaybookgrapher.graph_model import (
+ PlaybookNode,
+ RoleNode,
+ PlayNode,
+)
+from ansibleplaybookgrapher.parser import PlaybookParser
+from ansibleplaybookgrapher.utils import merge_dicts
+
+
+class Grapher:
+ def __init__(self, playbook_filenames: List[str]):
+ """
+ :param playbook_filenames: List of playbooks to graph
+ """
+ self.playbook_filenames = playbook_filenames
+
+ def parse(
+ self,
+ include_role_tasks: bool = False,
+ tags: List[str] = None,
+ skip_tags: List[str] = None,
+ group_roles_by_name: bool = False,
+ ) -> Tuple[List[PlaybookNode], Dict[RoleNode, Set[PlayNode]]]:
+ """
+ Parses all the provided playbooks
+ :param include_role_tasks: Should we include the role tasks
+ :param tags: Only add plays and tasks tagged with these values
+ :param skip_tags: Only add plays and tasks whose tags do not match these values
+ :param group_roles_by_name: Group roles by name instead of considering them as separate nodes with different IDs
+ :return: Tuple of the list of playbook nodes and the dictionary of the role usages: the key is the role and the
+ value is the set of plays that use the role.
+ """
+ playbook_nodes = []
+ roles_usage: Dict[RoleNode, Set[PlayNode]] = {}
+
+ for playbook_file in self.playbook_filenames:
+ playbook_parser = PlaybookParser(
+ playbook_filename=playbook_file,
+ tags=tags,
+ skip_tags=skip_tags,
+ include_role_tasks=include_role_tasks,
+ group_roles_by_name=group_roles_by_name,
+ )
+ playbook_node = playbook_parser.parse()
+ playbook_nodes.append(playbook_node)
+
+ # Update the usage of the roles
+ roles_usage = merge_dicts(roles_usage, playbook_node.roles_usage())
+
+ return playbook_nodes, roles_usage
diff --git a/ansibleplaybookgrapher/parser.py b/ansibleplaybookgrapher/parser.py
index 6a8779b5..97763596 100644
--- a/ansibleplaybookgrapher/parser.py
+++ b/ansibleplaybookgrapher/parser.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2023 Mohamed El Mouctar HAIDARA
+# Copyright (C) 2024 Mohamed El Mouctar HAIDARA
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -167,7 +167,7 @@ def parse(self, *args, **kwargs) -> PlaybookNode:
add post_tasks
:return:
"""
-
+ display.display(f"Parsing playbook {self.playbook_filename}")
playbook = Playbook.load(
self.playbook_filename,
loader=self.data_loader,
diff --git a/ansibleplaybookgrapher/renderer/mermaid.py b/ansibleplaybookgrapher/renderer/mermaid.py
index fb208c87..677de1ae 100644
--- a/ansibleplaybookgrapher/renderer/mermaid.py
+++ b/ansibleplaybookgrapher/renderer/mermaid.py
@@ -18,7 +18,13 @@
from ansible.utils.display import Display
-from ansibleplaybookgrapher import BlockNode, RoleNode, TaskNode, PlayNode, PlaybookNode
+from ansibleplaybookgrapher.graph_model import (
+ BlockNode,
+ RoleNode,
+ TaskNode,
+ PlayNode,
+ PlaybookNode,
+)
from ansibleplaybookgrapher.renderer import PlaybookBuilder, Renderer
display = Display()
diff --git a/setup.cfg b/setup.cfg
index 5424cc26..6b947792 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -1,5 +1,5 @@
[metadata]
-description-file = Readme.md
+description_file = Readme.md
[bdist_wheel]
universal = 1
diff --git a/tests/test_parser.py b/tests/test_parser.py
index 3f6b6a0f..80d4d9ab 100644
--- a/tests/test_parser.py
+++ b/tests/test_parser.py
@@ -4,7 +4,7 @@
import pytest
from ansible.utils.display import Display
-from ansibleplaybookgrapher import PlaybookParser
+from ansibleplaybookgrapher.parser import PlaybookParser
from ansibleplaybookgrapher.cli import PlaybookGrapherCLI
from ansibleplaybookgrapher.graph_model import (
TaskNode,