From 4751e7c63c0ed7b55d8104884ea7c09fc7d677ab Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Tue, 5 Sep 2017 13:25:43 -0700 Subject: [PATCH] detector/file: pwd symlink should be determined with EvalSymlinks We were using `ReadLink` before which read the exact link. Unfortunately, we want to evaluate this link relative to the pwd if it is an absolute path otherwise we evaluate the symlink incorrectly. For example, if the pwd is set to "/foo/fake" and the value is "../real", but we're evaluating go-getter from the real shell pwd of "/bar", then we'd turn "/foo/fake" into "/bar/real". The behavior of shells is to take it relative to its location, not your pwd. This preserves that. --- detect_file.go | 2 +- detect_file_test.go | 50 +++++++++++++++---- .../detect-file-symlink-pwd/real/hello.txt | 0 .../detect-file-symlink-pwd/syml/pwd | 1 + 4 files changed, 42 insertions(+), 11 deletions(-) create mode 100644 test-fixtures/detect-file-symlink-pwd/real/hello.txt create mode 120000 test-fixtures/detect-file-symlink-pwd/syml/pwd diff --git a/detect_file.go b/detect_file.go index 756ea43f8..4ef41ea73 100644 --- a/detect_file.go +++ b/detect_file.go @@ -32,7 +32,7 @@ func (d *FileDetector) Detect(src, pwd string) (string, bool, error) { return "", true, err } if fi.Mode()&os.ModeSymlink != 0 { - pwd, err = os.Readlink(pwd) + pwd, err = filepath.EvalSymlinks(pwd) if err != nil { return "", true, err } diff --git a/detect_file_test.go b/detect_file_test.go index aa4ff2aaf..106702a5c 100644 --- a/detect_file_test.go +++ b/detect_file_test.go @@ -1,7 +1,11 @@ package getter import ( + "fmt" + "os" + "path/filepath" "runtime" + "strings" "testing" ) @@ -17,6 +21,9 @@ var fileTests = []fileTest{ } var unixFileTests = []fileTest{ + {"./foo", "test-fixtures/detect-file-symlink-pwd/syml/pwd", + "test-fixtures/detect-file-symlink-pwd/real/foo", false}, + {"/foo", "/pwd", "file:///foo", false}, {"/foo?bar=baz", "/pwd", "file:///foo?bar=baz", false}, } @@ -34,19 +41,42 @@ func TestFileDetector(t *testing.T) { fileTests = append(fileTests, unixFileTests...) } + // Get the pwd + pwdRoot, err := os.Getwd() + if err != nil { + t.Fatalf("err: %s", err) + } + pwdRoot, err = filepath.Abs(pwdRoot) + if err != nil { + t.Fatalf("err: %s", err) + } + f := new(FileDetector) for i, tc := range fileTests { - out, ok, err := f.Detect(tc.in, tc.pwd) - if err != nil { - t.Fatalf("err: %s", err) - } - if !ok { - t.Fatal("not ok") - } + t.Run(fmt.Sprintf("%d", i), func(t *testing.T) { + pwd := tc.pwd + if !filepath.IsAbs(pwd) { + pwd = filepath.Join(pwdRoot, pwd) + } - if out != tc.out { - t.Fatalf("%d: bad: %#v", i, out) - } + out, ok, err := f.Detect(tc.in, pwd) + if err != nil { + t.Fatalf("err: %s", err) + } + if !ok { + t.Fatal("not ok") + } + + expected := tc.out + if !strings.HasPrefix(expected, "file://") { + expected = "file://" + filepath.Join(pwdRoot, expected) + } + + if out != expected { + t.Fatalf("input: %q\npwd: %q\nexpected: %q\nbad output: %#v", + tc.in, pwd, expected, out) + } + }) } } diff --git a/test-fixtures/detect-file-symlink-pwd/real/hello.txt b/test-fixtures/detect-file-symlink-pwd/real/hello.txt new file mode 100644 index 000000000..e69de29bb diff --git a/test-fixtures/detect-file-symlink-pwd/syml/pwd b/test-fixtures/detect-file-symlink-pwd/syml/pwd new file mode 120000 index 000000000..05b44e001 --- /dev/null +++ b/test-fixtures/detect-file-symlink-pwd/syml/pwd @@ -0,0 +1 @@ +../real \ No newline at end of file