Avoid mismatch in --locked with Git dependencies (#5865)

## Summary

We were dropping the query and fragment in the wrong place, so the URLs
didn't match up after resolving from an existing lockfile.

Closes https://github.com/astral-sh/uv/issues/5851.
This commit is contained in:
Charlie Marsh
2024-08-07 11:47:48 -04:00
committed by GitHub
parent e4ec6e4025
commit dceba77ff7
3 changed files with 49 additions and 23 deletions
+13 -10
View File
@@ -862,9 +862,15 @@ impl Distribution {
distribution_types::SourceDist::Directory(dir_dist)
}
Source::Git(url, git) => {
// Remove the fragment and query from the URL; they're already present in the
// `GitSource`.
let mut url = url.to_url();
url.set_fragment(None);
url.set_query(None);
// Reconstruct the `GitUrl` from the `GitSource`.
let git_url = uv_git::GitUrl::from_commit(
url.to_url(),
url,
GitReference::from(git.kind.clone()),
git.precise,
);
@@ -1613,13 +1619,14 @@ impl TryFrom<SourceWire> for Source {
match wire {
Registry { registry } => Ok(Source::Registry(registry)),
Git { git } => {
let mut url = Url::parse(&git)
let url = Url::parse(&git)
.map_err(|err| SourceParseError::InvalidUrl {
given: git.to_string(),
err,
})
.map_err(LockErrorKind::InvalidGitSourceUrl)?;
let git_source = GitSource::from_url(&mut url)
let git_source = GitSource::from_url(&url)
.map_err(|err| match err {
GitSourceError::InvalidSha => SourceParseError::InvalidSha {
given: git.to_string(),
@@ -1629,6 +1636,7 @@ impl TryFrom<SourceWire> for Source {
},
})
.map_err(LockErrorKind::InvalidGitSourceUrl)?;
Ok(Source::Git(UrlString::from(url), git_source))
}
Direct { url, subdirectory } => Ok(Source::Direct(url, DirectSource { subdirectory })),
@@ -1663,12 +1671,9 @@ enum GitSourceError {
}
impl GitSource {
/// Extracts a git source reference from the query pairs and the hash
/// Extracts a Git source reference from the query pairs and the hash
/// fragment in the given URL.
///
/// This also removes the query pairs and hash fragment from the given
/// URL in place.
fn from_url(url: &mut Url) -> Result<GitSource, GitSourceError> {
fn from_url(url: &Url) -> Result<GitSource, GitSourceError> {
let mut kind = GitSourceKind::DefaultBranch;
let mut subdirectory = None;
for (key, val) in url.query_pairs() {
@@ -1683,8 +1688,6 @@ impl GitSource {
let precise = GitSha::from_str(url.fragment().ok_or(GitSourceError::MissingSha)?)
.map_err(|_| GitSourceError::InvalidSha)?;
url.set_query(None);
url.set_fragment(None);
Ok(GitSource {
precise,
subdirectory,
+5 -5
View File
@@ -188,7 +188,7 @@ fn add_git() -> Result<()> {
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@0dacfd662c64cb4ceb16e6cf65a157a8b715b979?tag=0.0.1#0dacfd662c64cb4ceb16e6cf65a157a8b715b979)
+ uv-public-pypackage==0.1.0 (from git+https://github.com/astral-test/uv-public-pypackage@0dacfd662c64cb4ceb16e6cf65a157a8b715b979)
"###);
let pyproject_toml = fs_err::read_to_string(context.temp_dir.join("pyproject.toml"))?;
@@ -396,7 +396,7 @@ fn add_git_raw() -> Result<()> {
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@0dacfd662c64cb4ceb16e6cf65a157a8b715b979?rev=0.0.1#0dacfd662c64cb4ceb16e6cf65a157a8b715b979)
+ uv-public-pypackage==0.1.0 (from git+https://github.com/astral-test/uv-public-pypackage@0dacfd662c64cb4ceb16e6cf65a157a8b715b979)
"###);
let pyproject_toml = fs_err::read_to_string(context.temp_dir.join("pyproject.toml"))?;
@@ -547,7 +547,7 @@ fn add_unnamed() -> Result<()> {
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@0dacfd662c64cb4ceb16e6cf65a157a8b715b979?tag=0.0.1#0dacfd662c64cb4ceb16e6cf65a157a8b715b979)
+ uv-public-pypackage==0.1.0 (from git+https://github.com/astral-test/uv-public-pypackage@0dacfd662c64cb4ceb16e6cf65a157a8b715b979)
"###);
let pyproject_toml = fs_err::read_to_string(context.temp_dir.join("pyproject.toml"))?;
@@ -1460,7 +1460,7 @@ fn update() -> Result<()> {
- project==0.1.0 (from file://[TEMP_DIR]/)
+ project==0.1.0 (from file://[TEMP_DIR]/)
- requests==2.31.0
+ requests==2.32.3 (from git+https://github.com/psf/requests@0e322af87745eff34caffe4df68456ebc20d9068?tag=v2.32.3#0e322af87745eff34caffe4df68456ebc20d9068)
+ requests==2.32.3 (from git+https://github.com/psf/requests@0e322af87745eff34caffe4df68456ebc20d9068)
"###);
let pyproject_toml = fs_err::read_to_string(context.temp_dir.join("pyproject.toml"))?;
@@ -1639,7 +1639,7 @@ fn update_source_replace_url() -> Result<()> {
+ charset-normalizer==3.3.2
+ idna==3.6
+ project==0.1.0 (from file://[TEMP_DIR]/)
+ requests==2.32.3 (from git+https://github.com/psf/requests@0e322af87745eff34caffe4df68456ebc20d9068?tag=v2.32.3#0e322af87745eff34caffe4df68456ebc20d9068)
+ requests==2.32.3 (from git+https://github.com/psf/requests@0e322af87745eff34caffe4df68456ebc20d9068)
+ urllib3==2.2.1
"###);
+31 -8
View File
@@ -261,6 +261,18 @@ fn lock_sdist_git() -> Result<()> {
});
}
// Re-run with `--locked`.
uv_snapshot!(context.filters(), context.lock().arg("--locked"), @r###"
success: true
exit_code: 0
----- stdout -----
----- stderr -----
warning: `uv lock` is experimental and may change without warning
warning: `uv.sources` is experimental and may change without warning
Resolved 2 packages in [TIME]
"###);
// Install from the lockfile.
uv_snapshot!(context.filters(), context.sync().arg("--frozen"), @r###"
success: true
@@ -459,7 +471,7 @@ fn lock_sdist_git_pep508() -> Result<()> {
"#,
)?;
// deterministic! { context =>
deterministic! { context =>
uv_snapshot!(context.filters(), context.lock(), @r###"
success: true
exit_code: 0
@@ -496,7 +508,18 @@ fn lock_sdist_git_pep508() -> Result<()> {
"###
);
});
// }
}
// Re-run with `--locked`.
uv_snapshot!(context.filters(), context.lock().arg("--locked"), @r###"
success: true
exit_code: 0
----- stdout -----
----- stderr -----
warning: `uv lock` is experimental and may change without warning
Resolved 2 packages in [TIME]
"###);
// Re-lock with a precise commit that maps to the same tag.
let pyproject_toml = context.temp_dir.child("pyproject.toml");
@@ -510,7 +533,7 @@ fn lock_sdist_git_pep508() -> Result<()> {
"#,
)?;
// deterministic! { context =>
deterministic! { context =>
uv_snapshot!(context.filters(), context.lock(), @r###"
success: true
exit_code: 0
@@ -547,7 +570,7 @@ fn lock_sdist_git_pep508() -> Result<()> {
"###
);
});
// }
}
// Re-lock with a different commit.
let pyproject_toml = context.temp_dir.child("pyproject.toml");
@@ -561,7 +584,7 @@ fn lock_sdist_git_pep508() -> Result<()> {
"#,
)?;
// deterministic! { context =>
deterministic! { context =>
uv_snapshot!(context.filters(), context.lock(), @r###"
success: true
exit_code: 0
@@ -598,7 +621,7 @@ fn lock_sdist_git_pep508() -> Result<()> {
"###
);
});
// }
}
// Re-lock with a different tag (which matches the new commit).
let pyproject_toml = context.temp_dir.child("pyproject.toml");
@@ -612,7 +635,7 @@ fn lock_sdist_git_pep508() -> Result<()> {
"#,
)?;
// deterministic! { context =>
deterministic! { context =>
uv_snapshot!(context.filters(), context.lock(), @r###"
success: true
exit_code: 0
@@ -649,7 +672,7 @@ fn lock_sdist_git_pep508() -> Result<()> {
"###
);
});
// }
}
Ok(())
}