From 08e8b40e451b17c404c8795ae431636a3a48bca8 Mon Sep 17 00:00:00 2001 From: Joining7943 <111500881+Joining7943@users.noreply.github.com> Date: Thu, 20 Apr 2023 21:08:12 +0200 Subject: [PATCH 1/3] tail: Refactor paths::Input::from method, Settings::inputs now use Vec instead of VecDeque --- src/uu/tail/src/args.rs | 26 ++++++++++---------------- src/uu/tail/src/follow/watch.rs | 3 +-- src/uu/tail/src/paths.rs | 11 ++++++----- 3 files changed, 17 insertions(+), 23 deletions(-) diff --git a/src/uu/tail/src/args.rs b/src/uu/tail/src/args.rs index 55014e029..eff332230 100644 --- a/src/uu/tail/src/args.rs +++ b/src/uu/tail/src/args.rs @@ -12,7 +12,6 @@ use clap::{Arg, ArgAction, ArgMatches, Command}; use fundu::DurationParser; use is_terminal::IsTerminal; use same_file::Handle; -use std::collections::VecDeque; use std::ffi::OsString; use std::time::Duration; use uucore::error::{UResult, USimpleError, UUsageError}; @@ -141,7 +140,8 @@ pub struct Settings { pub use_polling: bool, pub verbose: bool, pub presume_input_pipe: bool, - pub inputs: VecDeque, + /// `FILE(s)` positional arguments + pub inputs: Vec, } impl Default for Settings { @@ -173,11 +173,11 @@ impl Settings { } settings.mode = FilterMode::from_obsolete_args(args); let input = if let Some(name) = name { - Input::from(&name) + Input::from(name) } else { Input::default() }; - settings.inputs.push_back(input); + settings.inputs.push(input); settings } @@ -282,19 +282,13 @@ impl Settings { } } - let mut inputs: VecDeque = matches - .get_many::(options::ARG_FILES) - .map(|v| v.map(|string| Input::from(&string)).collect()) - .unwrap_or_default(); + settings.inputs = matches + .get_raw(options::ARG_FILES) + .map(|v| v.map(Input::from).collect()) + .unwrap_or_else(|| vec![Input::default()]); - // apply default and add '-' to inputs if none is present - if inputs.is_empty() { - inputs.push_front(Input::default()); - } - - settings.verbose = inputs.len() > 1 && !matches.get_flag(options::verbosity::QUIET); - - settings.inputs = inputs; + settings.verbose = + settings.inputs.len() > 1 && !matches.get_flag(options::verbosity::QUIET); Ok(settings) } diff --git a/src/uu/tail/src/follow/watch.rs b/src/uu/tail/src/follow/watch.rs index 2c3cf10b8..966f39120 100644 --- a/src/uu/tail/src/follow/watch.rs +++ b/src/uu/tail/src/follow/watch.rs @@ -10,7 +10,6 @@ use crate::follow::files::{FileHandling, PathData}; use crate::paths::{Input, InputKind, MetadataExtTail, PathExtTail}; use crate::{platform, text}; use notify::{RecommendedWatcher, RecursiveMode, Watcher, WatcherKind}; -use std::collections::VecDeque; use std::io::BufRead; use std::path::{Path, PathBuf}; use std::sync::mpsc::{self, channel, Receiver}; @@ -270,7 +269,7 @@ impl Observer { self.follow_name() && self.retry } - fn init_files(&mut self, inputs: &VecDeque) -> UResult<()> { + fn init_files(&mut self, inputs: &Vec) -> UResult<()> { if let Some(watcher_rx) = &mut self.watcher_rx { for input in inputs { match input.kind() { diff --git a/src/uu/tail/src/paths.rs b/src/uu/tail/src/paths.rs index 4badd6866..d813ea942 100644 --- a/src/uu/tail/src/paths.rs +++ b/src/uu/tail/src/paths.rs @@ -27,20 +27,21 @@ pub struct Input { } impl Input { - pub fn from>(string: &T) -> Self { - let kind = if string.as_ref() == Path::new(text::DASH) { + pub fn from>(string: T) -> Self { + let string = string.as_ref(); + let kind = if string == OsStr::new(text::DASH) { InputKind::Stdin } else { - InputKind::File(PathBuf::from(string.as_ref())) + InputKind::File(PathBuf::from(string)) }; let display_name = match kind { - InputKind::File(_) => string.as_ref().to_string_lossy().to_string(), + InputKind::File(_) => string.to_string_lossy().to_string(), InputKind::Stdin => { if cfg!(unix) { text::STDIN_HEADER.to_string() } else { - string.as_ref().to_string_lossy().to_string() + string.to_string_lossy().to_string() } } }; From ae60045f3f0cf35c4f893c02f22d3c93b396b37f Mon Sep 17 00:00:00 2001 From: Joining7943 <111500881+Joining7943@users.noreply.github.com> Date: Thu, 20 Apr 2023 21:12:24 +0200 Subject: [PATCH 2/3] tail: Fix printed header for stdin should be the same on all platforms --- src/uu/tail/src/paths.rs | 43 ++++++++++++++++++++++++++------------ tests/by-util/test_tail.rs | 6 +----- 2 files changed, 31 insertions(+), 18 deletions(-) diff --git a/src/uu/tail/src/paths.rs b/src/uu/tail/src/paths.rs index d813ea942..cce3270a8 100644 --- a/src/uu/tail/src/paths.rs +++ b/src/uu/tail/src/paths.rs @@ -10,7 +10,10 @@ use std::ffi::OsStr; use std::fs::{File, Metadata}; use std::io::{Seek, SeekFrom}; #[cfg(unix)] -use std::os::unix::fs::{FileTypeExt, MetadataExt}; +use std::os::unix::{ + fs::{FileTypeExt, MetadataExt}, + prelude::OsStrExt, +}; use std::path::{Path, PathBuf}; use uucore::error::UResult; @@ -20,6 +23,30 @@ pub enum InputKind { Stdin, } +#[cfg(unix)] +impl From<&OsStr> for InputKind { + fn from(value: &OsStr) -> Self { + const DASH: [u8; 1] = [b'-']; + + if value.as_bytes() == DASH { + Self::Stdin + } else { + Self::File(PathBuf::from(value)) + } + } +} + +#[cfg(not(unix))] +impl From<&OsStr> for InputKind { + fn from(value: &OsStr) -> Self { + if value == OsStr::new(text::DASH) { + Self::Stdin + } else { + Self::File(PathBuf::from(value)) + } + } +} + #[derive(Debug, Clone)] pub struct Input { kind: InputKind, @@ -29,21 +56,11 @@ pub struct Input { impl Input { pub fn from>(string: T) -> Self { let string = string.as_ref(); - let kind = if string == OsStr::new(text::DASH) { - InputKind::Stdin - } else { - InputKind::File(PathBuf::from(string)) - }; + let kind = string.into(); let display_name = match kind { InputKind::File(_) => string.to_string_lossy().to_string(), - InputKind::Stdin => { - if cfg!(unix) { - text::STDIN_HEADER.to_string() - } else { - string.to_string_lossy().to_string() - } - } + InputKind::Stdin => text::STDIN_HEADER.to_string(), }; Self { kind, display_name } diff --git a/tests/by-util/test_tail.rs b/tests/by-util/test_tail.rs index f3e55e434..2391a5f7a 100644 --- a/tests/by-util/test_tail.rs +++ b/tests/by-util/test_tail.rs @@ -145,12 +145,8 @@ fn test_stdin_redirect_offset() { } #[test] -#[cfg(all(not(target_vendor = "apple"), not(target_os = "windows")))] // FIXME: for currently not working platforms +#[cfg(all(not(target_vendor = "apple")))] // FIXME: for currently not working platforms fn test_stdin_redirect_offset2() { - // FIXME: windows: Failed because of difference in printed header. See below. - // actual : ==> - <== - // expected: ==> standard input <== - // like test_stdin_redirect_offset but with multiple files let ts = TestScenario::new(util_name!()); From 5a667db43daee79fd67c329f0dd808d6bbbf8357 Mon Sep 17 00:00:00 2001 From: Terts Diepraam Date: Mon, 3 Jul 2023 13:20:48 +0200 Subject: [PATCH 3/3] tail: clean up some small things in input parsing --- src/uu/tail/src/args.rs | 5 +++-- src/uu/tail/src/paths.rs | 9 ++------- 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/src/uu/tail/src/args.rs b/src/uu/tail/src/args.rs index eff332230..487e366e6 100644 --- a/src/uu/tail/src/args.rs +++ b/src/uu/tail/src/args.rs @@ -7,7 +7,7 @@ use crate::paths::Input; use crate::{parse, platform, Quotable}; -use clap::crate_version; +use clap::{crate_version, value_parser}; use clap::{Arg, ArgAction, ArgMatches, Command}; use fundu::DurationParser; use is_terminal::IsTerminal; @@ -283,7 +283,7 @@ impl Settings { } settings.inputs = matches - .get_raw(options::ARG_FILES) + .get_many::(options::ARG_FILES) .map(|v| v.map(Input::from).collect()) .unwrap_or_else(|| vec![Input::default()]); @@ -584,6 +584,7 @@ pub fn uu_app() -> Command { Arg::new(options::ARG_FILES) .action(ArgAction::Append) .num_args(1..) + .value_parser(value_parser!(OsString)) .value_hint(clap::ValueHint::FilePath), ) } diff --git a/src/uu/tail/src/paths.rs b/src/uu/tail/src/paths.rs index cce3270a8..5ed654037 100644 --- a/src/uu/tail/src/paths.rs +++ b/src/uu/tail/src/paths.rs @@ -10,10 +10,7 @@ use std::ffi::OsStr; use std::fs::{File, Metadata}; use std::io::{Seek, SeekFrom}; #[cfg(unix)] -use std::os::unix::{ - fs::{FileTypeExt, MetadataExt}, - prelude::OsStrExt, -}; +use std::os::unix::fs::{FileTypeExt, MetadataExt}; use std::path::{Path, PathBuf}; use uucore::error::UResult; @@ -26,9 +23,7 @@ pub enum InputKind { #[cfg(unix)] impl From<&OsStr> for InputKind { fn from(value: &OsStr) -> Self { - const DASH: [u8; 1] = [b'-']; - - if value.as_bytes() == DASH { + if value == OsStr::new("-") { Self::Stdin } else { Self::File(PathBuf::from(value))