Merge "Allow comments in variable files to be rendered in docs"
This commit is contained in:
commit
fb29b03c1f
@ -6,4 +6,5 @@ sphinxcontrib-apidoc>=0.2.0 # BSD License
|
|||||||
sphinxcontrib-svg2pdfconverter>=1.1.1 # BSD License
|
sphinxcontrib-svg2pdfconverter>=1.1.1 # BSD License
|
||||||
doc8>=0.8.0 # Apache-2.0
|
doc8>=0.8.0 # Apache-2.0
|
||||||
bashate>=0.6.0 # Apache-2.0
|
bashate>=0.6.0 # Apache-2.0
|
||||||
|
ruamel.yaml>=0.15.5 # MIT
|
||||||
six>=1.11.0 # MIT
|
six>=1.11.0 # MIT
|
||||||
|
@ -26,6 +26,7 @@ from docutils.writers.html4css1 import Writer
|
|||||||
from sphinx import addnodes
|
from sphinx import addnodes
|
||||||
|
|
||||||
import yaml
|
import yaml
|
||||||
|
from ruamel.yaml import YAML as RYAML
|
||||||
|
|
||||||
try:
|
try:
|
||||||
import io
|
import io
|
||||||
@ -34,17 +35,14 @@ except ImportError:
|
|||||||
import StringIO
|
import StringIO
|
||||||
|
|
||||||
|
|
||||||
class DocYaml:
|
class DocYaml(RYAML):
|
||||||
"""
|
|
||||||
Wrapper clas around calls to yaml lib.
|
|
||||||
"""
|
|
||||||
def _license_filter(self, data):
|
def _license_filter(self, data):
|
||||||
"""This will filter out our boilerplate license heading in return data.
|
"""This will filter out our boilerplate license heading in return data.
|
||||||
|
|
||||||
The filter is used to allow documentation we're creating in variable
|
The filter is used to allow documentation we're creating in variable
|
||||||
files to be rendered more beautifully.
|
files to be rendered more beautifully.
|
||||||
"""
|
"""
|
||||||
lines = []
|
lines = list()
|
||||||
mark = True
|
mark = True
|
||||||
for line in data.splitlines():
|
for line in data.splitlines():
|
||||||
if '# Copyright' in line:
|
if '# Copyright' in line:
|
||||||
@ -59,15 +57,14 @@ class DocYaml:
|
|||||||
if not stream:
|
if not stream:
|
||||||
stream = StringIO()
|
stream = StringIO()
|
||||||
try:
|
try:
|
||||||
yaml.dump(data=data, stream=stream, Dumper=yaml.Dumper, **kw)
|
RYAML.dump(self, data, stream, **kw)
|
||||||
return self._license_filter(stream.getvalue().strip())
|
return self._license_filter(stream.getvalue().strip())
|
||||||
finally:
|
finally:
|
||||||
stream.close()
|
stream.close()
|
||||||
|
|
||||||
def load(self, data):
|
|
||||||
return yaml.load(data, Loader=yaml.Loader)
|
|
||||||
|
|
||||||
DOCYAML = DocYaml()
|
DOCYAML = DocYaml()
|
||||||
|
DOCYAML.default_flow_style = False
|
||||||
|
|
||||||
|
|
||||||
class AnsibleAutoPluginDirective(Directive):
|
class AnsibleAutoPluginDirective(Directive):
|
||||||
@ -208,28 +205,37 @@ class AnsibleAutoPluginDirective(Directive):
|
|||||||
|
|
||||||
def _run_role(self, role):
|
def _run_role(self, role):
|
||||||
section = self._section_block(
|
section = self._section_block(
|
||||||
title='Role Documentation',
|
title="Role Documentation",
|
||||||
text='Welcome to the "{}" role documentation.'.format(
|
text="Welcome to the '{}' role documentation.".format(
|
||||||
os.path.basename(role)
|
os.path.basename(role)
|
||||||
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
molecule_defaults = None
|
||||||
|
abspath_role = os.path.dirname(os.path.abspath(role))
|
||||||
|
molecule_shared_file = os.path.join(
|
||||||
|
os.path.dirname(abspath_role), "../.config/molecule/config.yml"
|
||||||
)
|
)
|
||||||
defaults_file = os.path.join(role, 'defaults', 'main.yml')
|
|
||||||
|
if os.path.exists(molecule_shared_file):
|
||||||
|
with open(molecule_shared_file) as msf:
|
||||||
|
molecule_defaults = DOCYAML.load(msf.read())
|
||||||
|
|
||||||
|
defaults_file = os.path.join(role, "defaults", "main.yml")
|
||||||
if os.path.exists(defaults_file):
|
if os.path.exists(defaults_file):
|
||||||
with open(defaults_file) as f:
|
with open(defaults_file) as f:
|
||||||
role_defaults = DOCYAML.load(f.read())
|
role_defaults = DOCYAML.load(f.read())
|
||||||
section.append(
|
section.append(
|
||||||
self._yaml_section(
|
self._yaml_section(
|
||||||
to_yaml_data=role_defaults,
|
to_yaml_data=role_defaults,
|
||||||
section_title='Role Defaults',
|
section_title="Role Defaults",
|
||||||
section_text='This section highlights all of the defaults'
|
section_text="This section highlights all of the defaults"
|
||||||
' and variables set within the "{}"'
|
" and variables set within the '{}'"
|
||||||
' role.'.format(
|
" role.".format(os.path.basename(role)),
|
||||||
os.path.basename(role)
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
vars_path = os.path.join(role, 'vars')
|
vars_path = os.path.join(role, "vars")
|
||||||
if os.path.exists(vars_path):
|
if os.path.exists(vars_path):
|
||||||
for v_file in os.listdir(vars_path):
|
for v_file in os.listdir(vars_path):
|
||||||
vars_file = os.path.join(vars_path, v_file)
|
vars_file = os.path.join(vars_path, v_file)
|
||||||
@ -238,81 +244,96 @@ class AnsibleAutoPluginDirective(Directive):
|
|||||||
section.append(
|
section.append(
|
||||||
self._yaml_section(
|
self._yaml_section(
|
||||||
to_yaml_data=vars_values,
|
to_yaml_data=vars_values,
|
||||||
section_title='Role Variables: {}'.format(v_file)
|
section_title="Role Variables: {}".format(v_file),
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
test_list = nodes.field_list()
|
test_list = nodes.field_list()
|
||||||
test_section = self._section_block(
|
test_section = self._section_block(
|
||||||
title='Molecule Scenarios',
|
title="Molecule Scenarios",
|
||||||
text='Molecule is being used to test the "{}" role. The'
|
text="Molecule is being used to test the '{}' role. The"
|
||||||
' following section highlights the drivers in service'
|
" following section highlights the drivers in service"
|
||||||
' and provides an example playbook showing how the role'
|
" and provides an example playbook showing how the role"
|
||||||
' is leveraged.'.format(
|
" is leveraged.".format(os.path.basename(role)),
|
||||||
os.path.basename(role)
|
|
||||||
)
|
)
|
||||||
)
|
|
||||||
molecule_path = os.path.join(role, 'molecule')
|
molecule_path = os.path.join(role, "molecule")
|
||||||
if os.path.exists(molecule_path):
|
if os.path.exists(molecule_path):
|
||||||
for test in os.listdir(molecule_path):
|
for test in os.listdir(molecule_path):
|
||||||
molecule_section = self._section_block(
|
molecule_section = self._section_block(
|
||||||
title='Scenario: {}'.format(test)
|
title="Scenario: {}".format(test)
|
||||||
)
|
|
||||||
molecule_file = os.path.join(
|
|
||||||
molecule_path,
|
|
||||||
test,
|
|
||||||
'molecule.yml'
|
|
||||||
)
|
)
|
||||||
|
molecule_file = os.path.join(molecule_path, test, "molecule.yml")
|
||||||
|
if not os.path.exists(molecule_file):
|
||||||
|
continue
|
||||||
|
|
||||||
with open(molecule_file) as f:
|
with open(molecule_file) as f:
|
||||||
molecule_conf = DOCYAML.load(f.read())
|
molecule_conf = DOCYAML.load(f.read())
|
||||||
if molecule_conf:
|
|
||||||
driver_data = molecule_conf.get('driver')
|
# if molecule.yml file from the scenarios, we get the
|
||||||
|
# information from the molecule shared configuration file.
|
||||||
|
if not molecule_conf:
|
||||||
|
molecule_conf = molecule_defaults
|
||||||
|
|
||||||
|
# Now that we use a shared molecule configuration file, the
|
||||||
|
# molecule.yml file in the role scenarios could be empty or
|
||||||
|
# contains only overriding keys.
|
||||||
|
driver_data = molecule_conf.get('driver',
|
||||||
|
molecule_defaults.get('driver'))
|
||||||
|
|
||||||
if driver_data:
|
if driver_data:
|
||||||
molecule_section.append(
|
molecule_section.append(
|
||||||
nodes.field_name(
|
nodes.field_name(text="Driver: {}".format(driver_data["name"]))
|
||||||
text='Driver: {}'.format(
|
|
||||||
driver_data['name']
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
|
|
||||||
options = driver_data.get('options')
|
options = driver_data.get("options")
|
||||||
if options:
|
if options:
|
||||||
molecule_section.append(
|
molecule_section.append(
|
||||||
self._yaml_section(
|
self._yaml_section(
|
||||||
to_yaml_data=options,
|
to_yaml_data=options, section_title="Molecule Options"
|
||||||
section_title='Molecule Options'
|
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
provisioner_data = molecule_conf.get('provisioner')
|
platforms_data = molecule_conf.get('platforms',
|
||||||
|
molecule_defaults.get('platforms'))
|
||||||
|
|
||||||
|
if platforms_data:
|
||||||
|
molecule_section.append(
|
||||||
|
self._yaml_section(
|
||||||
|
to_yaml_data=platforms_data,
|
||||||
|
section_title="Molecule Platform(s)",
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
default_playbook = [molecule_path, test, "converge.yml"]
|
||||||
|
|
||||||
|
provisioner_data = molecule_conf.get('provisioner',
|
||||||
|
molecule_defaults.get('provisioner'))
|
||||||
|
|
||||||
if provisioner_data:
|
if provisioner_data:
|
||||||
inventory = provisioner_data.get('inventory')
|
inventory = provisioner_data.get('inventory')
|
||||||
if inventory:
|
if inventory:
|
||||||
molecule_section.append(
|
molecule_section.append(
|
||||||
self._yaml_section(
|
self._yaml_section(
|
||||||
to_yaml_data=inventory,
|
to_yaml_data=inventory,
|
||||||
section_title='Molecule Inventory'
|
section_title="Molecule Inventory",
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
molecule_playbook_path = os.path.join(
|
try:
|
||||||
molecule_path,
|
converge = provisioner_data['playbooks']['converge']
|
||||||
test,
|
default_playbook = default_playbook[:-1] + [converge]
|
||||||
'converge.yml'
|
except KeyError:
|
||||||
)
|
pass
|
||||||
if not os.path.exists(molecule_playbook_path):
|
|
||||||
molecule_playbook_path = os.path.join(
|
molecule_playbook_path = os.path.join(*default_playbook)
|
||||||
molecule_path,
|
|
||||||
test,
|
|
||||||
'playbook.yml'
|
|
||||||
)
|
|
||||||
with open(molecule_playbook_path) as f:
|
with open(molecule_playbook_path) as f:
|
||||||
molecule_playbook = DOCYAML.load(f.read())
|
molecule_playbook = DOCYAML.load(f.read())
|
||||||
molecule_section.append(
|
molecule_section.append(
|
||||||
self._yaml_section(
|
self._yaml_section(
|
||||||
to_yaml_data=molecule_playbook,
|
to_yaml_data=molecule_playbook,
|
||||||
section_title='Example {} playbook'.format(test)
|
section_title="Example {} playbook".format(test),
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
test_list.append(molecule_section)
|
test_list.append(molecule_section)
|
||||||
@ -323,21 +344,18 @@ class AnsibleAutoPluginDirective(Directive):
|
|||||||
self.run_returns.append(section)
|
self.run_returns.append(section)
|
||||||
|
|
||||||
# Document any libraries nested within the role
|
# Document any libraries nested within the role
|
||||||
library_path = os.path.join(role, 'library')
|
library_path = os.path.join(role, "library")
|
||||||
if os.path.exists(library_path):
|
if os.path.exists(library_path):
|
||||||
self.options['documentation'] = True
|
self.options['documentation'] = True
|
||||||
self.options['examples'] = True
|
self.options['examples'] = True
|
||||||
for lib in os.listdir(library_path):
|
for lib in os.listdir(library_path):
|
||||||
if lib.endswith('.py'):
|
if lib.endswith(".py"):
|
||||||
self._run_module(
|
self._run_module(
|
||||||
module=self.load_module(
|
module=self.load_module(
|
||||||
filename=os.path.join(
|
filename=os.path.join(library_path, lib)
|
||||||
library_path,
|
|
||||||
lib
|
|
||||||
)
|
|
||||||
),
|
),
|
||||||
module_title='Embedded module: {}'.format(lib),
|
module_title="Embedded module: {}".format(lib),
|
||||||
example_title='Examples for embedded module'
|
example_title="Examples for embedded module",
|
||||||
)
|
)
|
||||||
|
|
||||||
def _run_module(self, module, module_title="Module Documentation",
|
def _run_module(self, module, module_title="Module Documentation",
|
||||||
|
Loading…
Reference in New Issue
Block a user