Treat missing package name error as an unsupported requirement (#1025)

## Summary

Based on user feedback. Calling it a "parse error" is misleading, since
this is really something we don't support, but that users can work
around.
This commit is contained in:
Charlie Marsh 2024-01-21 19:53:10 -05:00 committed by GitHub
parent 4026710189
commit 540442b8de
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 90 additions and 18 deletions

View file

@ -71,6 +71,9 @@ pub enum Pep508ErrorSource {
/// A URL parsing error.
#[error(transparent)]
UrlError(#[from] verbatim_url::VerbatimUrlError),
/// The version requirement is not supported.
#[error("{0}")]
UnsupportedRequirement(String),
}
impl Display for Pep508Error {
@ -842,11 +845,9 @@ fn parse(cursor: &mut Cursor) -> Result<Requirement, Pep508Error> {
// a package name. pip supports this in `requirements.txt`, but it doesn't adhere to
// the PEP 508 grammar.
let mut clone = cursor.clone().at(start);
return if let Ok(url) = parse_url(&mut clone) {
return if parse_url(&mut clone).is_ok() {
Err(Pep508Error {
message: Pep508ErrorSource::String(format!(
"URL requirement is missing a package name; expected: `package_name @ {url}`",
)),
message: Pep508ErrorSource::UnsupportedRequirement("URL requirement must be preceded by a package name. Add the name of the package before the URL (e.g., `package_name @ https://...`).".to_string()),
start,
len: clone.pos() - start,
input: clone.to_string(),
@ -1305,7 +1306,7 @@ mod tests {
assert_err(
r#"git+https://github.com/pallets/flask.git"#,
indoc! {"
URL requirement is missing a package name; expected: `package_name @ git+https://github.com/pallets/flask.git`
URL requirement must be preceded by a package name. Add the name of the package before the URL (e.g., `package_name @ https://...`).
git+https://github.com/pallets/flask.git
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^"
},

View file

@ -5,18 +5,20 @@ use std::path::{Component, Path, PathBuf};
use once_cell::sync::Lazy;
use regex::Regex;
use serde::{Deserialize, Serialize};
use url::Url;
/// A wrapper around [`Url`] that preserves the original string.
#[derive(Debug, Clone, Eq, derivative::Derivative)]
#[derivative(PartialEq, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct VerbatimUrl {
/// The parsed URL.
#[serde(
serialize_with = "Url::serialize_internal",
deserialize_with = "Url::deserialize_internal"
#[cfg_attr(
feature = "serde",
serde(
serialize_with = "Url::serialize_internal",
deserialize_with = "Url::deserialize_internal"
)
)]
url: Url,
/// The URL as it was provided by the user.