feat: merge all documentation functionality, leverage __doc__ for Pulumi modules
ZeroDownTime/CloudBender/pipeline/head This commit looks good Details

This commit is contained in:
Stefan Reimer 2022-06-30 17:42:49 +02:00
parent ac51a0774a
commit adc92bf24a
3 changed files with 121 additions and 105 deletions

View File

@ -26,11 +26,11 @@ clean:
pybuild:
hatchling build
test_upload: $(PACKAGE_FILE)
twine upload --repository-url https://test.pypi.org/legacy/ dist/cloudbender-*.whl
test_upload: pybuild
twine upload --repository-url https://test.pypi.org/legacy/ --non-interactive dist/cloudbender-*.whl
upload: $(PACKAGE_FILE)
twine upload --repository-url https://upload.pypi.org/legacy/ dist/cloudbender-*.whl
upload: pybuild
twine upload -r pypi --non-interactive dist/cloudbender-*.whl
build:
podman build --rm -t $(REPOSITORY):$(TAG) -t $(REPOSITORY):latest .

View File

@ -145,12 +145,12 @@ def outputs(cb, stack_names, multi, include, values):
@click.option("--multi", is_flag=True, help="Allow more than one stack to match")
@click.option("--graph", is_flag=True, help="Create Dot Graph file")
@click.pass_obj
def create_docs(cb, stack_names, multi, graph):
"""Parses all documentation fragments out of rendered templates creating docs/*.md file"""
def docs(cb, stack_names, multi, graph):
"""Outputs docs for stack(s). For Pulumi stacks prints out docstring. For CloudFormation templates render a markdown file. Same idea as helm-docs."""
stacks = _find_stacks(cb, stack_names, multi)
for s in stacks:
s.create_docs(graph=graph)
s.docs(graph=graph)
@click.command()
@ -183,19 +183,14 @@ def refresh(cb, stack_name):
@click.argument("stack_name")
@click.argument("function", default="")
@click.argument("args", nargs=-1)
@click.option(
"--listall",
is_flag=True,
help="List all available execute functions for this stack",
)
@click.pass_obj
def execute(cb, stack_name, function, args, listall=False):
def execute(cb, stack_name, function, args):
"""Executes custom Python function within an existing stack context"""
stacks = _find_stacks(cb, [stack_name])
for s in stacks:
if s.mode == "pulumi":
s.execute(function, args, listall)
s.execute(function, args)
else:
logger.info(
"{} uses Cloudformation, no exec feature available.".format(s.stackname)
@ -455,7 +450,7 @@ cli.add_command(delete)
cli.add_command(clean)
cli.add_command(create_change_set)
cli.add_command(outputs)
cli.add_command(create_docs)
cli.add_command(docs)
cli.add_command(refresh)
cli.add_command(preview)
cli.add_command(set_config)

View File

@ -574,12 +574,31 @@ class Stack(object):
)
)
def create_docs(self, template=False, graph=False):
@pulumi_ws
def docs(self, template=False, graph=False):
"""Read rendered template, parse documentation fragments, eg. parameter description
and create a mardown doc file for the stack
same idea as eg. helm-docs for values.yaml
and create a mardown doc file for the stack. Same idea as helm-docs for the values.yaml
"""
if self.mode == "pulumi":
if vars(self._pulumi_code)["__doc__"]:
print(vars(self._pulumi_code)["__doc__"])
else:
print("No template documentation found.")
# collect all __doc__ from available _execute_ functions
_help = ""
for k in vars(self._pulumi_code).keys():
if k.startswith("_execute_"):
docstring = vars(self._pulumi_code)[k].__doc__
_help = _help + "## {}\n{}\n".format(
k.lstrip("_execute_"), docstring
)
if _help:
print(f"# Available `execute` functions: \n\n{_help}")
else:
try:
self.read_template_file()
except FileNotFoundError:
@ -627,7 +646,9 @@ class Stack(object):
with open(doc_file, "w") as doc_contents:
doc_contents.write(template.render(**data))
logger.info("Wrote documentation for %s to %s", self.stackname, doc_file)
logger.info(
"Wrote documentation for %s to %s", self.stackname, doc_file
)
# Write Graph in Dot format
if graph:
@ -636,9 +657,15 @@ class Stack(object):
)
lint_args = ["--template", filename]
(args, filenames, formatter) = cfnlint.core.get_args_filenames(lint_args)
(template, rules, matches) = cfnlint.core.get_template_rules(filename, args)
template_obj = cfnlint.template.Template(filename, template, [self.region])
(args, filenames, formatter) = cfnlint.core.get_args_filenames(
lint_args
)
(template, rules, matches) = cfnlint.core.get_template_rules(
filename, args
)
template_obj = cfnlint.template.Template(
filename, template, [self.region]
)
path = os.path.join(
self.ctx["docs_path"], self.rel_path, self.stackname + ".dot"
@ -867,18 +894,14 @@ class Stack(object):
return
@pulumi_ws
def execute(self, function, args, listall=False):
"""Executes custom Python function within a Pulumi stack"""
def execute(self, function, args):
"""
Executes custom Python function within a Pulumi stack
# call all available functions and output built in help
if listall:
for k in vars(self._pulumi_code).keys():
if k.startswith("_execute_"):
docstring = vars(self._pulumi_code)[k](docstring=True)
print("{}: {}".format(k.lstrip("_execute_"), docstring))
return
These functions are executed within the stack environment and are provided with all stack input parameters as well as current outputs.
Think of "docker exec" into an existing container...
else:
"""
if not function:
logger.error("No function specified !")
return
@ -893,9 +916,7 @@ class Stack(object):
)
else:
logger.error(
"{} is not defined in {}".format(function, self._pulumi_code)
)
logger.error("{} is not defined in {}".format(function, self._pulumi_code))
@pulumi_ws
def assimilate(self):