Skip to content

Commit

Permalink
Fix wildcard sync command if files have special characters
Browse files Browse the repository at this point in the history
  • Loading branch information
Brice Flaceliere committed Oct 1, 2024
1 parent c280956 commit 12d1038
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 9 deletions.
3 changes: 2 additions & 1 deletion command/context.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"strconv"
"strings"

"github.com/kballard/go-shellquote"
"github.com/peak/s5cmd/v2/storage/url"
"github.com/urfave/cli/v2"
)
Expand Down Expand Up @@ -68,7 +69,7 @@ func generateCommand(c *cli.Context, cmd string, defaultFlags map[string]interfa

var args []string
for _, url := range urls {
args = append(args, fmt.Sprintf("%q", url.String()))
args = append(args, shellquote.Join(url.String()))
}

flags := []string{}
Expand Down
27 changes: 19 additions & 8 deletions command/context_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,17 @@ func TestGenerateCommand(t *testing.T) {
mustNewURL(t, "s3://bucket/key1"),
mustNewURL(t, "s3://bucket/key2"),
},
expectedCommand: `cp "s3://bucket/key1" "s3://bucket/key2"`,
expectedCommand: `cp s3://bucket/key1 s3://bucket/key2`,
},
{
name: "empty-cli-flags-with-special-char",
cmd: "cp",
flags: []cli.Flag{},
urls: []*url.URL{
mustNewURL(t, "s3://bucket/key '\"1"),
mustNewURL(t, "s3://bucket/key2"),
},
expectedCommand: `cp 's3://bucket/key '\''"1' s3://bucket/key2`,
},
{
name: "empty-cli-flags-with-default-flags",
Expand All @@ -45,7 +55,7 @@ func TestGenerateCommand(t *testing.T) {
mustNewURL(t, "s3://bucket/key1"),
mustNewURL(t, "s3://bucket/key2"),
},
expectedCommand: `cp --acl='public-read' --raw='true' "s3://bucket/key1" "s3://bucket/key2"`,
expectedCommand: `cp --acl='public-read' --raw='true' s3://bucket/key1 s3://bucket/key2`,
},
{
name: "cli-flag-with-whitespaced-flag-value",
Expand All @@ -63,7 +73,7 @@ func TestGenerateCommand(t *testing.T) {
mustNewURL(t, "s3://bucket/key1"),
mustNewURL(t, "s3://bucket/key2"),
},
expectedCommand: `cp --cache-control='public, max-age=31536000, immutable' --raw='true' "s3://bucket/key1" "s3://bucket/key2"`,
expectedCommand: `cp --cache-control='public, max-age=31536000, immutable' --raw='true' s3://bucket/key1 s3://bucket/key2`,
},
{
name: "same-flag-should-be-ignored-if-given-from-both-default-and-cli-flags",
Expand All @@ -81,7 +91,7 @@ func TestGenerateCommand(t *testing.T) {
mustNewURL(t, "s3://bucket/key1"),
mustNewURL(t, "s3://bucket/key2"),
},
expectedCommand: `cp --raw='true' "s3://bucket/key1" "s3://bucket/key2"`,
expectedCommand: `cp --raw='true' s3://bucket/key1 s3://bucket/key2`,
},
{
name: "ignore-non-shared-flag",
Expand Down Expand Up @@ -118,7 +128,7 @@ func TestGenerateCommand(t *testing.T) {
mustNewURL(t, "s3://bucket/key1"),
mustNewURL(t, "s3://bucket/key2"),
},
expectedCommand: `cp --concurrency='6' --flatten='true' --force-glacier-transfer='true' --raw='true' "s3://bucket/key1" "s3://bucket/key2"`,
expectedCommand: `cp --concurrency='6' --flatten='true' --force-glacier-transfer='true' --raw='true' s3://bucket/key1 s3://bucket/key2`,
},
{
name: "string-slice-flag",
Expand All @@ -133,7 +143,7 @@ func TestGenerateCommand(t *testing.T) {
mustNewURL(t, "/source/dir"),
mustNewURL(t, "s3://bucket/prefix/"),
},
expectedCommand: `cp --exclude='*.log' --exclude='*.txt' "/source/dir" "s3://bucket/prefix/"`,
expectedCommand: `cp --exclude='*.log' --exclude='*.txt' /source/dir s3://bucket/prefix/`,
},
{
name: "command-with-multiple-args",
Expand All @@ -142,10 +152,11 @@ func TestGenerateCommand(t *testing.T) {
urls: []*url.URL{
mustNewURL(t, "s3://bucket/key1"),
mustNewURL(t, "s3://bucket/key2"),
mustNewURL(t, "s3://bucket/key3 .txt"),
mustNewURL(t, "s3://bucket/prefix/key3"),
mustNewURL(t, "s3://bucket/prefix/key4"),
},
expectedCommand: `rm "s3://bucket/key1" "s3://bucket/key2" "s3://bucket/prefix/key3" "s3://bucket/prefix/key4"`,
expectedCommand: `rm s3://bucket/key1 s3://bucket/key2 's3://bucket/key3 .txt' s3://bucket/prefix/key3 s3://bucket/prefix/key4`,
},
{
name: "command-args-with-spaces",
Expand All @@ -155,7 +166,7 @@ func TestGenerateCommand(t *testing.T) {
mustNewURL(t, "file with space"),
mustNewURL(t, "wow wow"),
},
expectedCommand: `rm "file with space" "wow wow"`,
expectedCommand: `rm 'file with space' 'wow wow'`,
},
}
for _, tc := range testcases {
Expand Down

0 comments on commit 12d1038

Please sign in to comment.