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
rustup CLI design #129
Comments
The thrust of this all sounds great to me. I wasn't personally deeply familiar with all the bells and whistles of multirust.sh, so for example I don't know what it means to add an override. Consolidating the top level commands into sub-sub commands seems good. I will say that For switching between toolchains and such ti may be worth taking a look at tools like RVM or NVM, maybe there's a "standard precedent"? |
I guess there will be an option to disable it, for when rustup itself is not writeable? (For instance when installed by the package manager). |
Yes. Good idea. |
I think I'd still like to have a Perhaps the bare |
This adds the `rustup` command as described in rust-lang#129. Major changes: * A bare `rustup` updates all tracked channels and self-updates. * All the `--copy-local`, `--link local` and `--installer` options are gone. There is just `rustup channel link`, which covers the most common reason for creating custom toolchains. * `add-target`, `list-targets`, and `remove-targets` are all under the `target` subcommand, and all operate on the current toolchain instead of needing to specify it explicitly. * Override comands are all under the `override` subcommand. * Lesser commands for modifying toolchains are under the `toolchain` subcommand, but I decided `multirust update` and `multirust update nightly` were useful enough to stay its own subcommand. * The UI for updating all channels is changed from `multirust-rs` slightly: both the update status and channel revision are displayed in the same place. * I've removed green from 'info' logging and used it only for successful updates to make it more impactful. Note there are several ways to update now: `rustup` updates everything, `rustup update` updates the current toolchain, and `rustup update [toolchain]` updates a specific toolchain.
This adds the `rustup` command as described in rust-lang#129. Major changes: * A bare `rustup` updates all tracked channels and self-updates. * All the `--copy-local`, `--link local` and `--installer` options are gone. There is just `rustup channel link`, which covers the most common reason for creating custom toolchains. * `add-target`, `list-targets`, and `remove-targets` are all under the `target` subcommand, and all operate on the current toolchain instead of needing to specify it explicitly. * Override comands are all under the `override` subcommand. * Lesser commands for modifying toolchains are under the `toolchain` subcommand, but I decided `multirust update` and `multirust update nightly` were useful enough to stay its own subcommand. * The UI for updating all channels is changed from `multirust-rs` slightly: both the update status and channel revision are displayed in the same place. * I've removed green from 'info' logging and used it only for successful updates to make it more impactful. Note there are several ways to update now: `rustup` updates everything, `rustup update` updates the current toolchain, and `rustup update [toolchain]` updates a specific toolchain.
This adds the `rustup` command as described in rust-lang#129. Major changes: * A bare `rustup` updates all tracked channels and self-updates. * All the `--copy-local`, `--link local` and `--installer` options are gone. There is just `rustup channel link`, which covers the most common reason for creating custom toolchains. * `add-target`, `list-targets`, and `remove-targets` are all under the `target` subcommand, and all operate on the current toolchain instead of needing to specify it explicitly. * Override comands are all under the `override` subcommand. * Lesser commands for modifying toolchains are under the `toolchain` subcommand, but I decided `multirust update` and `multirust update nightly` were useful enough to stay its own subcommand. * The UI for updating all channels is changed from `multirust-rs` slightly: both the update status and channel revision are displayed in the same place. * I've removed green from 'info' logging and used it only for successful updates to make it more impactful. Note there are several ways to update now: `rustup` updates everything, `rustup update` updates the current toolchain, and `rustup update [toolchain]` updates a specific toolchain.
@brson, in line with @alexcrichton's suggestion about looking at rvm/nvm above, I've been following this with some interest and am also a heavy user of rbenv/pyenv/nodenv, and those are also worth looking at for comparison. It's a pretty well-designed UI.
The overall structure for installed versions is pretty similar to what you've already been doing with multicast, too, with a dedicated directory at e.g. A common $ pyenv install 2.7.10
$ pyenv install 3.5.1
$ pyenv global 2.7.10
$ pyenv version
2.7.10 (set by /Users/chris/.pyenv/version)
$ python --version
2.7.10
$ mkdir my_project
$ cd my_project
$ pyenv local 3.5.1
$ pyenv version
3.5.1 (set by /Users/chris/my_project/.python_version
$ python --version
Python 3.5.1 Obvious there are some substantial tweaks that would be needed to account for the special notions we have in Rust for our stable/beta/nightly channels approach, so I'm not suggesting you just adopt it wholesale, but again: it's a great UI, so probably worth stealing from as makes good sense. |
Thanks for the feedback @chriskrycho. I've taken your pyenv examples and translated them to both
|
I noticed that pyenv stores the local toolchain overrides inside the project directories. I don't remember why I didn't do that in multirust (perhaps I didn't want people to check that information in) but it has obvious advantages. Probably doesn't impact the cli much though. |
I like pyenv's scheme that puts the override version at |
@chriskrycho Edit: After further reading it seems that |
For conversation's sake here is the
|
@alexcrichton nvm calls |
We could switch from 'default' / 'override' terminology to 'global' / 'local' since there's such strong precedence. My main resistence is because of potential confusion when discussing system installs of rust, which are also in a sense 'global'. I do think 'default' / 'override' is clearer than 'global' / 'local'. nvm uses 'use' for this, which is the word I like best, but doesn't convey the globalness of default/global, nor have an obvious partner word like override/local. |
I've personally always been a little skeptical of some of the things rvm/nvm do, specifically directory-level overrides, shell overrides, etc. They're convenient to use, but they come at a toll. Awhile back I noticed that a new shell windows took noticeably longer to give me a prompt, and it got way faster once I stopped loading nvm. Similarly, I wouldn't want all normal To me, so long as the startup time is or can be super optimized, I'm fine with a global/local concept (although I will agree that just having one "default" is easier to understand). In terms of shell vs run vs rustc vs cargo, I agree that |
👍 on that; I agree 100%.
Huh. Maybe I'm misunderstanding the source and the help, but I believe all that Since That particular use case is likely to be much less common in Rust, unless people decide to start using it as their built tool glue (!), but it's definitely more convenient IMO for a series of commands using a non-default/non-override toolchain than actually launching a full shell instance just for those tasks, a la
I agree about startup times; zsh plugins sometimes make me sad. That said, I would guess that the local overrides are going to be really useful to people. Thinking, for example, about using something like Diesel in one project, but not in another (and so, nightly in one project but not another): it's very convenient for both the shell itself and anything launched from it (editors, e.g.) to be able to set the relevant paths appropriately. One other point: Any chance you could make |
I think multirust has existed long enough, and seen enough use, for its own conventions to be just as important as rbenv conventions (eg: global/local vs default/override) and in that case, I think that default/override are better names anyway. |
Guh, you seem to be right, but I'm still confused. I don't understand how running
I totally agree! |
I've been thinking about this, and whether We could just switch to 'global' / 'local' and 'install' to maintain familiarity. I'm not sure how important it is for rustup to work like pyenv. @chriskrycho to be clear, do you prefer to keep 'default' / 'override' or switch to 'global' / 'local'? |
Thanks for the feedback. I do agree that we have to weigh our own precedent against others' and our existing users are already familiar with our terminology. |
Since I saw it mentioned in #88, you can now order the arguments in whatever order you want, instead of just the default which is alphabetical. This can help emphasize arguments or prioritize common options and commands. The ordering can be done on an argument by argument basis (or sucommand), or be derived from the declaration order. Arguments can also be hidden from the help text, in case there are rare or developmental arguments and commands. Finally, what clap calls two separate categories Combining all of the above one should be able to get a good help message. |
@brson, I think you're right (as are @Diggsey and @alexcrichton) about sticking with
|
Great. I've already changed the
@chriskrycho that 'other than setting Ok, I just went and tested it and this is exactly what happens - calling After further investigation I've figured out how it works. The key is this:
Every time the shell starts it calls Thanks for the other feedback. We'll do something for |
OH! I had totally forgotten about I totally forgot about the way the environment variable/subprocess bits related there (if I ever knew it). TIL. Thanks for the thoughtful interactions about it! 👍 |
This issue has served it's purpose. The new CLI is landed. |
Edit: Here's the interface as of 3/20. Here's a comparison to pyenv.
Here's what I'm thinking on the rustup UI.
A few main principles.
commands. The current output is generally good enough.
command
rustup
will just update all the things.release channel toolchain management. The
--copy-local
,--link-local
, and--installer
features will be dealt with differently.rustup toolchain link <path>
will link in development toolchains(and they will automatically get a fallback cargo).
so you don't have to e.g. specify the toolchain when adding a target.
Such commands will probably have
--channel
flags.self" command, to free up the root namespace for more features and bury lesser features.
TLDR
This is the important stuff
rustup
. Upgrades all tracking toolchains and self-upgrades,tracking toolchain statuses.
rustup default <toolchain>
. Sets the default toolchain, installing it if it isn't already. Same asmultirust default
but without the custom toolchain parts.rustup update [toolchain]
. Updates the current toolchain or a given toolchain, installing if it isn't already. Mostly the same asmultirust update
but without custom toolchain parts.rustup toolchain link
. Symlinks a toolchain. Useful for development. The same asmultirust update --link-local
.rustup toolchain remove
rustup toolchain list
. Lists the installed toolchains in some useful way.rustup target list/add/remove
. Modify target architectures for a toolchain.rustup override add <toolchain>
. Sets the toolchain for cwd. Same asmultirust override <toolchain>
.rustup override remove
rustup run <toolchain> [args ..]
. Runs a command with the environment of a given toolchain. Same asmultirust
.rustup self uninstall
rustup self update
rustup self upgrade-data
Basic usage
After installation, the user already has a toolchain installed
("stable" by default). Many users don't need to interact with rustup
again until the next version of Rust is released. At that time they
will upgrade Rust by writing
rustup
upgrades every tracking toolchain installed, so by default itupgrades stable; then it displays the status of every tracking
toolchain, then it quietly upgrades itself.
The bare
rustup
command is non-interactive. It just does all thebusiness. It's not clear yet whether it will update ndk components.
The
rustup update <toolchain>
can still be used to update a single toolchain.At some point they want to try out nightly so they write
FIXME: The word 'default' could also be something like 'use'
or 'activate'.
FIXME: I might want a more convenient way to 'try out' toolchains
than switching the default or running
rustup run nightly bash
.Now they want to try android by installing another target.
All commands related to changing a toolchains targets are now
subcommands of 'target'. They can also
rustup target remove
.Finally after making all these changes, they want to be reminded what
the state of the world is, they write
It's not clear what all this shows, but perhaps the state of the
tracking channels and the current override information. It replaces
show-default
andshow-override
.Toolchain managament
rustup toolchain list
rustup toolchain update [toolchain]
. FIXMErustup toolchain link <path>
- the equivalent ofupdate --link-local
rustup toolchain remove
rustup toolchain show [toolchain]
- the same info displayedafter updates. I often want to know this. subset of
rustup status
I want to hold off on adding equivalents of
--copy-local
and--installer
.Overrides
rustup override add <toolchain>
rustup override remove
rustup override list
rustup override show
. Subset ofrustup status
.Misc
update-data
anddelete-data
will sink into theself
subcommand.I think
run
andproxy
can be merged.cc @Diggsey @alexcrichton
Looking for feedback.
Edit: There are some contradictory bits in here about whether to preserve functionality for just showing the current override and other lesser functions. I'm not sure where I stand.
The text was updated successfully, but these errors were encountered: