mirror of
https://github.com/RGBCube/uutils-coreutils
synced 2025-07-28 11:37:44 +00:00
touch: address cognitive_complexity lint
Signed-off-by: Paul Houssel <paul.houssel@telecom-sudparis.eu>
This commit is contained in:
parent
da43183fc7
commit
eb3dd521ee
1 changed files with 90 additions and 75 deletions
|
@ -11,7 +11,7 @@ use chrono::{
|
|||
TimeZone, Timelike,
|
||||
};
|
||||
use clap::builder::ValueParser;
|
||||
use clap::{crate_version, Arg, ArgAction, ArgGroup, Command};
|
||||
use clap::{crate_version, Arg, ArgAction, ArgGroup, ArgMatches, Command};
|
||||
use filetime::{set_file_times, set_symlink_file_times, FileTime};
|
||||
use std::ffi::OsString;
|
||||
use std::fs::{self, File};
|
||||
|
@ -73,7 +73,6 @@ fn filetime_to_datetime(ft: &FileTime) -> Option<DateTime<Local>> {
|
|||
}
|
||||
|
||||
#[uucore::main]
|
||||
#[allow(clippy::cognitive_complexity)]
|
||||
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
||||
let matches = uu_app().try_get_matches_from(args)?;
|
||||
|
||||
|
@ -86,37 +85,8 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
|||
),
|
||||
)
|
||||
})?;
|
||||
let (mut atime, mut mtime) = match (
|
||||
matches.get_one::<OsString>(options::sources::REFERENCE),
|
||||
matches.get_one::<String>(options::sources::DATE),
|
||||
) {
|
||||
(Some(reference), Some(date)) => {
|
||||
let (atime, mtime) = stat(Path::new(reference), !matches.get_flag(options::NO_DEREF))?;
|
||||
let atime = filetime_to_datetime(&atime).ok_or_else(|| {
|
||||
USimpleError::new(1, "Could not process the reference access time")
|
||||
})?;
|
||||
let mtime = filetime_to_datetime(&mtime).ok_or_else(|| {
|
||||
USimpleError::new(1, "Could not process the reference modification time")
|
||||
})?;
|
||||
(parse_date(atime, date)?, parse_date(mtime, date)?)
|
||||
}
|
||||
(Some(reference), None) => {
|
||||
stat(Path::new(reference), !matches.get_flag(options::NO_DEREF))?
|
||||
}
|
||||
(None, Some(date)) => {
|
||||
let timestamp = parse_date(Local::now(), date)?;
|
||||
(timestamp, timestamp)
|
||||
}
|
||||
(None, None) => {
|
||||
let timestamp = if let Some(ts) = matches.get_one::<String>(options::sources::TIMESTAMP)
|
||||
{
|
||||
parse_timestamp(ts)?
|
||||
} else {
|
||||
datetime_to_filetime(&Local::now())
|
||||
};
|
||||
(timestamp, timestamp)
|
||||
}
|
||||
};
|
||||
|
||||
let (atime, mtime) = determine_times(&matches)?;
|
||||
|
||||
for filename in files {
|
||||
// FIXME: find a way to avoid having to clone the path
|
||||
|
@ -165,48 +135,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
|||
}
|
||||
}
|
||||
|
||||
// If changing "only" atime or mtime, grab the existing value of the other.
|
||||
// Note that "-a" and "-m" may be passed together; this is not an xor.
|
||||
if matches.get_flag(options::ACCESS)
|
||||
|| matches.get_flag(options::MODIFICATION)
|
||||
|| matches.contains_id(options::TIME)
|
||||
{
|
||||
let st = stat(path, !matches.get_flag(options::NO_DEREF))?;
|
||||
let time = matches
|
||||
.get_one::<String>(options::TIME)
|
||||
.map(|s| s.as_str())
|
||||
.unwrap_or("");
|
||||
|
||||
if !(matches.get_flag(options::ACCESS)
|
||||
|| time.contains(&"access".to_owned())
|
||||
|| time.contains(&"atime".to_owned())
|
||||
|| time.contains(&"use".to_owned()))
|
||||
{
|
||||
atime = st.0;
|
||||
}
|
||||
|
||||
if !(matches.get_flag(options::MODIFICATION)
|
||||
|| time.contains(&"modify".to_owned())
|
||||
|| time.contains(&"mtime".to_owned()))
|
||||
{
|
||||
mtime = st.1;
|
||||
}
|
||||
}
|
||||
|
||||
// sets the file access and modification times for a file or a symbolic link.
|
||||
// The filename, access time (atime), and modification time (mtime) are provided as inputs.
|
||||
|
||||
// If the filename is not "-", indicating a special case for touch -h -,
|
||||
// the code checks if the NO_DEREF flag is set, which means the user wants to
|
||||
// set the times for a symbolic link itself, rather than the file it points to.
|
||||
if filename == "-" {
|
||||
filetime::set_file_times(path, atime, mtime)
|
||||
} else if matches.get_flag(options::NO_DEREF) {
|
||||
set_symlink_file_times(path, atime, mtime)
|
||||
} else {
|
||||
set_file_times(path, atime, mtime)
|
||||
}
|
||||
.map_err_context(|| format!("setting times of {}", path.quote()))?;
|
||||
update_times(&matches, path, atime, mtime, filename)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
@ -307,6 +236,92 @@ pub fn uu_app() -> Command {
|
|||
)
|
||||
}
|
||||
|
||||
// Determine the access and modification time
|
||||
fn determine_times(matches: &ArgMatches) -> UResult<(FileTime, FileTime)> {
|
||||
match (
|
||||
matches.get_one::<OsString>(options::sources::REFERENCE),
|
||||
matches.get_one::<String>(options::sources::DATE),
|
||||
) {
|
||||
(Some(reference), Some(date)) => {
|
||||
let (atime, mtime) = stat(Path::new(&reference), !matches.get_flag(options::NO_DEREF))?;
|
||||
let atime = filetime_to_datetime(&atime).ok_or_else(|| {
|
||||
USimpleError::new(1, "Could not process the reference access time")
|
||||
})?;
|
||||
let mtime = filetime_to_datetime(&mtime).ok_or_else(|| {
|
||||
USimpleError::new(1, "Could not process the reference modification time")
|
||||
})?;
|
||||
Ok((parse_date(atime, date)?, parse_date(mtime, date)?))
|
||||
}
|
||||
(Some(reference), None) => {
|
||||
stat(Path::new(&reference), !matches.get_flag(options::NO_DEREF))
|
||||
}
|
||||
(None, Some(date)) => {
|
||||
let timestamp = parse_date(Local::now(), date)?;
|
||||
Ok((timestamp, timestamp))
|
||||
}
|
||||
(None, None) => {
|
||||
let timestamp = if let Some(ts) = matches.get_one::<String>(options::sources::TIMESTAMP)
|
||||
{
|
||||
parse_timestamp(ts)?
|
||||
} else {
|
||||
datetime_to_filetime(&Local::now())
|
||||
};
|
||||
Ok((timestamp, timestamp))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Updating file access and modification times based on user-specified options
|
||||
fn update_times(
|
||||
matches: &ArgMatches,
|
||||
path: &Path,
|
||||
mut atime: FileTime,
|
||||
mut mtime: FileTime,
|
||||
filename: &OsString,
|
||||
) -> UResult<()> {
|
||||
// If changing "only" atime or mtime, grab the existing value of the other.
|
||||
// Note that "-a" and "-m" may be passed together; this is not an xor.
|
||||
if matches.get_flag(options::ACCESS)
|
||||
|| matches.get_flag(options::MODIFICATION)
|
||||
|| matches.contains_id(options::TIME)
|
||||
{
|
||||
let st = stat(path, !matches.get_flag(options::NO_DEREF))?;
|
||||
let time = matches
|
||||
.get_one::<String>(options::TIME)
|
||||
.map(|s| s.as_str())
|
||||
.unwrap_or("");
|
||||
|
||||
if !(matches.get_flag(options::ACCESS)
|
||||
|| time.contains(&"access".to_owned())
|
||||
|| time.contains(&"atime".to_owned())
|
||||
|| time.contains(&"use".to_owned()))
|
||||
{
|
||||
atime = st.0;
|
||||
}
|
||||
|
||||
if !(matches.get_flag(options::MODIFICATION)
|
||||
|| time.contains(&"modify".to_owned())
|
||||
|| time.contains(&"mtime".to_owned()))
|
||||
{
|
||||
mtime = st.1;
|
||||
}
|
||||
}
|
||||
|
||||
// sets the file access and modification times for a file or a symbolic link.
|
||||
// The filename, access time (atime), and modification time (mtime) are provided as inputs.
|
||||
|
||||
// If the filename is not "-", indicating a special case for touch -h -,
|
||||
// the code checks if the NO_DEREF flag is set, which means the user wants to
|
||||
// set the times for a symbolic link itself, rather than the file it points to.
|
||||
if filename == "-" {
|
||||
filetime::set_file_times(path, atime, mtime)
|
||||
} else if matches.get_flag(options::NO_DEREF) {
|
||||
set_symlink_file_times(path, atime, mtime)
|
||||
} else {
|
||||
set_file_times(path, atime, mtime)
|
||||
}
|
||||
.map_err_context(|| format!("setting times of {}", path.quote()))
|
||||
}
|
||||
// Get metadata of the provided path
|
||||
// If `follow` is `true`, the function will try to follow symlinks
|
||||
// If `follow` is `false` or the symlink is broken, the function will return metadata of the symlink itself
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue