Fix command replacement with the Eshell builtin versions of "sudo" and "doas"

This is particularly important when the inner command to execute is an
alias.  Aliases throw 'eshell-replace-command' too, so we want to do
this in two phases: first, replace the "sudo"/"doas" with a
let-binding of 'default-directory', and then later, let the alias code
do its own replacement (bug#68074).

* lisp/eshell/em-tramp.el (eshell/sudo, eshell/doas): Use
'eshell-replace-command' to wrap the inner command.
* test/lisp/eshell/em-tramp-tests.el (mock-eshell-named-command):
Remove.
(em-tramp-test/sudo-basic, em-tramp-test/sudo-user)
(em-tramp-test/doas-basic, em-tramp-test/doas-user): Catch
'eshell-replace-command'.
This commit is contained in:
Jim Porter 2024-01-24 18:32:00 -08:00
parent aa386cd92f
commit 3c680968e4
2 changed files with 50 additions and 61 deletions

View file

@ -121,12 +121,11 @@ Uses the system sudo through Tramp's sudo method."
:usage "[(-u | --user) USER] (-s | --shell) | COMMAND
Execute a COMMAND as the superuser or another USER.")
(let ((dir (eshell--method-wrap-directory default-directory "sudo" user)))
(if shell
(throw 'eshell-replace-command
(eshell-parse-command "cd" (list dir)))
(throw 'eshell-external
(let ((default-directory dir))
(eshell-named-command (car args) (cdr args))))))))
(throw 'eshell-replace-command
(if shell
(eshell-parse-command "cd" (list dir))
`(let ((default-directory ,dir))
(eshell-named-command ',(car args) ',(cdr args))))))))
(put 'eshell/sudo 'eshell-no-numeric-conversions t)
@ -144,12 +143,11 @@ Uses the system doas through Tramp's doas method."
:usage "[(-u | --user) USER] (-s | --shell) | COMMAND
Execute a COMMAND as the superuser or another USER.")
(let ((dir (eshell--method-wrap-directory default-directory "doas" user)))
(if shell
(throw 'eshell-replace-command
(eshell-parse-command "cd" (list dir)))
(throw 'eshell-external
(let ((default-directory dir))
(eshell-named-command (car args) (cdr args))))))))
(throw 'eshell-replace-command
(if shell
(eshell-parse-command "cd" (list dir))
`(let ((default-directory ,dir))
(eshell-named-command ',(car args) ',(cdr args))))))))
(put 'eshell/doas 'eshell-no-numeric-conversions t)

View file

@ -59,35 +59,31 @@
"cd"
(list ,(format "/su:root@%s:~/" tramp-default-host))))))
(defun mock-eshell-named-command (&rest args)
"Dummy function to test Eshell `sudo' command rewriting."
(list default-directory args))
(ert-deftest em-tramp-test/sudo-basic ()
"Test Eshell `sudo' command with default user."
(cl-letf (((symbol-function 'eshell-named-command)
#'mock-eshell-named-command))
(should (equal
(catch 'eshell-external (eshell/sudo "echo" "hi"))
`(,(format "/sudo:root@%s:%s" tramp-default-host default-directory)
("echo" ("hi")))))
(should (equal
(catch 'eshell-external (eshell/sudo "echo" "-u" "hi"))
`(,(format "/sudo:root@%s:%s" tramp-default-host default-directory)
("echo" ("-u" "hi")))))))
(let ((sudo-directory (format "/sudo:root@%s:%s"
tramp-default-host default-directory)))
(should (equal (catch 'eshell-replace-command
(eshell/sudo "echo" "hi"))
`(let ((default-directory ,sudo-directory))
(eshell-named-command '"echo" '("hi")))))
(should (equal (catch 'eshell-replace-command
(eshell/sudo "echo" "-u" "hi"))
`(let ((default-directory ,sudo-directory))
(eshell-named-command '"echo" '("-u" "hi")))))))
(ert-deftest em-tramp-test/sudo-user ()
"Test Eshell `sudo' command with specified user."
(cl-letf (((symbol-function 'eshell-named-command)
#'mock-eshell-named-command))
(should (equal
(catch 'eshell-external (eshell/sudo "-u" "USER" "echo" "hi"))
`(,(format "/sudo:USER@%s:%s" tramp-default-host default-directory)
("echo" ("hi")))))
(should (equal
(catch 'eshell-external (eshell/sudo "-u" "USER" "echo" "-u" "hi"))
`(,(format "/sudo:USER@%s:%s" tramp-default-host default-directory)
("echo" ("-u" "hi")))))))
(let ((sudo-directory (format "/sudo:USER@%s:%s"
tramp-default-host default-directory)))
(should (equal (catch 'eshell-replace-command
(eshell/sudo "-u" "USER" "echo" "hi"))
`(let ((default-directory ,sudo-directory))
(eshell-named-command '"echo" '("hi")))))
(should (equal (catch 'eshell-replace-command
(eshell/sudo "-u" "USER" "echo" "-u" "hi"))
`(let ((default-directory ,sudo-directory))
(eshell-named-command '"echo" '("-u" "hi")))))))
(ert-deftest em-tramp-test/sudo-shell ()
"Test Eshell `sudo' command with -s/--shell option."
@ -109,34 +105,29 @@
(ert-deftest em-tramp-test/doas-basic ()
"Test Eshell `doas' command with default user."
(cl-letf (((symbol-function 'eshell-named-command)
#'mock-eshell-named-command))
(should (equal
(catch 'eshell-external (eshell/doas "echo" "hi"))
`(,(format "/doas:root@%s:%s"
tramp-default-host default-directory)
("echo" ("hi")))))
(should (equal
(catch 'eshell-external (eshell/doas "echo" "-u" "hi"))
`(,(format "/doas:root@%s:%s"
tramp-default-host default-directory)
("echo" ("-u" "hi")))))))
(let ((doas-directory (format "/doas:root@%s:%s"
tramp-default-host default-directory)))
(should (equal (catch 'eshell-replace-command
(eshell/doas "echo" "hi"))
`(let ((default-directory ,doas-directory))
(eshell-named-command '"echo" '("hi")))))
(should (equal (catch 'eshell-replace-command
(eshell/doas "echo" "-u" "hi"))
`(let ((default-directory ,doas-directory))
(eshell-named-command '"echo" '("-u" "hi")))))))
(ert-deftest em-tramp-test/doas-user ()
"Test Eshell `doas' command with specified user."
(cl-letf (((symbol-function 'eshell-named-command)
#'mock-eshell-named-command))
(should (equal
(catch 'eshell-external (eshell/doas "-u" "USER" "echo" "hi"))
`(,(format "/doas:USER@%s:%s"
tramp-default-host default-directory)
("echo" ("hi")))))
(should (equal
(catch 'eshell-external
(eshell/doas "-u" "USER" "echo" "-u" "hi"))
`(,(format "/doas:USER@%s:%s"
tramp-default-host default-directory)
("echo" ("-u" "hi")))))))
(let ((doas-directory (format "/doas:USER@%s:%s"
tramp-default-host default-directory)))
(should (equal (catch 'eshell-replace-command
(eshell/doas "-u" "USER" "echo" "hi"))
`(let ((default-directory ,doas-directory))
(eshell-named-command '"echo" '("hi")))))
(should (equal (catch 'eshell-replace-command
(eshell/doas "-u" "USER" "echo" "-u" "hi"))
`(let ((default-directory ,doas-directory))
(eshell-named-command '"echo" '("-u" "hi")))))))
(ert-deftest em-tramp-test/doas-shell ()
"Test Eshell `doas' command with -s/--shell option."