Skip to content

Commit

Permalink
fix: scp bug when copying / (#104)
Browse files Browse the repository at this point in the history
  • Loading branch information
caarlos0 committed Nov 30, 2022
1 parent d501f49 commit 0e4e2e5
Show file tree
Hide file tree
Showing 9 changed files with 87 additions and 6 deletions.
2 changes: 1 addition & 1 deletion examples/cobra/main.go
Expand Up @@ -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
}

Expand Down
6 changes: 4 additions & 2 deletions examples/scp/main.go
Expand Up @@ -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")
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Expand Up @@ -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
Expand All @@ -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
Expand Down
1 change: 1 addition & 0 deletions go.sum
Expand Up @@ -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=
Expand Down
10 changes: 8 additions & 2 deletions scp/filesystem.go
Expand Up @@ -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),
}
Expand Down Expand Up @@ -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) {
Expand Down
17 changes: 17 additions & 0 deletions scp/filesystem_test.go
Expand Up @@ -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) {
Expand Down
17 changes: 17 additions & 0 deletions scp/fs_test.go
Expand Up @@ -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)

Expand Down
19 changes: 19 additions & 0 deletions 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 file<NULL>E
E
E
T1323853868 0 1323853868 0
C0644 11 c.txt
c text file<NULL>E
E
19 changes: 19 additions & 0 deletions 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 file<NULL>E
E
E
T1323853868 0 1323853868 0
C0644 11 c.txt
c text file<NULL>E
E

0 comments on commit 0e4e2e5

Please sign in to comment.