From 9ed4a968d995e7985301867b243b2b83e5fb8e2a Mon Sep 17 00:00:00 2001 From: Rain Date: Sat, 27 Feb 2021 12:38:21 -0800 Subject: [PATCH] add support for camino Utf8Path and Utf8PathBuf Add support behind a non-default `"camino"` feature. Closes #90. --- .github/workflows/ci.yml | 1 + Cargo.toml | 4 ++++ src/lib.rs | 31 ++++++++++++++++++++++++++++ src/test.rs | 44 +++++++++++++++++++++++++++++++++++++++- 4 files changed, 79 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0abefcc..89a29aa 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -17,6 +17,7 @@ jobs: toolchain: ${{ matrix.rust_version }} override: true - run: cargo test + - run: cargo test --all-features - name: test duct_sh run: cargo test working-directory: ./duct_sh diff --git a/Cargo.toml b/Cargo.toml index a106a92..b1fe4a0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,9 +14,13 @@ edition = "2018" os_pipe = "0.9.0" shared_child = "0.3.4" once_cell = "1.0.1" +camino = { version = "1.0.1", optional = true } [target.'cfg(unix)'.dependencies] libc = "0.2.43" [dev-dependencies] tempdir = "0.3.7" + +[package.metadata.docs.rs] +all-features = true diff --git a/src/lib.rs b/src/lib.rs index e4254f4..6abb9a7 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -11,6 +11,13 @@ //! - [GitHub repo](https://github.com/oconnor663/duct.rs) //! - [the same library, in Python](https://github.com/oconnor663/duct.py) //! +//! Optional features +//! ----------------- +//! +//! `camino`: Adds support for [`camino`] paths as the first argument to `cmd!` and `cmd`. +//! +//! [`camino`]: https://docs.rs/camino/1 +//! //! Examples //! -------- //! @@ -1755,6 +1762,30 @@ impl<'a> IntoExecutablePath for &'a PathBuf { } } +#[cfg(feature = "camino")] +mod camino_impls { + use super::*; + use camino::{Utf8Path, Utf8PathBuf}; + + impl<'a> IntoExecutablePath for &'a Utf8Path { + fn to_executable(self) -> OsString { + dotify_relative_exe_path(self.as_ref()).into() + } + } + + impl IntoExecutablePath for Utf8PathBuf { + fn to_executable(self) -> OsString { + dotify_relative_exe_path(self.as_ref()).into() + } + } + + impl<'a> IntoExecutablePath for &'a Utf8PathBuf { + fn to_executable(self) -> OsString { + dotify_relative_exe_path(self.as_ref()).into() + } + } +} + impl<'a> IntoExecutablePath for &'a str { fn to_executable(self) -> OsString { self.into() diff --git a/src/test.rs b/src/test.rs index 9e89f3f..5def462 100644 --- a/src/test.rs +++ b/src/test.rs @@ -1,4 +1,4 @@ -use super::{cmd, Expression}; +use super::{cmd, Expression, ExpressionInner}; use std; use std::collections::HashMap; use std::env; @@ -610,3 +610,45 @@ fn test_pids() -> io::Result<()> { Ok(()) } + +#[test] +fn test_into_executable_path() { + let expected_undotted: Vec = vec!["does-not-exist".into(), "arg".into()]; + let expected_dotted: Vec = vec![ + [".", "does-not-exist"].iter().collect::().into(), + "arg".into(), + ]; + + // Bare strings are undotted. + let cmd = cmd!("does-not-exist", "arg"); + assert!(matches!(&*cmd.0, ExpressionInner::Cmd(x) if x == &expected_undotted)); + let cmd = cmd!("does-not-exist".to_string(), "arg"); + assert!(matches!(&*cmd.0, ExpressionInner::Cmd(x) if x == &expected_undotted)); + + // Path and PathBuf are dotted. + let cmd = cmd!(Path::new("does-not-exist"), "arg"); + assert!(matches!(&*cmd.0, ExpressionInner::Cmd(x) if x == &expected_dotted)); + let cmd = cmd!(PathBuf::from("does-not-exist"), "arg"); + assert!(matches!(&*cmd.0, ExpressionInner::Cmd(x) if x == &expected_dotted)); + let cmd = cmd!(&PathBuf::from("does-not-exist"), "arg"); + assert!(matches!(&*cmd.0, ExpressionInner::Cmd(x) if x == &expected_dotted)); +} + +#[cfg(feature = "camino")] +#[test] +fn test_into_executable_utf8_path() { + use camino::{Utf8Path, Utf8PathBuf}; + + let expected_dotted: Vec = vec![ + [".", "does-not-exist"].iter().collect::().into(), + "arg".into(), + ]; + + // Utf8Path and Utf8PathBuf are dotted. + let cmd = cmd!(Utf8Path::new("does-not-exist"), "arg"); + assert!(matches!(&*cmd.0, ExpressionInner::Cmd(x) if x == &expected_dotted)); + let cmd = cmd!(Utf8PathBuf::from("does-not-exist"), "arg"); + assert!(matches!(&*cmd.0, ExpressionInner::Cmd(x) if x == &expected_dotted)); + let cmd = cmd!(&Utf8PathBuf::from("does-not-exist"), "arg"); + assert!(matches!(&*cmd.0, ExpressionInner::Cmd(x) if x == &expected_dotted)); +}