mirror of
https://github.com/astral-sh/uv.git
synced 2025-07-07 13:25:00 +00:00
Surface error when unable to find package (#45)
This commit is contained in:
parent
9be02d1590
commit
92160e37df
7 changed files with 30 additions and 11 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -1773,6 +1773,7 @@ dependencies = [
|
||||||
"platform-tags",
|
"platform-tags",
|
||||||
"puffin-client",
|
"puffin-client",
|
||||||
"puffin-package",
|
"puffin-package",
|
||||||
|
"thiserror",
|
||||||
"tracing",
|
"tracing",
|
||||||
"wheel-filename",
|
"wheel-filename",
|
||||||
]
|
]
|
||||||
|
|
|
@ -49,7 +49,7 @@ pub(crate) async fn compile(src: &Path, cache: Option<&Path>) -> Result<ExitStat
|
||||||
markers,
|
markers,
|
||||||
&tags,
|
&tags,
|
||||||
&client,
|
&client,
|
||||||
puffin_resolver::Flags::default(),
|
puffin_resolver::ResolveFlags::default(),
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
|
|
|
@ -82,7 +82,7 @@ pub(crate) async fn sync(src: &Path, cache: Option<&Path>, flags: SyncFlags) ->
|
||||||
markers,
|
markers,
|
||||||
&tags,
|
&tags,
|
||||||
&client,
|
&client,
|
||||||
puffin_resolver::Flags::NO_DEPS,
|
puffin_resolver::ResolveFlags::NO_DEPS,
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
|
|
|
@ -95,10 +95,7 @@ async fn main() -> ExitCode {
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
#[allow(clippy::print_stderr)]
|
#[allow(clippy::print_stderr)]
|
||||||
{
|
{
|
||||||
eprintln!("{}", "puffin failed".red().bold());
|
eprintln!("{}: {}", "error".red().bold(), err);
|
||||||
for cause in err.chain() {
|
|
||||||
eprintln!(" {} {cause}", "Cause:".bold());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
ExitStatus::Error.into()
|
ExitStatus::Error.into()
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
pub use api::{File, SimpleJson};
|
pub use api::{File, SimpleJson};
|
||||||
pub use client::{PypiClient, PypiClientBuilder};
|
pub use client::{PypiClient, PypiClientBuilder};
|
||||||
|
pub use error::PypiClientError;
|
||||||
|
|
||||||
mod api;
|
mod api;
|
||||||
mod client;
|
mod client;
|
||||||
|
|
|
@ -21,4 +21,5 @@ bitflags = { workspace = true }
|
||||||
futures = { workspace = true }
|
futures = { workspace = true }
|
||||||
pep440_rs = { path = "../pep440-rs" }
|
pep440_rs = { path = "../pep440-rs" }
|
||||||
pep508_rs = { path = "../pep508-rs" }
|
pep508_rs = { path = "../pep508-rs" }
|
||||||
|
thiserror = { workspace = true }
|
||||||
tracing = { workspace = true }
|
tracing = { workspace = true }
|
||||||
|
|
|
@ -5,6 +5,7 @@ use anyhow::Result;
|
||||||
use bitflags::bitflags;
|
use bitflags::bitflags;
|
||||||
use futures::future::Either;
|
use futures::future::Either;
|
||||||
use futures::{StreamExt, TryFutureExt};
|
use futures::{StreamExt, TryFutureExt};
|
||||||
|
use thiserror::Error;
|
||||||
use tracing::debug;
|
use tracing::debug;
|
||||||
|
|
||||||
use pep440_rs::Version;
|
use pep440_rs::Version;
|
||||||
|
@ -45,20 +46,38 @@ impl PinnedPackage {
|
||||||
|
|
||||||
bitflags! {
|
bitflags! {
|
||||||
#[derive(Debug, Copy, Clone, Default)]
|
#[derive(Debug, Copy, Clone, Default)]
|
||||||
pub struct Flags: u8 {
|
pub struct ResolveFlags: u8 {
|
||||||
/// Don't install package dependencies.
|
/// Don't install package dependencies.
|
||||||
const NO_DEPS = 1 << 0;
|
const NO_DEPS = 1 << 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Error, Debug)]
|
||||||
|
pub enum ResolveError {
|
||||||
|
#[error("Failed to find a version of {0} that satisfies the requirement")]
|
||||||
|
NotFound(Requirement),
|
||||||
|
|
||||||
|
#[error(transparent)]
|
||||||
|
Client(#[from] puffin_client::PypiClientError),
|
||||||
|
|
||||||
|
#[error(transparent)]
|
||||||
|
TrySend(#[from] futures::channel::mpsc::SendError),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> From<futures::channel::mpsc::TrySendError<T>> for ResolveError {
|
||||||
|
fn from(value: futures::channel::mpsc::TrySendError<T>) -> Self {
|
||||||
|
value.into_send_error().into()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Resolve a set of requirements into a set of pinned versions.
|
/// Resolve a set of requirements into a set of pinned versions.
|
||||||
pub async fn resolve(
|
pub async fn resolve(
|
||||||
requirements: &Requirements,
|
requirements: &Requirements,
|
||||||
markers: &MarkerEnvironment,
|
markers: &MarkerEnvironment,
|
||||||
tags: &Tags,
|
tags: &Tags,
|
||||||
client: &PypiClient,
|
client: &PypiClient,
|
||||||
flags: Flags,
|
flags: ResolveFlags,
|
||||||
) -> Result<Resolution> {
|
) -> Result<Resolution, ResolveError> {
|
||||||
// A channel to fetch package metadata (e.g., given `flask`, fetch all versions) and version
|
// A channel to fetch package metadata (e.g., given `flask`, fetch all versions) and version
|
||||||
// metadata (e.g., given `flask==1.0.0`, fetch the metadata for that version).
|
// metadata (e.g., given `flask==1.0.0`, fetch the metadata for that version).
|
||||||
let (package_sink, package_stream) = futures::channel::mpsc::unbounded();
|
let (package_sink, package_stream) = futures::channel::mpsc::unbounded();
|
||||||
|
@ -128,7 +147,7 @@ pub async fn resolve(
|
||||||
.iter()
|
.iter()
|
||||||
.all(|specifier| specifier.contains(&version))
|
.all(|specifier| specifier.contains(&version))
|
||||||
}) else {
|
}) else {
|
||||||
continue;
|
return Err(ResolveError::NotFound(requirement));
|
||||||
};
|
};
|
||||||
|
|
||||||
package_sink.unbounded_send(Request::Version(requirement, file.clone()))?;
|
package_sink.unbounded_send(Request::Version(requirement, file.clone()))?;
|
||||||
|
@ -151,7 +170,7 @@ pub async fn resolve(
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
if !flags.intersects(Flags::NO_DEPS) {
|
if !flags.intersects(ResolveFlags::NO_DEPS) {
|
||||||
// Enqueue its dependencies.
|
// Enqueue its dependencies.
|
||||||
for dependency in metadata.requires_dist {
|
for dependency in metadata.requires_dist {
|
||||||
if !dependency.evaluate_markers(
|
if !dependency.evaluate_markers(
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue