From d919714aa58caf50a86c5c0be29fc9d984960399 Mon Sep 17 00:00:00 2001 From: Carlos A Becker Date: Wed, 30 Nov 2022 10:52:36 -0300 Subject: [PATCH] fix: scp bug when copying / Signed-off-by: Carlos A Becker --- examples/cobra/main.go | 2 +- examples/scp/main.go | 6 ++++-- go.mod | 2 +- go.sum | 1 + scp/filesystem.go | 10 ++++++++-- scp/filesystem_test.go | 17 +++++++++++++++++ scp/fs_test.go | 17 +++++++++++++++++ scp/testdata/TestFS/recursive_folder.test | 19 +++++++++++++++++++ .../scp_-f/recursive_folder.test | 19 +++++++++++++++++++ 9 files changed, 87 insertions(+), 6 deletions(-) create mode 100644 scp/testdata/TestFS/recursive_folder.test create mode 100644 scp/testdata/TestFilesystem/scp_-f/recursive_folder.test diff --git a/examples/cobra/main.go b/examples/cobra/main.go index 236ba41..ccb42fa 100644 --- a/examples/cobra/main.go +++ b/examples/cobra/main.go @@ -57,7 +57,7 @@ func main() { rootCmd.SetErr(s.Stderr()) rootCmd.CompletionOptions.DisableDefaultCmd = true if err := rootCmd.Execute(); err != nil { - s.Exit(1) + _ = s.Exit(1) return } diff --git a/examples/scp/main.go b/examples/scp/main.go index d0086d7..267353d 100644 --- a/examples/scp/main.go +++ b/examples/scp/main.go @@ -15,8 +15,10 @@ import ( "github.com/charmbracelet/wish/scp" ) -const host = "localhost" -const port = 23234 +const ( + host = "localhost" + port = 23235 +) func main() { handler := scp.NewFileSystemHandler("./examples/scp/testdata") diff --git a/go.mod b/go.mod index 9ffb7f6..3fb897f 100644 --- a/go.mod +++ b/go.mod @@ -8,6 +8,7 @@ require ( github.com/charmbracelet/lipgloss v0.6.0 github.com/charmbracelet/ssh v0.0.0-20221117183211-483d43d97103 github.com/go-git/go-git/v5 v5.4.2 + github.com/google/go-cmp v0.5.5 github.com/hashicorp/golang-lru/v2 v2.0.1 github.com/matryer/is v1.4.0 github.com/muesli/termenv v0.13.0 @@ -28,7 +29,6 @@ require ( github.com/gliderlabs/ssh v0.3.5 // indirect github.com/go-git/gcfg v1.5.0 // indirect github.com/go-git/go-billy/v5 v5.3.1 // indirect - github.com/google/go-cmp v0.5.5 // indirect github.com/imdario/mergo v0.3.12 // indirect github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect github.com/kevinburke/ssh_config v0.0.0-20201106050909-4977a11b4351 // indirect diff --git a/go.sum b/go.sum index 7335aef..40d4946 100644 --- a/go.sum +++ b/go.sum @@ -150,6 +150,7 @@ golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/time v0.0.0-20220411224347-583f2d630306 h1:+gHMid33q6pen7kv9xvT+JRinntgeXO2AeZVd0AWD3w= golang.org/x/time v0.0.0-20220411224347-583f2d630306/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/scp/filesystem.go b/scp/filesystem.go index 2027fdf..72f4903 100644 --- a/scp/filesystem.go +++ b/scp/filesystem.go @@ -18,7 +18,6 @@ var _ Handler = &fileSystemHandler{} // NewFileSystemHandler return a Handler based on the given dir. func NewFileSystemHandler(root string) Handler { - // FIXME: if you scp -r host:/, it'll copy the root folder too, and it shouldn't. return &fileSystemHandler{ root: filepath.Clean(root), } @@ -62,7 +61,14 @@ func (h *fileSystemHandler) Glob(_ ssh.Session, s string) ([]string, error) { } func (h *fileSystemHandler) WalkDir(_ ssh.Session, path string, fn fs.WalkDirFunc) error { - return filepath.WalkDir(h.prefixed(path), fn) + return filepath.WalkDir(h.prefixed(path), func(path string, d fs.DirEntry, err error) error { + // if h.root is ./foo/bar, we don't want to server `bar` as the root, + // but instead its contents. + if path == h.root { + return err + } + return fn(path, d, err) + }) } func (h *fileSystemHandler) NewDirEntry(_ ssh.Session, name string) (*DirEntry, error) { diff --git a/scp/filesystem_test.go b/scp/filesystem_test.go index 1db3373..a0ced6a 100644 --- a/scp/filesystem_test.go +++ b/scp/filesystem_test.go @@ -102,6 +102,23 @@ func TestFilesystem(t *testing.T) { _, err := session.CombinedOutput("scp -r -f a") is.True(err != nil) }) + + t.Run("recursive folder", func(t *testing.T) { + is := is.New(t) + + dir := t.TempDir() + h := NewFileSystemHandler(dir) + + is.NoErr(os.MkdirAll(filepath.Join(dir, "a/b/c/d/e"), 0o755)) + is.NoErr(os.WriteFile(filepath.Join(dir, "a/b/c.txt"), []byte("c text file"), 0o644)) + is.NoErr(os.WriteFile(filepath.Join(dir, "a/b/c/d/e/e.txt"), []byte("e text file"), 0o644)) + chtimesTree(t, dir, atime, mtime) + + session := setup(t, h, nil) + bts, err := session.CombinedOutput("scp -r -f /") + is.NoErr(err) + requireEqualGolden(t, bts) + }) }) t.Run("scp -t", func(t *testing.T) { diff --git a/scp/fs_test.go b/scp/fs_test.go index c88d998..2c03982 100644 --- a/scp/fs_test.go +++ b/scp/fs_test.go @@ -88,6 +88,23 @@ func TestFS(t *testing.T) { requireEqualGolden(t, bts) }) + t.Run("recursive folder", func(t *testing.T) { + is := is.New(t) + + dir := t.TempDir() + h := NewFileSystemHandler(dir) + + is.NoErr(os.MkdirAll(filepath.Join(dir, "a/b/c/d/e"), 0o755)) + is.NoErr(os.WriteFile(filepath.Join(dir, "a/b/c.txt"), []byte("c text file"), 0o644)) + is.NoErr(os.WriteFile(filepath.Join(dir, "a/b/c/d/e/e.txt"), []byte("e text file"), 0o644)) + chtimesTree(t, dir, atime, mtime) + + session := setup(t, h, nil) + bts, err := session.CombinedOutput("scp -r -f /") + is.NoErr(err) + requireEqualGolden(t, bts) + }) + t.Run("recursive invalid file", func(t *testing.T) { is := is.New(t) diff --git a/scp/testdata/TestFS/recursive_folder.test b/scp/testdata/TestFS/recursive_folder.test new file mode 100644 index 0000000..5621c00 --- /dev/null +++ b/scp/testdata/TestFS/recursive_folder.test @@ -0,0 +1,19 @@ +T1323853868 0 1323853868 0 +D0755 0 a +T1323853868 0 1323853868 0 +D0755 0 b +T1323853868 0 1323853868 0 +D0755 0 c +T1323853868 0 1323853868 0 +D0755 0 d +T1323853868 0 1323853868 0 +D0755 0 e +T1323853868 0 1323853868 0 +C0644 11 e.txt +e text fileE +E +E +T1323853868 0 1323853868 0 +C0644 11 c.txt +c text fileE +E diff --git a/scp/testdata/TestFilesystem/scp_-f/recursive_folder.test b/scp/testdata/TestFilesystem/scp_-f/recursive_folder.test new file mode 100644 index 0000000..5621c00 --- /dev/null +++ b/scp/testdata/TestFilesystem/scp_-f/recursive_folder.test @@ -0,0 +1,19 @@ +T1323853868 0 1323853868 0 +D0755 0 a +T1323853868 0 1323853868 0 +D0755 0 b +T1323853868 0 1323853868 0 +D0755 0 c +T1323853868 0 1323853868 0 +D0755 0 d +T1323853868 0 1323853868 0 +D0755 0 e +T1323853868 0 1323853868 0 +C0644 11 e.txt +e text fileE +E +E +T1323853868 0 1323853868 0 +C0644 11 c.txt +c text fileE +E