Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update docs generations #1846

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
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: 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
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)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you add more assertions/test cases to check if proper number of files is generated and their content is ok?



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

Expand Down
Loading