Skip to content

Commit

Permalink
Post-review-fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
sfc-gh-jsikorski committed Aug 26, 2024
1 parent 448c087 commit e03ba65
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 14 deletions.
13 changes: 11 additions & 2 deletions src/snowflake/cli/api/project/schemas/entities/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
from abc import ABC
from typing import Generic, List, Optional, TypeVar, Union

from pydantic import Field, PrivateAttr
from pydantic import Field, PrivateAttr, field_validator
from snowflake.cli.api.identifiers import FQN
from snowflake.cli.api.project.schemas.identifier_model import Identifier
from snowflake.cli.api.project.schemas.native_app.application import (
Expand All @@ -41,11 +41,20 @@ class MetaField(UpdatableModel):
title="Actions that will be executed after the application object is created/upgraded",
default=None,
)
use_mixins: Optional[str | List[str]] = Field(
use_mixins: Optional[List[str]] = Field(
title="Name of the mixin used to fill the entity fields",
default=None,
)

@field_validator("use_mixins", mode="before")
@classmethod
def ensure_use_mixins_is_a_list(
cls, mixins: Optional[str | List[str]]
) -> Optional[List[str]]:
if isinstance(mixins, str):
return [mixins]
return mixins


class DefaultsField(UpdatableModel):
schema_: Optional[str] = Field(
Expand Down
29 changes: 17 additions & 12 deletions src/snowflake/cli/api/project/schemas/project_definition.py
Original file line number Diff line number Diff line change
Expand Up @@ -201,18 +201,23 @@ def apply_mixins(cls, data: Dict) -> Dict:
"""
Applies mixins to those entities, whose meta field contains the mixin name.
"""
if "mixins" in data and "entities" in data:
for entity in data["entities"].values():
entity_mixins = entity_mixins_to_list(
entity.get("meta", {}).get("use_mixins")
)
entity_fields = get_allowed_fields_for_entity(entity)
if entity_fields and entity_mixins:
for mixin_name in entity_mixins:
if mixin_name in data["mixins"]:
for key, value in data["mixins"][mixin_name].items():
if key in entity_fields:
entity[key] = value
if "mixins" not in data or "entities" not in data:
return data

for entity in data["entities"].values():
entity_mixins = entity_mixins_to_list(
entity.get("meta", {}).get("use_mixins")
)

entity_fields = get_allowed_fields_for_entity(entity)
if entity_fields and entity_mixins:
for mixin_name in entity_mixins:
if mixin_name in data["mixins"]:
for key, value in data["mixins"][mixin_name].items():
if key in entity_fields:
entity[key] = value
else:
raise ValueError(f"Mixin {mixin_name} not found in mixins")
return data

def get_entities_by_type(self, entity_type: str):
Expand Down
3 changes: 3 additions & 0 deletions tests/project/test_project_definition_v2.py
Original file line number Diff line number Diff line change
Expand Up @@ -385,6 +385,9 @@ def test_v1_to_v2_conversion(
_assert_entities_are_equal(v1_function, v2_function)


# TODO:
# 1. rewrite projects to have one big definition covering all complex positive cases
# 2. Add negative case - entity uses non-existent mixin
@pytest.mark.parametrize(
"project_name,stage1,stage2",
[("mixins_basic", "foo", "bar"), ("mixins_defaults_hierarchy", "foo", "baz")],
Expand Down

0 comments on commit e03ba65

Please sign in to comment.