Skip to content
Merged
Show file tree
Hide file tree
Changes from 14 commits
Commits
Show all changes
51 commits
Select commit Hold shift + click to select a range
b86effb
Refactoring to test v1 recipes.
janjagusch Aug 7, 2025
1864588
Add newline.
janjagusch Aug 8, 2025
b953af0
Clean up test case.
janjagusch Aug 8, 2025
79f2f40
Reset base classes.
janjagusch Aug 8, 2025
796cd8c
Remove assert_new_runtime_requirements_equal.
janjagusch Aug 8, 2025
8c23c27
Reset.
janjagusch Aug 8, 2025
59ac851
Remove log file.
janjagusch Aug 8, 2025
d530097
Reset integration test.
janjagusch Aug 8, 2025
07fdc75
Don't ignore env dir.
janjagusch Aug 8, 2025
97217ec
Merge branch 'main' into add-tests-for-v1-recipes
janjagusch Aug 8, 2025
f7dd2a1
Satisfy pch.
janjagusch Aug 8, 2025
cfa5343
Merge branch 'add-tests-for-v1-recipes' of https://github.com/janjagu…
janjagusch Aug 8, 2025
4abbeda
Merge branch 'main' into add-tests-for-v1-recipes
janjagusch Aug 8, 2025
6436bc4
Add v1 grayskull feature and test.
janjagusch Aug 11, 2025
e77f8e8
Remove breakpoint.
janjagusch Aug 11, 2025
1c8f212
Revert hardcoded custom URLs.
janjagusch Aug 11, 2025
489ed1d
Use default dict.
janjagusch Aug 11, 2025
ef39d27
Do not try to replace expressions.
janjagusch Aug 11, 2025
2329ad1
Add get_v1_recipe_file_if_exists function.
janjagusch Aug 11, 2025
ee4f0fe
Make private.
janjagusch Aug 11, 2025
c21907a
Add comments.
janjagusch Aug 11, 2025
2092c4f
Add docstring.
janjagusch Aug 11, 2025
e8bb9cb
Merge branch 'main' into add-runtime-requirements-test-for-v1-recipe
janjagusch Aug 13, 2025
5c5bddf
Add unit tests for get_grayskull_comparison for v0 and v1 format.
janjagusch Aug 13, 2025
f4321e7
Merge branch 'main' into add-runtime-requirements-test-for-v1-recipe
janjagusch Aug 13, 2025
ef38259
relock w/ conda-lock
regro-cf-autotick-bot Aug 14, 2025
d006cbb
Add unit test case for DependencyUpdateMigrator for v1 recipe format.
janjagusch Aug 14, 2025
cbdf760
Reword.
janjagusch Aug 14, 2025
6b2bbd1
Remove azure-cli-core integration test.
janjagusch Aug 14, 2025
042edf3
Add basis of fastapi v1 integration test.
janjagusch Aug 14, 2025
86536c9
Add v1 support to integration test helper.
janjagusch Aug 14, 2025
a2b1cef
Add separate v0 and v1 test methods.
janjagusch Aug 14, 2025
3e64431
Add v1 test case for fastapi.
janjagusch Aug 14, 2025
5d7793a
Fix retrieving new version.
janjagusch Aug 14, 2025
f37fe40
Allow traffic to codeload.github.com.
janjagusch Aug 14, 2025
b3bb35e
Mock pypi.org/pypi/fastapi/0.116.1/json.
janjagusch Aug 14, 2025
909340f
Fix unit tests.
janjagusch Aug 14, 2025
62fe221
Add integration test for updated run requirements.
janjagusch Aug 14, 2025
2802ffb
Only update run section for v1.
janjagusch Aug 14, 2025
e38e28f
Rename function.
janjagusch Aug 14, 2025
17e49e1
Merge branch 'main' into add-runtime-requirements-test-for-v1-recipe
janjagusch Aug 14, 2025
78a8391
Rename variable to grayskull_recipe.
janjagusch Aug 14, 2025
45992e3
Add test docstring.
janjagusch Aug 14, 2025
c367c4d
Handle when patch.before is None.
janjagusch Aug 14, 2025
e66ae2b
Update test since we no longer update the host section.
janjagusch Aug 14, 2025
f4ed57f
Fix test.
janjagusch Aug 14, 2025
32e467f
relock w/ conda-lock
regro-cf-autotick-bot Aug 18, 2025
ebd015a
Merge branch 'main' into add-runtime-requirements-test-for-v1-recipe
beckermr Aug 18, 2025
b623018
Merge branch 'main' into add-runtime-requirements-test-for-v1-recipe
beckermr Aug 18, 2025
4ea9436
Merge branch 'main' into add-runtime-requirements-test-for-v1-recipe
janjagusch Aug 19, 2025
86821f9
Merge branch 'main' into add-runtime-requirements-test-for-v1-recipe
beckermr Aug 19, 2025
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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -63,3 +63,4 @@ pixi.toml
venv
oryx-build-commands.txt
.env
.DS_Store
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,6 @@
[submodule "tests_integration/definitions/pydantic/resources/feedstock_v1"]
path = tests_integration/lib/_definitions/pydantic/resources/feedstock_v1
url = https://github.com/conda-forge/pydantic-feedstock.git
[submodule "tests_integration/lib/_definitions/azure-cli-core/resources/feedstock"]
path = tests_integration/lib/_definitions/azure_cli_core/resources/feedstock
url = https://github.com/conda-forge/azure-cli-core-feedstock.git
1 change: 1 addition & 0 deletions conda_forge_tick/migrators/dep_updates.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

class DependencyUpdateMigrator(MiniMigrator):
post_migration = True
allowed_schema_versions = [0, 1]

def __init__(self, python_nodes):
if not hasattr(self, "_init_args"):
Expand Down
83 changes: 83 additions & 0 deletions conda_forge_tick/update_deps.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@
import os
import pprint
import tempfile
from dataclasses import dataclass
from pathlib import Path
from typing import Dict, Literal, Union

import requests
from ruamel.yaml import YAML
from stdlib_list import stdlib_list

from conda_forge_tick.depfinder_api import simple_import_to_pkg_map
Expand All @@ -25,6 +27,15 @@

logger = logging.getLogger(__name__)

yaml = YAML()
yaml.default_flow_style = False
yaml.block_seq_indent = True
yaml.indent(mapping=2, sequence=4, offset=2)
yaml.width = 4096
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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


EnvDepComparison = dict[Literal["df_minus_cf", "cf_minus_df"], set[str]]
DepComparison = dict[Literal["host", "run"], EnvDepComparison]


SECTIONS_TO_PARSE = ["host", "run"]
SECTIONS_TO_UPDATE = ["run"]
Expand Down Expand Up @@ -584,6 +595,72 @@ def _gen_key_selector(dct, key):
yield k


@dataclass
class Patch:
before: str | None = None
after: str | None = None


def _env_dep_comparison_to_patches(
env_dep_comparison: EnvDepComparison,
) -> dict[str, Patch]:
deps_to_remove = copy.copy(env_dep_comparison["cf_minus_df"])
deps_to_add = copy.copy(env_dep_comparison["df_minus_cf"])
patches: dict[str, Patch] = {}
for dep in deps_to_add:
package = dep.split(" ")[0]
patches[package] = Patch(after=dep)
for dep in deps_to_remove:
package = dep.split(" ")[0]
if package in patches:
patches[package].before = dep
else:
patches[package] = Patch(before=dep)
return patches


def _apply_env_dep_comparison(
deps: list[str], env_dep_comparison: EnvDepComparison
) -> list[str]:
new_deps = copy.copy(deps)
patches = _env_dep_comparison_to_patches(env_dep_comparison)
for package, patch in patches.items():
# Do not touch Python itself - too finicky.
if package == "python":
continue
if patch.before is None:
new_deps.append(patch.after)
elif patch.after is None:
new_deps.remove(patch.before)
else:
new_deps[new_deps.index(patch.before)] = patch.after
return new_deps


def _is_multi_output_v1_recipe(recipe: dict) -> bool:
return "outputs" in recipe


def _is_v1_recipe_okay_for_dep_updates(recipe: dict) -> bool:
return not _is_multi_output_v1_recipe(recipe=recipe)


def _apply_dep_update_v1(recipe: dict, dep_comparison: DepComparison) -> dict:
new_recipe = copy.deepcopy(recipe)
if not _is_v1_recipe_okay_for_dep_updates(recipe):
return new_recipe

host_deps = _apply_env_dep_comparison(
recipe["requirements"]["host"], dep_comparison["host"]
)
run_deps = _apply_env_dep_comparison(
recipe["requirements"]["run"], dep_comparison["run"]
)
new_recipe["requirements"]["host"] = host_deps
new_recipe["requirements"]["run"] = run_deps
return new_recipe


def apply_dep_update(recipe_dir, dep_comparison):
"""Update a recipe given a dependency comparison.

Expand All @@ -594,6 +671,12 @@ def apply_dep_update(recipe_dir, dep_comparison):
dep_comparison : dict
The dependency comparison.
"""
if (recipe_file := Path(recipe_dir).joinpath("recipe.yaml")).is_file():
recipe = yaml.load(recipe_file.read_text())
if (new_recipe := _apply_dep_update_v1(recipe, dep_comparison)) != recipe:
with recipe_file.open("w") as f:
yaml.dump(new_recipe, f)
return
recipe_pth = os.path.join(recipe_dir, "meta.yaml")
with open(recipe_pth) as fp:
lines = fp.readlines()
Expand Down
186 changes: 186 additions & 0 deletions tests/test_update_deps.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,10 @@
from conda_forge_tick.migrators import DependencyUpdateMigrator, Version
from conda_forge_tick.recipe_parser import CondaMetaYAML
from conda_forge_tick.update_deps import (
DepComparison,
_merge_dep_comparisons_sec,
_update_sec_deps,
apply_dep_update,
generate_dep_hint,
get_dep_updates_and_hints,
get_depfinder_comparison,
Expand Down Expand Up @@ -625,3 +627,187 @@ def test_update_deps_version_pyquil(caplog, tmp_path, update_kind, out_yml):
tmp_path=tmp_path,
make_body=True,
)


@pytest.mark.parametrize(
"recipe, dep_comparison, new_recipe",
[
(
"""schema_version: 1

context:
name: azure-cli-core
version: "2.75.0"

package:
name: ${{ name|lower }}
version: ${{ version }}

source:
url: https://pypi.org/packages/source/${{ name[0] }}/${{ name }}/${{ name | replace('-', '_') }}-${{ version }}.tar.gz
sha256: 0187f93949c806f8e39617cdb3b4fd4e3cac5ebe45f02dc0763850bcf7de8df2

build:
number: 0
noarch: python
script: ${{ PYTHON }} -m pip install . --no-deps -vv

requirements:
host:
- python ${{ python_min }}.*
- pip
- setuptools
run:
- python >=${{ python_min }}
- argcomplete >=3.5.2,<3.5.3
- azure-cli-telemetry >=1.1.0
- azure-mgmt-core >=1.2.0,<2
- cryptography
- distro
- humanfriendly >=10.0
- jmespath
- knack >=0.11.0,<0.11.1
- microsoft-security-utilities-secret-masker >=1.0.0b4,<1.1.0
- msal ==1.33.0b1
- msal_extensions ==1.2.0
- packaging >=20.9
- pkginfo >=1.5.0.1
- psutil >=5.9
- py-deviceid
- pyjwt >=2.1.0
- pyopenssl >=17.1.0
- pysocks >=1.6.0
- requests >=2.20.0

tests:
- python:
imports:
- azure
- azure.cli
- azure.cli.core
- azure.cli.core.commands
- azure.cli.core.extension
- azure.cli.core.profiles
python_version: ${{ python_min }}.*

about:
license: MIT
license_file: LICENSE
summary: Microsoft Azure Command-Line Tools Core Module
homepage: https://github.com/Azure/azure-cli
repository: https://github.com/Azure/azure-cli
documentation: https://docs.microsoft.com/en-us/cli/azure

extra:
recipe-maintainers:
- dhirschfeld
- andreyz4k
- janjagusch""",
{
"host": {
"cf_minus_df": {"python 3.9.*", "setuptools"},
"df_minus_cf": {"python"},
},
"run": {
"cf_minus_df": {
"knack >=0.11.0,<0.11.1",
"pysocks >=1.6.0",
"azure-cli-telemetry >=1.1.0",
"python >=3.9",
"microsoft-security-utilities-secret-masker >=1.0.0b4,<1.1.0",
"humanfriendly >=10.0",
"argcomplete >=3.5.2,<3.5.3",
"requests >=2.20.0",
"msal_extensions ==1.2.0",
},
"df_minus_cf": {
"requests",
"knack >=0.11.0,<0.12.dev0",
"humanfriendly >=10.0,<11.dev0",
"argcomplete >=3.5.2,<3.6.dev0",
"microsoft-security-utilities-secret-masker >=1.0.0b4,<1.1.dev0",
"python",
"msal-extensions ==1.2.0",
"azure-cli-telemetry ==1.1.0.*",
},
},
},
"""schema_version: 1

context:
name: azure-cli-core
version: 2.75.0

package:
name: ${{ name|lower }}
version: ${{ version }}

source:
url: https://pypi.org/packages/source/${{ name[0] }}/${{ name }}/${{ name | replace('-', '_') }}-${{ version }}.tar.gz
sha256: 0187f93949c806f8e39617cdb3b4fd4e3cac5ebe45f02dc0763850bcf7de8df2

build:
number: 0
noarch: python
script: ${{ PYTHON }} -m pip install . --no-deps -vv

requirements:
host:
- python ${{ python_min }}.*
- pip
run:
- python >=${{ python_min }}
- argcomplete >=3.5.2,<3.6.dev0
- azure-cli-telemetry ==1.1.0.*
- azure-mgmt-core >=1.2.0,<2
- cryptography
- distro
- humanfriendly >=10.0,<11.dev0
- jmespath
- knack >=0.11.0,<0.12.dev0
- microsoft-security-utilities-secret-masker >=1.0.0b4,<1.1.dev0
- msal ==1.33.0b1
- packaging >=20.9
- pkginfo >=1.5.0.1
- psutil >=5.9
- py-deviceid
- pyjwt >=2.1.0
- pyopenssl >=17.1.0
- requests
- msal-extensions ==1.2.0
tests:
- python:
imports:
- azure
- azure.cli
- azure.cli.core
- azure.cli.core.commands
- azure.cli.core.extension
- azure.cli.core.profiles
python_version: ${{ python_min }}.*

about:
license: MIT
license_file: LICENSE
summary: Microsoft Azure Command-Line Tools Core Module
homepage: https://github.com/Azure/azure-cli
repository: https://github.com/Azure/azure-cli
documentation: https://docs.microsoft.com/en-us/cli/azure

extra:
recipe-maintainers:
- dhirschfeld
- andreyz4k
- janjagusch
""",
)
],
)
def test_apply_dep_update_v1(
recipe: str, dep_comparison: DepComparison, new_recipe: str, tmp_path: Path
):
recipe_file = tmp_path / "recipe.yaml"
recipe_file.write_text(recipe)
apply_dep_update(tmp_path, dep_comparison=dep_comparison)
breakpoint()
assert recipe_file.read_text() == new_recipe
3 changes: 2 additions & 1 deletion tests_integration/lib/_definitions/__init__.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
from . import conda_forge_pinning, pydantic
from . import azure_cli_core, conda_forge_pinning, pydantic
from .base_classes import AbstractIntegrationTestHelper, GitHubAccount, TestCase

TEST_CASE_MAPPING: dict[str, list[TestCase]] = {
"azure-cli-core": azure_cli_core.ALL_TEST_CASES,
"conda-forge-pinning": conda_forge_pinning.ALL_TEST_CASES,
"pydantic": pydantic.ALL_TEST_CASES,
}
Expand Down
Loading