Skip to content

Commit ae65b17

Browse files
Merge pull request #247 from dropbox/put-if-exists-flag
Add --if-exists flag to put command
2 parents 3b76c04 + 64651ef commit ae65b17

7 files changed

Lines changed: 664 additions & 19 deletions

File tree

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -256,8 +256,11 @@ The `--verbose` option will turn on verbose logging and is useful for debugging.
256256
$ dbxcli put file.txt /destination/file.txt # upload a single file
257257
$ dbxcli put -r ./project /backup/project # recursively upload a directory
258258
$ dbxcli put -r -w 8 ./large-folder /backup/large # use 8 workers per large file
259+
$ dbxcli put --if-exists skip file.txt /dest.txt # skip if the file already exists
259260
```
260261

262+
By default, `put` overwrites existing destination files. Use `--if-exists overwrite|skip|fail` to choose whether existing files are overwritten, skipped, or treated as an error.
263+
261264
### Downloading files and directories
262265

263266
```sh

cmd/ls.go

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -47,11 +47,6 @@ func printFolderMetadata(w io.Writer, e *files.FolderMetadata, longFormat bool)
4747
_, _ = fmt.Fprint(w, formatFolderMetadata(e, longFormat))
4848
}
4949

50-
// Invoked by search.go and revs.go
51-
func printFileMetadata(w io.Writer, e *files.FileMetadata, longFormat bool) {
52-
_, _ = fmt.Fprint(w, formatFileMetadata(e, longFormat))
53-
}
54-
5550
func formatFolderMetadata(e *files.FolderMetadata, longFormat bool) string {
5651
text := fmt.Sprintf("%s\t", e.PathDisplay)
5752
if longFormat {

cmd/pipe_test.go

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,15 @@ func testPutCmdWithStdin(stdin io.Reader) *cobra.Command {
1919
return cmd
2020
}
2121

22+
type failReadReader struct {
23+
t *testing.T
24+
}
25+
26+
func (r failReadReader) Read(_ []byte) (int, error) {
27+
r.t.Fatal("stdin should not be read")
28+
return 0, io.EOF
29+
}
30+
2231
func TestPutStdin_RequiresTarget(t *testing.T) {
2332
cmd := testPutCmdWithStdin(strings.NewReader("data"))
2433
err := put(cmd, []string{"-"})
@@ -103,6 +112,32 @@ func TestPutStdin_UploadsContent(t *testing.T) {
103112
}
104113
}
105114

115+
func TestPutStdinIfExistsSkipDoesNotReadStdin(t *testing.T) {
116+
cmd := testPutCmdWithStdin(failReadReader{t: t})
117+
_ = cmd.Flags().Set("if-exists", "skip")
118+
var stderr bytes.Buffer
119+
cmd.SetErr(&stderr)
120+
121+
mock := &mockFilesClient{
122+
getMetadataFn: func(arg *files.GetMetadataArg) (files.IsMetadata, error) {
123+
return &files.FileMetadata{Metadata: files.Metadata{PathDisplay: arg.Path}}, nil
124+
},
125+
uploadFn: func(arg *files.UploadArg, r io.Reader) (*files.FileMetadata, error) {
126+
t.Fatal("upload should not be called for existing destination with --if-exists skip")
127+
return nil, nil
128+
},
129+
}
130+
stubFilesClient(t, mock)
131+
132+
err := put(cmd, []string{"-", "/existing.txt"})
133+
if err != nil {
134+
t.Fatalf("put stdin error: %v", err)
135+
}
136+
if !strings.Contains(stderr.String(), "Skipping /existing.txt") {
137+
t.Errorf("stderr = %q, want skip message", stderr.String())
138+
}
139+
}
140+
106141
func TestPutStdin_UploadsToDashPath(t *testing.T) {
107142
content := "dash path"
108143
cmd := testPutCmdWithStdin(strings.NewReader(content))

0 commit comments

Comments
 (0)