ptfs

package module
v1.0.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Dec 12, 2025 License: MIT Imports: 4 Imported by: 0

README

ptfs - Pass Through File System

Go Reference Go Report Card CI License

The ptfs package implements the absfs filesystem interfaces. ptfs wraps an object that implements one of the absfs interfaces, and passes all interfaces methods to the underlying type without modification, returning the unmodified results to the caller.

This is useful as a template for creating new absfs types, but it serves another subtle but important purpose.

Anti-Reflective Coating

Wrapping a absfs compatible object in a psfs type forces the object to be the absfs interface type exclusively.

The pass through filesystem is useful in contexts in which you need to obscure a type from reflection or type assertion. For example if a package produces and consumes absfs.FileSystem objects, and recognizes it's own FileSystem objects, wrapping those objects in a psfs.FileSystem type will prevent recognition. Type assertion is an important and useful feature of Go, and typically shouldn't be circumvented, but in special cases such as testing, it may be useful to use the pass through filesystem to shield against reflection. An anti-reflection coating if you will.

The ptfs package implements the absfs.FileSystem, absfs.Filer, and absfs.SymlinkFileSystem interfaces. Additionally ptfs has Unwrap functions that can remove the pass through filesystem wrapper and return the underlying absfs interface type.

Install

$ go get github.com/absfs/ptfs

Example

package main

import (
    "fmt"
    "os"
    "time"

    "github.com/absfs/absfs"
    "github.com/absfs/ptfs"
)

type myfs struct {
    //...
}

// myfs implements `absfs.FileSystem`
// Plus...

func (fs *myfs) String() string {
    return "It is a `myfs` type."
}

func FsStringer(fs absfs.FileSystem) string {
    // myfs is an absfs.FileSystem, and can be cast to a Stringer.
    // ptfs.FileSystem is an absfs.FileSystem, but cannot be cast to a Stringer.
    s, ok := fs.(fmt.Stringer)
    if ok {
        return s.String()
    }
    return "It doesn't look like anything to me."
}

func main() {
    var fs absfs.FileSystem
    fs = &myfs{}

    fmt.Println(FsStringer(fs)) // output: "It is a `myfs` type."
    fs, _ = ptfs.NewFS(fs)
    fmt.Println(FsStringer(fs)) // output: "It doesn't look like anything to me."
}

absfs

Check out the absfs repo for more information about the abstract FileSystem interface and features like FileSystem composition.

LICENSE

This project is governed by the MIT License. See LICENSE

Documentation

Overview

Example (AntiReflection)

Example demonstrating the anti-reflection feature.

package main

import (
	"fmt"

	"github.com/absfs/absfs"
	"github.com/absfs/memfs"
	"github.com/absfs/ptfs"
)

func main() {
	// Create a memfs filesystem
	mfs, _ := memfs.NewFS()

	// Without wrapping, type assertion succeeds
	var fs absfs.SymlinkFileSystem = mfs
	_, isMemfs := fs.(*memfs.FileSystem)
	fmt.Printf("Before wrapping: is memfs? %v\n", isMemfs)

	// After wrapping with ptfs, type assertion fails
	wrapped, _ := ptfs.NewSymlinkFS(mfs)
	fs = wrapped
	_, isMemfs = fs.(*memfs.FileSystem)
	fmt.Printf("After wrapping: is memfs? %v\n", isMemfs)

}
Output:

Before wrapping: is memfs? true
After wrapping: is memfs? false
Example (BasicUsage)

Example demonstrating basic pass-through usage.

package main

import (
	"fmt"

	"github.com/absfs/memfs"
	"github.com/absfs/ptfs"
)

func main() {
	// Create a memfs filesystem
	mfs, _ := memfs.NewFS()

	// Wrap it with ptfs
	pfs, _ := ptfs.NewSymlinkFS(mfs)

	// Use the wrapped filesystem - all operations pass through
	f, _ := pfs.Create("/hello.txt")
	f.WriteString("Hello, World!")
	f.Close()

	// Read it back
	f, _ = pfs.Open("/hello.txt")
	buf := make([]byte, 100)
	n, _ := f.Read(buf)
	f.Close()

	fmt.Println(string(buf[:n]))
}
Output:

Hello, World!
Example (MultiLayerWrap)

Example demonstrating multi-layer wrapping.

package main

import (
	"fmt"

	"github.com/absfs/memfs"
	"github.com/absfs/ptfs"
)

func main() {
	mfs, _ := memfs.NewFS()

	// Wrap multiple times
	layer1, _ := ptfs.NewSymlinkFS(mfs)
	layer2, _ := ptfs.NewSymlinkFS(layer1)

	// Operations still work through multiple layers
	f, _ := layer2.Create("/test.txt")
	f.WriteString("Multi-layer test")
	f.Close()

	info, _ := layer2.Stat("/test.txt")
	fmt.Printf("File size: %d\n", info.Size())

	// Unwrap layer by layer
	unwrap1 := ptfs.UnwrapSymlinkFS(layer2)
	_, isFirstLayer := unwrap1.(*ptfs.SymlinkFileSystem)
	fmt.Printf("First unwrap is ptfs? %v\n", isFirstLayer)

	unwrap2 := ptfs.UnwrapSymlinkFS(unwrap1)
	_, isMemfs := unwrap2.(*memfs.FileSystem)
	fmt.Printf("Second unwrap is memfs? %v\n", isMemfs)

}
Output:

File size: 16
First unwrap is ptfs? true
Second unwrap is memfs? true
Example (Unwrap)

Example demonstrating the unwrap functionality.

package main

import (
	"fmt"

	"github.com/absfs/absfs"
	"github.com/absfs/memfs"
	"github.com/absfs/ptfs"
)

func main() {
	// Create and wrap a memfs
	mfs, _ := memfs.NewFS()
	wrapped, _ := ptfs.NewSymlinkFS(mfs)

	// Type assertion fails on wrapped
	var fs absfs.SymlinkFileSystem = wrapped
	_, ok := fs.(*memfs.FileSystem)
	fmt.Printf("Wrapped: type assertion succeeded? %v\n", ok)

	// Unwrap to get original back
	unwrapped := ptfs.UnwrapSymlinkFS(wrapped)
	_, ok = unwrapped.(*memfs.FileSystem)
	fmt.Printf("Unwrapped: type assertion succeeded? %v\n", ok)

}
Output:

Wrapped: type assertion succeeded? false
Unwrapped: type assertion succeeded? true

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func UnwrapFS

func UnwrapFS(fs absfs.FileSystem) absfs.FileSystem

UnwrapFS unwraps a `absfs.FileSystem` if it is a pass through filesystem, and returns the underlying `absfs.FileSystem` object, otherwise it returns the argument unmodified.

func UnwrapFiler

func UnwrapFiler(fs absfs.Filer) absfs.Filer

UnwrapFiler unwraps an `absfs.Filer` if it is a pass through filer, and returns the underlying `absfs.Filer` object, otherwise it returns the argument unmodified.

func UnwrapSymlinkFS

func UnwrapSymlinkFS(fs absfs.SymlinkFileSystem) absfs.SymlinkFileSystem

SymlinkFileSystem unwraps an `absfs.Filer` if it is a pass through filer, and returns the underlying `absfs.Filer` object, otherwise it returns the argument unmodified.

Types

type File

type File struct {
	// contains filtered or unexported fields
}

func (*File) Close

func (f *File) Close() error

func (*File) Name

func (f *File) Name() string

func (*File) Read

func (f *File) Read(p []byte) (int, error)

func (*File) ReadAt

func (f *File) ReadAt(b []byte, off int64) (n int, err error)

func (*File) ReadDir

func (f *File) ReadDir(n int) ([]fs.DirEntry, error)

func (*File) Readdir

func (f *File) Readdir(n int) ([]os.FileInfo, error)

func (*File) Readdirnames

func (f *File) Readdirnames(n int) ([]string, error)

func (*File) Seek

func (f *File) Seek(offset int64, whence int) (ret int64, err error)

func (*File) Stat

func (f *File) Stat() (os.FileInfo, error)

func (*File) Sync

func (f *File) Sync() error

func (*File) Truncate

func (f *File) Truncate(size int64) error

func (*File) Write

func (f *File) Write(p []byte) (int, error)

func (*File) WriteAt

func (f *File) WriteAt(b []byte, off int64) (n int, err error)

func (*File) WriteString

func (f *File) WriteString(s string) (n int, err error)

type FileSystem

type FileSystem struct {
	// contains filtered or unexported fields
}

func NewFS

func NewFS(fs absfs.FileSystem) (*FileSystem, error)

func (*FileSystem) Chdir

func (f *FileSystem) Chdir(dir string) error

func (*FileSystem) Chmod

func (f *FileSystem) Chmod(name string, mode os.FileMode) error

Chmod changes the mode of the named file to mode.

func (*FileSystem) Chown

func (f *FileSystem) Chown(name string, uid, gid int) error

Chown changes the owner and group ids of the named file

func (*FileSystem) Chtimes

func (f *FileSystem) Chtimes(name string, atime time.Time, mtime time.Time) error

Chtimes changes the access and modification times of the named file

func (*FileSystem) Create

func (f *FileSystem) Create(name string) (absfs.File, error)

func (*FileSystem) Getwd

func (f *FileSystem) Getwd() (dir string, err error)

func (*FileSystem) Mkdir

func (f *FileSystem) Mkdir(name string, perm os.FileMode) error

Mkdir creates a directory in the filesystem, return an error if any happens.

func (*FileSystem) MkdirAll

func (f *FileSystem) MkdirAll(name string, perm os.FileMode) error

func (*FileSystem) Open

func (f *FileSystem) Open(name string) (absfs.File, error)

func (*FileSystem) OpenFile

func (f *FileSystem) OpenFile(name string, flag int, perm os.FileMode) (absfs.File, error)

OpenFile opens a file using the given flags and the given mode.

func (*FileSystem) ReadDir

func (f *FileSystem) ReadDir(name string) ([]fs.DirEntry, error)

func (*FileSystem) ReadFile

func (f *FileSystem) ReadFile(name string) ([]byte, error)

func (*FileSystem) Remove

func (f *FileSystem) Remove(name string) error

Remove removes a file identified by name, returning an error, if any happens.

func (*FileSystem) RemoveAll

func (f *FileSystem) RemoveAll(path string) (err error)

func (*FileSystem) Rename

func (f *FileSystem) Rename(oldname, newname string) error

func (*FileSystem) Stat

func (f *FileSystem) Stat(name string) (os.FileInfo, error)

Stat returns the FileInfo structure describing file. If there is an error, it will be of type *PathError.

func (*FileSystem) Sub

func (f *FileSystem) Sub(dir string) (fs.FS, error)

func (*FileSystem) TempDir

func (f *FileSystem) TempDir() string

func (*FileSystem) Truncate

func (f *FileSystem) Truncate(name string, size int64) error

type Filer

type Filer struct {
	// contains filtered or unexported fields
}

func NewFiler

func NewFiler(fs absfs.Filer) (*Filer, error)

func (*Filer) Chmod

func (f *Filer) Chmod(name string, mode os.FileMode) error

Chmod changes the mode of the named file to mode.

func (*Filer) Chown

func (f *Filer) Chown(name string, uid, gid int) error

Chown changes the owner and group ids of the named file

func (*Filer) Chtimes

func (f *Filer) Chtimes(name string, atime time.Time, mtime time.Time) error

Chtimes changes the access and modification times of the named file

func (*Filer) Mkdir

func (f *Filer) Mkdir(name string, perm os.FileMode) error

Mkdir creates a directory in the filesystem, return an error if any happens.

func (*Filer) OpenFile

func (f *Filer) OpenFile(name string, flag int, perm os.FileMode) (absfs.File, error)

OpenFile opens a file using the given flags and the given mode.

func (*Filer) ReadDir

func (f *Filer) ReadDir(name string) ([]fs.DirEntry, error)

func (*Filer) ReadFile

func (f *Filer) ReadFile(name string) ([]byte, error)

func (*Filer) Remove

func (f *Filer) Remove(name string) error

Remove removes a file identified by name, returning an error, if any happens.

func (*Filer) Rename

func (f *Filer) Rename(oldname, newname string) error

func (*Filer) Stat

func (f *Filer) Stat(name string) (os.FileInfo, error)

Stat returns the FileInfo structure describing file. If there is an error, it will be of type *PathError.

func (*Filer) Sub

func (f *Filer) Sub(dir string) (fs.FS, error)

type SymlinkFileSystem

type SymlinkFileSystem struct {
	// contains filtered or unexported fields
}

func (*SymlinkFileSystem) Chdir

func (f *SymlinkFileSystem) Chdir(dir string) error

func (*SymlinkFileSystem) Chmod

func (f *SymlinkFileSystem) Chmod(name string, mode os.FileMode) error

Chmod changes the mode of the named file to mode.

func (*SymlinkFileSystem) Chown

func (f *SymlinkFileSystem) Chown(name string, uid, gid int) error

Chown changes the owner and group ids of the named file

func (*SymlinkFileSystem) Chtimes

func (f *SymlinkFileSystem) Chtimes(name string, atime time.Time, mtime time.Time) error

Chtimes changes the access and modification times of the named file

func (*SymlinkFileSystem) Create

func (f *SymlinkFileSystem) Create(name string) (absfs.File, error)

func (*SymlinkFileSystem) Getwd

func (f *SymlinkFileSystem) Getwd() (dir string, err error)

func (*SymlinkFileSystem) Lchown

func (f *SymlinkFileSystem) Lchown(name string, uid, gid int) error

Lchown changes the numeric uid and gid of the named file. If the file is a symbolic link, it changes the uid and gid of the link itself. If there is an error, it will be of type *PathError.

On Windows, it always returns the syscall.EWINDOWS error, wrapped in *PathError.

func (*SymlinkFileSystem) Lstat

func (f *SymlinkFileSystem) Lstat(name string) (os.FileInfo, error)

Lstat returns a FileInfo describing the named file. If the file is a symbolic link, the returned FileInfo describes the symbolic link. Lstat makes no attempt to follow the link. If there is an error, it will be of type *PathError.

func (*SymlinkFileSystem) Mkdir

func (f *SymlinkFileSystem) Mkdir(name string, perm os.FileMode) error

Mkdir creates a directory in the filesystem, return an error if any happens.

func (*SymlinkFileSystem) MkdirAll

func (f *SymlinkFileSystem) MkdirAll(name string, perm os.FileMode) error

func (*SymlinkFileSystem) Open

func (f *SymlinkFileSystem) Open(name string) (absfs.File, error)

func (*SymlinkFileSystem) OpenFile

func (f *SymlinkFileSystem) OpenFile(name string, flag int, perm os.FileMode) (absfs.File, error)

OpenFile opens a file using the given flags and the given mode.

func (*SymlinkFileSystem) ReadDir

func (f *SymlinkFileSystem) ReadDir(name string) ([]fs.DirEntry, error)

func (*SymlinkFileSystem) ReadFile

func (f *SymlinkFileSystem) ReadFile(name string) ([]byte, error)
func (f *SymlinkFileSystem) Readlink(name string) (string, error)

Readlink returns the destination of the named symbolic link. If there is an error, it will be of type *PathError.

func (*SymlinkFileSystem) Remove

func (f *SymlinkFileSystem) Remove(name string) error

Remove removes a file identified by name, returning an error, if any happens.

func (*SymlinkFileSystem) RemoveAll

func (f *SymlinkFileSystem) RemoveAll(path string) (err error)

func (*SymlinkFileSystem) Rename

func (f *SymlinkFileSystem) Rename(oldname, newname string) error

func (*SymlinkFileSystem) Stat

func (f *SymlinkFileSystem) Stat(name string) (os.FileInfo, error)

Stat returns the FileInfo structure describing file. If there is an error, it will be of type *PathError.

func (*SymlinkFileSystem) Sub

func (f *SymlinkFileSystem) Sub(dir string) (fs.FS, error)
func (f *SymlinkFileSystem) Symlink(oldname, newname string) error

Symlink creates newname as a symbolic link to oldname. If there is an error, it will be of type *LinkError.

func (*SymlinkFileSystem) TempDir

func (f *SymlinkFileSystem) TempDir() string

func (*SymlinkFileSystem) Truncate

func (f *SymlinkFileSystem) Truncate(name string, size int64) error

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL