mirror of
https://github.com/RGBCube/uutils-coreutils
synced 2025-09-15 19:36:16 +00:00
mv: implement update=[switch]
This commit is contained in:
parent
ecde4b6aa3
commit
0e8dd894a3
1 changed files with 15 additions and 16 deletions
|
@ -25,6 +25,7 @@ use std::path::{Path, PathBuf};
|
||||||
use uucore::backup_control::{self, BackupMode};
|
use uucore::backup_control::{self, BackupMode};
|
||||||
use uucore::display::Quotable;
|
use uucore::display::Quotable;
|
||||||
use uucore::error::{set_exit_code, FromIo, UError, UResult, USimpleError, UUsageError};
|
use uucore::error::{set_exit_code, FromIo, UError, UResult, USimpleError, UUsageError};
|
||||||
|
use uucore::update_control::{self, UpdateMode};
|
||||||
use uucore::{format_usage, help_about, help_usage, prompt_yes, show};
|
use uucore::{format_usage, help_about, help_usage, prompt_yes, show};
|
||||||
|
|
||||||
use fs_extra::dir::{
|
use fs_extra::dir::{
|
||||||
|
@ -38,7 +39,7 @@ pub struct Behavior {
|
||||||
overwrite: OverwriteMode,
|
overwrite: OverwriteMode,
|
||||||
backup: BackupMode,
|
backup: BackupMode,
|
||||||
suffix: String,
|
suffix: String,
|
||||||
update: bool,
|
update: UpdateMode,
|
||||||
target_dir: Option<OsString>,
|
target_dir: Option<OsString>,
|
||||||
no_target_dir: bool,
|
no_target_dir: bool,
|
||||||
verbose: bool,
|
verbose: bool,
|
||||||
|
@ -62,14 +63,15 @@ static OPT_NO_CLOBBER: &str = "no-clobber";
|
||||||
static OPT_STRIP_TRAILING_SLASHES: &str = "strip-trailing-slashes";
|
static OPT_STRIP_TRAILING_SLASHES: &str = "strip-trailing-slashes";
|
||||||
static OPT_TARGET_DIRECTORY: &str = "target-directory";
|
static OPT_TARGET_DIRECTORY: &str = "target-directory";
|
||||||
static OPT_NO_TARGET_DIRECTORY: &str = "no-target-directory";
|
static OPT_NO_TARGET_DIRECTORY: &str = "no-target-directory";
|
||||||
static OPT_UPDATE: &str = "update";
|
|
||||||
static OPT_VERBOSE: &str = "verbose";
|
static OPT_VERBOSE: &str = "verbose";
|
||||||
static OPT_PROGRESS: &str = "progress";
|
static OPT_PROGRESS: &str = "progress";
|
||||||
static ARG_FILES: &str = "files";
|
static ARG_FILES: &str = "files";
|
||||||
|
|
||||||
#[uucore::main]
|
#[uucore::main]
|
||||||
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
||||||
let mut app = uu_app().after_help(backup_control::BACKUP_CONTROL_LONG_HELP);
|
let mut app = uu_app()
|
||||||
|
.after_help(backup_control::BACKUP_CONTROL_LONG_HELP)
|
||||||
|
.after_help(update_control::UPDATE_CONTROL_LONG_HELP);
|
||||||
let matches = app.try_get_matches_from_mut(args)?;
|
let matches = app.try_get_matches_from_mut(args)?;
|
||||||
|
|
||||||
if !matches.contains_id(OPT_TARGET_DIRECTORY)
|
if !matches.contains_id(OPT_TARGET_DIRECTORY)
|
||||||
|
@ -96,6 +98,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
||||||
|
|
||||||
let overwrite_mode = determine_overwrite_mode(&matches);
|
let overwrite_mode = determine_overwrite_mode(&matches);
|
||||||
let backup_mode = backup_control::determine_backup_mode(&matches)?;
|
let backup_mode = backup_control::determine_backup_mode(&matches)?;
|
||||||
|
let update_mode = update_control::determine_update_mode(&matches);
|
||||||
|
|
||||||
if overwrite_mode == OverwriteMode::NoClobber && backup_mode != BackupMode::NoBackup {
|
if overwrite_mode == OverwriteMode::NoClobber && backup_mode != BackupMode::NoBackup {
|
||||||
return Err(UUsageError::new(
|
return Err(UUsageError::new(
|
||||||
|
@ -110,7 +113,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
||||||
overwrite: overwrite_mode,
|
overwrite: overwrite_mode,
|
||||||
backup: backup_mode,
|
backup: backup_mode,
|
||||||
suffix: backup_suffix,
|
suffix: backup_suffix,
|
||||||
update: matches.get_flag(OPT_UPDATE),
|
update: update_mode,
|
||||||
target_dir: matches
|
target_dir: matches
|
||||||
.get_one::<OsString>(OPT_TARGET_DIRECTORY)
|
.get_one::<OsString>(OPT_TARGET_DIRECTORY)
|
||||||
.map(OsString::from),
|
.map(OsString::from),
|
||||||
|
@ -131,6 +134,8 @@ pub fn uu_app() -> Command {
|
||||||
.infer_long_args(true)
|
.infer_long_args(true)
|
||||||
.arg(backup_control::arguments::backup())
|
.arg(backup_control::arguments::backup())
|
||||||
.arg(backup_control::arguments::backup_no_args())
|
.arg(backup_control::arguments::backup_no_args())
|
||||||
|
.arg(update_control::arguments::update())
|
||||||
|
.arg(update_control::arguments::update_no_args())
|
||||||
.arg(
|
.arg(
|
||||||
Arg::new(OPT_FORCE)
|
Arg::new(OPT_FORCE)
|
||||||
.short('f')
|
.short('f')
|
||||||
|
@ -176,16 +181,6 @@ pub fn uu_app() -> Command {
|
||||||
.help("treat DEST as a normal file")
|
.help("treat DEST as a normal file")
|
||||||
.action(ArgAction::SetTrue),
|
.action(ArgAction::SetTrue),
|
||||||
)
|
)
|
||||||
.arg(
|
|
||||||
Arg::new(OPT_UPDATE)
|
|
||||||
.short('u')
|
|
||||||
.long(OPT_UPDATE)
|
|
||||||
.help(
|
|
||||||
"move only when the SOURCE file is newer than the destination file \
|
|
||||||
or when the destination file is missing",
|
|
||||||
)
|
|
||||||
.action(ArgAction::SetTrue),
|
|
||||||
)
|
|
||||||
.arg(
|
.arg(
|
||||||
Arg::new(OPT_VERBOSE)
|
Arg::new(OPT_VERBOSE)
|
||||||
.short('v')
|
.short('v')
|
||||||
|
@ -412,7 +407,9 @@ fn rename(
|
||||||
let mut backup_path = None;
|
let mut backup_path = None;
|
||||||
|
|
||||||
if to.exists() {
|
if to.exists() {
|
||||||
if b.update && b.overwrite == OverwriteMode::Interactive {
|
if (b.update == UpdateMode::ReplaceIfOlder || b.update == UpdateMode::ReplaceNone)
|
||||||
|
&& b.overwrite == OverwriteMode::Interactive
|
||||||
|
{
|
||||||
// `mv -i --update old new` when `new` exists doesn't move anything
|
// `mv -i --update old new` when `new` exists doesn't move anything
|
||||||
// and exit with 0
|
// and exit with 0
|
||||||
return Ok(());
|
return Ok(());
|
||||||
|
@ -433,7 +430,9 @@ fn rename(
|
||||||
rename_with_fallback(to, backup_path, multi_progress)?;
|
rename_with_fallback(to, backup_path, multi_progress)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
if b.update && fs::metadata(from)?.modified()? <= fs::metadata(to)?.modified()? {
|
if (b.update == UpdateMode::ReplaceIfOlder)
|
||||||
|
&& fs::metadata(from)?.modified()? <= fs::metadata(to)?.modified()?
|
||||||
|
{
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue