all messages for Guix-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
From: Ian Eure <ian@retrospec.tv>
To: guix-devel <guix-devel@gnu.org>
Subject: Guix CLI, thoughts and suggestions
Date: Mon, 15 Jan 2024 11:24:29 -0800	[thread overview]
Message-ID: <87il3upczg.fsf@retrospec.tv> (raw)

Greetings,

As I’ve been learning Guix, one of the things I’ve found somewhat 
unpleasant is the lack of consistency within the guix CLI tool. 
It feels a bit Git-like, with not much consistency, commands that 
non-obvioulsy perform more than operation, related commands in 
different places in the tree, etc.

Just so you know where I’m coming from: I’ve found that compliex 
CLI tooling benefits from organization and consistency.  The Linux 
ip(8) command is a good example of this kind of organization: to 
add an IP address, you use `ip address add'.  To show address, `ip 
address show', and to remove one `ip address del'.  When options 
are needed, they get added after the verb or branch in the verb 
tree; the final verb may take positional arguments as well as 
--long or -s (short)-form options.

Some examples of where I think Guix could do better.  This is an 
illustrative list, not an exhaustive one.

Inconsistent organization
=========================

Most package-related commands are under `guix package', but many 
are sibling commands.  Examples are `guix size', `guix lint', 
`guix hash', etc.


Inconsistency between verbs and options
=======================================

Some verbs are bare-word positional arguments, and others are 
flags to related verbs.  IMO, this is the biggest problem, and 
makes it very difficult to find all the things the CLI can do. 
`guix package' is a major offender in this area, as it mixes verbs 
and verb-specific options into the same level.  For example, 
installing a package is `guix package -i foo' rather than `guix 
package install foo', removing is `guix package -r foo' rather 
than `guix package remove foo', and listing installed packages is 
`guix package -I' rather than `guix package installed' (or 
similar).

This means that users can express commands which *seem* like they 
should work, but do not.  For example `guix package -i emacs -r 
emacs-pgtk -I' represents a command to 1) install emacs 2) remove 
emacs-pgtk 3) list installed packages (which would verify the 
previous two operations occurred).  This is a valid command within 
the accepted organization of `guix package', and doesn’t cause an 
error, but doesn’t work: the install and remove steps are ignored. 
A thing I’ve found throughout my career is that designing systems 
so it’s *impossible* to represent unsupported, nonsensical, or 
undefined things is an extremely valuable technique to avoid 
errors and pitfalls.  I think Guix could get a lot of mileage out 
of adopting something similar.

This causes a related problem of making it impossible to know what 
options are valid for what verbs.  Will `guix package --cores=8 -r 
emacs' remove the package while using eight cores of my system? 
Will `guix system -s i686 switch-generation 5' switch me to a 
32-bit version of generation 5?  If verbs are organized better, 
and have their own options, this ambiguity vanishes.


More inconsistency
==================

Other parts of guix have the opposite problem: `guix system 
docker-image' probably ought to be an option to `guix system 
image' rather than a separate verb.


Inconsistency between similar commands
======================================

There are generations of both the system (for GuixSD) and the user 
profile, however, they work differently.  For the system, there’s 
`guix system list-generations' and `guix system 
switch-generation', but for the user profile, you need `guix 
package --list-generations' and `guix package 
--switch-generation=PATTERN'.  Additionally, no help is available 
for either of the system commands: `guix system switch-generations 
--help' gives the same output as `guix system --help' -- no 
description of the supported ways of expressing a generation are 
available.


Flattened verbs
===============

Related, the generation-related commands under `guix system' ought 
to be one level deeper: `guix system generation list', `guix 
system generation switch' etc.


Repeated options
================

Many commands (`guix package', `guix system', `guix build', `guix 
shell') take -L options, to add Guile source to their load-path. 
This probably ought to be an option to guix itself, so you can do 
`guix -L~/src/my-channel build ...'.


Suggestions
===========

All commands should be organized into a tree of verbs.

Verbs should have common aliases (`rm' for `remove', etc).

Verbs should be selected by specifying the minimum unambiguous 
substring.  For example `guix sys gen sw' could refer to `guix 
system generation switch'.

Options should be applicable to each level of the tree, ex `guix 
-L~/src/my-channel' would add that load-path, which would be 
visible to any command.  

Requesting help is a verb.  Appending "help" to any level of the 
verb tree should show both options applicable to that verb, and 
its child verbs.  `guix help' would show global options and all 
top-level verbs (package, system, generation, etc); `guix package 
help' would show package-specific options and package-specific 
verbs; and so on.


Conclusion
==========

I have no idea if anyone feels similarly about this, or whether 
there’s appetite to change the CLI, but I think it’d be time 
well-spent.  Having some kind of agreed-upon standard for how the 
CLI stuff is organized seems like a good thing to me, even if it 
just stops or slows the addition of more commands with unique 
expressions.

It seems like a lot of work to change, and backwards compatibility 
also is an issue.  One option I could see working is shoving the 
entire existing structure under a command in the new tool, so you 
could do `guix old package -I' or similar.  An alternate approach 
would be using an environment variable to change behaviors.

What do you all think?

Thanks,

  — Ian


             reply	other threads:[~2024-01-15 20:19 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-01-15 19:24 Ian Eure [this message]
2024-01-15 21:01 ` Guix CLI, thoughts and suggestions Felix Lechner via Development of GNU Guix and the GNU System distribution.
2024-01-15 22:08 ` Carlo Zancanaro
2024-01-20 22:50   ` Ian Eure
2024-01-22  0:21     ` Carlo Zancanaro
2024-02-04 12:21       ` Rostislav Svoboda
2024-01-17  7:21 ` Efraim Flashner
2024-01-18 13:51   ` Rostislav Svoboda

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

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

  git send-email \
    --in-reply-to=87il3upczg.fsf@retrospec.tv \
    --to=ian@retrospec.tv \
    --cc=guix-devel@gnu.org \
    /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 external index

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

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.