Allow copying file to dir (#607)

* Allow copying file to dir

* Add error when trying to copy dir

* Fix root case

* Using --help is not an error

* Add check for empty destination

* Rename test
This commit is contained in:
Vincent Ollivier 2024-04-05 09:42:05 +02:00 committed by GitHub
parent d04d1a0539
commit 348b2b6d63
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 62 additions and 10 deletions

View File

@ -224,7 +224,14 @@ pub fn read_dir(path: &str) -> Result<Vec<FileInfo>, ()> {
}
#[test_case]
fn test_file() {
fn test_filename() {
assert_eq!(filename("/path/to/file.txt"), "file.txt");
assert_eq!(filename("/file.txt"), "file.txt");
assert_eq!(filename("file.txt"), "file.txt");
}
#[test_case]
fn test_fs() {
use crate::sys::fs::{dismount, format_mem, mount_mem};
mount_mem();
format_mem();

View File

@ -2,12 +2,11 @@ use crate::api::console::Style;
use crate::api::fs;
use crate::api::process::ExitCode;
use alloc::format;
use alloc::string::{String, ToString};
pub fn main(args: &[&str]) -> Result<(), ExitCode> {
let n = args.len();
if n != 3 {
help();
return Err(ExitCode::UsageError);
}
for i in 1..n {
match args[i] {
"-h" | "--help" => {
@ -17,12 +16,26 @@ pub fn main(args: &[&str]) -> Result<(), ExitCode> {
_ => continue,
}
}
if n != 3 {
help();
return Err(ExitCode::UsageError);
}
if args[2].is_empty() {
error!("Could not write to ''");
return Err(ExitCode::Failure);
}
let source = args[1];
let dest = args[2];
let dest = destination(args[1], args[2]);
if fs::is_dir(source) {
error!("Could not copy directory '{}'", source);
return Err(ExitCode::Failure);
}
if let Ok(contents) = fs::read_to_bytes(source) {
if fs::write(dest, &contents).is_ok() {
if fs::write(&dest, &contents).is_ok() {
Ok(())
} else {
error!("Could not write to '{}'", dest);
@ -34,6 +47,16 @@ pub fn main(args: &[&str]) -> Result<(), ExitCode> {
}
}
fn destination(source: &str, dest: &str) -> String {
debug_assert!(!dest.is_empty());
let mut dest = dest.trim_end_matches('/').to_string();
if dest.is_empty() || fs::is_dir(&dest) {
let file = fs::filename(source);
dest = format!("{}/{}", dest, file);
}
dest
}
fn help() {
let csi_option = Style::color("LightCyan");
let csi_title = Style::color("Yellow");
@ -43,3 +66,24 @@ fn help() {
csi_title, csi_reset, csi_option, csi_reset
);
}
#[test_case]
fn test_destination() {
use crate::{usr, sys};
sys::fs::mount_mem();
sys::fs::format_mem();
usr::install::copy_files(false);
assert_eq!(destination("foo.txt", "bar.txt"), "bar.txt");
assert_eq!(destination("foo.txt", "/"), "/foo.txt");
assert_eq!(destination("foo.txt", "/tmp"), "/tmp/foo.txt");
assert_eq!(destination("foo.txt", "/tmp/"), "/tmp/foo.txt");
assert_eq!(destination("/usr/vinc/foo.txt", "/"), "/foo.txt");
assert_eq!(destination("/usr/vinc/foo.txt", "/tmp"), "/tmp/foo.txt");
assert_eq!(destination("/usr/vinc/foo.txt", "/tmp/"), "/tmp/foo.txt");
sys::fs::dismount();
}

View File

@ -19,9 +19,10 @@ pub fn main(args: &[&str]) -> Result<(), ExitCode> {
}
// TODO: Avoid doing copy+delete
match usr::copy::main(args) {
Ok(()) => usr::delete::main(&args[0..2]),
_ => Err(ExitCode::Failure),
if usr::copy::main(args).is_ok() {
usr::delete::main(&args[0..2])
} else {
Err(ExitCode::Failure)
}
}