From ba5abcaff0001f21516241eb677a5a3634a7fa7f Mon Sep 17 00:00:00 2001 From: Charlie Marsh Date: Wed, 7 Aug 2024 11:14:40 -0400 Subject: [PATCH] Assume git+ prefix when URLs end in .git --- crates/pypi-types/src/parsed_url.rs | 5 +++ crates/uv/src/commands/project/add.rs | 2 +- crates/uv/tests/edit.rs | 58 +++++++++++++++++++++++++++ crates/uv/tests/pip_install.rs | 25 ++++++++++++ 4 files changed, 89 insertions(+), 1 deletion(-) diff --git a/crates/pypi-types/src/parsed_url.rs b/crates/pypi-types/src/parsed_url.rs index 16396b91203e6..f562886b740f3 100644 --- a/crates/pypi-types/src/parsed_url.rs +++ b/crates/pypi-types/src/parsed_url.rs @@ -347,6 +347,11 @@ impl TryFrom for ParsedUrl { message: "Unknown scheme", }), } + } else if Path::new(url.path()) + .extension() + .is_some_and(|ext| ext.eq_ignore_ascii_case("git")) + { + Ok(Self::Git(ParsedGitUrl::try_from(url)?)) } else if url.scheme().eq_ignore_ascii_case("file") { let path = url .to_file_path() diff --git a/crates/uv/src/commands/project/add.rs b/crates/uv/src/commands/project/add.rs index b0e1c97b736a3..6f5ffafa02169 100644 --- a/crates/uv/src/commands/project/add.rs +++ b/crates/uv/src/commands/project/add.rs @@ -106,7 +106,7 @@ pub(crate) async fn add( // Read the requirements. let RequirementsSpecification { requirements, .. } = - RequirementsSpecification::from_sources(&requirements, &[], &[], &client_builder).await?; + RequirementsSpecification::from_simple_sources(&requirements, &client_builder).await?; // TODO(charlie): These are all default values. We should consider whether we want to make them // optional on the downstream APIs. diff --git a/crates/uv/tests/edit.rs b/crates/uv/tests/edit.rs index 3236d76a0af72..3ce43c35f7eb7 100644 --- a/crates/uv/tests/edit.rs +++ b/crates/uv/tests/edit.rs @@ -491,6 +491,64 @@ fn add_git_raw() -> Result<()> { Ok(()) } +/// Add a Git requirement without the `git+` prefix. +#[test] +fn add_git_implicit() -> 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 = ["anyio==3.7.0"] + "#})?; + + uv_snapshot!(context.filters(), context.lock(), @r###" + success: true + exit_code: 0 + ----- stdout ----- + + ----- stderr ----- + warning: `uv lock` is experimental and may change without warning + Resolved 4 packages in [TIME] + "###); + + uv_snapshot!(context.filters(), context.sync().arg("--frozen"), @r###" + success: true + exit_code: 0 + ----- stdout ----- + + ----- stderr ----- + warning: `uv sync` is experimental and may change without warning + Prepared 4 packages in [TIME] + Installed 4 packages in [TIME] + + anyio==3.7.0 + + idna==3.6 + + project==0.1.0 (from file://[TEMP_DIR]/) + + sniffio==1.3.1 + "###); + + // Omit the `git+` prefix. + uv_snapshot!(context.filters(), context.add(&["uv-public-pypackage @ https://github.com/astral-test/uv-public-pypackage.git"]).arg("--preview"), @r###" + success: true + exit_code: 0 + ----- stdout ----- + + ----- stderr ----- + Resolved 5 packages in [TIME] + Prepared 2 packages in [TIME] + Uninstalled 1 package in [TIME] + Installed 2 packages in [TIME] + - project==0.1.0 (from file://[TEMP_DIR]/) + + project==0.1.0 (from file://[TEMP_DIR]/) + + uv-public-pypackage==0.1.0 (from git+https://github.com/astral-test/uv-public-pypackage.git@b270df1a2fb5d012294e9aaf05e7e0bab1e6a389) + "###); + + Ok(()) +} + /// `--raw-sources` should be considered conflicting with sources-specific arguments, like `--tag`. #[test] fn add_raw_error() -> Result<()> { diff --git a/crates/uv/tests/pip_install.rs b/crates/uv/tests/pip_install.rs index 6f016010328e4..fd0fa7a55b39c 100644 --- a/crates/uv/tests/pip_install.rs +++ b/crates/uv/tests/pip_install.rs @@ -1357,6 +1357,31 @@ fn install_git_public_https() { context.assert_installed("uv_public_pypackage", "0.1.0"); } +/// Install a package from a public GitHub repository, omitting the `git+` prefix +#[test] +#[cfg(feature = "git")] +fn install_implicit_git_public_https() { + let context = TestContext::new("3.8"); + + uv_snapshot!( + context + .pip_install() + .arg("uv-public-pypackage @ https://github.com/astral-test/uv-public-pypackage.git"), + @r###" + success: true + exit_code: 0 + ----- stdout ----- + + ----- stderr ----- + Resolved 1 package in [TIME] + Prepared 1 package in [TIME] + Installed 1 package in [TIME] + + uv-public-pypackage==0.1.0 (from git+https://github.com/astral-test/uv-public-pypackage.git@b270df1a2fb5d012294e9aaf05e7e0bab1e6a389) + "###); + + context.assert_installed("uv_public_pypackage", "0.1.0"); +} + /// Install and update a package from a public GitHub repository #[test] #[cfg(feature = "git")]