diff options
author | Sam Doran <sdoran@redhat.com> | 2018-12-04 12:32:02 -0500 |
---|---|---|
committer | ansibot <ansibot@users.noreply.github.com> | 2018-12-04 12:32:02 -0500 |
commit | 40a5f7bfdfa3371ecd97212bba9e4baf00a2652b (patch) | |
tree | 2d1557b80f8cbcd7b9f7f1b7d93c5d1cc19de673 /lib/ansible/errors | |
parent | 2f8d235ce552cf8c8dee88e50fe6bf441d1192f5 (diff) | |
download | ansible-40a5f7bfdfa3371ecd97212bba9e4baf00a2652b.tar.gz |
Add better error when k=v syntax is used with YAML in tasks (#41754)
* Add error message for k=v and YAML in a single task
Find the correct line, column, and position for k=v errors since they are different than the position reported initially.
Document bug in quoting syntax check.
* Change tense or error message
Since the error still exists, switch to present tense rather than past tense.
* Remove double spaces after periods in error messages.
http://www.slate.com/articles/technology/technology/2011/01/space_invaders.html
* Add changelog fragment
* Add tests for new error message
* Fix tests
* Add clarifying comments to unit test
Diffstat (limited to 'lib/ansible/errors')
-rw-r--r-- | lib/ansible/errors/__init__.py | 22 | ||||
-rw-r--r-- | lib/ansible/errors/yaml_strings.py | 27 |
2 files changed, 34 insertions, 15 deletions
diff --git a/lib/ansible/errors/__init__.py b/lib/ansible/errors/__init__.py index 8de1834dbe..5b20c276dd 100644 --- a/lib/ansible/errors/__init__.py +++ b/lib/ansible/errors/__init__.py @@ -19,8 +19,9 @@ from __future__ import (absolute_import, division, print_function) __metaclass__ = type -import traceback +import re import sys +import traceback from ansible.errors.yaml_strings import ( YAML_COMMON_DICT_ERROR, @@ -30,6 +31,7 @@ from ansible.errors.yaml_strings import ( YAML_COMMON_UNQUOTED_COLON_ERROR, YAML_COMMON_UNQUOTED_VARIABLE_ERROR, YAML_POSITION_DETAILS, + YAML_AND_SHORTHAND_ERROR, ) from ansible.module_utils._text import to_native, to_text from ansible.module_utils.common._collections_compat import Sequence @@ -120,9 +122,18 @@ class AnsibleError(Exception): prev_line = to_text(prev_line) if target_line: stripped_line = target_line.replace(" ", "") - arrow_line = (" " * (col_number - 1)) + "^ here" - # header_line = ("=" * 73) - error_message += "\nThe offending line appears to be:\n\n%s\n%s\n%s\n" % (prev_line.rstrip(), target_line.rstrip(), arrow_line) + + # Check for k=v syntax in addition to YAML syntax and set the appropriate error position, + # arrow index + if re.search(r'\w+(\s+)?=(\s+)?[\w/-]+', prev_line): + error_position = prev_line.rstrip().find('=') + arrow_line = (" " * error_position) + "^ here" + error_message = YAML_POSITION_DETAILS % (src_file, line_number - 1, error_position + 1) + error_message += "\nThe offending line appears to be:\n\n%s\n%s\n\n" % (prev_line.rstrip(), arrow_line) + error_message += YAML_AND_SHORTHAND_ERROR + else: + arrow_line = (" " * (col_number - 1)) + "^ here" + error_message += "\nThe offending line appears to be:\n\n%s\n%s\n%s\n" % (prev_line.rstrip(), target_line.rstrip(), arrow_line) # TODO: There may be cases where there is a valid tab in a line that has other errors. if '\t' in target_line: @@ -143,6 +154,9 @@ class AnsibleError(Exception): error_message += YAML_COMMON_UNQUOTED_COLON_ERROR # otherwise, check for some common quoting mistakes else: + # FIXME: This needs to split on the first ':' to account for modules like lineinfile + # that may have lines that contain legitimate colons, e.g., line: 'i ALL= (ALL) NOPASSWD: ALL' + # and throw off the quote matching logic. parts = target_line.split(":") if len(parts) > 1: middle = parts[1].strip() diff --git a/lib/ansible/errors/yaml_strings.py b/lib/ansible/errors/yaml_strings.py index ed574eb99e..e10a3f9d91 100644 --- a/lib/ansible/errors/yaml_strings.py +++ b/lib/ansible/errors/yaml_strings.py @@ -9,11 +9,11 @@ # # Ansible 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 +# 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 Ansible. If not, see <http://www.gnu.org/licenses/>. +# along with Ansible. If not, see <http://www.gnu.org/licenses/>. # Make coding more python3-ish from __future__ import (absolute_import, division, print_function) @@ -34,13 +34,13 @@ Syntax Error while loading YAML. %s""" YAML_POSITION_DETAILS = """\ -The error appears to have been in '%s': line %s, column %s, but may +The error appears to be in '%s': line %s, column %s, but may be elsewhere in the file depending on the exact syntax problem. """ YAML_COMMON_DICT_ERROR = """\ -This one looks easy to fix. YAML thought it was looking for the start of a -hash/dictionary and was confused to see a second "{". Most likely this was +This one looks easy to fix. YAML thought it was looking for the start of a +hash/dictionary and was confused to see a second "{". Most likely this was meant to be an ansible template evaluation instead, so we have to give the parser a small hint that we wanted a string instead. The solution here is to just quote the entire value. @@ -56,7 +56,7 @@ It should be written as: YAML_COMMON_UNQUOTED_VARIABLE_ERROR = """\ We could be wrong, but this one looks like it might be an issue with -missing quotes. Always quote template expression brackets when they +missing quotes. Always quote template expression brackets when they start a value. For instance: with_items: @@ -69,7 +69,7 @@ Should be written as: """ YAML_COMMON_UNQUOTED_COLON_ERROR = """\ -This one looks easy to fix. There seems to be an extra unquoted colon in the line +This one looks easy to fix. There seems to be an extra unquoted colon in the line and this is confusing the parser. It was only expecting to find one free colon. The solution is just add some quotes around the colon, or quote the entire line after the first colon. @@ -88,9 +88,9 @@ Or: """ YAML_COMMON_PARTIALLY_QUOTED_LINE_ERROR = """\ -This one looks easy to fix. It seems that there is a value started +This one looks easy to fix. It seems that there is a value started with a quote, and the YAML parser is expecting to see the line ended -with the same kind of quote. For instance: +with the same kind of quote. For instance: when: "ok" in result.stdout @@ -105,8 +105,8 @@ Or equivalently: YAML_COMMON_UNBALANCED_QUOTES_ERROR = """\ We could be wrong, but this one looks like it might be an issue with -unbalanced quotes. If starting a value with a quote, make sure the -line ends with the same set of quotes. For instance this arbitrary +unbalanced quotes. If starting a value with a quote, make sure the +line ends with the same set of quotes. For instance this arbitrary example: foo: "bad" "wolf" @@ -133,3 +133,8 @@ Should be written as: version: 1.2.3 # ^--- all spaces here. """ + +YAML_AND_SHORTHAND_ERROR = """\ +There appears to be both 'k=v' shorthand syntax and YAML in this task. \ +Only one syntax may be used. +""" |