diff --git a/crates/uv-requirements/src/sources.rs b/crates/uv-requirements/src/sources.rs index 92aa97b42586d..0f5f07be77367 100644 --- a/crates/uv-requirements/src/sources.rs +++ b/crates/uv-requirements/src/sources.rs @@ -23,6 +23,8 @@ pub enum RequirementsSource { SetupCfg(PathBuf), /// Dependencies were provided via a path to a source tree (e.g., `pip install .`). SourceTree(PathBuf), + /// Dependencies were provided via an unsupported Conda `environment.yml` file (e.g., `pip install -r environment.yml`). + EnvironmentYml(PathBuf), } impl RequirementsSource { @@ -35,6 +37,8 @@ impl RequirementsSource { Self::SetupPy(path) } else if path.ends_with("setup.cfg") { Self::SetupCfg(path) + } else if path.ends_with("environment.yml") { + Self::EnvironmentYml(path) } else { Self::RequirementsTxt(path) } @@ -217,6 +221,7 @@ impl std::fmt::Display for RequirementsSource { | Self::PyprojectToml(path) | Self::SetupPy(path) | Self::SetupCfg(path) + | Self::EnvironmentYml(path) | Self::SourceTree(path) => { write!(f, "{}", path.simplified_display()) } diff --git a/crates/uv-requirements/src/specification.rs b/crates/uv-requirements/src/specification.rs index 32b9ef2085366..0f16ada104ccc 100644 --- a/crates/uv-requirements/src/specification.rs +++ b/crates/uv-requirements/src/specification.rs @@ -212,6 +212,12 @@ impl RequirementsSpecification { ..Self::default() } } + RequirementsSource::EnvironmentYml(path) => { + return Err(anyhow::anyhow!( + "Conda environment files (i.e. `{}`) are not supported", + path.user_display() + )) + } }) } diff --git a/crates/uv/tests/it/edit.rs b/crates/uv/tests/it/edit.rs index 4f8b6cccd89c0..013b2725d61e0 100644 --- a/crates/uv/tests/it/edit.rs +++ b/crates/uv/tests/it/edit.rs @@ -3662,6 +3662,41 @@ fn add_error() -> Result<()> { Ok(()) } +/// Emit dedicated error message when adding Conda `environment.yml` +#[test] +fn add_environment_yml_error() -> Result<()> { + let context = TestContext::new("3.12"); + + let pyproject_toml = context.temp_dir.child("pyproject.toml"); + pyproject_toml.write_str(indoc! {r#" + [project] + name = "project" + version = "0.1.0" + requires-python = ">=3.12" + dependencies = [] + "#})?; + + let environment_yml = context.temp_dir.child("environment.yml"); + environment_yml.write_str(indoc! {r" + name: test-env + channels: + - conda-forge + dependencies: + - python>=3.12 + "})?; + + uv_snapshot!(context.filters(), context.add().arg("-r").arg("environment.yml"), @r" + success: false + exit_code: 2 + ----- stdout ----- + + ----- stderr ----- + error: Conda environment files (i.e. `environment.yml`) are not supported + "); + + Ok(()) +} + /// Set a lower bound when adding unconstrained dependencies. #[test] fn add_lower_bound() -> Result<()> { diff --git a/crates/uv/tests/it/pip_install.rs b/crates/uv/tests/it/pip_install.rs index 12e2a4cc0af14..93b64236e7429 100644 --- a/crates/uv/tests/it/pip_install.rs +++ b/crates/uv/tests/it/pip_install.rs @@ -8028,6 +8028,32 @@ fn install_incompatible_python_version_interpreter_broken_in_path() -> Result<() Ok(()) } +/// Emit dedicated error message when installing Conda `environment.yml` +#[test] +fn install_unsupported_environment_yml() -> Result<()> { + let context = TestContext::new("3.12"); + + let environment_yml = context.temp_dir.child("environment.yml"); + environment_yml.write_str(indoc! {r" + name: test-env + channels: + - conda-forge + dependencies: + - python>=3.12 + "})?; + + uv_snapshot!(context.filters(), context.pip_install().arg("-r").arg("environment.yml"), @r" + success: false + exit_code: 2 + ----- stdout ----- + + ----- stderr ----- + error: Conda environment files (i.e. `environment.yml`) are not supported + "); + + Ok(()) +} + /// Include a `build_constraints.txt` file with an incompatible constraint. #[test] fn incompatible_build_constraint() -> Result<()> {