From 3fa8bea03d156c43e8fc1599a94ff83e04a7b938 Mon Sep 17 00:00:00 2001
From: Mohamed El Mouctar Haidara <elmhaidara@gmail.com>
Date: Tue, 9 Nov 2021 23:33:21 +0100
Subject: [PATCH] fix: Drop support for ansible 2.9, 2.10 and add ansible
 2.11.6 (#94)

---
 .github/workflows/testing.yaml   | 10 +++---
 CHANGELOG.md                     | 58 +++++++++++++++++---------------
 Makefile                         |  2 +-
 README.md                        | 13 +++----
 ansibleplaybookgrapher/cli.py    |  7 +---
 ansibleplaybookgrapher/parser.py |  4 +++
 ansibleplaybookgrapher/utils.py  |  9 +++--
 requirements.txt                 |  2 +-
 test_install.sh                  |  4 +--
 9 files changed, 57 insertions(+), 52 deletions(-)

diff --git a/.github/workflows/testing.yaml b/.github/workflows/testing.yaml
index 084c27b4..476faf5c 100644
--- a/.github/workflows/testing.yaml
+++ b/.github/workflows/testing.yaml
@@ -13,9 +13,11 @@ jobs:
     name: Tests Py${{ matrix.python-version }} - Ansible ${{ matrix.ansible-version }}
     runs-on: ubuntu-20.04
     strategy:
+      fail-fast: false
       matrix:
-        python-version: [ 3.7, 3.8 ]
-        ansible-version: [ 2.9.14, 2.10.7 ]
+        python-version: [ 3.8, 3.9 ]
+        # See https://www.ansible.com/blog/ansible-3.0.0-qa and https://docs.ansible.com/ansible/devel/reference_appendices/release_and_maintenance.html
+        ansible-version: [ 2.11.6, 2.12.0 ]
 
     steps:
       - name: Checkout code
@@ -28,7 +30,7 @@ jobs:
 
       - name: Install prereqs
         run: |
-          pip install ansible==${{ matrix.ansible-version }} virtualenv setuptools wheel coveralls
+          pip install ansible-core==${{ matrix.ansible-version }} virtualenv setuptools wheel coveralls
           pip install -r tests/requirements_tests.txt
           pip freeze
           sudo apt-get install -y graphviz
@@ -46,7 +48,7 @@ jobs:
           if-no-files-found: error # the tests should generate SVGs files
 
       - name: Test installation in virtualenv
-        run: make test_install
+        run: make test_install ANSIBLE_VERSION=${{ matrix.ansible-version }}
 
       - name: Upload Coverage
         run: cd tests && coveralls --service=github
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 67318de4..58997c74 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -3,34 +3,36 @@
 - refactor: See [\#81](https://github.com/haidaraM/ansible-playbook-grapher/pull/81)
     - Completely rewrite the grapher: the parser, the graph and the renderer to graphviz have been split.
     - Hide some ansible internals in the parser.
-    - Clean code.
 - feat:
-  - Consider inclue_role as normal role instead of
-    task [\#82](https://github.com/haidaraM/ansible-playbook-grapher/pull/82)
-  - feat: Curved edge label based on the path [\#84](https://github.com/haidaraM/ansible-playbook-grapher/pull/84)
-  - feat: Add option to automatically view the generated
-    file [\#88](https://github.com/haidaraM/ansible-playbook-grapher/pull/88)
-  - feat: Add support for block [\#86](https://github.com/haidaraM/ansible-playbook-grapher/pull/86)
-  - Add support for when on include_role
+    - Consider include_role as normal role instead of
+      task [\#82](https://github.com/haidaraM/ansible-playbook-grapher/pull/82)
+    - feat: Curved edge label based on the path [\#84](https://github.com/haidaraM/ansible-playbook-grapher/pull/84)
+    - feat: Add option to automatically view the generated
+      file [\#88](https://github.com/haidaraM/ansible-playbook-grapher/pull/88)
+    - feat: Add support for block [\#86](https://github.com/haidaraM/ansible-playbook-grapher/pull/86). They are now
+      visible in the graph.
+    - Add support for when on include_role.
+    - Only Ansible >= 2.11 is supported. **Python >=3.8** is now
+      required [\#94](https://github.com/haidaraM/ansible-playbook-grapher/pull/94).
 - fix:
-  - front: Refactor the JS part and fix issue when selecting/unselecting nodes
-  - front: Do not unhighlight the current selected node when hovering on parent node
-  - cli(typo): rename `--ouput-file-name` to `--output-file-name`
-  - Use the correct tooltip for edges
-  - style: Do not use bold style by default and apply color on nodes border
-  - Merge when condition with `and`
-  - Explicitly set color luminance to avoid bright colors
-  - Reduce Node ID lengths. No need to use the full UUID
-  - Make grapher works with graphviz >= 0.18. See [\#91](https://github.com/haidaraM/ansible-playbook-grapher/issues/91)
+    - front: Refactor the JS part and fix issue when selecting/unselecting nodes
+    - front: Do not unhighlight the current selected node when hovering on parent node
+    - cli(typo): rename `--ouput-file-name` to `--output-file-name`
+    - Use the correct tooltip for edges
+    - style: Do not use bold style by default and apply color on nodes border
+    - Merge when condition with `and`
+    - Explicitly set color luminance to avoid bright colors
+    - Reduce Node ID lengths. No need to use the full UUID
+    - Make grapher works with graphviz >= 0.18.
+      See [\#91](https://github.com/haidaraM/ansible-playbook-grapher/issues/91)
 - test:
-  - Add Ansible 2.10.7 in the test matrix
-  - Make test verbose by default with `-vv` in the args
+    - Make test verbose by default with `-vv` in the args
+    - Fix test_install in GitHub Actions which was not using the correct Ansible version.
 - docs:
-  - Reformat CHANGELOG
-  - Reformat README.md
+    - Reformat CHANGELOG.md and README.md
 - Dependencies:
-  - bump pytest from 6.2.4 to 6.2.5 [\#83](https://github.com/haidaraM/ansible-playbook-grapher/pull/83)
-  - bump pytest-cov from 2.12.1 to 3.0.0 [\#90](https://github.com/haidaraM/ansible-playbook-grapher/pull/90)
+    - bump pytest from 6.2.4 to 6.2.5 [\#83](https://github.com/haidaraM/ansible-playbook-grapher/pull/83)
+    - bump pytest-cov from 2.12.1 to 3.0.0 [\#90](https://github.com/haidaraM/ansible-playbook-grapher/pull/90)
 
 # 0.11.2 (2021-11-07)
 
@@ -39,10 +41,10 @@
 # 0.11.1 (2021-07-28)
 
 - Dependencies:
-  - Unpin requirements. See [\#71](https://github.com/haidaraM/ansible-playbook-grapher/issues/71)
-  - Bump pytest-cov from 2.11.1 to 2.12.1 [\#78](https://github.com/haidaraM/ansible-playbook-grapher/issues/78)
-  - Bump pytest from 6.2.2 to 6.2.4 [\#76](https://github.com/haidaraM/ansible-playbook-grapher/issues/76)
-  - Upgrade to GitHub-native Dependabot [\#72](https://github.com/haidaraM/ansible-playbook-grapher/issues/72)
+    - Unpin requirements. See [\#71](https://github.com/haidaraM/ansible-playbook-grapher/issues/71)
+    - Bump pytest-cov from 2.11.1 to 2.12.1 [\#78](https://github.com/haidaraM/ansible-playbook-grapher/issues/78)
+    - Bump pytest from 6.2.2 to 6.2.4 [\#76](https://github.com/haidaraM/ansible-playbook-grapher/issues/76)
+    - Upgrade to GitHub-native Dependabot [\#72](https://github.com/haidaraM/ansible-playbook-grapher/issues/72)
 - Drop support for ansible 2.8. **The grapher requires at least ansible
   2.9** [\#74](https://github.com/haidaraM/ansible-playbook-grapher/issues/74)
 - Fix:
@@ -64,7 +66,7 @@
     - Rewriting the grapher, clean code.
     - Generate node IDs from an util function
 - Style: Replace some `format` by f-string
-- CI: Replace Travis by Github actions (#54)
+- CI: Replace Travis by GitHub actions (#54)
 - Dependencies:
     - Bump pytest from 6.0.1 to 6.2.2 (PRs #50, #51, #62, #67)
     - Bump pytest-cov from 2.10.0 to 2.11.1 (PRs #49, #65)
diff --git a/Makefile b/Makefile
index e6702138..8d0608cb 100644
--- a/Makefile
+++ b/Makefile
@@ -1,4 +1,4 @@
-ANSIBLE_VERSION=2.9
+ANSIBLE_VERSION=2.10.7
 VIRTUALENV_DIR=venv
 PACKAGE := dist/$(shell ls dist 2> /dev/null)
 SRC=$(wildcard ansibleplaybookgrapher/*.py setup.py ansibleplaybookgrapher/data/*)
diff --git a/README.md b/README.md
index ec4ee554..408404c5 100644
--- a/README.md
+++ b/README.md
@@ -12,17 +12,18 @@ Inspired by [Ansible Inventory Grapher](https://github.com/willthames/ansible-in
 
 ## Prerequisites
 
-- Python 3
-- **Ansible** >= 2.9: If you still use an older version of Ansible, create a virtual environment and install
-  ansible-playbook-grapher.
-  **pip will install a version of Ansible >= 2.9 if not already installed.** I try to
-  respect [Red Hat Ansible Engine Life Cycle](https://access.redhat.com/support/policy/updates/ansible-engine) for the
-  supported Ansible version.
+- Python 3.8 at least
+- A virtual environment from which to run the grapher. This is **highly recommended** because the grapher depends on
+  some versions of ansible-core which are not necessarily installed in your environment and may cause issues if you use
+  some older versions of Ansible.
 - **Graphviz**: The tool used to generate the graph in SVG.
   ```shell script
   $ sudo apt-get install graphviz # or yum install or brew install
   ```
 
+I try to respect [Red Hat Ansible Engine Life Cycle](https://access.redhat.com/support/policy/updates/ansible-engine)
+for the supported Ansible version.
+
 ## Installation
 
 ```shell script
diff --git a/ansibleplaybookgrapher/cli.py b/ansibleplaybookgrapher/cli.py
index 64e6d32f..bb367dfd 100644
--- a/ansibleplaybookgrapher/cli.py
+++ b/ansibleplaybookgrapher/cli.py
@@ -7,17 +7,12 @@
 from ansible.cli.arguments import option_helpers
 from ansible.release import __version__ as ansible_version
 from ansible.utils.display import Display
-from packaging import version
 
 from ansibleplaybookgrapher import __prog__, __version__
 from ansibleplaybookgrapher.parser import PlaybookParser
 from ansibleplaybookgrapher.postprocessor import GraphVizPostProcessor
 from ansibleplaybookgrapher.renderer import GraphvizRenderer
 
-# At some time, we needed to know if we are using ansible 2.8 because the CLI has been refactored in this PR:
-# https://github.com/ansible/ansible/pull/50069
-IS_ANSIBLE_2_9_X = version.parse(ansible_version) >= version.parse("2.9")
-
 
 def get_cli_class():
     """
@@ -61,7 +56,7 @@ def run(self):
 
 class PlaybookGrapherCLI(GrapherCLI):
     """
-    The dedicated playbook CLI for Ansible 2.9 and above (for the moment)
+    The dedicated playbook grapher CLI
     """
 
     def __init__(self, args, callback=None):
diff --git a/ansibleplaybookgrapher/parser.py b/ansibleplaybookgrapher/parser.py
index f67eaae9..e7c8032c 100644
--- a/ansibleplaybookgrapher/parser.py
+++ b/ansibleplaybookgrapher/parser.py
@@ -68,6 +68,10 @@ def _add_task(self, task: Task, task_vars: Dict, node_type: str, parent_node: Co
         :return: True if the task has been included, false otherwise
         """
 
+        # Ansible-core 2.11 added an implicit meta tasks at the end of the role. So wee skip it here.
+        if task.action == "meta" and task.implicit:
+            return False
+
         if not task.evaluate_tags(only_tags=self.tags, skip_tags=self.skip_tags, all_vars=task_vars):
             self.display.vv(f"The task '{task.get_name()}' is skipped due to the tags.")
             return False
diff --git a/ansibleplaybookgrapher/utils.py b/ansibleplaybookgrapher/utils.py
index f5744d58..2a2092bc 100644
--- a/ansibleplaybookgrapher/utils.py
+++ b/ansibleplaybookgrapher/utils.py
@@ -3,7 +3,6 @@
 from typing import Tuple, List
 
 from ansible.parsing.dataloader import DataLoader
-from ansible.parsing.yaml.objects import AnsibleUnicode
 from ansible.playbook import Play
 from ansible.playbook.role_include import IncludeRole
 from ansible.playbook.task import Task
@@ -12,14 +11,18 @@
 from colour import Color
 
 
-def convert_when_to_str(when: List[AnsibleUnicode]) -> str:
+def convert_when_to_str(when: List) -> str:
     """
     Convert ansible conditional when to str
     :param when:
     :return:
     """
+    if len(when) == 0:
+        return ""
 
-    return f"[when: {' and '.join(when)}]" if len(when) > 0 else ""
+    # Convert each element in the list to str
+    when_to_str = list(map(str, when))
+    return f"[when: {' and '.join(when_to_str)}]"
 
 
 def generate_id(prefix: str = "") -> str:
diff --git a/requirements.txt b/requirements.txt
index 7a3165ac..ec69fe07 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,4 +1,4 @@
-ansible>=2.9.0
+ansible-core>=2.11,<3
 graphviz>=0.18,<1
 colour<1
 lxml<5
diff --git a/test_install.sh b/test_install.sh
index 6a32d096..278b6a7a 100755
--- a/test_install.sh
+++ b/test_install.sh
@@ -19,13 +19,11 @@ virtualenv --clear ${VIRTUALENV_DIR}
 
 source ${VIRTUALENV_DIR}/bin/activate
 
-pip -V
-
 package=dist/$(ls dist)
 
 echo -e "${GREEN}Installing the packages ${package} and ansible ${ANSIBLE_VERSION} ${NC}"
 
-pip install -q ${package} ansible==${ANSIBLE_VERSION}
+pip install -q ${package} ansible-core==${ANSIBLE_VERSION}
 
 ${VIRTUALENV_DIR}/bin/ansible-playbook-grapher --version
 ${VIRTUALENV_DIR}/bin/ansible-playbook-grapher tests/fixtures/example.yml