vfmt: keep file permissions with -w on !windows (#13334)
parent
7c1b249da0
commit
51513ae19a
|
@ -259,7 +259,15 @@ fn (foptions &FormatOptions) post_process_file(file string, formatted_file_path
|
|||
file_bak := '${file}.bak'
|
||||
os.cp(file, file_bak) or {}
|
||||
}
|
||||
mut perms_to_restore := u32(0)
|
||||
$if !windows {
|
||||
fm := os.inode(file)
|
||||
perms_to_restore = fm.bitmask()
|
||||
}
|
||||
os.mv_by_cp(formatted_file_path, file) or { panic(err) }
|
||||
$if !windows {
|
||||
os.chmod(file, int(perms_to_restore)) or { panic(err) }
|
||||
}
|
||||
eprintln('Reformatted file: $file')
|
||||
} else {
|
||||
eprintln('Already formatted file: $file')
|
||||
|
|
|
@ -20,6 +20,22 @@ pub:
|
|||
execute bool
|
||||
}
|
||||
|
||||
// bitmask returns a 3 bit sequence in the order RWE where
|
||||
// the bit is set to 1 if the value is true or 0 otherwise.
|
||||
pub fn (p FilePermission) bitmask() u32 {
|
||||
mut mask := u32(0)
|
||||
if p.read {
|
||||
mask |= 4
|
||||
}
|
||||
if p.write {
|
||||
mask |= 2
|
||||
}
|
||||
if p.execute {
|
||||
mask |= 1
|
||||
}
|
||||
return mask
|
||||
}
|
||||
|
||||
struct FileMode {
|
||||
pub:
|
||||
typ FileType
|
||||
|
@ -28,6 +44,12 @@ pub:
|
|||
others FilePermission
|
||||
}
|
||||
|
||||
// bitmask returns a 9 bit sequence in the order owner + group + others.
|
||||
// This is a valid bitmask to use with `os.chmod`.
|
||||
pub fn (m FileMode) bitmask() u32 {
|
||||
return m.owner.bitmask() << 6 | m.group.bitmask() << 3 | m.others.bitmask()
|
||||
}
|
||||
|
||||
// inode returns the mode of the file/inode containing inode type and permission information
|
||||
// it supports windows for regular files but it doesn't matter if you use owner, group or others when checking permissions on windows
|
||||
pub fn inode(path string) FileMode {
|
||||
|
|
|
@ -41,3 +41,16 @@ fn test_inode_file_owner_permission() {
|
|||
assert mode.owner.write
|
||||
assert !mode.owner.execute
|
||||
}
|
||||
|
||||
fn test_inode_file_permissions_bitmask() {
|
||||
if user_os() == 'windows' {
|
||||
println('> skipping ${@FN} on windows')
|
||||
return
|
||||
}
|
||||
filename := './test3.txt'
|
||||
mut file := open_file(filename, 'w', 0o641) or { return }
|
||||
file.close()
|
||||
mode := inode(filename)
|
||||
rm(filename) or {}
|
||||
assert mode.bitmask() == 0o641
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue