Problem trying to use ansible-docs on Debian Bookworm
Hi @kpfleming thanks for your work on this tool.
I'm trying to use ansible-docs
but haven't had much luck, when in a role directory am I right in understanding that the minimal command that can be used is as follows?
ansible-docs . markdown
Or have I misunderstood something?
The result I get is:
Traceback (most recent call last):
File "/home/chris/.local/bin/ansible-docs", line 8, in <module>
sys.exit(app())
^^^^^
File "/home/chris/.local/lib/python3.11/site-packages/typer/main.py", line 214, in __call__
return get_command(self)(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3/dist-packages/click/core.py", line 1130, in __call__
return self.main(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3/dist-packages/click/core.py", line 1055, in main
rv = self.invoke(ctx)
^^^^^^^^^^^^^^^^
File "/usr/lib/python3/dist-packages/click/core.py", line 1657, in invoke
return _process_result(sub_ctx.command.invoke(sub_ctx))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3/dist-packages/click/core.py", line 1404, in invoke
return ctx.invoke(self.callback, **ctx.params)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3/dist-packages/click/core.py", line 760, in invoke
return __callback(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/chris/.local/lib/python3.11/site-packages/typer/main.py", line 532, in wrapper
return callback(**use_params) # type: ignore
^^^^^^^^^^^^^^^^^^^^^^
File "/home/chris/.local/lib/python3.11/site-packages/ansible_docs/cli.py", line 44, in markdown
content = render_content(ctx, "markdown.j2")
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/chris/.local/lib/python3.11/site-packages/ansible_docs/cli.py", line 166, in render_content
content = env.get_template(content_template).render(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/chris/.local/lib/python3.11/site-packages/jinja2/environment.py", line 1010, in get_template
return self._load_template(name, globals)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/chris/.local/lib/python3.11/site-packages/jinja2/environment.py", line 969, in _load_template
template = self.loader.load(self, name, self.make_globals(globals))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/chris/.local/lib/python3.11/site-packages/jinja2/loaders.py", line 126, in load
source, filename, uptodate = self.get_source(environment, name)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/chris/.local/lib/python3.11/site-packages/jinja2/loaders.py", line 218, in get_source
raise TemplateNotFound(template)
jinja2.exceptions.TemplateNotFound: markdown.j2
I running Debian Bookworm with Python 3.11.1.
This is how I initially installed it:
pip install --user git+https://gitlab.com/kankare/ansible-docs
Collecting git+https://gitlab.com/kankare/ansible-docs
Cloning https://gitlab.com/kankare/ansible-docs to /tmp/pip-req-build-5qx99akz
Running command git clone --filter=blob:none --quiet https://gitlab.com/kankare/ansible-docs /tmp/pip-req-build-5qx99akz
warning: redirecting to https://gitlab.com/kankare/ansible-docs.git/
Resolved https://gitlab.com/kankare/ansible-docs to commit cd2b2d8f2275d8ea8a52dc3e53d79420c6c5b889 /home/chris/webarch/m
Installing build dependencies ... done
Getting requirements to build wheel ... done "stat": {"a
Preparing metadata (pyproject.toml) ... done utes": ["ex
Collecting typer<0.5.0,>=0.4.1
Downloading typer-0.4.2-py3-none-any.whl (27 kB) a623821e636
Collecting Jinja2<4.0.0,>=3.1.2
Using cached Jinja2-3.1.2-py3-none-any.whl (133 kB) "executabl
Requirement already satisfied: PyYAML<7.0,>=6.0 in /usr/lib/python3/dist-packages (from ansible-docs==0.1.0) (6.0) ctory present] *********"
Requirement already satisfied: click<9.0.0,>=8.1.3 in /usr/lib/python3/dist-packages (from ansible-docs==0.1.0) (8.1.3) ] => {"changed": false, e
Requirement already satisfied: MarkupSafe>=2.0 in /usr/lib/python3/dist-packages (from Jinja2<4.0.0,>=3.1.2->ansible-docs==0.1.0) (2.1.2)
Building wheels for collected packages: ansible-docs
Building wheel for ansible-docs (pyproject.toml) ... done
Created wheel for ansible-docs: filename=ansible_docs-0.1.0-py3-none-any.whl size=4148 sha256=2edb2e647ac37b439eeb126bde8911095b7de0a2877535fef363acf517870605
Stored in directory: /tmp/pip-ephem-wheel-cache-fdiao98d/wheels/69/e1/11/40635c6ba913937d4c2dfc620807fde4e7ac008492850f2408
Successfully built ansible-docs
Installing collected packages: typer, Jinja2, ansible-docs
Successfully installed Jinja2-3.1.2 ansible-docs-0.1.0 typer-0.4.2
I then uninstalled the user typer package and installed the system one:
pip3 uninstall typer
Found existing installation: typer 0.4.2
Uninstalling typer-0.4.2:
Would remove:
/home/chris/.local/lib/python3.11/site-packages/typer-0.4.2.dist-info/*
/home/chris/.local/lib/python3.11/site-packages/typer/*
Proceed (Y/n)? y
Successfully uninstalled typer-0.4.2
sudo apt install python3-typer
Now I have this colourfull result:
ansible-docs . markdown
╭─────────────────────────────── Traceback (most recent call last) ────────────────────────────────╮
│ /home/chris/.local/lib/python3.11/site-packages/ansible_docs/cli.py:44 in markdown │
│ │
│ 41 │ """ │
│ 42 │ │
│ 43 │ # FIXME: ctx should not be passed to these non-command()'s │
│ ❱ 44 │ content = render_content(ctx, "markdown.j2") │
│ 45 │ write(ctx, content) │
│ 46 │
│ 47 │
│ │
│ ╭────────────────────── locals ───────────────────────╮ │
│ │ ctx = <click.core.Context object at 0x7f05196edd90> │ │
│ ╰─────────────────────────────────────────────────────╯ │
│ │
│ /home/chris/.local/lib/python3.11/site-packages/ansible_docs/cli.py:166 in render_content │
│ │
│ 163 │ loader = jinja2.FileSystemLoader(templates) │
│ 164 │ │
│ 165 │ env = jinja2.Environment(loader=loader) │
│ ❱ 166 │ content = env.get_template(content_template).render( │
│ 167 │ │ role=ctx.obj["config"]["role"], │
│ 168 │ │ metadata=ctx.obj["data"]["metadata"], │
│ 169 │ │ argument_specs=ctx.obj["data"]["argument_specs"], │
│ │
│ ╭───────────────────────────────────────── locals ──────────────────────────────────────────╮ │
│ │ content_template = 'markdown.j2' │ │
│ │ ctx = <click.core.Context object at 0x7f05196edd90> │ │
│ │ env = <jinja2.environment.Environment object at 0x7f0519b24b10> │ │
│ │ loader = <jinja2.loaders.FileSystemLoader object at 0x7f051970fe90> │ │
│ │ templates = PosixPath('/home/chris/.local/lib/python3.11/site-packages/templates') │ │
│ ╰───────────────────────────────────────────────────────────────────────────────────────────╯ │
│ │
│ /home/chris/.local/lib/python3.11/site-packages/jinja2/environment.py:1010 in get_template │
│ │
│ 1007 │ │ if parent is not None: │
│ 1008 │ │ │ name = self.join_path(name, parent) │
│ 1009 │ │ │
│ ❱ 1010 │ │ return self._load_template(name, globals) │
│ 1011 │ │
│ 1012 │ @internalcode │
│ 1013 │ def select_template( │
│ │
│ ╭────────────────────────────── locals ───────────────────────────────╮ │
│ │ globals = None │ │
│ │ name = 'markdown.j2' │ │
│ │ parent = None │ │
│ │ self = <jinja2.environment.Environment object at 0x7f0519b24b10> │ │
│ ╰─────────────────────────────────────────────────────────────────────╯ │
│ │
│ /home/chris/.local/lib/python3.11/site-packages/jinja2/environment.py:969 in _load_template │
│ │
│ 966 │ │ │ │ │
│ 967 │ │ │ │ return template │
│ 968 │ │ │
│ ❱ 969 │ │ template = self.loader.load(self, name, self.make_globals(globals)) │
│ 970 │ │ │
│ 971 │ │ if self.cache is not None: │
│ 972 │ │ │ self.cache[cache_key] = template │
│ │
│ ╭─────────────────────────────────────────── locals ───────────────────────────────────────────╮ │
│ │ cache_key = ( │ │
│ │ │ <weakref at 0x7f0519707dd0; to 'FileSystemLoader' at 0x7f051970fe90>, │ │
│ │ │ 'markdown.j2' │ │
│ │ ) │ │
│ │ globals = None │ │
│ │ name = 'markdown.j2' │ │
│ │ self = <jinja2.environment.Environment object at 0x7f0519b24b10> │ │
│ │ template = None │ │
│ ╰──────────────────────────────────────────────────────────────────────────────────────────────╯ │
│ │
│ /home/chris/.local/lib/python3.11/site-packages/jinja2/loaders.py:126 in load │
│ │
│ 123 │ │ │
│ 124 │ │ # first we try to get the source for this template together │
│ 125 │ │ # with the filename and the uptodate function. │
│ ❱ 126 │ │ source, filename, uptodate = self.get_source(environment, name) │
│ 127 │ │ │
│ 128 │ │ # try to load the code from the bytecode cache if there is a │
│ 129 │ │ # bytecode cache configured. │
│ │
│ ╭─────────────────────────────────────────── locals ───────────────────────────────────────────╮ │
│ │ code = None │ │
│ │ environment = <jinja2.environment.Environment object at 0x7f0519b24b10> │ │
│ │ globals = ChainMap({}, {'range': <class 'range'>, 'dict': <class 'dict'>, 'lipsum': │ │
│ │ <function generate_lorem_ipsum at 0x7f051a326480>, 'cycler': <class │ │
│ │ 'jinja2.utils.Cycler'>, 'joiner': <class 'jinja2.utils.Joiner'>, 'namespace': │ │
│ │ <class 'jinja2.utils.Namespace'>}) │ │
│ │ name = 'markdown.j2' │ │
│ │ self = <jinja2.loaders.FileSystemLoader object at 0x7f051970fe90> │ │
│ ╰──────────────────────────────────────────────────────────────────────────────────────────────╯ │
│ │
│ /home/chris/.local/lib/python3.11/site-packages/jinja2/loaders.py:218 in get_source │
│ │
│ 215 │ │ │ │
│ 216 │ │ │ # Use normpath to convert Windows altsep to sep. │
│ 217 │ │ │ return contents, os.path.normpath(filename), uptodate │
│ ❱ 218 │ │ raise TemplateNotFound(template) │
│ 219 │ │
│ 220 │ def list_templates(self) -> t.List[str]: │
│ 221 │ │ found = set() │
│ │
│ ╭─────────────────────────────────────── locals ────────────────────────────────────────╮ │
│ │ environment = <jinja2.environment.Environment object at 0x7f0519b24b10> │ │
│ │ f = None │ │
│ │ filename = '/home/chris/.local/lib/python3.11/site-packages/templates/markdown.j2' │ │
│ │ pieces = ['markdown.j2'] │ │
│ │ searchpath = '/home/chris/.local/lib/python3.11/site-packages/templates' │ │
│ │ self = <jinja2.loaders.FileSystemLoader object at 0x7f051970fe90> │ │
│ │ template = 'markdown.j2' │ │
│ ╰───────────────────────────────────────────────────────────────────────────────────────╯ │
╰──────────────────────────────────────────────────────────────────────────────────────────────────╯
TemplateNotFound: markdown.j2
So I tried manually downloading markdown.j2
:
mkdir /home/chris/.local/lib/python3.11/site-packages/templates
cd /home/chris/.local/lib/python3.11/site-packages/templates
wget https://gitlab.com/kpfleming/ansible-role-docs/-/raw/main/ansible_role_docs/templates/markdown.j2
And now I have this result:
ansible-docs . markdown
╭─────────────────────────────── Traceback (most recent call last) ────────────────────────────────╮
│ /home/chris/.local/lib/python3.11/site-packages/ansible_docs/cli.py:44 in markdown │
│ │
│ 41 │ """ │
│ 42 │ │
│ 43 │ # FIXME: ctx should not be passed to these non-command()'s │
│ ❱ 44 │ content = render_content(ctx, "markdown.j2") │
│ 45 │ write(ctx, content) │
│ 46 │
│ 47 │
│ │
│ ╭────────────────────── locals ───────────────────────╮ │
│ │ ctx = <click.core.Context object at 0x7fd5efe4abd0> │ │
│ ╰─────────────────────────────────────────────────────╯ │
│ │
│ /home/chris/.local/lib/python3.11/site-packages/ansible_docs/cli.py:166 in render_content │
│ │
│ 163 │ loader = jinja2.FileSystemLoader(templates) │
│ 164 │ │
│ 165 │ env = jinja2.Environment(loader=loader) │
│ ❱ 166 │ content = env.get_template(content_template).render( │
│ 167 │ │ role=ctx.obj["config"]["role"], │
│ 168 │ │ metadata=ctx.obj["data"]["metadata"], │
│ 169 │ │ argument_specs=ctx.obj["data"]["argument_specs"], │
│ │
│ ╭───────────────────────────────────────── locals ──────────────────────────────────────────╮ │
│ │ content_template = 'markdown.j2' │ │
│ │ ctx = <click.core.Context object at 0x7fd5efe4abd0> │ │
│ │ env = <jinja2.environment.Environment object at 0x7fd5f008e190> │ │
│ │ loader = <jinja2.loaders.FileSystemLoader object at 0x7fd5efe8fa90> │ │
│ │ templates = PosixPath('/home/chris/.local/lib/python3.11/site-packages/templates') │ │
│ ╰───────────────────────────────────────────────────────────────────────────────────────────╯ │
│ │
│ /home/chris/.local/lib/python3.11/site-packages/jinja2/environment.py:1301 in render │
│ │
│ 1298 │ │ try: │
│ 1299 │ │ │ return self.environment.concat(self.root_render_func(ctx)) # type: ignore │
│ 1300 │ │ except Exception: │
│ ❱ 1301 │ │ │ self.environment.handle_exception() │
│ 1302 │ │
│ 1303 │ async def render_async(self, *args: t.Any, **kwargs: t.Any) -> str: │
│ 1304 │ │ """This works similar to :meth:`render` but returns a coroutine │
│ │
│ ╭─────────────────────────────────────────── locals ───────────────────────────────────────────╮ │
│ │ args = () │ │
│ │ ctx = <Context {'range': <class 'range'>, 'dict': <class 'dict'>, 'lipsum': <function │ │
│ │ generate_lorem_ipsum at 0x7fd5f0552480>, 'cycler': <class 'jinja2.utils.Cycler'>, │ │
│ │ 'joiner': <class 'jinja2.utils.Joiner'>, 'namespace': <class │ │
│ │ 'jinja2.utils.Namespace'>, 'role': 'php', 'metadata': {'galaxy_info': {'role_name': │ │
│ │ 'php', 'author': 'Chris Croome', 'namespace': 'chriscroome', 'description': │ │
│ │ 'Ansible role for installing and configuring PHP on Debian Bullseye and Buster', │ │
│ │ 'company': 'Webarchitects Co-operative', 'license': 'GNU General Public License │ │
│ │ v3.0 (GPLv3)', 'min_ansible_version': '2.13', 'platforms': [{'name': 'Debian', │ │
│ │ 'versions': ['bullseye', 'buster']}], 'galaxy_tags': ['debian', 'php', 'sury']}, │ │
│ │ 'dependencies': []}, 'argument_specs': {'main': {'author': 'Chris Croome', │ │
│ │ 'description': 'Ansible role for installing and configuring PHP on Debian', │ │
│ │ 'short_description': 'The main entry point for the PHP role.', 'options': {'php': │ │
│ │ {'type': 'bool', 'required': True, 'description': 'Run the tasks in this role.'}, │ │
│ │ 'php_config': {'type': 'list', 'required': False, 'description': 'Optional PHP │ │
│ │ configuration.', 'elements': 'dict', 'options': {'files': {'type': 'list', │ │
│ │ 'required': False, 'description': 'A list PHP file paths and their configuration.', │ │
│ │ 'elements': 'dict', 'options': {'conf': {'type': 'dict', 'required': False, │ │
│ │ 'description': 'A YAML dictionary representing the sections, variables and values │ │
│ │ of the PHP configuration file.'}, 'name': {'type': 'str', 'required': False, │ │
│ │ 'description': 'An optional name for the PHP configuration file.'}, 'path': │ │
│ │ {'type': 'str', 'required': True, 'description': 'The path of the PHP configuration │ │
│ │ file.'}, 'state': {'type': 'str', 'required': True, 'description': 'The state of │ │
│ │ the PHP configuration file.', 'choices': ['absent', 'edited', 'present', │ │
│ │ 'templated']}}}, 'name': {'type': 'str', 'required': False, 'description': 'A YAML │ │
│ │ dictionary representing the variables for the PHP configuration file.'}, 'path': │ │
│ │ {'type': 'str', 'required': True, 'description': 'The PHP version number.'}, │ │
│ │ 'state': {'type': 'str', 'required': True, 'description': 'The state of the │ │
│ │ configuration files for the version of PHP.', 'choices': ['absent', 'present']}}}, │ │
│ │ 'php_sury': {'type': 'bool', 'required': False, 'description': 'Configure the Sury │ │
│ │ PHP deb package repo.'}, 'php_versions': {'type': 'list', 'required': False, │ │
│ │ 'description': 'A list of PHP versions and their packages and state.', 'elements': │ │
│ │ 'dict', 'options': {'name': {'type': 'str', 'required': False, 'description': 'A │ │
│ │ optional name for the PHP version packages.'}, 'pkg_absent': {'type': 'list', │ │
│ │ 'required': False, 'description': 'Packages that should be absent for this PHP │ │
│ │ version.', 'elements': 'str'}, 'pkg_present': {'type': 'list', 'required': False, │ │
│ │ 'description': 'Packages that should be present for this PHP version.', 'elements': │ │
│ │ 'str'}, 'state': {'type': 'str', 'required': True, 'description': 'The state of the │ │
│ │ packages for the PHP version.', 'choices': ['absent', 'present']}, 'version': │ │
│ │ {'type': 'str', 'required': True, 'description': 'The PHP version number.'}}}}}}} │ │
│ │ of 'markdown.j2'> │ │
│ │ kwargs = { │ │
│ │ │ 'role': 'php', │ │
│ │ │ 'metadata': { │ │
│ │ │ │ 'galaxy_info': { │ │
│ │ │ │ │ 'role_name': 'php', │ │
│ │ │ │ │ 'author': 'Chris Croome', │ │
│ │ │ │ │ 'namespace': 'chriscroome', │ │
│ │ │ │ │ 'description': 'Ansible role for installing and configuring PHP on │ │
│ │ Debian Bullseye and Buster', │ │
│ │ │ │ │ 'company': 'Webarchitects Co-operative', │ │
│ │ │ │ │ 'license': 'GNU General Public License v3.0 (GPLv3)', │ │
│ │ │ │ │ 'min_ansible_version': '2.13', │ │
│ │ │ │ │ 'platforms': [{'name': 'Debian', 'versions': ['bullseye', 'buster']}], │ │
│ │ │ │ │ 'galaxy_tags': ['debian', 'php', 'sury'] │ │
│ │ │ │ }, │ │
│ │ │ │ 'dependencies': [] │ │
│ │ │ }, │ │
│ │ │ 'argument_specs': { │ │
│ │ │ │ 'main': { │ │
│ │ │ │ │ 'author': 'Chris Croome', │ │
│ │ │ │ │ 'description': 'Ansible role for installing and configuring PHP on │ │
│ │ Debian', │ │
│ │ │ │ │ 'short_description': 'The main entry point for the PHP role.', │ │
│ │ │ │ │ 'options': { │ │
│ │ │ │ │ │ 'php': { │ │
│ │ │ │ │ │ │ 'type': 'bool', │ │
│ │ │ │ │ │ │ 'required': True, │ │
│ │ │ │ │ │ │ 'description': 'Run the tasks in this role.' │ │
│ │ │ │ │ │ }, │ │
│ │ │ │ │ │ 'php_config': { │ │
│ │ │ │ │ │ │ 'type': 'list', │ │
│ │ │ │ │ │ │ 'required': False, │ │
│ │ │ │ │ │ │ 'description': 'Optional PHP configuration.', │ │
│ │ │ │ │ │ │ 'elements': 'dict', │ │
│ │ │ │ │ │ │ 'options': { │ │
│ │ │ │ │ │ │ │ 'files': { │ │
│ │ │ │ │ │ │ │ │ 'type': 'list', │ │
│ │ │ │ │ │ │ │ │ 'required': False, │ │
│ │ │ │ │ │ │ │ │ 'description': 'A list PHP file paths and their │ │
│ │ configuration.', │ │
│ │ │ │ │ │ │ │ │ 'elements': 'dict', │ │
│ │ │ │ │ │ │ │ │ 'options': { │ │
│ │ │ │ │ │ │ │ │ │ 'conf': { │ │
│ │ │ │ │ │ │ │ │ │ │ 'type': 'dict', │ │
│ │ │ │ │ │ │ │ │ │ │ 'required': False, │ │
│ │ │ │ │ │ │ │ │ │ │ 'description': 'A YAML dictionary representing │ │
│ │ the sections, variables and values of the PHP con'+16 │ │
│ │ │ │ │ │ │ │ │ │ }, │ │
│ │ │ │ │ │ │ │ │ │ 'name': { │ │
│ │ │ │ │ │ │ │ │ │ │ 'type': 'str', │ │
│ │ │ │ │ │ │ │ │ │ │ 'required': False, │ │
│ │ │ │ │ │ │ │ │ │ │ 'description': 'An optional name for the PHP │ │
│ │ configuration file.' │ │
│ │ │ │ │ │ │ │ │ │ }, │ │
│ │ │ │ │ │ │ │ │ │ 'path': { │ │
│ │ │ │ │ │ │ │ │ │ │ 'type': 'str', │ │
│ │ │ │ │ │ │ │ │ │ │ 'required': True, │ │
│ │ │ │ │ │ │ │ │ │ │ 'description': 'The path of the PHP │ │
│ │ configuration file.' │ │
│ │ │ │ │ │ │ │ │ │ }, │ │
│ │ │ │ │ │ │ │ │ │ 'state': { │ │
│ │ │ │ │ │ │ │ │ │ │ 'type': 'str', │ │
│ │ │ │ │ │ │ │ │ │ │ 'required': True, │ │
│ │ │ │ │ │ │ │ │ │ │ 'description': 'The state of the PHP │ │
│ │ configuration file.', │ │
│ │ │ │ │ │ │ │ │ │ │ 'choices': [ │ │
│ │ │ │ │ │ │ │ │ │ │ │ 'absent', │ │
│ │ │ │ │ │ │ │ │ │ │ │ 'edited', │ │
│ │ │ │ │ │ │ │ │ │ │ │ 'present', │ │
│ │ │ │ │ │ │ │ │ │ │ │ 'templated' │ │
│ │ │ │ │ │ │ │ │ │ │ ] │ │
│ │ │ │ │ │ │ │ │ │ } │ │
│ │ │ │ │ │ │ │ │ } │ │
│ │ │ │ │ │ │ │ }, │ │
│ │ │ │ │ │ │ │ 'name': { │ │
│ │ │ │ │ │ │ │ │ 'type': 'str', │ │
│ │ │ │ │ │ │ │ │ 'required': False, │ │
│ │ │ │ │ │ │ │ │ 'description': 'A YAML dictionary representing the │ │
│ │ variables for the PHP configuration file.' │ │
│ │ │ │ │ │ │ │ }, │ │
│ │ │ │ │ │ │ │ 'path': { │ │
│ │ │ │ │ │ │ │ │ 'type': 'str', │ │
│ │ │ │ │ │ │ │ │ 'required': True, │ │
│ │ │ │ │ │ │ │ │ 'description': 'The PHP version number.' │ │
│ │ │ │ │ │ │ │ }, │ │
│ │ │ │ │ │ │ │ 'state': { │ │
│ │ │ │ │ │ │ │ │ 'type': 'str', │ │
│ │ │ │ │ │ │ │ │ 'required': True, │ │
│ │ │ │ │ │ │ │ │ 'description': 'The state of the configuration files │ │
│ │ for the version of PHP.', │ │
│ │ │ │ │ │ │ │ │ 'choices': ['absent', 'present'] │ │
│ │ │ │ │ │ │ │ } │ │
│ │ │ │ │ │ │ } │ │
│ │ │ │ │ │ }, │ │
│ │ │ │ │ │ 'php_sury': { │ │
│ │ │ │ │ │ │ 'type': 'bool', │ │
│ │ │ │ │ │ │ 'required': False, │ │
│ │ │ │ │ │ │ 'description': 'Configure the Sury PHP deb package repo.' │ │
│ │ │ │ │ │ }, │ │
│ │ │ │ │ │ 'php_versions': { │ │
│ │ │ │ │ │ │ 'type': 'list', │ │
│ │ │ │ │ │ │ 'required': False, │ │
│ │ │ │ │ │ │ 'description': 'A list of PHP versions and their packages and │ │
│ │ state.', │ │
│ │ │ │ │ │ │ 'elements': 'dict', │ │
│ │ │ │ │ │ │ 'options': { │ │
│ │ │ │ │ │ │ │ 'name': { │ │
│ │ │ │ │ │ │ │ │ 'type': 'str', │ │
│ │ │ │ │ │ │ │ │ 'required': False, │ │
│ │ │ │ │ │ │ │ │ 'description': 'A optional name for the PHP version │ │
│ │ packages.' │ │
│ │ │ │ │ │ │ │ }, │ │
│ │ │ │ │ │ │ │ 'pkg_absent': { │ │
│ │ │ │ │ │ │ │ │ 'type': 'list', │ │
│ │ │ │ │ │ │ │ │ 'required': False, │ │
│ │ │ │ │ │ │ │ │ 'description': 'Packages that should be absent for this │ │
│ │ PHP version.', │ │
│ │ │ │ │ │ │ │ │ 'elements': 'str' │ │
│ │ │ │ │ │ │ │ }, │ │
│ │ │ │ │ │ │ │ 'pkg_present': { │ │
│ │ │ │ │ │ │ │ │ 'type': 'list', │ │
│ │ │ │ │ │ │ │ │ 'required': False, │ │
│ │ │ │ │ │ │ │ │ 'description': 'Packages that should be present for │ │
│ │ this PHP version.', │ │
│ │ │ │ │ │ │ │ │ 'elements': 'str' │ │
│ │ │ │ │ │ │ │ }, │ │
│ │ │ │ │ │ │ │ 'state': { │ │
│ │ │ │ │ │ │ │ │ 'type': 'str', │ │
│ │ │ │ │ │ │ │ │ 'required': True, │ │
│ │ │ │ │ │ │ │ │ 'description': 'The state of the packages for the PHP │ │
│ │ version.', │ │
│ │ │ │ │ │ │ │ │ 'choices': ['absent', 'present'] │ │
│ │ │ │ │ │ │ │ }, │ │
│ │ │ │ │ │ │ │ 'version': { │ │
│ │ │ │ │ │ │ │ │ 'type': 'str', │ │
│ │ │ │ │ │ │ │ │ 'required': True, │ │
│ │ │ │ │ │ │ │ │ 'description': 'The PHP version number.' │ │
│ │ │ │ │ │ │ │ } │ │
│ │ │ │ │ │ │ } │ │
│ │ │ │ │ │ } │ │
│ │ │ │ │ } │ │
│ │ │ │ } │ │
│ │ │ } │ │
│ │ } │ │
│ │ self = <Template 'markdown.j2'> │ │
│ ╰──────────────────────────────────────────────────────────────────────────────────────────────╯ │
│ │
│ /home/chris/.local/lib/python3.11/site-packages/jinja2/environment.py:936 in handle_exception │
│ │
│ 933 │ │ """ │
│ 934 │ │ from .debug import rewrite_traceback_stack │
│ 935 │ │ │
│ ❱ 936 │ │ raise rewrite_traceback_stack(source=source) │
│ 937 │ │
│ 938 │ def join_path(self, template: str, parent: str) -> str: │
│ 939 │ │ """Join a template with the parent. By default all the lookups are │
│ │
│ ╭────────────────────────────────────── locals ───────────────────────────────────────╮ │
│ │ rewrite_traceback_stack = <function rewrite_traceback_stack at 0x7fd5efe91300> │ │
│ │ self = <jinja2.environment.Environment object at 0x7fd5f008e190> │ │
│ │ source = None │ │
│ ╰─────────────────────────────────────────────────────────────────────────────────────╯ │
│ │
│ /home/chris/.local/lib/python3.11/site-packages/templates/markdown.j2:22 in top-level template │
│ code │
│ │
│ 19 ## Role Arguments │
│ 20 --- │
│ 21 {% for entrypoint in argument_specs.keys() %} │
│ ❱ 22 {%- set path, options=entrypoint_options[entrypoint][0] -%} │
│ 23 ### Entrypoint: {{ entrypoint }} │
│ 24 --- │
│ 25 {{ argument_specs[entrypoint].short_description }} │
│ │
│ ╭─────────────────────────────────────────── locals ───────────────────────────────────────────╮ │
│ │ argument_specs = { │ │
│ │ │ 'main': { │ │
│ │ │ │ 'author': 'Chris Croome', │ │
│ │ │ │ 'description': 'Ansible role for installing and configuring PHP on │ │
│ │ Debian', │ │
│ │ │ │ 'short_description': 'The main entry point for the PHP role.', │ │
│ │ │ │ 'options': { │ │
│ │ │ │ │ 'php': { │ │
│ │ │ │ │ │ 'type': 'bool', │ │
│ │ │ │ │ │ 'required': True, │ │
│ │ │ │ │ │ 'description': 'Run the tasks in this role.' │ │
│ │ │ │ │ }, │ │
│ │ │ │ │ 'php_config': { │ │
│ │ │ │ │ │ 'type': 'list', │ │
│ │ │ │ │ │ 'required': False, │ │
│ │ │ │ │ │ 'description': 'Optional PHP configuration.', │ │
│ │ │ │ │ │ 'elements': 'dict', │ │
│ │ │ │ │ │ 'options': { │ │
│ │ │ │ │ │ │ 'files': { │ │
│ │ │ │ │ │ │ │ 'type': 'list', │ │
│ │ │ │ │ │ │ │ 'required': False, │ │
│ │ │ │ │ │ │ │ 'description': 'A list PHP file paths and their │ │
│ │ configuration.', │ │
│ │ │ │ │ │ │ │ 'elements': 'dict', │ │
│ │ │ │ │ │ │ │ 'options': { │ │
│ │ │ │ │ │ │ │ │ 'conf': { │ │
│ │ │ │ │ │ │ │ │ │ 'type': 'dict', │ │
│ │ │ │ │ │ │ │ │ │ 'required': False, │ │
│ │ │ │ │ │ │ │ │ │ 'description': 'A YAML dictionary │ │
│ │ representing the sections, variables and values of the PHP con'+16 │ │
│ │ │ │ │ │ │ │ │ }, │ │
│ │ │ │ │ │ │ │ │ 'name': { │ │
│ │ │ │ │ │ │ │ │ │ 'type': 'str', │ │
│ │ │ │ │ │ │ │ │ │ 'required': False, │ │
│ │ │ │ │ │ │ │ │ │ 'description': 'An optional name for the │ │
│ │ PHP configuration file.' │ │
│ │ │ │ │ │ │ │ │ }, │ │
│ │ │ │ │ │ │ │ │ 'path': { │ │
│ │ │ │ │ │ │ │ │ │ 'type': 'str', │ │
│ │ │ │ │ │ │ │ │ │ 'required': True, │ │
│ │ │ │ │ │ │ │ │ │ 'description': 'The path of the PHP │ │
│ │ configuration file.' │ │
│ │ │ │ │ │ │ │ │ }, │ │
│ │ │ │ │ │ │ │ │ 'state': { │ │
│ │ │ │ │ │ │ │ │ │ 'type': 'str', │ │
│ │ │ │ │ │ │ │ │ │ 'required': True, │ │
│ │ │ │ │ │ │ │ │ │ 'description': 'The state of the PHP │ │
│ │ configuration file.', │ │
│ │ │ │ │ │ │ │ │ │ 'choices': [ │ │
│ │ │ │ │ │ │ │ │ │ │ 'absent', │ │
│ │ │ │ │ │ │ │ │ │ │ 'edited', │ │
│ │ │ │ │ │ │ │ │ │ │ 'present', │ │
│ │ │ │ │ │ │ │ │ │ │ 'templated' │ │
│ │ │ │ │ │ │ │ │ │ ] │ │
│ │ │ │ │ │ │ │ │ } │ │
│ │ │ │ │ │ │ │ } │ │
│ │ │ │ │ │ │ }, │ │
│ │ │ │ │ │ │ 'name': { │ │
│ │ │ │ │ │ │ │ 'type': 'str', │ │
│ │ │ │ │ │ │ │ 'required': False, │ │
│ │ │ │ │ │ │ │ 'description': 'A YAML dictionary representing the │ │
│ │ variables for the PHP configuration file.' │ │
│ │ │ │ │ │ │ }, │ │
│ │ │ │ │ │ │ 'path': { │ │
│ │ │ │ │ │ │ │ 'type': 'str', │ │
│ │ │ │ │ │ │ │ 'required': True, │ │
│ │ │ │ │ │ │ │ 'description': 'The PHP version number.' │ │
│ │ │ │ │ │ │ }, │ │
│ │ │ │ │ │ │ 'state': { │ │
│ │ │ │ │ │ │ │ 'type': 'str', │ │
│ │ │ │ │ │ │ │ 'required': True, │ │
│ │ │ │ │ │ │ │ 'description': 'The state of the configuration │ │
│ │ files for the version of PHP.', │ │
│ │ │ │ │ │ │ │ 'choices': ['absent', 'present'] │ │
│ │ │ │ │ │ │ } │ │
│ │ │ │ │ │ } │ │
│ │ │ │ │ }, │ │
│ │ │ │ │ 'php_sury': { │ │
│ │ │ │ │ │ 'type': 'bool', │ │
│ │ │ │ │ │ 'required': False, │ │
│ │ │ │ │ │ 'description': 'Configure the Sury PHP deb package repo.' │ │
│ │ │ │ │ }, │ │
│ │ │ │ │ 'php_versions': { │ │
│ │ │ │ │ │ 'type': 'list', │ │
│ │ │ │ │ │ 'required': False, │ │
│ │ │ │ │ │ 'description': 'A list of PHP versions and their packages │ │
│ │ and state.', │ │
│ │ │ │ │ │ 'elements': 'dict', │ │
│ │ │ │ │ │ 'options': { │ │
│ │ │ │ │ │ │ 'name': { │ │
│ │ │ │ │ │ │ │ 'type': 'str', │ │
│ │ │ │ │ │ │ │ 'required': False, │ │
│ │ │ │ │ │ │ │ 'description': 'A optional name for the PHP version │ │
│ │ packages.' │ │
│ │ │ │ │ │ │ }, │ │
│ │ │ │ │ │ │ 'pkg_absent': { │ │
│ │ │ │ │ │ │ │ 'type': 'list', │ │
│ │ │ │ │ │ │ │ 'required': False, │ │
│ │ │ │ │ │ │ │ 'description': 'Packages that should be absent for │ │
│ │ this PHP version.', │ │
│ │ │ │ │ │ │ │ 'elements': 'str' │ │
│ │ │ │ │ │ │ }, │ │
│ │ │ │ │ │ │ 'pkg_present': { │ │
│ │ │ │ │ │ │ │ 'type': 'list', │ │
│ │ │ │ │ │ │ │ 'required': False, │ │
│ │ │ │ │ │ │ │ 'description': 'Packages that should be present for │ │
│ │ this PHP version.', │ │
│ │ │ │ │ │ │ │ 'elements': 'str' │ │
│ │ │ │ │ │ │ }, │ │
│ │ │ │ │ │ │ 'state': { │ │
│ │ │ │ │ │ │ │ 'type': 'str', │ │
│ │ │ │ │ │ │ │ 'required': True, │ │
│ │ │ │ │ │ │ │ 'description': 'The state of the packages for the │ │
│ │ PHP version.', │ │
│ │ │ │ │ │ │ │ 'choices': ['absent', 'present'] │ │
│ │ │ │ │ │ │ }, │ │
│ │ │ │ │ │ │ 'version': { │ │
│ │ │ │ │ │ │ │ 'type': 'str', │ │
│ │ │ │ │ │ │ │ 'required': True, │ │
│ │ │ │ │ │ │ │ 'description': 'The PHP version number.' │ │
│ │ │ │ │ │ │ } │ │
│ │ │ │ │ │ } │ │
│ │ │ │ │ } │ │
│ │ │ │ } │ │
│ │ │ } │ │
│ │ } │ │
│ │ cycler = <class 'jinja2.utils.Cycler'> │ │
│ │ dict = <class 'dict'> │ │
│ │ entrypoint = 'main' │ │
│ │ joiner = <class 'jinja2.utils.Joiner'> │ │
│ │ lipsum = <function generate_lorem_ipsum at 0x7fd5f0552480> │ │
│ │ metadata = { │ │
│ │ │ 'galaxy_info': { │ │
│ │ │ │ 'role_name': 'php', │ │
│ │ │ │ 'author': 'Chris Croome', │ │
│ │ │ │ 'namespace': 'chriscroome', │ │
│ │ │ │ 'description': 'Ansible role for installing and configuring PHP on │ │
│ │ Debian Bullseye and Buster', │ │
│ │ │ │ 'company': 'Webarchitects Co-operative', │ │
│ │ │ │ 'license': 'GNU General Public License v3.0 (GPLv3)', │ │
│ │ │ │ 'min_ansible_version': '2.13', │ │
│ │ │ │ 'platforms': [ │ │
│ │ │ │ │ {'name': 'Debian', 'versions': ['bullseye', 'buster']} │ │
│ │ │ │ ], │ │
│ │ │ │ 'galaxy_tags': ['debian', 'php', 'sury'] │ │
│ │ │ }, │ │
│ │ │ 'dependencies': [] │ │
│ │ } │ │
│ │ namespace = <class 'jinja2.utils.Namespace'> │ │
│ │ range = <class 'range'> │ │
│ │ role = 'php' │ │
│ ╰──────────────────────────────────────────────────────────────────────────────────────────────╯ │
│ │
│ /home/chris/.local/lib/python3.11/site-packages/jinja2/environment.py:466 in getitem │
│ │
│ 463 │ ) -> t.Union[t.Any, Undefined]: │
│ 464 │ │ """Get an item or attribute of an object but prefer the item.""" │
│ 465 │ │ try: │
│ ❱ 466 │ │ │ return obj[argument] │
│ 467 │ │ except (AttributeError, TypeError, LookupError): │
│ 468 │ │ │ if isinstance(argument, str): │
│ 469 │ │ │ │ try: │
│ │
│ ╭─────────────────────────────── locals ───────────────────────────────╮ │
│ │ argument = 'main' │ │
│ │ obj = Undefined │ │
│ │ self = <jinja2.environment.Environment object at 0x7fd5f008e190> │ │
│ ╰──────────────────────────────────────────────────────────────────────╯ │
╰──────────────────────────────────────────────────────────────────────────────────────────────────╯
UndefinedError: 'entrypoint_options' is undefined
These are the files in the meta
directory:
- https://git.coop/webarch/php/-/blob/sury/meta/argument_specs.yml
- https://git.coop/webarch/php/-/blob/sury/meta/main.yml
Any idea what I'm doing wrong?
(The sury
branch of the role in question is a WIP but I think the metadata files are valid.)