diff --git a/crates/uv-resolver/src/lock.rs b/crates/uv-resolver/src/lock.rs index 5dfee6e90..a9edb6bb3 100644 --- a/crates/uv-resolver/src/lock.rs +++ b/crates/uv-resolver/src/lock.rs @@ -732,14 +732,23 @@ impl Distribution { Ok(Dist::Source(source_dist)) } Source::Registry(url) => { + let file_url = sdist.url().ok_or_else(|| LockErrorKind::MissingUrl { + id: self.id.clone(), + })?; + let filename = + sdist + .filename() + .ok_or_else(|| LockErrorKind::MissingFilename { + id: self.id.clone(), + })?; let file = Box::new(distribution_types::File { dist_info_metadata: false, - filename: sdist.filename().unwrap().to_string(), + filename: filename.to_string(), hashes: vec![], requires_python: None, size: sdist.size(), upload_time_utc_ms: None, - url: FileLocation::AbsoluteUrl(url.to_string()), + url: FileLocation::AbsoluteUrl(file_url.to_string()), yanked: None, }); let index = IndexUrl::Url(VerbatimUrl::from_url(url.clone())); @@ -1196,7 +1205,7 @@ where } impl SourceDist { - pub(crate) fn filename(&self) -> Option> { + fn filename(&self) -> Option> { match self { SourceDist::Url { url, .. } => url.filename().ok(), SourceDist::Path { path, .. } => { @@ -1205,6 +1214,13 @@ impl SourceDist { } } + fn url(&self) -> Option<&Url> { + match &self { + SourceDist::Url { url, .. } => Some(url), + SourceDist::Path { .. } => None, + } + } + fn hash(&self) -> Option<&Hash> { match &self { SourceDist::Url { metadata, .. } => metadata.hash.as_ref(), @@ -1857,6 +1873,20 @@ enum LockErrorKind { /// The kind of the invalid source. source_type: &'static str, }, + /// An error that occurs when a distribution indicates that it is sourced from a registry, but + /// is missing a URL. + #[error("found registry distribution {id} without a valid URL")] + MissingUrl { + /// The ID of the distribution that is missing a URL. + id: DistributionId, + }, + /// An error that occurs when a distribution indicates that it is sourced from a registry, but + /// is missing a filename. + #[error("found registry distribution {id} without a valid filename")] + MissingFilename { + /// The ID of the distribution that is missing a filename. + id: DistributionId, + }, /// An error that occurs when a distribution is included with neither wheels nor a source /// distribution. #[error("found distribution {id} with neither wheels nor source distribution")] diff --git a/crates/uv/tests/lock.rs b/crates/uv/tests/lock.rs index 926bec39d..85e466053 100644 --- a/crates/uv/tests/lock.rs +++ b/crates/uv/tests/lock.rs @@ -190,6 +190,20 @@ fn lock_sdist_registry() -> Result<()> { ); }); + // Install from the lockfile. + uv_snapshot!(context.filters(), context.sync(), @r###" + success: true + exit_code: 0 + ----- stdout ----- + + ----- stderr ----- + warning: `uv sync` is experimental and may change without warning. + Downloaded 2 packages in [TIME] + Installed 2 packages in [TIME] + + project==0.1.0 (from file://[TEMP_DIR]/) + + source-distribution==0.0.1 + "###); + Ok(()) }