Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
9 changes: 1 addition & 8 deletions src/rapids_dependency_file_generator/_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,14 +47,7 @@ def validate_args(argv):
codependent_args.add_argument(
"--output",
help="The output file type to generate.",
choices=[
x.value
for x in [
Output.CONDA,
Output.PYPROJECT,
Output.REQUIREMENTS,
]
],
choices=[x.value for x in Output],
)
codependent_args.add_argument(
"--matrix",
Expand Down
7 changes: 7 additions & 0 deletions src/rapids_dependency_file_generator/_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ class Output(Enum):
REQUIREMENTS = "requirements"
"""Generate a ``requirements.txt``."""

CONSTRAINTS = "constraints"
"""Generate a ``constraints.txt``."""
Comment thread
KyleFromNVIDIA marked this conversation as resolved.

CONDA = "conda"
"""Generate a Conda environment file."""

Expand Down Expand Up @@ -67,6 +70,9 @@ class File:
requirements_dir: Path = Path(_constants.default_requirements_dir)
"""The directory in which to write ``requirements.txt``."""

constraints_dir: Path = Path(_constants.default_constraints_dir)
"""The directory in which to write ``constraints.txt``."""

conda_dir: Path = Path(_constants.default_conda_dir)
"""The directory in which to write the Conda environment file."""

Expand Down Expand Up @@ -173,6 +179,7 @@ def get_extras() -> typing.Union[FileExtras, None]:
includes=list(file_config["includes"]),
matrix={key: list(value) for key, value in file_config.get("matrix", {}).items()},
requirements_dir=Path(file_config.get("requirements_dir", _constants.default_requirements_dir)),
constraints_dir=Path(file_config.get("constraints_dir", _constants.default_constraints_dir)),
conda_dir=Path(file_config.get("conda_dir", _constants.default_conda_dir)),
pyproject_dir=Path(file_config.get("pyproject_dir", _constants.default_pyproject_dir)),
)
Expand Down
1 change: 1 addition & 0 deletions src/rapids_dependency_file_generator/_constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,6 @@

default_conda_dir = "conda/environments"
default_requirements_dir = "python"
default_constraints_dir = "python"
default_pyproject_dir = "python"
default_dependency_file_path = "dependencies.yaml"
Original file line number Diff line number Diff line change
Expand Up @@ -149,10 +149,10 @@ def make_dependency_file(
if conda_env_name is not None:
env_dict["name"] = conda_env_name
file_contents += yaml.dump(env_dict)
elif file_type == _config.Output.REQUIREMENTS:
elif file_type in {_config.Output.REQUIREMENTS, _config.Output.CONSTRAINTS}:
for dep in dependencies:
if isinstance(dep, dict):
raise ValueError(f"Map inputs like {dep} are not allowed for the 'requirements' file type.")
raise ValueError(f"Map inputs like {dep} are not allowed for the '{file_type.value}' file type.")

file_contents += f"{dep}\n"
elif file_type == _config.Output.PYPROJECT:
Expand Down Expand Up @@ -249,6 +249,9 @@ def get_filename(file_type: _config.Output, file_key: str, matrix_combo: dict[st
elif file_type == _config.Output.REQUIREMENTS:
file_ext = ".txt"
file_type_prefix = "requirements"
elif file_type == _config.Output.CONSTRAINTS:
file_ext = ".txt"
file_type_prefix = "constraints"
elif file_type == _config.Output.PYPROJECT:
file_ext = ".toml"
# Unlike for files like requirements.txt or conda environment YAML files, which
Expand Down Expand Up @@ -287,6 +290,8 @@ def get_output_dir(*, file_type: _config.Output, config_file_path: os.PathLike,
path.append(file_config.conda_dir)
elif file_type == _config.Output.REQUIREMENTS:
path.append(file_config.requirements_dir)
elif file_type == _config.Output.CONSTRAINTS:
path.append(file_config.constraints_dir)
elif file_type == _config.Output.PYPROJECT:
path.append(file_config.pyproject_dir)
return os.path.join(*path)
Expand Down
3 changes: 2 additions & 1 deletion src/rapids_dependency_file_generator/schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
"includes": {"type": "array", "items": {"type": "string"}},
"matrix": {"$ref": "#/$defs/matrix"},
"requirements_dir": {"type": "string"},
"constraints_dir": {"type": "string"},
"conda_dir": {"type": "string"},
"pyproject_dir": {"type": "string"}
},
Expand Down Expand Up @@ -121,7 +122,7 @@
"items": {"$ref": "#/$defs/matrix-matcher"}
},
"output-types": {
"enum": ["conda", "requirements", "pyproject"]
"enum": ["conda", "requirements", "constraints", "pyproject"]
},
"output-types-array": {
"type": "array",
Expand Down
8 changes: 4 additions & 4 deletions tests/examples/overlapping-deps/dependencies.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ channels:
dependencies:
depends_on_numpy:
common:
- output_types: [requirements, pyproject]
- output_types: [requirements, constraints, pyproject]
packages:
- numpy>=2.0
# using 'pip' intentionally to test handling of that nested list
Expand All @@ -47,7 +47,7 @@ dependencies:
- numpy>=2.0
depends_on_pandas:
common:
- output_types: [conda, requirements, pyproject]
- output_types: [conda, requirements, constraints, pyproject]
packages:
- pandas<3.0
depends_on_scikit_learn:
Expand All @@ -72,10 +72,10 @@ dependencies:
- folium
rapids_build_skbuild:
common:
- output_types: [conda, requirements, pyproject]
- output_types: [conda, requirements, constraints, pyproject]
packages:
- rapids-build-backend>=0.3.1
- output_types: [requirements, pyproject]
- output_types: [requirements, constraints, pyproject]
packages:
- scikit-build-core[pyproject]>=0.9.0
- output_types: [conda]
Expand Down
12 changes: 8 additions & 4 deletions tests/examples/requirements-minimal/dependencies.yaml
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
files:
all:
output: requirements
requirements_dir: output/actual
output: [requirements, constraints]
requirements_dir: output/actual/requirements
constraints_dir: output/actual/constraints
matrix:
cuda: ["11.5", "11.6"]
arch: [x86_64]
Expand Down Expand Up @@ -35,14 +36,17 @@ channels:
dependencies:
build:
common:
- output_types: [conda, requirements]
- output_types: [conda, requirements, constraints]
packages:
- clang=11.1.0
- output_types: requirements
packages:
- spdlog>=1.8.5,<1.9
- output_types: constraints
packages:
- spdlog
specific:
- output_types: [conda, requirements]
- output_types: [conda, requirements, constraints]
matrices:
- matrix:
cuda: "11.5"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# This file is generated by `rapids-dependency-file-generator`.
# To make changes, edit ../../../dependencies.yaml and run `rapids-dependency-file-generator`.
clang=11.1.0
cuda-python>=11.5,<11.7.1
spdlog
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# This file is generated by `rapids-dependency-file-generator`.
# To make changes, edit ../../../dependencies.yaml and run `rapids-dependency-file-generator`.
clang=11.1.0
cuda-python>=11.6,<11.7.1
spdlog
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# This file is generated by `rapids-dependency-file-generator`.
# To make changes, edit ../../dependencies.yaml and run `rapids-dependency-file-generator`.
# To make changes, edit ../../../dependencies.yaml and run `rapids-dependency-file-generator`.
clang=11.1.0
cuda-python>=11.5,<11.7.1
cudatoolkit=11.5
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# This file is generated by `rapids-dependency-file-generator`.
# To make changes, edit ../../dependencies.yaml and run `rapids-dependency-file-generator`.
# To make changes, edit ../../../dependencies.yaml and run `rapids-dependency-file-generator`.
clang=11.1.0
cuda-python>=11.6,<11.7.1
cudatoolkit=11.6
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# This file is generated by `rapids-dependency-file-generator`.
# To make changes, edit ../dependencies.yaml and run `rapids-dependency-file-generator`.
clang=11.1.0
spdlog
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# This file is generated by `rapids-dependency-file-generator`.
# To make changes, edit ../dependencies.yaml and run `rapids-dependency-file-generator`.
clang=11.1.0
spdlog
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# This file is generated by `rapids-dependency-file-generator`.
# To make changes, edit ../dependencies.yaml and run `rapids-dependency-file-generator`.
clang=11.1.0
spdlog
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# This file is generated by `rapids-dependency-file-generator`.
# To make changes, edit ../dependencies.yaml and run `rapids-dependency-file-generator`.
clang=11.1.0
spdlog
2 changes: 1 addition & 1 deletion tests/examples/requirements-pip-dict/dependencies.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ files:
dependencies:
run_deps:
common:
- output_types: [requirements]
- output_types: [requirements, constraints]
packages:
- fsspec>=0.6.0
- pip:
Expand Down
9 changes: 6 additions & 3 deletions tests/test_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,11 @@
("none", set()),
(["none"], set()),
(
["pyproject", "requirements", "conda"],
["pyproject", "requirements", "constraints", "conda"],
{
_config.Output.PYPROJECT,
_config.Output.REQUIREMENTS,
_config.Output.CONSTRAINTS,
_config.Output.CONDA,
},
),
Expand Down Expand Up @@ -144,7 +145,7 @@ def test_parse_file(input, output):
"packages": [],
},
{
"output_types": ["pyproject", "requirements"],
"output_types": ["pyproject", "requirements", "constraints"],
"packages": [
"package1",
{
Expand Down Expand Up @@ -192,6 +193,7 @@ def test_parse_file(input, output):
output_types={
_config.Output.PYPROJECT,
_config.Output.REQUIREMENTS,
_config.Output.CONSTRAINTS,
},
packages=[
"package1",
Expand Down Expand Up @@ -362,7 +364,7 @@ def test_parse_config(input, path, output):
packages:
- package1
specific:
- output_types: ["conda", "requirements"]
- output_types: ["conda", "requirements", "constraints"]
matrices:
- matrix:
packages:
Expand Down Expand Up @@ -395,6 +397,7 @@ def test_parse_config(input, path, output):
output_types={
_config.Output.CONDA,
_config.Output.REQUIREMENTS,
_config.Output.CONSTRAINTS,
},
matrices=[
_config.MatrixMatcher(
Expand Down
55 changes: 39 additions & 16 deletions tests/test_rapids_dependency_file_generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,17 +70,18 @@ def test_make_dependency_file(mock_relpath):
}
)

env = make_dependency_file(
file_type=_config.Output.REQUIREMENTS,
conda_env_name="tmp_env",
file_name="tmp_env.txt",
config_file="config_file",
output_dir="output_path",
conda_channels=["rapidsai", "nvidia"],
dependencies=["dep1", "dep2"],
extras=None,
)
assert env == header + "dep1\ndep2\n"
for file_type in [_config.Output.REQUIREMENTS, _config.Output.CONSTRAINTS]:
env = make_dependency_file(
file_type=file_type,
conda_env_name="tmp_env",
file_name="tmp_env.txt",
config_file="config_file",
output_dir="output_path",
conda_channels=["rapidsai", "nvidia"],
dependencies=["dep1", "dep2"],
extras=None,
)
assert env == header + "dep1\ndep2\n"
Comment thread
KyleFromNVIDIA marked this conversation as resolved.
Outdated


def test_make_dependency_file_should_raise_informative_error_when_extras_is_missing_for_pyproj():
Expand Down Expand Up @@ -110,14 +111,29 @@ def test_make_dependency_files_should_raise_informative_error_when_multiple_file
to_stdout=True
)

def test_make_dependency_files_should_raise_informative_error_on_map_inputs_for_requirements():
@pytest.mark.parametrize(
["output_type", "msg_match"],
[
pytest.param(
_config.Output.REQUIREMENTS,
r"Map inputs like {'pip': \['pandas<1.0'\]} are not allowed for the 'requirements' file type.",
id="requirements",
),
pytest.param(
_config.Output.CONSTRAINTS,
r"Map inputs like {'pip': \['pandas<1.0'\]} are not allowed for the 'constraints' file type.",
id="constraints",
),
],
)
def test_make_dependency_files_should_raise_informative_error_on_map_inputs_for_requirements_and_constraints(output_type, msg_match):

current_dir = pathlib.Path(__file__).parent
with pytest.raises(ValueError, match=re.escape("Map inputs like {'pip': ['pandas<1.0']} are not allowed for the 'requirements' file type.")):
with pytest.raises(ValueError, match=msg_match):
make_dependency_files(
parsed_config=_config.load_config_from_file(current_dir / "examples" / "requirements-pip-dict" / "dependencies.yaml"),
file_keys=["all_of_the_things"],
output={_config.Output.REQUIREMENTS},
output={output_type},
matrix=None,
prepend_channels=[],
to_stdout=True
Expand Down Expand Up @@ -147,13 +163,20 @@ def test_make_dependency_files_should_choose_correct_pyproject_toml(capsys):
# and should NOT contain anything from the root-level pyproject.toml
assert set(dict(doc).keys()) == {"project"}

def test_make_dependency_files_requirements_to_stdout_with_multiple_file_keys_works(capsys):
@pytest.mark.parametrize(
["output_type"],
[
pytest.param(_config.Output.REQUIREMENTS, id="requirements"),
pytest.param(_config.Output.CONSTRAINTS, id="constraints"),
],
)
def test_make_dependency_files_requirements_and_constraints_to_stdout_with_multiple_file_keys_works(capsys, output_type):

current_dir = pathlib.Path(__file__).parent
make_dependency_files(
parsed_config=_config.load_config_from_file(current_dir / "examples" / "overlapping-deps" / "dependencies.yaml"),
file_keys=["build_deps", "even_more_build_deps"],
output={_config.Output.REQUIREMENTS},
output={output_type},
matrix={"arch": ["x86_64"]},
prepend_channels=[],
to_stdout=True
Expand Down