From 1599ac0691bbe4a7ffb73851a32bdb1a3133c985 Mon Sep 17 00:00:00 2001 From: Felix Fontein Date: Sun, 13 Jul 2025 12:03:29 +0200 Subject: [PATCH 1/2] Avoid code-blocks without language. --- .../style_guide/grammar_punctuation.rst | 6 +- .../rst/playbook_guide/playbooks_loops.rst | 4 +- .../rst/porting_guides/porting_guide_2.0.rst | 64 +++++++++++++------ .../rst/porting_guides/porting_guide_2.10.rst | 2 +- .../rst/porting_guides/porting_guide_2.4.rst | 8 ++- .../rst/porting_guides/porting_guide_2.5.rst | 8 ++- .../rst/porting_guides/porting_guide_2.6.rst | 8 ++- .../rst/porting_guides/porting_guide_2.7.rst | 4 +- .../rst/porting_guides/porting_guide_2.8.rst | 24 +++++-- .../porting_guide_core_2.19.rst | 32 +++++++--- 10 files changed, 115 insertions(+), 45 deletions(-) diff --git a/docs/docsite/rst/dev_guide/style_guide/grammar_punctuation.rst b/docs/docsite/rst/dev_guide/style_guide/grammar_punctuation.rst index f9a873b4a7..603b7c40cf 100644 --- a/docs/docsite/rst/dev_guide/style_guide/grammar_punctuation.rst +++ b/docs/docsite/rst/dev_guide/style_guide/grammar_punctuation.rst @@ -77,7 +77,7 @@ A pair of em dashes can replace a pair of parentheses. Dashes are considered les .. note:: When dashes are used in place of parentheses, surrounding punctuation should be omitted. Compare the following examples. -:: +.. code-block:: text Upon discovering the errors (all 124 of them), the publisher immediately recalled the books. @@ -86,7 +86,7 @@ A pair of em dashes can replace a pair of parentheses. Dashes are considered les When used in place of parentheses at the end of a sentence, only a single dash is used. -:: +.. code-block:: text After three weeks on set, the cast was fed up with his direction (or, rather, lack of direction). @@ -114,7 +114,7 @@ The hyphen's primary function is the formation of certain compound terms. Do not Use hyphens to avoid ambiguity or confusion: -:: +.. code-block:: text a little-used car a little used-car diff --git a/docs/docsite/rst/playbook_guide/playbooks_loops.rst b/docs/docsite/rst/playbook_guide/playbooks_loops.rst index 8bab3d4f3a..809afe04ff 100644 --- a/docs/docsite/rst/playbook_guide/playbooks_loops.rst +++ b/docs/docsite/rst/playbook_guide/playbooks_loops.rst @@ -456,7 +456,7 @@ Variable Description ``ansible_loop.nextitem`` The item from the following iteration of the loop. Undefined during the last iteration. ========================== =========== -:: +.. code-block:: yaml loop_control: extended: true @@ -467,7 +467,7 @@ Variable Description To disable the ``ansible_loop.allitems`` item, to reduce memory consumption, set ``loop_control.extended_allitems: false``. -:: +.. code-block:: yaml loop_control: extended: true diff --git a/docs/docsite/rst/porting_guides/porting_guide_2.0.rst b/docs/docsite/rst/porting_guides/porting_guide_2.0.rst index 9d2ef46c7f..dafa22dda9 100644 --- a/docs/docsite/rst/porting_guides/porting_guide_2.0.rst +++ b/docs/docsite/rst/porting_guides/porting_guide_2.0.rst @@ -43,20 +43,24 @@ This section discusses any changes you may need to make to your playbooks. "msg": "test1 1\\3" -To make an escaped string that will work on all versions you have two options:: +To make an escaped string that will work on all versions you have two options: -- debug: msg="{{ 'test1_junk 1\\3' | regex_replace('(.*)_junk (.*)', '\\1 \\2') }}" +.. code-block:: yaml+jinja -uses key=value escaping which has not changed. The other option is to check for the ansible version:: + - debug: msg="{{ 'test1_junk 1\\3' | regex_replace('(.*)_junk (.*)', '\\1 \\2') }}" -"{{ (ansible_version|version_compare('2.0', 'ge'))|ternary( 'test1_junk 1\\3' | regex_replace('(.*)_junk (.*)', '\\1 \\2') , 'test1_junk 1\\\\3' | regex_replace('(.*)_junk (.*)', '\\\\1 \\\\2') ) }}" +uses key=value escaping which has not changed. The other option is to check for the ansible version: + +.. code-block:: jinja + + "{{ (ansible_version|version_compare('2.0', 'ge'))|ternary( 'test1_junk 1\\3' | regex_replace('(.*)_junk (.*)', '\\1 \\2') , 'test1_junk 1\\\\3' | regex_replace('(.*)_junk (.*)', '\\\\1 \\\\2') ) }}" * trailing newline When a string with a trailing newline was specified in the playbook through yaml dict format, the trailing newline was stripped. When specified in key=value format, the trailing newlines were kept. In v2, both methods of specifying the string will keep the trailing newlines. If you relied on the trailing newline being stripped, you can change your playbook - using the following as an example:: + using the following as an example: * Syntax in 1.9.x @@ -168,17 +172,23 @@ Example of a recommended variant: * Ranges specified in host patterns should use the [x:y] syntax, instead of [x-y]. * Playbooks using privilege escalation should always use "become*" options rather than the old su*/sudo* options. * The "short form" for vars_prompt is no longer supported. - For example:: + For example: + + .. code-block:: yaml+jinja vars_prompt: variable_name: "Prompt string" -* Specifying variables at the top level of a task include statement is no longer supported. For example:: +* Specifying variables at the top level of a task include statement is no longer supported. For example: + + .. code-block:: yaml+jinja - include_tasks: foo.yml - a: 1 + a: 1 + +Should now be: -Should now be:: +.. code-block:: yaml+jinja - include_tasks: foo.yml vars: @@ -187,11 +197,15 @@ Should now be:: * Setting any_errors_fatal on a task is no longer supported. This should be set at the play level only. * Bare variables in the `environment` dictionary (for plays/tasks/and so on) are no longer supported. Variables specified there should use the full variable syntax: '{{foo}}'. * Tags (or any directive) should no longer be specified with other parameters in a task include. Instead, they should be specified as an option on the task. - For example:: + For example: + + .. code-block:: yaml+jinja - include_tasks: foo.yml tags=a,b,c - Should be:: + Should be: + + .. code-block:: yaml+jinja - include_tasks: foo.yml tags: [a, b, c] @@ -204,15 +218,21 @@ Other caveats Here are some corner cases encountered when updating. These are mostly caused by the more stringent parser validation and the capture of errors that were previously ignored. -* Bad variable composition:: +* Bad variable composition: + + .. code-block:: yaml+jinja with_items: myvar_{{rest_of_name}} - This worked 'by accident' as the errors were retemplated and ended up resolving the variable, it was never intended as valid syntax and now properly returns an error, use the following instead.:: + This worked 'by accident' as the errors were retemplated and ended up resolving the variable, it was never intended as valid syntax and now properly returns an error, use the following instead.: + + .. code-block:: jinja hostvars[inventory_hostname]['myvar_' + rest_of_name] -* Misspelled directives:: +* Misspelled directives: + + .. code-block:: yaml+jinja - task: dostuf becom: yes @@ -220,7 +240,9 @@ Here are some corner cases encountered when updating. These are mostly caused by The task always ran without using privilege escalation (for that you need `become`) but was also silently ignored so the play 'ran' even though it should not, now this is a parsing error. -* Duplicate directives:: +* Duplicate directives: + + .. code-block:: yaml+jinja - task: dostuf when: True @@ -228,7 +250,9 @@ Here are some corner cases encountered when updating. These are mostly caused by The first `when` was ignored and only the 2nd one was used as the play ran w/o warning it was ignoring one of the directives, now this produces a parsing error. -* Conflating variables and directives:: +* Conflating variables and directives: + + .. code-block:: yaml+jinja - role: {name=rosy, port=435 } @@ -239,12 +263,16 @@ Here are some corner cases encountered when updating. These are mostly caused by later in the play, this created issues if a host tried to reconnect or was using a non caching connection. Now it will be correctly identified as a directive and the `port` variable will appear as undefined, this now forces the use of non conflicting names and removes ambiguity when adding settings and variables to a role invocation. -* Bare operations on `with_`:: +* Bare operations on `with_`: + + .. code-block:: yaml+jinja with_items: var1 + var2 An issue with the 'bare variable' features, which was supposed only template a single variable without the need of braces ({{ )}}, would in some versions of Ansible template full expressions. - Now you need to use proper templating and braces for all expressions everywhere except conditionals (`when`):: + Now you need to use proper templating and braces for all expressions everywhere except conditionals (`when`): + + .. code-block:: yaml+jinja with_items: "{{var1 + var2}}" diff --git a/docs/docsite/rst/porting_guides/porting_guide_2.10.rst b/docs/docsite/rst/porting_guides/porting_guide_2.10.rst index 6d388abd87..47ea661662 100644 --- a/docs/docsite/rst/porting_guides/porting_guide_2.10.rst +++ b/docs/docsite/rst/porting_guides/porting_guide_2.10.rst @@ -576,7 +576,7 @@ netbox.netbox the decision to change the method to convert to an integer for the NetBox API. - :: + .. code-block:: yaml+jinja tasks: - name: Create device within NetBox with only required information diff --git a/docs/docsite/rst/porting_guides/porting_guide_2.4.rst b/docs/docsite/rst/porting_guides/porting_guide_2.4.rst index d58ae48d13..59779ad29e 100644 --- a/docs/docsite/rst/porting_guides/porting_guide_2.4.rst +++ b/docs/docsite/rst/porting_guides/porting_guide_2.4.rst @@ -152,7 +152,9 @@ automatically. In 2.4, users are responsible for escaping backslashes themselves brings the template lookup plugin inline with the template module so that the same backslash escaping rules apply to both. -If you have a template lookup like this:: +If you have a template lookup like this: + +.. code-block:: yaml+jinja - debug: msg: '{{ lookup("template", "template.j2") }}' @@ -175,7 +177,9 @@ Tests Tests succeeded/failed ----------------------- -Prior to Ansible version 2.4, a task return code of ``rc`` would override a return code of ``failed``. In version 2.4, both ``rc`` and ``failed`` are used to calculate the state of the task. Because of this, test plugins ``succeeded``/``failed``` have also been changed. This means that overriding a task failure with ``failed_when: no`` will result in ``succeeded``/``failed`` returning ``True``/``False``. For example:: +Prior to Ansible version 2.4, a task return code of ``rc`` would override a return code of ``failed``. In version 2.4, both ``rc`` and ``failed`` are used to calculate the state of the task. Because of this, test plugins ``succeeded``/``failed``` have also been changed. This means that overriding a task failure with ``failed_when: no`` will result in ``succeeded``/``failed`` returning ``True``/``False``. For example: + +.. code-block:: yaml+jinja - command: /bin/false register: result diff --git a/docs/docsite/rst/porting_guides/porting_guide_2.5.rst b/docs/docsite/rst/porting_guides/porting_guide_2.5.rst index a0d02833bb..f20735c943 100644 --- a/docs/docsite/rst/porting_guides/porting_guide_2.5.rst +++ b/docs/docsite/rst/porting_guides/porting_guide_2.5.rst @@ -78,12 +78,16 @@ The relevant change in those examples is, that in Ansible 2.5, the included file Fixed handling of keywords and inline variables ----------------------------------------------- -We made several fixes to how we handle keywords and 'inline variables', to avoid conflating the two. Unfortunately these changes mean you must specify whether `name` is a keyword or a variable when calling roles. If you have playbooks that look like this:: +We made several fixes to how we handle keywords and 'inline variables', to avoid conflating the two. Unfortunately these changes mean you must specify whether `name` is a keyword or a variable when calling roles. If you have playbooks that look like this: + +.. code-block:: yaml+jinja roles: - { role: myrole, name: Justin, othervar: othervalue, become: True} -You will run into errors because Ansible reads name in this context as a keyword. Beginning in 2.5, if you want to use a variable name that is also a keyword, you must explicitly declare it as a variable for the role:: +You will run into errors because Ansible reads name in this context as a keyword. Beginning in 2.5, if you want to use a variable name that is also a keyword, you must explicitly declare it as a variable for the role: + +.. code-block:: yaml+jinja roles: - { role: myrole, vars: {name: Justin, othervar: othervalue}, become: True} diff --git a/docs/docsite/rst/porting_guides/porting_guide_2.6.rst b/docs/docsite/rst/porting_guides/porting_guide_2.6.rst index 96db366b50..be29d4e5d2 100644 --- a/docs/docsite/rst/porting_guides/porting_guide_2.6.rst +++ b/docs/docsite/rst/porting_guides/porting_guide_2.6.rst @@ -56,12 +56,16 @@ Noteworthy module changes * The :ref:`file_module` now emits a deprecation warning when ``src`` is specified with a state other than ``hard`` or ``link`` as it is only supposed to be useful with those. This could have an effect on people who were depending on a buggy interaction between src and other state's to - place files into a subdirectory. For example:: + place files into a subdirectory. For example: + + .. code-block:: console $ ansible localhost -m file -a 'path=/var/lib src=/tmp/ state=directory' Would create a directory named ``/tmp/lib``. Instead of the above, simply spell out the entire - destination path like this:: + destination path like this: + + .. code-block:: console $ ansible localhost -m file -a 'path=/tmp/lib state=directory' diff --git a/docs/docsite/rst/porting_guides/porting_guide_2.7.rst b/docs/docsite/rst/porting_guides/porting_guide_2.7.rst index 3010190b73..1a60f54d89 100644 --- a/docs/docsite/rst/porting_guides/porting_guide_2.7.rst +++ b/docs/docsite/rst/porting_guides/porting_guide_2.7.rst @@ -217,7 +217,9 @@ Noteworthy module changes * The ``win_disk_image`` module has deprecated the return value ``mount_path``, use ``mount_paths[0]`` instead. This will be removed in Ansible 2.11. -* ``include_role`` and ``include_tasks`` can now be used directly from ``ansible`` (adhoc) and ``ansible-console``:: +* ``include_role`` and ``include_tasks`` can now be used directly from ``ansible`` (adhoc) and ``ansible-console``: + + .. code-block:: console #> ansible -m include_role -a 'name=myrole' all diff --git a/docs/docsite/rst/porting_guides/porting_guide_2.8.rst b/docs/docsite/rst/porting_guides/porting_guide_2.8.rst index 1f3903476e..047de8e976 100644 --- a/docs/docsite/rst/porting_guides/porting_guide_2.8.rst +++ b/docs/docsite/rst/porting_guides/porting_guide_2.8.rst @@ -44,15 +44,21 @@ Jinja Undefined values Beginning in version 2.8, attempting to access an attribute of an Undefined value in Jinja will return another Undefined value, rather than throwing an error immediately. This means that you can now simply use a default with a value in a nested data structure when you don't know if the intermediate values are defined. -In Ansible 2.8:: +In Ansible 2.8: + +.. code-block:: jinja {{ foo.bar.baz | default('DEFAULT') }} -In Ansible 2.7 and older:: +In Ansible 2.7 and older: + +.. code-block:: jinja {{ ((foo | default({})).bar | default({})).baz | default('DEFAULT') }} -or:: +or: + +.. code-block:: jinja {{ foo.bar.baz if (foo is defined and foo.bar is defined and foo.bar.baz is defined) else 'DEFAULT' }} @@ -309,14 +315,18 @@ Become Prompting Beginning in version 2.8, by default Ansible will use the word ``BECOME`` to prompt you for a password for elevated privileges (``sudo`` privileges on Unix systems or ``enable`` mode on network devices): -By default in Ansible 2.8:: +By default in Ansible 2.8: + +.. code-block:: console ansible-playbook --become --ask-become-pass site.yml BECOME password: If you want the prompt to display the specific ``become_method`` you're using, instead of the general value ``BECOME``, set :ref:`AGNOSTIC_BECOME_PROMPT` to ``False`` in your Ansible configuration. -By default in Ansible 2.7, or with ``AGNOSTIC_BECOME_PROMPT=False`` in Ansible 2.8:: +By default in Ansible 2.7, or with ``AGNOSTIC_BECOME_PROMPT=False`` in Ansible 2.8: + +.. code-block:: console ansible-playbook --become --ask-become-pass site.yml SUDO password: @@ -325,7 +335,9 @@ Deprecated ========== * Setting the async directory using ``ANSIBLE_ASYNC_DIR`` as an task/play environment key is deprecated and will be - removed in Ansible 2.12. You can achieve the same result by setting ``ansible_async_dir`` as a variable like:: + removed in Ansible 2.12. You can achieve the same result by setting ``ansible_async_dir`` as a variable like: + + .. code-block:: yaml+jinja - name: run task with custom async directory command: sleep 5 diff --git a/docs/docsite/rst/porting_guides/porting_guide_core_2.19.rst b/docs/docsite/rst/porting_guides/porting_guide_core_2.19.rst index 872acd46b1..4d60fad9dc 100644 --- a/docs/docsite/rst/porting_guides/porting_guide_core_2.19.rst +++ b/docs/docsite/rst/porting_guides/porting_guide_core_2.19.rst @@ -59,7 +59,9 @@ An explicit predicate with a boolean result, such as ``| length > 0`` or ``is tr - assert: that: inventory_hostname -The error reported is:: +The error reported is: + +.. code-block:: text Conditional result was 'localhost' of type 'str', which evaluates to True. Conditionals must have a boolean result. @@ -84,7 +86,9 @@ The quoted part becomes the expression result (evaluated as truthy), so the expr that: inventory_hostname is defined and 'inventory_hostname | length > 0' -The error reported is:: +The error reported is: + +.. code-block:: text Conditional result was 'inventory_hostname | length > 0' of type 'str', which evaluates to True. Conditionals must have a boolean result. @@ -109,7 +113,9 @@ Previous Ansible releases could mask some expression syntax errors as a truthy r # ^ invalid comma -The error reported is:: +The error reported is: + +.. code-block:: text Syntax error in expression: chunk after expression @@ -129,7 +135,9 @@ The result is always a non-empty string, which is truthy. that: inventory_hostname is contains "local" ~ "host" -The error reported is:: +The error reported is: + +.. code-block:: text Conditional result was 'Truehost' of type 'str', which evaluates to True. Conditionals must have a boolean result. @@ -156,7 +164,9 @@ Non-empty mappings are always truthy. - result.msg == "some_key: some_value" # ^^ colon+space == problem -The error reported is:: +The error reported is: + +.. code-block:: text Conditional expressions must be strings. @@ -190,7 +200,9 @@ This conditional references a variable using a template instead of using the var value: 1 -The error reported is:: +The error reported is: + +.. code-block:: text Syntax error in expression. Template delimiters are not supported in expressions: expected token ':', got '}' @@ -220,7 +232,9 @@ which was later evaluated by the ``assert`` action. comparison: == -The error reported is:: +The error reported is: + +.. code-block:: text Syntax error in expression. Template delimiters are not supported in expressions: chunk after expression @@ -556,7 +570,9 @@ location of the expression that accessed it. ) -When accessing the `color_name` from the module result, the following warning will be shown:: +When accessing the `color_name` from the module result, the following warning will be shown + +.. code-block:: text [DEPRECATION WARNING]: The `color_name` return value is deprecated. This feature will be removed from the 'ns.collection.paint' module in a future release. Origin: /examples/use_deprecated.yml:8:14 From 19a82d83bf1e2c9c65e2d58495d941a83afd98dd Mon Sep 17 00:00:00 2001 From: Felix Fontein Date: Sun, 13 Jul 2025 12:04:40 +0200 Subject: [PATCH 2/2] Adjust checker to catch such code blocks as well. --- tests/checkers/rst-yamllint.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/tests/checkers/rst-yamllint.py b/tests/checkers/rst-yamllint.py index 45eef97536..eeea59c511 100644 --- a/tests/checkers/rst-yamllint.py +++ b/tests/checkers/rst-yamllint.py @@ -115,6 +115,20 @@ def visit_literal_block(self, node: nodes.literal_block) -> None: ), } ) + else: + allowed_languages = ", ".join(sorted(ALLOWED_LANGUAGES)) + self.__results.append( + { + "path": self.__path, + "line": node.line or "unknown", + "col": 0, + "message": ( + "Warning: literal block (check for double colons '::')." + " Please convert this to a regular code block with an appropriate language." + f" Allowed languages: {allowed_languages}" + ), + } + ) raise nodes.SkipNode language = node.attributes["ansible-code-language"]