From 31793cfa6287cb90cc12eb4fbd0c76bd496e91a5 Mon Sep 17 00:00:00 2001 From: Niklas Mohrin Date: Sun, 8 Nov 2020 22:23:43 +0100 Subject: [PATCH] Add io cycle detection with clircle --- Cargo.lock | 44 ++++++++++++++++++++++++++++++++++---------- Cargo.toml | 1 + src/controller.rs | 14 ++++++++++++++ src/input.rs | 14 ++++++++++++++ 4 files changed, 63 insertions(+), 10 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f5c13bec..7ae9d8e0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -99,6 +99,7 @@ dependencies = [ "assert_cmd", "atty", "clap", + "clircle", "console", "content_inspector", "dirs", @@ -244,6 +245,17 @@ dependencies = [ "vec_map", ] +[[package]] +name = "clircle" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44c9ae10f655554a2dd1ed8ad4e36203f5d7ceae3dc4aecdb8b1f2391bcd1e43" +dependencies = [ + "nix", + "serde", + "winapi", +] + [[package]] name = "console" version = "0.13.0" @@ -492,9 +504,9 @@ dependencies = [ [[package]] name = "git2" -version = "0.13.12" +version = "0.13.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca6f1a0238d7f8f8fd5ee642f4ebac4dbc03e03d1f78fbe7a3ede35dcf7e2224" +checksum = "1e094214efbc7fdbbdee952147e493b00e99a4e52817492277e98967ae918165" dependencies = [ "bitflags", "libc", @@ -511,9 +523,9 @@ checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574" [[package]] name = "globset" -version = "0.4.6" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c152169ef1e421390738366d2f796655fec62621dabbd0fd476f905934061e4a" +checksum = "7ad1da430bd7281dde2576f44c84cc3f0f7b475e7202cd503042dff01a8c8120" dependencies = [ "aho-corasick", "bstr", @@ -587,15 +599,15 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" [[package]] name = "libc" -version = "0.2.78" +version = "0.2.80" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa7087f49d294270db4e1928fc110c976cd4b9e5a16348e0a1df09afa99e6c98" +checksum = "4d58d1b70b004888f764dfbf6a26a3b0342a1632d33968e4a179d8011c760614" [[package]] name = "libgit2-sys" -version = "0.12.14+1.1.0" +version = "0.12.13+1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f25af58e6495f7caf2919d08f212de550cfa3ed2f5e744988938ea292b9f549" +checksum = "069eea34f76ec15f2822ccf78fe0cdb8c9016764d0a12865278585a74dbdeae5" dependencies = [ "cc", "libc", @@ -667,6 +679,18 @@ dependencies = [ "autocfg", ] +[[package]] +name = "nix" +version = "0.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85db2feff6bf70ebc3a4793191517d5f0331100a2f10f9bf93b5e5214f32b7b7" +dependencies = [ + "bitflags", + "cc", + "cfg-if", + "libc", +] + [[package]] name = "normalize-line-endings" version = "0.3.0" @@ -1011,9 +1035,9 @@ dependencies = [ [[package]] name = "serde_yaml" -version = "0.8.14" +version = "0.8.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7baae0a99f1a324984bcdc5f0718384c1f69775f1c7eec8b859b71b443e3fd7" +checksum = "ae3e2dd40a7cdc18ca80db804b7f461a39bb721160a85c9a1fa30134bf3c02a5" dependencies = [ "dtoa", "linked-hash-map", diff --git a/Cargo.toml b/Cargo.toml index a1af0195..d78bf8d4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -51,6 +51,7 @@ serde = { version = "1.0", features = ["derive"] } serde_yaml = "0.8" semver = "0.11" path_abs = { version = "0.5", default-features = false } +clircle = "0.1.3" [dependencies.git2] version = "0.13" diff --git a/src/controller.rs b/src/controller.rs index dff817cd..d9b8e809 100644 --- a/src/controller.rs +++ b/src/controller.rs @@ -13,6 +13,7 @@ use crate::output::OutputType; #[cfg(feature = "paging")] use crate::paging::PagingMode; use crate::printer::{InteractivePrinter, Printer, SimplePrinter}; +use std::convert::TryFrom; pub struct Controller<'a> { config: &'a Config<'a>, @@ -66,6 +67,14 @@ impl<'b> Controller<'b> { } let attached_to_pager = output_type.is_pager(); + let rw_cycle_detected = !attached_to_pager && { + let identifiers: Vec<_> = inputs + .iter() + .flat_map(clircle::Identifier::try_from) + .collect(); + clircle::stdout_among_inputs(&identifiers) + }; + let writer = output_type.handle()?; let mut no_errors: bool = true; @@ -78,6 +87,11 @@ impl<'b> Controller<'b> { } }; + if rw_cycle_detected { + print_error(&"The output file is also an input!".into(), writer); + return Ok(false); + } + for (index, input) in inputs.into_iter().enumerate() { match input.open(io::stdin().lock()) { Err(error) => { diff --git a/src/input.rs b/src/input.rs index b4b058e2..3a723631 100644 --- a/src/input.rs +++ b/src/input.rs @@ -1,6 +1,8 @@ +use std::convert::TryFrom; use std::ffi::{OsStr, OsString}; use std::fs::File; use std::io::{self, BufRead, BufReader, Read}; +use std::path::Path; use content_inspector::{self, ContentType}; @@ -192,6 +194,18 @@ impl<'a> Input<'a> { } } +impl TryFrom<&'_ Input<'_>> for clircle::Identifier { + type Error = (); + + fn try_from(input: &Input) -> std::result::Result { + match input.kind { + InputKind::OrdinaryFile(ref path) => Self::try_from(Path::new(path)).map_err(|_| ()), + InputKind::StdIn => Self::try_from(clircle::Stdio::Stdin).map_err(|_| ()), + InputKind::CustomReader(_) => Err(()), + } + } +} + pub(crate) struct InputReader<'a> { inner: Box, pub(crate) first_line: Vec,