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

Refactor meta.yaml lint logic #1906

Open
wants to merge 33 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
3ad8791
refactor conda-forge.yml linting logic, hint about extra fields
ytausch Apr 2, 2024
942baa0
add news entry 1900
ytausch Apr 2, 2024
29ae96e
news entry 1900: we hint about missing conda-forge.yml
ytausch Apr 2, 2024
705a6ac
re-add str_type and lintify_forge_yaml (deprecated)
ytausch Apr 2, 2024
2f2049c
rename lint_meta_yaml back to lintify_meta_yaml
ytausch Apr 2, 2024
8d46efc
add deprecation to news
ytausch Apr 2, 2024
7394562
use legacy typing.Callable
ytausch Apr 2, 2024
70ec15e
use legacy tape annotations
ytausch Apr 2, 2024
7852a01
more legacy types
ytausch Apr 2, 2024
3331fcb
even more legacy types
ytausch Apr 2, 2024
fea25db
fix typo
ytausch Apr 2, 2024
c7843c9
begin refactoring meta_yaml lints
ytausch Apr 3, 2024
d21e423
extract everything out of lintify_meta_yaml
ytausch Apr 4, 2024
88ff637
fix detail issues
ytausch Apr 5, 2024
1a30752
undo regex optimizations by PyCharm
ytausch Apr 5, 2024
d612f52
fix lint string
ytausch Apr 5, 2024
e7deee7
fix: version floats are supported
ytausch Apr 5, 2024
f54325e
"script" is actually in a subsubsection
ytausch Apr 5, 2024
44a0073
opened issue #1905 for TODO
ytausch Apr 5, 2024
e112bfe
support None instead of empty list
ytausch Apr 5, 2024
ae43a83
lint wrong section types
ytausch Apr 5, 2024
c5332fc
check completeness of META_YAML_LINTERS list
ytausch Apr 5, 2024
e4b1098
use modern LintsHints API
ytausch Apr 5, 2024
7ab9f58
deduplicate lints
ytausch Apr 5, 2024
4b3b9c6
don't use io.open
ytausch Apr 5, 2024
f1236ac
removed unused REQUIREMENTS_ORDER
ytausch Apr 5, 2024
642d519
fix type signature of lint_section_order, add test
ytausch Apr 5, 2024
59bc1e4
re-add some fields as deprecated
ytausch Apr 5, 2024
8f6174c
re-add deprecated methods, use new lint_meta_yaml method
ytausch Apr 5, 2024
6e8ba9f
replace mode rt with r
ytausch Apr 5, 2024
5fbe8f1
fix CI issues
ytausch Apr 5, 2024
a654438
fix lint_recipe_dir_inside_example_dir
ytausch Apr 5, 2024
6089d50
add news file
ytausch Apr 5, 2024
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
1 change: 0 additions & 1 deletion conda_smithy/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
import sys
import time
import argparse
import io
import tempfile

from textwrap import dedent
Expand Down
86 changes: 86 additions & 0 deletions conda_smithy/config_file_helpers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
from pathlib import Path
from typing import Optional

try:
from enum import StrEnum
except ImportError:
from backports.strenum import StrEnum

from conda_smithy.utils import get_yaml


class MultipleConfigFilesError(ValueError):
"""
Raised when multiple configuration files are found in different locations and only one is allowed.
"""

pass


class ConfigFileMustBeDictError(ValueError):
"""
Raised when a configuration file does not represent a dictionary.
"""

pass


class ConfigFileName(StrEnum):
CONDA_FORGE_YML = "conda-forge.yml"
CONDA_BUILD_CONFIG = "conda_build_config.yaml"


def read_local_config_file(
recipe_dir: Path, filename: ConfigFileName, enforce_one: bool = True
) -> dict:
"""
Read a local YAML configuration file from the recipe directory.
It is assumed that the local configuration file has a dictionary-like structure.
Multiple relative paths are checked for the file in a specific order.

:param recipe_dir: the recipe directory of a feedstock
:param filename: the name of the configuration file
:param enforce_one: if True, only one config file with the given name is allowed when looking for it in different
locations. If False, the contents of the first file found is returned.

:raises FileNotFoundError if the file does not exist in all possible locations
:raises ConfigFileMustBeDictError if the file does not represent a dictionary
(takes precedence over MultipleConfigFilesError)
:raises MultipleConfigFilesError if multiple files are found and only one is allowed
"""

file_candidates = [
recipe_dir / filename,
recipe_dir / ".." / filename,
recipe_dir / ".." / ".." / filename,
]

file_contents: Optional[dict] = None

for file in file_candidates:
if file_contents is not None and file.exists():
# we know that enforce_one is True since otherwise we would have returned already
raise MultipleConfigFilesError(
f"Multiple configuration files '{filename}' found in different locations relative to {recipe_dir}."
)

try:
file_contents = get_yaml().load(file)
except FileNotFoundError:
continue

if not isinstance(file_contents, dict):
raise ConfigFileMustBeDictError(
f"The YAML configuration file '{file}' does not represent a dictionary."
)

if not enforce_one:
# early return
return file_contents

if file_contents is not None:
return file_contents

raise FileNotFoundError(
f"No {filename} file found in any of the following locations: {', '.join(map(str, file_candidates))}"
)
2 changes: 1 addition & 1 deletion conda_smithy/configure_feedstock.py
Original file line number Diff line number Diff line change
Expand Up @@ -2698,7 +2698,7 @@ def main(
import argparse

parser = argparse.ArgumentParser(
description=("Configure a feedstock given " "a conda-forge.yml file.")
description="Configure a feedstock given a conda-forge.yml file."
)
parser.add_argument(
"forge_file_directory",
Expand Down
Loading
Loading