Introduce ErrNotExist and ErrExist in io/fs package

This commit is contained in:
Ingo Oppermann
2023-07-19 16:42:30 +02:00
parent a03b38c4a6
commit bdcf4bdeb4
6 changed files with 44 additions and 40 deletions

View File

@@ -203,7 +203,7 @@ func NewRootedDiskFilesystem(config RootedDiskConfig) (Filesystem, error) {
info, err := os.Stat(fs.root) info, err := os.Stat(fs.root)
if err != nil { if err != nil {
return nil, os.ErrNotExist return nil, ErrNotExist
} }
if !info.IsDir() { if !info.IsDir() {
@@ -285,7 +285,7 @@ func (fs *diskFilesystem) Symlink(oldname, newname string) error {
info, err := os.Lstat(oldname) info, err := os.Lstat(oldname)
if err != nil { if err != nil {
return os.ErrNotExist return ErrNotExist
} }
if info.Mode()&os.ModeSymlink != 0 { if info.Mode()&os.ModeSymlink != 0 {
@@ -494,7 +494,7 @@ func (fs *diskFilesystem) Stat(path string) (FileInfo, error) {
info, err := os.Lstat(path) info, err := os.Lstat(path)
if err != nil { if err != nil {
return nil, os.ErrNotExist return nil, ErrNotExist
} }
dif.mode = info.Mode() dif.mode = info.Mode()
@@ -502,7 +502,7 @@ func (fs *diskFilesystem) Stat(path string) (FileInfo, error) {
if info.Mode()&os.ModeSymlink != 0 { if info.Mode()&os.ModeSymlink != 0 {
info, err = os.Stat(path) info, err = os.Stat(path)
if err != nil { if err != nil {
return nil, os.ErrNotExist return nil, ErrNotExist
} }
} }
@@ -674,7 +674,7 @@ func (fs *diskFilesystem) LookPath(file string) (string, error) {
if err == nil { if err == nil {
return file, nil return file, nil
} }
return "", os.ErrNotExist return "", ErrNotExist
} }
path := os.Getenv("PATH") path := os.Getenv("PATH")
for _, dir := range filepath.SplitList(path) { for _, dir := range filepath.SplitList(path) {
@@ -686,12 +686,12 @@ func (fs *diskFilesystem) LookPath(file string) (string, error) {
path = fs.cleanPath(path) path = fs.cleanPath(path)
if err := fs.findExecutable(path); err == nil { if err := fs.findExecutable(path); err == nil {
if !filepath.IsAbs(path) { if !filepath.IsAbs(path) {
return path, os.ErrNotExist return path, ErrNotExist
} }
return path, nil return path, nil
} }
} }
return "", os.ErrNotExist return "", ErrNotExist
} }
func (fs *diskFilesystem) findExecutable(file string) error { func (fs *diskFilesystem) findExecutable(file string) error {

View File

@@ -2,12 +2,16 @@
package fs package fs
import ( import (
"errors"
"io" "io"
"io/fs" "io/fs"
"os" "os"
"time" "time"
) )
var ErrExist = errors.New("file or directory already exists")
var ErrNotExist = errors.New("file or directory does not exist")
// FileInfo describes a file and is returned by Stat. // FileInfo describes a file and is returned by Stat.
type FileInfo interface { type FileInfo interface {
// Name returns the full name of the file. // Name returns the full name of the file.
@@ -67,9 +71,9 @@ type ReadFilesystem interface {
// the number of bytes read or an error. // the number of bytes read or an error.
ReadFile(path string) ([]byte, error) ReadFile(path string) ([]byte, error)
// Stat returns info about the file at path. If the file doesn't exist, an error // Stat returns info about the file at path. If the file doesn't exist, the error
// will be returned. If the file is a symlink, the info reports the name and mode // ErrNotExist will be returned. If the file is a symlink, the info reports the name
// of the link itself, but the modification time and size are of the linked file. // and mode of the link itself, but the modification time and size are of the linked file.
Stat(path string) (FileInfo, error) Stat(path string) (FileInfo, error)
// List lists all files that are currently on the filesystem. // List lists all files that are currently on the filesystem.
@@ -78,12 +82,13 @@ type ReadFilesystem interface {
// LookPath searches for an executable named file in the directories named by the PATH environment // LookPath searches for an executable named file in the directories named by the PATH environment
// variable. If file contains a slash, it is tried directly and the PATH is not consulted. Otherwise, // variable. If file contains a slash, it is tried directly and the PATH is not consulted. Otherwise,
// on success, the result is an absolute path. On non-disk filesystems. Only the mere existence // on success, the result is an absolute path. On non-disk filesystems. Only the mere existence
// of that file is verfied. // of that file is verfied. In case the file is not found, the error ErrNotExist will be returned.
LookPath(file string) (string, error) LookPath(file string) (string, error)
} }
type WriteFilesystem interface { type WriteFilesystem interface {
// Symlink creates newname as a symbolic link to oldname. // Symlink creates newname as a symbolic link to oldname. Return ErrNotExist if oldname doesn't exist.
// If newname already exists, ErrExits will be returned.
Symlink(oldname, newname string) error Symlink(oldname, newname string) error
// WriteFileReader adds a file to the filesystem. Returns the size of the data that has been // WriteFileReader adds a file to the filesystem. Returns the size of the data that has been
@@ -105,6 +110,7 @@ type WriteFilesystem interface {
// MkdirAll creates a directory named path, along with any necessary parents, and returns nil, // MkdirAll creates a directory named path, along with any necessary parents, and returns nil,
// or else returns an error. The permission bits perm (before umask) are used for all directories // or else returns an error. The permission bits perm (before umask) are used for all directories
// that MkdirAll creates. If path is already a directory, MkdirAll does nothing and returns nil. // that MkdirAll creates. If path is already a directory, MkdirAll does nothing and returns nil.
// If the path already exists and is a regular file, ErrExists will be returned.
MkdirAll(path string, perm os.FileMode) error MkdirAll(path string, perm os.FileMode) error
// Rename renames the file from src to dst. If src and dst can't be renamed // Rename renames the file from src to dst. If src and dst can't be renamed

View File

@@ -289,13 +289,13 @@ func (fs *memFilesystem) ReadFile(path string) ([]byte, error) {
fs.filesLock.RUnlock() fs.filesLock.RUnlock()
if !ok { if !ok {
return nil, os.ErrNotExist return nil, ErrNotExist
} }
if len(file.linkTo) != 0 { if len(file.linkTo) != 0 {
file, ok = fs.files[file.linkTo] file, ok = fs.files[file.linkTo]
if !ok { if !ok {
return nil, os.ErrNotExist return nil, ErrNotExist
} }
} }
@@ -310,11 +310,11 @@ func (fs *memFilesystem) Symlink(oldname, newname string) error {
defer fs.filesLock.Unlock() defer fs.filesLock.Unlock()
if _, ok := fs.files[oldname]; !ok { if _, ok := fs.files[oldname]; !ok {
return os.ErrNotExist return ErrNotExist
} }
if _, ok := fs.files[newname]; ok { if _, ok := fs.files[newname]; ok {
return os.ErrExist return ErrExist
} }
if file, ok := fs.files[oldname]; ok { if file, ok := fs.files[oldname]; ok {
@@ -465,7 +465,7 @@ func (fs *memFilesystem) MkdirAll(path string, perm os.FileMode) error {
return nil return nil
} }
return os.ErrExist return ErrExist
} }
f := &internalMemFile{ f := &internalMemFile{
@@ -495,7 +495,7 @@ func (fs *memFilesystem) Rename(src, dst string) error {
srcFile, ok := fs.files[src] srcFile, ok := fs.files[src]
if !ok { if !ok {
return os.ErrNotExist return ErrNotExist
} }
dstFile, ok := fs.files[dst] dstFile, ok := fs.files[dst]
@@ -524,11 +524,11 @@ func (fs *memFilesystem) Copy(src, dst string) error {
srcFile, ok := fs.files[src] srcFile, ok := fs.files[src]
if !ok { if !ok {
return os.ErrNotExist return ErrNotExist
} }
if srcFile.dir { if srcFile.dir {
return os.ErrNotExist return ErrNotExist
} }
if fs.isDir(dst) { if fs.isDir(dst) {
@@ -582,7 +582,7 @@ func (fs *memFilesystem) stat(path string) (FileInfo, error) {
if len(f.linkTo) != 0 { if len(f.linkTo) != 0 {
file, ok := fs.files[f.linkTo] file, ok := fs.files[f.linkTo]
if !ok { if !ok {
return nil, os.ErrNotExist return nil, ErrNotExist
} }
f.lastMod = file.lastMod f.lastMod = file.lastMod
@@ -594,7 +594,7 @@ func (fs *memFilesystem) stat(path string) (FileInfo, error) {
// Check for directories // Check for directories
if !fs.isDir(path) { if !fs.isDir(path) {
return nil, os.ErrNotExist return nil, ErrNotExist
} }
f := &memFileInfo{ f := &memFileInfo{
@@ -799,11 +799,11 @@ func (fs *memFilesystem) LookPath(file string) (string, error) {
info, err := fs.Stat(file) info, err := fs.Stat(file)
if err == nil { if err == nil {
if !info.Mode().IsRegular() { if !info.Mode().IsRegular() {
return file, os.ErrNotExist return file, ErrNotExist
} }
return file, nil return file, nil
} }
return "", os.ErrNotExist return "", ErrNotExist
} }
path := os.Getenv("PATH") path := os.Getenv("PATH")
for _, dir := range filepath.SplitList(path) { for _, dir := range filepath.SplitList(path) {
@@ -815,15 +815,15 @@ func (fs *memFilesystem) LookPath(file string) (string, error) {
path = fs.cleanPath(path) path = fs.cleanPath(path)
if info, err := fs.Stat(path); err == nil { if info, err := fs.Stat(path); err == nil {
if !filepath.IsAbs(path) { if !filepath.IsAbs(path) {
return path, os.ErrNotExist return path, ErrNotExist
} }
if !info.Mode().IsRegular() { if !info.Mode().IsRegular() {
return path, os.ErrNotExist return path, ErrNotExist
} }
return path, nil return path, nil
} }
} }
return "", os.ErrNotExist return "", ErrNotExist
} }
func (fs *memFilesystem) cleanPath(path string) string { func (fs *memFilesystem) cleanPath(path string) string {

View File

@@ -270,7 +270,7 @@ func (fs *s3Filesystem) ReadFile(path string) ([]byte, error) {
path = fs.cleanPath(path) path = fs.cleanPath(path)
file := fs.Open(path) file := fs.Open(path)
if file == nil { if file == nil {
return nil, os.ErrNotExist return nil, ErrNotExist
} }
defer file.Close() defer file.Close()
@@ -403,7 +403,7 @@ func (fs *s3Filesystem) MkdirAll(path string, perm os.FileMode) error {
info, err := fs.Stat(path) info, err := fs.Stat(path)
if err == nil { if err == nil {
if !info.IsDir() { if !info.IsDir() {
return os.ErrExist return ErrExist
} }
return nil return nil
@@ -624,11 +624,11 @@ func (fs *s3Filesystem) LookPath(file string) (string, error) {
info, err := fs.Stat(file) info, err := fs.Stat(file)
if err == nil { if err == nil {
if !info.Mode().IsRegular() { if !info.Mode().IsRegular() {
return file, os.ErrNotExist return file, ErrNotExist
} }
return file, nil return file, nil
} }
return "", os.ErrNotExist return "", ErrNotExist
} }
path := os.Getenv("PATH") path := os.Getenv("PATH")
for _, dir := range filepath.SplitList(path) { for _, dir := range filepath.SplitList(path) {
@@ -640,15 +640,15 @@ func (fs *s3Filesystem) LookPath(file string) (string, error) {
path = fs.cleanPath(path) path = fs.cleanPath(path)
if info, err := fs.Stat(path); err == nil { if info, err := fs.Stat(path); err == nil {
if !filepath.IsAbs(path) { if !filepath.IsAbs(path) {
return path, os.ErrNotExist return path, ErrNotExist
} }
if !info.Mode().IsRegular() { if !info.Mode().IsRegular() {
return path, os.ErrNotExist return path, ErrNotExist
} }
return path, nil return path, nil
} }
} }
return "", os.ErrNotExist return "", ErrNotExist
} }
func (fs *s3Filesystem) isDir(path string) bool { func (fs *s3Filesystem) isDir(path string) bool {

View File

@@ -2,9 +2,7 @@ package session
import ( import (
"bytes" "bytes"
"errors"
"io" "io"
"os"
"github.com/datarhei/core/v16/io/fs" "github.com/datarhei/core/v16/io/fs"
) )
@@ -34,14 +32,14 @@ type historySource struct {
// session history. If there's no data, a nil source with a nil error will be returned. // session history. If there's no data, a nil source with a nil error will be returned.
// If there's data, a non-nil source with a nil error will be returned. Otherwise // If there's data, a non-nil source with a nil error will be returned. Otherwise
// the source will be nil and the error non-nil. // the source will be nil and the error non-nil.
func NewHistorySource(fs fs.Filesystem, path string) (SnapshotSource, error) { func NewHistorySource(filesystem fs.Filesystem, path string) (SnapshotSource, error) {
s := &historySource{ s := &historySource{
fs: fs, fs: filesystem,
path: path, path: path,
} }
if _, err := s.fs.Stat(s.path); err != nil { if _, err := s.fs.Stat(s.path); err != nil {
if errors.Is(err, os.ErrNotExist) { if err == fs.ErrNotExist {
return nil, nil return nil, nil
} }

View File

@@ -11,7 +11,7 @@ func TestHistorySource(t *testing.T) {
memfs, err := fs.NewMemFilesystem(fs.MemConfig{}) memfs, err := fs.NewMemFilesystem(fs.MemConfig{})
require.NoError(t, err) require.NoError(t, err)
s, err := NewHistorySource(memfs, "/foobar.json") s, err := NewHistorySource(memfs, "./foobar.json")
require.NoError(t, err) require.NoError(t, err)
require.Nil(t, s) require.Nil(t, s)
} }