summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNiklas Mohrin <niklas.mohrin@gmail.com>2020-11-08 22:23:43 +0100
committerDavid Peter <sharkdp@users.noreply.github.com>2020-11-23 14:06:54 +0100
commit31793cfa6287cb90cc12eb4fbd0c76bd496e91a5 (patch)
treeef6158094db86f6c3f5a6a0a112655b440dad658
parent6d75540d4e95c57ba89d5810d271bc687761763e (diff)
Add io cycle detection with clircle
-rw-r--r--Cargo.lock44
-rw-r--r--Cargo.toml1
-rw-r--r--src/controller.rs14
-rw-r--r--src/input.rs14
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",
@@ -245,6 +246,17 @@ dependencies = [
]
[[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"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -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",
@@ -668,6 +680,18 @@ dependencies = [
]
[[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"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -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<clircle::Identifier, ()> {
+ 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<dyn BufRead + 'a>,
pub(crate) first_line: Vec<u8>,