unofficial mirror of bug-gnu-emacs@gnu.org 
 help / color / mirror / code / Atom feed
From: Brian Cully via "Bug reports for GNU Emacs, the Swiss army knife of text editors" <bug-gnu-emacs@gnu.org>
To: Eli Zaretskii <eliz@gnu.org>
Cc: jporterbugs@gmail.com, 58899@debbugs.gnu.org
Subject: bug#58899: [PATCH v1] Add the "doas" alias to eshell.
Date: Mon, 31 Oct 2022 14:29:24 -0400	[thread overview]
Message-ID: <87k04f3kzf.fsf@ditto.jhoto.spork.org> (raw)
In-Reply-To: <83k04feutc.fsf@gnu.org>

[-- Attachment #1: Type: text/plain, Size: 522 bytes --]

Eli Zaretskii <eliz@gnu.org> writes:

> Two spaces between sentences.

Fixed.

>> +(defun eshell/doas (&rest args)
>> +  "Call Tramp’s doas method with ARGS.
>            ^^^^^^^
> Please use only ASCII characters in the doc strings.
>
> (I'm guessing you have some electric mode enabled, so please make sure
> to have it disabled when you work on our documentation.)

Fixed, and yes I do.

I also spotted an errant ‘q’ I managed to typo into the sudo usage
string, which is now removed.

-bjc


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: v3-0001-Add-the-doas-alias-to-eshell.patch --]
[-- Type: text/x-patch, Size: 10603 bytes --]

From a4c060c7a540065e1fce321b7a4172c0a3da84c1 Mon Sep 17 00:00:00 2001
From: Brian Cully <bjc@kublai.com>
Date: Wed, 26 Oct 2022 21:10:21 -0400
Subject: [PATCH v3 1/2] Add the "doas" alias to eshell.

  * lisp/eshell/em-tramp.el (eshell/doas): new function.
  (eshell--method-wrap-directory): new function.
  (eshell/sudo): accept '-s'/'--shell' for interactive use.
  * test/lisp/eshell/em-tramp-tests.el
  (em-tramp-test/sudo-shell) (em-tramp-test/sudo-user-shell)
  (em-tramp-test/doas-basic) (em-tramp-test/doas-user)
  (em-tramp-test/doas-shell) (em-tramp-test/doas-user-shell): new
  tests.
  * etc/NEWS: mention new 'doas' eshell command.
  * doc/misc/eshell.texi: add 'doas' command documentation.
---
 doc/misc/eshell.texi               |  9 ++--
 etc/NEWS                           |  5 ++
 lisp/eshell/em-tramp.el            | 78 ++++++++++++++++++++----------
 test/lisp/eshell/em-tramp-tests.el | 66 +++++++++++++++++++++++++
 4 files changed, 129 insertions(+), 29 deletions(-)

diff --git a/doc/misc/eshell.texi b/doc/misc/eshell.texi
index ff368c9dc4..96873a3f9a 100644
--- a/doc/misc/eshell.texi
+++ b/doc/misc/eshell.texi
@@ -717,9 +717,12 @@ Built-ins
 @cmindex su
 @itemx sudo
 @cmindex sudo
-Uses TRAMP's @command{su} or @command{sudo} method @pxref{Inline methods, , , tramp}
-to run a command via @command{su} or @command{sudo}.  These commands
-are in the eshell-tramp module, which is disabled by default.
+@itemx doas
+@cmindex doas
+Uses TRAMP's @command{su}, @command{sudo}, or @command{doas} method
+@pxref{Inline methods, , , tramp} to run a command via @command{su},
+@command{sudo}, or @command{doas}.  These commands are in the
+eshell-tramp module, which is disabled by default.
 
 
 @item substitute
diff --git a/etc/NEWS b/etc/NEWS
index bf50c900ea..175e190d31 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -379,6 +379,11 @@ node in the Eshell manual for more details.
 *** Eshell pipelines now only pipe stdout by default.
 To pipe both stdout and stderr, use the '|&' operator instead of '|'.
 
+*** New eshell built-in command 'doas'.
+The privilege-escalation program 'doas' has been added to the existing
+'su' and 'sudo' commands from the 'eshell-tramp' module.  The external
+command may still be accessed by using '*doas'.
+
 ---
 ** The 'delete-forward-char' command now deletes by grapheme clusters.
 This command is by default bound to the <Delete> function key
diff --git a/lisp/eshell/em-tramp.el b/lisp/eshell/em-tramp.el
index aebbc36e71..3daac1db3b 100644
--- a/lisp/eshell/em-tramp.el
+++ b/lisp/eshell/em-tramp.el
@@ -40,9 +40,10 @@
  (defgroup eshell-tramp nil
    "This module defines commands that use TRAMP in a way that is
   not transparent to the user.  So far, this includes only the
-  built-in su and sudo commands, which are not compatible with
-  the full, external su and sudo commands, and require the user
-  to understand how to use the TRAMP sudo method."
+  built-in su, sudo and doas commands, which are not compatible
+  with the full, external su, sudo, and doas commands, and
+  require the user to understand how to use the TRAMP sudo
+  method."
    :tag "TRAMP Eshell features"
    :group 'eshell-module))
 
@@ -52,7 +53,7 @@ eshell-tramp-initialize
     (add-hook 'pcomplete-try-first-hook
 	      'eshell-complete-host-reference nil t))
   (setq-local eshell-complex-commands
-              (append '("su" "sudo")
+              (append '("su" "sudo" "doas")
                       eshell-complex-commands)))
 
 (autoload 'eshell-parse-command "esh-cmd")
@@ -91,6 +92,21 @@ eshell/su
 
 (put 'eshell/su 'eshell-no-numeric-conversions t)
 
+(defun eshell--method-wrap-directory (directory method &optional user)
+  "Return DIRECTORY as accessed by a Tramp METHOD for USER."
+  (let ((user (or user "root"))
+        (dir (file-local-name (expand-file-name directory)))
+        (prefix (file-remote-p directory))
+        (host (or (file-remote-p directory 'host)
+                 tramp-default-host))
+        (rmethod (file-remote-p directory 'method))
+        (ruser (file-remote-p directory 'user)))
+    (if (and prefix (or (not (string-equal rmethod method))
+                     (not (string-equal ruser user))))
+        (format "%s|%s:%s@%s:%s"
+                (substring prefix 0 -1) method user host dir)
+      (format "/%s:%s@%s:%s" method user host dir))))
+
 (defun eshell/sudo (&rest args)
   "Alias \"sudo\" to call Tramp.
 
@@ -99,34 +115,44 @@ eshell/sudo
    "sudo" args
    '((?h "help" nil nil "show this usage screen")
      (?u "user" t user "execute a command as another USER")
+     (?s "shell" nil shell "start a shell instead of executing COMMAND")
      :show-usage
      :parse-leading-options-only
-     :usage "[(-u | --user) USER] COMMAND
+     :usage "[(-u | --user) USER] (-s | --shell) | COMMAND
 Execute a COMMAND as the superuser or another USER.")
-   (throw 'eshell-external
-          (let* ((user (or user "root"))
-                 (host (or (file-remote-p default-directory 'host)
-                           tramp-default-host))
-                 (dir (file-local-name (expand-file-name default-directory)))
-                 (prefix (file-remote-p default-directory))
-                 (default-directory
-                   (if (and prefix
-                            (or
-                             (not
-                              (string-equal
-                               "sudo"
-                               (file-remote-p default-directory 'method)))
-                             (not
-                              (string-equal
-                               user
-                               (file-remote-p default-directory 'user)))))
-                       (format "%s|sudo:%s@%s:%s"
-                               (substring prefix 0 -1) user host dir)
-                     (format "/sudo:%s@%s:%s" user host dir))))
-            (eshell-named-command (car args) (cdr args))))))
+   (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))))))))
 
 (put 'eshell/sudo 'eshell-no-numeric-conversions t)
 
+(defun eshell/doas (&rest args)
+  "Call Tramp's doas method with ARGS.
+
+Uses the system doas through Tramp's doas method."
+  (eshell-eval-using-options
+   "doas" args
+   '((?h "help" nil nil "show this usage screen")
+     (?u "user" t user "execute a command as another USER")
+     (?s "shell" nil shell "start a shell instead of executing COMMAND")
+     :show-usage
+     :parse-leading-options-only
+     :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))))))))
+
+(put 'eshell/doas 'eshell-no-numeric-conversions t)
+
 (provide 'em-tramp)
 
 ;; Local Variables:
diff --git a/test/lisp/eshell/em-tramp-tests.el b/test/lisp/eshell/em-tramp-tests.el
index 8969c1e229..9d28d6be82 100644
--- a/test/lisp/eshell/em-tramp-tests.el
+++ b/test/lisp/eshell/em-tramp-tests.el
@@ -85,4 +85,70 @@ em-tramp-test/sudo-user
              `(,(format "/sudo:USER@%s:%s" tramp-default-host default-directory)
                ("echo" ("-u" "hi")))))))
 
+(ert-deftest em-tramp-test/sudo-shell ()
+  "Test Eshell `sudo' command with -s/--shell option."
+  (dolist (args '(("--shell")
+                  ("-s")))
+    (should (equal
+             (catch 'eshell-replace-command (apply #'eshell/sudo args))
+             `(eshell-trap-errors
+               (eshell-named-command
+                "cd"
+                (list ,(format "/sudo:root@%s:%s" tramp-default-host default-directory))))))))
+
+(ert-deftest em-tramp-test/sudo-user-shell ()
+  "Test Eshell `sudo' command with -s and -u options."
+  (should (equal
+           (catch 'eshell-replace-command (eshell/sudo "-u" "USER" "-s"))
+           `(eshell-trap-errors
+             (eshell-named-command
+              "cd"
+              (list ,(format "/sudo:USER@%s:%s" tramp-default-host default-directory)))))))
+
+(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")))))))
+
+(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")))))))
+
+(ert-deftest em-tramp-test/doas-shell ()
+  "Test Eshell `doas' command with -s/--shell option."
+  (dolist (args '(("--shell")
+                  ("-s")))
+    (should (equal
+             (catch 'eshell-replace-command (apply #'eshell/doas args))
+             `(eshell-trap-errors
+               (eshell-named-command
+                "cd"
+                (list ,(format "/doas:root@%s:%s" tramp-default-host default-directory))))))))
+
+(ert-deftest em-tramp-test/doas-user-shell ()
+  "Test Eshell `doas' command with -s and -u options."
+  (should (equal
+           (catch 'eshell-replace-command (eshell/doas "-u" "USER" "-s"))
+           `(eshell-trap-errors
+             (eshell-named-command
+              "cd"
+              (list ,(format "/doas:USER@%s:%s" tramp-default-host default-directory)))))))
+
 ;;; em-tramp-tests.el ends here
-- 
2.38.0


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #3: v3-0002-lisp-eshell-em-tramp.el-Rename-TRAMP-to-Tramp.patch --]
[-- Type: text/x-patch, Size: 2500 bytes --]

From 4703a99e7b56d64686c3bd374657e2dbf7853e5d Mon Sep 17 00:00:00 2001
From: Brian Cully <bjc@kublai.com>
Date: Mon, 31 Oct 2022 11:55:45 -0400
Subject: [PATCH v3 2/2] lisp/eshell/em-tramp.el: Rename 'TRAMP' to 'Tramp'.

---
 lisp/eshell/em-tramp.el | 18 +++++++++---------
 1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/lisp/eshell/em-tramp.el b/lisp/eshell/em-tramp.el
index 3daac1db3b..499deaa7fc 100644
--- a/lisp/eshell/em-tramp.el
+++ b/lisp/eshell/em-tramp.el
@@ -1,4 +1,4 @@
-;;; em-tramp.el --- Eshell features that require TRAMP  -*- lexical-binding:t -*-
+;;; em-tramp.el --- Eshell features that require Tramp  -*- lexical-binding:t -*-
 
 ;; Copyright (C) 1999-2022 Free Software Foundation, Inc.
 
@@ -21,7 +21,7 @@
 
 ;;; Commentary:
 
-;; Eshell features that require TRAMP.
+;; Eshell features that require Tramp.
 
 ;;; Code:
 
@@ -38,17 +38,17 @@
 ;;;###autoload
 (progn
  (defgroup eshell-tramp nil
-   "This module defines commands that use TRAMP in a way that is
+   "This module defines commands that use Tramp in a way that is
   not transparent to the user.  So far, this includes only the
   built-in su, sudo and doas commands, which are not compatible
   with the full, external su, sudo, and doas commands, and
-  require the user to understand how to use the TRAMP sudo
+  require the user to understand how to use the Tramp sudo
   method."
-   :tag "TRAMP Eshell features"
+   :tag "Tramp Eshell features"
    :group 'eshell-module))
 
 (defun eshell-tramp-initialize ()   ;Called from `eshell-mode' via intern-soft!
-  "Initialize the TRAMP-using commands code."
+  "Initialize the Tramp-using commands code."
   (when (eshell-using-module 'eshell-cmpl)
     (add-hook 'pcomplete-try-first-hook
 	      'eshell-complete-host-reference nil t))
@@ -59,9 +59,9 @@ eshell-tramp-initialize
 (autoload 'eshell-parse-command "esh-cmd")
 
 (defun eshell/su (&rest args)
-  "Alias \"su\" to call TRAMP.
+  "Alias \"su\" to call Tramp.
 
-Uses the system su through TRAMP's su method."
+Uses the system su through Tramp's su method."
   (eshell-eval-using-options
    "su" args
    '((?h "help" nil nil "show this usage screen")
@@ -110,7 +110,7 @@ eshell--method-wrap-directory
 (defun eshell/sudo (&rest args)
   "Alias \"sudo\" to call Tramp.
 
-Uses the system sudo through TRAMP's sudo method."
+Uses the system sudo through Tramp's sudo method."
   (eshell-eval-using-options
    "sudo" args
    '((?h "help" nil nil "show this usage screen")
-- 
2.38.0


  reply	other threads:[~2022-10-31 18:29 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-10-30 16:42 bug#58899: [PATCH v1] Add the "doas" alias to eshell Brian Cully via Bug reports for GNU Emacs, the Swiss army knife of text editors
2022-10-30 21:51 ` Jim Porter
2022-10-30 22:06   ` Jim Porter
2022-10-31 12:36     ` Eli Zaretskii
2022-10-31  8:16   ` Michael Albinus
2022-10-31 16:01   ` Brian Cully via Bug reports for GNU Emacs, the Swiss army knife of text editors
2022-10-31 18:01     ` Eli Zaretskii
2022-10-31 18:29       ` Brian Cully via Bug reports for GNU Emacs, the Swiss army knife of text editors [this message]
2022-11-03 17:09         ` Jim Porter
2022-11-03 20:24           ` Brian Cully via Bug reports for GNU Emacs, the Swiss army knife of text editors
2022-11-05 19:10             ` Jim Porter

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.gnu.org/software/emacs/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=87k04f3kzf.fsf@ditto.jhoto.spork.org \
    --to=bug-gnu-emacs@gnu.org \
    --cc=58899@debbugs.gnu.org \
    --cc=bjc@spork.org \
    --cc=eliz@gnu.org \
    --cc=jporterbugs@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).