From e2576125e4e62323d95791a5889ea174a2607001 Mon Sep 17 00:00:00 2001 From: Charles Bousseau Date: Wed, 18 Oct 2023 11:51:27 -0400 Subject: [PATCH 01/10] add util function to get path of a dep --- anaconda_linter/utils.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/anaconda_linter/utils.py b/anaconda_linter/utils.py index 69f28b57..6f9c76e6 100644 --- a/anaconda_linter/utils.py +++ b/anaconda_linter/utils.py @@ -213,6 +213,15 @@ def ensure_list(obj): return [obj] +def get_dep_path(recipe, dep): + for n, spec in enumerate(recipe.get(dep.path, [])): + if spec is None: # Fixme: lint this + continue + if spec == dep.raw_dep: + return f"{dep.path}/{n}" + return dep.path + + def get_deps_dict(recipe, sections=None, outputs=True): if not sections: sections = ("build", "run", "host") From e0814735613edfbe7dde9f715f99137b6e44c121 Mon Sep 17 00:00:00 2001 From: Charles Bousseau Date: Wed, 18 Oct 2023 11:51:44 -0400 Subject: [PATCH 02/10] set percy to >=0.1.0,<0.2.0 --- environment.yaml | 2 +- recipe/meta.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/environment.yaml b/environment.yaml index d8863c5f..6e487359 100644 --- a/environment.yaml +++ b/environment.yaml @@ -8,7 +8,7 @@ dependencies: - setuptools - pip # run - - percy ==0.0.5 + - percy >=0.1.0,<0.2.0 - ruamel.yaml - license-expression - jinja2 diff --git a/recipe/meta.yaml b/recipe/meta.yaml index 68cc2cd9..77a640bd 100644 --- a/recipe/meta.yaml +++ b/recipe/meta.yaml @@ -30,7 +30,7 @@ requirements: - conda-build - jsonschema - networkx - - percy ==0.0.5 + - percy >=0.1.0,<0.2.0 test: source_files: From 46582023d0ea4d1283f17382029f89d99b787fb5 Mon Sep 17 00:00:00 2001 From: Charles Bousseau Date: Wed, 18 Oct 2023 11:52:49 -0400 Subject: [PATCH 03/10] correct typo --- anaconda_linter/lint/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/anaconda_linter/lint/__init__.py b/anaconda_linter/lint/__init__.py index d536398b..9f9a9b2f 100644 --- a/anaconda_linter/lint/__init__.py +++ b/anaconda_linter/lint/__init__.py @@ -27,7 +27,7 @@ - The class property ``requires`` may contain a list of other check classes that are required to have passed before this check is executed. Use this to avoid duplicate errors presented, or to - ensure that asumptions made by your check are met by the recipe. + ensure that assumptions made by your check are met by the recipe. - Each class is instantiated once per linting run. Do slow preparation work in the constructor. E.g. the `recipe_in_blocklist` check From 2d348a5415e0d2e586e7346507bc491669f49b9a Mon Sep 17 00:00:00 2001 From: Charles Bousseau Date: Wed, 18 Oct 2023 11:53:03 -0400 Subject: [PATCH 04/10] update build checks and add fixes --- anaconda_linter/lint/check_build_help.py | 172 +++++++++++++++-------- 1 file changed, 113 insertions(+), 59 deletions(-) diff --git a/anaconda_linter/lint/check_build_help.py b/anaconda_linter/lint/check_build_help.py index f9a9ceed..ebb9576d 100644 --- a/anaconda_linter/lint/check_build_help.py +++ b/anaconda_linter/lint/check_build_help.py @@ -7,6 +7,7 @@ import os import re +from pathlib import Path from typing import Any from .. import utils as _utils @@ -115,7 +116,8 @@ def recipe_has_patches(recipe): class host_section_needs_exact_pinnings(LintCheck): - """Packages in host must have exact version pinnings, except python build tools. + """Linked libraries host should have exact version pinnings. + Other dependencies are case by case. Specifically, comparison operators must not be used. The version numbers can be specified in a conda_build_config.yaml file. @@ -131,7 +133,7 @@ def check_recipe(self, recipe): if constraint == "" or re.search("^[<>!]", constraint) is not None: path = dep["paths"][c] output = -1 if not path.startswith("outputs") else int(path.split("/")[1]) - self.message(section=path, output=output) + self.message(section=path, severity=WARNING, output=output) @staticmethod def is_exception(package): @@ -145,7 +147,44 @@ def is_exception(package): # It doesn't make sense to pin the versions of hatch plugins if we're not pinning # hatch. We could explicitly enumerate the 15 odd plugins in PYTHON_BUILD_TOOLS, but # this seemed lower maintenance - return (package in exceptions) or package.startswith("hatch-") + return (package in exceptions) or any( + [package.startswith(f"{pkg}-") for pkg in PYTHON_BUILD_TOOLS] + ) + + +class cbc_dep_in_run_missing_from_host(LintCheck): + """Run dependencies listed in the cbc should also be present in the host section.""" + + def check_recipe(self, recipe): + for package in recipe.packages.values(): + for dep in package.run: + if dep.pkg in recipe.selector_dict and recipe.selector_dict[dep.pkg]: + if not self.is_exception(dep.pkg) and not package.has_dep("host", dep.pkg): + dep_path = _utils.get_dep_path(recipe, dep) + self.message( + section=dep_path, + data=(recipe, f"{package.path_prefix}requirements/host", dep.pkg), + ) + + @staticmethod + def is_exception(package): + exceptions = ( + "python", + "numpy", + ) + return package in exceptions + + def fix(self, _message, _data): + (recipe, path, dep) = _data + op = [ + { + "op": "add", + "path": path, + "match": f"{dep}.*", + "value": [f"{dep} " + "{{ " + f"{dep}" + " }}"], + }, + ] + return recipe.patch(op) class should_use_compilers(LintCheck): @@ -337,36 +376,50 @@ def _check_line(line: str) -> bool: return False return True - def check_deps(self, deps): - if "setuptools" not in deps: - return # no setuptools, no problem - - for path in deps["setuptools"]["paths"]: - if path.startswith("output"): - n = path.split("/")[1] - script = f"outputs/{n}/script" - output = int(n) - else: - script = "build/script" - output = -1 - if self.recipe.contains(script, "setup.py install", ""): - self.message(section=script) - continue - if self.recipe.dir: + def check_recipe(self, recipe): + for package in recipe.packages.values(): + if not self._check_line(recipe.get(f"{package.path_prefix}build/script", "")): + self.message( + section=f"{package.path_prefix}build/script", + data=(recipe, f"{package.path_prefix}build/script"), + ) + elif not self._check_line(recipe.get(f"{package.path_prefix}/script", "")): + self.message( + section=f"{package.path_prefix}script", + data=(recipe, f"{package.path_prefix}script"), + ) + elif self.recipe.dir: try: - if script == "build/script": - build_file = "build.sh" - else: - build_file = self.recipe.get(script, "") + build_file = self.recipe.get(f"{package.path_prefix}script", "") if not build_file: - continue - with open(os.path.join(self.recipe.dir, build_file)) as buildsh: - for num, line in enumerate(buildsh): - if not self._check_line(line): - self.message(fname=build_file, line=num, output=output) + build_file = self.recipe.get( + f"{package.path_prefix}build/script", "build.sh" + ) + build_file = self.recipe.dir / Path(build_file) + if build_file.exists(): + with open(str(build_file)) as buildsh: + for num, line in enumerate(buildsh): + if not self._check_line(line): + if package.path_prefix.startswith("output"): + output = int(package.path_prefix.split("/")[1]) + else: + output = -1 + self.message(fname=build_file, line=num, output=output) except FileNotFoundError: pass + def fix(self, _message, _data): + (recipe, path) = _data + op = [ + { + "op": "replace", + "path": path, + "match": ".* setup.py .*", + "value": "{{PYTHON}} -m pip install . --no-deps --no-build-isolation --ignore-installed --no-cache-dir -vv", # noqa: E501 + }, + ] + return recipe.patch(op) + class pip_install_args(LintCheck): """`pip install` should be run with --no-deps and --no-build-isolation. @@ -393,45 +446,46 @@ def _check_line(x: Any) -> bool: return True - def check_deps(self, deps): - if "pip" not in deps: - return # no pip, no problem - - for path in deps["pip"]["paths"]: - if path.startswith("output"): - n = path.split("/")[1] - script = f"outputs/{n}/script" - output = int(n) - else: - script = "build/script" - output = -1 - if not self._check_line(self.recipe.get(script, "")): - self.message(section=script, data=self.recipe) - continue - if self.recipe.dir: + def check_recipe(self, recipe): + for package in recipe.packages.values(): + if not self._check_line(recipe.get(f"{package.path_prefix}build/script", "")): + self.message( + section=f"{package.path_prefix}build/script", + data=(recipe, f"{package.path_prefix}build/script"), + ) + elif not self._check_line(recipe.get(f"{package.path_prefix}/script", "")): + self.message( + section=f"{package.path_prefix}script", + data=(recipe, f"{package.path_prefix}script"), + ) + elif self.recipe.dir: try: - if script == "build/script": - build_file = "build.sh" - else: - build_file = self.recipe.get(script, "") + build_file = self.recipe.get(f"{package.path_prefix}script", "") if not build_file: - continue - with open(os.path.join(self.recipe.dir, build_file)) as buildsh: - for num, line in enumerate(buildsh): - if not self._check_line(line): - self.message( - fname=build_file, line=num, output=output, data=self.recipe - ) + build_file = self.recipe.get( + f"{package.path_prefix}build/script", "build.sh" + ) + build_file = self.recipe.dir / Path(build_file) + if build_file.exists(): + with open(str(build_file)) as buildsh: + for num, line in enumerate(buildsh): + if not self._check_line(line): + if package.path_prefix.startswith("output"): + output = int(package.path_prefix.split("/")[1]) + else: + output = -1 + self.message(fname=build_file, line=num, output=output) except FileNotFoundError: pass - def fix(self, _message, recipe): + def fix(self, _message, _data): + (recipe, path) = _data op = [ { "op": "replace", - "path": "@output/build/script", - "match": "pip install(?!=.*--no-build-isolation).*", - "value": "pip install . --no-deps --no-build-isolation --ignore-installed --no-cache-dir -vv", + "path": path, + "match": r"(.*\s)?pip install(?!=.*--no-build-isolation).*", + "value": "{{ PYTHON }} -m pip install . --no-deps --no-build-isolation --ignore-installed --no-cache-dir -vv", # noqa: E501 }, ] return recipe.patch(op) From 67e9be94b5aeca9eb307bd14fdd9bd6ed89c57e2 Mon Sep 17 00:00:00 2001 From: Charles Bousseau Date: Wed, 18 Oct 2023 11:53:12 -0400 Subject: [PATCH 05/10] Update changelog --- CHANGELOG.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6721e7ac..dbee5289 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,12 @@ Note: version releases in the 0.x.y range may introduce breaking changes. ## 0.1.1 - +- Add knowledge of Python build backends to the missing_wheel rule +- Relax host_section_needs_exact_pinnings +- Add cbc_dep_in_run_missing_from_host +- Make uses_setup_py an error +- Add auto-fix for cbc_dep_in_run_missing_from_host, uses_setup_py, pip_install_args +- Update percy to >=0.1.0,<0.2.0 ## 0.1.0 - Use percy as render backend From 1262a8f6b3a983d68262b3aa161884e8c4b264ff Mon Sep 17 00:00:00 2001 From: Charles Bousseau Date: Wed, 18 Oct 2023 15:50:04 -0400 Subject: [PATCH 06/10] update tests --- anaconda_linter/lint/check_build_help.py | 19 +++-- anaconda_linter/lint_names.md | 2 + tests/conftest.py | 7 +- tests/test_build_help.py | 96 +++++++++++++++++++++++- 4 files changed, 113 insertions(+), 11 deletions(-) diff --git a/anaconda_linter/lint/check_build_help.py b/anaconda_linter/lint/check_build_help.py index ebb9576d..8fb4c29b 100644 --- a/anaconda_linter/lint/check_build_help.py +++ b/anaconda_linter/lint/check_build_help.py @@ -370,20 +370,25 @@ class uses_setup_py(LintCheck): """ @staticmethod - def _check_line(line: str) -> bool: + def _check_line(x: str) -> bool: """Check a line for a broken call to setup.py""" - if "setup.py install" in line: - return False + if isinstance(x, str): + x = [x] + elif not isinstance(x, list): + return True + for line in x: + if "setup.py install" in line: + return False return True def check_recipe(self, recipe): for package in recipe.packages.values(): - if not self._check_line(recipe.get(f"{package.path_prefix}build/script", "")): + if not self._check_line(recipe.get(f"{package.path_prefix}build/script", None)): self.message( section=f"{package.path_prefix}build/script", data=(recipe, f"{package.path_prefix}build/script"), ) - elif not self._check_line(recipe.get(f"{package.path_prefix}/script", "")): + elif not self._check_line(recipe.get(f"{package.path_prefix}script", None)): self.message( section=f"{package.path_prefix}script", data=(recipe, f"{package.path_prefix}script"), @@ -448,12 +453,12 @@ def _check_line(x: Any) -> bool: def check_recipe(self, recipe): for package in recipe.packages.values(): - if not self._check_line(recipe.get(f"{package.path_prefix}build/script", "")): + if not self._check_line(recipe.get(f"{package.path_prefix}build/script", None)): self.message( section=f"{package.path_prefix}build/script", data=(recipe, f"{package.path_prefix}build/script"), ) - elif not self._check_line(recipe.get(f"{package.path_prefix}/script", "")): + elif not self._check_line(recipe.get(f"{package.path_prefix}script", None)): self.message( section=f"{package.path_prefix}script", data=(recipe, f"{package.path_prefix}script"), diff --git a/anaconda_linter/lint_names.md b/anaconda_linter/lint_names.md index 0d129bcb..181d5166 100644 --- a/anaconda_linter/lint_names.md +++ b/anaconda_linter/lint_names.md @@ -121,3 +121,5 @@ yaml_load_failure missing_package_name missing_package_version + +cbc_dep_in_run_missing_from_host diff --git a/tests/conftest.py b/tests/conftest.py index 93b8354d..a4ef96d7 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -35,14 +35,17 @@ def recipe_dir(tmpdir): return recipe_directory -def check(check_name, recipe_str, arch="linux-64"): +def check(check_name, recipe_str, arch="linux-64", expand_variant=None): config_file = Path(__file__).parent / "config.yaml" config = utils.load_config(str(config_file.resolve())) linter = Linter(config=config) + variant = config[arch] + if expand_variant: + variant.update(expand_variant) recipe = Recipe.from_string( recipe_text=recipe_str, variant_id="dummy", - variant=config[arch], + variant=variant, renderer=RendererType.RUAMEL, ) messages = linter.check_instances[check_name].run(recipe=recipe) diff --git a/tests/test_build_help.py b/tests/test_build_help.py index 176e8a97..0f4ba30e 100644 --- a/tests/test_build_help.py +++ b/tests/test_build_help.py @@ -159,7 +159,10 @@ def test_host_section_needs_exact_pinnings_bad(base_yaml, constraint): ) lint_check = "host_section_needs_exact_pinnings" messages = check(lint_check, yaml_str) - assert len(messages) == 1 and "must have exact version pinnings" in messages[0].title + assert ( + len(messages) == 1 + and "Linked libraries host should have exact version pinnings." in messages[0].title + ) @pytest.mark.parametrize("constraint", ("", ">=0.13", "<0.14", "!=0.13.7")) @@ -181,7 +184,7 @@ def test_host_section_needs_exact_pinnings_bad_multi(base_yaml, constraint): lint_check = "host_section_needs_exact_pinnings" messages = check(lint_check, yaml_str) assert len(messages) == 2 and all( - "must have exact version pinnings" in msg.title for msg in messages + "Linked libraries host should have exact version pinnings." in msg.title for msg in messages ) @@ -2986,3 +2989,92 @@ def test_gui_app_bad(base_yaml, gui): ) messages = check(lint_check, yaml_str) assert len(messages) == 1 and "GUI application" in messages[0].title + + +def test_cbc_dep_in_run_missing_from_host_good(base_yaml): + yaml_str = ( + base_yaml + + """ + requirements: + host: + - python + - hdf5 + run: + - python + - hdf5 + """ + ) + lint_check = "cbc_dep_in_run_missing_from_host" + messages = check(lint_check, yaml_str) + assert len(messages) == 0 + + +def test_cbc_dep_in_run_missing_from_host_good_multi(base_yaml): + yaml_str = ( + base_yaml + + """ + outputs: + - name: output1 + requirements: + host: + - python + - hdf5 + run: + - python + - hdf5 + - name: output2 + requirements: + host: + - python + - hdf5 + run: + - python + - hdf5 + """ + ) + lint_check = "cbc_dep_in_run_missing_from_host" + messages = check(lint_check, yaml_str) + assert len(messages) == 0 + + +def test_cbc_dep_in_run_missing_from_host_bad(base_yaml): + yaml_str = ( + base_yaml + + """ + requirements: + host: + - python + run: + - python + - hdf5 + """ + ) + lint_check = "cbc_dep_in_run_missing_from_host" + messages = check(lint_check, yaml_str, "linux-64", {"hdf5": "1.2.3"}) + assert len(messages) == 1 + + +def test_cbc_dep_in_run_missing_from_host_bad_multi(base_yaml): + yaml_str = ( + base_yaml + + """ + outputs: + - name: output1 + requirements: + host: + - python + run: + - python + - hdf5 + - name: output2 + requirements: + host: + - python + run: + - python + - hdf5 + """ + ) + lint_check = "cbc_dep_in_run_missing_from_host" + messages = check(lint_check, yaml_str, "linux-64", {"hdf5": "1.2.3"}) + assert len(messages) == 2 From febd2da4ea0c3e6fb41b7d6c95d47e6bd8a55ae9 Mon Sep 17 00:00:00 2001 From: Charles Bousseau Date: Wed, 18 Oct 2023 15:58:39 -0400 Subject: [PATCH 07/10] Add wrong_output_script_key check --- CHANGELOG.md | 1 + anaconda_linter/lint/check_completeness.py | 23 +++++++++++++++++ anaconda_linter/lint_names.md | 2 ++ tests/test_completeness.py | 29 ++++++++++++++++++++++ 4 files changed, 55 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index dbee5289..6f6b5f2f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ Note: version releases in the 0.x.y range may introduce breaking changes. - Make uses_setup_py an error - Add auto-fix for cbc_dep_in_run_missing_from_host, uses_setup_py, pip_install_args - Update percy to >=0.1.0,<0.2.0 +- Add wrong_output_script_key ## 0.1.0 - Use percy as render backend diff --git a/anaconda_linter/lint/check_completeness.py b/anaconda_linter/lint/check_completeness.py index 5e4a7760..2c997b2f 100644 --- a/anaconda_linter/lint/check_completeness.py +++ b/anaconda_linter/lint/check_completeness.py @@ -391,3 +391,26 @@ class missing_description(LintCheck): def check_recipe(self, recipe): if not recipe.get("about/description", ""): self.message(section="about", severity=WARNING) + + +class wrong_output_script_key(LintCheck): + """It should be `outputs/x/script`, not `outputs/x/build/script` + + Please change from:: + outputs: + - name: output1 + build: + script: build_script.sh + + To:: + + outputs: + - name: output1 + script: build_script.sh + """ + + def check_recipe(self, recipe): + for package in recipe.packages.values(): + if package.path_prefix.startswith("outputs"): + if recipe.get(f"{package.path_prefix}build/script", None): + self.message(section=f"{package.path_prefix}build/script") diff --git a/anaconda_linter/lint_names.md b/anaconda_linter/lint_names.md index 181d5166..d6fc4d11 100644 --- a/anaconda_linter/lint_names.md +++ b/anaconda_linter/lint_names.md @@ -123,3 +123,5 @@ missing_package_name missing_package_version cbc_dep_in_run_missing_from_host + +wrong_output_script_key diff --git a/tests/test_completeness.py b/tests/test_completeness.py index 7d55a74e..49456936 100644 --- a/tests/test_completeness.py +++ b/tests/test_completeness.py @@ -650,3 +650,32 @@ def test_missing_description_bad(base_yaml): lint_check = "missing_description" messages = check(lint_check, yaml_str) assert len(messages) == 1 and "missing a description" in messages[0].title + + +def test_wrong_output_script_key_good(base_yaml): + yaml_str = ( + base_yaml + + """ + outputs: + - name: output1 + script: build_script.sh + """ + ) + lint_check = "wrong_output_script_key" + messages = check(lint_check, yaml_str) + assert len(messages) == 0 + + +def test_wrong_output_script_key_bad(base_yaml): + yaml_str = ( + base_yaml + + """ + outputs: + - name: output1 + build: + script: build_script.sh + """ + ) + lint_check = "wrong_output_script_key" + messages = check(lint_check, yaml_str) + assert len(messages) == 1 From ae591b371addea5045be099873343bc68e101ac2 Mon Sep 17 00:00:00 2001 From: Charles Bousseau Date: Wed, 18 Oct 2023 16:14:02 -0400 Subject: [PATCH 08/10] Add potentially_bad_ignore_run_exports --- CHANGELOG.md | 1 + anaconda_linter/lint/check_build_help.py | 10 ++++ anaconda_linter/lint_names.md | 2 + tests/test_build_help.py | 76 ++++++++++++++++++++++++ 4 files changed, 89 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6f6b5f2f..489fcf67 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ Note: version releases in the 0.x.y range may introduce breaking changes. - Add auto-fix for cbc_dep_in_run_missing_from_host, uses_setup_py, pip_install_args - Update percy to >=0.1.0,<0.2.0 - Add wrong_output_script_key +- Add potentially_bad_ignore_run_exports ## 0.1.0 - Use percy as render backend diff --git a/anaconda_linter/lint/check_build_help.py b/anaconda_linter/lint/check_build_help.py index 8fb4c29b..9db25d21 100644 --- a/anaconda_linter/lint/check_build_help.py +++ b/anaconda_linter/lint/check_build_help.py @@ -187,6 +187,16 @@ def fix(self, _message, _data): return recipe.patch(op) +class potentially_bad_ignore_run_exports(LintCheck): + """Ignoring run_export of a host dependency. In some cases it is more appropriate to remove the --error-overdepending flag of conda-build.""" + + def check_recipe(self, recipe): + for package in recipe.packages.values(): + for dep in package.host: + if dep.pkg in package.ignore_run_exports: + self.message(section=_utils.get_dep_path(recipe, dep), severity=INFO) + + class should_use_compilers(LintCheck): """The recipe requires a compiler directly diff --git a/anaconda_linter/lint_names.md b/anaconda_linter/lint_names.md index d6fc4d11..ed270070 100644 --- a/anaconda_linter/lint_names.md +++ b/anaconda_linter/lint_names.md @@ -125,3 +125,5 @@ missing_package_version cbc_dep_in_run_missing_from_host wrong_output_script_key + +potentially_bad_ignore_run_exports diff --git a/tests/test_build_help.py b/tests/test_build_help.py index 0f4ba30e..8bdd1129 100644 --- a/tests/test_build_help.py +++ b/tests/test_build_help.py @@ -3078,3 +3078,79 @@ def test_cbc_dep_in_run_missing_from_host_bad_multi(base_yaml): lint_check = "cbc_dep_in_run_missing_from_host" messages = check(lint_check, yaml_str, "linux-64", {"hdf5": "1.2.3"}) assert len(messages) == 2 + + +def test_potentially_bad_ignore_run_exports_good(base_yaml): + yaml_str = ( + base_yaml + + """ + + build: + ignore_run_exports: + - bb + requirements: + host: + - aa + """ + ) + lint_check = "potentially_bad_ignore_run_exports" + messages = check(lint_check, yaml_str) + assert len(messages) == 0 + + +def test_potentially_bad_ignore_run_exports_good_multi(base_yaml): + yaml_str = ( + base_yaml + + """ + + outputs: + - name: output1 + build: + ignore_run_exports: + - bb + requirements: + host: + - aa + """ + ) + lint_check = "potentially_bad_ignore_run_exports" + messages = check(lint_check, yaml_str) + assert len(messages) == 0 + + +def test_potentially_bad_ignore_run_exports_bad(base_yaml): + yaml_str = ( + base_yaml + + """ + + build: + ignore_run_exports: + - aa + requirements: + host: + - aa + """ + ) + lint_check = "potentially_bad_ignore_run_exports" + messages = check(lint_check, yaml_str) + assert len(messages) == 1 + + +def test_potentially_bad_ignore_run_exports_bad_multi(base_yaml): + yaml_str = ( + base_yaml + + """ + + outputs: + - name: output1 + build: + ignore_run_exports: + - aa + requirements: + host: + - aa + """ + ) + lint_check = "potentially_bad_ignore_run_exports" + messages = check(lint_check, yaml_str) + assert len(messages) == 1 From e3d992a3a933c2e0b82f46a023c59a89bae6b124 Mon Sep 17 00:00:00 2001 From: Charles Bousseau Date: Wed, 18 Oct 2023 16:17:28 -0400 Subject: [PATCH 09/10] make linter happy --- anaconda_linter/lint/check_build_help.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/anaconda_linter/lint/check_build_help.py b/anaconda_linter/lint/check_build_help.py index 9db25d21..34830793 100644 --- a/anaconda_linter/lint/check_build_help.py +++ b/anaconda_linter/lint/check_build_help.py @@ -188,7 +188,7 @@ def fix(self, _message, _data): class potentially_bad_ignore_run_exports(LintCheck): - """Ignoring run_export of a host dependency. In some cases it is more appropriate to remove the --error-overdepending flag of conda-build.""" + """Ignoring run_export of a host dependency. In some cases it is more appropriate to remove the --error-overdepending flag of conda-build.""" # noqa: E501 def check_recipe(self, recipe): for package in recipe.packages.values(): From 1101fcde11b5f8369f624c706bd54ed2c8000465 Mon Sep 17 00:00:00 2001 From: Charles Bousseau Date: Wed, 18 Oct 2023 16:20:50 -0400 Subject: [PATCH 10/10] also make black happy... --- anaconda_linter/lint/check_build_help.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/anaconda_linter/lint/check_build_help.py b/anaconda_linter/lint/check_build_help.py index 34830793..e8a3e529 100644 --- a/anaconda_linter/lint/check_build_help.py +++ b/anaconda_linter/lint/check_build_help.py @@ -188,7 +188,7 @@ def fix(self, _message, _data): class potentially_bad_ignore_run_exports(LintCheck): - """Ignoring run_export of a host dependency. In some cases it is more appropriate to remove the --error-overdepending flag of conda-build.""" # noqa: E501 + """Ignoring run_export of a host dependency. In some cases it is more appropriate to remove the --error-overdepending flag of conda-build.""" # noqa: E501 def check_recipe(self, recipe): for package in recipe.packages.values():