From 3aeb6179b7816605b2da8e263a804d97189a55e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Pei=C3=9Fl?= <7underlines@gmail.com> Date: Sun, 22 Jan 2023 18:02:04 +0100 Subject: [PATCH] os: rework mv so it works with different partitions (add fallback to os.mv_by_cp + tests) (#17065) --- vlib/os/os.c.v | 6 ++--- vlib/os/os.v | 5 ++++ vlib/os/os_js.js.v | 14 +++++++++++ vlib/os/os_test.v | 60 ++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 82 insertions(+), 3 deletions(-) diff --git a/vlib/os/os.c.v b/vlib/os/os.c.v index 6d94ca54dc..38b823c536 100644 --- a/vlib/os/os.c.v +++ b/vlib/os/os.c.v @@ -211,9 +211,9 @@ pub fn file_size(path string) u64 { return 0 } -// mv moves files or folders from `src` to `dst`. -// if you are not sure that the source and target are on the same mount/partition use mv_by_cp -pub fn mv(src string, dst string) ! { +// rename renames the file or folder from `src` to `dst`. +// Use mv to move or rename a file in a platform independent manner. +pub fn rename(src string, dst string) ! { mut rdst := dst if is_dir(rdst) { rdst = join_path_single(rdst.trim_right(path_separator), file_name(src.trim_right(path_separator))) diff --git a/vlib/os/os.v b/vlib/os/os.v index 7e8e8466d9..e643857e97 100644 --- a/vlib/os/os.v +++ b/vlib/os/os.v @@ -126,6 +126,11 @@ pub fn mv_by_cp(source string, target string) ! { rm(source)! } +// mv moves files or folders from `src` to `dst`. +pub fn mv(source string, target string) ! { + rename(source, target) or { mv_by_cp(source, target)! } +} + // read_lines reads the file in `path` into an array of lines. [manualfree] pub fn read_lines(path string) ![]string { diff --git a/vlib/os/os_js.js.v b/vlib/os/os_js.js.v index f4f91df0de..d6fbb79cc3 100644 --- a/vlib/os/os_js.js.v +++ b/vlib/os/os_js.js.v @@ -123,6 +123,20 @@ pub fn cp(src string, dst string) ! { } } +pub fn rename(src string, dst string) ! { + $if js_node { + err := '' + #try { + #$fs.renameSync(src.str,dst.str); + #return; + #} catch (e) { + #err.str = 'failed to rename ' + src.str + ' to ' + dst.str + ': ' + e.toString(); + #} + + return error(err) + } +} + pub fn read_file(s string) !string { mut err := '' err = err diff --git a/vlib/os/os_test.v b/vlib/os/os_test.v index 8b60727297..f5fb690668 100644 --- a/vlib/os/os_test.v +++ b/vlib/os/os_test.v @@ -930,3 +930,63 @@ fn test_reading_from_empty_file() { assert content_bytes.len == 0 os.rm(empty_file)! } + +fn move_across_partitions_using_function(f fn (src string, dst string) !) ! { + bindfs := os.find_abs_path_of_executable('bindfs') or { + eprintln('skipping test_mv_by_cp, because bindfs was not present') + return + } + // eprintln('>> $bindfs') + pfolder := os.join_path(tfolder, 'parent') + cfolder := os.join_path(pfolder, 'child') + mfolder := os.join_path(pfolder, 'mountpoint') + cdeepfolder := os.join_path(cfolder, 'deep', 'folder') + os.mkdir_all(mfolder)! + os.mkdir_all(cfolder)! + os.mkdir_all(cdeepfolder)! + // + original_path := os.join_path(pfolder, 'original.txt') + target_path := os.join_path(cdeepfolder, 'target.txt') + os.write_file(original_path, 'text')! + os.write_file(os.join_path(cdeepfolder, 'x.txt'), 'some text')! + // os.system('tree $pfolder') + /* + /tmp/v_1000/v/tests/os_test/parent + ├── child + │   └── deep + │   └── folder + │   └── x.txt + ├── mountpoint + └── original.txt + */ + os.system('${bindfs} --no-allow-other ${cfolder} ${mfolder}') + defer { + os.system('sync; umount ${mfolder}') + } + // os.system('tree $pfolder') + /* + /tmp/v_1000/v/tests/os_test/parent + ├── child + │   └── deep + │   └── folder + │   └── x.txt + ├── mountpoint + │ └── deep + │ └── folder + │ └── x.txt + └── original.txt + */ + + f(original_path, target_path)! + + assert os.exists(target_path) + assert !os.exists(original_path) +} + +fn test_mv_by_cp_across_partitions() { + move_across_partitions_using_function(os.mv_by_cp)! +} + +fn test_mv_across_partitions() { + move_across_partitions_using_function(os.mv)! +}