Subject: [PATCH v3 2/2] scripts: Warn the first time pull or package is run as root.

From: "(" <[email-masked]>
Date: Thu, 27 Oct 2022 20:42:43 +0100

* guix/ui.scm (root-warning): New variable.
* guix/scripts/pull.scm (guix-pull): Warn the first time it's being
  run as root.
* guix/scripts/package.scm (guix-package*): Likewise if the new
  `root-hint?' argument is `#t'.
(guix-package): Use `#:root-hint? #t' in invocation of `guix-package*'.
* guix/scripts/install.scm (guix-install): Likewise.
* guix/scripts/remove.scm (guix-remove): Likewise.
* guix/scripts/remove.scm (guix-upgrade): Likewise.

A pretty common beginner mistake, it seems, is assuming that since
every other package manager you've used requires root for installing,
removing, and upgrading packages, Guix must too.

This commit tries to make it harder to make such an assumption, by
making commands such as `pull`, `package`, and `upgrade` display
a warning the first time they are run as root.
---
 guix/scripts/install.scm |  3 ++-
 guix/scripts/package.scm | 11 ++++++++---
 guix/scripts/pull.scm    |  2 ++
 guix/scripts/remove.scm  |  3 ++-
 guix/scripts/upgrade.scm |  3 ++-
 guix/ui.scm              |  8 ++++++++
 6 files changed, 24 insertions(+), 6 deletions(-)

diff --git a/guix/scripts/install.scm b/guix/scripts/install.scm
index 63e625f266..bf11fc7b11 100644
--- a/guix/scripts/install.scm
+++ b/guix/scripts/install.scm
@@ -1,5 +1,6 @@
 ;;; GNU Guix --- Functional package management for GNU
 ;;; Copyright © 2019, 2020 Ludovic Courtès <[email-masked]>
+;;; Copyright © 2022 ( <[email-masked]>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -80,4 +81,4 @@ (define opts
                         (list %package-default-options #f)
                         #:argument-handler handle-argument))
 
-  (guix-package* opts))
+  (guix-package* opts #:root-hint? #t))
diff --git a/guix/scripts/package.scm b/guix/scripts/package.scm
index b9090307ac..10cf32475b 100644
--- a/guix/scripts/package.scm
+++ b/guix/scripts/package.scm
@@ -12,6 +12,7 @@
 ;;; Copyright © 2018 Steve Sprang <[email-masked]>
 ;;; Copyright © 2022 Josselin Poiret <[email-masked]>
 ;;; Copyright © 2022 Antero Mejr <[email-masked]>
+;;; Copyright © 2022 ( <[email-masked]>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -1078,12 +1079,16 @@ (define opts
     (parse-command-line args %options (list %default-options #f)
                         #:argument-handler handle-argument))
 
-  (guix-package* opts))
+  (guix-package* opts #:root-hint? #t))
 
-(define (guix-package* opts)
+(define* (guix-package* opts #:key (root-hint? #f))
   "Run the 'guix package' command on OPTS, an alist resulting for command-line
-option processing with 'parse-command-line'."
+option processing with 'parse-command-line'.  If ROOT-HINT? is #T, a hint is
+shown on the first usage of this procedure that informs users about Guix's
+support for per-user package management."
   (with-error-handling
+    (when root-hint?
+      (root-warning 'package-root-hint))
     (or (process-query opts)
         (parameterize ((%store  (open-connection))
                        (%graft? (assoc-ref opts 'graft?)))
diff --git a/guix/scripts/pull.scm b/guix/scripts/pull.scm
index 7b6c58dbc3..98aaf0b377 100644
--- a/guix/scripts/pull.scm
+++ b/guix/scripts/pull.scm
@@ -2,6 +2,7 @@
 ;;; Copyright © 2013-2015, 2017-2022 Ludovic Courtès <[email-masked]>
 ;;; Copyright © 2017 Marius Bakke <[email-masked]>
 ;;; Copyright © 2020, 2021 Tobias Geerinckx-Rice <[email-masked]>
+;;; Copyright © 2022 ( <[email-masked]>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -826,6 +827,7 @@ (define (no-arguments arg _)
     (leave (G_ "~A: extraneous argument~%") arg))
 
   (with-error-handling
+    (root-warning 'pull-root-hint)
     (with-git-error-handling
      (let* ((opts         (parse-command-line args %options
                                               (list %default-options)
diff --git a/guix/scripts/remove.scm b/guix/scripts/remove.scm
index a46ad04d56..131649eace 100644
--- a/guix/scripts/remove.scm
+++ b/guix/scripts/remove.scm
@@ -1,5 +1,6 @@
 ;;; GNU Guix --- Functional package management for GNU
 ;;; Copyright © 2019, 2020 Ludovic Courtès <[email-masked]>
+;;; Copyright © 2022 ( <[email-masked]>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -76,4 +77,4 @@ (define opts
                         (list %package-default-options #f)
                         #:argument-handler handle-argument))
 
-  (guix-package* opts))
+  (guix-package* opts #:root-hint? #t))
diff --git a/guix/scripts/upgrade.scm b/guix/scripts/upgrade.scm
index beb59cbe6f..dd14600fe4 100644
--- a/guix/scripts/upgrade.scm
+++ b/guix/scripts/upgrade.scm
@@ -2,6 +2,7 @@
 ;;; Copyright © 2019, 2020 Ludovic Courtès <[email-masked]>
 ;;; Copyright © 2020 Jakub Kądziołka <[email-masked]>
 ;;; Copyright © 2020 Simon Tournier <[email-masked]>
+;;; Copyright © 2022 ( <[email-masked]>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -87,4 +88,4 @@ (define opts
                               #f)
                         #:argument-handler handle-argument))
 
-  (guix-package* opts))
+  (guix-package* opts #:root-hint? #t))
diff --git a/guix/ui.scm b/guix/ui.scm
index 3512c761d2..0f1a603025 100644
--- a/guix/ui.scm
+++ b/guix/ui.scm
@@ -142,6 +142,7 @@ (define-module (guix ui)
             hint-file
             record-hint
             hint-given?
+            root-warning
 
             %default-message-language
             current-message-language
@@ -2086,6 +2087,13 @@ (define (hint-given? hint)
   "Return true if HINT was already given."
   (file-exists? (hint-file hint)))
 
+(define (root-warning hint-name)
+  (when (and (not (hint-given? hint-name))
+             (zero? (getuid)))
+    (record-hint hint-name)
+    (warning (G_ "this command is user-specific, so running it as root \
+will affect only the 'root' user~%"))))
+
 
 ;;;
 ;;; Command-line option processing.
-- 
2.38.0