Skip to content
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

allow selectors in noarch_platforms recipes #1682

Merged
merged 3 commits into from
Oct 29, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 40 additions & 10 deletions conda_smithy/lint_recipe.py
Original file line number Diff line number Diff line change
Expand Up @@ -384,8 +384,27 @@ def lintify(meta, recipe_dir=None, conda_forge=False):
)
)

if recipe_dir:
forge_yaml_filename = (
glob(os.path.join(recipe_dir, "..", "conda-forge.yml"))
or glob(
os.path.join(recipe_dir, "conda-forge.yml"),
)
or glob(
os.path.join(recipe_dir, "..", "..", "conda-forge.yml"),
)
)
if forge_yaml_filename:
with open(forge_yaml_filename[0], "r") as fh:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't we check for noarch_platforms in all existing conda-forge.ymls, not just the first one we found? Or is it guaranteed that only one exists?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's only one used.

forge_yaml = get_yaml().load(fh)
else:
forge_yaml = {}
else:
forge_yaml = {}

# 18: noarch doesn't work with selectors for runtime dependencies
if noarch_value is not None and os.path.exists(meta_fname):
noarch_platforms = len(forge_yaml.get("noarch_platforms", [])) > 1
with io.open(meta_fname, "rt") as fh:
in_runreqs = False
for line in fh:
Expand All @@ -396,7 +415,7 @@ def lintify(meta, recipe_dir=None, conda_forge=False):
continue
if line_s.startswith("skip:") and is_selector_line(line):
lints.append(
"`noarch` packages can't have selectors. If "
"`noarch` packages can't have skips with selectors. If "
"the selectors are necessary, please remove "
"`noarch: {}`.".format(noarch_value)
)
Expand All @@ -405,7 +424,9 @@ def lintify(meta, recipe_dir=None, conda_forge=False):
if runreqs_spacing == line[: -len(line.lstrip())]:
in_runreqs = False
continue
if is_selector_line(line):
if is_selector_line(
line, allow_platforms=noarch_platforms
):
lints.append(
"`noarch` packages can't have selectors. If "
"the selectors are necessary, please remove "
Expand Down Expand Up @@ -662,11 +683,18 @@ def check_pins_build_and_requirements(top_level):
shell_scripts = []
if recipe_dir:
shell_scripts = glob(os.path.join(recipe_dir, "*.sh"))
# support feedstocks and staged-recipes
forge_yaml = glob(
os.path.join(recipe_dir, "..", "conda-forge.yml")
) or glob(
os.path.join(recipe_dir, "..", "..", "conda-forge.yml"),
# support
# 1. feedstocks
# 2. staged-recipes with custom conda-forge.yaml in recipe
# 3. staged-recipes
forge_yaml = (
glob(os.path.join(recipe_dir, "..", "conda-forge.yml"))
or glob(
os.path.join(recipe_dir, "conda-forge.yml"),
)
or glob(
os.path.join(recipe_dir, "..", "..", "conda-forge.yml"),
)
)
if shell_scripts and forge_yaml:
with open(forge_yaml[0], "r") as fh:
Expand Down Expand Up @@ -904,7 +932,7 @@ def run_conda_forge_specific(meta, recipe_dir, lints, hints):
hints.append(msg)


def is_selector_line(line):
def is_selector_line(line, allow_platforms=False):
# Using the same pattern defined in conda-build (metadata.py),
# we identify selectors.
line = line.rstrip()
Expand All @@ -913,8 +941,10 @@ def is_selector_line(line):
return False
m = sel_pat.match(line)
if m:
m.group(3)
return True
if allow_platforms and m.group(3) in ["win", "linux", "osx", "unix"]:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't this also be the opposite? Meaning not win etc.?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Check #1735

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

return False
else:
return True
return False


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

* <news item>

**Changed:**

* recipes with ``noarch_platforms`` will no longer give a lint when selectors are used.

**Deprecated:**

* <news item>

**Removed:**

* <news item>

**Fixed:**

* <news item>

**Security:**

* <news item>
13 changes: 13 additions & 0 deletions tests/recipes/noarch_platforms/conda-forge.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
build_platform:
osx_arm64: osx_64
conda_forge_output_validation: true
github:
branch_name: main
tooling_branch_name: main
provider:
linux_aarch64: default
linux_ppc64le: default
test_on_native_only: true
noarch_platforms:
- linux_64
- win_64
71 changes: 71 additions & 0 deletions tests/recipes/noarch_platforms/recipe/meta.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
{% set version = "7.1.3" %}

package:
name: pytest
version: {{ version }}

source:
url: https://pypi.io/packages/source/p/pytest/pytest-{{ version }}.tar.gz
sha256: 4f365fec2dff9c1162f834d9f18af1ba13062db0c708bf7b946f8a5c76180c39

build:
number: 1
script: {{ PYTHON }} setup.py install --single-version-externally-managed --record record.txt
entry_points:
- pytest = pytest:console_main
- py.test = pytest:console_main
noarch: python
string: "win_pyh{{ PKG_HASH }}_{{ PKG_BUILDNUM }}" # [win]
string: "unix_pyh{{ PKG_HASH }}_{{ PKG_BUILDNUM }}" # [unix]


requirements:
build:
- python # [build_platform != target_platform]
- cross-python_{{ target_platform }} # [build_platform != target_platform]
host:
- pip
- python >=3.8
- setuptools >=42.0
- setuptools_scm >=6.0
run:
- python >=3.8
- attrs >=19.2.0
- iniconfig
- packaging
- pluggy >=0.12,<2.0
- py >=1.8.2
- tomli >=1.0.0
- colorama # [win]
- __win # [win]
- __unix # [unix]

run_constrained:
# pytest-faulthandler 2 is a dummy package.
# if an older version of fault-handler is installed, it will conflict with pytest >=5.
- pytest-faulthandler >=2

test:
commands:
- pytest -h
imports:
- pytest

about:
home: https://docs.pytest.org/en/latest/
license: MIT
license_file: LICENSE
summary: Simple and powerful testing with Python.
description: |
The pytest framework makes it easy to write small tests, yet scales to
support complex functional testing for applications and libraries.
doc_url: https://docs.pytest.org/en/latest/
dev_url: https://github.com/pytest-dev/pytest/

extra:
recipe-maintainers:
- flub
- goanpeca
- nicoddemus
- ocefpaf
- mingwandroid
8 changes: 7 additions & 1 deletion tests/test_lint_recipe.py
Original file line number Diff line number Diff line change
Expand Up @@ -415,7 +415,7 @@ def assert_pyXY_selector(meta_string, is_good=False, kind="lint"):
)

def test_noarch_selectors(self):
expected_start = "`noarch` packages can't have selectors."
expected_start = "`noarch` packages can't have"

with tmp_directory() as recipe_dir:

Expand Down Expand Up @@ -1179,6 +1179,12 @@ def test_multiple_sources(self):
)
assert not lints

def test_noarch_platforms(self):
lints = linter.main(
os.path.join(_thisdir, "recipes", "noarch_platforms", "recipe")
)
assert not lints

def test_string_source(self):
url = "http://mistake.com/v1.0.tar.gz"
lints, hints = linter.lintify({"source": url})
Expand Down