From 8baf53b9525b3957c33fb5105a751ee742d33e5d Mon Sep 17 00:00:00 2001 From: Schuyler Martin Date: Tue, 13 Feb 2024 14:32:30 -0700 Subject: [PATCH] Handles `/about` section transformations for new format - Handles transformations found in the new `/about` section. See [here](https://github.com/conda-incubator/ceps/blob/main/cep-14.md#about-section) for more details --- percy/parser/recipe_parser.py | 43 ++++++++++- percy/tests/parser/test_recipe_parser.py | 2 +- .../new_format_huggingface_hub.yaml | 75 +++++++++++++++++++ 3 files changed, 118 insertions(+), 2 deletions(-) create mode 100644 percy/tests/test_aux_files/new_format_huggingface_hub.yaml diff --git a/percy/parser/recipe_parser.py b/percy/parser/recipe_parser.py index df15371..c18fe0b 100644 --- a/percy/parser/recipe_parser.py +++ b/percy/parser/recipe_parser.py @@ -769,7 +769,48 @@ def _patch_and_log(patch: JsonPatchType) -> None: _patch_and_log({"op": "add", "path": requirements_path, "value": None}) _patch_and_log({"op": "move", "from": old_ire_path, "path": new_ire_path}) - # TODO Complete: handle changes to the recipe structure and fields + ## `about` section changes and validation ## + # Warn if "required" fields are missing + about_required: Final[list[str]] = [ + "summary", + "description", + "license", + "license_file", + "license_url", + ] + for field in about_required: + path = f"/about/{field}" + if not new_recipe.contains_value(path): + msg_tbl.add_message(MessageCategory.WARNING, f"Required field missing: {path}") + + # Transform renamed fields + about_rename: Final[list[tuple[str, str]]] = [ + ("home", "homepage"), + ("dev_url", "repository"), + ("doc_url", "documentation"), + ] + for old, new in about_rename: + old_path = f"/about/{old}" + new_path = f"/about/{new}" + if new_recipe.contains_value(old_path): + _patch_and_log({"op": "move", "from": old_path, "path": new_path}) + + # TODO validate: /about/license must be SPDX recognized. + + # Remove deprecated `about` fields + about_deprecated: Final[list[str]] = [ + "prelink_message", + "license_family", + "identifiers", + "tags", + "keywords", + "doc_source_url", + ] + for field in about_deprecated: + path = f"/about/{field}" + if new_recipe.contains_value(path): + _patch_and_log({"op": "remove", "path": path}) + # TODO Complete: move operations may result in empty fields we can eliminate. This may require changes # to `contains_value()` diff --git a/percy/tests/parser/test_recipe_parser.py b/percy/tests/parser/test_recipe_parser.py index 835b2c0..79f9cef 100644 --- a/percy/tests/parser/test_recipe_parser.py +++ b/percy/tests/parser/test_recipe_parser.py @@ -317,7 +317,7 @@ def test_render_to_object_multi_output() -> None: } -@pytest.mark.parametrize("file_base", ["simple-recipe.yaml", "multi-output.yaml"]) +@pytest.mark.parametrize("file_base", ["simple-recipe.yaml", "multi-output.yaml", "huggingface_hub.yaml"]) def test_render_to_new_recipe_format(file_base: str) -> None: """ Validates rendering a recipe in the new format. diff --git a/percy/tests/test_aux_files/new_format_huggingface_hub.yaml b/percy/tests/test_aux_files/new_format_huggingface_hub.yaml new file mode 100644 index 0000000..4988ead --- /dev/null +++ b/percy/tests/test_aux_files/new_format_huggingface_hub.yaml @@ -0,0 +1,75 @@ +schema_version: 1 + +context: + name: huggingface_hub + version: 0.15.1 + +package: + name: ${{ name|lower }} + version: ${{ version }} + +source: + url: https://pypi.io/packages/source/${{ name[0] }}/${{ name }}/${{ name }}-${{ version }}.tar.gz + sha256: a61b7d1a7769fe10119e730277c72ab99d95c48d86a3d6da3e9f3d0f632a4081 + +build: + number: 0 + skip: ${{ true if py<37 }} + entry_points: + - huggingface-cli=huggingface_hub.commands.huggingface_cli:main + script: ${{ PYTHON }} -m pip install . --no-deps --no-build-isolation -vv + +requirements: + host: + - python + - pip + - setuptools + - wheel + run: + - python + - filelock + - fsspec + - if: py<38 + then: importlib-metadata + - packaging >=20.9 + - pyyaml >=5.1 + - requests + - tqdm >=4.42.1 + - typing-extensions >=3.7.4.3 + run_constrained: + - fastai >=2.4 + - fastcore >=1.3.27 + - InquirerPy ==0.3.4 + +test: + imports: + - huggingface_hub + - huggingface_hub.commands + requires: + - pip + commands: + - pip check + - huggingface-cli --help + +about: + summary: Client library to download and publish models, datasets and other repos on the huggingface.co hub + description: | + The huggingface_hub is a client library to interact with the Hugging Face Hub. The Hugging Face Hub is a platform with over 35K models, 4K datasets, and 2K demos in which people can easily collaborate in their ML workflows. The Hub works as a central place where anyone can share, explore, discover, and experiment with open-source Machine Learning. + + With huggingface_hub, you can easily download and upload models, datasets, and Spaces. You can extract useful information from the Hub, and do much more. Some example use cases: + + - Downloading and caching files from a Hub repository. + - Creating repositories and uploading an updated model every few epochs. + - Extract metadata from all models that match certain criteria (e.g. models for text-classification). + - List all files from a specific repository. + license: Apache-2.0 + license_file: LICENSE + homepage: https://github.com/huggingface/huggingface_hub + repository: https://github.com/huggingface/huggingface_hub + documentation: https://huggingface.co/docs/hub/index + +extra: + recipe-maintainers: + - BastianZim + skip-lints: + - python_build_tool_in_run