diff --git a/Cargo.toml b/Cargo.toml index 6cd3e60aa..6f522fa4d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -111,6 +111,10 @@ path = "logname/logname.rs" name = "mkdir" path = "mkdir/mkdir.rs" +[[bin]] +name = "mv" +path = "mv/mv.rs" + [[bin]] name = "mkfifo" path = "mkfifo/mkfifo.rs" diff --git a/Makefile b/Makefile index 0497c4495..76aa3fa81 100644 --- a/Makefile +++ b/Makefile @@ -54,6 +54,7 @@ PROGS := \ link \ hashsum \ mkdir \ + mv \ nl \ paste \ printenv \ @@ -131,6 +132,7 @@ TEST_PROGS := \ cat \ cp \ mkdir \ + mv \ nl \ seq \ tr \ diff --git a/src/mv/mv.rs b/src/mv/mv.rs new file mode 100644 index 000000000..bb5afc60d --- /dev/null +++ b/src/mv/mv.rs @@ -0,0 +1,89 @@ +#![crate_name = "mv"] + +/* + * This file is part of the uutils coreutils package. + * + * (c) Sokovikov Evgeniy + * + * For the full copyright and license information, please view the LICENSE file + * that was distributed with this source code. + */ + +#![feature(macro_rules)] + +extern crate getopts; + +use std::io::fs; + +use getopts::{ + getopts, + optflag, + usage, +}; + +static NAME: &'static str = "mv"; +static VERSION: &'static str = "0.0.1"; + +#[path = "../common/util.rs"] +mod util; + +pub fn uumain(args: Vec) -> int { + let opts = [ + optflag("h", "help", "display this help and exit"), + optflag("V", "version", "output version information and exit"), + ]; + let matches = match getopts(args.tail(), opts) { + Ok(m) => m, + Err(f) => crash!(1, "Invalid options\n{}", f) + }; + + let progname = &args[0]; + let usage = usage("Move SOURCE to DEST", opts); + + if matches.opt_present("version") { + println!("{}", VERSION); + return 0; + } + + if matches.opt_present("help") { + help(progname.as_slice(), usage.as_slice()); + return 0; + } + + let source = if matches.free.len() < 1 { + println!("error: Missing SOURCE argument. Try --help."); + return 1; + } else { + Path::new(matches.free[0].as_slice()) + }; + + let dest = if matches.free.len() < 2 { + println!("error: Missing DEST argument. Try --help."); + return 1; + } else { + Path::new(matches.free[1].as_slice()) + }; + + mv(source, dest) +} + +fn mv(source: Path, dest: Path) -> int { + let io_result = fs::rename(&source, &dest); + + if io_result.is_err() { + let err = io_result.unwrap_err(); + println!("error: {:s}", err.to_string()); + 1 + } else { + 0 + } +} + +fn help(progname: &str, usage: &str) { + let msg = format!("Usage: {0} SOURCE DEST\n \ + or: {0} SOURCE... DIRECTORY\n \ + \n\ + {1}", progname, usage); + println!("{}", msg); +} + diff --git a/test/fixtures/mv/hello_world.txt b/test/fixtures/mv/hello_world.txt new file mode 100644 index 000000000..8ab686eaf --- /dev/null +++ b/test/fixtures/mv/hello_world.txt @@ -0,0 +1 @@ +Hello, World! diff --git a/test/mv.rs b/test/mv.rs new file mode 100644 index 000000000..13d380abd --- /dev/null +++ b/test/mv.rs @@ -0,0 +1,24 @@ +use std::io::process::Command; +use std::io::fs::{PathExtensions}; + +static EXE: &'static str = "./mv"; +static TEST_HELLO_WORLD_SOURCE: &'static str = "hello_world.txt"; +static TEST_HELLO_WORLD_DEST: &'static str = "move_of_hello_world.txt"; + +#[test] +fn test_mv() { + let prog = Command::new(EXE) + .arg(TEST_HELLO_WORLD_SOURCE) + .arg(TEST_HELLO_WORLD_DEST) + .status(); + + let exit_success = prog.unwrap().success(); + assert_eq!(exit_success, true); + + let dest = Path::new(TEST_HELLO_WORLD_DEST); + assert!(dest.exists() == true); + + let source = Path::new(TEST_HELLO_WORLD_SOURCE); + assert!(source.exists() == false); +} +