use std::path::PathBuf;
use thiserror::Error;
use crate::vars::VarExpandError;
pub const EXEC_STDERR_CAPTURE_MAX: usize = 2048;
#[non_exhaustive]
#[derive(Debug, Error)]
pub enum ExecError {
#[error("variable expansion failed in field `{field}`: {source}")]
VarExpand {
field: &'static str,
#[source]
source: VarExpandError,
},
#[error("invalid path after expansion: `{0}`")]
InvalidPath(String),
#[error("require predicate failed: {detail}")]
RequireFailed {
detail: String,
},
#[error("exec validation failed: {0}")]
ExecInvalid(String),
#[error("no plugin registered for action `{0}`")]
UnknownAction(String),
#[error("symlink destination `{}` is occupied; enable `backup: true` to rename it out of the way", dst.display())]
SymlinkDestOccupied {
dst: PathBuf,
},
#[error("symlink creation denied (Windows: enable Developer Mode or run elevated): {detail}")]
SymlinkPrivilegeDenied {
detail: String,
},
#[error("path `{}` conflicts with action: {reason}", path.display())]
PathConflict {
path: PathBuf,
reason: &'static str,
},
#[error("rmdir on non-empty directory `{}` without force", path.display())]
RmdirNotEmpty {
path: PathBuf,
},
#[error("env scope `{scope}` persistence not supported on {platform}")]
EnvPersistenceNotSupported {
scope: String,
platform: &'static str,
},
#[error("predicate `{predicate}` not supported on {platform}")]
PredicateNotSupported {
predicate: &'static str,
platform: &'static str,
},
#[error("predicate `{predicate}` probe failed: {detail}")]
PredicateProbeFailed {
predicate: &'static str,
detail: String,
},
#[error("env scope `{scope}` persistence denied: {detail}")]
EnvPersistenceDenied {
scope: String,
detail: String,
},
#[error("exec exited with status {status}: {command}")]
ExecNonZero {
status: i32,
command: String,
stderr: String,
},
#[error("exec spawn failed for `{command}`: {detail}")]
ExecSpawnFailed {
command: String,
detail: String,
},
#[error("fs {op} failed on `{}`: {detail}", path.display())]
FsIo {
op: &'static str,
path: PathBuf,
detail: String,
},
#[error(
"cannot infer symlink kind for `{}`: `src` does not exist. \
Specify `kind: file` or `kind: directory` explicitly ({detail}).",
src.display()
)]
SymlinkAutoKindUnresolvable {
src: PathBuf,
detail: String,
},
#[error("meta recursion cycle at pack path `{}`", path.display())]
MetaCycle {
path: PathBuf,
},
#[error("no pack-type plugin registered for `{requested}`")]
UnknownPackType {
requested: String,
},
#[error(
"symlink create failed after backup, dst `{}` could not be restored from `{}` (create: {create_error}; restore: {})",
dst.display(),
backup.display(),
restore_error.as_deref().unwrap_or("<none>"),
)]
SymlinkCreateAfterBackupFailed {
dst: PathBuf,
backup: PathBuf,
create_error: String,
restore_error: Option<String>,
},
}
pub(crate) fn io_to_fs(op: &'static str, path: PathBuf, err: std::io::Error) -> ExecError {
ExecError::FsIo { op, path, detail: err.to_string() }
}