Skip to content

Commit 33b2b3a

Browse files
authored
feature: 增加对move和copy的支持 (#93)
issue #89
1 parent 26b7c21 commit 33b2b3a

File tree

7 files changed

+411
-0
lines changed

7 files changed

+411
-0
lines changed

README.md

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,8 @@ docker run --rm upx upx -v
8686
| [get](#get) | 下载一个文件或目录 |
8787
| [put](#put) | 上传一个文件或目录 |
8888
| [upload](#upload) | 上传多个文件或目录或 http(s) 文件, 支持 Glob 模式过滤上传文件|
89+
| [mv](#mv) | 在同一 bucket 内移动文件|
90+
| [cp](#cp) | 在同一 bucket 内复制文件 |
8991
| [rm](#rm) | 删除目录或文件 |
9092
| [sync](#sync) | 目录增量同步,类似 rsync |
9193
| [auth](#auth) | 生成包含空间名操作员密码信息的 auth 字符串 |
@@ -442,6 +444,64 @@ upx rm -d /www
442444
upx rm /aaa.png
443445
```
444446

447+
## mv
448+
449+
> `bucket` 内部移动文件
450+
451+
| args | 说明 |
452+
| --------- | ---- |
453+
| source-file | 需要移动的源文件 |
454+
| dest-file | 需要移动到的目标文件 |
455+
456+
| options | 说明 |
457+
| --------- | ---- |
458+
| -f | 允许覆盖目标文件 |
459+
460+
#### 语法
461+
```bash
462+
upx mv [options] <source-file> <dest-file>
463+
```
464+
465+
#### 示例
466+
移动文件
467+
```bash
468+
upx mv /aaa.mp4 /abc/aaa.mp4
469+
```
470+
471+
移动文件,如果目标存在则强制覆盖
472+
```bash
473+
upx mv -f /aaa.mp4 /abc/aaa.mp4
474+
```
475+
476+
## cp
477+
478+
> `bucket` 内部拷贝文件
479+
480+
| args | 说明 |
481+
| --------- | ---- |
482+
| source-file | 需要复制的源文件 |
483+
| dest-file | 需要复制到的目标文件 |
484+
485+
| options | 说明 |
486+
| --------- | ---- |
487+
| -f | 允许覆盖目标文件 |
488+
489+
#### 语法
490+
```bash
491+
upx mv [options] <source-file> <dest-file>
492+
```
493+
494+
#### 示例
495+
移动文件
496+
```bash
497+
upx cp /aaa.mp4 /abc/aaa.mp4
498+
```
499+
500+
复制文件,如果目标存在则强制覆盖
501+
```bash
502+
upx cp -f /aaa.mp4 /abc/aaa.mp4
503+
```
504+
445505
## sync
446506

447507
> sync 本地路径 存储路径

commands.go

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -561,3 +561,45 @@ func NewUpgradeCommand() cli.Command {
561561
},
562562
}
563563
}
564+
565+
func NewCopyCommand() cli.Command {
566+
return cli.Command{
567+
Name: "cp",
568+
Usage: "copy files inside cloud storage",
569+
ArgsUsage: "[remote-source-path] [remote-target-path]",
570+
Before: CreateInitCheckFunc(LOGIN, CHECK),
571+
Action: func(c *cli.Context) error {
572+
if c.NArg() != 2 {
573+
PrintErrorAndExit("invalid command args")
574+
}
575+
if err := session.Copy(c.Args()[0], c.Args()[1], c.Bool("f")); err != nil {
576+
PrintErrorAndExit(err.Error())
577+
}
578+
return nil
579+
},
580+
Flags: []cli.Flag{
581+
cli.BoolFlag{Name: "f", Usage: "Force overwrite existing files"},
582+
},
583+
}
584+
}
585+
586+
func NewMoveCommand() cli.Command {
587+
return cli.Command{
588+
Name: "mv",
589+
Usage: "move files inside cloud storage",
590+
ArgsUsage: "[remote-source-path] [remote-target-path]",
591+
Before: CreateInitCheckFunc(LOGIN, CHECK),
592+
Action: func(c *cli.Context) error {
593+
if c.NArg() != 2 {
594+
PrintErrorAndExit("invalid command args")
595+
}
596+
if err := session.Move(c.Args()[0], c.Args()[1], c.Bool("f")); err != nil {
597+
PrintErrorAndExit(err.Error())
598+
}
599+
return nil
600+
},
601+
Flags: []cli.Flag{
602+
cli.BoolFlag{Name: "f", Usage: "Force overwrite existing files"},
603+
},
604+
}
605+
}

copy_test.go

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
package upx
2+
3+
import (
4+
"fmt"
5+
"io/ioutil"
6+
"path"
7+
"path/filepath"
8+
"testing"
9+
"time"
10+
11+
"github.com/stretchr/testify/assert"
12+
)
13+
14+
func TestCopy(t *testing.T) {
15+
SetUp()
16+
defer TearDown()
17+
18+
upRootPath := path.Join(ROOT, "copy")
19+
Upx("mkdir", upRootPath)
20+
21+
localRootPath, err := ioutil.TempDir("", "test")
22+
assert.NoError(t, err)
23+
localRootName := filepath.Base(localRootPath)
24+
25+
CreateFile(path.Join(localRootPath, "FILE1"))
26+
CreateFile(path.Join(localRootPath, "FILE2"))
27+
28+
// 上传文件
29+
_, err = Upx("put", localRootPath, upRootPath)
30+
assert.NoError(t, err)
31+
32+
files, err := Ls(path.Join(upRootPath, localRootName))
33+
assert.NoError(t, err)
34+
assert.Len(t, files, 2)
35+
assert.ElementsMatch(
36+
t,
37+
files,
38+
[]string{"FILE1", "FILE2"},
39+
)
40+
41+
time.Sleep(time.Second)
42+
43+
// 正常复制文件
44+
_, err = Upx(
45+
"cp",
46+
path.Join(upRootPath, localRootName, "FILE1"),
47+
path.Join(upRootPath, localRootName, "FILE3"),
48+
)
49+
assert.NoError(t, err)
50+
51+
files, err = Ls(path.Join(upRootPath, localRootName))
52+
assert.NoError(t, err)
53+
assert.Len(t, files, 3)
54+
assert.ElementsMatch(
55+
t,
56+
files,
57+
[]string{"FILE1", "FILE2", "FILE3"},
58+
)
59+
60+
time.Sleep(time.Second)
61+
62+
// 目标文件已存在
63+
_, err = Upx(
64+
"cp",
65+
path.Join(upRootPath, localRootName, "FILE1"),
66+
path.Join(upRootPath, localRootName, "FILE2"),
67+
)
68+
assert.Error(t, err)
69+
assert.Equal(
70+
t,
71+
err.Error(),
72+
fmt.Sprintf(
73+
"target path %s already exists use -f to force overwrite\n",
74+
path.Join(upRootPath, localRootName, "FILE2"),
75+
),
76+
)
77+
78+
files, err = Ls(path.Join(upRootPath, localRootName))
79+
assert.NoError(t, err)
80+
assert.Len(t, files, 3)
81+
assert.ElementsMatch(
82+
t,
83+
files,
84+
[]string{"FILE1", "FILE2", "FILE3"},
85+
)
86+
87+
time.Sleep(time.Second)
88+
89+
// 目标文件已存在, 强制覆盖
90+
_, err = Upx(
91+
"cp",
92+
"-f",
93+
path.Join(upRootPath, localRootName, "FILE1"),
94+
path.Join(upRootPath, localRootName, "FILE2"),
95+
)
96+
assert.NoError(t, err)
97+
98+
files, err = Ls(path.Join(upRootPath, localRootName))
99+
assert.NoError(t, err)
100+
assert.Len(t, files, 3)
101+
assert.ElementsMatch(
102+
t,
103+
files,
104+
[]string{"FILE1", "FILE2", "FILE3"},
105+
)
106+
}

move_test.go

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
package upx
2+
3+
import (
4+
"fmt"
5+
"io/ioutil"
6+
"path"
7+
"path/filepath"
8+
"testing"
9+
"time"
10+
11+
"github.com/stretchr/testify/assert"
12+
)
13+
14+
func TestMove(t *testing.T) {
15+
SetUp()
16+
defer TearDown()
17+
18+
upRootPath := path.Join(ROOT, "move")
19+
Upx("mkdir", upRootPath)
20+
21+
localRootPath, err := ioutil.TempDir("", "test")
22+
assert.NoError(t, err)
23+
localRootName := filepath.Base(localRootPath)
24+
25+
CreateFile(path.Join(localRootPath, "FILE1"))
26+
CreateFile(path.Join(localRootPath, "FILE2"))
27+
28+
// 上传文件
29+
Upx("put", localRootPath, upRootPath)
30+
files, err := Ls(path.Join(upRootPath, localRootName))
31+
32+
assert.NoError(t, err)
33+
assert.Len(t, files, 2)
34+
assert.ElementsMatch(
35+
t,
36+
files,
37+
[]string{"FILE1", "FILE2"},
38+
)
39+
40+
time.Sleep(time.Second)
41+
42+
// 正常移动文件
43+
_, err = Upx(
44+
"mv",
45+
path.Join(upRootPath, localRootName, "FILE1"),
46+
path.Join(upRootPath, localRootName, "FILE3"),
47+
)
48+
assert.NoError(t, err)
49+
50+
files, err = Ls(path.Join(upRootPath, localRootName))
51+
assert.NoError(t, err)
52+
assert.Len(t, files, 2)
53+
assert.ElementsMatch(
54+
t,
55+
files,
56+
[]string{"FILE2", "FILE3"},
57+
)
58+
59+
time.Sleep(time.Second)
60+
61+
// 目标文件已存在
62+
_, err = Upx(
63+
"mv",
64+
path.Join(upRootPath, localRootName, "FILE2"),
65+
path.Join(upRootPath, localRootName, "FILE3"),
66+
)
67+
assert.Equal(
68+
t,
69+
err.Error(),
70+
fmt.Sprintf(
71+
"target path %s already exists use -f to force overwrite\n",
72+
path.Join(upRootPath, localRootName, "FILE3"),
73+
),
74+
)
75+
76+
files, err = Ls(path.Join(upRootPath, localRootName))
77+
assert.NoError(t, err)
78+
assert.Len(t, files, 2)
79+
assert.ElementsMatch(
80+
t,
81+
files,
82+
[]string{"FILE2", "FILE3"},
83+
)
84+
85+
time.Sleep(time.Second)
86+
87+
// 目标文件已存在, 强制覆盖
88+
_, err = Upx(
89+
"mv",
90+
"-f",
91+
path.Join(upRootPath, localRootName, "FILE2"),
92+
path.Join(upRootPath, localRootName, "FILE3"),
93+
)
94+
assert.NoError(t, err)
95+
96+
files, err = Ls(path.Join(upRootPath, localRootName))
97+
assert.NoError(t, err)
98+
assert.Len(t, files, 1)
99+
assert.ElementsMatch(
100+
t,
101+
files,
102+
[]string{"FILE3"},
103+
)
104+
}

putiginore_test.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66
"path/filepath"
77
"strings"
88
"testing"
9+
"time"
910

1011
"github.com/stretchr/testify/assert"
1112
)
@@ -54,6 +55,8 @@ func TestPutIgnore(t *testing.T) {
5455
[]string{"FILE1", "FILE2"},
5556
)
5657

58+
time.Sleep(time.Second)
59+
5760
// 上传隐藏的文件夹, 无all,上传失效
5861
Upx(
5962
"put",
@@ -70,6 +73,8 @@ func TestPutIgnore(t *testing.T) {
7073
[]string{"FILE1", "FILE2"},
7174
)
7275

76+
time.Sleep(time.Second)
77+
7378
// 上传隐藏的文件夹, 有all,上传成功
7479
Upx(
7580
"put",
@@ -86,6 +91,8 @@ func TestPutIgnore(t *testing.T) {
8691
[]string{"FILE1", "FILE2", ".FILES"},
8792
)
8893

94+
time.Sleep(time.Second)
95+
8996
// 上传所有文件
9097
Upx("put", "-all", localRootPath, upRootPath)
9198
files, err = Ls(path.Join(upRootPath, localRootName))

0 commit comments

Comments
 (0)