From c59472715aab6e528f76d9add0980da6148e92c6 Mon Sep 17 00:00:00 2001 From: Matt Martz Date: Wed, 12 Aug 2020 09:17:45 -0500 Subject: [PATCH] Add support for non-yaml EXAMPLES (#71184) * Add support for non-yaml EXAMPLES * Make pattern raw string * fmt tag should be the first non-whitespace line * Add changelog fragment --- .../71184-allow-non-yaml-examples.yml | 4 + lib/ansible/plugins/inventory/ini.py | 64 ++++++----- lib/ansible/plugins/inventory/toml.py | 105 +++++++++--------- .../_data/sanity/yamllint/yamllinter.py | 15 ++- 4 files changed, 101 insertions(+), 87 deletions(-) create mode 100644 changelogs/fragments/71184-allow-non-yaml-examples.yml diff --git a/changelogs/fragments/71184-allow-non-yaml-examples.yml b/changelogs/fragments/71184-allow-non-yaml-examples.yml new file mode 100644 index 00000000000..2fd9450557d --- /dev/null +++ b/changelogs/fragments/71184-allow-non-yaml-examples.yml @@ -0,0 +1,4 @@ +minor_changes: +- plugin examples - Allow non-YAML examples, so that examples for + plugins like the INI and TOML inventory plugins can be directly + represented (https://github.com/ansible/ansible/pull/71184) diff --git a/lib/ansible/plugins/inventory/ini.py b/lib/ansible/plugins/inventory/ini.py index 2175f421bac..366171ea435 100644 --- a/lib/ansible/plugins/inventory/ini.py +++ b/lib/ansible/plugins/inventory/ini.py @@ -29,49 +29,47 @@ DOCUMENTATION = ''' The YAML inventory plugin processes variable values consistently and correctly. ''' -EXAMPLES = ''' - example1: | - # example cfg file - [web] - host1 - host2 ansible_port=222 # defined inline, interpreted as an integer +EXAMPLES = '''# fmt: ini +# Example 1 +[web] +host1 +host2 ansible_port=222 # defined inline, interpreted as an integer - [web:vars] - http_port=8080 # all members of 'web' will inherit these - myvar=23 # defined in a :vars section, interpreted as a string +[web:vars] +http_port=8080 # all members of 'web' will inherit these +myvar=23 # defined in a :vars section, interpreted as a string - [web:children] # child groups will automatically add their hosts to parent group - apache - nginx +[web:children] # child groups will automatically add their hosts to parent group +apache +nginx - [apache] - tomcat1 - tomcat2 myvar=34 # host specific vars override group vars - tomcat3 mysecret="'03#pa33w0rd'" # proper quoting to prevent value changes +[apache] +tomcat1 +tomcat2 myvar=34 # host specific vars override group vars +tomcat3 mysecret="'03#pa33w0rd'" # proper quoting to prevent value changes - [nginx] - jenkins1 +[nginx] +jenkins1 - [nginx:vars] - has_java = True # vars in child groups override same in parent +[nginx:vars] +has_java = True # vars in child groups override same in parent - [all:vars] - has_java = False # 'all' is 'top' parent +[all:vars] +has_java = False # 'all' is 'top' parent - example2: | - # other example config - host1 # this is 'ungrouped' +# Example 2 +host1 # this is 'ungrouped' - # both hosts have same IP but diff ports, also 'ungrouped' - host2 ansible_host=127.0.0.1 ansible_port=44 - host3 ansible_host=127.0.0.1 ansible_port=45 +# both hosts have same IP but diff ports, also 'ungrouped' +host2 ansible_host=127.0.0.1 ansible_port=44 +host3 ansible_host=127.0.0.1 ansible_port=45 - [g1] - host4 +[g1] +host4 - [g2] - host4 # same host as above, but member of 2 groups, will inherit vars from both - # inventory hostnames are unique +[g2] +host4 # same host as above, but member of 2 groups, will inherit vars from both + # inventory hostnames are unique ''' import ast diff --git a/lib/ansible/plugins/inventory/toml.py b/lib/ansible/plugins/inventory/toml.py index ca4ca036eb6..5d7ce314085 100644 --- a/lib/ansible/plugins/inventory/toml.py +++ b/lib/ansible/plugins/inventory/toml.py @@ -15,76 +15,75 @@ DOCUMENTATION = r''' - Requires the 'toml' python library ''' -EXAMPLES = r''' -# Following are examples of 3 different inventories in TOML format -example1: | - [all.vars] - has_java = false +EXAMPLES = r'''# fmt: toml +# Example 1 +[all.vars] +has_java = false - [web] - children = [ - "apache", - "nginx" - ] - vars = { http_port = 8080, myvar = 23 } +[web] +children = [ + "apache", + "nginx" +] +vars = { http_port = 8080, myvar = 23 } - [web.hosts] - host1 = {} - host2 = { ansible_port = 222 } +[web.hosts] +host1 = {} +host2 = { ansible_port = 222 } - [apache.hosts] - tomcat1 = {} - tomcat2 = { myvar = 34 } - tomcat3 = { mysecret = "03#pa33w0rd" } +[apache.hosts] +tomcat1 = {} +tomcat2 = { myvar = 34 } +tomcat3 = { mysecret = "03#pa33w0rd" } - [nginx.hosts] - jenkins1 = {} +[nginx.hosts] +jenkins1 = {} - [nginx.vars] - has_java = true +[nginx.vars] +has_java = true -example2: | - [all.vars] - has_java = false +# Example 2 +[all.vars] +has_java = false - [web] - children = [ - "apache", - "nginx" - ] +[web] +children = [ + "apache", + "nginx" +] - [web.vars] - http_port = 8080 - myvar = 23 +[web.vars] +http_port = 8080 +myvar = 23 - [web.hosts.host1] - [web.hosts.host2] - ansible_port = 222 +[web.hosts.host1] +[web.hosts.host2] +ansible_port = 222 - [apache.hosts.tomcat1] +[apache.hosts.tomcat1] - [apache.hosts.tomcat2] - myvar = 34 +[apache.hosts.tomcat2] +myvar = 34 - [apache.hosts.tomcat3] - mysecret = "03#pa33w0rd" +[apache.hosts.tomcat3] +mysecret = "03#pa33w0rd" - [nginx.hosts.jenkins1] +[nginx.hosts.jenkins1] - [nginx.vars] - has_java = true +[nginx.vars] +has_java = true -example3: | - [ungrouped.hosts] - host1 = {} - host2 = { ansible_host = "127.0.0.1", ansible_port = 44 } - host3 = { ansible_host = "127.0.0.1", ansible_port = 45 } +# Example 3 +[ungrouped.hosts] +host1 = {} +host2 = { ansible_host = "127.0.0.1", ansible_port = 44 } +host3 = { ansible_host = "127.0.0.1", ansible_port = 45 } - [g1.hosts] - host4 = {} +[g1.hosts] +host4 = {} - [g2.hosts] - host4 = {} +[g2.hosts] +host4 = {} ''' import os diff --git a/test/lib/ansible_test/_data/sanity/yamllint/yamllinter.py b/test/lib/ansible_test/_data/sanity/yamllint/yamllinter.py index 933debe707a..ca21cfcbd82 100644 --- a/test/lib/ansible_test/_data/sanity/yamllint/yamllinter.py +++ b/test/lib/ansible_test/_data/sanity/yamllint/yamllinter.py @@ -6,6 +6,7 @@ __metaclass__ = type import ast import json import os +import re import sys import yaml @@ -114,6 +115,10 @@ class YamlChecker: for key, value in docs.items(): yaml_data = value['yaml'] lineno = value['lineno'] + fmt = value['fmt'] + + if fmt != 'yaml': + continue if yaml_data.startswith('\n'): yaml_data = yaml_data[1:] @@ -177,6 +182,8 @@ class YamlChecker: docs = {} + fmt_re = re.compile(r'^# fmt:\s+(\S+)') + def check_assignment(statement, doc_types=None): """Check the given statement for a documentation assignment.""" for target in statement.targets: @@ -186,10 +193,16 @@ class YamlChecker: if doc_types and target.id not in doc_types: continue + fmt_match = fmt_re.match(statement.value.s.lstrip()) + fmt = 'yaml' + if fmt_match: + fmt = fmt_match.group(1) + docs[target.id] = dict( yaml=statement.value.s, lineno=statement.lineno, - end_lineno=statement.lineno + len(statement.value.s.splitlines()) + end_lineno=statement.lineno + len(statement.value.s.splitlines()), + fmt=fmt.lower(), ) module_ast = self.parse_module(path, contents)