From 24ebdf02c046e786b880d623705eefae33fd6a4a Mon Sep 17 00:00:00 2001 From: Assad Yousuf <45297189+assadyousuf@users.noreply.github.com> Date: Thu, 9 Oct 2025 09:07:00 -0700 Subject: [PATCH] Preserve comments on version bump (#16141) ## Summary Fixes [1633](https://github.com/astral-sh/uv/issues/16133). Preserves comments preceding "version = ..." line when uv version --bump is ran ## Test Plan Added IT test --------- Co-authored-by: konsti --- crates/uv-workspace/src/pyproject_mut.rs | 16 ++++++--- crates/uv/tests/it/version.rs | 44 ++++++++++++++++++++++++ 2 files changed, 56 insertions(+), 4 deletions(-) diff --git a/crates/uv-workspace/src/pyproject_mut.rs b/crates/uv-workspace/src/pyproject_mut.rs index ba489818b..6070a9f9d 100644 --- a/crates/uv-workspace/src/pyproject_mut.rs +++ b/crates/uv-workspace/src/pyproject_mut.rs @@ -1141,10 +1141,18 @@ impl PyProjectTomlMut { .get_mut("project") .and_then(Item::as_table_mut) .ok_or(Error::MalformedWorkspace)?; - project.insert( - "version", - Item::Value(Value::String(Formatted::new(version.to_string()))), - ); + + if let Some(existing) = project.get_mut("version") { + if let Some(value) = existing.as_value_mut() { + let mut formatted = Value::from(version.to_string()); + *formatted.decor_mut() = value.decor().clone(); + *value = formatted; + } else { + *existing = Item::Value(Value::from(version.to_string())); + } + } else { + project.insert("version", Item::Value(Value::from(version.to_string()))); + } Ok(()) } diff --git a/crates/uv/tests/it/version.rs b/crates/uv/tests/it/version.rs index 7093b0cbb..b25f5bbce 100644 --- a/crates/uv/tests/it/version.rs +++ b/crates/uv/tests/it/version.rs @@ -289,6 +289,50 @@ requires-python = ">=3.12" Ok(()) } +/// Preserve comments immediately preceding the version when bumping +#[test] +fn version_bump_preserves_preceding_comments() -> Result<()> { + let context: TestContext = TestContext::new("3.12"); + + let pyproject_toml = context.temp_dir.child("pyproject.toml"); + pyproject_toml.write_str( + r#" + [project] + name = "hello-world" + # pre-1: stays above version + # pre-2: stays below pre-1 + version = "0.1.0" # eol: stays on same line + # after-version: remains after version + description = "Add your description here" + "#, + )?; + + // Bump patch version + context + .version() + .arg("--bump") + .arg("patch") + .assert() + .success(); + + // Ensure comments are preserved around the version entry + let pyproject = fs_err::read_to_string(&pyproject_toml)?; + assert_snapshot!( + pyproject, + @r#" + [project] + name = "hello-world" + # pre-1: stays above version + # pre-2: stays below pre-1 + version = "0.1.1" # eol: stays on same line + # after-version: remains after version + description = "Add your description here" + "# + ); + + Ok(()) +} + // Bump minor version #[test] fn version_bump_minor() -> Result<()> {