mirror of https://github.com/astral-sh/uv
Reject `--editable` flag on non-directory requirements (#10994)
## Summary Closes https://github.com/astral-sh/uv/issues/10992.
This commit is contained in:
parent
71f0798536
commit
a00f6f5d3d
|
|
@ -1312,6 +1312,10 @@ pub enum SourceError {
|
||||||
UnusedTag(String, String),
|
UnusedTag(String, String),
|
||||||
#[error("`{0}` did not resolve to a Git repository, but a Git reference (`--branch {1}`) was provided.")]
|
#[error("`{0}` did not resolve to a Git repository, but a Git reference (`--branch {1}`) was provided.")]
|
||||||
UnusedBranch(String, String),
|
UnusedBranch(String, String),
|
||||||
|
#[error("`{0}` did not resolve to a local directory, but the `--editable` flag was provided. Editable installs are only supported for local directories.")]
|
||||||
|
UnusedEditable(String),
|
||||||
|
#[error("Workspace dependency `{0}` was marked as `--no-editable`, but workspace dependencies are always added in editable mode. Pass `--no-editable` to `uv sync` or `uv run` to install workspace dependencies in non-editable mode.")]
|
||||||
|
UnusedNoEditable(String),
|
||||||
#[error("Failed to resolve absolute path")]
|
#[error("Failed to resolve absolute path")]
|
||||||
Absolute(#[from] std::io::Error),
|
Absolute(#[from] std::io::Error),
|
||||||
#[error("Path contains invalid characters: `{}`", _0.display())]
|
#[error("Path contains invalid characters: `{}`", _0.display())]
|
||||||
|
|
@ -1349,6 +1353,20 @@ impl Source {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if workspace {
|
||||||
|
// If a workspace source is added with `--no-editable`, error.
|
||||||
|
if editable == Some(false) {
|
||||||
|
return Err(SourceError::UnusedNoEditable(name.to_string()));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// If we resolved a non-path source, and user specified an `--editable` flag, error.
|
||||||
|
if !matches!(source, RequirementSource::Directory { .. }) {
|
||||||
|
if editable == Some(true) {
|
||||||
|
return Err(SourceError::UnusedEditable(name.to_string()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// If the source is a workspace package, error if the user tried to specify a source.
|
// If the source is a workspace package, error if the user tried to specify a source.
|
||||||
if workspace {
|
if workspace {
|
||||||
return match source {
|
return match source {
|
||||||
|
|
|
||||||
|
|
@ -875,6 +875,37 @@ fn add_raw_error() -> Result<()> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[cfg(feature = "git")]
|
||||||
|
fn add_editable_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 = []
|
||||||
|
|
||||||
|
[build-system]
|
||||||
|
requires = ["setuptools>=42"]
|
||||||
|
build-backend = "setuptools.build_meta"
|
||||||
|
"#})?;
|
||||||
|
|
||||||
|
// Provide `--editable` with a non-source tree.
|
||||||
|
uv_snapshot!(context.filters(), context.add().arg("flask @ https://files.pythonhosted.org/packages/61/80/ffe1da13ad9300f87c93af113edd0638c75138c42a0994becfacac078c06/flask-3.0.3-py3-none-any.whl").arg("--editable"), @r###"
|
||||||
|
success: false
|
||||||
|
exit_code: 2
|
||||||
|
----- stdout -----
|
||||||
|
|
||||||
|
----- stderr -----
|
||||||
|
error: `flask` did not resolve to a local directory, but the `--editable` flag was provided. Editable installs are only supported for local directories.
|
||||||
|
"###);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
/// Add an unnamed requirement.
|
/// Add an unnamed requirement.
|
||||||
#[test]
|
#[test]
|
||||||
#[cfg(feature = "git")]
|
#[cfg(feature = "git")]
|
||||||
|
|
@ -2186,6 +2217,24 @@ fn add_workspace_editable() -> Result<()> {
|
||||||
"#})?;
|
"#})?;
|
||||||
|
|
||||||
let child1 = context.temp_dir.join("child1");
|
let child1 = context.temp_dir.join("child1");
|
||||||
|
|
||||||
|
// `--no-editable` should error.
|
||||||
|
let mut add_cmd = context.add();
|
||||||
|
add_cmd
|
||||||
|
.arg("child2")
|
||||||
|
.arg("--no-editable")
|
||||||
|
.current_dir(&child1);
|
||||||
|
|
||||||
|
uv_snapshot!(context.filters(), add_cmd, @r###"
|
||||||
|
success: false
|
||||||
|
exit_code: 2
|
||||||
|
----- stdout -----
|
||||||
|
|
||||||
|
----- stderr -----
|
||||||
|
error: Workspace dependency `child2` was marked as `--no-editable`, but workspace dependencies are always added in editable mode. Pass `--no-editable` to `uv sync` or `uv run` to install workspace dependencies in non-editable mode.
|
||||||
|
"###);
|
||||||
|
|
||||||
|
// `--editable` should not.
|
||||||
let mut add_cmd = context.add();
|
let mut add_cmd = context.add();
|
||||||
add_cmd.arg("child2").arg("--editable").current_dir(&child1);
|
add_cmd.arg("child2").arg("--editable").current_dir(&child1);
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue