-
Notifications
You must be signed in to change notification settings - Fork 0
/
ls.go
126 lines (111 loc) · 2.29 KB
/
ls.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
package command
import (
"flag"
"fmt"
"io"
"io/fs"
"github.com/jarxorg/fssh"
)
type ls struct {
flagSet *flag.FlagSet
isLong bool
}
func newLs() fssh.Command {
return &ls{}
}
func (c *ls) Name() string {
return "ls"
}
func (c *ls) Description() string {
return "list directory contents"
}
func (c *ls) FlagSet() *flag.FlagSet {
if c.flagSet == nil {
s := flag.NewFlagSet(c.Name(), flag.ContinueOnError)
s.Usage = func() {}
s.BoolVar(&c.isLong, "l", false, "long format")
c.flagSet = s
}
return c.flagSet
}
func (c *ls) Reset() {
c.isLong = false
}
func (c *ls) Exec(sh *fssh.Shell) error {
args := c.FlagSet().Args()
name := "."
if len(args) > 0 {
name = args[0]
}
subFs, subName, err := sh.SubFS(name)
if err != nil {
return err
}
if fssh.IsGlobPattern(subName) {
matches, err := fs.Glob(subFs, subName)
if err != nil {
return err
}
for _, match := range matches {
info, err := fs.Stat(subFs, match)
if err != nil {
return err
}
c.printInfo(sh, info)
}
return nil
}
info, err := fs.Stat(subFs, subName)
if err != nil {
return err
}
if !info.IsDir() {
c.printInfo(sh, info)
return nil
}
entries, err := fs.ReadDir(subFs, subName)
if err != nil {
return err
}
for _, entry := range entries {
info, err := entry.Info()
if err != nil {
return err
}
c.printInfo(sh, info)
}
return nil
}
func (c *ls) printInfo(sh *fssh.Shell, info fs.FileInfo) {
name := info.Name()
if c.isLong {
modTime := info.ModTime().Format("2006-01-02 15:04")
size := fssh.DisplaySize(info.Size())
fmt.Fprintf(sh.Stdout, "%s %s %s %s\n", info.Mode(), modTime, size, name)
return
}
tailSlash := ""
if info.IsDir() {
tailSlash = "/"
}
fmt.Fprintf(sh.Stdout, "%s%s\n", name, tailSlash)
}
func (c *ls) AutoCompleter() fssh.AutoCompleterFunc {
return c.autoComplete
}
func (c *ls) autoComplete(sh *fssh.Shell, arg string) ([]string, error) {
return sh.PrefixMatcher.Matches(sh, arg)
}
func (c *ls) Usage(w io.Writer) {
name := c.Name()
fmt.Fprintf(w, "Usage:\n %s ([flags]) ([dir])\n", name)
fmt.Fprintln(w, "Flags:")
c.FlagSet().SetOutput(w)
c.FlagSet().PrintDefaults()
fmt.Fprintln(w, "Examples:")
fmt.Fprintf(w, " %s DIR\n", name)
fmt.Fprintf(w, " %s (s3|gs)://BUCKET/DIR\n", name)
}
func init() {
fssh.RegisterNewCommandFunc(newLs)
}