Skip to content

Commit

Permalink
refactor(cmd): add process module
Browse files Browse the repository at this point in the history
  • Loading branch information
Ajpantuso committed Jan 27, 2024
1 parent f04f6ac commit 1f59079
Show file tree
Hide file tree
Showing 4 changed files with 81 additions and 75 deletions.
85 changes: 11 additions & 74 deletions src/cmd.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
use std::ffi::{OsStr, OsString};
use std::fmt::{Display, Formatter};
use std::io;
use std::io::{BufRead, BufReader, Write};
use std::ops::{Deref, DerefMut};
use std::path::{Path, PathBuf};
use std::process::{Child, Command, ExitStatus, Stdio};
use std::process::{Command, Stdio};
use std::sync::mpsc::channel;
use std::sync::{Mutex, RwLock};
use std::thread;
Expand All @@ -20,6 +18,7 @@ use crate::config::Settings;
use crate::env;
use crate::errors::Error::ScriptFailed;
use crate::file::display_path;
use crate::process::{spawn, ExitStatus};
use crate::ui::progress_report::SingleReport;

/// Create a command with any number of of positional arguments, which may be
Expand Down Expand Up @@ -236,8 +235,8 @@ impl<'a> CmdLineRunner<'a> {
let _write_lock = RAW_LOCK.write().unwrap();
return self.execute_raw();
}
let mut cp = TimedProcess::spawn(&mut self.cmd)
.wrap_err_with(|| format!("failed to execute command: {self}"))?;
let mut cp =
spawn(&mut self.cmd).wrap_err_with(|| format!("failed to execute command: {self}"))?;
let (tx, rx) = channel();
if let Some(stdout) = cp.stdout.take() {
thread::spawn({
Expand Down Expand Up @@ -312,16 +311,16 @@ impl<'a> CmdLineRunner<'a> {
let status = status.unwrap();

if !status.success() {
self.on_error(combined_output.join("\n"), *status)?;
return self.on_error(combined_output.join("\n"), status);
}

Ok(status.into())
}

fn execute_raw(mut self) -> Result<ExecStatus> {
let status = TimedProcess::spawn(&mut self.cmd)?.wait()?;
let status = spawn(&mut self.cmd)?.wait()?;
if !status.success() {
self.on_error(String::new(), *status)?;
return self.on_error(String::new(), status);
}

Ok(status.into())
Expand Down Expand Up @@ -358,7 +357,7 @@ impl<'a> CmdLineRunner<'a> {
}
}

fn on_error(&self, output: String, status: ExitStatus) -> Result<()> {
fn on_error(&self, output: String, status: ExitStatus) -> Result<ExecStatus> {
let settings = Settings::try_get()?;
match self.pr {
Some(pr) => {
Expand Down Expand Up @@ -396,72 +395,10 @@ impl Display for CmdLineRunner<'_> {
enum ChildProcessOutput {
Stdout(String),
Stderr(String),
ExitStatus(TimedProcessExitStatus),
ExitStatus(ExitStatus),
Signal(i32),
}

struct TimedProcess {
proc: Child,
instant: time::Instant,
}

impl TimedProcess {
fn spawn(cmd: &mut Command) -> io::Result<TimedProcess> {
Ok(Self {
proc: cmd.spawn()?,
instant: time::Instant::now(),
})
}

fn wait(&mut self) -> io::Result<TimedProcessExitStatus> {
let status = self.proc.wait()?;

Ok(TimedProcessExitStatus {
status,
elapsed: self.instant.elapsed(),
})
}
}

impl Deref for TimedProcess {
type Target = Child;

fn deref(&self) -> &Self::Target {
&self.proc
}
}

impl DerefMut for TimedProcess {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.proc
}
}

struct TimedProcessExitStatus {
pub status: ExitStatus,
elapsed: time::Duration,
}

impl TimedProcessExitStatus {
pub fn elapsed(&self) -> time::Duration {
self.elapsed
}
}

impl Deref for TimedProcessExitStatus {
type Target = ExitStatus;

fn deref(&self) -> &Self::Target {
&self.status
}
}

impl DerefMut for TimedProcessExitStatus {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.status
}
}

#[derive(Debug, Clone)]
pub struct ExecStatus {
elapsed: time::Duration,
Expand All @@ -473,8 +410,8 @@ impl ExecStatus {
}
}

impl From<TimedProcessExitStatus> for ExecStatus {
fn from(status: TimedProcessExitStatus) -> Self {
impl From<ExitStatus> for ExecStatus {
fn from(status: ExitStatus) -> Self {
Self {
elapsed: status.elapsed(),
}
Expand Down
2 changes: 1 addition & 1 deletion src/errors.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::process::ExitStatus;
use crate::process::ExitStatus;

use thiserror::Error;

Expand Down
1 change: 1 addition & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ mod logger;
mod migrate;
mod path_env;
mod plugins;
mod process;
mod rand;
mod runtime_symlinks;
mod shell;
Expand Down
68 changes: 68 additions & 0 deletions src/process.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
use color_eyre::Result;
use std::ops::{Deref, DerefMut};
use std::process;
use std::process::{Child, Command};
use std::time;

pub fn spawn(cmd: &mut Command) -> Result<Process> {
Ok(Process {
proc: cmd.spawn()?,
instant: time::Instant::now(),
})
}

pub struct Process {
proc: Child,
instant: time::Instant,
}

impl Process {
pub fn wait(&mut self) -> Result<ExitStatus> {
let status = self.proc.wait()?;

Ok(ExitStatus {
status,
elapsed: self.instant.elapsed(),
})
}
}

impl Deref for Process {
type Target = Child;

fn deref(&self) -> &Self::Target {
&self.proc
}
}

impl DerefMut for Process {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.proc
}
}

#[derive(Clone, Copy, Debug)]
pub struct ExitStatus {
pub status: process::ExitStatus,
elapsed: time::Duration,
}

impl ExitStatus {
pub fn elapsed(&self) -> time::Duration {
self.elapsed
}
}

impl Deref for ExitStatus {
type Target = process::ExitStatus;

fn deref(&self) -> &Self::Target {
&self.status
}
}

impl DerefMut for ExitStatus {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.status
}
}

0 comments on commit 1f59079

Please sign in to comment.