Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add aliases for commonly used commands #8130

Open
dreua opened this issue Apr 24, 2020 · 21 comments
Open

Add aliases for commonly used commands #8130

dreua opened this issue Apr 24, 2020 · 21 comments
Labels
type: feature request Request for a new feature UX: ecosystem research epic Temporary label to link tickets to #8515 UX: functionality research epic Temporary label to link tickets to #8516 UX User experience related

Comments

@dreua
Copy link

dreua commented Apr 24, 2020

What's the problem this feature will solve?

As a software developer and package maintainer, I often install and remove software packages with different package managers. With pip I often run into this error:

$ pip3 remove pdfarranger
ERROR: unknown command "remove"

Describe the solution you'd like

Have a remove command that does exactly the same as uninstall.

Alternative Solutions

  • Using bash's alias command is not easily possible because it can only match the main command (I can add an alias for pip in general but not for pip remove.)
  • pip does not seem to provide a built in alias command like dnf has

Additional context

Package managers which use remove and don't know uninstall:

  1. dnf/yum (they do have erase as an alias)
  2. apt(-get)
  3. pacman

Package managers which have both:

  1. flatpak
@triage-new-issues triage-new-issues bot added the S: needs triage Issues/PRs that need to be triaged label Apr 24, 2020
@pradyunsg pradyunsg added the UX User experience related label Apr 25, 2020
@triage-new-issues triage-new-issues bot removed the S: needs triage Issues/PRs that need to be triaged label Apr 25, 2020
@pradyunsg pradyunsg added the type: feature request Request for a new feature label Apr 25, 2020
@uranusjr
Copy link
Member

Sounds reasonable. I’d suggest not listing the alias in help to avoid clutter, but having the alias itself is fine.

@gutsytechster
Copy link
Contributor

How do we add an alias to a command? I am not sure about it.

@McSinyx
Copy link
Contributor

McSinyx commented Apr 25, 2020

IMHO it's as trivial as

diff --git a/src/pip/_internal/commands/__init__.py b/src/pip/_internal/commands/__init__.py
index 6825fa6e..defcf967 100644
--- a/src/pip/_internal/commands/__init__.py
+++ b/src/pip/_internal/commands/__init__.py
@@ -44,6 +44,10 @@ commands_dict = OrderedDict([
         'pip._internal.commands.uninstall', 'UninstallCommand',
         'Uninstall packages.',
     )),
+    ('remove', CommandInfo(
+        'pip._internal.commands.uninstall', 'UninstallCommand',
+        'Uninstall packages.',
+    )),
     ('freeze', CommandInfo(
         'pip._internal.commands.freeze', 'FreezeCommand',
         'Output installed packages in requirements format.',

I'm trying to work on this because I thought it's easy but had to come here to ask about testing strategy 😄

@gutsytechster
Copy link
Contributor

Thanks, @McSinyx! Please go ahead, no issue :)

As for testing, the approach I can think of is to parametrize the tests which involve uninstall command with remove command as well. IMO, this would test all the cases involve with uninstall command.

@McSinyx
Copy link
Contributor

McSinyx commented Apr 25, 2020

parametrize the tests which involve uninstall command with remove command as well

That's brilliant (kudos to pytest devs for making little convenient things like this possible too). I'm a bit worried about redundancy but first class command may need first class supports.

@deveshks
Copy link
Contributor

deveshks commented Apr 25, 2020

IMHO it's as trivial as

This might cause remove to be listed in pip help, which I think we want to avoid as per #8130 (comment)

$ pip help

Usage:   
  pip <command> [options]

Commands:
  install                     Install packages.
  download                    Download packages.
  uninstall                   Uninstall packages.
  remove                      Uninstall packages.
  freeze                      Output installed packages in requirements format.
  list                        List installed packages.
  show                        Show information about installed packages.
  check                       Verify installed packages have compatible dependencies.
  config                      Manage local and global configuration.
  search                      Search PyPI for packages.
  cache                       Inspect and manage pip's wheel cache.
  wheel                       Build wheels from your requirements.
  hash                        Compute hashes of package archives.
  completion                  A helper command used for command completion.
  debug                       Show information useful for debugging.
  help                        Show help for commands.

I was thinking along the lines of implementing get_alias_commands which looks for a mapping between alias and it's commands (in this case it will be remove -> install) and call it at https://github.com/pypa/pip/blob/master/src/pip/_internal/cli/main_parser.py#L87

@McSinyx
Copy link
Contributor

McSinyx commented Apr 25, 2020

@deveshks, thank you for the heads up, that looks like a much better idea.

@cjc7373
Copy link
Contributor

cjc7373 commented Apr 25, 2020

Personally I on board with the alias command or some similar settings. (like what git has)

@pradyunsg pradyunsg changed the title [Feature request] Add 'remove' command as an alias to 'uninstall' Add 'remove' command as an alias to 'uninstall' Apr 25, 2020
@pradyunsg
Copy link
Member

I’d suggest not listing the alias in help to avoid clutter, but having the alias itself is fine.

I think if we're adding aliases, we definitely want them to be visible to the user via help. That said, we should avoid any amount of clutter that we can. So, I agree that just adding "remove" with the same CommandInfo as uninstall is not what we want to do here.

I'd say, we should aim to have a uniform and proper way to provide aliases to users, allowing for multiple aliases for multiple commands, such that it's not difficult to add another alias for a command (similar to how adding a command is a matter of manipulating a single list).

Of course, this means we'd have to get a bit more fancy with how our command parser works, figure out how help should know about the command names and all that... but I much prefer that to something more "bolted on" / invisible to the users.

I'd imagine aliases could look like this:

$ pip help

Usage:   
  pip <command> [options]

Commands:
  i, add, install             Install packages.
  download                    Download packages.
  u, rm, remove, uninstall    Uninstall packages.
  ...

Or... we could do what npm does in their docs/help:

npm install (with no args, in package dir)
[snip, bunch more examples]

aliases: npm i, npm add
common options: [snip]

Even though I'm using them in the example above... I'm a -1 on adding a "remove" alias for uninstall, without a counterpart "add" alias for install and... I'm a -0 on adding them both together. I don't know how useful this, on it's own, would be to the general audience of pip users. I'm personally a lot more interested in adding shorthands for "most common commands", like I hinted at in the example above, which would be similar to npm i.

All that said, there's also the risk of "too many ways to do the same thing", which... is really the last thing I'd want to start messing about with pip's CLI today. I think we should wait until we move away from optparse to something else (see #4659), where it's easier to do these things properly without adding significantly more technical debt / complexity to the fairly complex/fragile CLI setup we have today.

@pradyunsg
Copy link
Member

As for testing, the approach I can think of is to parametrize the tests which involve uninstall command with remove command as well.

Doubling the number of tests (which doubles test execution times) is not a good idea. I'd much rather have a unit test that mocks out the actual implementation of the commands, and checks that various aliases hit the same Command.run block.

That's 1 extra unit test to run after adding an alias, which is significantly better than running 30+ tests w/ subprocesses and virtual environments being created for isolating them.

@pfmoore
Copy link
Member

pfmoore commented Apr 25, 2020

I'm also somewhat concerned about the precedent this sets. I'm sure there are plenty of other places where pip's commands don't quite match those of other package managers. Should we add aliases for all of those? Why aren't other package managers adding aliases to match pip's commands?

A user-defined alias mechanism like git has might be useful, but explicitly adding code to pip for each alias that someone feels would be useful isn't scalable (or IMO advisable).

@McSinyx
Copy link
Contributor

McSinyx commented Apr 26, 2020

Thank you @pradyunsg and @pfmoore for your thoughtful comments. Given no(t yet any) consensus on the execution, I'll mark my PR as draft until I figured out a clean way to resolve your requests al(most)together, to avoid discussion without concrete code for reference.

Edit: to add to the concerns above, personally I'm neither certain about the representation of subcommand docs, e.g. for uninstall should the usage section be

docs mockups

Usage:   
  pip uninstall [options] <package> ...
  pip uninstall [options] -r <requirements file> ...
  pip remove [options] <package> ...
  pip remove [options] -r <requirements file> ...

or

Usage:   
  pip uninstall [options] <package> ...
  pip remove [options] <package> ...
  pip uninstall [options] -r <requirements file> ...
  pip remove [options] -r <requirements file> ...

or

Usage:   
  pip {uninstall,remove} [options] <package> ...
  pip {uninstall,remove} [options] -r <requirements file> ...

Neither looks visually pleasing to me personally.

@pradyunsg
Copy link
Member

the representation of subcommand docs

Usage:   
  pip uninstall [options] <package> ...
  pip uninstall [options] -r <requirements file> ...

Aliases: pip remove

@McSinyx
Copy link
Contributor

McSinyx commented Apr 26, 2020

@pradyunsg, could you please see if the behavior in GH-8137 fits your vision. I'd be happy with your new suggestion though, just wanna make sure you've seen it.

@dreua
Copy link
Author

dreua commented May 7, 2020

Thank you all for your comments and especially @McSinyx for the PR. I like the proposed behavior and it would make my life (and probably others' too) a bit easier by not having to spend brain cycles to figure out whether you need to type uninstall or remove. Is there anything else I can do to get this merged and shipped?

@wshayes
Copy link

wshayes commented Jun 6, 2020

I just searched for this issue after using remove and add for the umpteenth time :)

I'd like to propose making the following changes

  • install == add
  • uninstall == remove (already part of PR obviously)
  • search == find

Any other commands that people mis-remember and use?

@McSinyx
Copy link
Contributor

McSinyx commented Jun 6, 2020

The search/find which is undergo a UX refactor which group everything together (I think @pradyunsg may explain this better to you, he's been planning it for a while now), but the other two are included in my linked PR (GH-8137).

@nlhkabu nlhkabu added UX: ecosystem research epic Temporary label to link tickets to #8515 UX: functionality research epic Temporary label to link tickets to #8516 labels Jul 28, 2020
@nlhkabu
Copy link
Member

nlhkabu commented Jul 28, 2020

I've added this issue to the UX team's research list.

Under #8516 I will conduct a command audit and find out what commands users currently struggle to remember.
Under #8515 @ei8fdb will compare pip's commands against other packaging tools.

@pradyunsg
Copy link
Member

pradyunsg commented Feb 18, 2022

OK, I'm on board for adding i as an alias for install and u as an alias for uninstall.

If someone wants to file a PR implementing this (based of off #8137, ideally), please feel welcome to. That isn't to say the PR would be guaranteed to merge; but it would help move us forward on this front! ^.^

@luiisp
Copy link

luiisp commented Jul 24, 2024

in response there is: #12828 (comment) (design)

I agree with the confusion about which commands are used by newer developers, but if we take this literally, no functionality would be released as one version would have access to the functionality and another would not.

but your comment is really useful and makes me think about the consequences of such a direct and visible implementation (being displayed with the --help command), taking this into account I thought we could implement this subtly in a gradual way and using just simple aliases ( i,u,ls) we would basically implement the aliases without displaying it in --help and after 4/5 years when most developers already have the version with support for aliases then yes we could display this

@morotti
Copy link
Contributor

morotti commented Jul 24, 2024

following the discussion, I think the most sensible way to go about this issue would be to implement a "remove" command... only to raise a useful error message that the remove command does not exist

# now in main
pip remove
ERROR: unknown command "remove"

# better
pip remove
ERROR: unknown command "pip remove", did you mean "pip uninstall"?

I think the issue is very specific to the uninstall command because it's only used once in a while. I myself can never remember if it's pip remove or pip delete, I try both and it's neither :D

pip install does not need any assistance IMO

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type: feature request Request for a new feature UX: ecosystem research epic Temporary label to link tickets to #8515 UX: functionality research epic Temporary label to link tickets to #8516 UX User experience related
Projects
None yet
Development

Successfully merging a pull request may close this issue.