Skip to content

Commit

Permalink
fix: omit also jinja functions (#37)
Browse files Browse the repository at this point in the history
  • Loading branch information
nichmor committed Aug 1, 2024
1 parent 441ae54 commit 5c61261
Show file tree
Hide file tree
Showing 9 changed files with 424 additions and 33 deletions.
Empty file.
28 changes: 28 additions & 0 deletions src/rattler_build_conda_compat/jinja/filters.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
from __future__ import annotations

from rattler_build_conda_compat.jinja.utils import _MissingUndefined


def _version_to_build_string(some_string: str | _MissingUndefined) -> str:
"""
Converts some version by removing the . character and returning only the first two elements of the version.
If piped value is undefined, it returns the undefined value as is.
"""
if isinstance(some_string, _MissingUndefined):
return f"{some_string._undefined_name}_version_to_build_string" # noqa: SLF001
# We first split the string by whitespace and take the first part
split = some_string.split()[0] if some_string.split() else some_string
# We then split the string by . and take the first two parts
parts = split.split(".")
major = parts[0] if len(parts) > 0 else ""
minor = parts[1] if len(parts) > 1 else ""
return f"{major}{minor}"


def _bool(value: str) -> bool:
return bool(value)


def _split(s: str, sep: str = " ") -> list[str]:
"""Filter that split a string by a separator"""
return s.split(sep)
Original file line number Diff line number Diff line change
Expand Up @@ -4,42 +4,78 @@

import jinja2
import yaml
from jinja2 import DebugUndefined

from rattler_build_conda_compat.jinja.filters import _bool, _split, _version_to_build_string
from rattler_build_conda_compat.jinja.objects import (
_stub_compatible_pin,
_stub_is_linux,
_stub_is_unix,
_stub_is_win,
_stub_match,
_stub_subpackage_pin,
_StubEnv,
)
from rattler_build_conda_compat.jinja.utils import _MissingUndefined
from rattler_build_conda_compat.loader import load_yaml


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


class _MissingUndefined(DebugUndefined):
def __str__(self) -> str:
"""
By default, `DebugUndefined` return values in the form `{{ value }}`.
`rattler-build` has a different syntax, so we need to override this method,
and return the value in the form `${{ value }}`.
"""
return f"${super().__str__()}"


def jinja_env() -> jinja2.Environment:
"""
Create a `rattler-build` specific Jinja2 environment with modified syntax.
Target platform, build platform, and mpi are set to linux-64 by default.
"""
return jinja2.Environment(

env = jinja2.Environment(
variable_start_string="${{",
variable_end_string="}}",
trim_blocks=True,
lstrip_blocks=True,
autoescape=True,
autoescape=jinja2.select_autoescape(default_for_string=False),
undefined=_MissingUndefined,
)

env_obj = _StubEnv()

# inject rattler-build recipe functions in jinja environment
env.globals.update(
{
"compiler": lambda x: x + "_compiler_stub",
"stdlib": lambda x: x + "_stdlib_stub",
"pin_subpackage": _stub_subpackage_pin,
"pin_compatible": _stub_compatible_pin,
"cdt": lambda *args, **kwargs: "cdt_stub", # noqa: ARG005
"env": env_obj,
"match": _stub_match,
"is_unix": _stub_is_unix,
"is_win": _stub_is_win,
"is_linux": _stub_is_linux,
"unix": True,
"linux": True,
"target_platform": "linux-64",
"build_platform": "linux-64",
"mpi": "mpi",
}
)

# inject rattler-build recipe filters in jinja environment
env.filters.update(
{
"version_to_buildstring": _version_to_build_string,
"split": _split,
"bool": _bool,
}
)
return env


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.
"""
# Process each key-value pair in the dictionary
for key, value in context.items():
Expand All @@ -56,6 +92,7 @@ def render_recipe_with_context(recipe_content: RecipeWithContext) -> dict[str, A
"""
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:
---
Expand Down
35 changes: 35 additions & 0 deletions src/rattler_build_conda_compat/jinja/objects.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
from __future__ import annotations


class _StubEnv:
"""A class to represent the env object used in rattler-build recipe."""

def get(self, env_var: str, default: str | None = None) -> str: # noqa: ARG002
return f"""env_"{env_var}" """

def exists(self, env_var: str) -> str:
return f"""env_exists_"{env_var}" """


def _stub_compatible_pin(*args, **kwargs) -> str: # noqa: ARG001, ANN003, ANN002
return f"compatible_pin {args[0]}"


def _stub_subpackage_pin(*args, **kwargs) -> str: # noqa: ARG001, ANN003, ANN002
return f"subpackage_pin {args[0]}"


def _stub_match(*args, **kwargs) -> str: # noqa: ARG001, ANN003, ANN002
return f"match {args[0]}"


def _stub_is_unix(platform: str) -> str:
return f"is_unix {platform}"


def _stub_is_win(platform: str) -> str:
return f"is_win {platform}"


def _stub_is_linux(platform: str) -> str:
return f"is_linux {platform}"
11 changes: 11 additions & 0 deletions src/rattler_build_conda_compat/jinja/utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
from jinja2 import DebugUndefined


class _MissingUndefined(DebugUndefined):
def __str__(self) -> str:
"""
By default, `DebugUndefined` return values in the form `{{ value }}`.
`rattler-build` has a different syntax, so we need to override this method,
and return the value in the form `${{ value }}`.
"""
return f"${super().__str__()}"
144 changes: 137 additions & 7 deletions tests/__snapshots__/test_jinja.ambr
Original file line number Diff line number Diff line change
@@ -1,15 +1,145 @@
# serializer version: 1
# name: test_render_recipe_with_context
'''
about:
description: '# Mamba, the Fast Cross-Platform Package Manager

env_"MY_ENV_VAR"

env_"MY_ENV_VAR"

env_exists_"MY_ENV_VAR"

'
homepage: https://github.com/mamba-org/mamba
license: BSD-3-Clause
license_family: BSD
license_file: LICENSE
repository: https://github.com/mamba-org/mamba
summary: A fast drop-in alternative to conda, using libsolv for dependency resolution
build:
string: ${{ blas_variant }}${{ hash }}_foo-bla
number: '2'
context:
name: foo
name_version: foo-bla
version: bla
package:
name: foo
version: bla
build_number: '2'
libmamba_version: 1.5.8
libmambapy_version: 1.5.8
mamba_version: 1.5.8
name: mamba
release: 2024.03.25
outputs:
- build:
script:
- build_mamba.sh
- ''
package:
name: libmamba
version: 1.5.8
requirements:
build:
- cxx_compiler_stub
- cmake
- ninja
- ''
host:
- libsolv >=0.7.23
- libcurl >=8.4.0
- fmt
- ''
ignore_run_exports:
by_name:
- spdlog
- python
run:
- libsolv >=0.7.23
run_exports:
- subpackage_pin libmamba
tests:
- script:
- else:
- if not exist %LIBRARY_PREFIX%\include\mamba\version.hpp (exit 1)
if: unix
then:
- test -d ${PREFIX}/include/mamba
- build:
script:
- build_mamba.sh
- ''
package:
name: libmambapy
version: 1.5.8
requirements:
build:
- cxx_compiler_stub
- cmake
- ninja
- if: build_platform != target_platform
then:
- python
- cross-python_linux-64
- pybind11
- pybind11-abi
host:
- python
- nlohmann_json
- subpackage_pin libmamba
ignore_run_exports:
by_name:
- spdlog
run:
- python
- subpackage_pin libmamba
run_exports:
- subpackage_pin libmambapy
tests:
- python:
imports:
- libmambapy
- libmambapy.bindings
- script:
- python -c "import libmambapy._version; assert libmambapy._version.__version__
== '1.5.8'"
- build:
python:
entry_points:
- mamba = mamba.mamba:main
script:
- build_mamba.sh
- ''
- ''
string: pypython_version_to_build_stringh${{ hash }}_2
package:
name: mamba
version: 1.5.8
requirements:
build:
- if: build_platform != target_platform
then:
- python
- cross-python_linux-64
run:
- python
- conda >=23.9,<24
- subpackage_pin libmambapy
tests:
- python:
imports:
- mamba
- script:
- mamba --help
- python -c "import mamba._version; assert mamba._version.__version__ == '1.5.8'"
- if: linux
then:
- test -f ${PREFIX}/etc/profile.d/mamba.sh
- mamba create -n test_py2 python=2.7 --dry-run
- mamba install xtensor xsimd -c conda-forge --dry-run
- if: unix
then:
- test -f ${PREFIX}/condabin/mamba
recipe:
name: mamba-split
source:
sha256: 6ddaf4b0758eb7ca1250f427bc40c2c3ede43257a60bac54e4320a4de66759a6
url: https://github.com/mamba-org/mamba/archive/refs/tags/2024.03.25.tar.gz

'''
# ---
11 changes: 0 additions & 11 deletions tests/data/context.yaml

This file was deleted.

Loading

0 comments on commit 5c61261

Please sign in to comment.