From 4581160d41fa773c3d6da504ffd221b2f18ae6fa Mon Sep 17 00:00:00 2001 From: Charlie Marsh Date: Tue, 1 Oct 2024 11:45:38 -0400 Subject: [PATCH] Always remove git+ --- crates/uv-workspace/src/pyproject.rs | 8 +++ crates/uv/tests/lock.rs | 92 ++++++++++++++++++++++++++++ 2 files changed, 100 insertions(+) diff --git a/crates/uv-workspace/src/pyproject.rs b/crates/uv-workspace/src/pyproject.rs index 90419804a8724..71c614bd98ee2 100644 --- a/crates/uv-workspace/src/pyproject.rs +++ b/crates/uv-workspace/src/pyproject.rs @@ -675,6 +675,7 @@ impl<'de> Deserialize<'de> for Source { )); } + // At most one of `rev`, `tag`, or `branch` may be set. match (rev.as_ref(), tag.as_ref(), branch.as_ref()) { (None, None, None) => {} (Some(_), None, None) => {} @@ -687,6 +688,13 @@ impl<'de> Deserialize<'de> for Source { } }; + // If the user prefixed the URL with `git+`, strip it. + let git = if let Some(git) = git.as_str().strip_prefix("git+") { + Url::parse(git).map_err(serde::de::Error::custom)? + } else { + git + }; + return Ok(Self::Git { git, subdirectory, diff --git a/crates/uv/tests/lock.rs b/crates/uv/tests/lock.rs index a6753229a3d59..a110b0f0635ff 100644 --- a/crates/uv/tests/lock.rs +++ b/crates/uv/tests/lock.rs @@ -2686,6 +2686,98 @@ fn lock_preference() -> Result<()> { Ok(()) } +/// If the user includes `git+` in a `tool.uv.sources` entry, we shouldn't fail. +#[test] +#[cfg(feature = "git")] +fn lock_git_plus_prefix() -> Result<()> { + let context = TestContext::new("3.12"); + + // Lock against `main`. + let pyproject_toml = context.temp_dir.child("pyproject.toml"); + pyproject_toml.write_str( + r#" + [project] + name = "project" + version = "0.1.0" + requires-python = ">=3.12" + dependencies = ["uv-public-pypackage"] + + [build-system] + requires = ["setuptools>=42"] + build-backend = "setuptools.build_meta" + + [tool.uv.sources] + uv-public-pypackage = { git = "git+https://github.com/astral-test/uv-public-pypackage" } + "#, + )?; + + uv_snapshot!(context.filters(), context.lock(), @r###" + success: true + exit_code: 0 + ----- stdout ----- + + ----- stderr ----- + Resolved 2 packages in [TIME] + "###); + + let lock = context.read("uv.lock"); + + insta::with_settings!({ + filters => context.filters(), + }, { + assert_snapshot!( + lock, @r###" + version = 1 + requires-python = ">=3.12" + + [options] + exclude-newer = "2024-03-25T00:00:00Z" + + [[package]] + name = "project" + version = "0.1.0" + source = { editable = "." } + dependencies = [ + { name = "uv-public-pypackage" }, + ] + + [package.metadata] + requires-dist = [{ name = "uv-public-pypackage", git = "https://github.com/astral-test/uv-public-pypackage" }] + + [[package]] + name = "uv-public-pypackage" + version = "0.1.0" + source = { git = "https://github.com/astral-test/uv-public-pypackage#b270df1a2fb5d012294e9aaf05e7e0bab1e6a389" } + "### + ); + }); + + // Re-run with `--locked`. + uv_snapshot!(context.filters(), context.lock().arg("--locked"), @r###" + success: true + exit_code: 0 + ----- stdout ----- + + ----- stderr ----- + Resolved 2 packages in [TIME] + "###); + + // Install from the lockfile, excluding development dependencies. + uv_snapshot!(context.filters(), context.sync().arg("--frozen").arg("--no-dev"), @r###" + success: true + exit_code: 0 + ----- stdout ----- + + ----- stderr ----- + Prepared 2 packages in [TIME] + Installed 2 packages in [TIME] + + project==0.1.0 (from file://[TEMP_DIR]/) + + uv-public-pypackage==0.1.0 (from git+https://github.com/astral-test/uv-public-pypackage@b270df1a2fb5d012294e9aaf05e7e0bab1e6a389) + "###); + + Ok(()) +} + /// Respect locked versions with `uv lock`, unless `--upgrade` is passed. #[test] #[cfg(feature = "git")]