mirror of
https://gitee.com/johng/gf
synced 2026-06-06 02:25:47 +08:00
improve internal/debug,glog,garray,gfile
This commit is contained in:
@ -5,3 +5,63 @@
|
||||
// You can obtain one at https://github.com/gogf/gf.
|
||||
|
||||
package garray
|
||||
|
||||
import "strings"
|
||||
|
||||
func defaultComparatorInt(a, b int) int {
|
||||
if a < b {
|
||||
return -1
|
||||
}
|
||||
if a > b {
|
||||
return 1
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func defaultComparatorStr(a, b string) int {
|
||||
return strings.Compare(a, b)
|
||||
}
|
||||
|
||||
// quickSortInt is the quick-sorting algorithm implements for int.
|
||||
func quickSortInt(values []int, comparator func(a, b int) int) {
|
||||
if len(values) <= 1 {
|
||||
return
|
||||
}
|
||||
mid, i := values[0], 1
|
||||
head, tail := 0, len(values)-1
|
||||
for head < tail {
|
||||
if comparator(values[i], mid) > 0 {
|
||||
values[i], values[tail] = values[tail], values[i]
|
||||
tail--
|
||||
} else {
|
||||
values[i], values[head] = values[head], values[i]
|
||||
head++
|
||||
i++
|
||||
}
|
||||
}
|
||||
values[head] = mid
|
||||
quickSortInt(values[:head], comparator)
|
||||
quickSortInt(values[head+1:], comparator)
|
||||
}
|
||||
|
||||
// quickSortStr is the quick-sorting algorithm implements for string.
|
||||
func quickSortStr(values []string, comparator func(a, b string) int) {
|
||||
if len(values) <= 1 {
|
||||
return
|
||||
}
|
||||
mid, i := values[0], 1
|
||||
head, tail := 0, len(values)-1
|
||||
for head < tail {
|
||||
if comparator(values[i], mid) > 0 {
|
||||
values[i], values[tail] = values[tail], values[i]
|
||||
tail--
|
||||
} else {
|
||||
values[i], values[head] = values[head], values[i]
|
||||
head++
|
||||
i++
|
||||
}
|
||||
}
|
||||
values[head] = mid
|
||||
quickSortStr(values[:head], comparator)
|
||||
quickSortStr(values[head+1:], comparator)
|
||||
}
|
||||
|
||||
@ -22,8 +22,8 @@ import (
|
||||
type SortedIntArray struct {
|
||||
mu *rwmutex.RWMutex
|
||||
array []int
|
||||
unique *gtype.Bool // Whether enable unique feature(false)
|
||||
comparator func(v1, v2 int) int // Comparison function(it returns -1: v1 < v2; 0: v1 == v2; 1: v1 > v2)
|
||||
unique *gtype.Bool // Whether enable unique feature(false)
|
||||
comparator func(a, b int) int // Comparison function(it returns -1: a < b; 0: a == b; 1: a > b)
|
||||
}
|
||||
|
||||
// NewSortedIntArray creates and returns an empty sorted array.
|
||||
@ -33,23 +33,23 @@ func NewSortedIntArray(safe ...bool) *SortedIntArray {
|
||||
return NewSortedIntArraySize(0, safe...)
|
||||
}
|
||||
|
||||
// NewSortedIntArrayComparator creates and returns an empty sorted array with specified comparator.
|
||||
// The parameter <safe> used to specify whether using array in concurrent-safety which is false in default.
|
||||
func NewSortedIntArrayComparator(comparator func(a, b int) int, safe ...bool) *SortedIntArray {
|
||||
array := NewSortedIntArray(safe...)
|
||||
array.comparator = comparator
|
||||
return array
|
||||
}
|
||||
|
||||
// NewSortedIntArraySize create and returns an sorted array with given size and cap.
|
||||
// The parameter <safe> used to specify whether using array in concurrent-safety,
|
||||
// which is false in default.
|
||||
func NewSortedIntArraySize(cap int, safe ...bool) *SortedIntArray {
|
||||
return &SortedIntArray{
|
||||
mu: rwmutex.New(safe...),
|
||||
array: make([]int, 0, cap),
|
||||
unique: gtype.NewBool(),
|
||||
comparator: func(v1, v2 int) int {
|
||||
if v1 < v2 {
|
||||
return -1
|
||||
}
|
||||
if v1 > v2 {
|
||||
return 1
|
||||
}
|
||||
return 0
|
||||
},
|
||||
mu: rwmutex.New(safe...),
|
||||
array: make([]int, 0, cap),
|
||||
unique: gtype.NewBool(),
|
||||
comparator: defaultComparatorInt,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -22,8 +22,8 @@ import (
|
||||
type SortedArray struct {
|
||||
mu *rwmutex.RWMutex
|
||||
array []interface{}
|
||||
unique *gtype.Bool // Whether enable unique feature(false)
|
||||
comparator func(v1, v2 interface{}) int // Comparison function(it returns -1: v1 < v2; 0: v1 == v2; 1: v1 > v2)
|
||||
unique *gtype.Bool // Whether enable unique feature(false)
|
||||
comparator func(a, b interface{}) int // Comparison function(it returns -1: a < b; 0: a == b; 1: a > b)
|
||||
}
|
||||
|
||||
// NewSortedArray creates and returns an empty sorted array.
|
||||
@ -32,14 +32,14 @@ type SortedArray struct {
|
||||
// if it returns value < 0, means v1 < v2;
|
||||
// if it returns value = 0, means v1 = v2;
|
||||
// if it returns value > 0, means v1 > v2;
|
||||
func NewSortedArray(comparator func(v1, v2 interface{}) int, safe ...bool) *SortedArray {
|
||||
func NewSortedArray(comparator func(a, b interface{}) int, safe ...bool) *SortedArray {
|
||||
return NewSortedArraySize(0, comparator, safe...)
|
||||
}
|
||||
|
||||
// NewSortedArraySize create and returns an sorted array with given size and cap.
|
||||
// The parameter <safe> used to specify whether using array in concurrent-safety,
|
||||
// which is false in default.
|
||||
func NewSortedArraySize(cap int, comparator func(v1, v2 interface{}) int, safe ...bool) *SortedArray {
|
||||
func NewSortedArraySize(cap int, comparator func(a, b interface{}) int, safe ...bool) *SortedArray {
|
||||
return &SortedArray{
|
||||
mu: rwmutex.New(safe...),
|
||||
unique: gtype.NewBool(),
|
||||
@ -51,7 +51,7 @@ func NewSortedArraySize(cap int, comparator func(v1, v2 interface{}) int, safe .
|
||||
// NewSortedArrayFrom creates and returns an sorted array with given slice <array>.
|
||||
// The parameter <safe> used to specify whether using array in concurrent-safety,
|
||||
// which is false in default.
|
||||
func NewSortedArrayFrom(array []interface{}, comparator func(v1, v2 interface{}) int, safe ...bool) *SortedArray {
|
||||
func NewSortedArrayFrom(array []interface{}, comparator func(a, b interface{}) int, safe ...bool) *SortedArray {
|
||||
a := NewSortedArraySize(0, comparator, safe...)
|
||||
a.array = array
|
||||
sort.Slice(a.array, func(i, j int) bool {
|
||||
@ -63,7 +63,7 @@ func NewSortedArrayFrom(array []interface{}, comparator func(v1, v2 interface{})
|
||||
// NewSortedArrayFromCopy creates and returns an sorted array from a copy of given slice <array>.
|
||||
// The parameter <safe> used to specify whether using array in concurrent-safety,
|
||||
// which is false in default.
|
||||
func NewSortedArrayFromCopy(array []interface{}, comparator func(v1, v2 interface{}) int, safe ...bool) *SortedArray {
|
||||
func NewSortedArrayFromCopy(array []interface{}, comparator func(a, b interface{}) int, safe ...bool) *SortedArray {
|
||||
newArray := make([]interface{}, len(array))
|
||||
copy(newArray, array)
|
||||
return NewSortedArrayFrom(newArray, comparator, safe...)
|
||||
|
||||
@ -10,8 +10,6 @@ import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"math"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"github.com/gogf/gf/g/container/gtype"
|
||||
"github.com/gogf/gf/g/internal/rwmutex"
|
||||
@ -23,8 +21,8 @@ import (
|
||||
type SortedStringArray struct {
|
||||
mu *rwmutex.RWMutex
|
||||
array []string
|
||||
unique *gtype.Bool // Whether enable unique feature(false)
|
||||
comparator func(v1, v2 string) int // Comparison function(it returns -1: v1 < v2; 0: v1 == v2; 1: v1 > v2)
|
||||
unique *gtype.Bool // Whether enable unique feature(false)
|
||||
comparator func(a, b string) int // Comparison function(it returns -1: a < b; 0: a == b; 1: a > b)
|
||||
}
|
||||
|
||||
// NewSortedStringArray creates and returns an empty sorted array.
|
||||
@ -34,17 +32,23 @@ func NewSortedStringArray(safe ...bool) *SortedStringArray {
|
||||
return NewSortedStringArraySize(0, safe...)
|
||||
}
|
||||
|
||||
// NewSortedStringArrayComparator creates and returns an empty sorted array with specified comparator.
|
||||
// The parameter <safe> used to specify whether using array in concurrent-safety which is false in default.
|
||||
func NewSortedStringArrayComparator(comparator func(a, b string) int, safe ...bool) *SortedStringArray {
|
||||
array := NewSortedStringArray(safe...)
|
||||
array.comparator = comparator
|
||||
return array
|
||||
}
|
||||
|
||||
// NewSortedStringArraySize create and returns an sorted array with given size and cap.
|
||||
// The parameter <safe> used to specify whether using array in concurrent-safety,
|
||||
// which is false in default.
|
||||
func NewSortedStringArraySize(cap int, safe ...bool) *SortedStringArray {
|
||||
return &SortedStringArray{
|
||||
mu: rwmutex.New(safe...),
|
||||
array: make([]string, 0, cap),
|
||||
unique: gtype.NewBool(),
|
||||
comparator: func(v1, v2 string) int {
|
||||
return strings.Compare(v1, v2)
|
||||
},
|
||||
mu: rwmutex.New(safe...),
|
||||
array: make([]string, 0, cap),
|
||||
unique: gtype.NewBool(),
|
||||
comparator: defaultComparatorStr,
|
||||
}
|
||||
}
|
||||
|
||||
@ -54,7 +58,7 @@ func NewSortedStringArraySize(cap int, safe ...bool) *SortedStringArray {
|
||||
func NewSortedStringArrayFrom(array []string, safe ...bool) *SortedStringArray {
|
||||
a := NewSortedStringArraySize(0, safe...)
|
||||
a.array = array
|
||||
sort.Strings(a.array)
|
||||
quickSortStr(a.array, a.comparator)
|
||||
return a
|
||||
}
|
||||
|
||||
@ -72,7 +76,7 @@ func (a *SortedStringArray) SetArray(array []string) *SortedStringArray {
|
||||
a.mu.Lock()
|
||||
defer a.mu.Unlock()
|
||||
a.array = array
|
||||
sort.Strings(a.array)
|
||||
quickSortStr(a.array, a.comparator)
|
||||
return a
|
||||
}
|
||||
|
||||
@ -82,7 +86,7 @@ func (a *SortedStringArray) SetArray(array []string) *SortedStringArray {
|
||||
func (a *SortedStringArray) Sort() *SortedStringArray {
|
||||
a.mu.Lock()
|
||||
defer a.mu.Unlock()
|
||||
sort.Strings(a.array)
|
||||
quickSortStr(a.array, a.comparator)
|
||||
return a
|
||||
}
|
||||
|
||||
|
||||
@ -17,7 +17,7 @@ import (
|
||||
|
||||
const (
|
||||
gMAX_DEPTH = 1000
|
||||
gFILTER_KEY = "/g/internal/debug/stack.go"
|
||||
gFILTER_KEY = "/g/internal/debug/debug.go"
|
||||
)
|
||||
|
||||
var (
|
||||
@ -84,14 +84,14 @@ func StackWithFilter(filter string, skip ...int) string {
|
||||
}
|
||||
|
||||
// CallerPath returns the absolute file path along with its line number of the caller.
|
||||
func Caller(skip ...int) string {
|
||||
func Caller(skip ...int) (path string, line int) {
|
||||
return CallerWithFilter("", skip...)
|
||||
}
|
||||
|
||||
// CallerPathWithFilter returns the absolute file path along with its line number of the caller.
|
||||
//
|
||||
// The parameter <filter> is used to filter the path of the caller.
|
||||
func CallerWithFilter(filter string, skip ...int) string {
|
||||
func CallerWithFilter(filter string, skip ...int) (path string, line int) {
|
||||
number := 0
|
||||
if len(skip) > 0 {
|
||||
number = skip[0]
|
||||
@ -104,12 +104,12 @@ func CallerWithFilter(filter string, skip ...int) string {
|
||||
if strings.Contains(file, gFILTER_KEY) {
|
||||
continue
|
||||
}
|
||||
return fmt.Sprintf(`%s:%d`, file, line)
|
||||
return file, line
|
||||
} else {
|
||||
break
|
||||
}
|
||||
}
|
||||
return ""
|
||||
return "", -1
|
||||
}
|
||||
|
||||
// callerFromIndex returns the caller position exclusive of the debug package.
|
||||
@ -18,21 +18,16 @@ import (
|
||||
"os/user"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"sort"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/gogf/gf/g/container/gtype"
|
||||
"github.com/gogf/gf/g/text/gregex"
|
||||
"github.com/gogf/gf/g/text/gstr"
|
||||
"github.com/gogf/gf/g/util/gconv"
|
||||
)
|
||||
|
||||
const (
|
||||
// Separator for file system.
|
||||
Separator = string(filepath.Separator)
|
||||
// Default perm for file opening.
|
||||
gDEFAULT_PERM = 0666
|
||||
Separator = string(filepath.Separator) // Separator for file system.
|
||||
gDEFAULT_PERM = 0666 // Default perm for file opening.
|
||||
)
|
||||
|
||||
var (
|
||||
@ -333,58 +328,6 @@ func Chmod(path string, mode os.FileMode) error {
|
||||
return os.Chmod(path, mode)
|
||||
}
|
||||
|
||||
// ScanDir returns all sub-files with absolute paths of given <path>,
|
||||
// It scans directory recursively if given parameter <recursive> is true.
|
||||
func ScanDir(path string, pattern string, recursive ...bool) ([]string, error) {
|
||||
list, err := doScanDir(path, pattern, recursive...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(list) > 0 {
|
||||
sort.Strings(list)
|
||||
}
|
||||
return list, nil
|
||||
}
|
||||
|
||||
// doScanDir is an internal method which scans directory
|
||||
// and returns the absolute path list of files that are not sorted.
|
||||
//
|
||||
// The pattern parameter <pattern> supports multiple file name patterns,
|
||||
// using the ',' symbol to separate multiple patterns.
|
||||
//
|
||||
// It scans directory recursively if given parameter <recursive> is true.
|
||||
func doScanDir(path string, pattern string, recursive ...bool) ([]string, error) {
|
||||
list := ([]string)(nil)
|
||||
file, err := os.Open(path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer file.Close()
|
||||
names, err := file.Readdirnames(-1)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, name := range names {
|
||||
path := fmt.Sprintf("%s%s%s", path, Separator, name)
|
||||
if IsDir(path) && len(recursive) > 0 && recursive[0] {
|
||||
array, _ := doScanDir(path, pattern, true)
|
||||
if len(array) > 0 {
|
||||
list = append(list, array...)
|
||||
}
|
||||
}
|
||||
// If it meets pattern, then add it to the result list.
|
||||
for _, p := range strings.Split(pattern, ",") {
|
||||
if match, err := filepath.Match(strings.TrimSpace(p), name); err == nil && match {
|
||||
path = Abs(path)
|
||||
if path != "" {
|
||||
list = append(list, path)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return list, nil
|
||||
}
|
||||
|
||||
// Abs returns an absolute representation of path.
|
||||
// If the path is not absolute it will be joined with the current
|
||||
// working directory to turn it into an absolute path. The absolute
|
||||
@ -516,54 +459,6 @@ func homeWindows() (string, error) {
|
||||
return home, nil
|
||||
}
|
||||
|
||||
// MainPkgPath returns absolute file path of package main,
|
||||
// which contains the entrance function main.
|
||||
//
|
||||
// It's only available in develop environment.
|
||||
//
|
||||
// Note1: Only valid for source development environments,
|
||||
// IE only valid for systems that generate this executable.
|
||||
// Note2: When the method is called for the first time, if it is in an asynchronous goroutine,
|
||||
// the method may not get the main package path.
|
||||
func MainPkgPath() string {
|
||||
path := mainPkgPath.Val()
|
||||
if path != "" {
|
||||
if path == "-" {
|
||||
return ""
|
||||
}
|
||||
return path
|
||||
}
|
||||
for i := 1; i < 10000; i++ {
|
||||
if _, file, _, ok := runtime.Caller(i); ok {
|
||||
// <file> is separated by '/'
|
||||
if gstr.Contains(file, "/gf/g/") {
|
||||
continue
|
||||
}
|
||||
if Ext(file) != ".go" {
|
||||
continue
|
||||
}
|
||||
// separator of <file> '/' will be converted to Separator.
|
||||
for path = Dir(file); len(path) > 1 && Exists(path) && path[len(path)-1] != os.PathSeparator; {
|
||||
files, _ := ScanDir(path, "*.go")
|
||||
for _, v := range files {
|
||||
if gregex.IsMatchString(`package\s+main`, GetContents(v)) {
|
||||
mainPkgPath.Set(path)
|
||||
return path
|
||||
}
|
||||
}
|
||||
path = Dir(path)
|
||||
}
|
||||
|
||||
} else {
|
||||
break
|
||||
}
|
||||
}
|
||||
// If it fails finding the path, then mark it as "-",
|
||||
// which means it will never do this search again.
|
||||
mainPkgPath.Set("-")
|
||||
return ""
|
||||
}
|
||||
|
||||
// See os.TempDir().
|
||||
func TempDir() string {
|
||||
return os.TempDir()
|
||||
|
||||
@ -29,7 +29,7 @@ func Replace(search, replace, path, pattern string, recursive ...bool) error {
|
||||
// ReplaceFunc replaces content for files under <path> with callback function <f>.
|
||||
// The parameter <pattern> specifies the file pattern which matches to be replaced.
|
||||
// It does replacement recursively if given parameter <recursive> is true.
|
||||
func ReplaceFunc(f func(content string) string, path, pattern string, recursive ...bool) error {
|
||||
func ReplaceFunc(f func(path, content string) string, path, pattern string, recursive ...bool) error {
|
||||
files, err := ScanDir(path, pattern, recursive...)
|
||||
if err != nil {
|
||||
return err
|
||||
@ -38,7 +38,7 @@ func ReplaceFunc(f func(content string) string, path, pattern string, recursive
|
||||
result := ""
|
||||
for _, file := range files {
|
||||
data = GetContents(file)
|
||||
result = f(data)
|
||||
result = f(file, data)
|
||||
if data != result {
|
||||
if err = PutContents(file, result); err != nil {
|
||||
return err
|
||||
|
||||
96
g/os/gfile/gfile_scan.go
Normal file
96
g/os/gfile/gfile_scan.go
Normal file
@ -0,0 +1,96 @@
|
||||
// Copyright 2017-2018 gf Author(https://github.com/gogf/gf). All Rights Reserved.
|
||||
//
|
||||
// This Source Code Form is subject to the terms of the MIT License.
|
||||
// If a copy of the MIT was not distributed with this file,
|
||||
// You can obtain one at https://github.com/gogf/gf.
|
||||
|
||||
package gfile
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"sort"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// ScanDir returns all sub-files with absolute paths of given <path>,
|
||||
// It scans directory recursively if given parameter <recursive> is true.
|
||||
func ScanDir(path string, pattern string, recursive ...bool) ([]string, error) {
|
||||
isRecursive := true
|
||||
if len(recursive) > 0 {
|
||||
isRecursive = recursive[0]
|
||||
}
|
||||
list, err := doScanDir(path, pattern, isRecursive, false)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(list) > 0 {
|
||||
sort.Strings(list)
|
||||
}
|
||||
return list, nil
|
||||
}
|
||||
|
||||
// ScanDirFile returns all sub-files with absolute paths of given <path>,
|
||||
// It scans directory recursively if given parameter <recursive> is true.
|
||||
//
|
||||
// Note that it returns only files, exclusive of directories.
|
||||
func ScanDirFile(path string, pattern string, recursive ...bool) ([]string, error) {
|
||||
isRecursive := true
|
||||
if len(recursive) > 0 {
|
||||
isRecursive = recursive[0]
|
||||
}
|
||||
list, err := doScanDir(path, pattern, isRecursive, true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(list) > 0 {
|
||||
sort.Strings(list)
|
||||
}
|
||||
return list, nil
|
||||
}
|
||||
|
||||
// doScanDir is an internal method which scans directory
|
||||
// and returns the absolute path list of files that are not sorted.
|
||||
//
|
||||
// The pattern parameter <pattern> supports multiple file name patterns,
|
||||
// using the ',' symbol to separate multiple patterns.
|
||||
//
|
||||
// It scans directory recursively if given parameter <recursive> is true.
|
||||
func doScanDir(path string, pattern string, recursive bool, onlyFile bool) ([]string, error) {
|
||||
list := ([]string)(nil)
|
||||
file, err := os.Open(path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer file.Close()
|
||||
names, err := file.Readdirnames(-1)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
filePath := ""
|
||||
isDir := false
|
||||
for _, name := range names {
|
||||
filePath = path + Separator + name
|
||||
isDir = IsDir(filePath)
|
||||
if isDir && recursive {
|
||||
array, _ := doScanDir(filePath, pattern, true, onlyFile)
|
||||
if len(array) > 0 {
|
||||
list = append(list, array...)
|
||||
}
|
||||
}
|
||||
// It returns only files.
|
||||
if isDir && onlyFile {
|
||||
continue
|
||||
}
|
||||
// If it meets pattern, then add it to the result list.
|
||||
for _, p := range strings.Split(pattern, ",") {
|
||||
if match, err := filepath.Match(strings.TrimSpace(p), name); err == nil && match {
|
||||
filePath = Abs(filePath)
|
||||
if filePath != "" {
|
||||
list = append(list, filePath)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return list, nil
|
||||
}
|
||||
40
g/os/gfile/gfile_sort.go
Normal file
40
g/os/gfile/gfile_sort.go
Normal file
@ -0,0 +1,40 @@
|
||||
// Copyright 2017-2018 gf Author(https://github.com/gogf/gf). All Rights Reserved.
|
||||
//
|
||||
// This Source Code Form is subject to the terms of the MIT License.
|
||||
// If a copy of the MIT was not distributed with this file,
|
||||
// You can obtain one at https://github.com/gogf/gf.
|
||||
|
||||
package gfile
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/gogf/gf/g/container/garray"
|
||||
)
|
||||
|
||||
// fileSortFunc is the comparison function for files.
|
||||
// It sorts the array in order of: directory -> file.
|
||||
// If <path1> and <path2> are the same type, it then sorts them as strings.
|
||||
func fileSortFunc(path1, path2 string) int {
|
||||
isDirPath1 := IsDir(path1)
|
||||
isDirPath2 := IsDir(path2)
|
||||
if isDirPath1 && !isDirPath2 {
|
||||
return -1
|
||||
}
|
||||
if !isDirPath1 && isDirPath2 {
|
||||
return 1
|
||||
}
|
||||
if n := strings.Compare(path1, path2); n != 0 {
|
||||
return n
|
||||
} else {
|
||||
return -1
|
||||
}
|
||||
}
|
||||
|
||||
// SortFiles sorts the <files> in order of: directory -> file.
|
||||
// Note that the item of <files> should be absolute path.
|
||||
func SortFiles(files []string) []string {
|
||||
array := garray.NewSortedStringArrayComparator(fileSortFunc)
|
||||
array.Add(files...)
|
||||
return array.Slice()
|
||||
}
|
||||
77
g/os/gfile/gfile_source.go
Normal file
77
g/os/gfile/gfile_source.go
Normal file
@ -0,0 +1,77 @@
|
||||
// Copyright 2017-2018 gf Author(https://github.com/gogf/gf). All Rights Reserved.
|
||||
//
|
||||
// This Source Code Form is subject to the terms of the MIT License.
|
||||
// If a copy of the MIT was not distributed with this file,
|
||||
// You can obtain one at https://github.com/gogf/gf.
|
||||
|
||||
package gfile
|
||||
|
||||
import (
|
||||
"os"
|
||||
"runtime"
|
||||
|
||||
"github.com/gogf/gf/g/internal/debug"
|
||||
"github.com/gogf/gf/g/text/gregex"
|
||||
"github.com/gogf/gf/g/text/gstr"
|
||||
)
|
||||
|
||||
const (
|
||||
gPATH_FILTER_KEY = "/g/os/gfile/gfile_source.go"
|
||||
)
|
||||
|
||||
// SourcePath returns absolute file path of the current source file path.
|
||||
//
|
||||
// Note that it's only available in develop environment.
|
||||
func SourcePath(skip ...int) string {
|
||||
path, _ := debug.CallerWithFilter(gPATH_FILTER_KEY, skip...)
|
||||
return path
|
||||
}
|
||||
|
||||
// MainPkgPath returns absolute file path of package main,
|
||||
// which contains the entrance function main.
|
||||
//
|
||||
// It's only available in develop environment.
|
||||
//
|
||||
// Note1: Only valid for source development environments,
|
||||
// IE only valid for systems that generate this executable.
|
||||
//
|
||||
// Note2: When the method is called for the first time, if it is in an asynchronous goroutine,
|
||||
// the method may not get the main package path.
|
||||
func MainPkgPath() string {
|
||||
path := mainPkgPath.Val()
|
||||
if path != "" {
|
||||
if path == "-" {
|
||||
return ""
|
||||
}
|
||||
return path
|
||||
}
|
||||
for i := 1; i < 10000; i++ {
|
||||
if _, file, _, ok := runtime.Caller(i); ok {
|
||||
// <file> is separated by '/'
|
||||
if gstr.Contains(file, "/gf/g/") {
|
||||
continue
|
||||
}
|
||||
if Ext(file) != ".go" {
|
||||
continue
|
||||
}
|
||||
// separator of <file> '/' will be converted to Separator.
|
||||
for path = Dir(file); len(path) > 1 && Exists(path) && path[len(path)-1] != os.PathSeparator; {
|
||||
files, _ := ScanDir(path, "*.go")
|
||||
for _, v := range files {
|
||||
if gregex.IsMatchString(`package\s+main`, GetContents(v)) {
|
||||
mainPkgPath.Set(path)
|
||||
return path
|
||||
}
|
||||
}
|
||||
path = Dir(path)
|
||||
}
|
||||
|
||||
} else {
|
||||
break
|
||||
}
|
||||
}
|
||||
// If it fails finding the path, then mark it as "-",
|
||||
// which means it will never do this search again.
|
||||
mainPkgPath.Set("-")
|
||||
return ""
|
||||
}
|
||||
@ -1,13 +1,14 @@
|
||||
package gfile_test
|
||||
|
||||
import (
|
||||
"github.com/gogf/gf/g/os/gfile"
|
||||
"github.com/gogf/gf/g/test/gtest"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/gogf/gf/g/os/gfile"
|
||||
"github.com/gogf/gf/g/test/gtest"
|
||||
)
|
||||
|
||||
// 创建测试文件
|
||||
@ -50,7 +51,7 @@ func testpath() string {
|
||||
return os.TempDir()
|
||||
}
|
||||
|
||||
func TestGetContents(t *testing.T) {
|
||||
func Test_GetContents(t *testing.T) {
|
||||
gtest.Case(t, func() {
|
||||
|
||||
var (
|
||||
@ -65,7 +66,7 @@ func TestGetContents(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func TestGetBinContents(t *testing.T) {
|
||||
func Test_GetBinContents(t *testing.T) {
|
||||
gtest.Case(t, func() {
|
||||
var (
|
||||
filepaths1 string = "/testfile_t1.txt" // 文件存在时
|
||||
@ -87,7 +88,7 @@ func TestGetBinContents(t *testing.T) {
|
||||
}
|
||||
|
||||
// 截断文件为指定的大小
|
||||
func TestTruncate(t *testing.T) {
|
||||
func Test_Truncate(t *testing.T) {
|
||||
gtest.Case(t, func() {
|
||||
var (
|
||||
filepaths1 string = "/testfile_GetContentsyyui.txt" //文件存在时
|
||||
@ -114,7 +115,7 @@ func TestTruncate(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func TestPutContents(t *testing.T) {
|
||||
func Test_PutContents(t *testing.T) {
|
||||
gtest.Case(t, func() {
|
||||
var (
|
||||
filepaths string = "/testfile_PutContents.txt"
|
||||
@ -138,7 +139,7 @@ func TestPutContents(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func TestPutContentsAppend(t *testing.T) {
|
||||
func Test_PutContentsAppend(t *testing.T) {
|
||||
gtest.Case(t, func() {
|
||||
var (
|
||||
filepaths string = "/testfile_PutContents.txt"
|
||||
@ -163,7 +164,7 @@ func TestPutContentsAppend(t *testing.T) {
|
||||
|
||||
}
|
||||
|
||||
func TestPutBinContents(t *testing.T) {
|
||||
func Test_PutBinContents(t *testing.T) {
|
||||
gtest.Case(t, func() {
|
||||
var (
|
||||
filepaths string = "/testfile_PutContents.txt"
|
||||
@ -187,7 +188,7 @@ func TestPutBinContents(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func TestPutBinContentsAppend(t *testing.T) {
|
||||
func Test_PutBinContentsAppend(t *testing.T) {
|
||||
gtest.Case(t, func() {
|
||||
var (
|
||||
filepaths string = "/testfile_PutContents.txt" //原文件内容: yy
|
||||
@ -210,7 +211,7 @@ func TestPutBinContentsAppend(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func TestGetBinContentsByTwoOffsetsByPath(t *testing.T) {
|
||||
func Test_GetBinContentsByTwoOffsetsByPath(t *testing.T) {
|
||||
gtest.Case(t, func() {
|
||||
var (
|
||||
filepaths string = "/testfile_GetContents.txt" // 文件内容: abcdefghijk
|
||||
@ -230,7 +231,7 @@ func TestGetBinContentsByTwoOffsetsByPath(t *testing.T) {
|
||||
|
||||
}
|
||||
|
||||
func TestGetNextCharOffsetByPath(t *testing.T) {
|
||||
func Test_GetNextCharOffsetByPath(t *testing.T) {
|
||||
gtest.Case(t, func() {
|
||||
var (
|
||||
filepaths string = "/testfile_GetContents.txt" // 文件内容: abcdefghijk
|
||||
@ -247,7 +248,7 @@ func TestGetNextCharOffsetByPath(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func TestGetNextCharOffset(t *testing.T) {
|
||||
func Test_GetNextCharOffset(t *testing.T) {
|
||||
gtest.Case(t, func() {
|
||||
var (
|
||||
localindex int64
|
||||
@ -263,7 +264,7 @@ func TestGetNextCharOffset(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func TestGetBinContentsByTwoOffsets(t *testing.T) {
|
||||
func Test_GetBinContentsByTwoOffsets(t *testing.T) {
|
||||
gtest.Case(t, func() {
|
||||
var (
|
||||
reads []byte
|
||||
@ -279,7 +280,7 @@ func TestGetBinContentsByTwoOffsets(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func TestGetBinContentsTilChar(t *testing.T) {
|
||||
func Test_GetBinContentsTilChar(t *testing.T) {
|
||||
gtest.Case(t, func() {
|
||||
var (
|
||||
reads []byte
|
||||
@ -296,7 +297,7 @@ func TestGetBinContentsTilChar(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func TestGetBinContentsTilCharByPath(t *testing.T) {
|
||||
func Test_GetBinContentsTilCharByPath(t *testing.T) {
|
||||
gtest.Case(t, func() {
|
||||
var (
|
||||
reads []byte
|
||||
@ -319,7 +320,7 @@ func TestGetBinContentsTilCharByPath(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func TestHome(t *testing.T) {
|
||||
func Test_Home(t *testing.T) {
|
||||
gtest.Case(t, func() {
|
||||
var (
|
||||
reads string
|
||||
|
||||
28
g/os/gfile/gfile_z_scan_test.go
Normal file
28
g/os/gfile/gfile_z_scan_test.go
Normal file
@ -0,0 +1,28 @@
|
||||
package gfile_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/gogf/gf/g/os/gfile"
|
||||
|
||||
"github.com/gogf/gf/g/test/gtest"
|
||||
)
|
||||
|
||||
func Test_Scan(t *testing.T) {
|
||||
teatPath := gfile.Dir(gfile.SourcePath()) + gfile.Separator + "testdata"
|
||||
gtest.Case(t, func() {
|
||||
files, err := gfile.ScanDir(teatPath, "*", false)
|
||||
gtest.Assert(err, nil)
|
||||
gtest.AssertIN(teatPath+gfile.Separator+"dir1", files)
|
||||
gtest.AssertIN(teatPath+gfile.Separator+"dir2", files)
|
||||
gtest.AssertNE(teatPath+gfile.Separator+"dir1"+gfile.Separator+"file1", files)
|
||||
})
|
||||
gtest.Case(t, func() {
|
||||
files, err := gfile.ScanDir(teatPath, "*", true)
|
||||
gtest.Assert(err, nil)
|
||||
gtest.AssertNE(teatPath+gfile.Separator+"dir1", files)
|
||||
gtest.AssertNE(teatPath+gfile.Separator+"dir2", files)
|
||||
gtest.AssertIN(teatPath+gfile.Separator+"dir1"+gfile.Separator+"file1", files)
|
||||
gtest.AssertIN(teatPath+gfile.Separator+"dir2"+gfile.Separator+"file2", files)
|
||||
})
|
||||
}
|
||||
@ -1,13 +1,14 @@
|
||||
package gfile_test
|
||||
|
||||
import (
|
||||
"github.com/gogf/gf/g/os/gfile"
|
||||
"github.com/gogf/gf/g/test/gtest"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"github.com/gogf/gf/g/os/gfile"
|
||||
"github.com/gogf/gf/g/test/gtest"
|
||||
)
|
||||
|
||||
func TestSearch(t *testing.T) {
|
||||
func Test_Search(t *testing.T) {
|
||||
gtest.Case(t, func() {
|
||||
var (
|
||||
paths1 string = "/testfiless"
|
||||
|
||||
@ -1,12 +1,13 @@
|
||||
package gfile_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/gogf/gf/g/os/gfile"
|
||||
"github.com/gogf/gf/g/test/gtest"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestSize(t *testing.T) {
|
||||
func Test_Size(t *testing.T) {
|
||||
gtest.Case(t, func() {
|
||||
var (
|
||||
paths1 string = "/testfile_t1.txt"
|
||||
@ -25,7 +26,7 @@ func TestSize(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func TestFormatSize(t *testing.T) {
|
||||
func Test_FormatSize(t *testing.T) {
|
||||
gtest.Case(t, func() {
|
||||
gtest.Assert(gfile.FormatSize(0), "0.00B")
|
||||
gtest.Assert(gfile.FormatSize(16), "16.00B")
|
||||
@ -38,13 +39,10 @@ func TestFormatSize(t *testing.T) {
|
||||
|
||||
gtest.Assert(gfile.FormatSize(9600000000000), "8.73T")
|
||||
gtest.Assert(gfile.FormatSize(9600000000000000), "8.53P")
|
||||
|
||||
gtest.Assert(gfile.FormatSize(9600000000000000000), "TooLarge")
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
func TestReadableSize(t *testing.T) {
|
||||
func Test_ReadableSize(t *testing.T) {
|
||||
gtest.Case(t, func() {
|
||||
|
||||
var (
|
||||
|
||||
@ -10,7 +10,7 @@ import (
|
||||
"github.com/gogf/gf/g/test/gtest"
|
||||
)
|
||||
|
||||
func TestIsDir(t *testing.T) {
|
||||
func Test_IsDir(t *testing.T) {
|
||||
|
||||
gtest.Case(t, func() {
|
||||
paths := "/testfile"
|
||||
@ -26,7 +26,7 @@ func TestIsDir(t *testing.T) {
|
||||
|
||||
}
|
||||
|
||||
func TestCreate(t *testing.T) {
|
||||
func Test_Create(t *testing.T) {
|
||||
gtest.Case(t, func() {
|
||||
var (
|
||||
err error
|
||||
@ -49,7 +49,7 @@ func TestCreate(t *testing.T) {
|
||||
|
||||
}
|
||||
|
||||
func TestOpen(t *testing.T) {
|
||||
func Test_Open(t *testing.T) {
|
||||
gtest.Case(t, func() {
|
||||
var (
|
||||
err error
|
||||
@ -82,7 +82,7 @@ func TestOpen(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func TestOpenFile(t *testing.T) {
|
||||
func Test_OpenFile(t *testing.T) {
|
||||
gtest.Case(t, func() {
|
||||
var (
|
||||
err error
|
||||
@ -115,7 +115,7 @@ func TestOpenFile(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func TestOpenWithFlag(t *testing.T) {
|
||||
func Test_OpenWithFlag(t *testing.T) {
|
||||
gtest.Case(t, func() {
|
||||
var (
|
||||
err error
|
||||
@ -147,7 +147,7 @@ func TestOpenWithFlag(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func TestOpenWithFlagPerm(t *testing.T) {
|
||||
func Test_OpenWithFlagPerm(t *testing.T) {
|
||||
gtest.Case(t, func() {
|
||||
var (
|
||||
err error
|
||||
@ -178,7 +178,7 @@ func TestOpenWithFlagPerm(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func TestExists(t *testing.T) {
|
||||
func Test_Exists(t *testing.T) {
|
||||
|
||||
gtest.Case(t, func() {
|
||||
var (
|
||||
@ -210,7 +210,7 @@ func TestExists(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func TestPwd(t *testing.T) {
|
||||
func Test_Pwd(t *testing.T) {
|
||||
gtest.Case(t, func() {
|
||||
paths, err := os.Getwd()
|
||||
gtest.Assert(err, nil)
|
||||
@ -219,7 +219,7 @@ func TestPwd(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func TestIsFile(t *testing.T) {
|
||||
func Test_IsFile(t *testing.T) {
|
||||
gtest.Case(t, func() {
|
||||
var (
|
||||
flag bool
|
||||
@ -255,7 +255,7 @@ func TestIsFile(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func TestInfo(t *testing.T) {
|
||||
func Test_Info(t *testing.T) {
|
||||
gtest.Case(t, func() {
|
||||
var (
|
||||
err error
|
||||
@ -277,7 +277,7 @@ func TestInfo(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func TestMove(t *testing.T) {
|
||||
func Test_Move(t *testing.T) {
|
||||
gtest.Case(t, func() {
|
||||
var (
|
||||
paths string = "/ovetest"
|
||||
@ -301,7 +301,7 @@ func TestMove(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func TestRename(t *testing.T) {
|
||||
func Test_Rename(t *testing.T) {
|
||||
gtest.Case(t, func() {
|
||||
var (
|
||||
paths string = "/testfiles"
|
||||
@ -324,7 +324,7 @@ func TestRename(t *testing.T) {
|
||||
|
||||
}
|
||||
|
||||
func TestCopy(t *testing.T) {
|
||||
func Test_Copy(t *testing.T) {
|
||||
gtest.Case(t, func() {
|
||||
var (
|
||||
paths string = "/testfile_copyfile1.txt"
|
||||
@ -342,7 +342,7 @@ func TestCopy(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func TestDirNames(t *testing.T) {
|
||||
func Test_DirNames(t *testing.T) {
|
||||
gtest.Case(t, func() {
|
||||
var (
|
||||
paths string = "/testdirs"
|
||||
@ -372,7 +372,7 @@ func TestDirNames(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func TestGlob(t *testing.T) {
|
||||
func Test_Glob(t *testing.T) {
|
||||
gtest.Case(t, func() {
|
||||
var (
|
||||
paths string = "/testfiles/*.txt"
|
||||
@ -413,7 +413,7 @@ func TestGlob(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func TestRemove(t *testing.T) {
|
||||
func Test_Remove(t *testing.T) {
|
||||
gtest.Case(t, func() {
|
||||
var (
|
||||
paths string = "/testfile_t1.txt"
|
||||
@ -428,7 +428,7 @@ func TestRemove(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func TestIsReadable(t *testing.T) {
|
||||
func Test_IsReadable(t *testing.T) {
|
||||
gtest.Case(t, func() {
|
||||
var (
|
||||
paths1 string = "/testfile_GetContents.txt"
|
||||
@ -444,7 +444,7 @@ func TestIsReadable(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func TestIsWritable(t *testing.T) {
|
||||
func Test_IsWritable(t *testing.T) {
|
||||
gtest.Case(t, func() {
|
||||
var (
|
||||
paths1 string = "/testfile_GetContents.txt"
|
||||
@ -459,7 +459,7 @@ func TestIsWritable(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func TestChmod(t *testing.T) {
|
||||
func Test_Chmod(t *testing.T) {
|
||||
gtest.Case(t, func() {
|
||||
var (
|
||||
paths1 string = "/testfile_GetContents.txt"
|
||||
@ -474,7 +474,7 @@ func TestChmod(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func TestScanDir(t *testing.T) {
|
||||
func Test_ScanDir(t *testing.T) {
|
||||
gtest.Case(t, func() {
|
||||
var (
|
||||
paths1 string = "/testfiledirs"
|
||||
@ -505,7 +505,7 @@ func TestScanDir(t *testing.T) {
|
||||
}
|
||||
|
||||
// 获取绝对目录地址
|
||||
func TestRealPath(t *testing.T) {
|
||||
func Test_RealPath(t *testing.T) {
|
||||
gtest.Case(t, func() {
|
||||
var (
|
||||
paths1 string = "/testfile_files"
|
||||
@ -529,7 +529,7 @@ func TestRealPath(t *testing.T) {
|
||||
}
|
||||
|
||||
// 获取当前执行文件的目录
|
||||
func TestSelfPath(t *testing.T) {
|
||||
func Test_SelfPath(t *testing.T) {
|
||||
gtest.Case(t, func() {
|
||||
var (
|
||||
paths1 string
|
||||
@ -548,7 +548,7 @@ func TestSelfPath(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func TestSelfDir(t *testing.T) {
|
||||
func Test_SelfDir(t *testing.T) {
|
||||
gtest.Case(t, func() {
|
||||
var (
|
||||
paths1 string
|
||||
@ -565,7 +565,7 @@ func TestSelfDir(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func TestBasename(t *testing.T) {
|
||||
func Test_Basename(t *testing.T) {
|
||||
gtest.Case(t, func() {
|
||||
var (
|
||||
paths1 string = "/testfilerr_GetContents.txt"
|
||||
@ -581,7 +581,7 @@ func TestBasename(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func TestDir(t *testing.T) {
|
||||
func Test_Dir(t *testing.T) {
|
||||
gtest.Case(t, func() {
|
||||
var (
|
||||
paths1 string = "/testfiless"
|
||||
@ -598,7 +598,7 @@ func TestDir(t *testing.T) {
|
||||
}
|
||||
|
||||
// 获取文件名
|
||||
func TestExt(t *testing.T) {
|
||||
func Test_Ext(t *testing.T) {
|
||||
gtest.Case(t, func() {
|
||||
var (
|
||||
paths1 string = "/testfile_GetContents.txt"
|
||||
@ -616,7 +616,7 @@ func TestExt(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func TestTempDir(t *testing.T) {
|
||||
func Test_TempDir(t *testing.T) {
|
||||
gtest.Case(t, func() {
|
||||
var (
|
||||
tpath string
|
||||
@ -628,7 +628,7 @@ func TestTempDir(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func TestMkdir(t *testing.T) {
|
||||
func Test_Mkdir(t *testing.T) {
|
||||
gtest.Case(t, func() {
|
||||
var (
|
||||
tpath string = "/testfile/createdir"
|
||||
@ -649,7 +649,7 @@ func TestMkdir(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func TestStat(t *testing.T) {
|
||||
func Test_Stat(t *testing.T) {
|
||||
gtest.Case(t, func() {
|
||||
var (
|
||||
tpath1 = "/testfile_t1.txt"
|
||||
@ -672,14 +672,14 @@ func TestStat(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func TestMainPkgPath(t *testing.T) {
|
||||
func Test_MainPkgPath(t *testing.T) {
|
||||
gtest.Case(t, func() {
|
||||
reads := gfile.MainPkgPath()
|
||||
gtest.Assert(reads, "")
|
||||
})
|
||||
}
|
||||
|
||||
func TestCopyFile(t *testing.T) {
|
||||
func Test_CopyFile(t *testing.T) {
|
||||
gtest.Case(t, func() {
|
||||
var (
|
||||
paths string = "/testfile_copyfile1.txt"
|
||||
@ -697,7 +697,7 @@ func TestCopyFile(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func TestCopyDir(t *testing.T) {
|
||||
func Test_CopyDir(t *testing.T) {
|
||||
gtest.Case(t, func() {
|
||||
var (
|
||||
dirpath1 string = "/testcopydir1"
|
||||
|
||||
@ -1,13 +1,14 @@
|
||||
package gfile_test
|
||||
|
||||
import (
|
||||
"github.com/gogf/gf/g/os/gfile"
|
||||
"github.com/gogf/gf/g/test/gtest"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/gogf/gf/g/os/gfile"
|
||||
"github.com/gogf/gf/g/test/gtest"
|
||||
)
|
||||
|
||||
func TestMTime(t *testing.T) {
|
||||
func Test_MTime(t *testing.T) {
|
||||
gtest.Case(t, func() {
|
||||
|
||||
var (
|
||||
@ -26,7 +27,7 @@ func TestMTime(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func TestMTimeMillisecond(t *testing.T) {
|
||||
func Test_MTimeMillisecond(t *testing.T) {
|
||||
gtest.Case(t, func() {
|
||||
var (
|
||||
file1 string = "/testfile_t1.txt"
|
||||
|
||||
0
g/os/gfile/testdata/dir1/file1
vendored
Normal file
0
g/os/gfile/testdata/dir1/file1
vendored
Normal file
0
g/os/gfile/testdata/dir2/file2
vendored
Normal file
0
g/os/gfile/testdata/dir2/file2
vendored
Normal file
@ -244,10 +244,12 @@ func (l *Logger) print(std io.Writer, lead string, value ...interface{}) {
|
||||
// Caller path.
|
||||
callerPath := ""
|
||||
if l.flags&F_FILE_LONG > 0 {
|
||||
callerPath = debug.CallerWithFilter(gPATH_FILTER_KEY, l.stSkip) + ": "
|
||||
path, line := debug.CallerWithFilter(gPATH_FILTER_KEY, l.stSkip)
|
||||
callerPath = fmt.Sprintf(`%s:%d: `, path, line)
|
||||
}
|
||||
if l.flags&F_FILE_SHORT > 0 {
|
||||
callerPath = gfile.Basename(debug.CallerWithFilter(gPATH_FILTER_KEY, l.stSkip)) + ": "
|
||||
path, line := debug.CallerWithFilter(gPATH_FILTER_KEY, l.stSkip)
|
||||
callerPath = fmt.Sprintf(`%s:%d: `, gfile.Basename(path), line)
|
||||
}
|
||||
if len(callerPath) > 0 {
|
||||
buffer.WriteString(callerPath)
|
||||
|
||||
@ -6,6 +6,6 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
gutil.Dump(gfile.ScanDir("/home/john/Documents", "*"))
|
||||
gutil.Dump(gfile.ScanDir("/Users/john/Documents", "*.*"))
|
||||
gutil.Dump(gfile.ScanDir("/home/john/temp/newproject", "*", true))
|
||||
}
|
||||
|
||||
@ -1,10 +1,5 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
)
|
||||
|
||||
func main() {
|
||||
fmt.Println(filepath.Abs("s/s/s/s/s"))
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user