mirror of
https://github.com/RGBCube/uutils-coreutils
synced 2025-07-28 11:37:44 +00:00
Merge pull request #4756 from Joining7943/tail-refactor-and-fix-input
`tail`: Refactor `paths::Input::from` and `Settings::inputs`
This commit is contained in:
commit
7a7842b5b8
4 changed files with 41 additions and 38 deletions
|
@ -7,12 +7,11 @@
|
||||||
|
|
||||||
use crate::paths::Input;
|
use crate::paths::Input;
|
||||||
use crate::{parse, platform, Quotable};
|
use crate::{parse, platform, Quotable};
|
||||||
use clap::crate_version;
|
use clap::{crate_version, value_parser};
|
||||||
use clap::{Arg, ArgAction, ArgMatches, Command};
|
use clap::{Arg, ArgAction, ArgMatches, Command};
|
||||||
use fundu::{DurationParser, SaturatingInto};
|
use fundu::{DurationParser, SaturatingInto};
|
||||||
use is_terminal::IsTerminal;
|
use is_terminal::IsTerminal;
|
||||||
use same_file::Handle;
|
use same_file::Handle;
|
||||||
use std::collections::VecDeque;
|
|
||||||
use std::ffi::OsString;
|
use std::ffi::OsString;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
use uucore::error::{UResult, USimpleError, UUsageError};
|
use uucore::error::{UResult, USimpleError, UUsageError};
|
||||||
|
@ -141,7 +140,8 @@ pub struct Settings {
|
||||||
pub use_polling: bool,
|
pub use_polling: bool,
|
||||||
pub verbose: bool,
|
pub verbose: bool,
|
||||||
pub presume_input_pipe: bool,
|
pub presume_input_pipe: bool,
|
||||||
pub inputs: VecDeque<Input>,
|
/// `FILE(s)` positional arguments
|
||||||
|
pub inputs: Vec<Input>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Settings {
|
impl Default for Settings {
|
||||||
|
@ -173,11 +173,11 @@ impl Settings {
|
||||||
}
|
}
|
||||||
settings.mode = FilterMode::from_obsolete_args(args);
|
settings.mode = FilterMode::from_obsolete_args(args);
|
||||||
let input = if let Some(name) = name {
|
let input = if let Some(name) = name {
|
||||||
Input::from(&name)
|
Input::from(name)
|
||||||
} else {
|
} else {
|
||||||
Input::default()
|
Input::default()
|
||||||
};
|
};
|
||||||
settings.inputs.push_back(input);
|
settings.inputs.push(input);
|
||||||
settings
|
settings
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -285,19 +285,13 @@ impl Settings {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut inputs: VecDeque<Input> = matches
|
settings.inputs = matches
|
||||||
.get_many::<String>(options::ARG_FILES)
|
.get_many::<OsString>(options::ARG_FILES)
|
||||||
.map(|v| v.map(|string| Input::from(&string)).collect())
|
.map(|v| v.map(Input::from).collect())
|
||||||
.unwrap_or_default();
|
.unwrap_or_else(|| vec![Input::default()]);
|
||||||
|
|
||||||
// apply default and add '-' to inputs if none is present
|
settings.verbose =
|
||||||
if inputs.is_empty() {
|
settings.inputs.len() > 1 && !matches.get_flag(options::verbosity::QUIET);
|
||||||
inputs.push_front(Input::default());
|
|
||||||
}
|
|
||||||
|
|
||||||
settings.verbose = inputs.len() > 1 && !matches.get_flag(options::verbosity::QUIET);
|
|
||||||
|
|
||||||
settings.inputs = inputs;
|
|
||||||
|
|
||||||
Ok(settings)
|
Ok(settings)
|
||||||
}
|
}
|
||||||
|
@ -593,6 +587,7 @@ pub fn uu_app() -> Command {
|
||||||
Arg::new(options::ARG_FILES)
|
Arg::new(options::ARG_FILES)
|
||||||
.action(ArgAction::Append)
|
.action(ArgAction::Append)
|
||||||
.num_args(1..)
|
.num_args(1..)
|
||||||
|
.value_parser(value_parser!(OsString))
|
||||||
.value_hint(clap::ValueHint::FilePath),
|
.value_hint(clap::ValueHint::FilePath),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,6 @@ use crate::follow::files::{FileHandling, PathData};
|
||||||
use crate::paths::{Input, InputKind, MetadataExtTail, PathExtTail};
|
use crate::paths::{Input, InputKind, MetadataExtTail, PathExtTail};
|
||||||
use crate::{platform, text};
|
use crate::{platform, text};
|
||||||
use notify::{RecommendedWatcher, RecursiveMode, Watcher, WatcherKind};
|
use notify::{RecommendedWatcher, RecursiveMode, Watcher, WatcherKind};
|
||||||
use std::collections::VecDeque;
|
|
||||||
use std::io::BufRead;
|
use std::io::BufRead;
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
use std::sync::mpsc::{self, channel, Receiver};
|
use std::sync::mpsc::{self, channel, Receiver};
|
||||||
|
@ -270,7 +269,7 @@ impl Observer {
|
||||||
self.follow_name() && self.retry
|
self.follow_name() && self.retry
|
||||||
}
|
}
|
||||||
|
|
||||||
fn init_files(&mut self, inputs: &VecDeque<Input>) -> UResult<()> {
|
fn init_files(&mut self, inputs: &Vec<Input>) -> UResult<()> {
|
||||||
if let Some(watcher_rx) = &mut self.watcher_rx {
|
if let Some(watcher_rx) = &mut self.watcher_rx {
|
||||||
for input in inputs {
|
for input in inputs {
|
||||||
match input.kind() {
|
match input.kind() {
|
||||||
|
|
|
@ -20,6 +20,28 @@ pub enum InputKind {
|
||||||
Stdin,
|
Stdin,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(unix)]
|
||||||
|
impl From<&OsStr> for InputKind {
|
||||||
|
fn from(value: &OsStr) -> Self {
|
||||||
|
if value == OsStr::new("-") {
|
||||||
|
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)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct Input {
|
pub struct Input {
|
||||||
kind: InputKind,
|
kind: InputKind,
|
||||||
|
@ -27,22 +49,13 @@ pub struct Input {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Input {
|
impl Input {
|
||||||
pub fn from<T: AsRef<OsStr>>(string: &T) -> Self {
|
pub fn from<T: AsRef<OsStr>>(string: T) -> Self {
|
||||||
let kind = if string.as_ref() == Path::new(text::DASH) {
|
let string = string.as_ref();
|
||||||
InputKind::Stdin
|
|
||||||
} else {
|
|
||||||
InputKind::File(PathBuf::from(string.as_ref()))
|
|
||||||
};
|
|
||||||
|
|
||||||
|
let kind = string.into();
|
||||||
let display_name = match kind {
|
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 => {
|
InputKind::Stdin => text::STDIN_HEADER.to_string(),
|
||||||
if cfg!(unix) {
|
|
||||||
text::STDIN_HEADER.to_string()
|
|
||||||
} else {
|
|
||||||
string.as_ref().to_string_lossy().to_string()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
Self { kind, display_name }
|
Self { kind, display_name }
|
||||||
|
|
|
@ -145,12 +145,8 @@ fn test_stdin_redirect_offset() {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[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() {
|
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
|
// like test_stdin_redirect_offset but with multiple files
|
||||||
|
|
||||||
let ts = TestScenario::new(util_name!());
|
let ts = TestScenario::new(util_name!());
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue