//! One error type for the whole CLI. //! //! Everything that can go wrong ends up as an [`Error`], gets a `?` at the //! call site, and is printed once by `main`. use std::path::PathBuf; use std::process::ExitStatus; /// Shorthand for the crate's result type. pub type Result = std::result::Result; /// How a failed process is described in [`Error::ExternalCommand`]. pub(crate) fn exit_code(status: &ExitStatus) -> String { status .code() .map_or_else(|| "signal".to_owned(), |code| code.to_string()) } #[derive(Debug, thiserror::Error)] pub enum Error { /// Nothing at the configured path at all. #[error("no kernel tree at `{path}`; set ${env} or clone one there")] KernelTreeMissing { path: PathBuf, env: &'static str }, /// Something is there, but it is not a kernel source tree. #[error("`{path}` is not a kernel source tree (no scripts/checkpatch.pl)")] NotAKernelTree { path: PathBuf }, /// An external tool ran and failed. #[error("`{program} {args}` failed (exit {code}):\n{stderr}")] ExternalCommand { program: String, args: String, code: String, stderr: String, }, /// An external tool could not even be started. #[error("could not run `{program}`")] CommandSpawn { program: String, #[source] source: std::io::Error, }, /// A patch file the user named does not exist. #[error("no patch named `{name}` in `{dir}`")] PatchNotFound { name: String, dir: PathBuf }, /// A revision named on the command line does not resolve. #[error("no revision `{rev}` in this tree; `--base` wants a branch or commit that exists")] UnknownRevision { rev: String }, /// The base is already at the tip, so there is no change to send. #[error("nothing to send: `{base}` and HEAD hold no commits; commit the change first")] NoCommitsToSend { base: String }, /// One patch file was asked to carry a whole set. #[error( "`{base}..HEAD` holds {count} commits; one patch file cannot carry a set (patch series support is not built yet)" )] RangeHoldsSeveralCommits { base: String, count: usize }, /// `--fix` was pointed at something that is not a patch file. #[error( "checkpatch only fixes a patch file; give `patch format` a patch instead of a revision" )] FixNeedsPatchFile, /// checkpatch's fix could not be put into the working tree. #[error("the fix could not be applied ({reason}); the working tree was left as it was")] FixApplyFailed { reason: String }, /// Re-rolling would land on a file that is already there. #[error("`{path}` already exists; delete it or pick another revision")] RerollWouldOverwrite { path: PathBuf }, #[error(transparent)] Io(#[from] std::io::Error), // Reached once `kernel quest` stops being a stub. #[allow(dead_code)] #[error(transparent)] Http(#[from] reqwest::Error), }