os: make os.ls('') return an error, make os.walk_ext more memory efficient on deep hierarchies, add tests for os.walk_ext
parent
d9c6c9a7df
commit
d1c4b470bc
18
vlib/os/os.v
18
vlib/os/os.v
|
@ -449,11 +449,16 @@ pub fn join_path(base string, dirs ...string) string {
|
|||
|
||||
// walk_ext returns a recursive list of all files in `path` ending with `ext`.
|
||||
pub fn walk_ext(path string, ext string) []string {
|
||||
if !is_dir(path) {
|
||||
return []
|
||||
}
|
||||
mut files := ls(path) or { return [] }
|
||||
mut res := []string{}
|
||||
impl_walk_ext(path, ext, mut res)
|
||||
return res
|
||||
}
|
||||
|
||||
pub fn impl_walk_ext(path string, ext string, mut out []string) {
|
||||
if !is_dir(path) {
|
||||
return
|
||||
}
|
||||
mut files := ls(path) or { return }
|
||||
separator := if path.ends_with(path_separator) { '' } else { path_separator }
|
||||
for file in files {
|
||||
if file.starts_with('.') {
|
||||
|
@ -461,12 +466,11 @@ pub fn walk_ext(path string, ext string) []string {
|
|||
}
|
||||
p := path + separator + file
|
||||
if is_dir(p) && !is_link(p) {
|
||||
res << walk_ext(p, ext)
|
||||
impl_walk_ext(p, ext, mut out)
|
||||
} else if file.ends_with(ext) {
|
||||
res << p
|
||||
out << p
|
||||
}
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
// walk recursively traverses the given directory `path`.
|
||||
|
|
|
@ -254,6 +254,9 @@ fn init_os_args(argc int, argv &&byte) []string {
|
|||
}
|
||||
|
||||
pub fn ls(path string) ?[]string {
|
||||
if path.len == 0 {
|
||||
return error('ls() expects a folder, not an empty string')
|
||||
}
|
||||
mut res := []string{}
|
||||
dir := unsafe { C.opendir(&char(path.str)) }
|
||||
if isnil(dir) {
|
||||
|
|
|
@ -84,12 +84,22 @@ fn test_open_file_binary() {
|
|||
// assert line1 == 'line 1\n'
|
||||
// assert line2 == 'line 2'
|
||||
// }
|
||||
fn test_create_file() {
|
||||
|
||||
fn create_file(fpath string) ? {
|
||||
mut f := os.create(fpath) ?
|
||||
f.close()
|
||||
}
|
||||
|
||||
fn create_and_write_to_file(fpath string, content string) ? {
|
||||
mut f := os.create(fpath) ?
|
||||
f.write_string(content) ?
|
||||
f.close()
|
||||
}
|
||||
|
||||
fn test_create_file() ? {
|
||||
filename := './test1.txt'
|
||||
hello := 'hello world!'
|
||||
mut f := os.create(filename) or { panic(err) }
|
||||
f.write_string(hello) or { panic(err) }
|
||||
f.close()
|
||||
create_and_write_to_file(filename, hello) ?
|
||||
assert hello.len == os.file_size(filename)
|
||||
os.rm(filename) or { panic(err) }
|
||||
}
|
||||
|
@ -175,6 +185,61 @@ fn test_write_and_read_bytes() {
|
|||
os.rm(file_name) or { panic(err) }
|
||||
}
|
||||
|
||||
fn test_ls() {
|
||||
if x := os.ls('') {
|
||||
assert false
|
||||
} else {
|
||||
assert true
|
||||
}
|
||||
if x := os.ls('.') {
|
||||
assert x.len > 0
|
||||
dump(x)
|
||||
} else {
|
||||
assert false
|
||||
}
|
||||
}
|
||||
|
||||
fn test_walk_ext() ? {
|
||||
os.mkdir_all('myfolder/f1/f2/f3') ?
|
||||
os.mkdir_all('myfolder/a1/a2/a3') ?
|
||||
create_file('myfolder/f1/f2/f3/a.txt') ?
|
||||
create_file('myfolder/f1/f2/f3/b.txt') ?
|
||||
create_file('myfolder/f1/f2/f3/c.txt') ?
|
||||
create_file('myfolder/f1/f2/f3/d.md') ?
|
||||
create_file('myfolder/f1/0.txt') ?
|
||||
create_file('myfolder/another.md') ?
|
||||
create_file('myfolder/a1/a2/a3/x.txt') ?
|
||||
create_file('myfolder/a1/a2/a3/y.txt') ?
|
||||
create_file('myfolder/a1/a2/a3/z.txt') ?
|
||||
create_file('myfolder/a1/1.txt') ?
|
||||
create_file('myfolder/xyz.ini') ?
|
||||
all := os.walk_ext('.', '')
|
||||
assert all.len > 10
|
||||
mut top := os.walk_ext('myfolder', '.txt')
|
||||
top.sort()
|
||||
assert top == [
|
||||
'myfolder/a1/1.txt',
|
||||
'myfolder/a1/a2/a3/x.txt',
|
||||
'myfolder/a1/a2/a3/y.txt',
|
||||
'myfolder/a1/a2/a3/z.txt',
|
||||
'myfolder/f1/0.txt',
|
||||
'myfolder/f1/f2/f3/a.txt',
|
||||
'myfolder/f1/f2/f3/b.txt',
|
||||
'myfolder/f1/f2/f3/c.txt',
|
||||
]
|
||||
mut subfolder_txts := os.walk_ext('myfolder/a1/a2', '.txt')
|
||||
subfolder_txts.sort()
|
||||
assert subfolder_txts == [
|
||||
'myfolder/a1/a2/a3/x.txt',
|
||||
'myfolder/a1/a2/a3/y.txt',
|
||||
'myfolder/a1/a2/a3/z.txt',
|
||||
]
|
||||
mut mds := os.walk_ext('myfolder', '.md')
|
||||
mds.sort()
|
||||
assert mds == ['myfolder/another.md', 'myfolder/f1/f2/f3/d.md']
|
||||
os.rmdir_all('myfolder') ?
|
||||
}
|
||||
|
||||
fn test_create_and_delete_folder() {
|
||||
folder := './test1'
|
||||
os.mkdir(folder) or { panic(err) }
|
||||
|
@ -346,8 +411,7 @@ fn test_realpath_does_not_absolutize_non_existing_relative_paths() {
|
|||
fn test_realpath_absolutepath_symlink() ? {
|
||||
file_name := 'tolink_file.txt'
|
||||
symlink_name := 'symlink.txt'
|
||||
mut f := os.create(file_name) ?
|
||||
f.close()
|
||||
create_file(file_name) ?
|
||||
assert os.symlink(file_name, symlink_name) ?
|
||||
rpath := os.real_path(symlink_name)
|
||||
println(rpath)
|
||||
|
@ -406,13 +470,12 @@ fn test_make_symlink_check_is_link_and_remove_symlink() {
|
|||
assert symlink_exists == false
|
||||
}
|
||||
|
||||
fn test_make_symlink_check_is_link_and_remove_symlink_with_file() {
|
||||
fn test_make_symlink_check_is_link_and_remove_symlink_with_file() ? {
|
||||
file := 'tfile'
|
||||
symlink := 'tsymlink'
|
||||
os.rm(symlink) or {}
|
||||
os.rm(file) or {}
|
||||
mut f := os.create(file) or { panic(err) }
|
||||
f.close()
|
||||
create_file(file) ?
|
||||
os.symlink(file, symlink) or { panic(err) }
|
||||
assert os.is_link(symlink)
|
||||
os.rm(symlink) or { panic(err) }
|
||||
|
@ -421,13 +484,12 @@ fn test_make_symlink_check_is_link_and_remove_symlink_with_file() {
|
|||
assert symlink_exists == false
|
||||
}
|
||||
|
||||
fn test_make_hardlink_check_is_link_and_remove_hardlink_with_file() {
|
||||
fn test_make_hardlink_check_is_link_and_remove_hardlink_with_file() ? {
|
||||
file := 'tfile'
|
||||
symlink := 'tsymlink'
|
||||
os.rm(symlink) or {}
|
||||
os.rm(file) or {}
|
||||
mut f := os.create(file) or { panic(err) }
|
||||
f.close()
|
||||
create_file(file) ?
|
||||
os.link(file, symlink) or { panic(err) }
|
||||
assert os.exists(symlink)
|
||||
os.rm(symlink) or { panic(err) }
|
||||
|
@ -470,13 +532,9 @@ fn test_symlink() {
|
|||
}
|
||||
}
|
||||
|
||||
fn test_is_executable_writable_readable() {
|
||||
fn test_is_executable_writable_readable() ? {
|
||||
file_name := 'rwxfile.exe'
|
||||
mut f := os.create(file_name) or {
|
||||
eprintln('failed to create file $file_name')
|
||||
return
|
||||
}
|
||||
f.close()
|
||||
create_file(file_name) ?
|
||||
$if !windows {
|
||||
os.chmod(file_name, 0o600) or {} // mark as readable && writable, but NOT executable
|
||||
assert os.is_writable(file_name)
|
||||
|
@ -634,12 +692,12 @@ cmd.close()
|
|||
*/
|
||||
}
|
||||
|
||||
fn test_posix_set_bit() {
|
||||
fn test_posix_set_bit() ? {
|
||||
$if windows {
|
||||
assert true
|
||||
} $else {
|
||||
fpath := '/tmp/permtest'
|
||||
os.create(fpath) or { panic("Couldn't create file") }
|
||||
fpath := 'permtest'
|
||||
create_file(fpath) ?
|
||||
os.chmod(fpath, 0o0777) or { panic(err) }
|
||||
c_fpath := &char(fpath.str)
|
||||
mut s := C.stat{}
|
||||
|
@ -694,11 +752,11 @@ fn test_exists_in_system_path() {
|
|||
assert os.exists_in_system_path('ls')
|
||||
}
|
||||
|
||||
fn test_truncate() {
|
||||
fn test_truncate() ? {
|
||||
filename := './test_trunc.txt'
|
||||
hello := 'hello world!'
|
||||
mut f := os.create(filename) or { panic(err) }
|
||||
f.write_string(hello) or { panic(err) }
|
||||
mut f := os.create(filename) ?
|
||||
f.write_string(hello) ?
|
||||
f.close()
|
||||
assert hello.len == os.file_size(filename)
|
||||
newlen := u64(40000)
|
||||
|
@ -711,17 +769,14 @@ fn test_hostname() {
|
|||
assert os.hostname().len > 2
|
||||
}
|
||||
|
||||
fn test_glob() {
|
||||
fn test_glob() ? {
|
||||
os.mkdir('test_dir') or { panic(err) }
|
||||
for i in 0 .. 4 {
|
||||
if i == 3 {
|
||||
mut f := os.create('test_dir/test0_another') or { panic(err) }
|
||||
f.close()
|
||||
mut f1 := os.create('test_dir/test') or { panic(err) }
|
||||
f1.close()
|
||||
create_file('test_dir/test0_another') ?
|
||||
create_file('test_dir/test') ?
|
||||
} else {
|
||||
mut f := os.create('test_dir/test' + i.str()) or { panic(err) }
|
||||
f.close()
|
||||
create_file('test_dir/test' + i.str()) ?
|
||||
}
|
||||
}
|
||||
files := os.glob('test_dir/t*') or { panic(err) }
|
||||
|
|
|
@ -153,6 +153,9 @@ pub fn utime(path string, actime int, modtime int) ? {
|
|||
}
|
||||
|
||||
pub fn ls(path string) ?[]string {
|
||||
if path.len == 0 {
|
||||
return error('ls() expects a folder, not an empty string')
|
||||
}
|
||||
mut find_file_data := Win32finddata{}
|
||||
mut dir_files := []string{}
|
||||
// We can also check if the handle is valid. but using is_dir instead
|
||||
|
|
Loading…
Reference in New Issue