Make the ssh layer injectable and cover the destructive server commands

The remote commands are the only code in mgsh that can destroy data, and
they were the least verifiable: each one is a single string handed to a
login shell, so a missing quote silently changes which paths it touches.
Every one of them now goes through the sshExec variable, and yesno is a
variable too, so a test can record what would have been sent and answer
the confirmations without a terminal.

The tests pin down what the previous commit fixed by reasoning alone:
that a declined or unreachable `init` sends no rm -rf, that a project
named "my 'weird' project" reaches the server fully quoted, and that
archive's cp/tar/rm sequence is named, ordered and quoted correctly.
push is driven end to end against a real local bare repository.

archive also gained the server-side existence check that init, clone and
show already had, so a project that was never pushed reports that instead
of failing inside cp -r.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-26 11:38:22 +02:00
co-authored by Claude Opus 5
parent ae8c7a3ec0
commit 689a3fe594
4 changed files with 369 additions and 6 deletions
+5 -2
View File
@@ -9,8 +9,11 @@ import (
"github.com/chzyer/readline"
)
// yesno asks a y/n question with a default. Reads a single keypress.
func yesno(prompt string, def bool) bool {
// yesno asks a y/n question with a default and reads a single keypress. It is a
// variable because it guards the destructive operations: tests replace it to
// drive those paths without a terminal, and to assert that the question was
// asked at all.
var yesno = func(prompt string, def bool) bool {
suffix := " y/N ? "
if def {
suffix = " Y/n ? "