Skip to content

Commit

Permalink
Update docs generations
Browse files Browse the repository at this point in the history
  • Loading branch information
sfc-gh-jvasquezrojas committed Nov 11, 2024
1 parent f4c69a8 commit d24b186
Show file tree
Hide file tree
Showing 6 changed files with 90 additions and 22 deletions.
7 changes: 6 additions & 1 deletion src/snowflake/cli/_app/dev/docs/generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@
from snowflake.cli._app.dev.docs.project_definition_docs_generator import (
generate_project_definition_docs,
)
from snowflake.cli.api.project.schemas.project_definition import (
DefinitionV11,
DefinitionV20,
)
from snowflake.cli.api.secure_path import SecurePath

log = logging.getLogger(__name__)
Expand All @@ -32,4 +36,5 @@ def generate_docs(root: SecurePath, command: Command):
"""
root.mkdir(exist_ok=True)
generate_command_docs(root / "commands", command)
generate_project_definition_docs(root / "project_definition")
generate_project_definition_docs(root / "project_definition_V11", DefinitionV11)
generate_project_definition_docs(root / "project_definition_V20", DefinitionV20)
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,17 @@
ProjectDefinitionGenerateJsonSchema,
)
from snowflake.cli._app.dev.docs.template_utils import get_template_environment
from snowflake.cli.api.project.schemas.project_definition import DefinitionV11
from snowflake.cli.api.project.schemas.updatable_model import UpdatableModel
from snowflake.cli.api.secure_path import SecurePath

log = logging.getLogger(__name__)

DEFINITION_DESCRIPTION = "definition_description.rst.jinja2"


def generate_project_definition_docs(root: SecurePath):
def generate_project_definition_docs(
root: SecurePath, definition: type[UpdatableModel]
) -> None:
"""
Recursively traverses the generated project definition schema,
creating a file for each section that mirrors the YAML structure.
Expand All @@ -39,7 +41,7 @@ def generate_project_definition_docs(root: SecurePath):

root.mkdir(exist_ok=True)
list_of_sections = model_json_schema(
DefinitionV11, schema_generator=ProjectDefinitionGenerateJsonSchema
definition, schema_generator=ProjectDefinitionGenerateJsonSchema
)["result"]
for section in list_of_sections:
_render_definition_description(root, section)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ class ProjectDefinitionProperty:
required: bool
name: str
description: str
examples: List[str]
add_types: bool
types: str

Expand Down Expand Up @@ -81,25 +82,64 @@ def generate(self, schema, mode="validation"):
self._remapped_definitions = json_schema["$defs"]
return {"result": self._get_definition_sections(json_schema)}

def _get_current_definition_sections(
self, current_definition_properties: Dict[str, Any]
):
result = {}
if "entities" in current_definition_properties:
entities_mapping = current_definition_properties["entities"][
"additionalProperties"
]["discriminator"]["mapping"]
for entity_name, entity_model in entities_mapping.items():
entity_name = entity_name.replace(" ", "_")
result["entities_" + entity_name] = {
**current_definition_properties["entities"],
"properties": {
entity_name
+ "_name": {"$ref": entity_model, "title": "Entity name"}
},
}

for property_name, property_model in current_definition_properties.items():
if property_name == "entities":
continue
result[property_name] = property_model
return result

def _get_definition_sections(
self, current_definition: Dict[str, Any]
) -> List[Dict[str, Any]]:
required_properties: List[Dict[str, Any]] = []
sections: List[Dict[str, Any]] = []

for property_name, property_model in current_definition["properties"].items():
for property_name, property_model in self._get_current_definition_sections(
current_definition["properties"]
).items():
section_name = property_name
is_required = (
"required" in current_definition
and property_name in current_definition["required"]
)
children_properties = self._get_children_properties(
property_model, property_name
)

if "entities" in property_name:
property_name = "entities"
children_properties = self._get_section_properties(
property_model,
property_name,
1,
False,
)

else:
children_properties = self._get_children_properties(
property_model, property_name
)

new_property = ProjectDefinitionProperty(
path=property_name,
title=property_model.get("title", ""),
description=property_model.get("description", ""),
examples=property_model.get("examples", []),
indents=0,
item_index=0,
required=is_required,
Expand All @@ -116,7 +156,7 @@ def _get_definition_sections(
{
"properties": properties,
"title": property_model["title"],
"name": property_name,
"name": section_name,
}
)

Expand Down Expand Up @@ -150,10 +190,12 @@ def _get_section_properties(
children_properties = self._get_children_properties(
property_model, new_current_path, depth
)

new_property = ProjectDefinitionProperty(
path=new_current_path,
title=property_model.get("title", ""),
description=property_model.get("description", ""),
examples=property_model.get("examples", []),
indents=depth,
item_index=item_index,
required=is_required,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,12 @@ The following table describes the project definition properties.
{% if property["description"] %}
{{ property["description"] }}
{% else %}{% endif -%}
{% if property["examples"] %}
**Examples**:
{% for example in property["examples"] %}
- {{ example }}
{%+ endfor %}
{% else %}{% endif -%}
{%+ endfor %}
{% else %}

Expand Down
11 changes: 1 addition & 10 deletions src/snowflake/cli/_app/main_typer.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,20 +17,11 @@
import sys

import typer
from snowflake.cli.api.cli_global_context import get_cli_context
from snowflake.cli.api.commands.flags import DEFAULT_CONTEXT_SETTINGS, DebugOption
from snowflake.cli.api.console import cli_console


def _handle_exception(exception: Exception):
if get_cli_context().enable_tracebacks:
raise exception
else:
cli_console.warning(
"\nAn unexpected exception occurred. Use --debug option to see the traceback. Exception message:\n\n"
+ exception.__str__()
)
raise SystemExit(1)
raise exception


class SnowCliMainTyper(typer.Typer):
Expand Down
28 changes: 25 additions & 3 deletions tests/test_docs_generation_output.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,10 @@
from click import Command
from pydantic.json_schema import GenerateJsonSchema, model_json_schema
from snowflake.cli._app.cli_app import app_context_holder
from snowflake.cli.api.project.schemas.project_definition import DefinitionV11
from snowflake.cli.api.project.schemas.project_definition import (
DefinitionV11,
DefinitionV20,
)


@mock.patch(
Expand Down Expand Up @@ -64,7 +67,7 @@ def test_definition_file_format_generated_from_json(mock_generate, runner, temp_
project_definition_path = (
Path(temp_dir)
/ "gen_docs"
/ "project_definition"
/ "project_definition_V11"
/ "definition_section_demo.txt"
)

Expand Down Expand Up @@ -115,7 +118,7 @@ def test_files_generated_for_each_optional_project_definition_property(
runner, temp_dir
):
runner.invoke(["--docs"])
project_definition_path = Path(temp_dir) / "gen_docs" / "project_definition"
project_definition_path = Path(temp_dir) / "gen_docs" / "project_definition_V11"
errors = []

model_json = model_json_schema(DefinitionV11, schema_generator=GenerateJsonSchema)
Expand All @@ -128,6 +131,25 @@ def test_files_generated_for_each_optional_project_definition_property(
assert len(errors) == 0, "\n".join(errors)


def test_files_generated_for_each_entity_definition(runner, temp_dir):
runner.invoke(["--docs"])
project_definition_path = Path(temp_dir) / "gen_docs" / "project_definition_V20"
errors = []

model_json = model_json_schema(DefinitionV20, schema_generator=GenerateJsonSchema)
mapping = model_json["properties"]["entities"]["additionalProperties"][
"discriminator"
]["mapping"]
for property_name, _ in mapping.items():
if not (
project_definition_path
/ f"definition_entities_{property_name.replace(' ', '_')}.txt"
).exists():
errors.append(f"Section `{property_name}` was not properly generated")

assert len(errors) == 0, "\n".join(errors)


def test_all_commands_have_generated_files(runner, temp_dir):
runner.invoke(["--docs"])

Expand Down

0 comments on commit d24b186

Please sign in to comment.