Skip to content

Commit

Permalink
Add a check for v0 selectors in v1 recipes (#2214)
Browse files Browse the repository at this point in the history
* Add a check for v0 selectors in v1 recipes

Fixes #2181

* Add a news entry

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Update conda_smithy/linter/lints.py

* Update tests/test_lint_recipe.py

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Matthew R. Becker <[email protected]>
  • Loading branch information
3 people authored Jan 13, 2025
1 parent 7ccd378 commit cd92ab0
Show file tree
Hide file tree
Showing 5 changed files with 98 additions and 3 deletions.
5 changes: 5 additions & 0 deletions conda_smithy/lint_recipe.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
lint_license_cannot_be_unknown,
lint_license_family_should_be_valid,
lint_license_should_not_have_license,
lint_no_comment_selectors,
lint_noarch,
lint_noarch_and_runtime_dependencies,
lint_non_noarch_builds,
Expand Down Expand Up @@ -200,6 +201,10 @@ def lintify_meta_yaml(
# v1 does not have selectors in comments form
lint_selectors_should_be_in_tidy_form(recipe_fname, lints, hints)

# 6a: Comment-style selectors must not be used in v1 recipes.
if recipe_version == 1:
lint_no_comment_selectors(recipe_fname, lints, hints)

# 7: The build section should have a build number.
lint_build_section_should_have_a_number(build_section, lints)

Expand Down
15 changes: 15 additions & 0 deletions conda_smithy/linter/lints.py
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,21 @@ def lint_selectors_should_be_in_tidy_form(recipe_fname, lints, hints):
)


def lint_no_comment_selectors(recipe_fname, lints, hints):
bad_lines = []
if os.path.exists(recipe_fname):
with open(recipe_fname) as fh:
for selector_line, line_number in selector_lines(
fh, only_in_comment=True
):
bad_lines.append(line_number)
if bad_lines:
lints.append(
"Selectors in comment form no longer work in v1 recipes. Instead,"
f" if / then / else maps must be used. See lines {bad_lines}."
)


def lint_build_section_should_have_a_number(build_section, lints):
if build_section.get("number", None) is None:
lints.append("The recipe must have a `build/number` section.")
Expand Down
10 changes: 7 additions & 3 deletions conda_smithy/linter/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,9 @@ def find_local_config_file(recipe_dir: str, filename: str) -> Optional[str]:
return found_filesname[0] if found_filesname else None


def is_selector_line(line, allow_platforms=False, allow_keys=set()):
def is_selector_line(
line, allow_platforms=False, allow_keys=set(), only_in_comment=False
):
# Using the same pattern defined in conda-build (metadata.py),
# we identify selectors.
line = line.rstrip()
Expand All @@ -155,6 +157,8 @@ def is_selector_line(line, allow_platforms=False, allow_keys=set()):
return False
m = sel_pat.match(line)
if m:
if only_in_comment and not m.group(2):
return False
nouns = {
w for w in m.group(3).split() if w not in ("not", "and", "or")
}
Expand All @@ -179,9 +183,9 @@ def is_jinja_line(line):
return False


def selector_lines(lines):
def selector_lines(lines, only_in_comment=False):
for i, line in enumerate(lines):
if is_selector_line(line):
if is_selector_line(line, only_in_comment=only_in_comment):
yield line, i


Expand Down
23 changes: 23 additions & 0 deletions news/v0-selectors-in-v1-recipe.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
**Added:**

* Added a linter check for use of v0 selectors in v1 recipes. (#2214)

**Changed:**

* <news item>

**Deprecated:**

* <news item>

**Removed:**

* <news item>

**Fixed:**

* <news item>

**Security:**

* <news item>
48 changes: 48 additions & 0 deletions tests/test_lint_recipe.py
Original file line number Diff line number Diff line change
Expand Up @@ -3924,5 +3924,53 @@ def test_lint_recipe_v1_python_min_in_python_version():
assert hints == []


def test_lint_recipe_v1_comment_selectors():
with tempfile.TemporaryDirectory() as tmpdir:
with open(os.path.join(tmpdir, "recipe.yaml"), "w") as f:
f.write(
textwrap.dedent(
"""
package:
name: test
version: 1.2.3
build:
number: 0
requirements:
host:
- foo # [unix]
# check for false positives with strings that look like
# old-style (non-comment) selectors
- bar =1.2.3 [build=${{ torch_proc_type }}*]
run:
- bar =1.2.3 [build=${{ torch_proc_type }}*] # [py==312]
# this is some [comment]
tests:
- script:
- false # [linux64]
- true # [osx or win]
about:
summary: test
homepage: https://example.com
license: MIT
license_file: COPYING
extra:
recipe-maintainers:
- a
"""
)
)
lints, _ = linter.main(tmpdir, return_hints=True, conda_forge=True)
assert lints == [
"Selectors in comment form no longer work in v1 recipes. "
"Instead, if / then / else maps must be used. "
"See lines [10, 15, 20, 21]."
]


if __name__ == "__main__":
unittest.main()

0 comments on commit cd92ab0

Please sign in to comment.