mirror of
https://github.com/rclone/rclone
synced 2025-01-03 03:46:24 +01:00
lib/random: unify random string generation into random.String
This was factored from fstest as we were including the testing
enviroment into the main binary because of it.
This was causing opening the browser to fail because of 8243ff8bc8
.
This commit is contained in:
parent
72d5b11d1b
commit
5065c422b4
5
backend/cache/cache_internal_test.go
vendored
5
backend/cache/cache_internal_test.go
vendored
@ -33,6 +33,7 @@ import (
|
|||||||
"github.com/rclone/rclone/fs/object"
|
"github.com/rclone/rclone/fs/object"
|
||||||
"github.com/rclone/rclone/fs/rc"
|
"github.com/rclone/rclone/fs/rc"
|
||||||
"github.com/rclone/rclone/fstest"
|
"github.com/rclone/rclone/fstest"
|
||||||
|
"github.com/rclone/rclone/lib/random"
|
||||||
"github.com/rclone/rclone/vfs"
|
"github.com/rclone/rclone/vfs"
|
||||||
"github.com/rclone/rclone/vfs/vfsflags"
|
"github.com/rclone/rclone/vfs/vfsflags"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
@ -355,8 +356,8 @@ func TestInternalCachedUpdatedContentMatches(t *testing.T) {
|
|||||||
testData2, err = base64.StdEncoding.DecodeString(cryptedText2Base64)
|
testData2, err = base64.StdEncoding.DecodeString(cryptedText2Base64)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
} else {
|
} else {
|
||||||
testData1 = []byte(fstest.RandomString(100))
|
testData1 = []byte(random.String(100))
|
||||||
testData2 = []byte(fstest.RandomString(200))
|
testData2 = []byte(random.String(200))
|
||||||
}
|
}
|
||||||
|
|
||||||
// write the object
|
// write the object
|
||||||
|
@ -13,6 +13,7 @@ import (
|
|||||||
"github.com/rclone/rclone/fs"
|
"github.com/rclone/rclone/fs"
|
||||||
"github.com/rclone/rclone/fs/hash"
|
"github.com/rclone/rclone/fs/hash"
|
||||||
"github.com/rclone/rclone/fstest"
|
"github.com/rclone/rclone/fstest"
|
||||||
|
"github.com/rclone/rclone/lib/random"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
@ -55,7 +56,7 @@ func TestIntegration(t *testing.T) {
|
|||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
t.Run("CreateAlbum", func(t *testing.T) {
|
t.Run("CreateAlbum", func(t *testing.T) {
|
||||||
albumName := "album/rclone-test-" + fstest.RandomString(24)
|
albumName := "album/rclone-test-" + random.String(24)
|
||||||
err = f.Mkdir(ctx, albumName)
|
err = f.Mkdir(ctx, albumName)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
remote := albumName + "/" + fileNameAlbum
|
remote := albumName + "/" + fileNameAlbum
|
||||||
|
@ -9,6 +9,7 @@ package cmd
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
|
"math/rand"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"path"
|
"path"
|
||||||
@ -492,6 +493,7 @@ func AddBackendFlags() {
|
|||||||
|
|
||||||
// Main runs rclone interpreting flags and commands out of os.Args
|
// Main runs rclone interpreting flags and commands out of os.Args
|
||||||
func Main() {
|
func Main() {
|
||||||
|
rand.Seed(time.Now().Unix())
|
||||||
setupRootCommand(Root)
|
setupRootCommand(Root)
|
||||||
AddBackendFlags()
|
AddBackendFlags()
|
||||||
if err := Root.Execute(); err != nil {
|
if err := Root.Execute(); err != nil {
|
||||||
|
@ -18,7 +18,7 @@ import (
|
|||||||
"github.com/rclone/rclone/fs"
|
"github.com/rclone/rclone/fs"
|
||||||
"github.com/rclone/rclone/fs/hash"
|
"github.com/rclone/rclone/fs/hash"
|
||||||
"github.com/rclone/rclone/fs/object"
|
"github.com/rclone/rclone/fs/object"
|
||||||
"github.com/rclone/rclone/fstest"
|
"github.com/rclone/rclone/lib/random"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -118,7 +118,7 @@ func (r *results) Print() {
|
|||||||
|
|
||||||
// writeFile writes a file with some random contents
|
// writeFile writes a file with some random contents
|
||||||
func (r *results) writeFile(path string) (fs.Object, error) {
|
func (r *results) writeFile(path string) (fs.Object, error) {
|
||||||
contents := fstest.RandomString(50)
|
contents := random.String(50)
|
||||||
src := object.NewStaticObjectInfo(path, time.Now(), int64(len(contents)), true, nil, r.f)
|
src := object.NewStaticObjectInfo(path, time.Now(), int64(len(contents)), true, nil, r.f)
|
||||||
return r.f.Put(r.ctx, bytes.NewBufferString(contents), src)
|
return r.f.Put(r.ctx, bytes.NewBufferString(contents), src)
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,7 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/rclone/rclone/fs/accounting"
|
"github.com/rclone/rclone/fs/accounting"
|
||||||
|
"github.com/rclone/rclone/lib/random"
|
||||||
|
|
||||||
"github.com/rclone/rclone/fs"
|
"github.com/rclone/rclone/fs"
|
||||||
"github.com/rclone/rclone/fstest"
|
"github.com/rclone/rclone/fstest"
|
||||||
@ -52,7 +53,7 @@ func TestMultithreadCopy(t *testing.T) {
|
|||||||
} {
|
} {
|
||||||
t.Run(fmt.Sprintf("%+v", test), func(t *testing.T) {
|
t.Run(fmt.Sprintf("%+v", test), func(t *testing.T) {
|
||||||
var err error
|
var err error
|
||||||
contents := fstest.RandomString(test.size)
|
contents := random.String(test.size)
|
||||||
t1 := fstest.Time("2001-02-03T04:05:06.499999999Z")
|
t1 := fstest.Time("2001-02-03T04:05:06.499999999Z")
|
||||||
file1 := r.WriteObject(context.Background(), "file1", contents, t1)
|
file1 := r.WriteObject(context.Background(), "file1", contents, t1)
|
||||||
fstest.CheckItems(t, r.Fremote, file1)
|
fstest.CheckItems(t, r.Fremote, file1)
|
||||||
|
@ -8,7 +8,6 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"math/rand"
|
|
||||||
"path"
|
"path"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"sort"
|
"sort"
|
||||||
@ -28,6 +27,7 @@ import (
|
|||||||
"github.com/rclone/rclone/fs/march"
|
"github.com/rclone/rclone/fs/march"
|
||||||
"github.com/rclone/rclone/fs/object"
|
"github.com/rclone/rclone/fs/object"
|
||||||
"github.com/rclone/rclone/fs/walk"
|
"github.com/rclone/rclone/fs/walk"
|
||||||
|
"github.com/rclone/rclone/lib/random"
|
||||||
"github.com/rclone/rclone/lib/readers"
|
"github.com/rclone/rclone/lib/readers"
|
||||||
"golang.org/x/sync/errgroup"
|
"golang.org/x/sync/errgroup"
|
||||||
)
|
)
|
||||||
@ -1666,7 +1666,7 @@ func moveOrCopyFile(ctx context.Context, fdst fs.Fs, fsrc fs.Fs, dstFileName str
|
|||||||
// to avoid issues with certain remotes and avoid file deletion.
|
// to avoid issues with certain remotes and avoid file deletion.
|
||||||
if !cp && fdst.Name() == fsrc.Name() && fdst.Features().CaseInsensitive && dstFileName != srcFileName && strings.ToLower(dstFilePath) == strings.ToLower(srcFilePath) {
|
if !cp && fdst.Name() == fsrc.Name() && fdst.Features().CaseInsensitive && dstFileName != srcFileName && strings.ToLower(dstFilePath) == strings.ToLower(srcFilePath) {
|
||||||
// Create random name to temporarily move file to
|
// Create random name to temporarily move file to
|
||||||
tmpObjName := dstFileName + "-rclone-move-" + random(8)
|
tmpObjName := dstFileName + "-rclone-move-" + random.String(8)
|
||||||
_, err := fdst.NewObject(ctx, tmpObjName)
|
_, err := fdst.NewObject(ctx, tmpObjName)
|
||||||
if err != fs.ErrorObjectNotFound {
|
if err != fs.ErrorObjectNotFound {
|
||||||
if err == nil {
|
if err == nil {
|
||||||
@ -1730,17 +1730,6 @@ func moveOrCopyFile(ctx context.Context, fdst fs.Fs, fsrc fs.Fs, dstFileName str
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// random generates a pseudorandom alphanumeric string
|
|
||||||
func random(length int) string {
|
|
||||||
randomOutput := make([]byte, length)
|
|
||||||
possibleCharacters := "123567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
|
||||||
rand.Seed(time.Now().Unix())
|
|
||||||
for i := range randomOutput {
|
|
||||||
randomOutput[i] = possibleCharacters[rand.Intn(len(possibleCharacters))]
|
|
||||||
}
|
|
||||||
return string(randomOutput)
|
|
||||||
}
|
|
||||||
|
|
||||||
// MoveFile moves a single file possibly to a new name
|
// MoveFile moves a single file possibly to a new name
|
||||||
func MoveFile(ctx context.Context, fdst fs.Fs, fsrc fs.Fs, dstFileName string, srcFileName string) (err error) {
|
func MoveFile(ctx context.Context, fdst fs.Fs, fsrc fs.Fs, dstFileName string, srcFileName string) (err error) {
|
||||||
return moveOrCopyFile(ctx, fdst, fsrc, dstFileName, srcFileName, false)
|
return moveOrCopyFile(ctx, fdst, fsrc, dstFileName, srcFileName, false)
|
||||||
|
@ -95,6 +95,8 @@ func (s *Server) Serve() error {
|
|||||||
// Don't open browser if serving in testing environment.
|
// Don't open browser if serving in testing environment.
|
||||||
if flag.Lookup("test.v") == nil {
|
if flag.Lookup("test.v") == nil {
|
||||||
_ = open.Start(openURL.String())
|
_ = open.Start(openURL.String())
|
||||||
|
} else {
|
||||||
|
fs.Errorf(nil, "Not opening browser in testing environment")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
@ -27,6 +27,7 @@ import (
|
|||||||
"github.com/rclone/rclone/fs/config"
|
"github.com/rclone/rclone/fs/config"
|
||||||
"github.com/rclone/rclone/fs/hash"
|
"github.com/rclone/rclone/fs/hash"
|
||||||
"github.com/rclone/rclone/fs/walk"
|
"github.com/rclone/rclone/fs/walk"
|
||||||
|
"github.com/rclone/rclone/lib/random"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
"golang.org/x/text/unicode/norm"
|
"golang.org/x/text/unicode/norm"
|
||||||
@ -357,24 +358,6 @@ func Time(timeString string) time.Time {
|
|||||||
return t
|
return t
|
||||||
}
|
}
|
||||||
|
|
||||||
// RandomString create a random string for test purposes
|
|
||||||
func RandomString(n int) string {
|
|
||||||
const (
|
|
||||||
vowel = "aeiou"
|
|
||||||
consonant = "bcdfghjklmnpqrstvwxyz"
|
|
||||||
digit = "0123456789"
|
|
||||||
)
|
|
||||||
pattern := []string{consonant, vowel, consonant, vowel, consonant, vowel, consonant, digit}
|
|
||||||
out := make([]byte, n)
|
|
||||||
p := 0
|
|
||||||
for i := range out {
|
|
||||||
source := pattern[p]
|
|
||||||
p = (p + 1) % len(pattern)
|
|
||||||
out[i] = source[rand.Intn(len(source))]
|
|
||||||
}
|
|
||||||
return string(out)
|
|
||||||
}
|
|
||||||
|
|
||||||
// LocalRemote creates a temporary directory name for local remotes
|
// LocalRemote creates a temporary directory name for local remotes
|
||||||
func LocalRemote() (path string, err error) {
|
func LocalRemote() (path string, err error) {
|
||||||
path, err = ioutil.TempDir("", "rclone")
|
path, err = ioutil.TempDir("", "rclone")
|
||||||
@ -403,7 +386,7 @@ func RandomRemoteName(remoteName string) (string, string, error) {
|
|||||||
if !strings.HasSuffix(remoteName, ":") {
|
if !strings.HasSuffix(remoteName, ":") {
|
||||||
remoteName += "/"
|
remoteName += "/"
|
||||||
}
|
}
|
||||||
leafName = "rclone-test-" + RandomString(24)
|
leafName = "rclone-test-" + random.String(24)
|
||||||
if !MatchTestRemote.MatchString(leafName) {
|
if !MatchTestRemote.MatchString(leafName) {
|
||||||
log.Fatalf("%q didn't match the test remote name regexp", leafName)
|
log.Fatalf("%q didn't match the test remote name regexp", leafName)
|
||||||
}
|
}
|
||||||
@ -432,7 +415,7 @@ func RandomRemote(remoteName string, subdir bool) (fs.Fs, string, func(), error)
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, "", nil, err
|
return nil, "", nil, err
|
||||||
}
|
}
|
||||||
remoteName += "/rclone-test-subdir-" + RandomString(8)
|
remoteName += "/rclone-test-subdir-" + random.String(8)
|
||||||
}
|
}
|
||||||
|
|
||||||
remote, err := fs.NewFs(remoteName)
|
remote, err := fs.NewFs(remoteName)
|
||||||
|
@ -31,6 +31,7 @@ import (
|
|||||||
"github.com/rclone/rclone/fs/operations"
|
"github.com/rclone/rclone/fs/operations"
|
||||||
"github.com/rclone/rclone/fs/walk"
|
"github.com/rclone/rclone/fs/walk"
|
||||||
"github.com/rclone/rclone/fstest"
|
"github.com/rclone/rclone/fstest"
|
||||||
|
"github.com/rclone/rclone/lib/random"
|
||||||
"github.com/rclone/rclone/lib/readers"
|
"github.com/rclone/rclone/lib/readers"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
@ -157,7 +158,7 @@ func testPut(t *testing.T, f fs.Fs, file *fstest.Item) (string, fs.Object) {
|
|||||||
contents string
|
contents string
|
||||||
)
|
)
|
||||||
retry(t, "Put", func() error {
|
retry(t, "Put", func() error {
|
||||||
contents = fstest.RandomString(100)
|
contents = random.String(100)
|
||||||
buf := bytes.NewBufferString(contents)
|
buf := bytes.NewBufferString(contents)
|
||||||
uploadHash = hash.NewMultiHasher()
|
uploadHash = hash.NewMultiHasher()
|
||||||
in := io.TeeReader(buf, uploadHash)
|
in := io.TeeReader(buf, uploadHash)
|
||||||
@ -557,7 +558,7 @@ func Run(t *testing.T, opt *Opt) {
|
|||||||
|
|
||||||
const N = 5 * 1024
|
const N = 5 * 1024
|
||||||
// Read N bytes then produce an error
|
// Read N bytes then produce an error
|
||||||
contents := fstest.RandomString(N)
|
contents := random.String(N)
|
||||||
buf := bytes.NewBufferString(contents)
|
buf := bytes.NewBufferString(contents)
|
||||||
er := &errorReader{errors.New("potato")}
|
er := &errorReader{errors.New("potato")}
|
||||||
in := io.MultiReader(buf, er)
|
in := io.MultiReader(buf, er)
|
||||||
@ -1322,7 +1323,7 @@ func Run(t *testing.T, opt *Opt) {
|
|||||||
// TestObjectUpdate tests that Update works
|
// TestObjectUpdate tests that Update works
|
||||||
t.Run("ObjectUpdate", func(t *testing.T) {
|
t.Run("ObjectUpdate", func(t *testing.T) {
|
||||||
skipIfNotOk(t)
|
skipIfNotOk(t)
|
||||||
contents := fstest.RandomString(200)
|
contents := random.String(200)
|
||||||
buf := bytes.NewBufferString(contents)
|
buf := bytes.NewBufferString(contents)
|
||||||
hash := hash.NewMultiHasher()
|
hash := hash.NewMultiHasher()
|
||||||
in := io.TeeReader(buf, hash)
|
in := io.TeeReader(buf, hash)
|
||||||
@ -1507,7 +1508,7 @@ func Run(t *testing.T, opt *Opt) {
|
|||||||
contentSize = 100
|
contentSize = 100
|
||||||
)
|
)
|
||||||
retry(t, "PutStream", func() error {
|
retry(t, "PutStream", func() error {
|
||||||
contents := fstest.RandomString(contentSize)
|
contents := random.String(contentSize)
|
||||||
buf := bytes.NewBufferString(contents)
|
buf := bytes.NewBufferString(contents)
|
||||||
uploadHash = hash.NewMultiHasher()
|
uploadHash = hash.NewMultiHasher()
|
||||||
in := io.TeeReader(buf, uploadHash)
|
in := io.TeeReader(buf, uploadHash)
|
||||||
@ -1564,7 +1565,7 @@ func Run(t *testing.T, opt *Opt) {
|
|||||||
assert.Nil(t, recover(), "Fs.Put() should not panic when src.Size() == -1")
|
assert.Nil(t, recover(), "Fs.Put() should not panic when src.Size() == -1")
|
||||||
}()
|
}()
|
||||||
|
|
||||||
contents := fstest.RandomString(100)
|
contents := random.String(100)
|
||||||
in := bytes.NewBufferString(contents)
|
in := bytes.NewBufferString(contents)
|
||||||
|
|
||||||
obji := object.NewStaticObjectInfo("unknown-size-put.txt", fstest.Time("2002-02-03T04:05:06.499999999Z"), -1, true, nil, nil)
|
obji := object.NewStaticObjectInfo("unknown-size-put.txt", fstest.Time("2002-02-03T04:05:06.499999999Z"), -1, true, nil, nil)
|
||||||
@ -1587,7 +1588,7 @@ func Run(t *testing.T, opt *Opt) {
|
|||||||
assert.Nil(t, recover(), "Object.Update() should not panic when src.Size() == -1")
|
assert.Nil(t, recover(), "Object.Update() should not panic when src.Size() == -1")
|
||||||
}()
|
}()
|
||||||
|
|
||||||
newContents := fstest.RandomString(200)
|
newContents := random.String(200)
|
||||||
in := bytes.NewBufferString(newContents)
|
in := bytes.NewBufferString(newContents)
|
||||||
|
|
||||||
obj := findObject(t, remote, unknownSizeUpdateFile.Path)
|
obj := findObject(t, remote, unknownSizeUpdateFile.Path)
|
||||||
|
22
lib/random/random.go
Normal file
22
lib/random/random.go
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
// Package random holds a few functions for working with random numbers
|
||||||
|
package random
|
||||||
|
|
||||||
|
import "math/rand"
|
||||||
|
|
||||||
|
// String create a random string for test purposes
|
||||||
|
func String(n int) string {
|
||||||
|
const (
|
||||||
|
vowel = "aeiou"
|
||||||
|
consonant = "bcdfghjklmnpqrstvwxyz"
|
||||||
|
digit = "0123456789"
|
||||||
|
)
|
||||||
|
pattern := []string{consonant, vowel, consonant, vowel, consonant, vowel, consonant, digit}
|
||||||
|
out := make([]byte, n)
|
||||||
|
p := 0
|
||||||
|
for i := range out {
|
||||||
|
source := pattern[p]
|
||||||
|
p = (p + 1) % len(pattern)
|
||||||
|
out[i] = source[rand.Intn(len(source))]
|
||||||
|
}
|
||||||
|
return string(out)
|
||||||
|
}
|
13
lib/random/random_test.go
Normal file
13
lib/random/random_test.go
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
package random
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestString(t *testing.T) {
|
||||||
|
for i := 0; i < 100; i++ {
|
||||||
|
assert.Equal(t, i, len(String(i)))
|
||||||
|
}
|
||||||
|
}
|
@ -18,6 +18,7 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/rclone/rclone/lib/file"
|
"github.com/rclone/rclone/lib/file"
|
||||||
|
"github.com/rclone/rclone/lib/random"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -35,24 +36,6 @@ func init() {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// RandomString create a random string for test purposes
|
|
||||||
func RandomString(n int) string {
|
|
||||||
const (
|
|
||||||
vowel = "aeiou"
|
|
||||||
consonant = "bcdfghjklmnpqrstvwxyz"
|
|
||||||
digit = "0123456789"
|
|
||||||
)
|
|
||||||
pattern := []string{consonant, vowel, consonant, vowel, consonant, vowel, consonant, digit}
|
|
||||||
out := make([]byte, n)
|
|
||||||
p := 0
|
|
||||||
for i := range out {
|
|
||||||
source := pattern[p]
|
|
||||||
p = (p + 1) % len(pattern)
|
|
||||||
out[i] = source[rand.Intn(len(source))]
|
|
||||||
}
|
|
||||||
return string(out)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Test contains stats about the running test which work for files or
|
// Test contains stats about the running test which work for files or
|
||||||
// directories
|
// directories
|
||||||
type Test struct {
|
type Test struct {
|
||||||
@ -71,7 +54,7 @@ type Test struct {
|
|||||||
func NewTest(Dir string) *Test {
|
func NewTest(Dir string) *Test {
|
||||||
t := &Test{
|
t := &Test{
|
||||||
dir: Dir,
|
dir: Dir,
|
||||||
name: RandomString(*nameLength),
|
name: random.String(*nameLength),
|
||||||
isDir: rand.Intn(2) == 0,
|
isDir: rand.Intn(2) == 0,
|
||||||
number: atomic.AddInt32(&testNumber, 1),
|
number: atomic.AddInt32(&testNumber, 1),
|
||||||
timer: time.NewTimer(*timeout),
|
timer: time.NewTimer(*timeout),
|
||||||
@ -168,7 +151,7 @@ func (t *Test) rename() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
t.logf("rename")
|
t.logf("rename")
|
||||||
NewName := RandomString(*nameLength)
|
NewName := random.String(*nameLength)
|
||||||
newPath := path.Join(t.dir, NewName)
|
newPath := path.Join(t.dir, NewName)
|
||||||
err := os.Rename(t.path(), newPath)
|
err := os.Rename(t.path(), newPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
Loading…
Reference in New Issue
Block a user