Skip to content

Commit

Permalink
Merge branch 'main' into feat/allow-eval-on-non-existing-namespace
Browse files Browse the repository at this point in the history
  • Loading branch information
nichmor committed Jul 22, 2024
2 parents b9601fc + 1a7d514 commit 77feaf7
Show file tree
Hide file tree
Showing 13 changed files with 17,668 additions and 5,033 deletions.
30 changes: 30 additions & 0 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
name: Tests
on:
push:
branches: [ "main" ]
pull_request:
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
run_tests:
name: ${{ matrix.pixi-environment }}
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
pixi-environment:
- py312
- py311
- py310
- py39
- py38
steps:
- uses: actions/checkout@v4
- uses: prefix-dev/[email protected]
with:
pixi-version: "latest"
environments: ${{ matrix.pixi-environment }}
- name: run tests
run: |
pixi run --environment ${{ matrix.pixi-environment }} tests
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
# name: Run updater that will check for conda-forge packages

name: Type Check
on:
push:
branches: [ "main" ]
Expand All @@ -15,8 +14,8 @@ jobs:
- uses: prefix-dev/[email protected]
with:
pixi-version: "latest"
environments: test
environments: lint

- name: run tests
- name: type check
run: |
pixi run -e test pytest
pixi run type-check
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -165,5 +165,4 @@ mapping/*# pixi environments
.pixi

.vscode/

.DS_Store
13 changes: 13 additions & 0 deletions docs/RELEASING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
## Small guide to releasing

Release new version:

1. Create a branch `release/v{version}` and do the following:
2. Update `pyproject.toml` and `pixi.toml`
3. Run `pixi install`
4. Add lock and toml files to commit.
5. Push to remote and see if CI is green. *if not*: either make changes in a separate PR (if big), or here (if small).
7. Merge to main.
8. Build an sdist using `pixi r build_sdist`. This needs to succeed.
9. Create a tag `git tag v{version}` `git push --tags`.
10. Create the release on github and generate release notes, upload the generated sdist.
22,429 changes: 17,486 additions & 4,943 deletions pixi.lock

Large diffs are not rendered by default.

58 changes: 38 additions & 20 deletions pixi.toml
Original file line number Diff line number Diff line change
@@ -1,50 +1,68 @@
[project]
name = "rattler-build-conda-compat"
version = "0.0.6"
version = "0.2.2"
description = "A package for exposing rattler-build API for conda-smithy"
authors = ["nichmor <[email protected]>"]
channels = ["conda-forge"]
platforms = ["win-64", "linux-64", "osx-64", "osx-arm64"]

[tasks]

build_sdist = "pixi run python -m build --sdist"

[dependencies]
python = ">=3.8"
build = "*"
rattler-build = "*"
conda-build = "*"
"ruamel.yaml" = "*"
build = ">=0.7.0,<0.8"
rattler-build = ">=0.18.1,<1"
conda-build = ">=24.3.0,<25.0"
"ruamel.yaml" = ">=0.18.6,<0.19"
conda = ">=4.2"
pygithub = ">=2,<3"
tomli = "*"
tomli = ">=2.0.1,<3"
typing-extensions = ">=4.12.2,<4.13"

[pypi-dependencies]
rattler-build-conda-compat = { path = ".", editable = true}

rattler-build-conda-compat = { path = ".", editable = true }

[feature.test.dependencies]
pytest = "*"
syrupy = "*"
ruff = "*"

[feature.test.tasks]
test = "pytest"
snapshot_update = "pytest --snapshot-update"
[feature.tests.dependencies]
pytest = ">=8.2.2,<9"
syrupy = ">=4.6.1,<5"

[feature.tests.tasks]
tests = "pytest tests"
snapshot_update = "pytest --snapshot-update tests"

[feature.lint.dependencies]
pre-commit = ">=3.7.1,<4"
pre-commit-hooks = ">=4.6.0,<5"
ruff = ">=0.4.8,<0.5"
typos = ">=1.23.1,<2"
mypy = ">=1.10.1,<2"
types-pyyaml = ">=6.0.12.20240311,<6.0.13"
ruff = ">=0.5.0,<0.6"

[feature.lint.tasks]
pre-commit-install = "pre-commit-install"
pre-commit-run = "pre-commit run"
type-check = "mypy src"

[feature.py312.dependencies]
python = "3.12.*"

[feature.py311.dependencies]
python = "3.11.*"

[feature.py310.dependencies]
python = "3.10.*"

[feature.py39.dependencies]
python = "3.9.*"

[feature.py38.dependencies]
python = "3.8.*"

[environments]
test = ["test"]
lint = { features = ["lint"], no-default-feature = true, solve-group = "default" }
py312 = { features = ["py312", "tests"] }
py311 = ["py311", "tests"]
py310 = ["py310", "tests"]
py39 = ["py39", "tests"]
py38 = ["py38", "tests"]
lint = { features = ["lint"], no-default-feature = true }
11 changes: 8 additions & 3 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@ build-backend = "hatchling.build"
[project]
name = "rattler-build-conda-compat"
description = "A package for exposing rattler-build API for conda-smithy"
version = "0.0.6"
version = "0.2.2"
readme = "README.md"
authors = [{ name = "Nichita Morcotilo", email = "[email protected]" }]
license = { file = "LICENSE.txt" }

dependencies = ["typing-extensions>=4.12,<5"]
requires-python = ">=3.8"

[tool.ruff]
Expand All @@ -30,6 +30,7 @@ ignore = [
"T201", # https://docs.astral.sh/ruff/rules/print/
"A003", # https://docs.astral.sh/ruff/rules/builtin-attribute-shadowing/
"PTH", # We dont want to change the API to pathlib just yet
"ANN101", # Deprecated
]
exclude = [
"src/rattler_build_conda_compat/lint.py",
Expand All @@ -42,4 +43,8 @@ exclude = [

[tool.pyright]
venvPath = ".pixi/envs"
venv = "default"
venv = "py312"

[tool.mypy]
python_version = "3.8"
allow_redefinition = true
17 changes: 11 additions & 6 deletions src/rattler_build_conda_compat/conditional_list.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
from __future__ import annotations

from typing import Any, Callable, Generator, Generic, TypeVar, Union
from typing import TYPE_CHECKING, Any, Generic, List, TypeVar, Union, cast

if TYPE_CHECKING:
from collections.abc import Callable, Generator

T = TypeVar("T")
K = TypeVar("K")


class IfStatement(Generic[T]):
Expand All @@ -11,11 +15,12 @@ class IfStatement(Generic[T]):
else_: T | list[T] | None


ConditionalList = Union[T, "IfStatement[T]", list[Union[T, "IfStatement[T]"]]]
ConditionalList = Union[T, IfStatement[T], List[Union[T, IfStatement[T]]]]


def visit_conditional_list( # noqa: C901
value: ConditionalList[T], evaluator: Callable[[Any], bool] | None = None
value: T | IfStatement[T] | list[T | IfStatement[T]],
evaluator: Callable[[Any], bool] | None = None,
) -> Generator[T, None, None]:
"""
A function that yields individual branches of a conditional list.
Expand All @@ -30,7 +35,7 @@ def visit_conditional_list( # noqa: C901
A generator that yields the individual branches.
"""

def yield_from_list(value: list[T] | T) -> Generator[T, None, None]:
def yield_from_list(value: list[K] | K) -> Generator[K, None, None]:
if isinstance(value, list):
yield from value
else:
Expand All @@ -57,8 +62,8 @@ def yield_from_list(value: list[T] | T) -> Generator[T, None, None]:
yield from yield_from_list(otherwise)
else:
# In this case its not an if statement
yield element
yield cast(T, element)
# If the element is not a dictionary, just yield it
else:
# (tim) I get a pyright error here, but I don't know how to fix it
yield element
yield cast(T, element)
2 changes: 2 additions & 0 deletions src/rattler_build_conda_compat/lint.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# mypy: ignore-errors

import re

from inspect import cleandoc
Expand Down
18 changes: 12 additions & 6 deletions src/rattler_build_conda_compat/loader.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,29 @@

import itertools
from contextlib import contextmanager
from typing import TYPE_CHECKING, Any, Iterator, Self
from typing import TYPE_CHECKING, Any

import yaml

from rattler_build_conda_compat.conditional_list import visit_conditional_list

if TYPE_CHECKING:
from collections.abc import Iterator
from os import PathLike

SELECTOR_OPERATORS = ("and", "or", "not")


class RecipeLoader(yaml.BaseLoader):
_namespace: dict[str, Any] | None = None

@classmethod
@contextmanager
def with_namespace(
cls: Self, namespace: dict[str, Any] | None, *, allow_missing_selector: bool = False
cls: type[RecipeLoader],
namespace: dict[str, Any] | None,
*,
allow_missing_selector: bool = False,
) -> Iterator[None]:
try:
cls._namespace = namespace
Expand All @@ -28,10 +34,10 @@ def with_namespace(
del cls._namespace

def construct_sequence( # noqa: C901, PLR0912
self: Self,
node: yaml.Node,
deep: bool = False, # noqa: FBT002, FBT001
) -> list[yaml.Node]:
self,
node: yaml.ScalarNode | yaml.SequenceNode | yaml.MappingNode,
deep: bool = False, # noqa: FBT002, FBT001,
) -> list[yaml.ScalarNode]:
"""deep is True when creating an object/mapping recursively,
in that case want the underlying elements available during construction
"""
Expand Down
33 changes: 22 additions & 11 deletions src/rattler_build_conda_compat/recipe_sources.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,20 @@
from __future__ import annotations

import sys
import typing
from typing import Any, Iterator, Mapping, NotRequired, TypedDict
from typing import Any, List, TypedDict, Union

from .conditional_list import ConditionalList, visit_conditional_list

OptionalUrlList = str | list[str] | None
if sys.version_info < (3, 11):
from typing_extensions import NotRequired
else:
from typing import NotRequired

if typing.TYPE_CHECKING:
from collections.abc import Iterator, Mapping

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


class Source(TypedDict):
Expand All @@ -29,10 +40,10 @@ def get_all_url_sources(recipe: Mapping[Any, Any]) -> Iterator[str]:

# Try getting all url top-level sources
if sources is not None:
sources = visit_conditional_list(sources, None)
for source in sources:
if "url" in source:
yield source["url"]
source_list = visit_conditional_list(sources, None)
for source in source_list:
if url := source.get("url"):
yield url

outputs = recipe.get("outputs", None)
if outputs is None:
Expand All @@ -43,8 +54,8 @@ def get_all_url_sources(recipe: Mapping[Any, Any]) -> Iterator[str]:
sources = output.get("source", None)
sources = typing.cast(ConditionalList[Source], sources)
if sources is None:
return
sources = visit_conditional_list(sources, None)
for source in sources:
if "url" in source:
yield source["url"]
continue
source_list = visit_conditional_list(sources, None)
for source in source_list:
if url := source.get("url"):
yield url
Loading

0 comments on commit 77feaf7

Please sign in to comment.