github.com/grailbio/base@v0.0.11/file/fsnode/fileinfo.go (about) 1 package fsnode 2 3 import ( 4 "os" 5 "time" 6 ) 7 8 // FileInfo implements os.FileInfo. Instances are immutable but convenient 9 // copy-and-set methods are provided for some fields. FileInfo implements 10 // (T).Info, so implementations of T can conveniently embed a FileInfo for 11 // simple cases, e.g. if the information is immutable. 12 type FileInfo struct { 13 name string 14 size int64 15 mode os.FileMode 16 mod time.Time 17 sys interface{} 18 cacheableFor time.Duration 19 } 20 21 // Info implements (T).Info. 22 func (fi FileInfo) Info() os.FileInfo { 23 return fi 24 } 25 26 // NewDirInfo constructs FileInfo for a directory. 27 // Default ModePerm is 0555 (r-xr-xr-x). Other defaults are zero. 28 func NewDirInfo(name string) FileInfo { return FileInfo{name: name, mode: os.ModeDir | 0555} } 29 30 // NewRegInfo constructs FileInfo for a regular file. 31 // Default ModePerm is 0444 (r--r--r--). Other defaults are zero. 32 func NewRegInfo(name string) FileInfo { return FileInfo{name: name, mode: 0444} } 33 34 // NewSymlinkInfo constructs FileInfo for a symlink. 35 // 36 // Create a symlink by using this FileInfo with a Leaf whose contents are the target path. 37 // The path may be relative or absolute. 38 func NewSymlinkInfo(name string) FileInfo { 39 return FileInfo{ 40 name: name, 41 // Note: Symlinks don't need permissions. From `man 7 symlink`: 42 // On Linux, the permissions of a symbolic link are not used in any operations; ... 43 // And on macOS: 44 // Of these, only the flags are used by the system; the access permissions and 45 // ownership are ignored. 46 mode: os.ModeSymlink, 47 } 48 } 49 50 // CopyFileInfo constructs FileInfo with the same public fields as info. 51 // It copies cacheability if available. 52 func CopyFileInfo(info os.FileInfo) FileInfo { 53 return FileInfo{ 54 name: info.Name(), 55 size: info.Size(), 56 mode: info.Mode(), 57 mod: info.ModTime(), 58 sys: info.Sys(), 59 cacheableFor: CacheableFor(info), 60 } 61 } 62 63 func (f FileInfo) Name() string { return f.name } 64 func (f FileInfo) Size() int64 { return f.size } 65 func (f FileInfo) Mode() os.FileMode { return f.mode } 66 func (f FileInfo) ModTime() time.Time { return f.mod } 67 func (f FileInfo) IsDir() bool { return f.mode&os.ModeDir != 0 } 68 func (f FileInfo) Sys() interface{} { return f.sys } 69 func (f FileInfo) CacheableFor() time.Duration { return f.cacheableFor } 70 71 func (f FileInfo) WithName(name string) FileInfo { 72 cp := f 73 cp.name = name 74 return cp 75 } 76 func (f FileInfo) WithSize(size int64) FileInfo { 77 cp := f 78 cp.size = size 79 return cp 80 } 81 func (f FileInfo) WithModePerm(perm os.FileMode) FileInfo { 82 cp := f 83 cp.mode = (perm & os.ModePerm) | (cp.mode &^ os.ModePerm) 84 return cp 85 } 86 func (f FileInfo) WithModeType(modeType os.FileMode) FileInfo { 87 cp := f 88 cp.mode = (modeType & os.ModeType) | (cp.mode &^ os.ModeType) 89 return cp 90 } 91 func (f FileInfo) WithModTime(mod time.Time) FileInfo { 92 cp := f 93 cp.mod = mod 94 return cp 95 } 96 func (f FileInfo) WithSys(sys interface{}) FileInfo { 97 cp := f 98 cp.sys = sys 99 return cp 100 } 101 func (f FileInfo) WithCacheableFor(d time.Duration) FileInfo { 102 cp := f 103 cp.cacheableFor = d 104 return cp 105 } 106 107 func (f FileInfo) Equal(g FileInfo) bool { 108 if !f.mod.Equal(g.mod) { 109 return false 110 } 111 f.mod = g.mod 112 return f == g 113 }