Skip to content

Commit

Permalink
feat: expose mv externals + document for nushell
Browse files Browse the repository at this point in the history
  • Loading branch information
PThorpe92 committed Sep 29, 2023
1 parent 0d8f8fc commit e0d8d81
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 40 deletions.
59 changes: 22 additions & 37 deletions src/uu/mv/src/mv.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,11 @@ use std::os::unix;
#[cfg(windows)]
use std::os::windows;
use std::path::{Path, PathBuf};
use uucore::backup_control::{self, source_is_target_backup, BackupMode};
pub use uucore::backup_control::BackupMode;
use uucore::backup_control::{self, source_is_target_backup};
use uucore::display::Quotable;
use uucore::error::{set_exit_code, FromIo, UError, UResult, USimpleError, UUsageError};
use uucore::fs::{are_hardlinks_or_one_way_symlink_to_same_file, are_hardlinks_to_same_file};
use uucore::libc::ENOTEMPTY;
use uucore::update_control::{self, UpdateMode};
use uucore::{format_usage, help_about, help_section, help_usage, prompt_yes, show};

Expand All @@ -33,12 +33,13 @@ use fs_extra::dir::{
};

use crate::error::MvError;

/// Options contains all the possible behaviors and flags for mv.
///
/// All options are public so that the options can be programmatically
/// constructed by other crates, such as nushell. That means that this struct
/// is part of our public API. It should therefore not be changed without good
/// reason.
/// constructed by other crates, such as nushell. That means that this struct is
/// part of our public API. It should therefore not be changed without good reason.
///
/// The fields are documented with the arguments that determine their value.
#[derive(Debug, Clone, Eq, PartialEq)]

Check warning on line 44 in src/uu/mv/src/mv.rs

View check run for this annotation

Codecov / codecov/patch

src/uu/mv/src/mv.rs#L44

Added line #L44 was not covered by tests
pub struct Options {
Expand Down Expand Up @@ -162,7 +163,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
progress_bar: matches.get_flag(OPT_PROGRESS),
};

exec_mv(&files[..], &opts)
mv(&files[..], &opts)
}

pub fn uu_app() -> Command {
Expand Down Expand Up @@ -254,7 +255,7 @@ pub fn uu_app() -> Command {
)
}

pub fn determine_overwrite_mode(matches: &ArgMatches) -> OverwriteMode {
fn determine_overwrite_mode(matches: &ArgMatches) -> OverwriteMode {
// This does not exactly match the GNU implementation:
// The GNU mv defaults to Force, but if more than one of the
// overwrite options are supplied, only the last takes effect.
Expand Down Expand Up @@ -358,12 +359,10 @@ fn handle_multiple_paths(paths: &[PathBuf], opts: &Options) -> UResult<()> {
move_files_into_dir(sources, target_dir, opts)
}

/// Execute mv command, moving 'source' to 'target', where
/// Execute the mv command. This moves 'source' to 'target', where
/// 'target' is a directory. If 'target' does not exist, and source is a single
/// file or directory, then 'source' will be renamed to 'target'.
///
/// returns MvError | UError
pub fn exec_mv(files: &[OsString], opts: &Options) -> UResult<()> {
pub fn mv(files: &[OsString], opts: &Options) -> UResult<()> {
let paths = parse_paths(files, opts);

if let Some(ref name) = opts.target_dir {
Expand Down Expand Up @@ -440,31 +439,17 @@ fn move_files_into_dir(files: &[PathBuf], target_dir: &Path, opts: &Options) ->
match rename(sourcepath, &targetpath, opts, multi_progress.as_ref()) {
Err(e) if e.to_string().is_empty() => set_exit_code(1),
Err(e) => {
match e.raw_os_error() {
Some(ENOTEMPTY) => {
// The error message was changed to match GNU's decision
// when an issue was filed. These will match when merged upstream.
let e = e
.map_err_context(|| format!("cannot overwrite {}", targetpath.quote()));
match multi_progress {
Some(ref pb) => pb.suspend(|| show!(e)),
None => show!(e),
};
}
_ => {
let e = e.map_err_context(|| {
format!(
"cannot move {} to {}",
sourcepath.quote(),
targetpath.quote()
)
});
match multi_progress {
Some(ref pb) => pb.suspend(|| show!(e)),
None => show!(e),
};
}
}
let e = e.map_err_context(|| {
format!(
"cannot move {} to {}",
sourcepath.quote(),
targetpath.quote()
)
});
match multi_progress {
Some(ref pb) => pb.suspend(|| show!(e)),
None => show!(e),
};
}
Ok(()) => (),
}
Expand Down Expand Up @@ -535,7 +520,7 @@ fn rename(
if is_empty_dir(to) {
fs::remove_dir(to)?;
} else {
return Err(io::Error::from_raw_os_error(ENOTEMPTY));
return Err(io::Error::new(io::ErrorKind::Other, "Directory not empty"));
}
}
}
Expand Down
6 changes: 3 additions & 3 deletions tests/by-util/test_split.rs
Original file line number Diff line number Diff line change
Expand Up @@ -448,7 +448,7 @@ fn test_split_obs_lines_within_combined_shorts() {
.no_stdout();
let glob = Glob::new(&at, ".", r"x\d\d$");
assert_eq!(glob.count(), 2);
assert_eq!(glob.collate(), at.read_bytes(name))
assert_eq!(glob.collate(), at.read_bytes(name));
}

/// Test for obsolete lines option as part of combined short options with tailing suffix length with value
Expand Down Expand Up @@ -480,7 +480,7 @@ fn test_split_obs_lines_starts_combined_shorts() {
.no_stdout();
let glob = Glob::new(&at, ".", r"x\d\d$");
assert_eq!(glob.count(), 2);
assert_eq!(glob.collate(), at.read_bytes(name))
assert_eq!(glob.collate(), at.read_bytes(name));
}

/// Test for using both obsolete lines (standalone) option and short/long lines option simultaneously
Expand Down Expand Up @@ -615,7 +615,7 @@ fn test_split_multiple_obs_lines_within_combined() {
.no_stdout();
let glob = Glob::new(&at, ".", r"x\d\d$");
assert_eq!(glob.count(), 2);
assert_eq!(glob.collate(), at.read_bytes(name))
assert_eq!(glob.collate(), at.read_bytes(name));
}

/// Test for using both obsolete lines option within combined shorts with conflicting -n option simultaneously
Expand Down

0 comments on commit e0d8d81

Please sign in to comment.