feat: long names in questions cut with … and the window as wide as its words; SSH dialog hides «Вход» for a saved host and says «подключение…» quietly; zip and unzip on SSH hosts without them through Python's zipfile
This commit is contained in:
1 parent
6db78399ac
commit
434900a168
5 files changed
+40
-20
No files matched your search
@@ -139,7 +139,8 @@ func (a *Agent) sshfsOpen(ctx context.Context, t proto.SSHTarget) (any, error) {
|
||||
}
|
||||
c := &sshfsConn{client: client, target: t, last: time.Now()}
|
||||
out, _ := sshRun(client, "stat -c %F / >/dev/null 2>&1 && echo GNU; stat -f %HT / >/dev/null 2>&1 && echo BSD; "+
|
||||
"command -v zip >/dev/null 2>&1 && echo ZIP; command -v unzip >/dev/null 2>&1 && echo UNZIP; echo \"$HOME\"")
|
||||
"command -v zip >/dev/null 2>&1 && echo ZIP; command -v unzip >/dev/null 2>&1 && echo UNZIP; "+
|
||||
"command -v python3 >/dev/null 2>&1 && echo PY; echo \"$HOME\"")
|
||||
lines := strings.Split(strings.TrimSpace(out), "\n")
|
||||
switch {
|
||||
case strings.Contains(out, "GNU"):
|
||||
@@ -158,7 +159,7 @@ func (a *Agent) sshfsOpen(ctx context.Context, t proto.SSHTarget) (any, error) {
|
||||
sshfsJanitor.Do(func() { go sshfsSweep() })
|
||||
// zip and unzip, where the host has them, for the pane's buttons.
|
||||
return map[string]any{"id": id, "home": c.home,
|
||||
"zip": hasLine(lines, "ZIP"), "unzip": hasLine(lines, "UNZIP")}, nil
|
||||
"zip": hasLine(lines, "ZIP") || hasLine(lines, "PY"), "unzip": hasLine(lines, "UNZIP") || hasLine(lines, "PY")}, nil
|
||||
}
|
||||
|
||||
func hasLine(lines []string, w string) bool {
|
||||
@@ -410,7 +411,10 @@ func zipCommand(paths []string, dest string) (string, error) {
|
||||
}
|
||||
names[i] = shq("./" + path.Base(p))
|
||||
}
|
||||
return "cd -- " + shq(dir) + " && zip -r -q -y " + shq(path.Clean(dest)) + " " + strings.Join(names, " "), nil
|
||||
// zip where the host has it, else Python's zipfile, which most have.
|
||||
items := strings.Join(names, " ")
|
||||
return "cd -- " + shq(dir) + " && if command -v zip >/dev/null 2>&1; then zip -r -q -y " + shq(path.Clean(dest)) + " " + items + "; " +
|
||||
"else python3 -m zipfile -c " + shq(path.Clean(dest)) + " " + items + "; fi", nil
|
||||
}
|
||||
|
||||
// unzipCommand unpacks the archive p into dest (its own folder if empty),
|
||||
@@ -419,7 +423,8 @@ func unzipCommand(p, dest string) string {
|
||||
if dest == "" {
|
||||
dest = path.Dir(path.Clean(p))
|
||||
}
|
||||
return "unzip -o -q " + shq(path.Clean(p)) + " -d " + shq(path.Clean(dest))
|
||||
return "if command -v unzip >/dev/null 2>&1; then unzip -o -q " + shq(path.Clean(p)) + " -d " + shq(path.Clean(dest)) + "; " +
|
||||
"else python3 -m zipfile -e " + shq(path.Clean(p)) + " " + shq(path.Clean(dest)) + "; fi"
|
||||
}
|
||||
|
||||
// writeCommand writes stdin to p through a file beside it, so a broken
|
||||
|
||||
@@ -114,7 +114,8 @@ func TestZipCommand(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
want := `cd -- '/srv' && zip -r -q -y '/tmp/x.zip' './a b' './it'\''s'`
|
||||
want := `cd -- '/srv' && if command -v zip >/dev/null 2>&1; then zip -r -q -y '/tmp/x.zip' './a b' './it'\''s'; ` +
|
||||
`else python3 -m zipfile -c '/tmp/x.zip' './a b' './it'\''s'; fi`
|
||||
if cmd != want {
|
||||
t.Fatalf("got %s\nwant %s", cmd, want)
|
||||
}
|
||||
@@ -124,7 +125,7 @@ func TestZipCommand(t *testing.T) {
|
||||
if _, err := zipCommand(nil, "/t.zip"); err == nil {
|
||||
t.Fatal("no items: want an error")
|
||||
}
|
||||
if got := unzipCommand("/srv/a.zip", ""); got != `unzip -o -q '/srv/a.zip' -d '/srv'` {
|
||||
if got := unzipCommand("/srv/a.zip", ""); got != `if command -v unzip >/dev/null 2>&1; then unzip -o -q '/srv/a.zip' -d '/srv'; else python3 -m zipfile -e '/srv/a.zip' '/srv'; fi` {
|
||||
t.Fatalf("unzip: %s", got)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user