Import source: handler/fs/path
Import the existing local project snapshot. This commit organizes existing files; it does not represent newly developed functionality.
This commit is contained in:
@@ -0,0 +1,94 @@
|
||||
package fs
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/fs"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
)
|
||||
|
||||
var (
|
||||
// ErrNoCurrentDir returned on creating the content file before the current
|
||||
// directory was created.
|
||||
ErrNoCurrentDir = errors.New("current dir was not created")
|
||||
|
||||
// ErrInvalidDest returned when provided save path is not a valid directory.
|
||||
ErrInvalidDest = errors.New("invalid destination path")
|
||||
)
|
||||
|
||||
type PathResolver struct {
|
||||
// Dest contains a base directory for all folders that will be created.
|
||||
// It should be a valid absolute or relative path and must already exist.
|
||||
Dest string
|
||||
|
||||
absDest string
|
||||
currentDest string
|
||||
}
|
||||
|
||||
// NewPathResolver returns new *PathResolver along with resolving provided dest
|
||||
// value. If an incorrect dest value is provided an error will be returned.
|
||||
func NewPathResolver(dest string) (*PathResolver, error) {
|
||||
absDest, err := filepath.Abs(dest)
|
||||
if err != nil {
|
||||
return nil, ErrInvalidDest
|
||||
}
|
||||
|
||||
stat, err := os.Stat(absDest)
|
||||
if err != nil || !stat.IsDir() {
|
||||
return nil, ErrInvalidDest
|
||||
}
|
||||
|
||||
return &PathResolver{
|
||||
Dest: dest,
|
||||
absDest: absDest,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// CreateFolder creates a new dir with the provided name within PathResolver.Dest dir.
|
||||
// Created dir will be marked as current dir. If dir already exists the creation
|
||||
// step will be skipped.
|
||||
func (p *PathResolver) CreateFolder(name string) error {
|
||||
err := os.Chdir(p.absDest)
|
||||
if err != nil {
|
||||
return fmt.Errorf("cannot resolve path for folder %s: %w", name, err)
|
||||
}
|
||||
|
||||
p.currentDest = path.Join(p.absDest, name)
|
||||
|
||||
err = os.Mkdir(name, fs.ModePerm)
|
||||
if err != nil {
|
||||
if os.IsExist(err) {
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("cannot create folder %s: %w", p.currentDest, err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// CreateFile creates a new file with the corresponding name and returns its
|
||||
// io.WriteCloser. If FSResolver.currentDest wasn't created before, then an error
|
||||
// will be returned.
|
||||
func (p *PathResolver) CreateFile(name string) (io.WriteCloser, error) {
|
||||
if p.currentDest == "" {
|
||||
return nil, ErrNoCurrentDir
|
||||
}
|
||||
|
||||
filePath := path.Join(p.currentDest, name)
|
||||
|
||||
f, err := os.Create(filePath)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("cannot create file %s: %w", filePath, err)
|
||||
}
|
||||
|
||||
return f, nil
|
||||
}
|
||||
|
||||
// Remove removes file or dir by its name. If the provided path wasn't found the
|
||||
// deletion step will be skipped.
|
||||
func (p *PathResolver) Remove(name string) {
|
||||
_ = os.Remove(name)
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
//go:build unit
|
||||
// +build unit
|
||||
|
||||
package fs_test
|
||||
|
||||
import (
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
"reactor-crw/handler/fs"
|
||||
)
|
||||
|
||||
func TestNewPathResolver(t *testing.T) {
|
||||
paths := []struct {
|
||||
name string
|
||||
msg string
|
||||
errExpected bool
|
||||
}{
|
||||
{" ", "Expected an error during resolving empty path", true},
|
||||
{"invalid_path", "Expected an error during resolving non-existent dir", true},
|
||||
{os.TempDir(), "Wasn't expected an error", false},
|
||||
}
|
||||
|
||||
for _, path := range paths {
|
||||
_, err := fs.NewPathResolver(path.name)
|
||||
if path.errExpected {
|
||||
require.Errorf(t, err, path.msg)
|
||||
}
|
||||
|
||||
if !path.errExpected {
|
||||
require.NoError(t, err, path.msg)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestPathResolver_CreateFolder(t *testing.T) {
|
||||
p, _ := fs.NewPathResolver(os.TempDir())
|
||||
|
||||
folders := []struct {
|
||||
name string
|
||||
errExpected bool
|
||||
}{
|
||||
{name: "test"},
|
||||
{name: "_123_test"},
|
||||
{name: "109483___"},
|
||||
}
|
||||
|
||||
for _, folder := range folders {
|
||||
err := p.CreateFolder(folder.name)
|
||||
if !folder.errExpected {
|
||||
require.NoError(t, err, "Wasn't expected an error during creating %s", folder.name)
|
||||
}
|
||||
|
||||
if folder.errExpected {
|
||||
require.Error(t, err, "Expected an error during creating %s", folder.name)
|
||||
}
|
||||
|
||||
p.Remove(folder.name)
|
||||
}
|
||||
|
||||
p = &fs.PathResolver{}
|
||||
err := p.CreateFolder("test")
|
||||
require.Error(t, err, "Expected an error during creating folder")
|
||||
}
|
||||
|
||||
func TestPathResolver_CreateFile(t *testing.T) {
|
||||
p, _ := fs.NewPathResolver(os.TempDir())
|
||||
_, err := p.CreateFile("filename")
|
||||
require.Error(t, err, "Expected an error during file. Folder wasn't created yet.")
|
||||
|
||||
_ = p.CreateFolder("test")
|
||||
|
||||
_, err = p.CreateFile("filename")
|
||||
require.NoError(t, err, "Wasn't expected an error during creating filename")
|
||||
|
||||
filePath := "./test/filename"
|
||||
_, err = os.Stat(filePath)
|
||||
require.NoError(t, err, "File %s wasn't created", filePath)
|
||||
|
||||
p.Remove(filePath)
|
||||
}
|
||||
Reference in New Issue
Block a user