Skip to content

Commit

Permalink
run pre-commit
Browse files Browse the repository at this point in the history
  • Loading branch information
wolfv committed Aug 7, 2024
1 parent 3a33fbd commit e0d37b3
Show file tree
Hide file tree
Showing 10 changed files with 86 additions and 57 deletions.
4 changes: 4 additions & 0 deletions conda_forge_tick/update_recipe/v2/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
from .build_number import update_build_number
from .version import update_version

__all__ = ["update_build_number", "update_version"]
12 changes: 9 additions & 3 deletions conda_forge_tick/update_recipe/v2/build_number.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@

import logging
from typing import TYPE_CHECKING, Any, Literal
from conda_forge_tick.update_recipe.v2.yaml import _load_yaml, _dump_yaml_to_str

from conda_forge_tick.update_recipe.v2.yaml import _dump_yaml_to_str, _load_yaml

if TYPE_CHECKING:
from pathlib import Path

Expand All @@ -11,15 +13,19 @@
HashType = Literal["md5", "sha256"]


def _update_build_number_in_context(recipe: dict[str, Any], new_build_number: int) -> bool:
def _update_build_number_in_context(
recipe: dict[str, Any], new_build_number: int
) -> bool:
for key in recipe.get("context", {}):
if key.startswith("build_") or key == "build":
recipe["context"][key] = new_build_number
return True
return False


def _update_build_number_in_recipe(recipe: dict[str, Any], new_build_number: int) -> bool:
def _update_build_number_in_recipe(
recipe: dict[str, Any], new_build_number: int
) -> bool:
is_modified = False
if "build" in recipe and "number" in recipe["build"]:
recipe["build"]["number"] = new_build_number
Expand Down
5 changes: 4 additions & 1 deletion conda_forge_tick/update_recipe/v2/context.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import jinja2

def load_recipe_context(context: dict[str, str], jinja_env: jinja2.Environment) -> dict[str, str]:

def load_recipe_context(
context: dict[str, str], jinja_env: jinja2.Environment
) -> dict[str, str]:
"""
Load all string values from the context dictionary as Jinja2 templates.
Use linux-64 as default target_platform, build_platform, and mpi.
Expand Down
3 changes: 3 additions & 0 deletions conda_forge_tick/update_recipe/v2/jinja/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
from .jinja import jinja_env

__all__ = ["jinja_env"]
2 changes: 1 addition & 1 deletion conda_forge_tick/update_recipe/v2/jinja/filters.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from __future__ import annotations

from conda_forge_tick.jinja.utils import _MissingUndefined
from conda_forge_tick.update_recipe.v2.jinja.utils import _MissingUndefined


def _version_to_build_string(some_string: str | _MissingUndefined) -> str:
Expand Down
79 changes: 43 additions & 36 deletions conda_forge_tick/update_recipe/v2/jinja/jinja.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
from __future__ import annotations

from typing import Any, TypedDict
from typing import TypedDict

import jinja2
import yaml
from jinja2.sandbox import SandboxedEnvironment

from conda_forge_tick.jinja.filters import _bool, _split, _version_to_build_string
from conda_forge_tick.jinja.objects import (
from conda_forge_tick.update_recipe.v2.jinja.filters import (
_bool,
_split,
_version_to_build_string,
)
from conda_forge_tick.update_recipe.v2.jinja.objects import (
_stub_compatible_pin,
_stub_is_linux,
_stub_is_unix,
Expand All @@ -15,20 +19,21 @@
_stub_subpackage_pin,
_StubEnv,
)
from conda_forge_tick.jinja.utils import _MissingUndefined
from conda_forge_tick.loader import load_yaml
from conda_forge_tick.update_recipe.v2.jinja.utils import _MissingUndefined

# from conda_forge_tick.update_recipe.v2.loader import load_yaml


class RecipeWithContext(TypedDict, total=False):
context: dict[str, str]


def jinja_env() -> jinja2.Environment:
def jinja_env() -> SandboxedEnvironment:
"""
Create a `rattler-build` specific Jinja2 environment with modified syntax.
Target platform, build platform, and mpi are set to linux-64 by default.
"""
env = jinja2.sandbox.SandboxedEnvironment(
env = SandboxedEnvironment(
variable_start_string="${{",
variable_end_string="}}",
trim_blocks=True,
Expand Down Expand Up @@ -71,7 +76,9 @@ def jinja_env() -> jinja2.Environment:
return env


def load_recipe_context(context: dict[str, str], jinja_env: jinja2.Environment) -> dict[str, str]:
def load_recipe_context(
context: dict[str, str], jinja_env: jinja2.Environment
) -> dict[str, str]:
"""
Load all string values from the context dictionary as Jinja2 templates.
Use linux-64 as default target_platform, build_platform, and mpi.
Expand All @@ -87,30 +94,30 @@ def load_recipe_context(context: dict[str, str], jinja_env: jinja2.Environment)
return context


def render_recipe_with_context(recipe_content: RecipeWithContext) -> dict[str, Any]:
"""
Render the recipe using known values from context section.
Unknown values are not evaluated and are kept as it is.
Target platform, build platform, and mpi are set to linux-64 by default.
Examples:
---
```python
>>> from pathlib import Path
>>> from conda_forge_tick.loader import load_yaml
>>> recipe_content = load_yaml((Path().resolve() / "tests" / "data" / "eval_recipe_using_context.yaml").read_text())
>>> evaluated_context = render_recipe_with_context(recipe_content)
>>> assert "my_value-${{ not_present_value }}" == evaluated_context["build"]["string"]
>>>
```
"""
env = jinja_env()
context = recipe_content.get("context", {})
# render out the context section and retrieve dictionary
context_variables = load_recipe_context(context, env)

# render the rest of the document with the values from the context
# and keep undefined expressions _as is_.
template = env.from_string(yaml.dump(recipe_content))
rendered_content = template.render(context_variables)
return load_yaml(rendered_content)
# def render_recipe_with_context(recipe_content: RecipeWithContext) -> dict[str, Any]:
# """
# Render the recipe using known values from context section.
# Unknown values are not evaluated and are kept as it is.
# Target platform, build platform, and mpi are set to linux-64 by default.

# Examples:
# ---
# ```python
# >>> from pathlib import Path
# >>> from conda_forge_tick.loader import load_yaml
# >>> recipe_content = load_yaml((Path().resolve() / "tests" / "data" / "eval_recipe_using_context.yaml").read_text())
# >>> evaluated_context = render_recipe_with_context(recipe_content)
# >>> assert "my_value-${{ not_present_value }}" == evaluated_context["build"]["string"]
# >>>
# ```
# """
# env = jinja_env()
# context = recipe_content.get("context", {})
# # render out the context section and retrieve dictionary
# context_variables = load_recipe_context(context, env)

# # render the rest of the document with the values from the context
# # and keep undefined expressions _as is_.
# template = env.from_string(yaml.dump(recipe_content))
# rendered_content = template.render(context_variables)
# return load_yaml(rendered_content)
15 changes: 9 additions & 6 deletions conda_forge_tick/update_recipe/v2/source.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
import typing
from typing import Union, List, TypedDict, Any, Iterator, NotRequired, Mapping
from conda_forge_tick.update_recipe.v2.conditional_list import visit_conditional_list, ConditionalList
from typing import Any, Iterator, List, Mapping, NotRequired, TypedDict, Union

from conda_forge_tick.update_recipe.v2.conditional_list import (
ConditionalList,
visit_conditional_list,
)

OptionalUrlList = Union[str, List[str], None]


class Source(TypedDict):
url: NotRequired[str | list[str]]
sha256: NotRequired[str]
Expand All @@ -29,8 +34,7 @@ def get_all_sources(recipe: Mapping[Any, Any]) -> Iterator[Source]:
# Try getting all url top-level sources
if sources is not None:
source_list = visit_conditional_list(sources, None)
for source in source_list:
yield source
yield from source_list

outputs = recipe.get("outputs", None)
if outputs is None:
Expand All @@ -43,5 +47,4 @@ def get_all_sources(recipe: Mapping[Any, Any]) -> Iterator[Source]:
if sources is None:
continue
source_list = visit_conditional_list(sources, None)
for source in source_list:
yield source
yield from source_list
7 changes: 4 additions & 3 deletions conda_forge_tick/update_recipe/v2/version.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@
import re
from typing import TYPE_CHECKING, Literal

import requests

from conda_forge_tick.update_recipe.v2.context import load_recipe_context
from conda_forge_tick.update_recipe.v2.jinja import jinja_env
from conda_forge_tick.update_recipe.v2.source import Source, get_all_sources
from conda_forge_tick.update_recipe.v2.yaml import _load_yaml, _dump_yaml_to_str

import requests
from conda_forge_tick.update_recipe.v2.yaml import _dump_yaml_to_str, _load_yaml

if TYPE_CHECKING:
from pathlib import Path
Expand All @@ -20,6 +20,7 @@

HashType = Literal["md5", "sha256"]


class CouldNotUpdateVersionError(Exception):
NO_CONTEXT = "Could not find context in recipe"
NO_VERSION = "Could not find version in recipe context"
Expand Down
10 changes: 5 additions & 5 deletions conda_forge_tick/update_recipe/v2/yaml.py
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
import io
from ruamel.yaml import YAML
from typing import TYPE_CHECKING
from pathlib import Path

if TYPE_CHECKING:
from pathlib import Path
from ruamel.yaml import YAML

yaml = YAML()
yaml.preserve_quotes = True
yaml.width = 4096
yaml.indent(mapping=2, sequence=4, offset=2)


def _load_yaml(file: Path) -> dict:
"""Load a YAML file."""
with file.open("r") as f:
return yaml.load(f)


def _dump_yaml_to_str(data: dict) -> str:
"""Dump a dictionary to a YAML string."""
with io.StringIO() as f:
yaml.dump(data, f)
return f.getvalue()
return f.getvalue()
6 changes: 4 additions & 2 deletions tests/test_recipe_editing_v2.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
import pytest
from pathlib import Path

from conda_forge_tick.recipe_editing_v2 import update_build_number, update_version
import pytest

from conda_forge_tick.update_recipe.v2 import update_build_number, update_version


@pytest.fixture
def data_dir() -> Path:
return Path(__file__).parent / "recipe_v2"


def test_build_number_mod(data_dir: Path) -> None:
tests = data_dir / "build_number"
result = update_build_number(tests / "test_1/recipe.yaml", 0)
Expand Down

0 comments on commit e0d37b3

Please sign in to comment.