From ea731517578f9cc0e2164786c367d7464fa60bc7 Mon Sep 17 00:00:00 2001 From: Michael DeHaan Date: Sun, 6 Oct 2013 10:23:44 -0400 Subject: [PATCH] Add automatic advice when folks hit one of two common but minor YAML gotchas, so they can be more easily correct them on their own. --- CHANGELOG.md | 3 ++- lib/ansible/utils/__init__.py | 46 +++++++++++++++++++++++++++++++++++ 2 files changed, 48 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4b15f4abca5..def8f2b963a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,9 +7,10 @@ Highlighted new features: * Added do-until feature, which can be used to retry a failed task a specified number of times with a delay in-between the retries. * (docs pending) Added failed_when option for tasks, which can be used to specify logical statements that make it easier to determine when a task has failed, or to make it easier to ignore certain non-zero return codes for some commands. -* (docs pending) Added the "subelement" lookup plugin, which allows iteration of the keys of a dictionary or items in a list. +* Added the "subelement" lookup plugin, which allows iteration of the keys of a dictionary or items in a list. * Added the capability to use either paramiko or ssh for the inital setup connection of an accelerated playbook. * (docs pending) Swap the active user on a task in the middle of a play with the 'remote_user' parameter. +* Automatically provide advice on common parser errors users encounter. New modules: diff --git a/lib/ansible/utils/__init__.py b/lib/ansible/utils/__init__.py index a8b05679b5f..d0b5d10d583 100644 --- a/lib/ansible/utils/__init__.py +++ b/lib/ansible/utils/__init__.py @@ -336,6 +336,48 @@ def parse_yaml(data): ''' convert a yaml string to a data structure ''' return smush_ds(yaml.safe_load(data)) +def process_common_errors(msg, probline, column): + replaced = probline.replace(" ","") + if replaced.find(":{{") != -1 and replaced.find("}}") != -1: + msg = msg + """ +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. + +For instance, if the original line was: + + app_path: {{ base_path }}/foo + +It should be written as: + + app_path: "{{ base_path }}/foo" +""" + + elif len(probline) and probline[column] == ":" and probline.find("=") != -1: + msg = msg + """ +This one looks easy to fix. There is 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. + +For instance, if the original line was: + + copy: src=file dest=/path/filename:with_colon.txt + +It can be written as: + + copy: src=file dest='/path/filename:with_colon.txt' + +Or: + + copy: 'src=file dest=/path/filename:with_colon.txt' + + +""" + return msg + def process_yaml_error(exc, data, path=None): if hasattr(exc, 'problem_mark'): mark = exc.problem_mark @@ -351,6 +393,10 @@ Note: The error may actually appear before this position: line %s, column %s %s %s %s""" % (path, mark.line + 1, mark.column + 1, before_probline, probline, arrow) + + msg = process_common_errors(msg, probline, mark.column) + + else: # No problem markers means we have to throw a generic # "stuff messed up" type message. Sry bud.