github.com/avfs/avfs@v0.33.1-0.20240303173310-c6ba67c33eb7/vfs/memfs/memfs_cfg.go (about) 1 // 2 // Copyright 2020 The AVFS authors 3 // 4 // Licensed under the Apache License, Version 2.0 (the "License"); 5 // you may not use this file except in compliance with the License. 6 // You may obtain a copy of the License at 7 // 8 // http://www.apache.org/licenses/LICENSE-2.0 9 // 10 // Unless required by applicable law or agreed to in writing, software 11 // distributed under the License is distributed on an "AS IS" BASIS, 12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 // See the License for the specific language governing permissions and 14 // limitations under the License. 15 // 16 17 package memfs 18 19 import ( 20 "io/fs" 21 22 "github.com/avfs/avfs" 23 "github.com/avfs/avfs/idm/memidm" 24 ) 25 26 // New returns a new memory file system (MemFS) with the default Options. 27 func New() *MemFS { 28 return NewWithOptions(nil) 29 } 30 31 // NewWithOptions returns a new memory file system (MemFS) with the selected Options. 32 func NewWithOptions(opts *Options) *MemFS { 33 if opts == nil { 34 opts = &Options{OSType: avfs.OsUnknown} 35 } 36 37 idm := opts.Idm 38 if idm == nil { 39 idm = memidm.New() 40 } 41 42 features := avfs.FeatHardlink | avfs.FeatSubFS | avfs.FeatSymlink | idm.Features() | avfs.BuildFeatures() 43 44 user := opts.User 45 if opts.User == nil { 46 user = idm.AdminUser() 47 } 48 49 vfs := &MemFS{ 50 dirMode: fs.ModeDir, 51 fileMode: 0, 52 lastId: new(uint64), 53 name: opts.Name, 54 } 55 56 _ = vfs.SetFeatures(features) 57 _ = vfs.SetOSType(opts.OSType) 58 _ = vfs.SetIdm(idm) 59 _ = vfs.SetUser(user) 60 61 vfs.err.SetOSType(vfs.OSType()) 62 vfs.rootNode = vfs.createRootNode() 63 64 var volumeName string 65 66 if vfs.OSType() == avfs.OsWindows { 67 vfs.dirMode |= avfs.DefaultDirPerm 68 vfs.fileMode |= avfs.DefaultFilePerm 69 70 volumeName = avfs.DefaultVolume 71 vfs.volumes = make(volumes) 72 vfs.volumes[volumeName] = vfs.rootNode 73 } 74 75 if len(opts.SystemDirs) == 0 { 76 opts.SystemDirs = avfs.SystemDirs(vfs, volumeName) 77 } 78 79 _ = avfs.MkSystemDirs(vfs, opts.SystemDirs) 80 _ = vfs.SetUMask(avfs.UMask()) 81 82 return vfs 83 } 84 85 // Name returns the name of the fileSystem. 86 func (vfs *MemFS) Name() string { 87 return vfs.name 88 } 89 90 // Type returns the type of the fileSystem or Identity manager. 91 func (*MemFS) Type() string { 92 return "MemFS" 93 } 94 95 // VolumeAdd adds a new volume to a Windows file system. 96 // If there is an error, it will be of type *PathError. 97 func (vfs *MemFS) VolumeAdd(path string) error { 98 const op = "VolumeAdd" 99 100 if vfs.OSType() != avfs.OsWindows { 101 return &fs.PathError{Op: op, Path: path, Err: avfs.ErrVolumeWindows} 102 } 103 104 vol := avfs.VolumeName(vfs, path) 105 if vol == "" { 106 return &fs.PathError{Op: op, Path: path, Err: avfs.ErrVolumeNameInvalid} 107 } 108 109 _, ok := vfs.volumes[vol] 110 if ok { 111 return &fs.PathError{Op: op, Path: path, Err: avfs.ErrVolumeAlreadyExists} 112 } 113 114 vfs.volumes[vol] = vfs.createRootNode() 115 116 return nil 117 } 118 119 // VolumeDelete deletes an existing volume and all its files from a Windows file system. 120 // If there is an error, it will be of type *PathError. 121 func (vfs *MemFS) VolumeDelete(path string) error { 122 const op = "VolumeDelete" 123 124 if vfs.OSType() != avfs.OsWindows { 125 return &fs.PathError{Op: op, Path: path, Err: avfs.ErrVolumeWindows} 126 } 127 128 vol := avfs.VolumeName(vfs, path) 129 if vol == "" { 130 return &fs.PathError{Op: op, Path: path, Err: avfs.ErrVolumeNameInvalid} 131 } 132 133 _, ok := vfs.volumes[vol] 134 if !ok { 135 return &fs.PathError{Op: op, Path: path, Err: avfs.ErrVolumeNameInvalid} 136 } 137 138 err := vfs.RemoveAll(vol) 139 if err != nil { 140 return err 141 } 142 143 delete(vfs.volumes, vol) 144 145 return nil 146 } 147 148 // VolumeList returns the volumes of the file system. 149 func (vfs *MemFS) VolumeList() []string { 150 var l []string //nolint:prealloc // Consider preallocating `l` 151 152 if vfs.OSType() != avfs.OsWindows { 153 return l 154 } 155 156 for v := range vfs.volumes { 157 l = append(l, v) 158 } 159 160 return l 161 }