From a09d97465270ef441791b65bca98d37c25eb0564 Mon Sep 17 00:00:00 2001
From: adamliesko <adamliesko@gmail.com>
Date: Sat, 18 Nov 2017 20:04:18 +0100
Subject: [PATCH] core: get cmd outPath removes trailing slash - fixes #3729

When using path with trailing slashes, ipfs get command had issues
with trying to store content into '.' folder (as the file part of the path
was empty). Now, it correctly stores the file into desired folder,
thanks to the removal of trailing slash by introducing a
getOutPath function in get command, which does proper parsing
Of the output path.

BEFORE:
 $  .pfs get /ipns/multiformats.io/
Saving file(s) to .

NOW:
$ ./ipfs get /ipns/multiformats.io/
Saving file(s) to multiformats.io

License: MIT
Signed-off-by: adamliesko <adamliesko@gmail.com>
---
 core/commands/get.go      | 16 ++++++----
 core/commands/get_test.go | 61 +++++++++++++++++++++++++++++++++++++++
 2 files changed, 72 insertions(+), 5 deletions(-)
 create mode 100644 core/commands/get_test.go

diff --git a/core/commands/get.go b/core/commands/get.go
index ec70ab66b..1fef99f64 100644
--- a/core/commands/get.go
+++ b/core/commands/get.go
@@ -120,11 +120,7 @@ may also specify the level of compression by specifying '-l=<1-9>'.
 					return
 				}
 
-				outPath, _, _ := req.Option("output").String()
-				if len(outPath) == 0 {
-					_, outPath = gopath.Split(req.Arguments()[0])
-					outPath = gopath.Clean(outPath)
-				}
+				outPath := getOutPath(req)
 
 				cmplvl, err := getCompressOptions(req)
 				if err != nil {
@@ -188,6 +184,16 @@ func makeProgressBar(out io.Writer, l int64) *pb.ProgressBar {
 	return bar
 }
 
+func getOutPath(req cmds.Request) string {
+	outPath, _, _ := req.Option("output").String()
+	if outPath == "" {
+		trimmed := strings.TrimRight(req.Arguments()[0], "/")
+		_, outPath = gopath.Split(trimmed)
+		outPath = gopath.Clean(outPath)
+	}
+	return outPath
+}
+
 type getWriter struct {
 	Out io.Writer // for output to user
 	Err io.Writer // for progress bar output
diff --git a/core/commands/get_test.go b/core/commands/get_test.go
new file mode 100644
index 000000000..032fc1095
--- /dev/null
+++ b/core/commands/get_test.go
@@ -0,0 +1,61 @@
+package commands
+
+import (
+	"testing"
+
+	"gx/ipfs/QmSNbH2A1evCCbJSDC6u3RV3GGDhgu6pRGbXHvrN89tMKf/go-ipfs-cmdkit"
+	"gx/ipfs/QmUgr8HrEkQqXfBPtj1A2UEg1V7cvhUhDsmL44wFPCJk5k/go-ipfs-cmds"
+)
+
+func TestGetOutputPath(t *testing.T) {
+	cases := []struct {
+		args    []string
+		opts    cmdkit.OptMap
+		outPath string
+	}{
+		{
+			args: []string{"/ipns/multiformats.io/"},
+			opts: map[string]interface{}{
+				"output": "takes-precedence",
+			},
+			outPath: "takes-precedence",
+		},
+		{
+			args: []string{"/ipns/multiformats.io/", "some-other-arg-to-be-ignored"},
+			opts: cmdkit.OptMap{
+				"output": "takes-precedence",
+			},
+			outPath: "takes-precedence",
+		},
+		{
+			args:    []string{"/ipns/multiformats.io/"},
+			outPath: "multiformats.io",
+			opts:    cmdkit.OptMap{},
+		},
+		{
+			args:    []string{"/ipns/multiformats.io/logo.svg/"},
+			outPath: "logo.svg",
+			opts:    cmdkit.OptMap{},
+		},
+		{
+			args:    []string{"/ipns/multiformats.io", "some-other-arg-to-be-ignored"},
+			outPath: "multiformats.io",
+			opts:    cmdkit.OptMap{},
+		},
+	}
+
+	defOpts, err := GetCmd.GetOptions([]string{})
+	if err != nil {
+		t.Fatalf("error getting default command options: %v", err)
+	}
+
+	for _, tc := range cases {
+		req, err := cmds.NewRequest([]string{}, tc.opts, tc.args, nil, GetCmd, defOpts)
+		if err != nil {
+			t.Fatalf("error creating a command request: %v", err)
+		}
+		if outPath := getOutPath(req); outPath != tc.outPath {
+			t.Errorf("expected outPath %s to be %s", outPath, tc.outPath)
+		}
+	}
+}
-- 
GitLab