fs

package module
v0.20.2 Latest Latest
Warning

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

Go to latest
Published: Dec 14, 2022 License: Apache-2.0 Imports: 10 Imported by: 11

README

File System Utilities in Go 1.18+

GoDoc License Go Report Card

Why no file locking?

See https://github.com/rwxrob/fs/issues/2

Documentation

Index

Examples

Constants

This section is empty.

Variables

View Source
var (
	ExtractFilePerms = _fs.FileMode(0600)
	ExtractDirPerms  = _fs.FileMode(0700)
)

Functions

func DupPerms added in v0.1.2

func DupPerms(orig, clone string) error

DupPerms duplicates the perms of one file or directory onto the second.

func Exists added in v0.3.0

func Exists(path string) bool

Exists returns true if the given path was absolutely found to exist on the system. A false return value means either the file does not exists or it was not able to determine if it exists or not. Use NotExists instead.

WARNING: do not use this function if a definitive check for the non-existence of a file is required since the possible indeterminate error state is a possibility. These checks are also not atomic on many file systems so avoid this usage for pseudo-semaphore designs and depend on file locks.

Example
package main

import (
	"fmt"

	"github.com/rwxrob/fs"
)

func main() {
	fmt.Println(fs.Exists("testdata/file")) // use NotExists instead of !
}
Output:

false

func ExtractEmbed added in v0.6.0

func ExtractEmbed(it embed.FS, root, target string) error

ExtractEmbed walks the embedded file system and duplicates its structure into the target directory beginning with root. Since embed.FS drops all permissions information from the original files all files and directories are written as read/write (0600) for the current effective user (0600 for file, 0700 for directories). This default can be changed by setting the package variables ExtractFilePerms and ExtractDirPerms. Note that each embedded file is full buffered into memory before writing.

Example
package main

import (
	"embed"
	"fmt"
	"os"
	"path/filepath"

	"github.com/rwxrob/fs"
)

//go:embed all:testdata/testfs
var testfs embed.FS

func main() {

	// go:embed all:testdata/testfs
	// var testfs embed.FS
	defer os.RemoveAll("testdata/testfsout")

	if err := fs.ExtractEmbed(testfs,
		"testdata/testfs", "testdata/testfsout"); err != nil {
		fmt.Println(err)
	}

	stuff := []string{
		`foo`,
		`_notignored`,
		`.secret`,
		`dir`,
		`dir/README.md`,
	}

	for _, i := range stuff {
		f, err := os.Stat(filepath.Join("testdata/testfsout", i))
		if err != nil {
			fmt.Println(err)
			continue
		}
		fmt.Printf("%v %v\n", i, f.Mode())
	}

}
Output:

foo -rw-------
_notignored -rw-------
.secret -rw-------
dir drwx------
dir/README.md -rw-------
Example (Confirm_Default_Read)
package main

import (
	"embed"
	"fmt"
)

//go:embed all:testdata/testfs
var testfs embed.FS

func main() {

	// go:embed all:testdata/testfs
	// var testfs embed.FS

	foo, err := testfs.Open("testdata/testfs/foo")
	if err != nil {
		fmt.Println(err)
	}
	info, err := foo.Stat()
	if err != nil {
		fmt.Println(err)
	}
	fmt.Println(info.Mode())

}
Output:

-r--r--r--

func HereOrAbove added in v0.5.2

func HereOrAbove(name string) (string, error)

HereOrAbove returns the full path to the file or directory if it is found in the current working directory, or if not exists in any parent directory recursively. Returns ErrNotExist error with the name if not found.

Example (Above)
package main

import (
	"fmt"
	"os"
	"path/filepath"
	"strings"

	"github.com/rwxrob/fs"
)

func main() {
	dir, _ := os.Getwd()
	defer func() { os.Chdir(dir) }()
	os.Chdir("testdata/adir")

	path, err := fs.HereOrAbove("anotherfile")
	if err != nil {
		fmt.Println(err)
	}
	d := strings.Split(path, string(filepath.Separator))
	fmt.Println(d[len(d)-2:])

}
Output:

[testdata anotherfile]
Example (Here)
package main

import (
	"fmt"
	"os"
	"path/filepath"
	"strings"

	"github.com/rwxrob/fs"
)

func main() {
	dir, _ := os.Getwd()
	defer func() { os.Chdir(dir) }()
	os.Chdir("testdata/adir")

	path, err := fs.HereOrAbove("afile")
	if err != nil {
		fmt.Println(err)
	}
	d := strings.Split(path, string(filepath.Separator))
	fmt.Println(d[len(d)-2:])

}
Output:

[adir afile]

func IsDir

func IsDir(path string) bool

IsDir returns true if the indicated path is a directory. Returns false and logs if unable to determine.

func IsDirFS added in v0.6.0

func IsDirFS(fsys _fs.FS, path string) bool

IsDirFS simply a shortcut for fs.Stat().IsDir(). Only returns true if the path is a directory. If not a directory (or an error prevented confirming it is a directory) then returns false.

func Isosec added in v0.18.0

func Isosec() string

Isosec returns the GMT current time in ISO8601 (RFC3339) without any punctuation or the T. This is frequently a very good unique suffix that has the added advantage of being chronologically sortable and more readable than the epoch. (Also see Second())

func LatestChange added in v0.9.0

func LatestChange(root string) (string, fs.FileInfo)

LatestChange walks the directory rooted at root looking at each file or directory within it recursively (including itself) and returns the time of the most recent change along with its full path. LastChange returns nil FileInfo and empty string if root is not a directory.

func ModTime added in v0.3.0

func ModTime(path string) time.Time

ModTime returns the FileInfo.ModTime() from Stat() as a convenience or returns a zero time if not. See time.IsZero.

Example
package main

import (
	"fmt"

	"github.com/rwxrob/fs"
)

func main() {
	fmt.Println(fs.ModTime("testdata/file").IsZero())
	fmt.Println(fs.ModTime("testdata/none"))
}
Output:

true
0001-01-01 00:00:00 +0000 UTC

func NameIsInt added in v0.17.1

func NameIsInt(path string) bool

NameIsInt returns true if the filepath.Base name of the passed path is a valid positive integer (including 0).

Example
package main

import (
	"fmt"

	"github.com/rwxrob/fs"
)

func main() {
	fmt.Println(fs.NameIsInt(`/some/1`))
	fmt.Println(fs.NameIsInt(`100`))
	fmt.Println(fs.NameIsInt(`-100`))
	fmt.Println(fs.NameIsInt(`/some/-1`))
	fmt.Println(fs.NameIsInt(`/some/`))
}
Output:

true
true
false
false
false

func NotExists added in v0.3.0

func NotExists(path string) bool

NotExists definitively returns true if the given path does not exist. See Exists as well.

Example
package main

import (
	"fmt"

	"github.com/rwxrob/fs"
)

func main() {
	fmt.Println(fs.NotExists("testdata/nope")) // use Exists instead of !
}
Output:

true

func Preserve added in v0.15.0

func Preserve(target string) (string, error)

Preserve moves the target to a new name with an "~" isosec suffix usually in anticipation of eventual deletion or restoration for transactionally safe dealings with directories and files. Returns the name of the new file or directory. Does *not* return an error if the target doesn't exist (since there is nothing to preserve) and returns an empty string. Pair this with defer RevertIfMissing to provide transactional backups of files and directories.

func RelPaths added in v0.8.0

func RelPaths(it fs.FS, root string) []string

Paths returns a list of full paths to each of the directories or files from the root but with the path to the root stripped resulting in relative paths.

func RevertIfMissing added in v0.16.1

func RevertIfMissing(target, backup string) error

RevertIfMissing is designed to be called from defer after calling a Preserve and storing the backup path to a variable. If the target is missing, backup is renamed back to the target. If the target is *not* missing, backup is removed. If the backup is an empty string no backup restoration is assumed and a nil error is returned with no action. This allows the output of Preserve to be passed directly to RevertIfMissing without complicating the defer.

func Tilde2Home added in v0.7.0

func Tilde2Home(dir string) string

Tilde2Home expands a Tilde (~) prefix into a proper os.UserHomeDir path. If it cannot find os.UserHomeDir simple returns unchanged path. Will not expand for specific users (~username).

Types

type ErrExist added in v0.15.0

type ErrExist struct {
	N string
}

func (ErrExist) Error added in v0.15.0

func (e ErrExist) Error() string

type ErrNotExist added in v0.14.1

type ErrNotExist struct {
	N string
}

func (ErrNotExist) Error added in v0.14.1

func (e ErrNotExist) Error() string

type ErrorExists added in v0.9.0

type ErrorExists struct {
	P string
}

func (ErrorExists) Error added in v0.9.0

func (e ErrorExists) Error() string

type PathEntry added in v0.10.0

type PathEntry struct {
	Path string
	Info fs.FileInfo
}

PathEntry contains the fully qualified path to a DirEntry and the returned FileInfo for that specific path. PathEntry saves the work of fetching this information a second time when functions in this package have already retrieved it.

func IntDirs added in v0.10.0

func IntDirs(target string) (paths []PathEntry, low, high int)

IntDirs returns all the directory entries within the target directory that have integer names. The lowest integer and highest integer values are also returned. Only positive integers are checked. This is useful when using directory names as database-friendly unique primary keys for other file system content.

IntDirs returns an empty slice and -1 values if no matches are found.

Errors looking up the FileInfo cause Info to be nil.

Example
package main

import (
	"fmt"
	"path/filepath"

	"github.com/rwxrob/fs"
)

func main() {

	dirs, low, high := fs.IntDirs("testdata/ints")

	fmt.Println(low)
	fmt.Println(high)

	for _, d := range dirs {
		fmt.Printf("%v ", filepath.Base(d.Path))
	}

}
Output:

2
10
10 2 3 4 5 6 7 8 9

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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