Propagate URL errors in verbatim parsing (#3720)

## Summary

Closes https://github.com/astral-sh/uv/issues/3715.

## Test Plan

```
❯ echo "/../test" | cargo run pip compile -
error: Couldn't parse requirement in `-` at position 0
  Caused by: path could not be normalized: /../test
/../test
^^^^^^^^

❯ echo "-e /../test" | cargo run pip compile -
error: Invalid URL in `-`: `/../test`
  Caused by: path could not be normalized: /../test
  Caused by: cannot normalize a relative path beyond the base directory
```
This commit is contained in:
Charlie Marsh 2024-05-21 15:58:59 -04:00 committed by GitHub
parent 19df1a4372
commit 558f628ef1
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 97 additions and 40 deletions

View file

@ -21,6 +21,8 @@ pub enum Error {
// Network error
#[error("Failed to parse URL: {0}")]
Url(String, #[source] url::ParseError),
#[error("Expected an absolute path, but received: {}", _0.user_display())]
RelativePath(PathBuf),
#[error(transparent)]
JoinRelativeUrl(#[from] pypi_types::JoinRelativeError),
#[error("Git operation failed")]

View file

@ -94,10 +94,10 @@ impl<'a> RegistryWheelIndex<'a> {
.filter_map(|flat_index| match flat_index {
FlatIndexLocation::Path(path) => {
let path = fs_err::canonicalize(path).ok()?;
Some(IndexUrl::Path(VerbatimUrl::from_path(path)))
Some(IndexUrl::Path(VerbatimUrl::from_path(path).ok()?))
}
FlatIndexLocation::Url(url) => {
Some(IndexUrl::Url(VerbatimUrl::unknown(url.clone())))
Some(IndexUrl::Url(VerbatimUrl::from_url(url.clone())))
}
})
.collect();

View file

@ -105,7 +105,8 @@ impl<'a, T: BuildContext> SourceDistributionBuilder<'a, T> {
Url::parse(url).map_err(|err| Error::Url(url.clone(), err))?
}
FileLocation::Path(path) => {
let url = Url::from_file_path(path).expect("path is absolute");
let url = Url::from_file_path(path)
.map_err(|()| Error::RelativePath(path.clone()))?;
return self
.archive(
source,
@ -262,7 +263,8 @@ impl<'a, T: BuildContext> SourceDistributionBuilder<'a, T> {
Url::parse(url).map_err(|err| Error::Url(url.clone(), err))?
}
FileLocation::Path(path) => {
let url = Url::from_file_path(path).expect("path is absolute");
let url = Url::from_file_path(path)
.map_err(|()| Error::RelativePath(path.clone()))?;
return self
.archive_metadata(
source,