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

perf(rust): additionally check rustup default for faster result. #3354

Merged
merged 2 commits into from
Dec 28, 2021

Conversation

syphar
Copy link
Contributor

@syphar syphar commented Dec 27, 2021

Description

After checking directory overrides we were directly falling back to the
relatively slow call to rustc --version.

Inserting a call to rustup default leads to a quicker response when using rustup.

The only way to make this even faster would be to try to read
.rustup/settings.toml, though this is not part of the official rustup
API
. Also we might safe the second call to rustup when we find out it doesn't exist in the first call.

I'm not sure about the classification (perf/fix), I'm happy to change it if
needed. Same goes for any other implementation parts, or when I might have
missed something that made rustup default give us the wrong result? I checked
#426 and didn't find any reasoning
why we cannot use rustup default.

From looking at the current rust-module tests and how command-output mocking is built inside utils::exec_cmd I don't see how we can write a clean test of the adaptions (or the untested rest of the rust module). I would propose to leave this as a later task with a more flexible command-output mocking.

Motivation and Context

This should help with (or fix?) #2004.

Fixes #2004

I found myself generally calling rustup override stable for any new rust repo because it was faster.

screenshots

before:
grafik
after:
grafik

How Has This Been Tested?

I did a manual test with mac OS and rustup, and tested if rustup default leads to a toolchain install in a fresh debian docker container (it doesn't).

  • I have tested using MacOS
  • I have tested using Linux
  • I have tested using Windows

Checklist

  • I have updated the documentation accordingly.
  • I have updated the tests accordingly.

After checking directory overrides we were directly falling back to the
relatively slow call to `rustc --version`.

Inserting a call to `rustup default` leads to a quicker response.
@syphar
Copy link
Contributor Author

syphar commented Dec 27, 2021

I see I need to fix some rustfmt,

also I just saw that the default might be missing, which I will handle.

Related rustup section:
https://github.com/rust-lang/rustup/blob/5225e87a5d974ab5f1626bcb2a7b43f76ab883f0/src/cli/rustup_mode.rs#L875-L880

Copy link
Member

@andytom andytom left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a really nice speed up have left a suggestion but other than that that this LGTM.

One thing to note is that from the docs it implies that rustup default might try to install the toolchain if it is not already installed but after testing with a fresh install it isn't the case if we are just checking what the default is

❯ rustup default --help
rustup-default 
Set the default toolchain

USAGE:
    rustup default [toolchain]

FLAGS:
    -h, --help    Prints help information

ARGS:
    <toolchain>    Toolchain name, such as 'stable', 'nightly', or '1.8.0'. For more information see `rustup help
                   toolchain`

DISCUSSION:
    Sets the default toolchain to the one specified. If the toolchain
    is not already installed then it is installed first.

Comment on lines 114 to 123
fn execute_rustup_default() -> Option<String> {
let Output { stdout, .. } = create_command("rustup")
.ok()?
.args(&["default"])
.output()
.ok()?;
let stdout = String::from_utf8(stdout).ok()?;

stdout.split_whitespace().next().map(str::to_owned)
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not a blocker but if possible can you use the exec_cmd here since it will also provide some additional logging and automatically kill the command if it takes too long e.g

Suggested change
fn execute_rustup_default() -> Option<String> {
let Output { stdout, .. } = create_command("rustup")
.ok()?
.args(&["default"])
.output()
.ok()?;
let stdout = String::from_utf8(stdout).ok()?;
stdout.split_whitespace().next().map(str::to_owned)
}
fn execute_rustup_default(context: &Context) -> Option<String> {
context
.exec_cmd("rustup", &["default"])?
.stdout
.split_whitespace()
.next()
.map(str::to_owned)
}

@@ -76,6 +77,7 @@ fn get_module_version(context: &Context, config: &RustConfig) -> Option<String>
if let Some(toolchain) = env_rustup_toolchain(context)
.or_else(|| execute_rustup_override_list(&context.current_dir))
.or_else(|| find_rust_toolchain_file(context))
.or_else(execute_rustup_default)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Related to the below suggestion

Suggested change
.or_else(execute_rustup_default)
.or_else(|| execute_rustup_default(context))

@syphar
Copy link
Contributor Author

syphar commented Dec 27, 2021

also I just saw that the default might be missing, which I will handle.

missing default makes rustup default return status code 1, so the rustup default output will be ignored.

Also, rustc --version without configured rustup default_toolchain will error :)

extract_toolchain_from_rustup_override_list(&stdout, cwd)
fn execute_rustup_override_list(context: &Context) -> Option<String> {
extract_toolchain_from_rustup_override_list(
&context.exec_cmd("rustup", &["default"])?.stdout,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this not be

Suggested change
&context.exec_cmd("rustup", &["default"])?.stdout,
&context.exec_cmd("rustup", &["override", "list"])?.stdout,

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks for the reminder, copy/paste errors still happen, no matter the experience :)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed it, in the same commit.

Or should I squash?

@davidkna davidkna merged commit c63e9a7 into starship:master Dec 28, 2021
@davidkna
Copy link
Member

Thanks for the speed-up @syphar, and thanks for reviewing @andytom!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Starship is slow within rust directories
3 participants