vfs

package module
v0.1.1 Latest Latest
Warning

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

Go to latest
Published: Nov 27, 2018 License: MIT Imports: 6 Imported by: 53

README

go-vfs

Build Status GoDoc Report Card

Package go-vfs provides an abstraction of the os and ioutil packages that is easy to test.

Key features

  • File system abstraction layer for commonly-used os and ioutil functions from the standard library.

  • Powerful testing framework, vfst. For a quick tour of vfst's features, see the examples in the documentation.

Quick start

go-vfs provides implementations of the FS interface:

// An FS is an abstraction over commonly-used functions in the os and ioutil
// packages.
type FS interface {
    Chmod(name string, mode os.FileMode) error
    Lstat(name string) (os.FileInfo, error)
    Mkdir(name string, perm os.FileMode) error
    ReadDir(dirname string) ([]os.FileInfo, error)
    ReadFile(filename string) ([]byte, error)
    Readlink(name string) (string, error)
    Remove(name string) error
    RemoveAll(name string) error
    Stat(name string) (os.FileInfo, error)
    Symlink(oldname, newname string) error
    WriteFile(filename string, data []byte, perm os.FileMode) error
}

To use go-vfs, you write your code to use the FS interface, and then use vfst to test it.

go-vfs also provides functions MkdirAll (equivalent to os.MkdirAll) and Walk (equivalent to filepath.Walk) that operate on an FS.

The implementations of FS provided are:

  • OSFS which calls the underlying os and ioutil functions directly.

  • PathFS which transforms all paths to provide a poor-man's chroot.

  • ReadOnlyFS which prevents modification of the underlying FS.

PathFS is used by vfst.NewTestFS which assists running tests on a real filesystem but in a temporary directory that is easily cleaned up.

// writeConfigFile is the function we're going to test. It can make arbitrary
changes to the filesystem through fs.
func writeConfigFile(fs vfs.FS) error {
    return fs.WriteFile("/home/user/app.conf", []byte(`app config`), 0644)
}

// TestWriteConfigFile is our test function.
func TestWriteConfigFile(t *testing.T) {
    // Create and populate an temporary directory with a home directory.
    fs, cleanup, err := vfst.NewTestFS(map[string]string{
        "/home/user/.bashrc": "# contents of user's .bashrc\n",
    })

    // Ensure that the temporary directory is removed.
    defer cleanup()

    // Check that the directory was populated successfully.
    if err != nil {
        t.Fatalf("vfsTest.NewTestFS(_) == _, _, %v, want _, _, <nil>", err)
    }

    // Call the function we want to test.
    if err := writeConfigFile(fs); err != nil {
        t.Error(err)
    }

    // Check properties of the filesystem after our function has modified it.
    vfst.RunTest(t, fs, "",
        vfst.PathTest("/home/user/app.conf",
            vfst.TestModeIsRegular,
            vfst.TestModePerm(0644),
            vfst.TestContentsString("app config"))),
}

Motivation

go-vfs was inspired by github.com/spf13/afero and github.com/twpayne/aferot. So, why not use these?

  • afero has several critical bugs in its in-memory mock filesystem implementation MemMapFs, to the point that it is unusable for non-trivial test cases. vfs does not attempt to implent an in-memory mock filesystem, and instead only provides a thin layer around the standard libary's os and ioutil packages, and as such should have fewer bugs.

  • afero does not support creating or reading symbolic links, and its LstatIfPossible interface is clumsy to use as it is not part of the afero.Fs interface. vfs provides out-of-the-box support for symbolic links with all methods in the vfs.FS interface.

  • afero has been effectively abandoned by its author, and a "friendly fork" (github.com/absfs/afero) has not seen much activity. vfs, by providing much less functionality than afero, should be smaller and easier to maintain.

License

The MIT License (MIT)

Copyright (c) 2018 Tom Payne

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

Documentation

Index

Constants

This section is empty.

Variables

View Source
var OSFS = &osfs{}

OSFS is the FS that calls os and ioutil functions directly.

Functions

func MkdirAll

func MkdirAll(fs FS, path string, perm os.FileMode) error

MkdirAll is equivalent to os.MkdirAll but operates on fs.

func Walk

func Walk(fs FS, path string, walkFn filepath.WalkFunc) error

Walk is the equivalent of filepath.Walk but operates on fs.

Types

type FS

type FS interface {
	Chmod(name string, mode os.FileMode) error
	Lstat(name string) (os.FileInfo, error)
	Mkdir(name string, perm os.FileMode) error
	ReadDir(dirname string) ([]os.FileInfo, error)
	ReadFile(filename string) ([]byte, error)
	Readlink(name string) (string, error)
	Remove(name string) error
	RemoveAll(name string) error
	Stat(name string) (os.FileInfo, error)
	Symlink(oldname, newname string) error
	WriteFile(filename string, data []byte, perm os.FileMode) error
}

An FS is an abstraction over commonly-used functions in the os and ioutil packages.

type PathFS

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

A PathFS operates on an existing FS, but prefixes all names with a path.

func NewPathFS

func NewPathFS(fs FS, path string) *PathFS

NewPathFS returns a new *PathFS operating on fs and prefixing all names with path.

func (*PathFS) Chmod

func (p *PathFS) Chmod(name string, mode os.FileMode) error

Chmod implements os.Chmod.

func (*PathFS) Join

func (p *PathFS) Join(name string) string

Join returns p's path joined with name.

func (*PathFS) Lstat

func (p *PathFS) Lstat(name string) (os.FileInfo, error)

Lstat implements os.Lstat.

func (*PathFS) Mkdir

func (p *PathFS) Mkdir(name string, perm os.FileMode) error

Mkdir implements os.Mkdir.

func (*PathFS) ReadDir

func (p *PathFS) ReadDir(dirname string) ([]os.FileInfo, error)

ReadDir implenents ioutil.ReadDir.

func (*PathFS) ReadFile

func (p *PathFS) ReadFile(filename string) ([]byte, error)

ReadFile implements ioutil.ReadFile.

func (p *PathFS) Readlink(name string) (string, error)

Readlink implments os.Readlink.

func (*PathFS) Remove

func (p *PathFS) Remove(name string) error

Remove implements os.Remove.

func (*PathFS) RemoveAll

func (p *PathFS) RemoveAll(name string) error

RemoveAll implements os.RemoveAll.

func (*PathFS) Stat

func (p *PathFS) Stat(name string) (os.FileInfo, error)

Stat implements os.Stat.

func (p *PathFS) Symlink(oldname, newname string) error

Symlink implements os.Symlink.

func (*PathFS) WriteFile

func (p *PathFS) WriteFile(filename string, data []byte, perm os.FileMode) error

WriteFile implements ioutil.WriteFile.

type ReadOnlyFS

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

A ReadOnlyFS operates on an existing FS, but any methods that modify the FS return an error.

func NewReadOnlyFS

func NewReadOnlyFS(fs FS) *ReadOnlyFS

NewReadOnlyFS returns a new *ReadOnlyFS operating on fs.

func (*ReadOnlyFS) Chmod

func (r *ReadOnlyFS) Chmod(name string, mode os.FileMode) error

Chmod implements os.Chmod.

func (*ReadOnlyFS) Lstat

func (r *ReadOnlyFS) Lstat(name string) (os.FileInfo, error)

Lstat implements os.Lstat.

func (*ReadOnlyFS) Mkdir

func (r *ReadOnlyFS) Mkdir(name string, perm os.FileMode) error

Mkdir implements os.Mkdir.

func (*ReadOnlyFS) ReadDir

func (r *ReadOnlyFS) ReadDir(dirname string) ([]os.FileInfo, error)

ReadDir implenents ioutil.ReadDir.

func (*ReadOnlyFS) ReadFile

func (r *ReadOnlyFS) ReadFile(filename string) ([]byte, error)

ReadFile implements ioutil.ReadFile.

func (r *ReadOnlyFS) Readlink(name string) (string, error)

Readlink implments os.Readlink.

func (*ReadOnlyFS) Remove

func (r *ReadOnlyFS) Remove(name string) error

Remove implements os.Remove.

func (*ReadOnlyFS) RemoveAll

func (r *ReadOnlyFS) RemoveAll(name string) error

RemoveAll implements os.RemoveAll.

func (*ReadOnlyFS) Stat

func (r *ReadOnlyFS) Stat(name string) (os.FileInfo, error)

Stat implements os.Stat.

func (r *ReadOnlyFS) Symlink(oldname, newname string) error

Symlink implements os.Symlink.

func (*ReadOnlyFS) WriteFile

func (r *ReadOnlyFS) WriteFile(filename string, data []byte, perm os.FileMode) error

WriteFile implements ioutil.WriteFile.

Directories

Path Synopsis
Package vfst provides helper functions for testing code that uses github.com/twpayne/go-vfs.
Package vfst provides helper functions for testing code that uses github.com/twpayne/go-vfs.

Jump to

Keyboard shortcuts

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