Revert "10.2.0 release " (#215)
Revert "10.2.0 release (#213)"
This reverts commit 13076fcef6.
This commit is contained in:
155
src/executor.rs
155
src/executor.rs
@@ -1,14 +1,11 @@
|
||||
//! Utilities for command execution
|
||||
use crate::error::{DryRun, TopgradeError};
|
||||
use crate::utils::{Check, CheckWithCodes};
|
||||
use anyhow::Result;
|
||||
use log::{debug, trace};
|
||||
use std::ffi::{OsStr, OsString};
|
||||
use std::path::Path;
|
||||
use std::process::{Child, Command, ExitStatus, Output};
|
||||
|
||||
use color_eyre::eyre;
|
||||
use color_eyre::eyre::Result;
|
||||
use tracing::debug;
|
||||
|
||||
use crate::command::CommandExt;
|
||||
use crate::error::DryRun;
|
||||
use std::process::{Child, Command, ExitStatus};
|
||||
|
||||
/// An enum telling whether Topgrade should perform dry runs or actually perform the steps.
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
@@ -59,16 +56,6 @@ pub enum Executor {
|
||||
}
|
||||
|
||||
impl Executor {
|
||||
/// Get the name of the program being run.
|
||||
///
|
||||
/// Will give weird results for non-UTF-8 programs; see `to_string_lossy()`.
|
||||
pub fn get_program(&self) -> String {
|
||||
match self {
|
||||
Executor::Wet(c) => c.get_program().to_string_lossy().into_owned(),
|
||||
Executor::Dry(c) => c.program.to_string_lossy().into_owned(),
|
||||
}
|
||||
}
|
||||
|
||||
/// See `std::process::Command::arg`
|
||||
pub fn arg<S: AsRef<OsStr>>(&mut self, arg: S) -> &mut Executor {
|
||||
match self {
|
||||
@@ -152,7 +139,7 @@ impl Executor {
|
||||
let result = match self {
|
||||
Executor::Wet(c) => {
|
||||
debug!("Running {:?}", c);
|
||||
c.spawn_checked().map(ExecutorChild::Wet)?
|
||||
c.spawn().map(ExecutorChild::Wet)?
|
||||
}
|
||||
Executor::Dry(c) => {
|
||||
c.dry_run();
|
||||
@@ -166,7 +153,7 @@ impl Executor {
|
||||
/// See `std::process::Command::output`
|
||||
pub fn output(&mut self) -> Result<ExecutorOutput> {
|
||||
match self {
|
||||
Executor::Wet(c) => Ok(ExecutorOutput::Wet(c.output_checked()?)),
|
||||
Executor::Wet(c) => Ok(ExecutorOutput::Wet(c.output()?)),
|
||||
Executor::Dry(c) => {
|
||||
c.dry_run();
|
||||
Ok(ExecutorOutput::Dry)
|
||||
@@ -174,28 +161,23 @@ impl Executor {
|
||||
}
|
||||
}
|
||||
|
||||
/// An extension of `status_checked` that allows you to set a sequence of codes
|
||||
/// A convinence method for `spawn().wait().check()`.
|
||||
/// Returns an error if something went wrong during the execution or if the
|
||||
/// process exited with failure.
|
||||
pub fn check_run(&mut self) -> Result<()> {
|
||||
self.spawn()?.wait()?.check()
|
||||
}
|
||||
|
||||
/// An extension of `check_run` that allows you to set a sequence of codes
|
||||
/// that can indicate success of a script
|
||||
#[cfg_attr(windows, allow(dead_code))]
|
||||
pub fn status_checked_with_codes(&mut self, codes: &[i32]) -> Result<()> {
|
||||
match self {
|
||||
Executor::Wet(c) => c.status_checked_with(|status| {
|
||||
if status.success() || status.code().as_ref().map(|c| codes.contains(c)).unwrap_or(false) {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(())
|
||||
}
|
||||
}),
|
||||
Executor::Dry(c) => {
|
||||
c.dry_run();
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
#[allow(dead_code)]
|
||||
pub fn check_run_with_codes(&mut self, codes: &[i32]) -> Result<()> {
|
||||
self.spawn()?.wait()?.check_with_codes(codes)
|
||||
}
|
||||
}
|
||||
|
||||
pub enum ExecutorOutput {
|
||||
Wet(Output),
|
||||
Wet(std::process::Output),
|
||||
Dry,
|
||||
}
|
||||
|
||||
@@ -232,33 +214,78 @@ pub enum ExecutorChild {
|
||||
Dry,
|
||||
}
|
||||
|
||||
impl CommandExt for Executor {
|
||||
type Child = ExecutorChild;
|
||||
impl ExecutorChild {
|
||||
/// See `std::process::Child::wait`
|
||||
pub fn wait(&mut self) -> Result<ExecutorExitStatus> {
|
||||
let result = match self {
|
||||
ExecutorChild::Wet(c) => c.wait().map(ExecutorExitStatus::Wet)?,
|
||||
ExecutorChild::Dry => ExecutorExitStatus::Dry,
|
||||
};
|
||||
|
||||
// TODO: It might be nice to make `output_checked_with` return something that has a
|
||||
// variant for wet/dry runs.
|
||||
|
||||
fn output_checked_with(&mut self, succeeded: impl Fn(&Output) -> Result<(), ()>) -> eyre::Result<Output> {
|
||||
match self {
|
||||
Executor::Wet(c) => c.output_checked_with(succeeded),
|
||||
Executor::Dry(c) => {
|
||||
c.dry_run();
|
||||
Err(DryRun().into())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn status_checked_with(&mut self, succeeded: impl Fn(ExitStatus) -> Result<(), ()>) -> eyre::Result<()> {
|
||||
match self {
|
||||
Executor::Wet(c) => c.status_checked_with(succeeded),
|
||||
Executor::Dry(c) => {
|
||||
c.dry_run();
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn spawn_checked(&mut self) -> eyre::Result<Self::Child> {
|
||||
self.spawn()
|
||||
Ok(result)
|
||||
}
|
||||
}
|
||||
|
||||
/// The Result of wait. Contains an actual `std::process::ExitStatus` if executed by a wet command.
|
||||
pub enum ExecutorExitStatus {
|
||||
Wet(ExitStatus),
|
||||
Dry,
|
||||
}
|
||||
|
||||
impl CheckWithCodes for ExecutorExitStatus {
|
||||
fn check_with_codes(self, codes: &[i32]) -> Result<()> {
|
||||
match self {
|
||||
ExecutorExitStatus::Wet(e) => e.check_with_codes(codes),
|
||||
ExecutorExitStatus::Dry => Ok(()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Extension methods for `std::process::Command`
|
||||
pub trait CommandExt {
|
||||
/// Run the command, wait for it to complete, check the return code and decode the output as UTF-8.
|
||||
fn check_output(&mut self) -> Result<String>;
|
||||
fn string_output(&mut self) -> Result<String>;
|
||||
}
|
||||
|
||||
impl CommandExt for Command {
|
||||
fn check_output(&mut self) -> Result<String> {
|
||||
let output = self.output()?;
|
||||
trace!("Output of {:?}: {:?}", self, output);
|
||||
let status = output.status;
|
||||
if !status.success() {
|
||||
let stderr = String::from_utf8(output.stderr).unwrap_or_default();
|
||||
return Err(TopgradeError::ProcessFailedWithOutput(status, stderr).into());
|
||||
}
|
||||
Ok(String::from_utf8(output.stdout)?)
|
||||
}
|
||||
|
||||
fn string_output(&mut self) -> Result<String> {
|
||||
let output = self.output()?;
|
||||
trace!("Output of {:?}: {:?}", self, output);
|
||||
Ok(String::from_utf8(output.stdout)?)
|
||||
}
|
||||
}
|
||||
|
||||
impl CommandExt for Executor {
|
||||
fn check_output(&mut self) -> Result<String> {
|
||||
let output = match self.output()? {
|
||||
ExecutorOutput::Wet(output) => output,
|
||||
ExecutorOutput::Dry => return Err(DryRun().into()),
|
||||
};
|
||||
let status = output.status;
|
||||
if !status.success() {
|
||||
let stderr = String::from_utf8(output.stderr).unwrap_or_default();
|
||||
return Err(TopgradeError::ProcessFailedWithOutput(status, stderr).into());
|
||||
}
|
||||
Ok(String::from_utf8(output.stdout)?)
|
||||
}
|
||||
|
||||
fn string_output(&mut self) -> Result<String> {
|
||||
let output = match self.output()? {
|
||||
ExecutorOutput::Wet(output) => output,
|
||||
ExecutorOutput::Dry => return Err(DryRun().into()),
|
||||
};
|
||||
Ok(String::from_utf8(output.stdout)?)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user