mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
os: make os.ls('') return an error, make os.walk_ext more memory efficient on deep hierarchies, add tests for os.walk_ext
This commit is contained in:
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`.
|
// walk_ext returns a recursive list of all files in `path` ending with `ext`.
|
||||||
pub fn walk_ext(path string, ext string) []string {
|
pub fn walk_ext(path string, ext string) []string {
|
||||||
if !is_dir(path) {
|
|
||||||
return []
|
|
||||||
}
|
|
||||||
mut files := ls(path) or { return [] }
|
|
||||||
mut res := []string{}
|
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 }
|
separator := if path.ends_with(path_separator) { '' } else { path_separator }
|
||||||
for file in files {
|
for file in files {
|
||||||
if file.starts_with('.') {
|
if file.starts_with('.') {
|
||||||
@ -461,12 +466,11 @@ pub fn walk_ext(path string, ext string) []string {
|
|||||||
}
|
}
|
||||||
p := path + separator + file
|
p := path + separator + file
|
||||||
if is_dir(p) && !is_link(p) {
|
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) {
|
} else if file.ends_with(ext) {
|
||||||
res << p
|
out << p
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return res
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// walk recursively traverses the given directory `path`.
|
// 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 {
|
pub fn ls(path string) ?[]string {
|
||||||
|
if path.len == 0 {
|
||||||
|
return error('ls() expects a folder, not an empty string')
|
||||||
|
}
|
||||||
mut res := []string{}
|
mut res := []string{}
|
||||||
dir := unsafe { C.opendir(&char(path.str)) }
|
dir := unsafe { C.opendir(&char(path.str)) }
|
||||||
if isnil(dir) {
|
if isnil(dir) {
|
||||||
|
@ -84,12 +84,22 @@ fn test_open_file_binary() {
|
|||||||
// assert line1 == 'line 1\n'
|
// assert line1 == 'line 1\n'
|
||||||
// assert line2 == 'line 2'
|
// 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'
|
filename := './test1.txt'
|
||||||
hello := 'hello world!'
|
hello := 'hello world!'
|
||||||
mut f := os.create(filename) or { panic(err) }
|
create_and_write_to_file(filename, hello) ?
|
||||||
f.write_string(hello) or { panic(err) }
|
|
||||||
f.close()
|
|
||||||
assert hello.len == os.file_size(filename)
|
assert hello.len == os.file_size(filename)
|
||||||
os.rm(filename) or { panic(err) }
|
os.rm(filename) or { panic(err) }
|
||||||
}
|
}
|
||||||
@ -175,6 +185,61 @@ fn test_write_and_read_bytes() {
|
|||||||
os.rm(file_name) or { panic(err) }
|
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() {
|
fn test_create_and_delete_folder() {
|
||||||
folder := './test1'
|
folder := './test1'
|
||||||
os.mkdir(folder) or { panic(err) }
|
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() ? {
|
fn test_realpath_absolutepath_symlink() ? {
|
||||||
file_name := 'tolink_file.txt'
|
file_name := 'tolink_file.txt'
|
||||||
symlink_name := 'symlink.txt'
|
symlink_name := 'symlink.txt'
|
||||||
mut f := os.create(file_name) ?
|
create_file(file_name) ?
|
||||||
f.close()
|
|
||||||
assert os.symlink(file_name, symlink_name) ?
|
assert os.symlink(file_name, symlink_name) ?
|
||||||
rpath := os.real_path(symlink_name)
|
rpath := os.real_path(symlink_name)
|
||||||
println(rpath)
|
println(rpath)
|
||||||
@ -406,13 +470,12 @@ fn test_make_symlink_check_is_link_and_remove_symlink() {
|
|||||||
assert symlink_exists == false
|
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'
|
file := 'tfile'
|
||||||
symlink := 'tsymlink'
|
symlink := 'tsymlink'
|
||||||
os.rm(symlink) or {}
|
os.rm(symlink) or {}
|
||||||
os.rm(file) or {}
|
os.rm(file) or {}
|
||||||
mut f := os.create(file) or { panic(err) }
|
create_file(file) ?
|
||||||
f.close()
|
|
||||||
os.symlink(file, symlink) or { panic(err) }
|
os.symlink(file, symlink) or { panic(err) }
|
||||||
assert os.is_link(symlink)
|
assert os.is_link(symlink)
|
||||||
os.rm(symlink) or { panic(err) }
|
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
|
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'
|
file := 'tfile'
|
||||||
symlink := 'tsymlink'
|
symlink := 'tsymlink'
|
||||||
os.rm(symlink) or {}
|
os.rm(symlink) or {}
|
||||||
os.rm(file) or {}
|
os.rm(file) or {}
|
||||||
mut f := os.create(file) or { panic(err) }
|
create_file(file) ?
|
||||||
f.close()
|
|
||||||
os.link(file, symlink) or { panic(err) }
|
os.link(file, symlink) or { panic(err) }
|
||||||
assert os.exists(symlink)
|
assert os.exists(symlink)
|
||||||
os.rm(symlink) or { panic(err) }
|
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'
|
file_name := 'rwxfile.exe'
|
||||||
mut f := os.create(file_name) or {
|
create_file(file_name) ?
|
||||||
eprintln('failed to create file $file_name')
|
|
||||||
return
|
|
||||||
}
|
|
||||||
f.close()
|
|
||||||
$if !windows {
|
$if !windows {
|
||||||
os.chmod(file_name, 0o600) or {} // mark as readable && writable, but NOT executable
|
os.chmod(file_name, 0o600) or {} // mark as readable && writable, but NOT executable
|
||||||
assert os.is_writable(file_name)
|
assert os.is_writable(file_name)
|
||||||
@ -634,12 +692,12 @@ cmd.close()
|
|||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test_posix_set_bit() {
|
fn test_posix_set_bit() ? {
|
||||||
$if windows {
|
$if windows {
|
||||||
assert true
|
assert true
|
||||||
} $else {
|
} $else {
|
||||||
fpath := '/tmp/permtest'
|
fpath := 'permtest'
|
||||||
os.create(fpath) or { panic("Couldn't create file") }
|
create_file(fpath) ?
|
||||||
os.chmod(fpath, 0o0777) or { panic(err) }
|
os.chmod(fpath, 0o0777) or { panic(err) }
|
||||||
c_fpath := &char(fpath.str)
|
c_fpath := &char(fpath.str)
|
||||||
mut s := C.stat{}
|
mut s := C.stat{}
|
||||||
@ -694,11 +752,11 @@ fn test_exists_in_system_path() {
|
|||||||
assert os.exists_in_system_path('ls')
|
assert os.exists_in_system_path('ls')
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test_truncate() {
|
fn test_truncate() ? {
|
||||||
filename := './test_trunc.txt'
|
filename := './test_trunc.txt'
|
||||||
hello := 'hello world!'
|
hello := 'hello world!'
|
||||||
mut f := os.create(filename) or { panic(err) }
|
mut f := os.create(filename) ?
|
||||||
f.write_string(hello) or { panic(err) }
|
f.write_string(hello) ?
|
||||||
f.close()
|
f.close()
|
||||||
assert hello.len == os.file_size(filename)
|
assert hello.len == os.file_size(filename)
|
||||||
newlen := u64(40000)
|
newlen := u64(40000)
|
||||||
@ -711,17 +769,14 @@ fn test_hostname() {
|
|||||||
assert os.hostname().len > 2
|
assert os.hostname().len > 2
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test_glob() {
|
fn test_glob() ? {
|
||||||
os.mkdir('test_dir') or { panic(err) }
|
os.mkdir('test_dir') or { panic(err) }
|
||||||
for i in 0 .. 4 {
|
for i in 0 .. 4 {
|
||||||
if i == 3 {
|
if i == 3 {
|
||||||
mut f := os.create('test_dir/test0_another') or { panic(err) }
|
create_file('test_dir/test0_another') ?
|
||||||
f.close()
|
create_file('test_dir/test') ?
|
||||||
mut f1 := os.create('test_dir/test') or { panic(err) }
|
|
||||||
f1.close()
|
|
||||||
} else {
|
} else {
|
||||||
mut f := os.create('test_dir/test' + i.str()) or { panic(err) }
|
create_file('test_dir/test' + i.str()) ?
|
||||||
f.close()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
files := os.glob('test_dir/t*') or { panic(err) }
|
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 {
|
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 find_file_data := Win32finddata{}
|
||||||
mut dir_files := []string{}
|
mut dir_files := []string{}
|
||||||
// We can also check if the handle is valid. but using is_dir instead
|
// We can also check if the handle is valid. but using is_dir instead
|
||||||
|
Loading…
Reference in New Issue
Block a user