mirror of
https://github.com/thegeeklab/ansible-doctor.git
synced 2024-11-16 10:10:39 +00:00
142 lines
6.1 KiB
Python
142 lines
6.1 KiB
Python
#!/usr/bin/env python3
|
|
|
|
import codecs
|
|
import glob
|
|
import json
|
|
import ntpath
|
|
import os
|
|
import pprint
|
|
import sys
|
|
|
|
import jinja2.exceptions
|
|
import ruamel.yaml
|
|
from jinja2 import Environment
|
|
from jinja2 import FileSystemLoader
|
|
from six import binary_type
|
|
from six import text_type
|
|
|
|
from ansibledoctor.Config import SingleConfig
|
|
from ansibledoctor.Utils import FileUtils
|
|
from ansibledoctor.Utils import SingleLog
|
|
|
|
|
|
class Generator:
|
|
def __init__(self, doc_parser):
|
|
self.template_files = []
|
|
self.extension = "j2"
|
|
self._parser = None
|
|
self.config = SingleConfig()
|
|
self.log = SingleLog()
|
|
self.log.info("Using template dir: " + self.config.get_template_base_dir())
|
|
self._parser = doc_parser
|
|
self._scan_template()
|
|
|
|
def _scan_template(self):
|
|
"""
|
|
Search for Jinja2 (.j2) files to apply to the destination.
|
|
|
|
:return: None
|
|
"""
|
|
base_dir = self.config.get_template_base_dir()
|
|
|
|
for file in glob.iglob(base_dir + "/**/*." + self.extension, recursive=True):
|
|
|
|
relative_file = file[len(base_dir) + 1:]
|
|
if ntpath.basename(file)[:1] != "_":
|
|
self.log.trace("[GENERATOR] found template file: " + relative_file)
|
|
self.template_files.append(relative_file)
|
|
else:
|
|
self.log.debug("[GENERATOR] ignoring template file: " + relative_file)
|
|
|
|
def _create_dir(self, directory):
|
|
if not self.config.dry_run:
|
|
os.makedirs(directory, exist_ok=True)
|
|
else:
|
|
self.log.info("[GENERATOR][DRY] Creating dir: " + dir)
|
|
|
|
def _write_doc(self):
|
|
files_to_overwite = []
|
|
|
|
for file in self.template_files:
|
|
doc_file = self.config.get_output_dir() + "/" + file[:-len(self.extension) - 1]
|
|
if os.path.isfile(doc_file):
|
|
files_to_overwite.append(doc_file)
|
|
|
|
if len(files_to_overwite) > 0 and self.config.template_overwrite is False:
|
|
SingleLog.print("This files will be overwritten:", files_to_overwite)
|
|
if not self.config.dry_run:
|
|
resulst = FileUtils.query_yes_no("Do you want to continue?")
|
|
if resulst != "yes":
|
|
sys.exit()
|
|
|
|
for file in self.template_files:
|
|
doc_file = self.config.get_output_dir() + "/" + file[:-len(self.extension) - 1]
|
|
source_file = self.config.get_template_base_dir() + "/" + file
|
|
|
|
self.log.trace("[GENERATOR] Writing doc output to: " + doc_file + " from: " + source_file)
|
|
|
|
# make sure the directory exists
|
|
self._create_dir(os.path.dirname(os.path.realpath(doc_file)))
|
|
|
|
if os.path.exists(source_file) and os.path.isfile(source_file):
|
|
with open(source_file, "r") as template:
|
|
data = template.read()
|
|
if data is not None:
|
|
try:
|
|
print(json.dumps(self._parser.get_data(), indent=4, sort_keys=True))
|
|
jenv = Environment(loader=FileSystemLoader(self.config.get_template_base_dir()), lstrip_blocks=True, trim_blocks=True, autoescape=True)
|
|
jenv.filters["to_nice_yaml"] = self._to_nice_yaml
|
|
data = jenv.from_string(data).render(self._parser.get_data(), role=self._parser.get_data())
|
|
if not self.config.dry_run:
|
|
with open(doc_file, "w") as outfile:
|
|
outfile.write(data)
|
|
self.log.info("Writing to: " + doc_file)
|
|
else:
|
|
self.log.info("[GENERATOR][DRY] Writing to: " + doc_file)
|
|
except jinja2.exceptions.UndefinedError as e:
|
|
self.log.error("Jinja2 templating error: <" + str(e) + "> when loading file: '" + file + "', run in debug mode to see full except")
|
|
if self.log.log_level < 1:
|
|
raise
|
|
except UnicodeEncodeError as e:
|
|
self.log.error("At the moment I'm unable to print special chars: <" + str(e) + ">, run in debug mode to see full except")
|
|
if self.log.log_level < 1:
|
|
raise
|
|
sys.exit()
|
|
|
|
def _to_nice_yaml(self, a, indent=4, *args, **kw):
|
|
"""Make verbose, human readable yaml."""
|
|
yaml = ruamel.yaml.YAML()
|
|
yaml.indent(mapping=indent, sequence=(indent * 2), offset=indent)
|
|
stream = ruamel.yaml.compat.StringIO()
|
|
yaml.dump(a, stream, **kw)
|
|
return stream.getvalue().rstrip()
|
|
|
|
def print_to_cli(self):
|
|
for file in self.template_files:
|
|
source_file = self.config.get_template_base_dir() + "/" + file
|
|
with open(source_file, "r") as template:
|
|
data = template.read()
|
|
|
|
if data is not None:
|
|
try:
|
|
data = Environment(loader=FileSystemLoader(self.config.get_template_base_dir()), lstrip_blocks=True, trim_blocks=True, autoescape=True).from_string(data).render(self._parser.get_data(), r=self._parser)
|
|
print(data)
|
|
except jinja2.exceptions.UndefinedError as e:
|
|
self.log.error("Jinja2 templating error: <" + str(e) + "> when loading file: '" + file + "', run in debug mode to see full except")
|
|
if self.log.log_level < 1:
|
|
raise
|
|
except UnicodeEncodeError as e:
|
|
self.log.error("At the moment I'm unable to print special chars: <" + str(e) + ">, run in debug mode to see full except")
|
|
if self.log.log_level < 1:
|
|
raise
|
|
except Exception:
|
|
print("Unexpected error:", sys.exc_info()[0])
|
|
raise
|
|
|
|
def render(self):
|
|
if self.config.use_print_template:
|
|
self.print_to_cli()
|
|
else:
|
|
self.log.info("Using output dir: " + self.config.get_output_dir())
|
|
self._write_doc()
|