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:
@@ -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,
|
||||
|
||||
@@ -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
@@ -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(())
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user