mirror of
https://github.com/thegeeklab/ansible-doctor.git
synced 2024-11-24 22:00:40 +00:00
feat: auto-discover tags and add annotation identifier (#250)
This commit is contained in:
parent
17563b5ab8
commit
15321e9fe9
@ -133,8 +133,8 @@ class Config():
|
|||||||
"tag": {
|
"tag": {
|
||||||
"name": "tag",
|
"name": "tag",
|
||||||
"automatic": True,
|
"automatic": True,
|
||||||
"subtypes": [],
|
"subtypes": ["value", "description"],
|
||||||
"allow_multiple": True
|
"allow_multiple": False
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,6 +14,7 @@ from ansibledoctor.contstants import YAML_EXTENSIONS
|
|||||||
from ansibledoctor.file_registry import Registry
|
from ansibledoctor.file_registry import Registry
|
||||||
from ansibledoctor.utils import SingleLog
|
from ansibledoctor.utils import SingleLog
|
||||||
from ansibledoctor.utils import UnsafeTag
|
from ansibledoctor.utils import UnsafeTag
|
||||||
|
from ansibledoctor.utils import flatten
|
||||||
|
|
||||||
|
|
||||||
class Parser:
|
class Parser:
|
||||||
@ -28,6 +29,7 @@ class Parser:
|
|||||||
self._files_registry = Registry()
|
self._files_registry = Registry()
|
||||||
self._parse_meta_file()
|
self._parse_meta_file()
|
||||||
self._parse_var_files()
|
self._parse_var_files()
|
||||||
|
self._parse_task_tags()
|
||||||
self._populate_doc_data()
|
self._populate_doc_data()
|
||||||
|
|
||||||
def _yaml_remove_comments(self, d):
|
def _yaml_remove_comments(self, d):
|
||||||
@ -107,7 +109,9 @@ class Parser:
|
|||||||
raw = ruamel.yaml.YAML(typ="rt").load(yaml_file)
|
raw = ruamel.yaml.YAML(typ="rt").load(yaml_file)
|
||||||
self._yaml_remove_comments(raw)
|
self._yaml_remove_comments(raw)
|
||||||
|
|
||||||
data = defaultdict(dict, raw)
|
tags = list(set(flatten(nested_lookup("tags", raw))))
|
||||||
|
for tag in tags:
|
||||||
|
self._data["tag"][tag] = {"value": tag}
|
||||||
except (
|
except (
|
||||||
ruamel.yaml.composer.ComposerError, ruamel.yaml.scanner.ScannerError
|
ruamel.yaml.composer.ComposerError, ruamel.yaml.scanner.ScannerError
|
||||||
) as e:
|
) as e:
|
||||||
@ -116,10 +120,6 @@ class Parser:
|
|||||||
"Unable to read yaml file {}\n{}".format(rfile, message)
|
"Unable to read yaml file {}\n{}".format(rfile, message)
|
||||||
)
|
)
|
||||||
|
|
||||||
tags_found = nested_lookup("tags", data)
|
|
||||||
for tag in tags_found:
|
|
||||||
self._data["tags"][tag] = {}
|
|
||||||
|
|
||||||
def _populate_doc_data(self):
|
def _populate_doc_data(self):
|
||||||
"""Generate the documentation data object."""
|
"""Generate the documentation data object."""
|
||||||
tags = defaultdict(dict)
|
tags = defaultdict(dict)
|
||||||
|
13
ansibledoctor/templates/hugo-book/_tag.j2
Normal file
13
ansibledoctor/templates/hugo-book/_tag.j2
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
{% set tag = role.tag | default({}) %}
|
||||||
|
{% if tag %}
|
||||||
|
## Discovered Tags
|
||||||
|
{% for key, item in tag | dictsort %}
|
||||||
|
|
||||||
|
{{ key }}
|
||||||
|
{% if item.description is defined and item.description | save_join(" ") | striptags %}
|
||||||
|
: {{ item.description | save_join(" ") | striptags }}
|
||||||
|
{% else %}
|
||||||
|
:
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
@ -5,6 +5,12 @@
|
|||||||
- [{{ key }}](#{{ key }})
|
- [{{ key }}](#{{ key }})
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
{% if tag %}
|
||||||
|
- [Discovered Tags](#discovered-tags)
|
||||||
|
{% endif %}
|
||||||
|
{% if todo %}
|
||||||
|
- [Open Tasks](#open-tasks)
|
||||||
|
{% endif %}
|
||||||
- [Dependencies](#dependencies)
|
- [Dependencies](#dependencies)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
@ -16,6 +16,9 @@ type: docs
|
|||||||
{# Vars #}
|
{# Vars #}
|
||||||
{% include '_vars.j2' %}
|
{% include '_vars.j2' %}
|
||||||
|
|
||||||
|
{# Todo #}
|
||||||
|
{% include '_tag.j2' %}
|
||||||
|
|
||||||
{# Todo #}
|
{# Todo #}
|
||||||
{% include '_todo.j2' %}
|
{% include '_todo.j2' %}
|
||||||
|
|
||||||
|
@ -13,6 +13,9 @@
|
|||||||
{# Vars #}
|
{# Vars #}
|
||||||
{% include '_vars.j2' %}
|
{% include '_vars.j2' %}
|
||||||
|
|
||||||
|
{# Todo #}
|
||||||
|
{% include '_tag.j2' %}
|
||||||
|
|
||||||
{# Todo #}
|
{# Todo #}
|
||||||
{% include '_todo.j2' %}
|
{% include '_todo.j2' %}
|
||||||
|
|
||||||
|
12
ansibledoctor/templates/readme/_tag.j2
Normal file
12
ansibledoctor/templates/readme/_tag.j2
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
{% set tag = role.tag | default({}) %}
|
||||||
|
{% if tag %}
|
||||||
|
## Discovered Tags
|
||||||
|
{% for key, item in tag | dictsort %}
|
||||||
|
{% set is_desc = item.description is defined and item.description | save_join(" ") | striptags %}
|
||||||
|
|
||||||
|
**_{{ key }}_**{{ "\\" if is_desc else "" }}
|
||||||
|
{% if is_desc %}
|
||||||
|
 {{ item.description | save_join(" ") | striptags }}
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
@ -7,6 +7,12 @@
|
|||||||
- [{{ key }}](#{{ key }})
|
- [{{ key }}](#{{ key }})
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
{% if tag %}
|
||||||
|
- [Discovered Tags](#discovered-tags)
|
||||||
|
{% endif %}
|
||||||
|
{% if todo %}
|
||||||
|
- [Open Tasks](#open-tasks)
|
||||||
|
{% endif %}
|
||||||
- [Dependencies](#dependencies)
|
- [Dependencies](#dependencies)
|
||||||
- [License](#license)
|
- [License](#license)
|
||||||
- [Author](#author)
|
- [Author](#author)
|
||||||
|
@ -9,6 +9,11 @@ from distutils.util import strtobool
|
|||||||
import colorama
|
import colorama
|
||||||
from pythonjsonlogger import jsonlogger
|
from pythonjsonlogger import jsonlogger
|
||||||
|
|
||||||
|
try:
|
||||||
|
from typing import Iterable
|
||||||
|
except ImportError:
|
||||||
|
from collections import Iterable
|
||||||
|
|
||||||
import ansibledoctor.exception
|
import ansibledoctor.exception
|
||||||
|
|
||||||
CONSOLE_FORMAT = "{}{}[%(levelname)s]{} %(message)s"
|
CONSOLE_FORMAT = "{}{}[%(levelname)s]{} %(message)s"
|
||||||
@ -19,6 +24,15 @@ def to_bool(string):
|
|||||||
return bool(strtobool(str(string)))
|
return bool(strtobool(str(string)))
|
||||||
|
|
||||||
|
|
||||||
|
def flatten(items):
|
||||||
|
for x in items:
|
||||||
|
if isinstance(x, Iterable) and not isinstance(x, (str, bytes)):
|
||||||
|
for sub_x in flatten(x):
|
||||||
|
yield sub_x
|
||||||
|
else:
|
||||||
|
yield x
|
||||||
|
|
||||||
|
|
||||||
def _should_do_markup():
|
def _should_do_markup():
|
||||||
py_colors = os.environ.get("PY_COLORS", None)
|
py_colors = os.environ.get("PY_COLORS", None)
|
||||||
if py_colors is not None:
|
if py_colors is not None:
|
||||||
|
@ -62,6 +62,33 @@ option2
|
|||||||
docker_registry_password: "secret"
|
docker_registry_password: "secret"
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### `@tag`
|
||||||
|
|
||||||
|
Used tags within the Ansible task files will be auto-discovered. This identifier can be used to define tags manually or add extended information to discovered tags.
|
||||||
|
|
||||||
|
option1
|
||||||
|
: the name of the tag to which additional information should be added
|
||||||
|
|
||||||
|
option2
|
||||||
|
: supports `["value", "description"]` as information scopes
|
||||||
|
|
||||||
|
**Example:**
|
||||||
|
|
||||||
|
```YAML
|
||||||
|
- name: Demo task with a tag list
|
||||||
|
debug:
|
||||||
|
msg: "Demo message"
|
||||||
|
tags:
|
||||||
|
- role-tag1
|
||||||
|
- role-tag2
|
||||||
|
|
||||||
|
# @tag single-tag:description: Example description of tag `single-tag`
|
||||||
|
- name: Demo task with a single tag
|
||||||
|
debug:
|
||||||
|
msg: "Demo message"
|
||||||
|
tags: single-tag
|
||||||
|
```
|
||||||
|
|
||||||
### `@todo`
|
### `@todo`
|
||||||
|
|
||||||
Identifier to open tasks that need to be addressed. The general structure for this identifier is `# @identifier option1: <value>`.
|
Identifier to open tasks that need to be addressed. The general structure for this identifier is `# @identifier option1: <value>`.
|
||||||
|
@ -15,6 +15,8 @@ Role to demonstrate ansible-doctor. It is also possible to overwrite the default
|
|||||||
- [demo_role_single](#demo_role_single)
|
- [demo_role_single](#demo_role_single)
|
||||||
- [demo_role_undefined_var](#demo_role_undefined_var)
|
- [demo_role_undefined_var](#demo_role_undefined_var)
|
||||||
- [demo_role_unset](#demo_role_unset)
|
- [demo_role_unset](#demo_role_unset)
|
||||||
|
- [Discovered Tags](#discovered-tags)
|
||||||
|
- [Open Tasks](#open-tasks)
|
||||||
- [Dependencies](#dependencies)
|
- [Dependencies](#dependencies)
|
||||||
- [License](#license)
|
- [License](#license)
|
||||||
- [Author](#author)
|
- [Author](#author)
|
||||||
@ -129,6 +131,15 @@ demo_role_unset:
|
|||||||
demo_role_unset: some_value
|
demo_role_unset: some_value
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Discovered Tags
|
||||||
|
|
||||||
|
**_role-tag1_**
|
||||||
|
|
||||||
|
**_role-tag2_**
|
||||||
|
|
||||||
|
**_single-tag_**\
|
||||||
|
 Example description of tag `single-tag`
|
||||||
|
|
||||||
## Open Tasks
|
## Open Tasks
|
||||||
|
|
||||||
- Unscoped general todo.
|
- Unscoped general todo.
|
||||||
|
@ -6,5 +6,17 @@
|
|||||||
# @end
|
# @end
|
||||||
|
|
||||||
# @todo improvement: Some things that need to be improved.
|
# @todo improvement: Some things that need to be improved.
|
||||||
|
|
||||||
# @todo default: Unscoped general todo.
|
# @todo default: Unscoped general todo.
|
||||||
|
|
||||||
|
- name: Demo task with a tag list
|
||||||
|
debug:
|
||||||
|
msg: "Demo message"
|
||||||
|
tags:
|
||||||
|
- role-tag1
|
||||||
|
- role-tag2
|
||||||
|
|
||||||
|
# @tag single-tag:description: Example description of tag `single-tag`
|
||||||
|
- name: Demo task with a single tag
|
||||||
|
debug:
|
||||||
|
msg: "Demo message"
|
||||||
|
tags: single-tag
|
||||||
|
Loading…
Reference in New Issue
Block a user