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

Prompt user to install the override toolchain if its specified but not installed yet #656

Draft
wants to merge 3 commits into
base: master
Choose a base branch
from

Conversation

alfiedotwtf
Copy link
Contributor

@alfiedotwtf alfiedotwtf commented Aug 26, 2024

This PR is in relation to #652

When overriding toolchains, there are 2 places to be concerned with when a toolchain is missing:

  1. When fuelup is the command run
  2. When a proxy command is run

For 2, we are already covering this scenario by installing missing components and plugins on first run.

As for 1, this PR will now bail!() unless the command is to install, uninstall, or create a new toolkit.

...

No tests yet because I want to get feedback to see if I'm on the right track.

@alfiedotwtf alfiedotwtf self-assigned this Aug 26, 2024
@alfiedotwtf alfiedotwtf added help wanted Extra attention is needed question Further information is requested fuelup labels Aug 26, 2024
@alfiedotwtf alfiedotwtf force-pushed the alfie/652-bail-when-override-missing branch from 1f2086b to 69176e8 Compare September 2, 2024 14:42
@alfiedotwtf alfiedotwtf marked this pull request as ready for review September 2, 2024 14:42
@fuel-service-user
Copy link
Contributor

LCOV of commit 69176e8 during CI #2038

Summary coverage rate:
  lines......: 82.3% (2364 of 2873 lines)
  functions..: 44.6% (367 of 823 functions)
  branches...: 59.6% (272 of 456 branches)

Files changed coverage rate: n/a

@alfiedotwtf
Copy link
Contributor Author

Once I found that toolchain installations were not failing because of code, everything started falling into place...

I've left the dialoguer comment in fmt.rs so that you can all see how that library is not able to be tested without a real tty (which is a shame given it works really nicely). So as is, we are still currently prompting the user via the original hand-rolled stdin nibbler.

We should now be a bit more robust with this PR when parsing <channel>-<date>-<target>, however I have left out most of the split on "-" code which I believe is/was causing most of the problems when specifying channel/toolchains, because it may be breaking behaviour which I'll avoid for now.

But for something to keep in mind, in the future we're probably better off converting split on "-" to regexes.

@alfiedotwtf alfiedotwtf changed the title Bail when override toolchain is not installed Prompt the user to install the override toolchain if its specified but not installed yet Sep 2, 2024
@alfiedotwtf alfiedotwtf changed the title Prompt the user to install the override toolchain if its specified but not installed yet Prompt user to install the override toolchain if its specified but not installed yet Sep 2, 2024
@alfiedotwtf
Copy link
Contributor Author

I forgot to mention, with the toolchain spec here:

/// Parses a distributable toolchain description from a string.
///
/// The supported formats are:
///     <channel>
///     <channel>-<target>
///     <channel>-<YYYY-MM-DD>
///     <channel>-<YYYY-MM-DD>-<target>
///     <channel>-<target>-<YYYY-MM-DD>
/// The parsing begins from the end of the string, so the target is the last part of the string,
/// then the date and finally the name
impl FromStr for DistToolchainDescription {

I think <channel>-<target>-<YYYY-MM-DD> should be removed since it doesn't follow the channel format of <channel>[-<date>].

--

Other quick change to the PR could be to move the URL concats into a separate function like fn github_releases_download_url(), but figured it was easy enough to leave it as is. Happy to change it if someone thinks it's better to go that way.

Copy link
Member

@sdankel sdankel left a comment

Choose a reason for hiding this comment

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

It's coming along! I left some comments, and make sure to run cargo fmt to get CI passing.

@@ -68,7 +50,7 @@ fn format_nightly_url(date: &Date) -> Result<String> {
}

fn construct_channel_url(desc: &DistToolchainDescription) -> Result<String> {
let mut url = FUELUP_GH_PAGES.to_owned();
let mut url = format!("{}{}/gh-pages/", GITHUB_USER_CONTENT_URL, "fuelup");
Copy link
Member

Choose a reason for hiding this comment

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

I'd prefer to keep FUELUP_GH_PAGES as a constant and refactor this to not use a mutable url.

fn construct_channel_url(desc: &DistToolchainDescription) -> Result<String> {
    let channel_file = match desc.name {
        DistToolchainName::Latest => {
            if let Some(date) = desc.date {
                &format!("channels/latest/channel-fuel-latest-{date}.toml")
            } else {
                CHANNEL_LATEST_FILE_NAME
            }
        }

        DistToolchainName::Nightly => {
            let mut file = "".to_string();
            if let Some(date) = desc.date {
                file.push_str(&format_nightly_url(&date)?);
                file.push('/');
            }
            file.push_str(CHANNEL_NIGHTLY_FILE_NAME);
            &file
        }
        DistToolchainName::Beta1 => CHANNEL_BETA_1_FILE_NAME,
        DistToolchainName::Beta2 => CHANNEL_BETA_2_FILE_NAME,
        DistToolchainName::Beta3 => CHANNEL_BETA_3_FILE_NAME,
        DistToolchainName::Beta4 => CHANNEL_BETA_4_FILE_NAME,
        DistToolchainName::Beta5 => CHANNEL_BETA_5_FILE_NAME,
        DistToolchainName::Devnet => CHANNEL_DEVNET_FILE_NAME,
        DistToolchainName::Testnet => CHANNEL_TESTNET_FILE_NAME,
    };
    let mut url = format!("{}{}/gh-pages/", GITHUB_USER_CONTENT_URL, "fuelup");


    Ok(format!("{FUELUP_GH_PAGES}{channel_file}"))
}

pub fn is_beta_toolchain(name: &str) -> Option<&str> {
BETA_CHANNELS
.iter()
.find(|&beta_channel| name.starts_with(beta_channel))
Copy link
Member

Choose a reason for hiding this comment

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

Shouldn't this still be name == beta_channel?

@@ -45,7 +45,7 @@ fn name_allowed(s: &str) -> Result<String> {
None => s,
};

if RESERVED_TOOLCHAIN_NAMES.contains(&name) {
if CHANNELS.contains(&name) {
Copy link
Member

Choose a reason for hiding this comment

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

RESERVED_TOOLCHAIN_NAMES is different from CHANNELS. We want stable to be reserved even though it isn't currently a usable channel.

@@ -25,7 +25,7 @@ impl Config {
.filter(|e| e.file_type().map(|f| f.is_dir()).unwrap_or(false))
{
let toolchain = dir_entry.file_name().to_string_lossy().to_string();
if RESERVED_TOOLCHAIN_NAMES
if CHANNELS
Copy link
Member

@sdankel sdankel Sep 4, 2024

Choose a reason for hiding this comment

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

Same comment here.

@@ -57,4 +57,14 @@ pub fn ask_user_yes_no_question(question: &str) -> io::Result<bool> {
return Ok(result);
}
}

// This is the dialoguer version of the prompter, but it's not testable
Copy link
Member

Choose a reason for hiding this comment

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

Have you tried testing it with rexpect? Here's an example

@@ -46,6 +51,41 @@ enum Commands {
pub fn fuelup_cli() -> Result<()> {
let cli = Cli::parse();

if let Some(toolchain_override) = ToolchainOverride::from_project_root() {
Copy link
Member

Choose a reason for hiding this comment

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

nit: add a comment here explaining what this is checking


if !toolchain.exists() {
match cli.command {
Commands::Toolchain(_) => {
Copy link
Member

Choose a reason for hiding this comment

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

We only want to do this for operations where the toolchain override will be used in some way, right? So we also don't need to do this for fuelup update/upgrade/install fuelup completions fuelup check fuelup default

We really only need it for proxy commands and for fuelup component which modifies the currently active toolchain.

For fuelup show it could be good to show the current state first and then prompt the user if they wish to install.


assert!(output
.stdout
.starts_with(&format!("Using override toolchain 'beta-1-{triple}'")));
Copy link
Member

Choose a reason for hiding this comment

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

nit: we're planning to remove support for betas 1-4 pretty soon, so it might be better to make these tests use beta-5


/// A convenience wrapper for executing 'fuelup' within the fuelup test configuration.
/// It takes an array ref of bytes to write into stdin.
pub fn fuelup_with_input(&mut self, args: &[&str], input: &[u8]) -> TestOutput {
Copy link
Member

Choose a reason for hiding this comment

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

This should be easier with rexpect

@alfiedotwtf alfiedotwtf marked this pull request as draft September 10, 2024 08:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
fuelup help wanted Extra attention is needed question Further information is requested
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants