- commit
- 92b854a
- parent
- 17217e6
- author
- Antonio Mika
- date
- 2025-03-12 16:30:59 -0400 EDT
Remove charm
4 files changed,
+113,
-142
M
go.mod
+0,
-8
1@@ -20,15 +20,12 @@ replace github.com/picosh/pobj => ../pobj
2
3 // replace git.sr.ht/~rockorager/vaxis => ../../vaxis
4
5-// replace github.com/charmbracelet/wish => ../../wish
6-
7 require (
8 git.sr.ht/~delthas/senpai v0.3.1-0.20250311003540-18f699aaf9b0
9 git.sr.ht/~rockorager/vaxis v0.12.1-0.20250312161844-81636f76af83
10 github.com/alecthomas/chroma/v2 v2.14.0
11 github.com/antoniomika/syncmap v1.0.0
12 github.com/araddon/dateparse v0.0.0-20210429162001-6b43995a97de
13- github.com/charmbracelet/lipgloss v1.0.0
14 github.com/containerd/console v1.0.4
15 github.com/darkweak/souin v1.7.5
16 github.com/darkweak/souin/plugins/souin/storages v1.7.5
17@@ -102,7 +99,6 @@ require (
18 github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.15 // indirect
19 github.com/aws/aws-sdk-go-v2/service/sts v1.33.15 // indirect
20 github.com/aws/smithy-go v1.22.3 // indirect
21- github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect
22 github.com/aymerick/douceur v0.2.0 // indirect
23 github.com/beorn7/perks v1.0.1 // indirect
24 github.com/bits-and-blooms/bitset v1.5.0 // indirect
25@@ -114,8 +110,6 @@ require (
26 github.com/caddyserver/zerossl v0.1.3 // indirect
27 github.com/cespare/xxhash v1.1.0 // indirect
28 github.com/cespare/xxhash/v2 v2.3.0 // indirect
29- github.com/charmbracelet/x/ansi v0.8.0 // indirect
30- github.com/charmbracelet/x/exp/golden v0.0.0-20240815200342-61de596daa2b // indirect
31 github.com/chzyer/readline v1.5.1 // indirect
32 github.com/coreos/go-semver v0.3.1 // indirect
33 github.com/coreos/go-systemd/v22 v22.5.0 // indirect
34@@ -203,7 +197,6 @@ require (
35 github.com/kr/pretty v0.3.1 // indirect
36 github.com/kr/text v0.2.0 // indirect
37 github.com/libdns/libdns v0.2.2 // indirect
38- github.com/lucasb-eyer/go-colorful v1.2.0 // indirect
39 github.com/lufia/plan9stats v0.0.0-20250224150550-a661cff19cfb // indirect
40 github.com/manifoldco/promptui v0.9.0 // indirect
41 github.com/maruel/natural v1.1.1 // indirect
42@@ -227,7 +220,6 @@ require (
43 github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
44 github.com/modern-go/reflect2 v1.0.2 // indirect
45 github.com/mschoch/smat v0.2.0 // indirect
46- github.com/muesli/termenv v0.16.0 // indirect
47 github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
48 github.com/nats-io/nats.go v1.36.0 // indirect
49 github.com/nats-io/nkeys v0.4.7 // indirect
M
go.sum
+0,
-14
1@@ -117,10 +117,6 @@ github.com/aws/aws-sdk-go-v2/service/sts v1.33.15 h1:ht1jVmeeo2anR7zDiYJLSnRYnO/
2 github.com/aws/aws-sdk-go-v2/service/sts v1.33.15/go.mod h1:xWZ5cOiFe3czngChE4LhCBqUxNwgfwndEF7XlYP/yD8=
3 github.com/aws/smithy-go v1.22.3 h1:Z//5NuZCSW6R4PhQ93hShNbyBbn8BWCmCVCt+Q8Io5k=
4 github.com/aws/smithy-go v1.22.3/go.mod h1:t1ufH5HMublsJYulve2RKmHDC15xu1f26kHCp/HgceI=
5-github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k=
6-github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8=
7-github.com/aymanbagabas/go-udiff v0.2.0 h1:TK0fH4MteXUDspT88n8CKzvK0X9O2xu9yQjWpi6yML8=
8-github.com/aymanbagabas/go-udiff v0.2.0/go.mod h1:RE4Ex0qsGkTAJoQdQQCA0uG+nAzJO/pI/QwceO5fgrA=
9 github.com/aymerick/douceur v0.2.0 h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuPk=
10 github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd30/FjWUq4=
11 github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
12@@ -150,12 +146,6 @@ github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XL
13 github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
14 github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
15 github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
16-github.com/charmbracelet/lipgloss v1.0.0 h1:O7VkGDvqEdGi93X+DeqsQ7PKHDgtQfF8j8/O2qFMQNg=
17-github.com/charmbracelet/lipgloss v1.0.0/go.mod h1:U5fy9Z+C38obMs+T+tJqst9VGzlOYGj4ri9reL3qUlo=
18-github.com/charmbracelet/x/ansi v0.8.0 h1:9GTq3xq9caJW8ZrBTe0LIe2fvfLR/bYXKTx2llXn7xE=
19-github.com/charmbracelet/x/ansi v0.8.0/go.mod h1:wdYl/ONOLHLIVmQaxbIYEC/cRKOQyjTkowiI4blgS9Q=
20-github.com/charmbracelet/x/exp/golden v0.0.0-20240815200342-61de596daa2b h1:MnAMdlwSltxJyULnrYbkZpp4k58Co7Tah3ciKhSNo0Q=
21-github.com/charmbracelet/x/exp/golden v0.0.0-20240815200342-61de596daa2b/go.mod h1:wDlXFlCrmJ8J+swcL/MnGUuYnqgQdW9rhSD61oNMb6U=
22 github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
23 github.com/chzyer/logex v1.2.1 h1:XHDu3E6q+gdHgsdTPH6ImJMIp436vR6MPtH8gP05QzM=
24 github.com/chzyer/logex v1.2.1/go.mod h1:JLbx6lG2kDbNRFnfkgvh4eRJRPX1QCoOIWomwysCBrQ=
25@@ -550,8 +540,6 @@ github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw=
26 github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
27 github.com/libdns/libdns v0.2.2 h1:O6ws7bAfRPaBsgAYt8MDe2HcNBGC29hkZ9MX2eUSX3s=
28 github.com/libdns/libdns v0.2.2/go.mod h1:4Bj9+5CQiNMVGf87wjX4CY3HQJypUHRuLvlsfsZqLWQ=
29-github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY=
30-github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0=
31 github.com/lufia/plan9stats v0.0.0-20250224150550-a661cff19cfb h1:YU0XAr3+rMpM8fP80KEesn32Qa9qkbquokvuwzWyYuA=
32 github.com/lufia/plan9stats v0.0.0-20250224150550-a661cff19cfb/go.mod h1:autxFIvghDt3jPTLoqZ9OZ7s9qTGNAWmYCjVFWPX/zg=
33 github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
34@@ -630,8 +618,6 @@ github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9G
35 github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
36 github.com/mschoch/smat v0.2.0 h1:8imxQsjDm8yFEAVBe7azKmKSgzSkZXDuKkSq9374khM=
37 github.com/mschoch/smat v0.2.0/go.mod h1:kc9mz7DoBKqDyiRL7VZN8KvXQMWeTaVnttLRXOlotKw=
38-github.com/muesli/termenv v0.16.0 h1:S5AlUN9dENB57rsbnkPyfdGuWIlkmzJjbFf0Tf5FWUc=
39-github.com/muesli/termenv v0.16.0/go.mod h1:ZRfOIKPFDYQoDFF4Olj7/QJbW60Ol/kL1pU3VfY/Cnk=
40 github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
41 github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
42 github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
+93,
-113
1@@ -4,13 +4,13 @@ import (
2 "context"
3 "errors"
4 "fmt"
5+ "io"
6 "log/slog"
7 "path/filepath"
8 "strings"
9+ "text/tabwriter"
10 "time"
11
12- "github.com/charmbracelet/lipgloss"
13- "github.com/charmbracelet/lipgloss/table"
14 "github.com/picosh/pico/db"
15 pgsdb "github.com/picosh/pico/pgs/db"
16 "github.com/picosh/pico/shared"
17@@ -18,106 +18,31 @@ import (
18 "github.com/picosh/utils"
19 )
20
21-func projectTable(projects []*db.Project, width int) *table.Table {
22- headers := []string{
23- "Name",
24- "Last Updated",
25- "Links To",
26- "ACL Type",
27- "ACL",
28- "Blocked",
29- }
30- data := [][]string{}
31+func NewTabWriter(out io.Writer) *tabwriter.Writer {
32+ return tabwriter.NewWriter(out, 0, 0, 1, ' ', tabwriter.TabIndent)
33+}
34+
35+func projectTable(sesh io.Writer, projects []*db.Project) {
36+ writer := NewTabWriter(sesh)
37+ fmt.Fprintln(writer, "Name\tLast Updated\tLinks To\tACL Type\tACL\tBlocked")
38+
39 for _, project := range projects {
40- row := []string{
41- project.Name,
42- project.UpdatedAt.Format("2006-01-02 15:04:05"),
43- }
44 links := ""
45 if project.ProjectDir != project.Name {
46 links = project.ProjectDir
47 }
48- row = append(row, links)
49- row = append(row,
50+ fmt.Fprintf(
51+ writer,
52+ "%s\t%s\t%s\t%s\t%s\t%s\n",
53+ project.Name,
54+ project.UpdatedAt.Format("2006-01-02 15:04:05"),
55+ links,
56 project.Acl.Type,
57 strings.Join(project.Acl.Data, " "),
58+ project.Blocked,
59 )
60- row = append(row, project.Blocked)
61- data = append(data, row)
62- }
63-
64- t := table.New().
65- Width(width).
66- Headers(headers...).
67- Rows(data...)
68- return t
69-}
70-
71-func getHelpText(width int) string {
72- helpStr := "Commands: [help, stats, ls, fzf, rm, link, unlink, prune, retain, depends, acl, cache]\n"
73- helpStr += "NOTICE:" + " *must* append with `--write` for the changes to persist.\n"
74-
75- projectName := "projA"
76- headers := []string{"Cmd", "Description"}
77- data := [][]string{
78- {
79- "help",
80- "prints this screen",
81- },
82- {
83- "stats",
84- "usage statistics",
85- },
86- {
87- "ls",
88- "lists projects",
89- },
90- {
91- fmt.Sprintf("fzf %s", projectName),
92- fmt.Sprintf("lists urls of all assets in %s", projectName),
93- },
94- {
95- fmt.Sprintf("rm %s", projectName),
96- fmt.Sprintf("delete %s", projectName),
97- },
98- {
99- fmt.Sprintf("link %s --to projB", projectName),
100- fmt.Sprintf("symbolic link `%s` to `projB`", projectName),
101- },
102- {
103- fmt.Sprintf("unlink %s", projectName),
104- fmt.Sprintf("removes symbolic link for `%s`", projectName),
105- },
106- {
107- fmt.Sprintf("prune %s", projectName),
108- fmt.Sprintf("removes projects that match prefix `%s`", projectName),
109- },
110- {
111- fmt.Sprintf("retain %s", projectName),
112- "alias to `prune` but keeps last N projects",
113- },
114- {
115- fmt.Sprintf("depends %s", projectName),
116- fmt.Sprintf("lists all projects linked to `%s`", projectName),
117- },
118- {
119- fmt.Sprintf("acl %s", projectName),
120- fmt.Sprintf("access control for `%s`", projectName),
121- },
122- {
123- fmt.Sprintf("cache %s", projectName),
124- fmt.Sprintf("clear http cache for `%s`", projectName),
125- },
126 }
127-
128- t := table.New().
129- Width(width).
130- Border(lipgloss.RoundedBorder()).
131- Headers(headers...).
132- Rows(data...)
133-
134- helpStr += t.String()
135- return helpStr
136+ writer.Flush()
137 }
138
139 type Cmd struct {
140@@ -201,7 +126,68 @@ func (c *Cmd) RmProjectAssets(projectName string) error {
141 }
142
143 func (c *Cmd) help() {
144- c.output(getHelpText(c.Width))
145+ helpStr := "Commands: [help, stats, ls, fzf, rm, link, unlink, prune, retain, depends, acl, cache]\n"
146+ helpStr += "NOTICE:" + " *must* append with `--write` for the changes to persist.\n"
147+ c.output(helpStr)
148+ projectName := "projA"
149+
150+ data := [][]string{
151+ {
152+ "help",
153+ "prints this screen",
154+ },
155+ {
156+ "stats",
157+ "usage statistics",
158+ },
159+ {
160+ "ls",
161+ "lists projects",
162+ },
163+ {
164+ fmt.Sprintf("fzf %s", projectName),
165+ fmt.Sprintf("lists urls of all assets in %s", projectName),
166+ },
167+ {
168+ fmt.Sprintf("rm %s", projectName),
169+ fmt.Sprintf("delete %s", projectName),
170+ },
171+ {
172+ fmt.Sprintf("link %s --to projB", projectName),
173+ fmt.Sprintf("symbolic link `%s` to `projB`", projectName),
174+ },
175+ {
176+ fmt.Sprintf("unlink %s", projectName),
177+ fmt.Sprintf("removes symbolic link for `%s`", projectName),
178+ },
179+ {
180+ fmt.Sprintf("prune %s", projectName),
181+ fmt.Sprintf("removes projects that match prefix `%s`", projectName),
182+ },
183+ {
184+ fmt.Sprintf("retain %s", projectName),
185+ "alias to `prune` but keeps last N projects",
186+ },
187+ {
188+ fmt.Sprintf("depends %s", projectName),
189+ fmt.Sprintf("lists all projects linked to `%s`", projectName),
190+ },
191+ {
192+ fmt.Sprintf("acl %s", projectName),
193+ fmt.Sprintf("access control for `%s`", projectName),
194+ },
195+ {
196+ fmt.Sprintf("cache %s", projectName),
197+ fmt.Sprintf("clear http cache for `%s`", projectName),
198+ },
199+ }
200+
201+ writer := NewTabWriter(c.Session)
202+ fmt.Fprintln(writer, "Cmd\tDescription")
203+ for _, dat := range data {
204+ fmt.Fprintf(writer, "%s\t%s\n", dat[0], dat[1])
205+ }
206+ writer.Flush()
207 }
208
209 func (c *Cmd) stats(cfgMaxSize uint64) error {
210@@ -229,20 +215,17 @@ func (c *Cmd) stats(cfgMaxSize uint64) error {
211 return err
212 }
213
214- headers := []string{"Used (GB)", "Quota (GB)", "Used (%)", "Projects (#)"}
215- data := []string{
216- fmt.Sprintf("%.4f", utils.BytesToGB(int(totalFileSize))),
217- fmt.Sprintf("%.4f", utils.BytesToGB(int(storageMax))),
218- fmt.Sprintf("%.4f", (float32(totalFileSize)/float32(storageMax))*100),
219- fmt.Sprintf("%d", len(projects)),
220- }
221-
222- t := table.New().
223- Width(c.Width).
224- Border(lipgloss.RoundedBorder()).
225- Headers(headers...).
226- Rows(data)
227- c.output(t.String())
228+ writer := NewTabWriter(c.Session)
229+ fmt.Fprintln(writer, "Used (GB)\tQuota (GB)\tUsed (%)\tProjects (#)")
230+ fmt.Fprintf(
231+ writer,
232+ "%.4f\t%.4f\t%.4f\t%d\n",
233+ utils.BytesToGB(int(totalFileSize)),
234+ utils.BytesToGB(int(storageMax)),
235+ (float32(totalFileSize)/float32(storageMax))*100,
236+ len(projects),
237+ )
238+ writer.Flush()
239
240 return nil
241 }
242@@ -257,8 +240,7 @@ func (c *Cmd) ls() error {
243 c.output("no projects found")
244 }
245
246- t := projectTable(projects, c.Width)
247- c.output(t.String())
248+ projectTable(c.Session, projects)
249
250 return nil
251 }
252@@ -374,9 +356,7 @@ func (c *Cmd) depends(projectName string) error {
253 return nil
254 }
255
256- t := projectTable(projects, c.Width)
257- c.output(t.String())
258-
259+ projectTable(c.Session, projects)
260 return nil
261 }
262
+20,
-7
1@@ -118,7 +118,8 @@ func (s *SSHServerConnSession) Close() error {
2 }
3
4 func (s *SSHServerConnSession) Exit(code int) error {
5- _, err := s.Channel.SendRequest("exit-status", false, ssh.Marshal(struct{ C int }{code}))
6+ status := struct{ Status uint32 }{uint32(code)}
7+ _, err := s.Channel.SendRequest("exit-status", false, ssh.Marshal(&status))
8 return err
9 }
10
11@@ -265,6 +266,10 @@ func (s *SSHServer) ListenAndServe() error {
12 }()
13 }
14
15+ if errors.Is(retErr, net.ErrClosed) {
16+ return nil
17+ }
18+
19 return retErr
20 }
21
22@@ -358,13 +363,17 @@ func NewSSHServer(ctx context.Context, logger *slog.Logger, config *SSHServerCon
23 SSHServerConn: sc,
24 }
25
26+ req.Reply(true, nil)
27+
28 if err := h(sesh); err != nil {
29- req.Reply(false, nil)
30- sesh.Close()
31+ sc.Logger.Error("subsystem middleware", "err", err)
32+ sesh.Fatal(err)
33+ return
34 }
35
36- req.Reply(true, nil)
37+ sesh.Exit(0)
38 sesh.Close()
39+ return
40 } else if req.Type == "exec" {
41 if len(sc.SSHServer.Config.Middleware) == 0 {
42 req.Reply(false, nil)
43@@ -382,13 +391,17 @@ func NewSSHServer(ctx context.Context, logger *slog.Logger, config *SSHServerCon
44 h = m(h)
45 }
46
47+ req.Reply(true, nil)
48+
49 if err := h(sesh); err != nil {
50- req.Reply(false, nil)
51- sesh.Close()
52+ sc.Logger.Error("exec middleware", "err", err)
53+ sesh.Fatal(err)
54+ return
55 }
56
57- req.Reply(true, nil)
58+ sesh.Exit(0)
59 sesh.Close()
60+ return
61 }
62 }()
63 }