diff --git a/conda_recipe_manager/parser/recipe_parser_convert.py b/conda_recipe_manager/parser/recipe_parser_convert.py index a287d3d6..819be276 100644 --- a/conda_recipe_manager/parser/recipe_parser_convert.py +++ b/conda_recipe_manager/parser/recipe_parser_convert.py @@ -31,6 +31,17 @@ class RecipeParserConvert(RecipeParserDeps): # "Static", one-time initialization of the the SPDX utility class. As this module is "read-only", we only need one # instance allocated for all converter-parsers that are initialized. _SPDX_UTILS: Final = SpdxUtils() + _ARCHIVE_SOURCE_SUFFIXES: Final[tuple[str, ...]] = ( + ".tar", + ".tar.bz2", + ".tar.gz", + ".tar.xz", + ".tar.zst", + ".tbz2", + ".tgz", + ".txz", + ".zip", + ) def __init__(self, content: str, flags: RecipeReaderFlags = RecipeReaderFlags.NONE): """ @@ -129,6 +140,23 @@ def _patch_move_new_path(self, base_path: str, old_ext: str, new_path: str, new_ self._patch_add_missing_path(base_path, new_path) self._patch_move_base_path(base_path, old_ext, RecipeParser.append_to_path(new_path, new_ext)) + def _source_has_archive_url(self, src_path: str) -> bool: + """ + Detects URL-based archive sources, whose V0 `fn` field cannot be translated to V1 `file_name`. + + :param src_path: Path to a source entry + :returns: True if the source URL looks like an archive + """ + url_path: Final[str] = RecipeParser.append_to_path(src_path, "/url") + if not self._v1_recipe.contains_value(url_path): + return False + + url = self._v1_recipe.get_value(url_path) + if not isinstance(url, str): + return False + + return url.lower().endswith(self._ARCHIVE_SOURCE_SUFFIXES) + def _patch_deprecated_fields(self, base_path: str, fields: list[str]) -> None: """ Automatically deprecates fields found in a common path. @@ -467,7 +495,15 @@ def _upgrade_source_section(self, base_package_paths: list[str]) -> None: ) # Basic renaming transformations - self._patch_move_base_path(src_path, "/fn", "/file_name") + fn_path = RecipeParser.append_to_path(src_path, "/fn") + if self._v1_recipe.contains_value(fn_path) and self._source_has_archive_url(src_path): + if self._patch_and_log({"op": "remove", "path": fn_path}): + self._msg_tbl.add_message( + MessageCategory.WARNING, + f"`fn` at `{fn_path}` was omitted because V1 `file_name` is invalid for archive sources.", + ) + else: + self._patch_move_base_path(src_path, "/fn", "/file_name") self._patch_move_base_path(src_path, "/folder", "/target_directory") # `git` source transformations (`conda` does not appear to support all of the new features) diff --git a/tests/parser/test_recipe_parser_convert.py b/tests/parser/test_recipe_parser_convert.py index 3a47d730..bd8c2f89 100644 --- a/tests/parser/test_recipe_parser_convert.py +++ b/tests/parser/test_recipe_parser_convert.py @@ -82,6 +82,7 @@ def test_pre_process_recipe_text(input_file: str, expected_file: str) -> None: "pytest-pep8.yaml", [], [ + "`fn` at `/source/fn` was omitted because V1 `file_name` is invalid for archive sources.", "Field at `/about/doc_source_url` is no longer supported.", ], ), @@ -140,6 +141,7 @@ def test_pre_process_recipe_text(input_file: str, expected_file: str) -> None: "boto.yaml", [], [ + "`fn` at `/source/fn` was omitted because V1 `file_name` is invalid for archive sources.", "Field at `/about/doc_source_url` is no longer supported.", ], ), diff --git a/tests/test_aux_files/v1_format/v1_boto.yaml b/tests/test_aux_files/v1_format/v1_boto.yaml index ad592942..f873ecf8 100644 --- a/tests/test_aux_files/v1_format/v1_boto.yaml +++ b/tests/test_aux_files/v1_format/v1_boto.yaml @@ -11,7 +11,6 @@ package: source: url: https://pypi.org/packages/source/${{ name[0] }}/${{ name }}/${{ name }}-${{ version }}.tar.gz sha256: ea0d3b40a2d852767be77ca343b58a9e3a4b00d9db440efb8da74b4e58025e5a - file_name: ${{ name }}-${{ version }}.tar.gz build: number: 0 diff --git a/tests/test_aux_files/v1_format/v1_pytest-pep8.yaml b/tests/test_aux_files/v1_format/v1_pytest-pep8.yaml index 8a0eeae0..d2f35944 100644 --- a/tests/test_aux_files/v1_format/v1_pytest-pep8.yaml +++ b/tests/test_aux_files/v1_format/v1_pytest-pep8.yaml @@ -12,7 +12,6 @@ package: source: url: https://pypi.io/packages/source/${{ name[0] }}/${{ name }}/${{ name }}-${{ version }}.tar.gz sha256: ${{ sha256 }} - file_name: ${{ name }}-${{ version }}.tar.gz build: number: 1