Skip to content

Commit

Permalink
allow selectors containing variants from cbc
Browse files Browse the repository at this point in the history
  • Loading branch information
0xbe7a committed Feb 19, 2024
1 parent 0d97d98 commit 91ac792
Show file tree
Hide file tree
Showing 5 changed files with 145 additions and 31 deletions.
80 changes: 49 additions & 31 deletions conda_smithy/lint_recipe.py
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,24 @@ def lint_about_contents(about_section, lints):
)


def find_local_config_file(recipe_dir, filename):
# support
# 1. feedstocks
# 2. staged-recipes with custom conda-forge.yaml in recipe
# 3. staged-recipes
found_filesname = (
glob(os.path.join(recipe_dir, filename))
or glob(
os.path.join(recipe_dir, "..", filename),
)
or glob(
os.path.join(recipe_dir, "..", "..", filename),
)
)

return found_filesname[0] if found_filesname else None


def lintify(meta, recipe_dir=None, conda_forge=False):
lints = []
hints = []
Expand Down Expand Up @@ -390,21 +408,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"),
)
conda_build_config_filename = find_local_config_file(
recipe_dir, "conda_build_config.yaml"
)

if conda_build_config_filename:
with open(conda_build_config_filename, "r") as fh:
conda_build_config_keys = set(get_yaml().load(fh).keys())
else:
conda_build_config_keys = set()

forge_yaml_filename = find_local_config_file(
recipe_dir, "conda-forge.yml"
)

if forge_yaml_filename:
with open(forge_yaml_filename[0], "r") as fh:
with open(forge_yaml_filename, "r") as fh:
forge_yaml = get_yaml().load(fh)
else:
forge_yaml = {}
else:
conda_build_config_keys = set()
forge_yaml = {}

# 18: noarch doesn't work with selectors for runtime dependencies
Expand All @@ -430,7 +454,9 @@ def lintify(meta, recipe_dir=None, conda_forge=False):
in_runreqs = False
continue
if is_selector_line(
line, allow_platforms=noarch_platforms
line,
allow_platforms=noarch_platforms,
allow_keys=conda_build_config_keys,
):
lints.append(
"`noarch` packages can't have selectors. If "
Expand Down Expand Up @@ -688,19 +714,7 @@ def check_pins_build_and_requirements(top_level):
shell_scripts = []
if recipe_dir:
shell_scripts = glob(os.path.join(recipe_dir, "*.sh"))
# 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"),
)
)
forge_yaml = find_local_config_file(recipe_dir, "conda-forge.yml")
if shell_scripts and forge_yaml:
with open(forge_yaml[0], "r") as fh:
code = get_yaml().load(fh)
Expand Down Expand Up @@ -980,7 +994,7 @@ def run_conda_forge_specific(meta, recipe_dir, lints, hints):
)


def is_selector_line(line, allow_platforms=False):
def is_selector_line(line, allow_platforms=False, allow_keys=set()):
# Using the same pattern defined in conda-build (metadata.py),
# we identify selectors.
line = line.rstrip()
Expand All @@ -989,13 +1003,17 @@ def is_selector_line(line, allow_platforms=False):
return False
m = sel_pat.match(line)
if m:
if allow_platforms:
nouns = {
w for w in m.group(3).split() if w not in ("not", "and", "or")
}
if nouns.issubset({"win", "linux", "osx", "unix"}):
# the selector only contains (a boolean chain of) platform selectors
return False
nouns = {
w for w in m.group(3).split() if w not in ("not", "and", "or")
}
allowed_nouns = (
{"win", "linux", "osx", "unix"} if allow_platforms else set()
) | allow_keys

if nouns.issubset(allowed_nouns):
# the selector only contains (a boolean chain of) platform selectors
# and/or keys from the conda_build_config.yaml
return False
else:
return True
return False
Expand Down
24 changes: 24 additions & 0 deletions news/noarch-selectors.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
**Added:**

* `noarch` packages can now include keys from their `conda_build_config.yaml` as selectors in their recipe.
This allows for building multiple variants of a `noarch` packages, e.g., to use different dependencies depending on the Python version as runtime.

**Changed:**

* <news item>

**Deprecated:**

* <news item>

**Removed:**

* <news item>

**Fixed:**

* <news item>

**Security:**

* <news item>
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
python_leq_310:
- False
- True
63 changes: 63 additions & 0 deletions tests/recipes/noarch_selector_variants/meta.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
{% set version = "1.34.41" %}
{% set hash = "3a6943c75a0d292ab6e008bce58ee6503776969479f991f5ad03a5d877af29ae" %}

package:
name: botocore
version: {{ version }}

source:
url: https://pypi.org/packages/source/b/botocore/botocore-{{ version }}.tar.gz
sha256: {{ hash }}

build:
number: 1
noarch: python
script: {{ PYTHON }} -m pip install . --no-deps --ignore-installed --no-cache-dir -vvv

requirements:
build:
- cross-python_{{ target_platform }} # [build_platform != target_platform]
- python # [build_platform != target_platform]
host:
- python
- pip
run:
- python
- jmespath >=0.7.1,<2.0.0
- python-dateutil >=2.1,<3.0.0
- urllib3 >=1.25.4,<1.27 # [python_leq_310]
- urllib3 >=1.25.4,<2.1 # [not python_leq_310]
- python <3.10 # [python_leq_310]
- python >=3.10 # [not python_leq_310]

test:
imports:
- botocore
- botocore.docs
- botocore.vendored
- botocore.vendored.requests
- botocore.vendored.requests.packages
- botocore.vendored.requests.packages.urllib3
commands:
- pip check
requires:
- pip

about:
home: http://aws.amazon.com/sdk-for-python/
license_file: LICENSE.txt
license: Apache-2.0
license_url: http://aws.amazon.com/apache2.0/
license_family: Apache
summary: Low-level, data-driven core of boto 3.
description: |
Provides the core functionality of Boto3, the AWS SDK for Python
dev_url: https://github.com/boto/botocore
doc_url: https://botocore.readthedocs.io/en/latest/

extra:
recipe-maintainers:
- hajapy
- tkelman
- ocefpaf
- '0xbe7a'
6 changes: 6 additions & 0 deletions tests/test_lint_recipe.py
Original file line number Diff line number Diff line change
Expand Up @@ -1265,6 +1265,12 @@ def test_noarch_platforms(self):
)
assert not lints

def test_noarch_selector_variants(self):
lints = linter.main(
os.path.join(_thisdir, "recipes", "noarch_selector_variants")
)
assert not lints

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

0 comments on commit 91ac792

Please sign in to comment.