pathlib

package module
v0.19.1 Latest Latest
Warning

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

Go to latest
Published: Dec 19, 2023 License: Apache-2.0 Imports: 9 Imported by: 14

README

pathlib

Build Status go.dev reference GitHub release (latest by date) codecov GitHub go.mod Go version License

Inspired by Python's pathlib, made better by Go.

pathlib is an "object-oriented" package for manipulating filesystem path objects. It takes many cues from Python's pathlib, although it does not strictly adhere to its design philosophy. It provides a simple, intuitive, easy, and abstracted interface for dealing with many different types of filesystems.

pathlib is currently in the beta stage of development. The API is not guaranteed to be solidified, however changes will be as minimal as possible.

Table of Contents

Examples

OsFs

Beacuse pathlib treats afero filesystems as first-class citizens, you can instantiate a Path object with the filesystem of your choosing.

Code
package main

import (
	"fmt"
	"os"

	"github.com/chigopher/pathlib"
	"github.com/spf13/afero"
)

func main() {
	// Create a path on your regular OS filesystem
	path := pathlib.NewPathAfero("/home/ltclipp", afero.NewOsFs())

	subdirs, err := path.ReadDir()
	if err != nil {
		fmt.Printf("%v\n", err)
		os.Exit(1)
	}

	for _, dir := range subdirs {
		fmt.Println(dir.Name())
	}
}
Output
[ltclipp@landon-virtualbox examples]$ go build .
[ltclipp@landon-virtualbox examples]$ ./examples | tail
Music
Pictures
Public
Templates
Videos
git
go
mockery_test
snap
software
In-memory FS
Code
package main

import (
	"fmt"
	"os"

	"github.com/chigopher/pathlib"
	"github.com/spf13/afero"
)

func main() {
	// Create a path using an in-memory filesystem
	path := pathlib.NewPathAfero("/", afero.NewMemMapFs())
	hello := path.Join("hello_world.txt")
	hello.WriteFile([]byte("hello world!"), 0o644)

	subpaths, err := path.ReadDir()
	if err != nil {
		fmt.Printf("%v\n", err)
		os.Exit(1)
	}

	for _, subpath := range subpaths {
		fmt.Printf("Name: %s Mode: %o Size: %d\n", subpath.Name(), subpath.Mode(), subpath.Size())
	}

	bytes, _ := hello.ReadFile()
	fmt.Println(string(bytes))
}
Output
[ltclipp@landon-virtualbox examples]$ go build
[ltclipp@landon-virtualbox examples]$ ./examples 
Name: hello_world.txt Mode: 644 Size: 12
hello world!

Design Philosophy

The design philosophy of this package is to be as thin of a layer as possible to existing community-standard packages, like io, afero, and os. Additional functionality is provided in consise and logical ways to extend the existing community APIs.

filepath.Path

The API of filepath.Path can be grouped into a few main categories:

  1. github.com/spf13/afero.Fs wrappers: these are methods that have nearly identical signatures to afero.Fs, with the exception of the path string (which is stored in the pathlib.Path object itself. afero.Fs is an object that is meant to interact directly with the filesystem.
  2. github.com/spf13/afero.Afero wrappers: these are methods that again have nearly identical signatures to afero.Afero. afero.Afero is a convenience object that provides higher-level behavior to the underlying afero.Fs object.
  3. Filesystem-specific methods: these are methods that are implemented by some, but not all, of the afero filesystems. These methods may fail at runtime if the filesystem you provide does not implement the required interface.
  4. Python's Pathlib-inspired methods: these are methods that are not implemented in the previous two steps, and that provide the power behind the object-oriented design.
  5. github.com/chigopher/pathlib-specific methods: these are miscellaneous methods that are not covered by any of the previous categories. These methods are typically conveniences around methods in one of the previous categories.
filepath.File

filepath.File is intended to be a thin wrapper around afero.File. We avoid simply returning this interface on calls to Open() and OpenFile() (etc) because we want the ability to extend our API beyond what afero provides. So, we create our own File object which embeds afero.File, but might possibly contain further functionality.

Whoa whoa whoa, what is this afero nonsense?

github.com/spf13/afero is a package that provides an abstracted interface to the underlying filesystem API calls. pathlib uses this package for operating on the abstracted filesystem. This is powerful because it allows you to to use essentially any kind of filesystem that you want. Additionally, afero is a first-class-citizen in pathlib meaning that you can implement and explicitly provide your own afero object.

The basic diagram looks like this:

Pathlib Diagram

Frequently Asked Questions

Why pathlib and not filepath?

filepath is a package that is tightly coupled to the OS filesystem APIs and also is not written in an object-oriented way. pathlib uses afero under the hood for its abstracted filesystem interface, which allows you to represent a vast array of different filesystems (e.g. SFTP, HTTP, in-memory, and of course OS filesystems) using the same Path object.

Why not use afero directly?

You certainly could, however afero does not represent a filesystem object in an object-oriented way. It is only object-oriented with respect to the filesystem itself. pathlib is simply a thin layer on top of afero that provides the filesystem-object-orientation.

Does this provide any benefit to my unit tests?

Most certainly! pathlib allows you to create in-memory filesystems, which have the nice property of being automatically garbage collected by Golang's GC when they go out of scope. You don't have to worry about defering any Remove() functions or setting up temporary dirs in /tmp. Just instantiate a MemMapFs and you're good to go!

What filesystems does this support?

Currently only POSIX-style paths are supported.

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrDoesNotImplement indicates that the afero filesystem doesn't
	// implement the required interface.
	ErrDoesNotImplement = fmt.Errorf("doesn't implement required interface")
	// ErrInfoIsNil indicates that a nil os.FileInfo object was provided
	ErrInfoIsNil = fmt.Errorf("provided os.Info object was nil")
	// ErrInvalidAlgorithm specifies that an unknown algorithm was given for Walk
	ErrInvalidAlgorithm = fmt.Errorf("invalid algorithm specified")
	// ErrLstatNotPossible specifies that the filesystem does not support lstat-ing
	ErrLstatNotPossible = fmt.Errorf("lstat is not possible")
	// ErrRelativeTo indicates that we could not make one path relative to another
	ErrRelativeTo = fmt.Errorf("failed to make path relative to other")

	// ErrSkipSubtree indicates to the walk function that the current subtree of
	// directories should be skipped. It's recommended to only use this error
	// with the AlgorithmPreOrderDepthFirst algorithm, as many other walk algorithms
	// will not respect this error due to the nature of the ordering in which the
	// algorithms visit each node of the filesystem tree.
	ErrWalkSkipSubtree = fmt.Errorf("skip subtree: %w", errWalkControl)
	// ErrStopWalk indicates to the Walk function that the walk should be aborted.
	// DEPRECATED: Use ErrWalkStop
	ErrStopWalk = ErrWalkStop
	// ErrWalkStop indicates to the Walk function that the walk should be aborted.
	ErrWalkStop = fmt.Errorf("stop filesystem walk: %w", errWalkControl)
)
View Source
var DefaultDirMode = os.FileMode(0o755)

DefaultDirMode is the default mode that will be applied to new directories

View Source
var DefaultFileMode = os.FileMode(0o644)

DefaultFileMode is the file mode that will be applied to new pathlib files

Functions

func IsDir added in v0.5.0

func IsDir(mode os.FileMode) bool

IsDir returns whether or not the os.FileMode object represents a directory.

func IsFile added in v0.5.0

func IsFile(mode os.FileMode) bool

IsFile returns whether or not the file described by the given os.FileMode is a regular file.

func IsSymlink(mode os.FileMode) bool

IsSymlink returns true if the file described by the given os.FileMode describes a symlink.

func Mtime added in v0.5.0

func Mtime(fileInfo os.FileInfo) (time.Time, error)

Mtime returns the mtime described in the given os.FileInfo object

func Size added in v0.5.0

func Size(fileInfo os.FileInfo) int64

Size returns the size described by the os.FileInfo. Before you say anything, yes... you could just do fileInfo.Size(). This is purely a convenience function to create API consistency.

Types

type Algorithm added in v0.7.0

type Algorithm int

Algorithm represents the walk algorithm that will be performed.

const (
	// AlgorithmBasic is a walk algorithm. It iterates over filesystem objects in the
	// order in which they are returned by the operating system. It guarantees no
	// ordering of any kind. It will recurse into subdirectories as soon as it encounters them,
	// and will continue iterating the remaining children after the recursion is complete.
	// It behaves as a quasi-DFS algorithm.
	AlgorithmBasic Algorithm = iota
	// AlgorithmDepthFirst is a walk algorithm. More specifically, it is a post-order
	// depth first search whereby subdirectories are recursed into before
	// visiting the children of the current directory.
	// DEPRECATED: Use AlgorithmPostOrderDepthFirst
	AlgorithmDepthFirst
	// AlgorithmPostOrderDepthFirst is a walk algorithm that recurses into all of its children
	// before visiting any of a node's elements.
	AlgorithmPostOrderDepthFirst
	// AlgorithmPreOrderDepthFirst is a walk algorithm. It visits all of a node's elements
	// before recursing into its children.
	AlgorithmPreOrderDepthFirst
)

type File added in v0.3.0

type File struct {
	afero.File
}

File represents a file in the filesystem. It inherits the afero.File interface but might also include additional functionality.

type Path

type Path struct {

	// DefaultFileMode is the mode that is used when creating new files in functions
	// that do not accept os.FileMode as a parameter.
	DefaultFileMode os.FileMode
	// DefaultDirMode is the mode that will be used when creating new directories
	DefaultDirMode os.FileMode
	// Sep is the seperator used in path calculations. By default this is set to
	// os.PathSeparator.
	Sep string
	// contains filtered or unexported fields
}

Path is an object that represents a path

func Glob

func Glob(fs afero.Fs, pattern string) ([]*Path, error)

Glob returns all of the path objects matched by the given pattern inside of the afero filesystem.

func NewPath

func NewPath(path string, opts ...PathOpts) *Path

NewPath returns a new OS path

func NewPathAfero deprecated

func NewPathAfero(path string, fs afero.Fs) *Path

NewPathAfero returns a Path object with the given Afero object

Deprecated: Use the PathWithAfero option in Newpath instead.

func (*Path) Chmod

func (p *Path) Chmod(mode os.FileMode) error

Chmod changes the file mode of the given path

func (*Path) Chtimes

func (p *Path) Chtimes(atime time.Time, mtime time.Time) error

Chtimes changes the modification and access time of the given path.

func (*Path) Clean added in v0.12.0

func (p *Path) Clean() *Path

Clean returns a new object that is a lexically-cleaned version of Path.

func (*Path) Copy added in v0.16.0

func (p *Path) Copy(other *Path) (int64, error)

Copy copies the path to another path using io.Copy. Returned is the number of bytes copied and any error values. The destination file is truncated if it exists, and is created if it does not exist.

func (*Path) Create added in v0.2.0

func (p *Path) Create() (File, error)

Create creates a file if possible, returning the file and an error, if any happens.

func (*Path) DeepEquals added in v0.9.0

func (p *Path) DeepEquals(other *Path) (bool, error)

DeepEquals returns whether or not the path pointed to by other has the same resolved filepath as self.

func (*Path) DirExists added in v0.2.0

func (p *Path) DirExists() (bool, error)

DirExists returns whether or not the path represents a directory that exists

func (*Path) Equals

func (p *Path) Equals(other *Path) bool

Equals returns whether or not the object's path is identical to other's, in a shallow sense. It simply checks for equivalence in the unresolved Paths() of each object.

func (*Path) Exists

func (p *Path) Exists() (bool, error)

Exists returns whether the path exists

func (*Path) FileContainsAnyBytes added in v0.2.0

func (p *Path) FileContainsAnyBytes(subslices [][]byte) (bool, error)

FileContainsAnyBytes returns whether or not the path contains any of the listed bytes.

func (*Path) FileContainsBytes added in v0.2.0

func (p *Path) FileContainsBytes(subslice []byte) (bool, error)

FileContainsBytes returns whether or not the given file contains the bytes

func (*Path) Fs added in v0.2.0

func (p *Path) Fs() afero.Fs

Fs returns the internal afero.Fs object.

func (*Path) GetLatest

func (p *Path) GetLatest() (*Path, error)

GetLatest returns the file or directory that has the most recent mtime. Only works if this path is a directory and it exists. If the directory is empty, the returned Path object will be nil.

func (*Path) Glob

func (p *Path) Glob(pattern string) ([]*Path, error)

Glob returns all matches of pattern relative to this object's path.

func (*Path) IsAbsolute

func (p *Path) IsAbsolute() bool

IsAbsolute returns whether or not the path is an absolute path. This is determined by checking if the path starts with a slash.

func (*Path) IsDir

func (p *Path) IsDir() (bool, error)

IsDir checks if a given path is a directory.

func (*Path) IsEmpty added in v0.2.0

func (p *Path) IsEmpty() (bool, error)

IsEmpty checks if a given file or directory is empty.

func (*Path) IsFile

func (p *Path) IsFile() (bool, error)

IsFile returns true if the given path is a file.

func (p *Path) IsSymlink() (bool, error)

IsSymlink returns true if the given path is a symlink. Fails if the filesystem doesn't implement afero.Lstater.

func (*Path) Join

func (p *Path) Join(elems ...string) *Path

Join joins the current object's path with the given elements and returns the resulting Path object.

func (*Path) JoinPath added in v0.4.0

func (p *Path) JoinPath(path *Path) *Path

JoinPath is the same as Join() except it accepts a path object

func (*Path) Lstat added in v0.5.0

func (p *Path) Lstat() (os.FileInfo, error)

Lstat lstat's the path if the underlying afero filesystem supports it. If the filesystem does not support afero.Lstater, or if the filesystem implements afero.Lstater but returns false for the "lstat called" return value.

A nil os.FileInfo is returned on errors.

func (*Path) Mkdir

func (p *Path) Mkdir() error

Mkdir makes the current dir. If the parents don't exist, an error is returned.

func (*Path) MkdirAll

func (p *Path) MkdirAll() error

MkdirAll makes all of the directories up to, and including, the given path.

func (*Path) MkdirAllMode added in v0.11.0

func (p *Path) MkdirAllMode(perm os.FileMode) error

MkdirAllMode makes all of the directories up to, and including, the given path.

func (*Path) MkdirMode added in v0.11.0

func (p *Path) MkdirMode(perm os.FileMode) error

MkdirMode makes the current dir. If the parents don't exist, an error is returned.

func (*Path) Mtime added in v0.1.0

func (p *Path) Mtime() (time.Time, error)

Mtime returns the modification time of the given path.

func (*Path) Name

func (p *Path) Name() string

Name returns the string representing the final path component

func (*Path) Open added in v0.2.0

func (p *Path) Open() (*File, error)

Open opens a file for read-only, returning it or an error, if any happens.

func (*Path) OpenFile added in v0.2.0

func (p *Path) OpenFile(flag int) (*File, error)

OpenFile opens a file using the given flags. See the list of flags at: https://golang.org/pkg/os/#pkg-constants

func (*Path) OpenFileMode added in v0.12.0

func (p *Path) OpenFileMode(flag int, perm os.FileMode) (*File, error)

OpenFileMode opens a file using the given flags and the given mode. See the list of flags at: https://golang.org/pkg/os/#pkg-constants

func (*Path) Parent

func (p *Path) Parent() *Path

Parent returns the Path object of the parent directory

func (*Path) Parts added in v0.4.0

func (p *Path) Parts() []string

Parts returns the individual components of a path

func (*Path) ReadDir

func (p *Path) ReadDir() ([]*Path, error)

ReadDir reads the current path and returns a list of the corresponding Path objects. This function differs from os.Readdir in that it does not call Stat() on the files. Instead, it calls Readdirnames which is less expensive and does not force the caller to make expensive Stat calls.

func (*Path) ReadFile

func (p *Path) ReadFile() ([]byte, error)

ReadFile reads the given path and returns the data. If the file doesn't exist or is a directory, an error is returned.

func (p *Path) Readlink() (*Path, error)

Readlink returns the target path of a symlink.

This will fail if the underlying afero filesystem does not implement afero.LinkReader.

func (*Path) RelativeTo

func (p *Path) RelativeTo(other *Path) (*Path, error)

RelativeTo computes a relative version of path to the other path. For instance, if the object is /path/to/foo.txt and you provide /path/ as the argment, the returned Path object will represent to/foo.txt.

func (*Path) RelativeToStr added in v0.12.0

func (p *Path) RelativeToStr(other string) (*Path, error)

RelativeToStr computes a relative version of path to the other path. For instance, if the object is /path/to/foo.txt and you provide /path/ as the argment, the returned Path object will represent to/foo.txt.

func (*Path) Remove

func (p *Path) Remove() error

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

func (*Path) RemoveAll

func (p *Path) RemoveAll() error

RemoveAll removes the given path and all of its children.

func (*Path) Rename

func (p *Path) Rename(target *Path) error

Rename renames a file

func (*Path) RenameStr added in v0.12.0

func (p *Path) RenameStr(newname string) error

RenameStr renames a file

func (*Path) ResolveAll added in v0.4.0

func (p *Path) ResolveAll() (*Path, error)

ResolveAll canonicalizes the path by following every symlink in every component of the given path recursively. The behavior should be identical to the `readlink -f` command from POSIX OSs. This will fail if the underlying afero filesystem does not implement afero.LinkReader. The path will be returned unchanged on errors.

func (*Path) SafeWriteReader added in v0.2.0

func (p *Path) SafeWriteReader(r io.Reader) error

SafeWriteReader is the same as WriteReader but checks to see if file/directory already exists.

func (*Path) Size added in v0.5.0

func (p *Path) Size() (int64, error)

Size returns the size of the object. Fails if the object doesn't exist.

func (*Path) Stat

func (p *Path) Stat() (os.FileInfo, error)

Stat returns the os.FileInfo of the given path

func (*Path) String added in v0.4.0

func (p *Path) String() string

String returns the string representation of the path

func (p *Path) Symlink(target *Path) error

Symlink symlinks to the target location. This will fail if the underlying afero filesystem does not implement afero.Linker.

func (*Path) SymlinkStr added in v0.12.0

func (p *Path) SymlinkStr(target string) error

SymlinkStr symlinks to the target location. This will fail if the underlying afero filesystem does not implement afero.Linker.

func (*Path) WriteFile

func (p *Path) WriteFile(data []byte) error

WriteFile writes the given data to the path (if possible). If the file exists, the file is truncated. If the file is a directory, or the path doesn't exist, an error is returned.

func (*Path) WriteFileMode added in v0.12.0

func (p *Path) WriteFileMode(data []byte, perm os.FileMode) error

WriteFileMode writes the given data to the path (if possible). If the file exists, the file is truncated. If the file is a directory, or the path doesn't exist, an error is returned.

func (*Path) WriteReader added in v0.2.0

func (p *Path) WriteReader(r io.Reader) error

WriteReader takes a reader and writes the content

type PathOpts added in v0.17.0

type PathOpts func(p *Path)

func PathWithAfero added in v0.17.0

func PathWithAfero(fs afero.Fs) PathOpts

func PathWithSeperator added in v0.17.0

func PathWithSeperator(sep string) PathOpts

type Walk added in v0.6.0

type Walk struct {
	Opts *WalkOpts
	// contains filtered or unexported fields
}

Walk is an object that handles walking through a directory tree

func NewWalk added in v0.6.0

func NewWalk(root *Path, opts ...WalkOptsFunc) (*Walk, error)

NewWalk returns a new Walk struct with default values applied

func NewWalkWithOpts added in v0.6.0

func NewWalkWithOpts(root *Path, opts *WalkOpts) (*Walk, error)

NewWalkWithOpts returns a Walk object with the given WalkOpts applied

func (*Walk) Walk added in v0.6.0

func (w *Walk) Walk(walkFn WalkFunc) error

Walk walks the directory using the algorithm specified in the configuration. Your WalkFunc may return any of the ErrWalk* errors to control various behavior of the walker. See the documentation of each error for more details.

type WalkFunc added in v0.6.0

type WalkFunc func(path *Path, info os.FileInfo, err error) error

WalkFunc is the function provided to the Walk function for each directory.

type WalkOpts added in v0.6.0

type WalkOpts struct {
	// Depth defines how far down a directory we should recurse. A value of -1 means
	// infinite depth. 0 means only the direct children of root will be returned, etc.
	Depth int

	// Algorithm specifies the algoritm that the Walk() function should use to
	// traverse the directory.
	Algorithm Algorithm

	// FollowSymlinks defines whether symlinks should be dereferenced or not. If True,
	// the symlink itself will never be returned to WalkFunc, but rather whatever it
	// points to.
	FollowSymlinks bool

	// MinimumFileSize specifies the minimum size of a file for visitation.
	// If negative, there is no minimum size.
	MinimumFileSize int64

	// MaximumFileSize specifies the maximum size of a file for visitation.
	// If negative, there is no maximum size.
	MaximumFileSize int64

	// VisitFiles specifies that we should visit regular files during
	// the walk.
	VisitFiles bool

	// VisitDirs specifies that we should visit directories during the walk.
	VisitDirs bool

	// VisitSymlinks specifies that we should visit symlinks during the walk.
	VisitSymlinks bool

	// SortChildren causes all children of a path to be lexigraphically sorted before
	// being sent to the WalkFunc.
	SortChildren bool
}

WalkOpts is the struct that defines how a walk should be performed

func DefaultWalkOpts added in v0.6.0

func DefaultWalkOpts() *WalkOpts

DefaultWalkOpts returns the default WalkOpts struct used when walking a directory.

func (*WalkOpts) MeetsMaximumSize added in v0.8.0

func (w *WalkOpts) MeetsMaximumSize(size int64) bool

MeetsMaximumSize returns whether size is less than or equal to the maximum specified.

func (*WalkOpts) MeetsMinimumSize added in v0.8.0

func (w *WalkOpts) MeetsMinimumSize(size int64) bool

MeetsMinimumSize returns whether size is at least the minimum specified.

type WalkOptsFunc added in v0.13.0

type WalkOptsFunc func(config *WalkOpts)

func WalkAlgorithm added in v0.13.0

func WalkAlgorithm(algo Algorithm) WalkOptsFunc

func WalkDepth added in v0.13.0

func WalkDepth(depth int) WalkOptsFunc
func WalkFollowSymlinks(follow bool) WalkOptsFunc

func WalkMaximumFileSize added in v0.13.0

func WalkMaximumFileSize(size int64) WalkOptsFunc

func WalkMinimumFileSize added in v0.13.0

func WalkMinimumFileSize(size int64) WalkOptsFunc

func WalkSortChildren added in v0.18.0

func WalkSortChildren(value bool) WalkOptsFunc

func WalkVisitDirs added in v0.13.0

func WalkVisitDirs(value bool) WalkOptsFunc

func WalkVisitFiles added in v0.13.0

func WalkVisitFiles(value bool) WalkOptsFunc
func WalkVisitSymlinks(value bool) WalkOptsFunc

Jump to

Keyboard shortcuts

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