mirror of
https://github.com/astral-sh/uv.git
synced 2025-10-23 08:41:48 +00:00
Avoid updating incorrect dependencies for sorted uv add
(#6939)
## Summary The indexes stored in the edits is wrong now that we add dependencies out-of-order. Closes https://github.com/astral-sh/uv/issues/6933.
This commit is contained in:
parent
42a4d80a63
commit
cbe2827e97
4 changed files with 52 additions and 14 deletions
|
@ -486,7 +486,7 @@ impl Source {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The type of a dependency in a `pyproject.toml`.
|
/// The type of a dependency in a `pyproject.toml`.
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
pub enum DependencyType {
|
pub enum DependencyType {
|
||||||
/// A dependency in `project.dependencies`.
|
/// A dependency in `project.dependencies`.
|
||||||
Production,
|
Production,
|
||||||
|
|
|
@ -48,6 +48,14 @@ pub enum ArrayEdit {
|
||||||
Add(usize),
|
Add(usize),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl ArrayEdit {
|
||||||
|
pub fn index(&self) -> usize {
|
||||||
|
match self {
|
||||||
|
Self::Update(i) | Self::Add(i) => *i,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Specifies whether dependencies are added to a script file or a `pyproject.toml` file.
|
/// Specifies whether dependencies are added to a script file or a `pyproject.toml` file.
|
||||||
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
||||||
pub enum DependencyTarget {
|
pub enum DependencyTarget {
|
||||||
|
|
|
@ -328,7 +328,7 @@ pub(crate) async fn add(
|
||||||
DependencyTarget::PyProjectToml,
|
DependencyTarget::PyProjectToml,
|
||||||
),
|
),
|
||||||
}?;
|
}?;
|
||||||
let mut edits = Vec::with_capacity(requirements.len());
|
let mut edits = Vec::<DependencyEdit>::with_capacity(requirements.len());
|
||||||
for mut requirement in requirements {
|
for mut requirement in requirements {
|
||||||
// Add the specified extras.
|
// Add the specified extras.
|
||||||
requirement.extras.extend(extras.iter().cloned());
|
requirement.extras.extend(extras.iter().cloned());
|
||||||
|
@ -407,6 +407,26 @@ pub(crate) async fn add(
|
||||||
};
|
};
|
||||||
|
|
||||||
// Keep track of the exact location of the edit.
|
// Keep track of the exact location of the edit.
|
||||||
|
let index = edit.index();
|
||||||
|
|
||||||
|
// If the edit was inserted before the end of the list, update the existing edits.
|
||||||
|
for edit in &mut edits {
|
||||||
|
if *edit.dependency_type == dependency_type {
|
||||||
|
match &mut edit.edit {
|
||||||
|
ArrayEdit::Add(existing) => {
|
||||||
|
if *existing >= index {
|
||||||
|
*existing += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ArrayEdit::Update(existing) => {
|
||||||
|
if *existing >= index {
|
||||||
|
*existing += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
edits.push(DependencyEdit {
|
edits.push(DependencyEdit {
|
||||||
dependency_type: &dependency_type,
|
dependency_type: &dependency_type,
|
||||||
requirement,
|
requirement,
|
||||||
|
|
|
@ -4411,8 +4411,8 @@ fn fail_to_add_revert_project() -> Result<()> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Ensure that the added dependencies are sorted
|
/// Ensure that the added dependencies are sorted if the dependency list was already sorted prior
|
||||||
/// if the dependency list was already sorted prior to adding the new one.
|
/// to the operation.
|
||||||
#[test]
|
#[test]
|
||||||
fn sorted_dependencies() -> Result<()> {
|
fn sorted_dependencies() -> Result<()> {
|
||||||
let context = TestContext::new("3.12");
|
let context = TestContext::new("3.12");
|
||||||
|
@ -4426,19 +4426,31 @@ fn sorted_dependencies() -> Result<()> {
|
||||||
requires-python = ">=3.12"
|
requires-python = ">=3.12"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"CacheControl[filecache]>=0.14,<0.15",
|
"CacheControl[filecache]>=0.14,<0.15",
|
||||||
"mwparserfromhell",
|
"iniconfig",
|
||||||
"pywikibot",
|
|
||||||
"sentry-sdk",
|
|
||||||
"yarl",
|
|
||||||
]
|
]
|
||||||
"#})?;
|
"#})?;
|
||||||
|
|
||||||
uv_snapshot!(context.filters(), context.add(&["pydantic"]).arg("--frozen"), @r###"
|
uv_snapshot!(context.filters(), context.add(&["typing-extensions", "anyio"]), @r###"
|
||||||
success: true
|
success: true
|
||||||
exit_code: 0
|
exit_code: 0
|
||||||
----- stdout -----
|
----- stdout -----
|
||||||
|
|
||||||
----- stderr -----
|
----- stderr -----
|
||||||
|
Resolved 13 packages in [TIME]
|
||||||
|
Prepared 12 packages in [TIME]
|
||||||
|
Installed 12 packages in [TIME]
|
||||||
|
+ anyio==4.3.0
|
||||||
|
+ cachecontrol==0.14.0
|
||||||
|
+ certifi==2024.2.2
|
||||||
|
+ charset-normalizer==3.3.2
|
||||||
|
+ filelock==3.13.1
|
||||||
|
+ idna==3.6
|
||||||
|
+ iniconfig==2.0.0
|
||||||
|
+ msgpack==1.0.8
|
||||||
|
+ requests==2.31.0
|
||||||
|
+ sniffio==1.3.1
|
||||||
|
+ typing-extensions==4.10.0
|
||||||
|
+ urllib3==2.2.1
|
||||||
"###);
|
"###);
|
||||||
|
|
||||||
let pyproject_toml = fs_err::read_to_string(context.temp_dir.join("pyproject.toml"))?;
|
let pyproject_toml = fs_err::read_to_string(context.temp_dir.join("pyproject.toml"))?;
|
||||||
|
@ -4455,11 +4467,9 @@ fn sorted_dependencies() -> Result<()> {
|
||||||
requires-python = ">=3.12"
|
requires-python = ">=3.12"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"CacheControl[filecache]>=0.14,<0.15",
|
"CacheControl[filecache]>=0.14,<0.15",
|
||||||
"mwparserfromhell",
|
"anyio>=4.3.0",
|
||||||
"pydantic",
|
"iniconfig",
|
||||||
"pywikibot",
|
"typing-extensions>=4.10.0",
|
||||||
"sentry-sdk",
|
|
||||||
"yarl",
|
|
||||||
]
|
]
|
||||||
"###
|
"###
|
||||||
);
|
);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue