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  }