From 460f58da2cb2b6352cfdadaca7ce68de94f8092a Mon Sep 17 00:00:00 2001 From: Dylan Waits Date: Fri, 27 May 2016 19:14:14 -0700 Subject: [PATCH 1/4] Add ability to run `ls` on files --- cmd/ls.go | 39 +++++++++++++++++++++++++++++---------- 1 file changed, 29 insertions(+), 10 deletions(-) diff --git a/cmd/ls.go b/cmd/ls.go index 634eae0..a417dd3 100644 --- a/cmd/ls.go +++ b/cmd/ls.go @@ -18,6 +18,7 @@ import ( "fmt" "io" "os" + "strings" "text/tabwriter" "github.com/dropbox/dropbox-sdk-go-unofficial/files" @@ -25,6 +26,17 @@ import ( "github.com/spf13/cobra" ) +func getFileMetadata(path string) (*files.Metadata, error) { + arg := files.NewGetMetadataArg(path) + + res, err := dbx.GetMetadata(arg) + if err != nil { + return nil, err + } + + return res, nil +} + func printFolderMetadata(w io.Writer, e *files.FolderMetadata, longFormat bool) { if longFormat { fmt.Fprintf(w, "-\t-\t-\t") @@ -50,21 +62,28 @@ func ls(cmd *cobra.Command, args []string) (err error) { arg := files.NewListFolderArg(path) res, err := dbx.ListFolder(arg) + var entries []*files.Metadata if err != nil { - return - } + if strings.Contains(err.Error(), "path/not_folder/") { + metaRes, _ := getFileMetadata(path) + entries = []*files.Metadata{metaRes} + err = nil + } else { + return err + } + } else { + entries = res.Entries - entries := res.Entries + for res.HasMore { + arg := files.NewListFolderContinueArg(res.Cursor) - for res.HasMore { - arg := files.NewListFolderContinueArg(res.Cursor) + res, err = dbx.ListFolderContinue(arg) + if err != nil { + return + } - res, err = dbx.ListFolderContinue(arg) - if err != nil { - return + entries = append(entries, res.Entries...) } - - entries = append(entries, res.Entries...) } w := new(tabwriter.Writer) From 9c597eb7a5e4d4c9a89374b159fc41281ede1544 Mon Sep 17 00:00:00 2001 From: Dylan Waits Date: Sat, 28 May 2016 14:40:51 -0700 Subject: [PATCH 2/4] Update `ls` command description and examples Reword examples slightly and add an example for running `ls` on a file. --- cmd/ls.go | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/cmd/ls.go b/cmd/ls.go index a417dd3..2c9e43e 100644 --- a/cmd/ls.go +++ b/cmd/ls.go @@ -109,16 +109,15 @@ func ls(cmd *cobra.Command, args []string) (err error) { // lsCmd represents the ls command var lsCmd = &cobra.Command{ Use: "ls [flags] []", - Short: "List folders", - Long: `List Folders. - Attempting ls on files will fail with 'Error: path/not_folder/.' - - Examples: - $ dbxcli ls / # Or, dbxcli ls - $ dbxcli ls some-folder - $ dbxcli ls /some-folder # Or dbxcli ls some-folder/ - $ dbxcli ls -l # Or, dbxcli ls --long - `, + Short: "List files and folders", + Long: `List files and folders + +Examples: +$ dbxcli ls / # Or just 'ls' +$ dbxcli ls /some-folder # Or 'ls some-folder' +$ dbxcli ls /some-folder/some-file.pdf +$ dbxcli ls -l # Or 'ls --long' +`, RunE: ls, } From 8710beebf1c2fdcf59544e51e4a0bde0fb5d396b Mon Sep 17 00:00:00 2001 From: Dylan Waits Date: Sat, 28 May 2016 15:33:18 -0700 Subject: [PATCH 3/4] Remove naked returns from `ls` command function Naked returns are discouraged in long functions because they harm readability; the `ls` function seems to be getting to that point. --- cmd/ls.go | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/cmd/ls.go b/cmd/ls.go index 2c9e43e..2f55ccc 100644 --- a/cmd/ls.go +++ b/cmd/ls.go @@ -26,6 +26,7 @@ import ( "github.com/spf13/cobra" ) +// Sends a get_metadata request for a given path and returns the response func getFileMetadata(path string) (*files.Metadata, error) { arg := files.NewGetMetadataArg(path) @@ -55,7 +56,7 @@ func ls(cmd *cobra.Command, args []string) (err error) { path := "" if len(args) > 0 { if path, err = validatePath(args[0]); err != nil { - return + return err } } @@ -64,11 +65,17 @@ func ls(cmd *cobra.Command, args []string) (err error) { res, err := dbx.ListFolder(arg) var entries []*files.Metadata if err != nil { + // Don't treat a "not_folder" error as fatal; recover by sending a + // get_metadata request for the same path and using that response instead. if strings.Contains(err.Error(), "path/not_folder/") { - metaRes, _ := getFileMetadata(path) + var metaRes *files.Metadata + metaRes, err = getFileMetadata(path) entries = []*files.Metadata{metaRes} - err = nil - } else { + } + + // Return if there's an error other than "not_folder" or if the follow-up + // metadata request fails. + if err != nil { return err } } else { @@ -79,7 +86,7 @@ func ls(cmd *cobra.Command, args []string) (err error) { res, err = dbx.ListFolderContinue(arg) if err != nil { - return + return err } entries = append(entries, res.Entries...) @@ -103,7 +110,7 @@ func ls(cmd *cobra.Command, args []string) (err error) { } w.Flush() - return + return err } // lsCmd represents the ls command From 44f15d71f92b338fd89f5d5d6cd86413003c14f2 Mon Sep 17 00:00:00 2001 From: Dylan Waits Date: Sun, 29 May 2016 17:12:53 -0700 Subject: [PATCH 4/4] Use correct struct field for `ls` command examples In cmd/ls assign the example text to `cobra.Command.Example` instead of `cobra.Command.Long` so that it's placed below the "usage" section in the help text output. --- cmd/ls.go | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/cmd/ls.go b/cmd/ls.go index 2f55ccc..d2d4744 100644 --- a/cmd/ls.go +++ b/cmd/ls.go @@ -117,14 +117,10 @@ func ls(cmd *cobra.Command, args []string) (err error) { var lsCmd = &cobra.Command{ Use: "ls [flags] []", Short: "List files and folders", - Long: `List files and folders - -Examples: -$ dbxcli ls / # Or just 'ls' -$ dbxcli ls /some-folder # Or 'ls some-folder' -$ dbxcli ls /some-folder/some-file.pdf -$ dbxcli ls -l # Or 'ls --long' -`, + Example: ` dbxcli ls / # Or just 'ls' + dbxcli ls /some-folder # Or 'ls some-folder' + dbxcli ls /some-folder/some-file.pdf + dbxcli ls -l`, RunE: ls, }