Use `PathBuf` types in `Source` enum (#6708)

This commit is contained in:
Charlie Marsh 2024-08-27 14:46:39 -04:00 committed by GitHub
parent bc5b069a61
commit a999303d2f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 24 additions and 19 deletions

View File

@ -257,6 +257,8 @@ pub enum LoweringError {
EditableFile(String), EditableFile(String),
#[error(transparent)] #[error(transparent)]
ParsedUrl(#[from] ParsedUrlError), ParsedUrl(#[from] ParsedUrlError),
#[error("Path must be UTF-8: `{0}`")]
NonUtf8Path(PathBuf),
#[error(transparent)] // Function attaches the context #[error(transparent)] // Function attaches the context
RelativeTo(io::Error), RelativeTo(io::Error),
} }
@ -264,7 +266,7 @@ pub enum LoweringError {
/// Convert a Git source into a [`RequirementSource`]. /// Convert a Git source into a [`RequirementSource`].
fn git_source( fn git_source(
git: &Url, git: &Url,
subdirectory: Option<String>, subdirectory: Option<PathBuf>,
rev: Option<String>, rev: Option<String>,
tag: Option<String>, tag: Option<String>,
branch: Option<String>, branch: Option<String>,
@ -282,7 +284,10 @@ fn git_source(
if let Some(rev) = reference.as_str() { if let Some(rev) = reference.as_str() {
url.set_path(&format!("{}@{}", url.path(), rev)); url.set_path(&format!("{}@{}", url.path(), rev));
} }
if let Some(subdirectory) = &subdirectory { if let Some(subdirectory) = subdirectory.as_ref() {
let subdirectory = subdirectory
.to_str()
.ok_or_else(|| LoweringError::NonUtf8Path(subdirectory.clone()))?;
url.set_fragment(Some(&format!("subdirectory={subdirectory}"))); url.set_fragment(Some(&format!("subdirectory={subdirectory}")));
} }
let url = VerbatimUrl::from_url(url); let url = VerbatimUrl::from_url(url);
@ -294,17 +299,20 @@ fn git_source(
repository, repository,
reference, reference,
precise: None, precise: None,
subdirectory: subdirectory.map(PathBuf::from), subdirectory,
}) })
} }
/// Convert a URL source into a [`RequirementSource`]. /// Convert a URL source into a [`RequirementSource`].
fn url_source(url: Url, subdirectory: Option<String>) -> Result<RequirementSource, LoweringError> { fn url_source(url: Url, subdirectory: Option<PathBuf>) -> Result<RequirementSource, LoweringError> {
let mut verbatim_url = url.clone(); let mut verbatim_url = url.clone();
if verbatim_url.fragment().is_some() { if verbatim_url.fragment().is_some() {
return Err(LoweringError::ForbiddenFragment(url)); return Err(LoweringError::ForbiddenFragment(url));
} }
if let Some(subdirectory) = &subdirectory { if let Some(subdirectory) = subdirectory.as_ref() {
let subdirectory = subdirectory
.to_str()
.ok_or_else(|| LoweringError::NonUtf8Path(subdirectory.clone()))?;
verbatim_url.set_fragment(Some(subdirectory)); verbatim_url.set_fragment(Some(subdirectory));
} }

View File

@ -314,7 +314,7 @@ pub enum Source {
/// The repository URL (without the `git+` prefix). /// The repository URL (without the `git+` prefix).
git: Url, git: Url,
/// The path to the directory with the `pyproject.toml`, if it's not in the archive root. /// The path to the directory with the `pyproject.toml`, if it's not in the archive root.
subdirectory: Option<String>, subdirectory: Option<PathBuf>,
// Only one of the three may be used; we'll validate this later and emit a custom error. // Only one of the three may be used; we'll validate this later and emit a custom error.
rev: Option<String>, rev: Option<String>,
tag: Option<String>, tag: Option<String>,
@ -331,13 +331,13 @@ pub enum Source {
url: Url, url: Url,
/// For source distributions, the path to the directory with the `pyproject.toml`, if it's /// For source distributions, the path to the directory with the `pyproject.toml`, if it's
/// not in the archive root. /// not in the archive root.
subdirectory: Option<String>, subdirectory: Option<PathBuf>,
}, },
/// The path to a dependency, either a wheel (a `.whl` file), source distribution (a `.zip` or /// The path to a dependency, either a wheel (a `.whl` file), source distribution (a `.zip` or
/// `.tar.gz` file), or source tree (i.e., a directory containing a `pyproject.toml` or /// `.tar.gz` file), or source tree (i.e., a directory containing a `pyproject.toml` or
/// `setup.py` file in the root). /// `setup.py` file in the root).
Path { Path {
path: String, path: PathBuf,
/// `false` by default. /// `false` by default.
editable: Option<bool>, editable: Option<bool>,
}, },
@ -355,12 +355,12 @@ pub enum Source {
/// A catch-all variant used to emit precise error messages when deserializing. /// A catch-all variant used to emit precise error messages when deserializing.
CatchAll { CatchAll {
git: String, git: String,
subdirectory: Option<String>, subdirectory: Option<PathBuf>,
rev: Option<String>, rev: Option<String>,
tag: Option<String>, tag: Option<String>,
branch: Option<String>, branch: Option<String>,
url: String, url: String,
patch: String, path: PathBuf,
index: String, index: String,
workspace: bool, workspace: bool,
}, },
@ -437,16 +437,13 @@ impl Source {
editable, editable,
path: relative_to(&install_path, root) path: relative_to(&install_path, root)
.or_else(|_| std::path::absolute(&install_path)) .or_else(|_| std::path::absolute(&install_path))
.map_err(SourceError::Absolute)? .map_err(SourceError::Absolute)?,
.to_str()
.ok_or_else(|| SourceError::NonUtf8Path(install_path))?
.to_string(),
}, },
RequirementSource::Url { RequirementSource::Url {
subdirectory, url, .. subdirectory, url, ..
} => Source::Url { } => Source::Url {
url: url.to_url(), url: url.to_url(),
subdirectory: subdirectory.map(|path| path.to_string_lossy().into_owned()), subdirectory,
}, },
RequirementSource::Git { RequirementSource::Git {
repository, repository,
@ -470,7 +467,7 @@ impl Source {
tag, tag,
branch, branch,
git: repository, git: repository,
subdirectory: subdirectory.map(|path| path.to_string_lossy().into_owned()), subdirectory,
} }
} else { } else {
Source::Git { Source::Git {
@ -478,7 +475,7 @@ impl Source {
tag, tag,
branch, branch,
git: repository, git: repository,
subdirectory: subdirectory.map(|path| path.to_string_lossy().into_owned()), subdirectory,
} }
} }
} }

4
uv.schema.json generated
View File

@ -1252,7 +1252,7 @@
"required": [ "required": [
"git", "git",
"index", "index",
"patch", "path",
"url", "url",
"workspace" "workspace"
], ],
@ -1269,7 +1269,7 @@
"index": { "index": {
"type": "string" "type": "string"
}, },
"patch": { "path": {
"type": "string" "type": "string"
}, },
"rev": { "rev": {