mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
os,tools: add os.vtmp_dir()
Use it to consistently place all temporary files created by tests in a overridable folder specific to the user, that is easy to cleanup later. NOTE: os.temp_dir() on macos returns `/tmp`, and using `/tmp/v` is a problem when multiple unix users are trying to access/create/write to it.
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
import os
|
||||
|
||||
const tfolder = os.join_path(os.temp_dir(), 'v', 'tests', 'os_file_test')
|
||||
const tfolder = os.join_path(os.vtmp_dir(), 'v', 'tests', 'os_file_test')
|
||||
|
||||
const tfile = os.join_path_single(tfolder, 'test_file')
|
||||
|
||||
|
@@ -1,46 +1,46 @@
|
||||
module os
|
||||
import os
|
||||
|
||||
fn test_find_abs_path_of_executable() {
|
||||
tfolder := join_path(temp_dir(), 'v', 'tests', 'filepath_test')
|
||||
rmdir_all(tfolder) or {}
|
||||
assert !is_dir(tfolder)
|
||||
mkdir_all(tfolder)?
|
||||
tfolder := os.join_path(os.vtmp_dir(), 'v', 'tests', 'filepath_test')
|
||||
os.rmdir_all(tfolder) or {}
|
||||
assert !os.is_dir(tfolder)
|
||||
os.mkdir_all(tfolder)!
|
||||
defer {
|
||||
rmdir_all(tfolder) or {}
|
||||
os.rmdir_all(tfolder) or {}
|
||||
}
|
||||
//
|
||||
original_path := getenv('PATH')
|
||||
original_wdir := getwd()
|
||||
original_path := os.getenv('PATH')
|
||||
original_wdir := os.getwd()
|
||||
defer {
|
||||
chdir(original_wdir) or {}
|
||||
os.chdir(original_wdir) or {}
|
||||
}
|
||||
//
|
||||
new_path := tfolder + path_delimiter + original_path
|
||||
setenv('PATH', new_path, true)
|
||||
new_path := tfolder + os.path_delimiter + original_path
|
||||
os.setenv('PATH', new_path, true)
|
||||
//
|
||||
mut myclang_file := 'myclang'
|
||||
$if windows {
|
||||
myclang_file += '.bat'
|
||||
}
|
||||
//
|
||||
chdir(tfolder)?
|
||||
write_file(myclang_file, 'echo hello')?
|
||||
chmod(myclang_file, 0o0777)!
|
||||
dump(real_path(myclang_file))
|
||||
dump(is_executable(myclang_file))
|
||||
os.chdir(tfolder)!
|
||||
os.write_file(myclang_file, 'echo hello')!
|
||||
os.chmod(myclang_file, 0o0777)!
|
||||
dump(os.real_path(myclang_file))
|
||||
dump(os.is_executable(myclang_file))
|
||||
defer {
|
||||
rm(myclang_file) or {}
|
||||
os.rm(myclang_file) or {}
|
||||
}
|
||||
//
|
||||
fpath := find_abs_path_of_executable('myclang') or {
|
||||
fpath := os.find_abs_path_of_executable('myclang') or {
|
||||
assert false
|
||||
return
|
||||
}
|
||||
dump(fpath)
|
||||
//
|
||||
setenv('PATH', original_path, true)
|
||||
chdir(home_dir())! // change to a *completely* different folder, to avoid the original PATH containing `.`
|
||||
if x := find_abs_path_of_executable('myclang') {
|
||||
os.setenv('PATH', original_path, true)
|
||||
os.chdir(os.home_dir())! // change to a *completely* different folder, to avoid the original PATH containing `.`
|
||||
if x := os.find_abs_path_of_executable('myclang') {
|
||||
eprintln('> find_abs_path_of_executable should have failed, but instead it found: $x')
|
||||
assert false
|
||||
}
|
||||
|
@@ -3,7 +3,7 @@
|
||||
// that can be found in the LICENSE file.
|
||||
module os
|
||||
|
||||
enum FileType {
|
||||
pub enum FileType {
|
||||
regular
|
||||
directory
|
||||
character_device
|
||||
|
@@ -1,56 +1,56 @@
|
||||
module os
|
||||
import os
|
||||
|
||||
const (
|
||||
// tfolder will contain all the temporary files/subfolders made by
|
||||
// the different tests. It would be removed in testsuite_end(), so
|
||||
// individual os tests do not need to clean up after themselves.
|
||||
tfolder = join_path(temp_dir(), 'v', 'tests', 'inode_test')
|
||||
tfolder = os.join_path(os.vtmp_dir(), 'v', 'tests', 'inode_test')
|
||||
)
|
||||
|
||||
fn testsuite_begin() {
|
||||
eprintln('testsuite_begin, tfolder = $os.tfolder')
|
||||
rmdir_all(os.tfolder) or {}
|
||||
assert !is_dir(os.tfolder)
|
||||
mkdir_all(os.tfolder) or { panic(err) }
|
||||
chdir(os.tfolder) or {}
|
||||
assert is_dir(os.tfolder)
|
||||
eprintln('testsuite_begin, tfolder = $tfolder')
|
||||
os.rmdir_all(tfolder) or {}
|
||||
assert !os.is_dir(tfolder)
|
||||
os.mkdir_all(tfolder) or { panic(err) }
|
||||
os.chdir(tfolder) or {}
|
||||
assert os.is_dir(tfolder)
|
||||
}
|
||||
|
||||
fn testsuite_end() {
|
||||
chdir(wd_at_startup) or {}
|
||||
rmdir_all(os.tfolder) or { panic(err) }
|
||||
assert !is_dir(os.tfolder)
|
||||
os.chdir(os.wd_at_startup) or {}
|
||||
os.rmdir_all(tfolder) or { panic(err) }
|
||||
assert !os.is_dir(tfolder)
|
||||
}
|
||||
|
||||
fn test_inode_file_type() {
|
||||
filename := './test1.txt'
|
||||
mut file := open_file(filename, 'w', 0o600) or { return }
|
||||
mut file := os.open_file(filename, 'w', 0o600) or { return }
|
||||
file.close()
|
||||
mode := inode(filename)
|
||||
rm(filename) or { panic(err) }
|
||||
mode := os.inode(filename)
|
||||
os.rm(filename) or { panic(err) }
|
||||
assert mode.typ == .regular
|
||||
}
|
||||
|
||||
fn test_inode_file_owner_permission() {
|
||||
filename := './test2.txt'
|
||||
mut file := open_file(filename, 'w', 0o600) or { return }
|
||||
mut file := os.open_file(filename, 'w', 0o600) or { return }
|
||||
file.close()
|
||||
mode := inode(filename)
|
||||
rm(filename) or {}
|
||||
mode := os.inode(filename)
|
||||
os.rm(filename) or {}
|
||||
assert mode.owner.read
|
||||
assert mode.owner.write
|
||||
assert !mode.owner.execute
|
||||
}
|
||||
|
||||
fn test_inode_file_permissions_bitmask() {
|
||||
if user_os() == 'windows' {
|
||||
if os.user_os() == 'windows' {
|
||||
println('> skipping ${@FN} on windows')
|
||||
return
|
||||
}
|
||||
filename := './test3.txt'
|
||||
mut file := open_file(filename, 'w', 0o641) or { return }
|
||||
mut file := os.open_file(filename, 'w', 0o641) or { return }
|
||||
file.close()
|
||||
mode := inode(filename)
|
||||
rm(filename) or {}
|
||||
mode := os.inode(filename)
|
||||
os.rm(filename) or {}
|
||||
assert mode.bitmask() == 0o641
|
||||
}
|
||||
|
17
vlib/os/os.v
17
vlib/os/os.v
@@ -719,6 +719,23 @@ pub fn temp_dir() string {
|
||||
return path
|
||||
}
|
||||
|
||||
// vtmp_dir returns the path to a folder, that is writable to V programs, *and* specific
|
||||
// to the OS user. It can be overriden by setting the env variable `VTMP`.
|
||||
pub fn vtmp_dir() string {
|
||||
mut vtmp := getenv('VTMP')
|
||||
if vtmp.len > 0 {
|
||||
return vtmp
|
||||
}
|
||||
uid := getuid()
|
||||
vtmp = join_path_single(temp_dir(), 'v_$uid')
|
||||
if !exists(vtmp) || !is_dir(vtmp) {
|
||||
// create a new directory, that is private to the user:
|
||||
mkdir_all(vtmp, mode: 0o700) or { panic(err) }
|
||||
}
|
||||
setenv('VTMP', vtmp, true)
|
||||
return vtmp
|
||||
}
|
||||
|
||||
fn default_vmodules_path() string {
|
||||
hdir := home_dir()
|
||||
res := join_path_single(hdir, '.vmodules')
|
||||
|
@@ -5,7 +5,7 @@ const (
|
||||
// tfolder will contain all the temporary files/subfolders made by
|
||||
// the different tests. It would be removed in testsuite_end(), so
|
||||
// individual os tests do not need to clean up after themselves.
|
||||
tfolder = os.join_path(os.temp_dir(), 'v', 'tests', 'os_test')
|
||||
tfolder = os.join_path(os.vtmp_dir(), 'v', 'tests', 'os_test')
|
||||
)
|
||||
|
||||
// os.args has to be *already initialized* with the program's argc/argv at this point
|
||||
|
@@ -6,7 +6,7 @@ import time
|
||||
const (
|
||||
vexe = os.getenv('VEXE')
|
||||
vroot = os.dir(vexe)
|
||||
tfolder = os.join_path(os.temp_dir(), 'v', 'tests', 'os_process')
|
||||
tfolder = os.join_path(os.vtmp_dir(), 'v', 'tests', 'os_process')
|
||||
test_os_process = os.join_path(tfolder, 'test_os_process.exe')
|
||||
test_os_process_source = os.join_path(vroot, 'cmd/tools/test_os_process.v')
|
||||
)
|
||||
|
Reference in New Issue
Block a user