mirror of
https://github.com/gogf/gf.git
synced 2025-04-05 11:18:50 +08:00
change errors wrapped by gerror.Wrap with error stack info for all packages
This commit is contained in:
parent
b9bb1ecd46
commit
48c5c1e5a8
@ -29,7 +29,7 @@ func Gzip(data []byte, level ...int) ([]byte, error) {
|
||||
if len(level) > 0 {
|
||||
writer, err = gzip.NewWriterLevel(&buf, level[0])
|
||||
if err != nil {
|
||||
err = gerror.Wrap(err, `gzip.NewWriterLevel failed`)
|
||||
err = gerror.Wrapf(err, `gzip.NewWriterLevel failed for level "%d"`, level[0])
|
||||
return nil, err
|
||||
}
|
||||
} else {
|
||||
|
@ -46,11 +46,11 @@ func NewPoolConn(addr string, timeout ...time.Duration) (*PoolConn, error) {
|
||||
})
|
||||
return pool
|
||||
})
|
||||
if v, err := v.(*gpool.Pool).Get(); err == nil {
|
||||
return v.(*PoolConn), nil
|
||||
} else {
|
||||
value, err := v.(*gpool.Pool).Get()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return value.(*PoolConn), nil
|
||||
}
|
||||
|
||||
// Close puts back the connection to the pool if it's active,
|
||||
|
@ -20,7 +20,7 @@ import (
|
||||
"github.com/gogf/gf/v2/util/gconv"
|
||||
)
|
||||
|
||||
var (
|
||||
const (
|
||||
// Separator for file system.
|
||||
// It here defines the separator as variable
|
||||
// to allow it modified by developer if necessary.
|
||||
@ -31,7 +31,9 @@ var (
|
||||
|
||||
// DefaultPermCopy is the default perm for file/folder copy.
|
||||
DefaultPermCopy = os.FileMode(0777)
|
||||
)
|
||||
|
||||
var (
|
||||
// The absolute file path for main package.
|
||||
// It can be only checked and set once.
|
||||
mainPkgPath = gtype.NewString()
|
||||
@ -63,7 +65,7 @@ func init() {
|
||||
// The parameter `path` is suggested to be an absolute path instead of relative one.
|
||||
func Mkdir(path string) (err error) {
|
||||
if err = os.MkdirAll(path, os.ModePerm); err != nil {
|
||||
err = gerror.Wrapf(err, `os.MkdirAll failed for path "%s"`, path)
|
||||
err = gerror.Wrapf(err, `os.MkdirAll failed for path "%s" with perm "%d"`, path, os.ModePerm)
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
@ -78,40 +80,52 @@ func Create(path string) (*os.File, error) {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return os.Create(path)
|
||||
file, err := os.Create(path)
|
||||
if err != nil {
|
||||
err = gerror.Wrapf(err, `os.Create failed for name "%s"`, path)
|
||||
}
|
||||
return file, err
|
||||
}
|
||||
|
||||
// Open opens file/directory READONLY.
|
||||
func Open(path string) (*os.File, error) {
|
||||
return os.Open(path)
|
||||
file, err := os.Open(path)
|
||||
if err != nil {
|
||||
err = gerror.Wrapf(err, `os.Open failed for name "%s"`, path)
|
||||
}
|
||||
return file, err
|
||||
}
|
||||
|
||||
// OpenFile opens file/directory with custom `flag` and `perm`.
|
||||
// The parameter `flag` is like: O_RDONLY, O_RDWR, O_RDWR|O_CREATE|O_TRUNC, etc.
|
||||
func OpenFile(path string, flag int, perm os.FileMode) (*os.File, error) {
|
||||
return os.OpenFile(path, flag, perm)
|
||||
file, err := os.OpenFile(path, flag, perm)
|
||||
if err != nil {
|
||||
err = gerror.Wrapf(err, `os.OpenFile failed with name "%s", flag "%d", perm "%d"`, path, flag, perm)
|
||||
}
|
||||
return file, err
|
||||
}
|
||||
|
||||
// OpenWithFlag opens file/directory with default perm and custom `flag`.
|
||||
// The default `perm` is 0666.
|
||||
// The parameter `flag` is like: O_RDONLY, O_RDWR, O_RDWR|O_CREATE|O_TRUNC, etc.
|
||||
func OpenWithFlag(path string, flag int) (*os.File, error) {
|
||||
f, err := os.OpenFile(path, flag, DefaultPermOpen)
|
||||
file, err := OpenFile(path, flag, DefaultPermOpen)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return f, nil
|
||||
return file, nil
|
||||
}
|
||||
|
||||
// OpenWithFlagPerm opens file/directory with custom `flag` and `perm`.
|
||||
// The parameter `flag` is like: O_RDONLY, O_RDWR, O_RDWR|O_CREATE|O_TRUNC, etc.
|
||||
// The parameter `perm` is like: 0600, 0666, 0777, etc.
|
||||
func OpenWithFlagPerm(path string, flag int, perm os.FileMode) (*os.File, error) {
|
||||
f, err := os.OpenFile(path, flag, perm)
|
||||
file, err := OpenFile(path, flag, perm)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return f, nil
|
||||
return file, nil
|
||||
}
|
||||
|
||||
// Join joins string array paths with file separator of current system.
|
||||
@ -157,14 +171,18 @@ func Pwd() string {
|
||||
|
||||
// Chdir changes the current working directory to the named directory.
|
||||
// If there is an error, it will be of type *PathError.
|
||||
func Chdir(dir string) error {
|
||||
return os.Chdir(dir)
|
||||
func Chdir(dir string) (err error) {
|
||||
err = os.Chdir(dir)
|
||||
if err != nil {
|
||||
err = gerror.Wrapf(err, `os.Chdir failed with dir "%s"`, dir)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// IsFile checks whether given `path` a file, which means it's not a directory.
|
||||
// Note that it returns false if the `path` does not exist.
|
||||
func IsFile(path string) bool {
|
||||
s, err := os.Stat(path)
|
||||
s, err := Stat(path)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
@ -174,13 +192,21 @@ func IsFile(path string) bool {
|
||||
// Stat returns a FileInfo describing the named file.
|
||||
// If there is an error, it will be of type *PathError.
|
||||
func Stat(path string) (os.FileInfo, error) {
|
||||
return os.Stat(path)
|
||||
info, err := os.Stat(path)
|
||||
if err != nil {
|
||||
err = gerror.Wrapf(err, `os.Stat failed for file "%s"`, path)
|
||||
}
|
||||
return info, err
|
||||
}
|
||||
|
||||
// Move renames (moves) `src` to `dst` path.
|
||||
// If `dst` already exists and is not a directory, it'll be replaced.
|
||||
func Move(src string, dst string) error {
|
||||
return os.Rename(src, dst)
|
||||
func Move(src string, dst string) (err error) {
|
||||
err = os.Rename(src, dst)
|
||||
if err != nil {
|
||||
err = gerror.Wrapf(err, `os.Rename failed from "%s" to "%s"`, src, dst)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Rename is alias of Move.
|
||||
@ -192,13 +218,14 @@ func Rename(src string, dst string) error {
|
||||
// DirNames returns sub-file names of given directory `path`.
|
||||
// Note that the returned names are NOT absolute paths.
|
||||
func DirNames(path string) ([]string, error) {
|
||||
f, err := os.Open(path)
|
||||
f, err := Open(path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
list, err := f.Readdirnames(-1)
|
||||
f.Close()
|
||||
_ = f.Close()
|
||||
if err != nil {
|
||||
err = gerror.Wrapf(err, `Read dir files failed from path "%s"`, path)
|
||||
return nil, err
|
||||
}
|
||||
return list, nil
|
||||
@ -213,24 +240,29 @@ func DirNames(path string) ([]string, error) {
|
||||
// The only possible returned error is ErrBadPattern, when pattern
|
||||
// is malformed.
|
||||
func Glob(pattern string, onlyNames ...bool) ([]string, error) {
|
||||
if list, err := filepath.Glob(pattern); err == nil {
|
||||
if len(onlyNames) > 0 && onlyNames[0] && len(list) > 0 {
|
||||
array := make([]string, len(list))
|
||||
for k, v := range list {
|
||||
array[k] = Basename(v)
|
||||
}
|
||||
return array, nil
|
||||
}
|
||||
return list, nil
|
||||
} else {
|
||||
list, err := filepath.Glob(pattern)
|
||||
if err != nil {
|
||||
err = gerror.Wrapf(err, `filepath.Glob failed for pattern "%s"`, pattern)
|
||||
return nil, err
|
||||
}
|
||||
if len(onlyNames) > 0 && onlyNames[0] && len(list) > 0 {
|
||||
array := make([]string, len(list))
|
||||
for k, v := range list {
|
||||
array[k] = Basename(v)
|
||||
}
|
||||
return array, nil
|
||||
}
|
||||
return list, nil
|
||||
}
|
||||
|
||||
// Remove deletes all file/directory with `path` parameter.
|
||||
// If parameter `path` is directory, it deletes it recursively.
|
||||
func Remove(path string) error {
|
||||
return os.RemoveAll(path)
|
||||
func Remove(path string) (err error) {
|
||||
err = os.RemoveAll(path)
|
||||
if err != nil {
|
||||
err = gerror.Wrapf(err, `os.RemoveAll failed for path "%s"`, path)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// IsReadable checks whether given `path` is readable.
|
||||
@ -255,24 +287,28 @@ func IsWritable(path string) bool {
|
||||
if f, err := Create(tmpFile); err != nil || !Exists(tmpFile) {
|
||||
result = false
|
||||
} else {
|
||||
f.Close()
|
||||
Remove(tmpFile)
|
||||
_ = f.Close()
|
||||
_ = Remove(tmpFile)
|
||||
}
|
||||
} else {
|
||||
// 如果是文件,那么判断文件是否可打开
|
||||
// If it's a file, check if it can open it.
|
||||
file, err := os.OpenFile(path, os.O_WRONLY, DefaultPermOpen)
|
||||
if err != nil {
|
||||
result = false
|
||||
}
|
||||
file.Close()
|
||||
_ = file.Close()
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// Chmod is alias of os.Chmod.
|
||||
// See os.Chmod.
|
||||
func Chmod(path string, mode os.FileMode) error {
|
||||
return os.Chmod(path, mode)
|
||||
func Chmod(path string, mode os.FileMode) (err error) {
|
||||
err = os.Chmod(path, mode)
|
||||
if err != nil {
|
||||
err = gerror.Wrapf(err, `os.Chmod failed with path "%s" and mode "%s"`, path, mode)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Abs returns an absolute representation of path.
|
||||
@ -392,7 +428,7 @@ func Ext(path string) string {
|
||||
}
|
||||
|
||||
// ExtName is like function Ext, which returns the file name extension used by path,
|
||||
// but the result does not contains symbol '.'.
|
||||
// but the result does not contain symbol '.'.
|
||||
func ExtName(path string) string {
|
||||
return strings.TrimLeft(Ext(path), ".")
|
||||
}
|
||||
@ -400,7 +436,7 @@ func ExtName(path string) string {
|
||||
// TempDir retrieves and returns the temporary directory of current system.
|
||||
// It returns "/tmp" is current in *nix system, or else it returns os.TempDir().
|
||||
//
|
||||
// The optional parameter `names` specifies the its sub-folders/sub-files,
|
||||
// The optional parameter `names` specifies the sub-folders/sub-files,
|
||||
// which will be joined with current system separator and returned with the path.
|
||||
func TempDir(names ...string) string {
|
||||
path := tempDir
|
||||
|
@ -11,6 +11,8 @@ import (
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
|
||||
"github.com/gogf/gf/v2/errors/gerror"
|
||||
)
|
||||
|
||||
var (
|
||||
@ -49,7 +51,10 @@ func putContents(path string, data []byte, flag int, perm os.FileMode) error {
|
||||
return err
|
||||
}
|
||||
defer f.Close()
|
||||
if n, err := f.Write(data); err != nil {
|
||||
// Write data.
|
||||
var n int
|
||||
if n, err = f.Write(data); err != nil {
|
||||
err = gerror.Wrapf(err, `Write data to file "%s" failed`, path)
|
||||
return err
|
||||
} else if n < len(data) {
|
||||
return io.ErrShortWrite
|
||||
@ -58,8 +63,12 @@ func putContents(path string, data []byte, flag int, perm os.FileMode) error {
|
||||
}
|
||||
|
||||
// Truncate truncates file of `path` to given size by `size`.
|
||||
func Truncate(path string, size int) error {
|
||||
return os.Truncate(path, int64(size))
|
||||
func Truncate(path string, size int) (err error) {
|
||||
err = os.Truncate(path, int64(size))
|
||||
if err != nil {
|
||||
err = gerror.Wrapf(err, `os.Truncate failed for file "%s", size "%d"`, path, size)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// PutContents puts string `content` to file of `path`.
|
||||
@ -168,7 +177,7 @@ func GetBytesByTwoOffsetsByPath(path string, start int64, end int64) []byte {
|
||||
// Note that the parameter passed to callback function might be an empty value, and the last non-empty line
|
||||
// will be passed to callback function `callback` even if it has no newline marker.
|
||||
func ReadLines(file string, callback func(text string) error) error {
|
||||
f, err := os.Open(file)
|
||||
f, err := Open(file)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -189,7 +198,7 @@ func ReadLines(file string, callback func(text string) error) error {
|
||||
// Note that the parameter passed to callback function might be an empty value, and the last non-empty line
|
||||
// will be passed to callback function `callback` even if it has no newline marker.
|
||||
func ReadLinesBytes(file string, callback func(bytes []byte) error) error {
|
||||
f, err := os.Open(file)
|
||||
f, err := Open(file)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -50,33 +50,33 @@ func CopyFile(src, dst string) (err error) {
|
||||
if src == dst {
|
||||
return nil
|
||||
}
|
||||
in, err := os.Open(src)
|
||||
in, err := Open(src)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
defer func() {
|
||||
if e := in.Close(); e != nil {
|
||||
err = e
|
||||
err = gerror.Wrapf(e, `file close failed for "%s"`, src)
|
||||
}
|
||||
}()
|
||||
out, err := os.Create(dst)
|
||||
out, err := Create(dst)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
defer func() {
|
||||
if e := out.Close(); e != nil {
|
||||
err = e
|
||||
err = gerror.Wrapf(e, `file close failed for "%s"`, dst)
|
||||
}
|
||||
}()
|
||||
_, err = io.Copy(out, in)
|
||||
if err != nil {
|
||||
if _, err = io.Copy(out, in); err != nil {
|
||||
err = gerror.Wrapf(err, `io.Copy failed from "%s" to "%s"`, src, dst)
|
||||
return
|
||||
}
|
||||
err = out.Sync()
|
||||
if err != nil {
|
||||
if err = out.Sync(); err != nil {
|
||||
err = gerror.Wrapf(err, `file sync failed for file "%s"`, dst)
|
||||
return
|
||||
}
|
||||
err = os.Chmod(dst, DefaultPermCopy)
|
||||
err = Chmod(dst, DefaultPermCopy)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
@ -99,7 +99,7 @@ func CopyDir(src string, dst string) (err error) {
|
||||
}
|
||||
src = filepath.Clean(src)
|
||||
dst = filepath.Clean(dst)
|
||||
si, err := os.Stat(src)
|
||||
si, err := Stat(src)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -107,21 +107,21 @@ func CopyDir(src string, dst string) (err error) {
|
||||
return gerror.NewCode(gcode.CodeInvalidParameter, "source is not a directory")
|
||||
}
|
||||
if !Exists(dst) {
|
||||
err = os.MkdirAll(dst, DefaultPermCopy)
|
||||
if err != nil {
|
||||
if err = os.MkdirAll(dst, DefaultPermCopy); err != nil {
|
||||
err = gerror.Wrapf(err, `create directory failed for path "%s", perm "%s"`, dst, DefaultPermCopy)
|
||||
return
|
||||
}
|
||||
}
|
||||
entries, err := ioutil.ReadDir(src)
|
||||
if err != nil {
|
||||
err = gerror.Wrapf(err, `read directory failed for path "%s"`, src)
|
||||
return
|
||||
}
|
||||
for _, entry := range entries {
|
||||
srcPath := filepath.Join(src, entry.Name())
|
||||
dstPath := filepath.Join(dst, entry.Name())
|
||||
if entry.IsDir() {
|
||||
err = CopyDir(srcPath, dstPath)
|
||||
if err != nil {
|
||||
if err = CopyDir(srcPath, dstPath); err != nil {
|
||||
return
|
||||
}
|
||||
} else {
|
||||
@ -129,8 +129,7 @@ func CopyDir(src string, dst string) (err error) {
|
||||
if entry.Mode()&os.ModeSymlink != 0 {
|
||||
continue
|
||||
}
|
||||
err = CopyFile(srcPath, dstPath)
|
||||
if err != nil {
|
||||
if err = CopyFile(srcPath, dstPath); err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
@ -14,7 +14,6 @@ import (
|
||||
"runtime"
|
||||
"strings"
|
||||
|
||||
"github.com/gogf/gf/v2/errors/gcode"
|
||||
"github.com/gogf/gf/v2/errors/gerror"
|
||||
)
|
||||
|
||||
@ -53,6 +52,7 @@ func homeUnix() (string, error) {
|
||||
cmd := exec.Command("sh", "-c", "eval echo ~$USER")
|
||||
cmd.Stdout = &stdout
|
||||
if err := cmd.Run(); err != nil {
|
||||
err = gerror.Wrapf(err, `retrieve home directory failed`)
|
||||
return "", err
|
||||
}
|
||||
|
||||
@ -75,7 +75,7 @@ func homeWindows() (string, error) {
|
||||
home = os.Getenv("USERPROFILE")
|
||||
}
|
||||
if home == "" {
|
||||
return "", gerror.New("HOMEDRIVE, HOMEPATH, and USERPROFILE are blank")
|
||||
return "", gerror.New("environment keys HOMEDRIVE, HOMEPATH and USERPROFILE are empty")
|
||||
}
|
||||
|
||||
return home, nil
|
||||
|
@ -7,11 +7,9 @@
|
||||
package gfile
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"sort"
|
||||
|
||||
"github.com/gogf/gf/v2/errors/gcode"
|
||||
"github.com/gogf/gf/v2/errors/gerror"
|
||||
"github.com/gogf/gf/v2/text/gstr"
|
||||
)
|
||||
@ -141,14 +139,17 @@ func doScanDir(depth int, path string, pattern string, recursive bool, handler f
|
||||
if depth >= maxScanDepth {
|
||||
return nil, gerror.Newf("directory scanning exceeds max recursive depth: %d", maxScanDepth)
|
||||
}
|
||||
list := ([]string)(nil)
|
||||
file, err := os.Open(path)
|
||||
var (
|
||||
list []string
|
||||
file, err = Open(path)
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer file.Close()
|
||||
names, err := file.Readdirnames(-1)
|
||||
if err != nil {
|
||||
err = gerror.Wrapf(err, `read directory files failed from path "%s"`, path)
|
||||
return nil, err
|
||||
}
|
||||
var (
|
||||
@ -172,9 +173,8 @@ func doScanDir(depth int, path string, pattern string, recursive bool, handler f
|
||||
}
|
||||
// If it meets pattern, then add it to the result list.
|
||||
for _, p := range patterns {
|
||||
if match, err := filepath.Match(p, name); err == nil && match {
|
||||
filePath = Abs(filePath)
|
||||
if filePath != "" {
|
||||
if match, _ := filepath.Match(p, name); match {
|
||||
if filePath = Abs(filePath); filePath != "" {
|
||||
list = append(list, filePath)
|
||||
}
|
||||
}
|
||||
|
@ -11,7 +11,6 @@ import (
|
||||
"fmt"
|
||||
|
||||
"github.com/gogf/gf/v2/container/garray"
|
||||
"github.com/gogf/gf/v2/errors/gcode"
|
||||
"github.com/gogf/gf/v2/errors/gerror"
|
||||
)
|
||||
|
||||
|
@ -12,6 +12,7 @@ import (
|
||||
|
||||
"github.com/gogf/gf/v2/container/gpool"
|
||||
"github.com/gogf/gf/v2/container/gtype"
|
||||
"github.com/gogf/gf/v2/errors/gerror"
|
||||
"github.com/gogf/gf/v2/os/gfsnotify"
|
||||
)
|
||||
|
||||
@ -41,6 +42,7 @@ func newFilePool(p *Pool, path string, flag int, perm os.FileMode, ttl time.Dura
|
||||
pool := gpool.New(ttl, func() (interface{}, error) {
|
||||
file, err := os.OpenFile(path, flag, perm)
|
||||
if err != nil {
|
||||
err = gerror.Wrapf(err, `os.OpenFile failed for file "%s", flag "%d", perm "%s"`, path, flag, perm)
|
||||
return nil, err
|
||||
}
|
||||
return &File{
|
||||
@ -65,7 +67,6 @@ func (p *Pool) File() (*File, error) {
|
||||
if v, err := p.pool.Get(); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
var err error
|
||||
f := v.(*File)
|
||||
f.stat, err = os.Stat(f.path)
|
||||
if f.flag&os.O_CREATE > 0 {
|
||||
|
@ -12,6 +12,8 @@ import (
|
||||
"path/filepath"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"github.com/gogf/gf/v2/errors/gerror"
|
||||
)
|
||||
|
||||
// fileDir returns all but the last element of path, typically the path's directory.
|
||||
@ -68,9 +70,9 @@ func fileAllDirs(path string) (list []string) {
|
||||
return list
|
||||
}
|
||||
for _, name := range names {
|
||||
path := fmt.Sprintf("%s%s%s", path, string(filepath.Separator), name)
|
||||
if fileIsDir(path) {
|
||||
if array := fileAllDirs(path); len(array) > 0 {
|
||||
tempPath := fmt.Sprintf("%s%s%s", path, string(filepath.Separator), name)
|
||||
if fileIsDir(tempPath) {
|
||||
if array := fileAllDirs(tempPath); len(array) > 0 {
|
||||
list = append(list, array...)
|
||||
}
|
||||
}
|
||||
@ -99,14 +101,18 @@ func fileScanDir(path string, pattern string, recursive ...bool) ([]string, erro
|
||||
//
|
||||
// It scans directory recursively if given parameter `recursive` is true.
|
||||
func doFileScanDir(path string, pattern string, recursive ...bool) ([]string, error) {
|
||||
list := ([]string)(nil)
|
||||
file, err := os.Open(path)
|
||||
var (
|
||||
list []string
|
||||
file, err = os.Open(path)
|
||||
)
|
||||
if err != nil {
|
||||
err = gerror.Wrapf(err, `os.Open failed for path "%s"`, path)
|
||||
return nil, err
|
||||
}
|
||||
defer file.Close()
|
||||
names, err := file.Readdirnames(-1)
|
||||
if err != nil {
|
||||
err = gerror.Wrapf(err, `read directory files failed for path "%s"`, path)
|
||||
return nil, err
|
||||
}
|
||||
filePath := ""
|
||||
@ -119,7 +125,7 @@ func doFileScanDir(path string, pattern string, recursive ...bool) ([]string, er
|
||||
}
|
||||
}
|
||||
for _, p := range strings.Split(pattern, ",") {
|
||||
if match, err := filepath.Match(strings.TrimSpace(p), name); err == nil && match {
|
||||
if match, _ := filepath.Match(strings.TrimSpace(p), name); match {
|
||||
list = append(list, filePath)
|
||||
}
|
||||
}
|
||||
|
@ -46,8 +46,8 @@ func (w *Watcher) AddOnce(name, path string, callbackFunc func(event *Event), re
|
||||
if fileIsDir(path) && (len(recursive) == 0 || recursive[0]) {
|
||||
for _, subPath := range fileAllDirs(path) {
|
||||
if fileIsDir(subPath) {
|
||||
if err := w.watcher.Add(subPath); err != nil {
|
||||
intlog.Error(context.TODO(), err)
|
||||
if err = w.watcher.Add(subPath); err != nil {
|
||||
err = gerror.Wrapf(err, `add watch failed for path "%s"`, subPath)
|
||||
} else {
|
||||
intlog.Printf(context.TODO(), "watcher adds monitor for: %s", subPath)
|
||||
}
|
||||
@ -94,8 +94,8 @@ func (w *Watcher) addWithCallbackFunc(name, path string, callbackFunc func(event
|
||||
callback.elem = list.PushBack(callback)
|
||||
})
|
||||
// Add the path to underlying monitor.
|
||||
if err := w.watcher.Add(path); err != nil {
|
||||
intlog.Error(context.TODO(), err)
|
||||
if err = w.watcher.Add(path); err != nil {
|
||||
err = gerror.Wrapf(err, `add watch failed for path "%s"`, path)
|
||||
} else {
|
||||
intlog.Printf(context.TODO(), "watcher adds monitor for: %s", path)
|
||||
}
|
||||
@ -116,11 +116,11 @@ func (w *Watcher) Close() {
|
||||
// Remove removes monitor and all callbacks associated with the `path` recursively.
|
||||
func (w *Watcher) Remove(path string) error {
|
||||
// Firstly remove the callbacks of the path.
|
||||
if r := w.callbacks.Remove(path); r != nil {
|
||||
list := r.(*glist.List)
|
||||
if value := w.callbacks.Remove(path); value != nil {
|
||||
list := value.(*glist.List)
|
||||
for {
|
||||
if r := list.PopFront(); r != nil {
|
||||
callbackIdMap.Remove(r.(*Callback).Id)
|
||||
if item := list.PopFront(); item != nil {
|
||||
callbackIdMap.Remove(item.(*Callback).Id)
|
||||
} else {
|
||||
break
|
||||
}
|
||||
@ -130,14 +130,18 @@ func (w *Watcher) Remove(path string) error {
|
||||
if subPaths, err := fileScanDir(path, "*", true); err == nil && len(subPaths) > 0 {
|
||||
for _, subPath := range subPaths {
|
||||
if w.checkPathCanBeRemoved(subPath) {
|
||||
if err := w.watcher.Remove(subPath); err != nil {
|
||||
intlog.Error(context.TODO(), err)
|
||||
if internalErr := w.watcher.Remove(subPath); internalErr != nil {
|
||||
intlog.Error(context.TODO(), internalErr)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Lastly remove the monitor of the path from underlying monitor.
|
||||
return w.watcher.Remove(path)
|
||||
err := w.watcher.Remove(path)
|
||||
if err != nil {
|
||||
err = gerror.Wrapf(err, `remove watch failed for path "%s"`, path)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// checkPathCanBeRemoved checks whether the given path have no callbacks bound.
|
||||
|
@ -18,7 +18,7 @@ const (
|
||||
|
||||
var (
|
||||
// Default logger object, for package method usage.
|
||||
logger = New()
|
||||
defaultLogger = New()
|
||||
|
||||
// Goroutine pool for async logging output.
|
||||
// It uses only one asynchronous worker to ensure log sequence.
|
||||
@ -36,12 +36,12 @@ func init() {
|
||||
|
||||
// DefaultLogger returns the default logger.
|
||||
func DefaultLogger() *Logger {
|
||||
return logger
|
||||
return defaultLogger
|
||||
}
|
||||
|
||||
// SetDefaultLogger sets the default logger for package glog.
|
||||
// Note that there might be concurrent safety issue if calls this function
|
||||
// in different goroutines.
|
||||
func SetDefaultLogger(l *Logger) {
|
||||
logger = l
|
||||
defaultLogger = l
|
||||
}
|
||||
|
@ -11,99 +11,99 @@ import "context"
|
||||
// Print prints `v` with newline using fmt.Sprintln.
|
||||
// The parameter `v` can be multiple variables.
|
||||
func Print(ctx context.Context, v ...interface{}) {
|
||||
logger.Print(ctx, v...)
|
||||
defaultLogger.Print(ctx, v...)
|
||||
}
|
||||
|
||||
// Printf prints `v` with format `format` using fmt.Sprintf.
|
||||
// The parameter `v` can be multiple variables.
|
||||
func Printf(ctx context.Context, format string, v ...interface{}) {
|
||||
logger.Printf(ctx, format, v...)
|
||||
defaultLogger.Printf(ctx, format, v...)
|
||||
}
|
||||
|
||||
// Fatal prints the logging content with [FATA] header and newline, then exit the current process.
|
||||
func Fatal(ctx context.Context, v ...interface{}) {
|
||||
logger.Fatal(ctx, v...)
|
||||
defaultLogger.Fatal(ctx, v...)
|
||||
}
|
||||
|
||||
// Fatalf prints the logging content with [FATA] header, custom format and newline, then exit the current process.
|
||||
func Fatalf(ctx context.Context, format string, v ...interface{}) {
|
||||
logger.Fatalf(ctx, format, v...)
|
||||
defaultLogger.Fatalf(ctx, format, v...)
|
||||
}
|
||||
|
||||
// Panic prints the logging content with [PANI] header and newline, then panics.
|
||||
func Panic(ctx context.Context, v ...interface{}) {
|
||||
logger.Panic(ctx, v...)
|
||||
defaultLogger.Panic(ctx, v...)
|
||||
}
|
||||
|
||||
// Panicf prints the logging content with [PANI] header, custom format and newline, then panics.
|
||||
func Panicf(ctx context.Context, format string, v ...interface{}) {
|
||||
logger.Panicf(ctx, format, v...)
|
||||
defaultLogger.Panicf(ctx, format, v...)
|
||||
}
|
||||
|
||||
// Info prints the logging content with [INFO] header and newline.
|
||||
func Info(ctx context.Context, v ...interface{}) {
|
||||
logger.Info(ctx, v...)
|
||||
defaultLogger.Info(ctx, v...)
|
||||
}
|
||||
|
||||
// Infof prints the logging content with [INFO] header, custom format and newline.
|
||||
func Infof(ctx context.Context, format string, v ...interface{}) {
|
||||
logger.Infof(ctx, format, v...)
|
||||
defaultLogger.Infof(ctx, format, v...)
|
||||
}
|
||||
|
||||
// Debug prints the logging content with [DEBU] header and newline.
|
||||
func Debug(ctx context.Context, v ...interface{}) {
|
||||
logger.Debug(ctx, v...)
|
||||
defaultLogger.Debug(ctx, v...)
|
||||
}
|
||||
|
||||
// Debugf prints the logging content with [DEBU] header, custom format and newline.
|
||||
func Debugf(ctx context.Context, format string, v ...interface{}) {
|
||||
logger.Debugf(ctx, format, v...)
|
||||
defaultLogger.Debugf(ctx, format, v...)
|
||||
}
|
||||
|
||||
// Notice prints the logging content with [NOTI] header and newline.
|
||||
// It also prints caller stack info if stack feature is enabled.
|
||||
func Notice(ctx context.Context, v ...interface{}) {
|
||||
logger.Notice(ctx, v...)
|
||||
defaultLogger.Notice(ctx, v...)
|
||||
}
|
||||
|
||||
// Noticef prints the logging content with [NOTI] header, custom format and newline.
|
||||
// It also prints caller stack info if stack feature is enabled.
|
||||
func Noticef(ctx context.Context, format string, v ...interface{}) {
|
||||
logger.Noticef(ctx, format, v...)
|
||||
defaultLogger.Noticef(ctx, format, v...)
|
||||
}
|
||||
|
||||
// Warning prints the logging content with [WARN] header and newline.
|
||||
// It also prints caller stack info if stack feature is enabled.
|
||||
func Warning(ctx context.Context, v ...interface{}) {
|
||||
logger.Warning(ctx, v...)
|
||||
defaultLogger.Warning(ctx, v...)
|
||||
}
|
||||
|
||||
// Warningf prints the logging content with [WARN] header, custom format and newline.
|
||||
// It also prints caller stack info if stack feature is enabled.
|
||||
func Warningf(ctx context.Context, format string, v ...interface{}) {
|
||||
logger.Warningf(ctx, format, v...)
|
||||
defaultLogger.Warningf(ctx, format, v...)
|
||||
}
|
||||
|
||||
// Error prints the logging content with [ERRO] header and newline.
|
||||
// It also prints caller stack info if stack feature is enabled.
|
||||
func Error(ctx context.Context, v ...interface{}) {
|
||||
logger.Error(ctx, v...)
|
||||
defaultLogger.Error(ctx, v...)
|
||||
}
|
||||
|
||||
// Errorf prints the logging content with [ERRO] header, custom format and newline.
|
||||
// It also prints caller stack info if stack feature is enabled.
|
||||
func Errorf(ctx context.Context, format string, v ...interface{}) {
|
||||
logger.Errorf(ctx, format, v...)
|
||||
defaultLogger.Errorf(ctx, format, v...)
|
||||
}
|
||||
|
||||
// Critical prints the logging content with [CRIT] header and newline.
|
||||
// It also prints caller stack info if stack feature is enabled.
|
||||
func Critical(ctx context.Context, v ...interface{}) {
|
||||
logger.Critical(ctx, v...)
|
||||
defaultLogger.Critical(ctx, v...)
|
||||
}
|
||||
|
||||
// Criticalf prints the logging content with [CRIT] header, custom format and newline.
|
||||
// It also prints caller stack info if stack feature is enabled.
|
||||
func Criticalf(ctx context.Context, format string, v ...interface{}) {
|
||||
logger.Criticalf(ctx, format, v...)
|
||||
defaultLogger.Criticalf(ctx, format, v...)
|
||||
}
|
||||
|
@ -12,87 +12,87 @@ import (
|
||||
|
||||
// Expose returns the default logger of package glog.
|
||||
func Expose() *Logger {
|
||||
return logger
|
||||
return defaultLogger
|
||||
}
|
||||
|
||||
// To is a chaining function,
|
||||
// which redirects current logging content output to the sepecified `writer`.
|
||||
func To(writer io.Writer) *Logger {
|
||||
return logger.To(writer)
|
||||
return defaultLogger.To(writer)
|
||||
}
|
||||
|
||||
// Path is a chaining function,
|
||||
// which sets the directory path to `path` for current logging content output.
|
||||
func Path(path string) *Logger {
|
||||
return logger.Path(path)
|
||||
return defaultLogger.Path(path)
|
||||
}
|
||||
|
||||
// Cat is a chaining function,
|
||||
// which sets the category to `category` for current logging content output.
|
||||
func Cat(category string) *Logger {
|
||||
return logger.Cat(category)
|
||||
return defaultLogger.Cat(category)
|
||||
}
|
||||
|
||||
// File is a chaining function,
|
||||
// which sets file name `pattern` for the current logging content output.
|
||||
func File(pattern string) *Logger {
|
||||
return logger.File(pattern)
|
||||
return defaultLogger.File(pattern)
|
||||
}
|
||||
|
||||
// Level is a chaining function,
|
||||
// which sets logging level for the current logging content output.
|
||||
func Level(level int) *Logger {
|
||||
return logger.Level(level)
|
||||
return defaultLogger.Level(level)
|
||||
}
|
||||
|
||||
// LevelStr is a chaining function,
|
||||
// which sets logging level for the current logging content output using level string.
|
||||
func LevelStr(levelStr string) *Logger {
|
||||
return logger.LevelStr(levelStr)
|
||||
return defaultLogger.LevelStr(levelStr)
|
||||
}
|
||||
|
||||
// Skip is a chaining function,
|
||||
// which sets stack skip for the current logging content output.
|
||||
// It also affects the caller file path checks when line number printing enabled.
|
||||
func Skip(skip int) *Logger {
|
||||
return logger.Skip(skip)
|
||||
return defaultLogger.Skip(skip)
|
||||
}
|
||||
|
||||
// Stack is a chaining function,
|
||||
// which sets stack options for the current logging content output .
|
||||
func Stack(enabled bool, skip ...int) *Logger {
|
||||
return logger.Stack(enabled, skip...)
|
||||
return defaultLogger.Stack(enabled, skip...)
|
||||
}
|
||||
|
||||
// StackWithFilter is a chaining function,
|
||||
// which sets stack filter for the current logging content output .
|
||||
func StackWithFilter(filter string) *Logger {
|
||||
return logger.StackWithFilter(filter)
|
||||
return defaultLogger.StackWithFilter(filter)
|
||||
}
|
||||
|
||||
// Stdout is a chaining function,
|
||||
// which enables/disables stdout for the current logging content output.
|
||||
// It's enabled in default.
|
||||
func Stdout(enabled ...bool) *Logger {
|
||||
return logger.Stdout(enabled...)
|
||||
return defaultLogger.Stdout(enabled...)
|
||||
}
|
||||
|
||||
// Header is a chaining function,
|
||||
// which enables/disables log header for the current logging content output.
|
||||
// It's enabled in default.
|
||||
func Header(enabled ...bool) *Logger {
|
||||
return logger.Header(enabled...)
|
||||
return defaultLogger.Header(enabled...)
|
||||
}
|
||||
|
||||
// Line is a chaining function,
|
||||
// which enables/disables printing its caller file along with its line number.
|
||||
// The parameter `long` specified whether print the long absolute file path, eg: /a/b/c/d.go:23.
|
||||
func Line(long ...bool) *Logger {
|
||||
return logger.Line(long...)
|
||||
return defaultLogger.Line(long...)
|
||||
}
|
||||
|
||||
// Async is a chaining function,
|
||||
// which enables/disables async logging output feature.
|
||||
func Async(enabled ...bool) *Logger {
|
||||
return logger.Async(enabled...)
|
||||
return defaultLogger.Async(enabled...)
|
||||
}
|
||||
|
@ -11,42 +11,42 @@ import (
|
||||
"io"
|
||||
)
|
||||
|
||||
// SetConfig set configurations for the logger.
|
||||
// SetConfig set configurations for the defaultLogger.
|
||||
func SetConfig(config Config) error {
|
||||
return logger.SetConfig(config)
|
||||
return defaultLogger.SetConfig(config)
|
||||
}
|
||||
|
||||
// SetConfigWithMap set configurations with map for the logger.
|
||||
// SetConfigWithMap set configurations with map for the defaultLogger.
|
||||
func SetConfigWithMap(m map[string]interface{}) error {
|
||||
return logger.SetConfigWithMap(m)
|
||||
return defaultLogger.SetConfigWithMap(m)
|
||||
}
|
||||
|
||||
// SetPath sets the directory path for file logging.
|
||||
func SetPath(path string) error {
|
||||
return logger.SetPath(path)
|
||||
return defaultLogger.SetPath(path)
|
||||
}
|
||||
|
||||
// GetPath returns the logging directory path for file logging.
|
||||
// It returns empty string if no directory path set.
|
||||
func GetPath() string {
|
||||
return logger.GetPath()
|
||||
return defaultLogger.GetPath()
|
||||
}
|
||||
|
||||
// SetFile sets the file name `pattern` for file logging.
|
||||
// Datetime pattern can be used in `pattern`, eg: access-{Ymd}.log.
|
||||
// The default file name pattern is: Y-m-d.log, eg: 2018-01-01.log
|
||||
func SetFile(pattern string) {
|
||||
logger.SetFile(pattern)
|
||||
defaultLogger.SetFile(pattern)
|
||||
}
|
||||
|
||||
// SetLevel sets the default logging level.
|
||||
func SetLevel(level int) {
|
||||
logger.SetLevel(level)
|
||||
defaultLogger.SetLevel(level)
|
||||
}
|
||||
|
||||
// GetLevel returns the default logging level value.
|
||||
func GetLevel() int {
|
||||
return logger.GetLevel()
|
||||
return defaultLogger.GetLevel()
|
||||
}
|
||||
|
||||
// SetWriter sets the customized logging `writer` for logging.
|
||||
@ -54,108 +54,108 @@ func GetLevel() int {
|
||||
// Developer can use customized logging `writer` to redirect logging output to another service,
|
||||
// eg: kafka, mysql, mongodb, etc.
|
||||
func SetWriter(writer io.Writer) {
|
||||
logger.SetWriter(writer)
|
||||
defaultLogger.SetWriter(writer)
|
||||
}
|
||||
|
||||
// GetWriter returns the customized writer object, which implements the io.Writer interface.
|
||||
// It returns nil if no customized writer set.
|
||||
func GetWriter() io.Writer {
|
||||
return logger.GetWriter()
|
||||
return defaultLogger.GetWriter()
|
||||
}
|
||||
|
||||
// SetDebug enables/disables the debug level for default logger.
|
||||
// SetDebug enables/disables the debug level for default defaultLogger.
|
||||
// The debug level is enabled in default.
|
||||
func SetDebug(debug bool) {
|
||||
logger.SetDebug(debug)
|
||||
defaultLogger.SetDebug(debug)
|
||||
}
|
||||
|
||||
// SetAsync enables/disables async logging output feature for default logger.
|
||||
// SetAsync enables/disables async logging output feature for default defaultLogger.
|
||||
func SetAsync(enabled bool) {
|
||||
logger.SetAsync(enabled)
|
||||
defaultLogger.SetAsync(enabled)
|
||||
}
|
||||
|
||||
// SetStdoutPrint sets whether ouptput the logging contents to stdout, which is true in default.
|
||||
func SetStdoutPrint(enabled bool) {
|
||||
logger.SetStdoutPrint(enabled)
|
||||
defaultLogger.SetStdoutPrint(enabled)
|
||||
}
|
||||
|
||||
// SetHeaderPrint sets whether output header of the logging contents, which is true in default.
|
||||
func SetHeaderPrint(enabled bool) {
|
||||
logger.SetHeaderPrint(enabled)
|
||||
defaultLogger.SetHeaderPrint(enabled)
|
||||
}
|
||||
|
||||
// SetPrefix sets prefix string for every logging content.
|
||||
// Prefix is part of header, which means if header output is shut, no prefix will be output.
|
||||
func SetPrefix(prefix string) {
|
||||
logger.SetPrefix(prefix)
|
||||
defaultLogger.SetPrefix(prefix)
|
||||
}
|
||||
|
||||
// SetFlags sets extra flags for logging output features.
|
||||
func SetFlags(flags int) {
|
||||
logger.SetFlags(flags)
|
||||
defaultLogger.SetFlags(flags)
|
||||
}
|
||||
|
||||
// GetFlags returns the flags of logger.
|
||||
// GetFlags returns the flags of defaultLogger.
|
||||
func GetFlags() int {
|
||||
return logger.GetFlags()
|
||||
return defaultLogger.GetFlags()
|
||||
}
|
||||
|
||||
// SetCtxKeys sets the context keys for logger. The keys is used for retrieving values
|
||||
// SetCtxKeys sets the context keys for defaultLogger. The keys is used for retrieving values
|
||||
// from context and printing them to logging content.
|
||||
//
|
||||
// Note that multiple calls of this function will overwrite the previous set context keys.
|
||||
func SetCtxKeys(keys ...interface{}) {
|
||||
logger.SetCtxKeys(keys...)
|
||||
defaultLogger.SetCtxKeys(keys...)
|
||||
}
|
||||
|
||||
// GetCtxKeys retrieves and returns the context keys for logging.
|
||||
func GetCtxKeys() []interface{} {
|
||||
return logger.GetCtxKeys()
|
||||
return defaultLogger.GetCtxKeys()
|
||||
}
|
||||
|
||||
// PrintStack prints the caller stack,
|
||||
// the optional parameter `skip` specify the skipped stack offset from the end point.
|
||||
func PrintStack(ctx context.Context, skip ...int) {
|
||||
logger.PrintStack(ctx, skip...)
|
||||
defaultLogger.PrintStack(ctx, skip...)
|
||||
}
|
||||
|
||||
// GetStack returns the caller stack content,
|
||||
// the optional parameter `skip` specify the skipped stack offset from the end point.
|
||||
func GetStack(skip ...int) string {
|
||||
return logger.GetStack(skip...)
|
||||
return defaultLogger.GetStack(skip...)
|
||||
}
|
||||
|
||||
// SetStack enables/disables the stack feature in failure logging outputs.
|
||||
func SetStack(enabled bool) {
|
||||
logger.SetStack(enabled)
|
||||
defaultLogger.SetStack(enabled)
|
||||
}
|
||||
|
||||
// SetLevelStr sets the logging level by level string.
|
||||
func SetLevelStr(levelStr string) error {
|
||||
return logger.SetLevelStr(levelStr)
|
||||
return defaultLogger.SetLevelStr(levelStr)
|
||||
}
|
||||
|
||||
// SetLevelPrefix sets the prefix string for specified level.
|
||||
func SetLevelPrefix(level int, prefix string) {
|
||||
logger.SetLevelPrefix(level, prefix)
|
||||
defaultLogger.SetLevelPrefix(level, prefix)
|
||||
}
|
||||
|
||||
// SetLevelPrefixes sets the level to prefix string mapping for the logger.
|
||||
// SetLevelPrefixes sets the level to prefix string mapping for the defaultLogger.
|
||||
func SetLevelPrefixes(prefixes map[int]string) {
|
||||
logger.SetLevelPrefixes(prefixes)
|
||||
defaultLogger.SetLevelPrefixes(prefixes)
|
||||
}
|
||||
|
||||
// GetLevelPrefix returns the prefix string for specified level.
|
||||
func GetLevelPrefix(level int) string {
|
||||
return logger.GetLevelPrefix(level)
|
||||
return defaultLogger.GetLevelPrefix(level)
|
||||
}
|
||||
|
||||
// SetHandlers sets the logging handlers for default logger.
|
||||
// SetHandlers sets the logging handlers for default defaultLogger.
|
||||
func SetHandlers(handlers ...Handler) {
|
||||
logger.SetHandlers(handlers...)
|
||||
defaultLogger.SetHandlers(handlers...)
|
||||
}
|
||||
|
||||
//SetWriterColorEnable sets the file logging with color
|
||||
func SetWriterColorEnable(enabled bool) {
|
||||
logger.SetWriterColorEnable(enabled)
|
||||
defaultLogger.SetWriterColorEnable(enabled)
|
||||
}
|
||||
|
@ -11,7 +11,6 @@ import (
|
||||
"fmt"
|
||||
|
||||
"github.com/gogf/gf/v2/container/gmap"
|
||||
"github.com/gogf/gf/v2/errors/gcode"
|
||||
"github.com/gogf/gf/v2/errors/gerror"
|
||||
"github.com/gogf/gf/v2/internal/intlog"
|
||||
"github.com/gogf/gf/v2/net/gtcp"
|
||||
@ -89,7 +88,7 @@ func getConnByPid(pid int) (*gtcp.PoolConn, error) {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return nil, gerror.Newf("could not find port for pid: %d", pid)
|
||||
return nil, gerror.Newf(`could not find port for pid "%d"`, pid)
|
||||
}
|
||||
|
||||
// getPortByPid returns the listening port for specified pid.
|
||||
|
@ -93,8 +93,7 @@ func receiveTcpHandler(conn *gtcp.Conn) {
|
||||
if len(buffer) > 0 {
|
||||
// Package decoding.
|
||||
msg := new(MsgRequest)
|
||||
if err := json.UnmarshalUseNumber(buffer, msg); err != nil {
|
||||
// glog.Error(err)
|
||||
if err = json.UnmarshalUseNumber(buffer, msg); err != nil {
|
||||
continue
|
||||
}
|
||||
if msg.RecvPid != Pid() {
|
||||
@ -117,12 +116,12 @@ func receiveTcpHandler(conn *gtcp.Conn) {
|
||||
if err != nil {
|
||||
glog.Error(ctx, err)
|
||||
}
|
||||
if err := conn.SendPkg(result); err != nil {
|
||||
if err = conn.SendPkg(result); err != nil {
|
||||
glog.Error(ctx, err)
|
||||
}
|
||||
} else {
|
||||
// Just close the connection if any error occurs.
|
||||
if err := conn.Close(); err != nil {
|
||||
if err = conn.Close(); err != nil {
|
||||
glog.Error(ctx, err)
|
||||
}
|
||||
break
|
||||
|
@ -10,6 +10,7 @@ import (
|
||||
"os"
|
||||
|
||||
"github.com/gogf/gf/v2/container/gmap"
|
||||
"github.com/gogf/gf/v2/errors/gerror"
|
||||
)
|
||||
|
||||
// Manager is a process manager maintaining multiple processes.
|
||||
@ -97,6 +98,7 @@ func (m *Manager) KillAll() error {
|
||||
func (m *Manager) SignalAll(sig os.Signal) error {
|
||||
for _, p := range m.Processes() {
|
||||
if err := p.Signal(sig); err != nil {
|
||||
err = gerror.Wrapf(err, `send signal to process failed for pid "%d" with signal "%s"`, p.Process.Pid, sig)
|
||||
return err
|
||||
}
|
||||
}
|
||||
@ -106,7 +108,7 @@ func (m *Manager) SignalAll(sig os.Signal) error {
|
||||
// Send sends data bytes to all processes in current manager.
|
||||
func (m *Manager) Send(data []byte) {
|
||||
for _, p := range m.Processes() {
|
||||
p.Send(data)
|
||||
_ = p.Send(data)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -112,23 +112,24 @@ func (p *Process) Release() error {
|
||||
}
|
||||
|
||||
// Kill causes the Process to exit immediately.
|
||||
func (p *Process) Kill() error {
|
||||
if err := p.Process.Kill(); err == nil {
|
||||
if p.Manager != nil {
|
||||
p.Manager.processes.Remove(p.Pid())
|
||||
}
|
||||
if runtime.GOOS != "windows" {
|
||||
if err = p.Process.Release(); err != nil {
|
||||
intlog.Error(context.TODO(), err)
|
||||
}
|
||||
}
|
||||
_, err = p.Process.Wait()
|
||||
intlog.Error(context.TODO(), err)
|
||||
// return err
|
||||
return nil
|
||||
} else {
|
||||
func (p *Process) Kill() (err error) {
|
||||
err = p.Process.Kill()
|
||||
if err != nil {
|
||||
err = gerror.Wrapf(err, `kill process failed for pid "%d"`, p.Process.Pid)
|
||||
return err
|
||||
}
|
||||
if p.Manager != nil {
|
||||
p.Manager.processes.Remove(p.Pid())
|
||||
}
|
||||
if runtime.GOOS != "windows" {
|
||||
if err = p.Process.Release(); err != nil {
|
||||
intlog.Error(context.TODO(), err)
|
||||
}
|
||||
}
|
||||
// It ignores this error, just log it.
|
||||
_, err = p.Process.Wait()
|
||||
intlog.Error(context.TODO(), err)
|
||||
return nil
|
||||
}
|
||||
|
||||
// Signal sends a signal to the Process.
|
||||
|
@ -12,6 +12,7 @@ import (
|
||||
"io"
|
||||
"os"
|
||||
|
||||
"github.com/gogf/gf/v2/errors/gerror"
|
||||
"github.com/gogf/gf/v2/internal/json"
|
||||
)
|
||||
|
||||
@ -36,11 +37,13 @@ func (f *File) Open() (io.ReadCloser, error) {
|
||||
func (f *File) Content() []byte {
|
||||
reader, err := f.Open()
|
||||
if err != nil {
|
||||
err = gerror.Wrapf(err, `open file failed for name "%s"`, f.Name())
|
||||
return nil
|
||||
}
|
||||
defer reader.Close()
|
||||
buffer := bytes.NewBuffer(nil)
|
||||
if _, err := io.Copy(buffer, reader); err != nil {
|
||||
if _, err = io.Copy(buffer, reader); err != nil {
|
||||
err = gerror.Wrapf(err, `read file content failed for name "%s"`, f.Name())
|
||||
return nil
|
||||
}
|
||||
return buffer.Bytes()
|
||||
|
@ -14,12 +14,13 @@ import (
|
||||
|
||||
"github.com/gogf/gf/v2/encoding/gbase64"
|
||||
"github.com/gogf/gf/v2/encoding/gcompress"
|
||||
"github.com/gogf/gf/v2/errors/gerror"
|
||||
"github.com/gogf/gf/v2/os/gfile"
|
||||
"github.com/gogf/gf/v2/text/gstr"
|
||||
)
|
||||
|
||||
const (
|
||||
packedGoSouceTemplate = `
|
||||
packedGoSourceTemplate = `
|
||||
package %s
|
||||
|
||||
import "github.com/gogf/gf/v2/os/gres"
|
||||
@ -80,7 +81,7 @@ func PackToGoFile(srcPath, goFilePath, pkgName string, keyPrefix ...string) erro
|
||||
}
|
||||
return gfile.PutContents(
|
||||
goFilePath,
|
||||
fmt.Sprintf(gstr.TrimLeft(packedGoSouceTemplate), pkgName, gbase64.EncodeToString(data)),
|
||||
fmt.Sprintf(gstr.TrimLeft(packedGoSourceTemplate), pkgName, gbase64.EncodeToString(data)),
|
||||
)
|
||||
}
|
||||
|
||||
@ -95,8 +96,10 @@ func Unpack(path string) ([]*File, error) {
|
||||
|
||||
// UnpackContent unpacks the content to []*File.
|
||||
func UnpackContent(content string) ([]*File, error) {
|
||||
var data []byte
|
||||
var err error
|
||||
var (
|
||||
err error
|
||||
data []byte
|
||||
)
|
||||
if isHexStr(content) {
|
||||
// It here keeps compatible with old version packing string using hex string.
|
||||
// TODO remove this support in the future.
|
||||
@ -122,6 +125,7 @@ func UnpackContent(content string) ([]*File, error) {
|
||||
}
|
||||
reader, err := zip.NewReader(bytes.NewReader(data), int64(len(data)))
|
||||
if err != nil {
|
||||
err = gerror.Wrapf(err, `create zip reader failed`)
|
||||
return nil, err
|
||||
}
|
||||
array := make([]*File, len(reader.File))
|
||||
@ -167,6 +171,6 @@ func isHexStr(s string) bool {
|
||||
func hexStrToBytes(s string) []byte {
|
||||
src := []byte(s)
|
||||
dst := make([]byte, hex.DecodedLen(len(src)))
|
||||
hex.Decode(dst, src)
|
||||
_, _ = hex.Decode(dst, src)
|
||||
return dst
|
||||
}
|
||||
|
@ -14,6 +14,7 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/gogf/gf/v2/errors/gerror"
|
||||
"github.com/gogf/gf/v2/internal/fileinfo"
|
||||
"github.com/gogf/gf/v2/internal/intlog"
|
||||
"github.com/gogf/gf/v2/os/gfile"
|
||||
@ -75,8 +76,7 @@ func doZipPathWriter(path string, exclude string, zipWriter *zip.Writer, prefix
|
||||
intlog.Printf(context.TODO(), `exclude file path: %s`, file)
|
||||
continue
|
||||
}
|
||||
err = zipFile(file, headerPrefix+gfile.Dir(file[len(path):]), zipWriter)
|
||||
if err != nil {
|
||||
if err = zipFile(file, headerPrefix+gfile.Dir(file[len(path):]), zipWriter); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
@ -86,10 +86,7 @@ func doZipPathWriter(path string, exclude string, zipWriter *zip.Writer, prefix
|
||||
path = headerPrefix
|
||||
for {
|
||||
name = strings.Replace(gfile.Basename(path), `\`, `/`, -1)
|
||||
err = zipFileVirtual(
|
||||
fileinfo.New(name, 0, os.ModeDir|os.ModePerm, time.Now()), path, zipWriter,
|
||||
)
|
||||
if err != nil {
|
||||
if err = zipFileVirtual(fileinfo.New(name, 0, os.ModeDir|os.ModePerm, time.Now()), path, zipWriter); err != nil {
|
||||
return err
|
||||
}
|
||||
if path == `/` || !strings.Contains(path, `/`) {
|
||||
@ -107,11 +104,13 @@ func zipFile(path string, prefix string, zw *zip.Writer) error {
|
||||
prefix = strings.Replace(prefix, `//`, `/`, -1)
|
||||
file, err := os.Open(path)
|
||||
if err != nil {
|
||||
err = gerror.Wrapf(err, `os.Open failed for file "%s"`, path)
|
||||
return nil
|
||||
}
|
||||
defer file.Close()
|
||||
info, err := file.Stat()
|
||||
if err != nil {
|
||||
err = gerror.Wrapf(err, `read file stat failed for file "%s"`, path)
|
||||
return err
|
||||
}
|
||||
header, err := createFileHeader(info, prefix)
|
||||
@ -123,10 +122,12 @@ func zipFile(path string, prefix string, zw *zip.Writer) error {
|
||||
}
|
||||
writer, err := zw.CreateHeader(header)
|
||||
if err != nil {
|
||||
err = gerror.Wrapf(err, `create zip header failed for %#v`, header)
|
||||
return err
|
||||
}
|
||||
if !info.IsDir() {
|
||||
if _, err = io.Copy(writer, file); err != nil {
|
||||
err = gerror.Wrapf(err, `io.Copy failed for file "%s"`, path)
|
||||
return err
|
||||
}
|
||||
}
|
||||
@ -140,6 +141,7 @@ func zipFileVirtual(info os.FileInfo, path string, zw *zip.Writer) error {
|
||||
}
|
||||
header.Name = path
|
||||
if _, err = zw.CreateHeader(header); err != nil {
|
||||
err = gerror.Wrapf(err, `create zip header failed for %#v`, header)
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
@ -148,6 +150,7 @@ func zipFileVirtual(info os.FileInfo, path string, zw *zip.Writer) error {
|
||||
func createFileHeader(info os.FileInfo, prefix string) (*zip.FileHeader, error) {
|
||||
header, err := zip.FileInfoHeader(info)
|
||||
if err != nil {
|
||||
err = gerror.Wrapf(err, `create file header failed for name "%s"`, info.Name())
|
||||
return nil, err
|
||||
}
|
||||
if len(prefix) > 0 {
|
||||
|
@ -9,6 +9,8 @@ package gres
|
||||
import (
|
||||
"bytes"
|
||||
"os"
|
||||
|
||||
"github.com/gogf/gf/v2/errors/gerror"
|
||||
)
|
||||
|
||||
// Close implements interface of http.File.
|
||||
@ -43,16 +45,22 @@ func (f *File) Read(b []byte) (n int, err error) {
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return reader.Read(b)
|
||||
if n, err = reader.Read(b); err != nil {
|
||||
err = gerror.Wrapf(err, `read content failed`)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Seek implements the io.Seeker interface.
|
||||
func (f *File) Seek(offset int64, whence int) (int64, error) {
|
||||
func (f *File) Seek(offset int64, whence int) (n int64, err error) {
|
||||
reader, err := f.getReader()
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return reader.Seek(offset, whence)
|
||||
if n, err = reader.Seek(offset, whence); err != nil {
|
||||
err = gerror.Wrapf(err, `seek failed for offset %d, whence %d`, offset, whence)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (f *File) getReader() (*bytes.Reader, error) {
|
||||
|
@ -32,13 +32,16 @@ type StorageFile struct {
|
||||
updatingIdSet *gset.StrSet
|
||||
}
|
||||
|
||||
var (
|
||||
DefaultStorageFilePath = gfile.TempDir("gsessions")
|
||||
DefaultStorageFileCryptoKey = []byte("Session storage file crypto key!")
|
||||
const (
|
||||
DefaultStorageFileCryptoEnabled = false
|
||||
DefaultStorageFileLoopInterval = 10 * time.Second
|
||||
)
|
||||
|
||||
var (
|
||||
DefaultStorageFilePath = gfile.TempDir("gsessions")
|
||||
DefaultStorageFileCryptoKey = []byte("Session storage file crypto key!")
|
||||
)
|
||||
|
||||
// NewStorageFile creates and returns a file storage object for session.
|
||||
func NewStorageFile(path ...string) *StorageFile {
|
||||
storagePath := DefaultStorageFilePath
|
||||
@ -112,7 +115,7 @@ func (s *StorageFile) Get(ctx context.Context, id string, key string) (value int
|
||||
return nil, ErrorDisabled
|
||||
}
|
||||
|
||||
// GetMap retrieves all key-value pairs as map from storage.
|
||||
// Data retrieves all key-value pairs as map from storage.
|
||||
func (s *StorageFile) Data(ctx context.Context, id string) (data map[string]interface{}, err error) {
|
||||
return nil, ErrorDisabled
|
||||
}
|
||||
@ -208,9 +211,11 @@ func (s *StorageFile) SetSession(ctx context.Context, id string, data *gmap.StrA
|
||||
}
|
||||
defer file.Close()
|
||||
if _, err = file.Write(gbinary.EncodeInt64(gtime.TimestampMilli())); err != nil {
|
||||
err = gerror.Wrapf(err, `write data failed to file "%s"`, path)
|
||||
return err
|
||||
}
|
||||
if _, err = file.Write(content); err != nil {
|
||||
err = gerror.Wrapf(err, `write data failed to file "%s"`, path)
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
@ -236,6 +241,7 @@ func (s *StorageFile) updateSessionTTl(ctx context.Context, id string) error {
|
||||
return err
|
||||
}
|
||||
if _, err = file.WriteAt(gbinary.EncodeInt64(gtime.TimestampMilli()), 0); err != nil {
|
||||
err = gerror.Wrapf(err, `write data failed to file "%s"`, path)
|
||||
return err
|
||||
}
|
||||
return file.Close()
|
||||
|
@ -24,7 +24,7 @@ type StorageRedis struct {
|
||||
updatingIdMap *gmap.StrIntMap // Updating TTL set for session id.
|
||||
}
|
||||
|
||||
var (
|
||||
const (
|
||||
// DefaultStorageRedisLoopInterval is the interval updating TTL for session ids
|
||||
// in last duration.
|
||||
DefaultStorageRedisLoopInterval = 10 * time.Second
|
||||
|
@ -108,12 +108,20 @@ var (
|
||||
//
|
||||
// This should be called before package "time" import.
|
||||
// Please refer to issue: https://github.com/golang/go/issues/34814
|
||||
func SetTimeZone(zone string) error {
|
||||
func SetTimeZone(zone string) (err error) {
|
||||
location, err := time.LoadLocation(zone)
|
||||
if err != nil {
|
||||
err = gerror.Wrapf(err, `time.LoadLocation failed for zone "%s"`, zone)
|
||||
return err
|
||||
}
|
||||
return os.Setenv("TZ", location.String())
|
||||
var (
|
||||
envKey = "TZ"
|
||||
envValue = location.String()
|
||||
)
|
||||
if err = os.Setenv(envKey, envValue); err != nil {
|
||||
err = gerror.Wrapf(err, `set environment failed with key "%s", value "%s"`, envKey, envValue)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Timestamp retrieves and returns the timestamp in seconds.
|
||||
@ -348,22 +356,14 @@ func ConvertZone(strTime string, toZone string, fromZone ...string) (*Time, erro
|
||||
var l *time.Location
|
||||
if len(fromZone) > 0 {
|
||||
if l, err = time.LoadLocation(fromZone[0]); err != nil {
|
||||
err = gerror.WrapCodef(
|
||||
gcode.CodeInvalidParameter, err,
|
||||
`time.LoadLocation failed for name "%s"`,
|
||||
fromZone[0],
|
||||
)
|
||||
err = gerror.WrapCodef(gcode.CodeInvalidParameter, err, `time.LoadLocation failed for name "%s"`, fromZone[0])
|
||||
return nil, err
|
||||
} else {
|
||||
t.Time = time.Date(t.Year(), time.Month(t.Month()), t.Day(), t.Hour(), t.Minute(), t.Time.Second(), t.Time.Nanosecond(), l)
|
||||
}
|
||||
}
|
||||
if l, err = time.LoadLocation(toZone); err != nil {
|
||||
err = gerror.WrapCodef(
|
||||
gcode.CodeInvalidParameter, err,
|
||||
`time.LoadLocation failed for name "%s"`,
|
||||
toZone,
|
||||
)
|
||||
err = gerror.WrapCodef(gcode.CodeInvalidParameter, err, `time.LoadLocation failed for name "%s"`, toZone)
|
||||
return nil, err
|
||||
} else {
|
||||
return t.ToLocation(l), nil
|
||||
|
@ -253,6 +253,7 @@ func (t *Time) Add(d time.Duration) *Time {
|
||||
// AddStr parses the given duration as string and adds it to current time.
|
||||
func (t *Time) AddStr(duration string) (*Time, error) {
|
||||
if d, err := time.ParseDuration(duration); err != nil {
|
||||
err = gerror.Wrapf(err, `time.ParseDuration failed for string "%s"`, duration)
|
||||
return nil, err
|
||||
} else {
|
||||
return t.Add(d), nil
|
||||
@ -475,6 +476,4 @@ func (t *Time) UnmarshalText(data []byte) error {
|
||||
}
|
||||
|
||||
// NoValidation marks this struct object will not be validated by package gvalid.
|
||||
func (t *Time) NoValidation() {
|
||||
|
||||
}
|
||||
func (t *Time) NoValidation() {}
|
||||
|
@ -9,6 +9,8 @@ package gtime
|
||||
import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/gogf/gf/v2/errors/gerror"
|
||||
)
|
||||
|
||||
var (
|
||||
@ -42,7 +44,10 @@ func (t *Time) getLocationByZoneName(name string) (location *time.Location, err
|
||||
locationMu.RUnlock()
|
||||
if location == nil {
|
||||
location, err = time.LoadLocation(name)
|
||||
if err == nil && location != nil {
|
||||
if err != nil {
|
||||
err = gerror.Wrapf(err, `time.LoadLocation failed for name "%s"`, name)
|
||||
}
|
||||
if location != nil {
|
||||
locationMu.Lock()
|
||||
locationMap[name] = location
|
||||
locationMu.Unlock()
|
||||
|
@ -151,6 +151,5 @@ func New(path ...string) *View {
|
||||
"times": view.buildInFuncTimes,
|
||||
"divide": view.buildInFuncDivide,
|
||||
})
|
||||
|
||||
return view
|
||||
}
|
||||
|
@ -126,7 +126,7 @@ func (view *View) SetPath(path string) error {
|
||||
}
|
||||
// Path not exist.
|
||||
if realPath == "" {
|
||||
err := gerror.NewCodef(gcode.CodeInvalidParameter, `[gview] SetPath failed: path "%s" does not exist`, path)
|
||||
err := gerror.NewCodef(gcode.CodeInvalidParameter, `View.SetPath failed: path "%s" does not exist`, path)
|
||||
if errorPrint() {
|
||||
glog.Error(ctx, err)
|
||||
}
|
||||
@ -134,7 +134,7 @@ func (view *View) SetPath(path string) error {
|
||||
}
|
||||
// Should be a directory.
|
||||
if !isDir {
|
||||
err := gerror.NewCodef(gcode.CodeInvalidParameter, `[gview] SetPath failed: path "%s" should be directory type`, path)
|
||||
err := gerror.NewCodef(gcode.CodeInvalidParameter, `View.SetPath failed: path "%s" should be directory type`, path)
|
||||
if errorPrint() {
|
||||
glog.Error(ctx, err)
|
||||
}
|
||||
@ -147,11 +147,10 @@ func (view *View) SetPath(path string) error {
|
||||
view.searchPaths.Clear()
|
||||
view.searchPaths.Append(realPath)
|
||||
view.fileCacheMap.Clear()
|
||||
// glog.Debug("[gview] SetPath:", realPath)
|
||||
return nil
|
||||
}
|
||||
|
||||
// AddPath adds a absolute or relative path to the search paths.
|
||||
// AddPath adds an absolute or relative path to the search paths.
|
||||
func (view *View) AddPath(path string) error {
|
||||
var (
|
||||
ctx = context.TODO()
|
||||
@ -163,13 +162,12 @@ func (view *View) AddPath(path string) error {
|
||||
isDir = file.FileInfo().IsDir()
|
||||
} else {
|
||||
// Absolute path.
|
||||
realPath = gfile.RealPath(path)
|
||||
if realPath == "" {
|
||||
if realPath = gfile.RealPath(path); realPath == "" {
|
||||
// Relative path.
|
||||
view.searchPaths.RLockFunc(func(array []string) {
|
||||
for _, v := range array {
|
||||
if path, _ := gspath.Search(v, path); path != "" {
|
||||
realPath = path
|
||||
if searchedPath, _ := gspath.Search(v, path); searchedPath != "" {
|
||||
realPath = searchedPath
|
||||
break
|
||||
}
|
||||
}
|
||||
@ -181,7 +179,7 @@ func (view *View) AddPath(path string) error {
|
||||
}
|
||||
// Path not exist.
|
||||
if realPath == "" {
|
||||
err := gerror.NewCodef(gcode.CodeInvalidParameter, `[gview] AddPath failed: path "%s" does not exist`, path)
|
||||
err := gerror.NewCodef(gcode.CodeInvalidParameter, `View.AddPath failed: path "%s" does not exist`, path)
|
||||
if errorPrint() {
|
||||
glog.Error(ctx, err)
|
||||
}
|
||||
@ -189,7 +187,7 @@ func (view *View) AddPath(path string) error {
|
||||
}
|
||||
// realPath should be type of folder.
|
||||
if !isDir {
|
||||
err := gerror.NewCodef(gcode.CodeInvalidParameter, `[gview] AddPath failed: path "%s" should be directory type`, path)
|
||||
err := gerror.NewCodef(gcode.CodeInvalidParameter, `View.AddPath failed: path "%s" should be directory type`, path)
|
||||
if errorPrint() {
|
||||
glog.Error(ctx, err)
|
||||
}
|
||||
|
@ -164,20 +164,22 @@ func (view *View) ParseContent(ctx context.Context, content string, params ...Pa
|
||||
if content == "" {
|
||||
return "", nil
|
||||
}
|
||||
err := (error)(nil)
|
||||
key := fmt.Sprintf("%s_%v_%v", templateNameForContentParsing, view.config.Delimiters, view.config.AutoEncode)
|
||||
tpl := templates.GetOrSetFuncLock(key, func() interface{} {
|
||||
if view.config.AutoEncode {
|
||||
return htmltpl.New(templateNameForContentParsing).Delims(
|
||||
var (
|
||||
err error
|
||||
key = fmt.Sprintf("%s_%v_%v", templateNameForContentParsing, view.config.Delimiters, view.config.AutoEncode)
|
||||
tpl = templates.GetOrSetFuncLock(key, func() interface{} {
|
||||
if view.config.AutoEncode {
|
||||
return htmltpl.New(templateNameForContentParsing).Delims(
|
||||
view.config.Delimiters[0],
|
||||
view.config.Delimiters[1],
|
||||
).Funcs(view.funcMap)
|
||||
}
|
||||
return texttpl.New(templateNameForContentParsing).Delims(
|
||||
view.config.Delimiters[0],
|
||||
view.config.Delimiters[1],
|
||||
).Funcs(view.funcMap)
|
||||
}
|
||||
return texttpl.New(templateNameForContentParsing).Delims(
|
||||
view.config.Delimiters[0],
|
||||
view.config.Delimiters[1],
|
||||
).Funcs(view.funcMap)
|
||||
})
|
||||
})
|
||||
)
|
||||
// Using memory lock to ensure concurrent safety for content parsing.
|
||||
hash := strconv.FormatUint(ghash.DJBHash64([]byte(content)), 10)
|
||||
gmlock.LockFunc("gview.ParseContent:"+hash, func() {
|
||||
@ -188,6 +190,7 @@ func (view *View) ParseContent(ctx context.Context, content string, params ...Pa
|
||||
}
|
||||
})
|
||||
if err != nil {
|
||||
err = gerror.Wrapf(err, `template parsing failed`)
|
||||
return "", err
|
||||
}
|
||||
// Note that the template variable assignment cannot change the value
|
||||
@ -201,15 +204,19 @@ func (view *View) ParseContent(ctx context.Context, content string, params ...Pa
|
||||
|
||||
buffer := bytes.NewBuffer(nil)
|
||||
if view.config.AutoEncode {
|
||||
newTpl, err := tpl.(*htmltpl.Template).Clone()
|
||||
var newTpl *htmltpl.Template
|
||||
newTpl, err = tpl.(*htmltpl.Template).Clone()
|
||||
if err != nil {
|
||||
err = gerror.Wrapf(err, `template clone failed`)
|
||||
return "", err
|
||||
}
|
||||
if err := newTpl.Execute(buffer, variables); err != nil {
|
||||
if err = newTpl.Execute(buffer, variables); err != nil {
|
||||
err = gerror.Wrapf(err, `template parsing failed`)
|
||||
return "", err
|
||||
}
|
||||
} else {
|
||||
if err := tpl.(*texttpl.Template).Execute(buffer, variables); err != nil {
|
||||
if err = tpl.(*texttpl.Template).Execute(buffer, variables); err != nil {
|
||||
err = gerror.Wrapf(err, `template parsing failed`)
|
||||
return "", err
|
||||
}
|
||||
}
|
||||
@ -224,85 +231,86 @@ func (view *View) ParseContent(ctx context.Context, content string, params ...Pa
|
||||
// with the same given `path`. It will also automatically refresh the template cache
|
||||
// if the template files under `path` changes (recursively).
|
||||
func (view *View) getTemplate(filePath, folderPath, pattern string) (tpl interface{}, err error) {
|
||||
// Key for template cache.
|
||||
key := fmt.Sprintf("%s_%v", filePath, view.config.Delimiters)
|
||||
result := templates.GetOrSetFuncLock(key, func() interface{} {
|
||||
tplName := filePath
|
||||
if view.config.AutoEncode {
|
||||
tpl = htmltpl.New(tplName).Delims(
|
||||
view.config.Delimiters[0],
|
||||
view.config.Delimiters[1],
|
||||
).Funcs(view.funcMap)
|
||||
} else {
|
||||
tpl = texttpl.New(tplName).Delims(
|
||||
view.config.Delimiters[0],
|
||||
view.config.Delimiters[1],
|
||||
).Funcs(view.funcMap)
|
||||
}
|
||||
// Firstly checking the resource manager.
|
||||
if !gres.IsEmpty() {
|
||||
if files := gres.ScanDirFile(folderPath, pattern, true); len(files) > 0 {
|
||||
var err error
|
||||
if view.config.AutoEncode {
|
||||
t := tpl.(*htmltpl.Template)
|
||||
for _, v := range files {
|
||||
_, err = t.New(v.FileInfo().Name()).Parse(string(v.Content()))
|
||||
if err != nil {
|
||||
err = view.formatTemplateObjectCreatingError(v.Name(), tplName, err)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
} else {
|
||||
t := tpl.(*texttpl.Template)
|
||||
for _, v := range files {
|
||||
_, err = t.New(v.FileInfo().Name()).Parse(string(v.Content()))
|
||||
if err != nil {
|
||||
err = view.formatTemplateObjectCreatingError(v.Name(), tplName, err)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
return tpl
|
||||
var (
|
||||
mapKey = fmt.Sprintf("%s_%v", filePath, view.config.Delimiters)
|
||||
mapFunc = func() interface{} {
|
||||
tplName := filePath
|
||||
if view.config.AutoEncode {
|
||||
tpl = htmltpl.New(tplName).Delims(
|
||||
view.config.Delimiters[0],
|
||||
view.config.Delimiters[1],
|
||||
).Funcs(view.funcMap)
|
||||
} else {
|
||||
tpl = texttpl.New(tplName).Delims(
|
||||
view.config.Delimiters[0],
|
||||
view.config.Delimiters[1],
|
||||
).Funcs(view.funcMap)
|
||||
}
|
||||
// Firstly checking the resource manager.
|
||||
if !gres.IsEmpty() {
|
||||
if files := gres.ScanDirFile(folderPath, pattern, true); len(files) > 0 {
|
||||
if view.config.AutoEncode {
|
||||
var t = tpl.(*htmltpl.Template)
|
||||
for _, v := range files {
|
||||
_, err = t.New(v.FileInfo().Name()).Parse(string(v.Content()))
|
||||
if err != nil {
|
||||
err = view.formatTemplateObjectCreatingError(v.Name(), tplName, err)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
} else {
|
||||
var t = tpl.(*texttpl.Template)
|
||||
for _, v := range files {
|
||||
_, err = t.New(v.FileInfo().Name()).Parse(string(v.Content()))
|
||||
if err != nil {
|
||||
err = view.formatTemplateObjectCreatingError(v.Name(), tplName, err)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
return tpl
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Secondly checking the file system.
|
||||
var (
|
||||
files []string
|
||||
)
|
||||
files, err = gfile.ScanDir(folderPath, pattern, true)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
if view.config.AutoEncode {
|
||||
t := tpl.(*htmltpl.Template)
|
||||
for _, file := range files {
|
||||
if _, err = t.Parse(gfile.GetContents(file)); err != nil {
|
||||
err = view.formatTemplateObjectCreatingError(file, tplName, err)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
} else {
|
||||
t := tpl.(*texttpl.Template)
|
||||
for _, file := range files {
|
||||
if _, err = t.Parse(gfile.GetContents(file)); err != nil {
|
||||
err = view.formatTemplateObjectCreatingError(file, tplName, err)
|
||||
return nil
|
||||
// Secondly checking the file system.
|
||||
var (
|
||||
files []string
|
||||
)
|
||||
files, err = gfile.ScanDir(folderPath, pattern, true)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
if view.config.AutoEncode {
|
||||
t := tpl.(*htmltpl.Template)
|
||||
for _, file := range files {
|
||||
if _, err = t.Parse(gfile.GetContents(file)); err != nil {
|
||||
err = view.formatTemplateObjectCreatingError(file, tplName, err)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
} else {
|
||||
t := tpl.(*texttpl.Template)
|
||||
for _, file := range files {
|
||||
if _, err = t.Parse(gfile.GetContents(file)); err != nil {
|
||||
err = view.formatTemplateObjectCreatingError(file, tplName, err)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
return tpl
|
||||
}
|
||||
return tpl
|
||||
})
|
||||
)
|
||||
result := templates.GetOrSetFuncLock(mapKey, mapFunc)
|
||||
if result != nil {
|
||||
return result, nil
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// formatTemplateObjectCreatingError formats the error that creted from creating template object.
|
||||
// formatTemplateObjectCreatingError formats the error that created from creating template object.
|
||||
func (view *View) formatTemplateObjectCreatingError(filePath, tplName string, err error) error {
|
||||
if err != nil {
|
||||
return gerror.NewCodeSkip(gcode.CodeInternalError, 1, gstr.Replace(err.Error(), tplName, filePath))
|
||||
return gerror.NewSkip(1, gstr.Replace(err.Error(), tplName, filePath))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@ -363,7 +371,7 @@ func (view *View) searchFile(ctx context.Context, file string) (path string, fol
|
||||
if path == "" {
|
||||
buffer := bytes.NewBuffer(nil)
|
||||
if view.searchPaths.Len() > 0 {
|
||||
buffer.WriteString(fmt.Sprintf("[gview] cannot find template file \"%s\" in following paths:", file))
|
||||
buffer.WriteString(fmt.Sprintf("cannot find template file \"%s\" in following paths:", file))
|
||||
view.searchPaths.RLockFunc(func(array []string) {
|
||||
index := 1
|
||||
for _, searchPath := range array {
|
||||
@ -378,7 +386,7 @@ func (view *View) searchFile(ctx context.Context, file string) (path string, fol
|
||||
}
|
||||
})
|
||||
} else {
|
||||
buffer.WriteString(fmt.Sprintf("[gview] cannot find template file \"%s\" with no path set/add", file))
|
||||
buffer.WriteString(fmt.Sprintf("cannot find template file \"%s\" with no path set/add", file))
|
||||
}
|
||||
if errorPrint() {
|
||||
glog.Error(ctx, buffer.String())
|
||||
|
@ -9,6 +9,8 @@ package gregex
|
||||
import (
|
||||
"regexp"
|
||||
"sync"
|
||||
|
||||
"github.com/gogf/gf/v2/errors/gerror"
|
||||
)
|
||||
|
||||
var (
|
||||
@ -38,6 +40,7 @@ func getRegexp(pattern string) (regex *regexp.Regexp, err error) {
|
||||
// it compiles the pattern and creates one.
|
||||
regex, err = regexp.Compile(pattern)
|
||||
if err != nil {
|
||||
err = gerror.Wrapf(err, `regexp.Compile failed for pattern "%s"`, pattern)
|
||||
return
|
||||
}
|
||||
// Cache the result object using writing lock.
|
||||
|
@ -7,10 +7,11 @@
|
||||
package gstr
|
||||
|
||||
import (
|
||||
"github.com/gogf/gf/v2/errors/gcode"
|
||||
"github.com/gogf/gf/v2/errors/gerror"
|
||||
"net/url"
|
||||
"strings"
|
||||
|
||||
"github.com/gogf/gf/v2/errors/gcode"
|
||||
"github.com/gogf/gf/v2/errors/gerror"
|
||||
)
|
||||
|
||||
// Parse parses the string into map[string]interface{}.
|
||||
@ -37,6 +38,7 @@ func Parse(s string) (result map[string]interface{}, err error) {
|
||||
}
|
||||
key, err := url.QueryUnescape(part[:pos])
|
||||
if err != nil {
|
||||
err = gerror.Wrapf(err, `url.QueryUnescape failed for string "%s"`, part[:pos])
|
||||
return nil, err
|
||||
}
|
||||
for key[0] == ' ' {
|
||||
@ -47,6 +49,7 @@ func Parse(s string) (result map[string]interface{}, err error) {
|
||||
}
|
||||
value, err := url.QueryUnescape(part[pos+1:])
|
||||
if err != nil {
|
||||
err = gerror.Wrapf(err, `url.QueryUnescape failed for string "%s"`, part[pos+1:])
|
||||
return nil, err
|
||||
}
|
||||
// split into multiple keys
|
||||
@ -87,7 +90,7 @@ func Parse(s string) (result map[string]interface{}, err error) {
|
||||
keys[0] = first
|
||||
|
||||
// build nested map
|
||||
if err := build(result, keys, value); err != nil {
|
||||
if err = build(result, keys, value); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
@ -96,9 +99,10 @@ func Parse(s string) (result map[string]interface{}, err error) {
|
||||
|
||||
// build nested map.
|
||||
func build(result map[string]interface{}, keys []string, value interface{}) error {
|
||||
length := len(keys)
|
||||
// trim ',"
|
||||
key := strings.Trim(keys[0], "'\"")
|
||||
var (
|
||||
length = len(keys)
|
||||
key = strings.Trim(keys[0], "'\"")
|
||||
)
|
||||
if length == 1 {
|
||||
result[key] = value
|
||||
return nil
|
||||
@ -145,13 +149,13 @@ func build(result map[string]interface{}, keys []string, value interface{}) erro
|
||||
if l := len(children); l > 0 {
|
||||
if child, ok := children[l-1].(map[string]interface{}); ok {
|
||||
if _, ok := child[keys[2]]; !ok {
|
||||
build(child, keys[2:], value)
|
||||
_ = build(child, keys[2:], value)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
child := map[string]interface{}{}
|
||||
build(child, keys[2:], value)
|
||||
_ = build(child, keys[2:], value)
|
||||
result[key] = append(children, child)
|
||||
return nil
|
||||
}
|
||||
|
@ -8,7 +8,6 @@
|
||||
package gutil
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
|
||||
"github.com/gogf/gf/v2/errors/gerror"
|
||||
@ -49,7 +48,7 @@ func TryCatch(try func(), catch ...func(exception error)) {
|
||||
if v, ok := exception.(error); ok && gerror.HasStack(v) {
|
||||
catch[0](v)
|
||||
} else {
|
||||
catch[0](fmt.Errorf(`%+v`, exception))
|
||||
catch[0](gerror.Newf(`%+v`, exception))
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
Loading…
x
Reference in New Issue
Block a user