Revert changes to pyproject.toml when sync fails duing uv add (#6526)

## Summary

<!-- What's the purpose of the change? What does it do, and why? -->
This is a attempt at fixing https://github.com/astral-sh/uv/issues/6486.
It reverts changes made to `pyproject.toml` when sync fails during `uv
add`. This solution felt a little heavy handed and could probably be
improved but it is what happens when locking fails during `uv add` so I
thought it would be a good start.

## Test Plan

<!-- How was it tested? -->

I have added a test case for this to `tests/edit.rs`. It uses
`pytorch==1.0.2` to achieve the desired failure.
This commit is contained in:
Thomas Quillan 2024-08-23 10:54:33 -07:00 committed by GitHub
parent 13da5b3cf5
commit 429e6e61a8
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 75 additions and 2 deletions

View file

@ -597,7 +597,7 @@ pub(crate) async fn add(
// Initialize any shared state.
let state = SharedState::default();
project::sync::do_sync(
if let Err(err) = project::sync::do_sync(
&project,
&venv,
&lock,
@ -613,7 +613,14 @@ pub(crate) async fn add(
cache,
printer,
)
.await?;
.await
{
// Revert the changes to the `pyproject.toml`, if necessary.
if modified {
fs_err::write(project.root().join("pyproject.toml"), existing)?;
}
return Err(err.into());
}
Ok(ExitStatus::Success)
}

View file

@ -3873,3 +3873,69 @@ fn add_git_to_script() -> Result<()> {
});
Ok(())
}
// Revert changes to pyproject.toml if add fails
#[test]
fn fail_to_add_revert_project() -> 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 = []
"#})?;
// Adding `pytorch==1.0.2` should produce an error
let filters = std::iter::once((r"exit code: 1", "exit status: 1"))
.chain(context.filters())
.collect::<Vec<_>>();
uv_snapshot!(filters, context.add(&["pytorch==1.0.2"]), @r###"
success: false
exit_code: 2
----- stdout -----
----- stderr -----
Resolved 2 packages in [TIME]
error: Failed to prepare distributions
Caused by: Failed to fetch wheel: pytorch==1.0.2
Caused by: Build backend failed to build wheel through `build_wheel()` with exit status: 1
--- stdout:
--- stderr:
Traceback (most recent call last):
File "<string>", line 11, in <module>
File "[CACHE_DIR]/builds-v0/[TMP]/build_meta.py", line 410, in build_wheel
return self._build_with_temp_dir(
^^^^^^^^^^^^^^^^^^^^^^^^^^
File "[CACHE_DIR]/builds-v0/[TMP]/build_meta.py", line 395, in _build_with_temp_dir
self.run_setup()
File "[CACHE_DIR]/builds-v0/[TMP]/build_meta.py", line 487, in run_setup
super().run_setup(setup_script=setup_script)
File "[CACHE_DIR]/builds-v0/[TMP]/build_meta.py", line 311, in run_setup
exec(code, locals())
File "<string>", line 15, in <module>
Exception: You tried to install "pytorch". The package named for PyTorch is "torch"
---
"###);
let pyproject_toml = fs_err::read_to_string(context.temp_dir.join("pyproject.toml"))?;
insta::with_settings!({
filters => context.filters(),
}, {
assert_snapshot!(
pyproject_toml, @r###"
[project]
name = "project"
version = "0.1.0"
requires-python = ">=3.12"
dependencies = []
"###
);
});
Ok(())
}