use std::fmt;
use crate::types::{Ecosystem, PackageManager};
#[derive(Debug)]
pub(crate) enum ResolveError {
NoSignalsFound {
ecosystem: Ecosystem,
soft: bool,
},
DevEnginesFailHard {
pm: PackageManager,
reason: DevEnginesFailReason,
},
MismatchPolicyError {
declared: PackageManager,
field: &'static str,
lockfile: PackageManager,
},
InvalidOverride {
value: String,
reason: &'static str,
},
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub(crate) enum DevEnginesFailReason {
BinaryMissing,
VersionMismatch {
declared: String,
actual: String,
},
}
impl fmt::Display for ResolveError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::NoSignalsFound { ecosystem, soft } => {
let suffix = if *soft { "" } else { " (--fallback=error)" };
write!(
f,
"no {} package manager detected{suffix}. Checked: lockfiles, manifest \
(packageManager + devEngines), PATH. Pin one with `--pm <name>`, set \
`RUNNER_PM=<name>`, add it to runner.toml, or install a supported PM.",
ecosystem.label(),
)
}
Self::DevEnginesFailHard { pm, reason } => match reason {
DevEnginesFailReason::BinaryMissing => write!(
f,
"devEngines.packageManager declares {} but it was not found on PATH \
(onFail=error)",
pm.label(),
),
DevEnginesFailReason::VersionMismatch { declared, actual } => write!(
f,
"devEngines.packageManager requires {} {declared} but the installed version \
is {actual} (onFail=error)",
pm.label(),
),
},
Self::MismatchPolicyError {
declared,
field,
lockfile,
} => write!(
f,
"{field} declares {} but the lockfile reflects {} (--on-mismatch=error)",
declared.label(),
lockfile.label(),
),
Self::InvalidOverride { value, reason } => {
write!(f, "invalid override value {value:?}: {reason}")
}
}
}
}
impl std::error::Error for ResolveError {}