Assume git+ prefix when URLs end in .git (#5868)

## Summary

Right now, this applies _everywhere_, so the following also works:

```
pip install "elmer-circuitbuilder @ https://github.com/ElmerCSC/elmer_circuitbuilder.git"
```

I actually think that's ok?

Closes https://github.com/astral-sh/uv/issues/5866.
This commit is contained in:
Charlie Marsh 2024-08-07 11:50:36 -04:00 committed by GitHub
parent dceba77ff7
commit 9a80dfeed4
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 89 additions and 1 deletions

View file

@ -347,6 +347,11 @@ impl TryFrom<Url> for ParsedUrl {
message: "Unknown scheme", 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") { } else if url.scheme().eq_ignore_ascii_case("file") {
let path = url let path = url
.to_file_path() .to_file_path()

View file

@ -106,7 +106,7 @@ pub(crate) async fn add(
// Read the requirements. // Read the requirements.
let RequirementsSpecification { 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 // TODO(charlie): These are all default values. We should consider whether we want to make them
// optional on the downstream APIs. // optional on the downstream APIs.

View file

@ -491,6 +491,64 @@ fn add_git_raw() -> Result<()> {
Ok(()) 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#b270df1a2fb5d012294e9aaf05e7e0bab1e6a389)
"###);
Ok(())
}
/// `--raw-sources` should be considered conflicting with sources-specific arguments, like `--tag`. /// `--raw-sources` should be considered conflicting with sources-specific arguments, like `--tag`.
#[test] #[test]
fn add_raw_error() -> Result<()> { fn add_raw_error() -> Result<()> {

View file

@ -1357,6 +1357,31 @@ fn install_git_public_https() {
context.assert_installed("uv_public_pypackage", "0.1.0"); 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 /// Install and update a package from a public GitHub repository
#[test] #[test]
#[cfg(feature = "git")] #[cfg(feature = "git")]