mirror of
https://github.com/gohugoio/hugo.git
synced 2024-11-21 20:46:30 -05:00
move some of the path helper utilities to afero
and provide wrappers in Hugo.
This commit is contained in:
parent
de14ceecc9
commit
6042fc2b83
2 changed files with 36 additions and 153 deletions
183
helpers/path.go
183
helpers/path.go
|
@ -16,17 +16,17 @@ package helpers
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/spf13/afero"
|
|
||||||
jww "github.com/spf13/jwalterweatherman"
|
|
||||||
"github.com/spf13/viper"
|
|
||||||
"golang.org/x/text/transform"
|
|
||||||
"golang.org/x/text/unicode/norm"
|
|
||||||
"io"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"regexp"
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
"unicode"
|
"unicode"
|
||||||
|
|
||||||
|
"github.com/spf13/afero"
|
||||||
|
"github.com/spf13/viper"
|
||||||
|
"golang.org/x/text/transform"
|
||||||
|
"golang.org/x/text/unicode/norm"
|
||||||
)
|
)
|
||||||
|
|
||||||
// filepathPathBridge is a bridge for common functionality in filepath vs path
|
// filepathPathBridge is a bridge for common functionality in filepath vs path
|
||||||
|
@ -125,74 +125,6 @@ func ReplaceExtension(path string, newExt string) string {
|
||||||
return f + "." + newExt
|
return f + "." + newExt
|
||||||
}
|
}
|
||||||
|
|
||||||
// DirExists checks if a path exists and is a directory.
|
|
||||||
func DirExists(path string, fs afero.Fs) (bool, error) {
|
|
||||||
fi, err := fs.Stat(path)
|
|
||||||
if err == nil && fi.IsDir() {
|
|
||||||
return true, nil
|
|
||||||
}
|
|
||||||
if os.IsNotExist(err) {
|
|
||||||
return false, nil
|
|
||||||
}
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsDir checks if a given path is a directory.
|
|
||||||
func IsDir(path string, fs afero.Fs) (bool, error) {
|
|
||||||
fi, err := fs.Stat(path)
|
|
||||||
if err != nil {
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
return fi.IsDir(), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsEmpty checks if a given path is empty.
|
|
||||||
func IsEmpty(path string, fs afero.Fs) (bool, error) {
|
|
||||||
if b, _ := Exists(path, fs); !b {
|
|
||||||
return false, fmt.Errorf("%q path does not exist", path)
|
|
||||||
}
|
|
||||||
fi, err := fs.Stat(path)
|
|
||||||
if err != nil {
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
if fi.IsDir() {
|
|
||||||
f, err := os.Open(path)
|
|
||||||
// FIX: Resource leak - f.close() should be called here by defer or is missed
|
|
||||||
// if the err != nil branch is taken.
|
|
||||||
defer f.Close()
|
|
||||||
if err != nil {
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
list, err := f.Readdir(-1)
|
|
||||||
// f.Close() - see bug fix above
|
|
||||||
return len(list) == 0, nil
|
|
||||||
}
|
|
||||||
return fi.Size() == 0, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if a file contains a specified string.
|
|
||||||
func FileContains(filename string, subslice []byte, fs afero.Fs) (bool, error) {
|
|
||||||
f, err := os.Open(filename)
|
|
||||||
if err != nil {
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
defer f.Close()
|
|
||||||
|
|
||||||
return ReaderContains(f, subslice), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if a file or directory exists.
|
|
||||||
func Exists(path string, fs afero.Fs) (bool, error) {
|
|
||||||
_, err := fs.Stat(path)
|
|
||||||
if err == nil {
|
|
||||||
return true, nil
|
|
||||||
}
|
|
||||||
if os.IsNotExist(err) {
|
|
||||||
return false, nil
|
|
||||||
}
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
|
|
||||||
func AbsPathify(inPath string) string {
|
func AbsPathify(inPath string) string {
|
||||||
if filepath.IsAbs(inPath) {
|
if filepath.IsAbs(inPath) {
|
||||||
return filepath.Clean(inPath)
|
return filepath.Clean(inPath)
|
||||||
|
@ -498,88 +430,39 @@ func FindCWD() (string, error) {
|
||||||
|
|
||||||
// Same as WriteToDisk but checks to see if file/directory already exists.
|
// Same as WriteToDisk but checks to see if file/directory already exists.
|
||||||
func SafeWriteToDisk(inpath string, r io.Reader, fs afero.Fs) (err error) {
|
func SafeWriteToDisk(inpath string, r io.Reader, fs afero.Fs) (err error) {
|
||||||
dir, _ := filepath.Split(inpath)
|
return afero.SafeWriteReader(fs, inpath, r)
|
||||||
ospath := filepath.FromSlash(dir)
|
|
||||||
|
|
||||||
if ospath != "" {
|
|
||||||
err = fs.MkdirAll(ospath, 0777) // rwx, rw, r
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
exists, err := Exists(inpath, fs)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if exists {
|
|
||||||
return fmt.Errorf("%v already exists", inpath)
|
|
||||||
}
|
|
||||||
|
|
||||||
file, err := fs.Create(inpath)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
defer file.Close()
|
|
||||||
|
|
||||||
_, err = io.Copy(file, r)
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Writes content to disk.
|
// Writes content to disk.
|
||||||
func WriteToDisk(inpath string, r io.Reader, fs afero.Fs) (err error) {
|
func WriteToDisk(inpath string, r io.Reader, fs afero.Fs) (err error) {
|
||||||
dir, _ := filepath.Split(inpath)
|
return afero.WriteReader(fs, inpath, r)
|
||||||
ospath := filepath.FromSlash(dir)
|
|
||||||
|
|
||||||
if ospath != "" {
|
|
||||||
err = fs.MkdirAll(ospath, 0777) // rwx, rw, r
|
|
||||||
if err != nil {
|
|
||||||
if err != os.ErrExist {
|
|
||||||
jww.FATAL.Fatalln(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
file, err := fs.Create(inpath)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
defer file.Close()
|
|
||||||
|
|
||||||
_, err = io.Copy(file, r)
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetTempDir returns the OS default temp directory with trailing slash
|
|
||||||
// if subPath is not empty then it will be created recursively with mode 777 rwx rwx rwx
|
|
||||||
func GetTempDir(subPath string, fs afero.Fs) string {
|
func GetTempDir(subPath string, fs afero.Fs) string {
|
||||||
addSlash := func(p string) string {
|
return afero.GetTempDir(fs, subPath)
|
||||||
if FilePathSeparator != p[len(p)-1:] {
|
}
|
||||||
p = p + FilePathSeparator
|
|
||||||
}
|
// DirExists checks if a path exists and is a directory.
|
||||||
return p
|
func DirExists(path string, fs afero.Fs) (bool, error) {
|
||||||
}
|
return afero.DirExists(fs, path)
|
||||||
dir := addSlash(os.TempDir())
|
}
|
||||||
|
|
||||||
if subPath != "" {
|
// IsDir checks if a given path is a directory.
|
||||||
// preserve windows backslash :-(
|
func IsDir(path string, fs afero.Fs) (bool, error) {
|
||||||
if FilePathSeparator == "\\" {
|
return afero.IsDir(fs, path)
|
||||||
subPath = strings.Replace(subPath, "\\", "____", -1)
|
}
|
||||||
}
|
|
||||||
dir = dir + MakePath(subPath)
|
// IsEmpty checks if a given path is empty.
|
||||||
if FilePathSeparator == "\\" {
|
func IsEmpty(path string, fs afero.Fs) (bool, error) {
|
||||||
dir = strings.Replace(dir, "____", "\\", -1)
|
return afero.IsEmpty(fs, path)
|
||||||
}
|
}
|
||||||
|
|
||||||
if exists, _ := Exists(dir, fs); exists {
|
// Check if a file contains a specified string.
|
||||||
return addSlash(dir)
|
func FileContains(filename string, subslice []byte, fs afero.Fs) (bool, error) {
|
||||||
}
|
return afero.FileContainsBytes(fs, filename, subslice)
|
||||||
|
}
|
||||||
err := fs.MkdirAll(dir, 0777)
|
|
||||||
if err != nil {
|
// Check if a file or directory exists.
|
||||||
panic(err)
|
func Exists(path string, fs afero.Fs) (bool, error) {
|
||||||
}
|
return afero.Exists(fs, path)
|
||||||
dir = addSlash(dir)
|
|
||||||
}
|
|
||||||
return dir
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -755,13 +755,13 @@ func TestGetTempDir(t *testing.T) {
|
||||||
expected string
|
expected string
|
||||||
}{
|
}{
|
||||||
{"", dir},
|
{"", dir},
|
||||||
{testDir + " Foo bar ", dir + testDir + "--Foo-bar" + FilePathSeparator},
|
{testDir + " Foo bar ", dir + testDir + " Foo bar " + FilePathSeparator},
|
||||||
{testDir + "Foo.Bar/foo_Bar-Foo", dir + testDir + "Foo.Bar/foo_Bar-Foo" + FilePathSeparator},
|
{testDir + "Foo.Bar/foo_Bar-Foo", dir + testDir + "Foo.Bar/foo_Bar-Foo" + FilePathSeparator},
|
||||||
{testDir + "fOO,bar:foo%bAR", dir + testDir + "fOObarfoobAR" + FilePathSeparator},
|
{testDir + "fOO,bar:foo%bAR", dir + testDir + "fOObarfoo%bAR" + FilePathSeparator},
|
||||||
{testDir + "FOo/BaR.html", dir + testDir + "FOo/BaR.html" + FilePathSeparator},
|
{testDir + "FOo/BaR.html", dir + testDir + "FOo/BaR.html" + FilePathSeparator},
|
||||||
{testDir + "трям/трям", dir + testDir + "трям/трям" + FilePathSeparator},
|
{testDir + "трям/трям", dir + testDir + "трям/трям" + FilePathSeparator},
|
||||||
{testDir + "은행", dir + testDir + "은행" + FilePathSeparator},
|
{testDir + "은행", dir + testDir + "은행" + FilePathSeparator},
|
||||||
{testDir + "Банковский кассир", dir + testDir + "Банковский-кассир" + FilePathSeparator},
|
{testDir + "Банковский кассир", dir + testDir + "Банковский кассир" + FilePathSeparator},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range tests {
|
for _, test := range tests {
|
||||||
|
|
Loading…
Reference in a new issue