Skip to content
This repository was archived by the owner on Dec 10, 2024. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions frigate/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,10 @@ def cli():
@click.option(
"--no-deps", is_flag=True, default=True, help="Do not render dependency values",
)
def gen(filename, output_format, no_credits, no_deps):
@click.option(
"--no-update", is_flag=True, default=True, help="Do not update the charts",
)
def gen(filename, output_format, no_credits, no_deps, no_update):
click.echo(
frigate.gen.gen(filename, output_format, credits=no_credits, deps=no_deps)
frigate.gen.gen(filename, output_format, credits=no_credits, deps=no_deps, update=no_update)
)
54 changes: 48 additions & 6 deletions frigate/gen.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
import tempfile
import shutil
import subprocess

import datetime
from json import JSONEncoder
from jinja2 import Environment, FileSystemLoader
from ruamel.yaml import YAML
from ruamel.yaml.comments import CommentedMap
Expand Down Expand Up @@ -36,6 +37,36 @@ def load_chart(chartdir, root=None):
return chart, list(traverse(values, root=root))


def load_prepacked_chart_with_dependencies(chartdir, root=None):
root = [] if root is None else root
chart, values = load_chart(chartdir, root=root)
if "dependencies" in chart:
for dependency in chart["dependencies"]:
dependency_name = dependency["name"]

with tempfile.TemporaryDirectory() as tmpdirname:
tar_file_path = os.path.join(
chartdir, "charts", f"{dependency_name}-{dependency['version']}.tgz",
)
if os.path.isfile(tar_file_path):
dependency_path = tar_file_path
shutil.unpack_archive(dependency_path, tmpdirname)
dependency_dir = os.path.join(tmpdirname, dependency_name)
else:
dependency_path = os.path.join(
chartdir, "charts", f"{dependency_name}",
)
dependency_dir = os.path.join(chartdir, dependency_path)
# chart namespace eg nginx.controller.foo
namespace = root + [dependency_name]

_, dependency_values = load_prepacked_chart_with_dependencies(
dependency_dir, namespace
)
values = squash_duplicate_values(values + dependency_values)
return chart, values


def load_chart_with_dependencies(chartdir, root=None):
"""Load the yaml information from a Helm chart directory and its dependencies.

Expand Down Expand Up @@ -184,6 +215,12 @@ def clean_comment(comment):
return comment.strip("# ")


class DateTimeEncoder(JSONEncoder):
def default(self, obj):
if isinstance(obj, (datetime.date, datetime.datetime)):
return obj.isoformat()


def traverse(tree, root=None):
"""Iterate over a tree of configuration and extract all information.

Expand Down Expand Up @@ -230,10 +267,10 @@ def traverse(tree, root=None):
if key in tree.ca.items:
comment = get_comment(tree, key)
param = ".".join(root + [key])
yield [param, comment, json.dumps(default)]
yield [param, comment, json.dumps(default, indent=4, sort_keys=True, cls=DateTimeEncoder)]


def gen(chartdir, output_format, credits=True, deps=True):
def gen(chartdir, output_format, credits=True, deps=True, update=True):
"""Generate documentation for a Helm chart.

Generate documentation for a Helm chart given the path to a chart and a
Expand All @@ -244,14 +281,19 @@ def gen(chartdir, output_format, credits=True, deps=True):
output_format (str): Output format (maps to jinja templates in frigate)
credits (bool): Show Frigate credits in documentation
deps (bool): Read values from chart dependencies and include them in the config table
update (bool): If false, frigate won't update the charts at runtime

Returns:
str: Rendered documentation for the Helm chart

"""
chart, values = (
load_chart_with_dependencies(chartdir) if deps else load_chart(chartdir)
)
if deps:
if update:
chart, values = load_chart_with_dependencies(chartdir)
else:
chart, values = load_prepacked_chart_with_dependencies(chartdir)
else:
chart, values = load_chart(chartdir)

templates = Environment(loader=FileSystemLoader([chartdir, TEMPLATES_PATH]))
if os.path.isfile(os.path.join(chartdir, DOTFILE_NAME)):
Expand Down
2 changes: 1 addition & 1 deletion frigate/templates/html.jinja2
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@
<tr>
<td><code>{{ param }}</code></td>
<td>{{ comment }}</td>
<td><code>{{ default }}</code></td>
<td><pre>{{ default }}</pre></td>
</tr>
{% endfor -%}
</table>
Expand Down
35 changes: 29 additions & 6 deletions frigate/templates/markdown.jinja2
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,37 @@
## Configuration

The following table lists the configurable parameters of the {{ name | capitalize }} chart and their default values.

| Parameter | Description | Default |
| ------------------------ | ----------------------- | -------------- |
<table>
<thead>
<tr>
<th>Parameter</th>
<th>Description</th>
<th>Default</th>
</tr>
</thead>
<tbody>
{% for (param, comment, default) in values -%}
| `{{ param }}` | {{ comment }} | `{{ default }}` |
<tr>
<td>{{ param }}</td>
<td>{{ comment }}</td>
<td>
{% if "\n" in default %}

```json

{{ default }}

```

{% else %}
{{ default }}
{% endif %}
</td>
</tr>
{% endfor -%}
</tbody>
</table>
{%- endblock %}

{% block footnotes -%}
{{ footnotes }}
{% endblock -%}
Expand All @@ -32,4 +55,4 @@ The following table lists the configurable parameters of the {{ name | capitaliz
---
_Documentation generated by [Frigate](https://frigate.readthedocs.io)._
{%- endif -%}
{%- endblock %}
{%- endblock %}
13 changes: 10 additions & 3 deletions frigate/tests/test_frigate.py
Original file line number Diff line number Diff line change
Expand Up @@ -150,9 +150,8 @@ def test_deps(deps_chart_path):

docs = gen(deps_chart_path, "markdown")

assert "simple.image.repository" in docs
[tag_line] = [line for line in docs.splitlines() if "simple.image.tag" in line]
assert "mainline" in tag_line
assert "<td>simple.image.repository</td>" in docs
assert "<td>\n\n\"mainline\"\n\n</td>" in docs


def test_squash_duplicates():
Expand All @@ -162,3 +161,11 @@ def test_squash_duplicates():

assert len(values) == 1
assert values[0][2] == "world"


def test_load_pre_packaged_chart(deps_chart_path):
from frigate.gen import gen

docs = gen(deps_chart_path, "markdown", update=False)
assert "image.repository" in docs
assert "<td>\n\n\"nginx\"\n\n</td>" in docs