From ce29497e4324d3e2f2c7c696a212672dbdb46884 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Fri, 14 Feb 2020 15:59:19 +0100 Subject: Replace Cmd with not-bash --- xtask/src/not_bash.rs | 96 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 96 insertions(+) create mode 100644 xtask/src/not_bash.rs (limited to 'xtask/src/not_bash.rs') diff --git a/xtask/src/not_bash.rs b/xtask/src/not_bash.rs new file mode 100644 index 000000000..a2e47c7af --- /dev/null +++ b/xtask/src/not_bash.rs @@ -0,0 +1,96 @@ +//! A bad shell -- small cross platform module for writing glue code +use std::{ + cell::RefCell, + env, + path::PathBuf, + process::{Command, Stdio}, +}; + +use anyhow::{bail, Context, Result}; + +macro_rules! _run { + ($($expr:expr),*) => { + run!($($expr),*; echo = true) + }; + ($($expr:expr),* ; echo = $echo:expr) => { + $crate::not_bash::run_process(format!($($expr),*), $echo) + }; +} +pub(crate) use _run as run; + +pub struct Pushd { + _p: (), +} + +pub fn pushd(path: impl Into) -> Pushd { + Env::with(|env| env.pushd(path.into())); + Pushd { _p: () } +} + +impl Drop for Pushd { + fn drop(&mut self) { + Env::with(|env| env.popd()) + } +} + +#[doc(hidden)] +pub fn run_process(cmd: String, echo: bool) -> Result { + run_process_inner(&cmd, echo).with_context(|| format!("process `{}` failed", cmd)) +} + +fn run_process_inner(cmd: &str, echo: bool) -> Result { + let cwd = Env::with(|env| env.cwd()); + let mut args = shelx(cmd); + let binary = args.remove(0); + + if echo { + println!("> {}", cmd) + } + + let output = Command::new(binary) + .args(args) + .current_dir(cwd) + .stdin(Stdio::null()) + .stderr(Stdio::inherit()) + .output()?; + let stdout = String::from_utf8(output.stdout)?; + + if echo { + print!("{}", stdout) + } + + if !output.status.success() { + bail!("returned non-zero status: {}", output.status) + } + + Ok(stdout) +} + +// FIXME: some real shell lexing here +fn shelx(cmd: &str) -> Vec { + cmd.split_whitespace().map(|it| it.to_string()).collect() +} + +#[derive(Default)] +struct Env { + pushd_stack: Vec, +} + +impl Env { + fn with T, T>(f: F) -> T { + thread_local! { + static ENV: RefCell = Default::default(); + } + ENV.with(|it| f(&mut *it.borrow_mut())) + } + + fn pushd(&mut self, dir: PathBuf) { + self.pushd_stack.push(dir) + } + fn popd(&mut self) { + self.pushd_stack.pop().unwrap(); + } + fn cwd(&self) -> PathBuf { + self.pushd_stack.last().cloned().unwrap_or_else(|| env::current_dir().unwrap()) + } +} -- cgit v1.2.3 From 269e2f22a942919d421b89287d5669b2c2607917 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Fri, 14 Feb 2020 17:05:56 +0100 Subject: More declarative fs massaging --- xtask/src/not_bash.rs | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) (limited to 'xtask/src/not_bash.rs') diff --git a/xtask/src/not_bash.rs b/xtask/src/not_bash.rs index a2e47c7af..4ec1efa73 100644 --- a/xtask/src/not_bash.rs +++ b/xtask/src/not_bash.rs @@ -2,6 +2,8 @@ use std::{ cell::RefCell, env, + ffi::OsStr, + fs, path::PathBuf, process::{Command, Stdio}, }; @@ -33,6 +35,31 @@ impl Drop for Pushd { } } +pub fn rm(glob: &str) -> Result<()> { + let cwd = Env::with(|env| env.cwd()); + ls(glob)?.into_iter().try_for_each(|it| fs::remove_file(cwd.join(it)))?; + Ok(()) +} + +pub fn ls(glob: &str) -> Result> { + let cwd = Env::with(|env| env.cwd()); + let mut res = Vec::new(); + for entry in fs::read_dir(&cwd)? { + let entry = entry?; + if matches(&entry.file_name(), glob) { + let path = entry.path(); + let path = path.strip_prefix(&cwd).unwrap(); + res.push(path.to_path_buf()) + } + } + return Ok(res); + + fn matches(file_name: &OsStr, glob: &str) -> bool { + assert!(glob.starts_with('*')); + file_name.to_string_lossy().ends_with(&glob[1..]) + } +} + #[doc(hidden)] pub fn run_process(cmd: String, echo: bool) -> Result { run_process_inner(&cmd, echo).with_context(|| format!("process `{}` failed", cmd)) -- cgit v1.2.3 From f2e8dfc8203bfd7cc69f58149577e207f6636fd3 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Fri, 14 Feb 2020 17:11:19 +0100 Subject: Cleanup --- xtask/src/not_bash.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'xtask/src/not_bash.rs') diff --git a/xtask/src/not_bash.rs b/xtask/src/not_bash.rs index 4ec1efa73..56d6c6c2d 100644 --- a/xtask/src/not_bash.rs +++ b/xtask/src/not_bash.rs @@ -87,7 +87,7 @@ fn run_process_inner(cmd: &str, echo: bool) -> Result { } if !output.status.success() { - bail!("returned non-zero status: {}", output.status) + bail!("{}", output.status) } Ok(stdout) -- cgit v1.2.3