on master help sign in
Add io cycle detection with clircle
commit31793cfa6287cb90cc12eb4fbd0c76bd496e91a5 authorNiklas Mohrin <niklas.mohrin@gmail.com> dateSun 8 Nov 2020, 22:23 (6 years ago) parent6d75540
4 files changed+63−10
Cargo.lock+34−10 Cargo.toml+1 src/controller.rs+14 src/input.rs+14
Cargo.lock+34−10
@@ -99,6 +99,7 @@ dependencies = [
9999 "assert_cmd",
100100 "atty",
101101 "clap",
102+ "clircle",
102103 "console",
103104 "content_inspector",
104105 "dirs",
@@ -244,6 +245,17 @@ dependencies = [
244245 "vec_map",
245246]
246247
248+[[package]]
249+name = "clircle"
250+version = "0.1.3"
251+source = "registry+https://github.com/rust-lang/crates.io-index"
252+checksum = "44c9ae10f655554a2dd1ed8ad4e36203f5d7ceae3dc4aecdb8b1f2391bcd1e43"
253+dependencies = [
254+ "nix",
255+ "serde",
256+ "winapi",
257+]
258+
247259[[package]]
248260name = "console"
249261version = "0.13.0"
@@ -492,9 +504,9 @@ dependencies = [
492504
493505[[package]]
494506name = "git2"
495−version = "0.13.12"
507+version = "0.13.11"
496508source = "registry+https://github.com/rust-lang/crates.io-index"
497−checksum = "ca6f1a0238d7f8f8fd5ee642f4ebac4dbc03e03d1f78fbe7a3ede35dcf7e2224"
509+checksum = "1e094214efbc7fdbbdee952147e493b00e99a4e52817492277e98967ae918165"
498510dependencies = [
499511 "bitflags",
500512 "libc",
@@ -511,9 +523,9 @@ checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574"
511523
512524[[package]]
513525name = "globset"
514−version = "0.4.6"
526+version = "0.4.5"
515527source = "registry+https://github.com/rust-lang/crates.io-index"
516−checksum = "c152169ef1e421390738366d2f796655fec62621dabbd0fd476f905934061e4a"
528+checksum = "7ad1da430bd7281dde2576f44c84cc3f0f7b475e7202cd503042dff01a8c8120"
517529dependencies = [
518530 "aho-corasick",
519531 "bstr",
@@ -587,15 +599,15 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55"
587599
588600[[package]]
589601name = "libc"
590−version = "0.2.78"
602+version = "0.2.80"
591603source = "registry+https://github.com/rust-lang/crates.io-index"
592−checksum = "aa7087f49d294270db4e1928fc110c976cd4b9e5a16348e0a1df09afa99e6c98"
604+checksum = "4d58d1b70b004888f764dfbf6a26a3b0342a1632d33968e4a179d8011c760614"
593605
594606[[package]]
595607name = "libgit2-sys"
596−version = "0.12.14+1.1.0"
608+version = "0.12.13+1.0.1"
597609source = "registry+https://github.com/rust-lang/crates.io-index"
598−checksum = "8f25af58e6495f7caf2919d08f212de550cfa3ed2f5e744988938ea292b9f549"
610+checksum = "069eea34f76ec15f2822ccf78fe0cdb8c9016764d0a12865278585a74dbdeae5"
599611dependencies = [
600612 "cc",
601613 "libc",
@@ -667,6 +679,18 @@ dependencies = [
667679 "autocfg",
668680]
669681
682+[[package]]
683+name = "nix"
684+version = "0.19.0"
685+source = "registry+https://github.com/rust-lang/crates.io-index"
686+checksum = "85db2feff6bf70ebc3a4793191517d5f0331100a2f10f9bf93b5e5214f32b7b7"
687+dependencies = [
688+ "bitflags",
689+ "cc",
690+ "cfg-if",
691+ "libc",
692+]
693+
670694[[package]]
671695name = "normalize-line-endings"
672696version = "0.3.0"
@@ -1011,9 +1035,9 @@ dependencies = [
10111035
10121036[[package]]
10131037name = "serde_yaml"
1014−version = "0.8.14"
1038+version = "0.8.13"
10151039source = "registry+https://github.com/rust-lang/crates.io-index"
1016−checksum = "f7baae0a99f1a324984bcdc5f0718384c1f69775f1c7eec8b859b71b443e3fd7"
1040+checksum = "ae3e2dd40a7cdc18ca80db804b7f461a39bb721160a85c9a1fa30134bf3c02a5"
10171041dependencies = [
10181042 "dtoa",
10191043 "linked-hash-map",
Cargo.toml+1
@@ -51,6 +51,7 @@ serde = { version = "1.0", features = ["derive"] }
5151serde_yaml = "0.8"
5252semver = "0.11"
5353path_abs = { version = "0.5", default-features = false }
54+clircle = "0.1.3"
5455
5556[dependencies.git2]
5657version = "0.13"
src/controller.rs+14
@@ -13,6 +13,7 @@ use crate::output::OutputType;
1313#[cfg(feature = "paging")]
1414use crate::paging::PagingMode;
1515use crate::printer::{InteractivePrinter, Printer, SimplePrinter};
16+use std::convert::TryFrom;
1617
1718pub struct Controller<'a> {
1819 config: &'a Config<'a>,
@@ -66,6 +67,14 @@ impl<'b> Controller<'b> {
6667 }
6768
6869 let attached_to_pager = output_type.is_pager();
70+ let rw_cycle_detected = !attached_to_pager && {
71+ let identifiers: Vec<_> = inputs
72+ .iter()
73+ .flat_map(clircle::Identifier::try_from)
74+ .collect();
75+ clircle::stdout_among_inputs(&identifiers)
76+ };
77+
6978 let writer = output_type.handle()?;
7079 let mut no_errors: bool = true;
7180
@@ -78,6 +87,11 @@ impl<'b> Controller<'b> {
7887 }
7988 };
8089
90+ if rw_cycle_detected {
91+ print_error(&"The output file is also an input!".into(), writer);
92+ return Ok(false);
93+ }
94+
8195 for (index, input) in inputs.into_iter().enumerate() {
8296 match input.open(io::stdin().lock()) {
8397 Err(error) => {
src/input.rs+14
@@ -1,6 +1,8 @@
1+use std::convert::TryFrom;
12use std::ffi::{OsStr, OsString};
23use std::fs::File;
34use std::io::{self, BufRead, BufReader, Read};
5+use std::path::Path;
46
57use content_inspector::{self, ContentType};
68
@@ -192,6 +194,18 @@ impl<'a> Input<'a> {
192194 }
193195}
194196
197+impl TryFrom<&'_ Input<'_>> for clircle::Identifier {
198+ type Error = ();
199+
200+ fn try_from(input: &Input) -> std::result::Result<clircle::Identifier, ()> {
201+ match input.kind {
202+ InputKind::OrdinaryFile(ref path) => Self::try_from(Path::new(path)).map_err(|_| ()),
203+ InputKind::StdIn => Self::try_from(clircle::Stdio::Stdin).map_err(|_| ()),
204+ InputKind::CustomReader(_) => Err(()),
205+ }
206+ }
207+}
208+
195209pub(crate) struct InputReader<'a> {
196210 inner: Box<dyn BufRead + 'a>,
197211 pub(crate) first_line: Vec<u8>,