Skip to content

Commit

Permalink
chore: Drop exit_status_error feature flag (#106)
Browse files Browse the repository at this point in the history
The exit_status_error feature flag isn't yet stable.
Drop it in favor of a hand-rolled implementation.
  • Loading branch information
abhinav authored Sep 7, 2024
1 parent 7cbabdd commit fed0224
Show file tree
Hide file tree
Showing 5 changed files with 78 additions and 2 deletions.
1 change: 1 addition & 0 deletions src/edit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use std::{env, fs, path, process};

use anyhow::{anyhow, bail, Context, Result};

use crate::exec::ExitStatusExt;
use crate::{git, restack};

const USAGE: &str = "\
Expand Down
75 changes: 75 additions & 0 deletions src/exec.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
//! exec adds an exit_ok method to process::ExitStatus.
//! This method returns an Error if the status code is non-zero.
//!
//! This is our own stable copy of the exit_status_error unstable feature.

use std::process;

// In lieu of exit_status_error stabilization,
// extend ExitStatus with our own exit_ok method.

/// Error returned if a process exits with a non-zero status code.
#[derive(Debug)]
pub struct Error {
/// The exit code of the process.
///
/// Guaranteed to be non-zero.
pub code: i32,
}

impl std::error::Error for Error {
fn description(&self) -> &str {
"exited with a non-zero status code"
}
}

impl std::fmt::Display for Error {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(f, "exited with status code: {}", self.code)
}
}

/// Extend ExitStatus with an exit_ok method.
pub trait ExitStatusExt {
/// Require that the process exited successfully.
/// If the process did not exit successfully, return an Error.
fn exit_ok(self) -> Result<(), Error>;
}

impl ExitStatusExt for process::ExitStatus {
fn exit_ok(self) -> Result<(), Error> {
if self.success() {
Ok(())
} else {
Err(Error {
code: self.code().unwrap_or(1),
})
}
}
}

#[cfg(test)]
mod tests {
use pretty_assertions::assert_eq;

use super::*;

#[test]
fn test_exit_ok() -> anyhow::Result<()> {
let status = process::Command::new("true").status()?;
status.exit_ok()?;

Ok(())
}

#[test]
fn test_exit_err() -> anyhow::Result<()> {
let status = process::Command::new("false").status()?;
let got_err = status.exit_ok().expect_err("expected error");

assert_eq!(1, got_err.code);
assert_eq!("exited with status code: 1", got_err.to_string());

Ok(())
}
}
1 change: 1 addition & 0 deletions src/git/shell.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use std::{ffi, path, process};
use anyhow::{Context, Result};

use super::{Branch, Git};
use crate::exec::ExitStatusExt;

/// Shell provides access to the git CLI.
pub struct Shell {}
Expand Down
2 changes: 1 addition & 1 deletion src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,11 @@
//! [2]: https://abhinavg.net/posts/restacking-branches/

#![warn(missing_docs)]
#![feature(exit_status_error)]

use anyhow::{anyhow, bail, Result};

mod edit;
mod exec;
mod git;
mod io;
mod restack;
Expand Down
1 change: 0 additions & 1 deletion tools/test/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,5 @@
//! restack's tests and integration tests.

#![warn(missing_docs)]
#![feature(exit_status_error)]

pub mod gitscript;

0 comments on commit fed0224

Please sign in to comment.