context: refactor context command running
All checks were successful
CI / build (push) Successful in 1m55s
All checks were successful
CI / build (push) Successful in 1m55s
This commit is contained in:
@@ -5,22 +5,12 @@ use std::path::{Path, PathBuf};
|
||||
|
||||
use super::local::LocalDriver;
|
||||
use super::ssh::SshDriver;
|
||||
|
||||
/// Internal trait defining the strategy for executing a command.
|
||||
///
|
||||
/// This allows to have different execution behaviors (Local, SSH, ...) while keeping the
|
||||
/// `ContextCommand` API consistent.
|
||||
pub trait CommandRunner {
|
||||
fn add_arg(&mut self, arg: String);
|
||||
fn status(&mut self) -> io::Result<std::process::ExitStatus>;
|
||||
fn output(&mut self) -> io::Result<std::process::Output>;
|
||||
}
|
||||
|
||||
pub trait ContextDriver {
|
||||
fn ensure_available(&self, src: &Path, dest_root: &str) -> io::Result<PathBuf>;
|
||||
fn retrieve_path(&self, src: &Path, dest: &Path) -> io::Result<()>;
|
||||
fn list_files(&self, path: &Path) -> io::Result<Vec<PathBuf>>;
|
||||
fn create_runner(&self, program: String) -> Box<dyn CommandRunner>;
|
||||
fn run(&self, program: &str, args: &[String]) -> io::Result<std::process::ExitStatus>;
|
||||
fn run_output(&self, program: &str, args: &[String]) -> io::Result<std::process::Output>;
|
||||
fn prepare_work_dir(&self) -> io::Result<String>;
|
||||
}
|
||||
|
||||
@@ -44,10 +34,11 @@ pub enum Context {
|
||||
|
||||
impl Context {
|
||||
pub fn command<S: AsRef<OsStr>>(&self, program: S) -> ContextCommand {
|
||||
let runner = self
|
||||
.driver()
|
||||
.create_runner(program.as_ref().to_string_lossy().to_string());
|
||||
ContextCommand { runner }
|
||||
ContextCommand {
|
||||
driver: self.driver(),
|
||||
program: program.as_ref().to_string_lossy().to_string(),
|
||||
args: Vec::new(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Ensures that the source file/directory exists at the destination context.
|
||||
@@ -93,15 +84,16 @@ impl Context {
|
||||
/// details of *how* the command is actually executed, allowing the user to simple chain arguments
|
||||
/// and call `status()` or `output()`.
|
||||
///
|
||||
/// It delegates the actual work to a `CommandRunner`.
|
||||
/// It delegates the actual work to a `ContextDriver`.
|
||||
pub struct ContextCommand {
|
||||
runner: Box<dyn CommandRunner>,
|
||||
driver: Box<dyn ContextDriver>,
|
||||
program: String,
|
||||
args: Vec<String>,
|
||||
}
|
||||
|
||||
impl ContextCommand {
|
||||
pub fn arg<S: AsRef<OsStr>>(&mut self, arg: S) -> &mut Self {
|
||||
self.runner
|
||||
.add_arg(arg.as_ref().to_string_lossy().to_string());
|
||||
self.args.push(arg.as_ref().to_string_lossy().to_string());
|
||||
self
|
||||
}
|
||||
|
||||
@@ -118,11 +110,11 @@ impl ContextCommand {
|
||||
}
|
||||
|
||||
pub fn status(&mut self) -> io::Result<std::process::ExitStatus> {
|
||||
self.runner.status()
|
||||
self.driver.run(&self.program, &self.args)
|
||||
}
|
||||
|
||||
// Capture output
|
||||
pub fn output(&mut self) -> io::Result<std::process::Output> {
|
||||
self.runner.output()
|
||||
self.driver.run_output(&self.program, &self.args)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user