-
Notifications
You must be signed in to change notification settings - Fork 91
Add Grayskull feature for v1 recipes #4575
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 14 commits
b86effb
1864588
b953af0
79f2f40
796cd8c
8c23c27
59ac851
d530097
07fdc75
97217ec
f7dd2a1
cfa5343
4abbeda
6436bc4
e77f8e8
1c8f212
489ed1d
ef39d27
2329ad1
ee4f0fe
c21907a
2092c4f
e8bb9cb
5c5bddf
f4321e7
ef38259
d006cbb
cbdf760
6b2bbd1
042edf3
86536c9
a2b1cef
3e64431
5d7793a
f37fe40
b3bb35e
909340f
62fe221
2802ffb
e38e28f
17e49e1
78a8391
45992e3
c367c4d
e66ae2b
f4ed57f
32e467f
ebd015a
b623018
4ea9436
86821f9
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -63,3 +63,4 @@ pixi.toml | |
| venv | ||
| oryx-build-commands.txt | ||
| .env | ||
| .DS_Store | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -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 | ||
|
|
@@ -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 | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We have this function: https://github.com/janjagusch/cf-scripts/blob/4ea94367e58c1c1ddde009e8986ef4e9da21a35f/conda_forge_tick/utils.py#L191 Not sure if that is suitable or not. There is also this: https://github.com/janjagusch/cf-scripts/blob/add-runtime-requirements-test-for-v1-recipe/conda_forge_tick/recipe_parser/_parser.py#L50 |
||
|
|
||
| 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"] | ||
|
|
@@ -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] = {} | ||
janjagusch marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| 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"] | ||
| ) | ||
janjagusch marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| 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. | ||
|
|
||
|
|
@@ -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(): | ||
janjagusch marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| 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() | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.