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

Check volta shims for reachability during tool install #1292

Open
wants to merge 9 commits into
base: main
Choose a base branch
from

Conversation

untitaker
Copy link

Fix #1268

Copy link
Contributor

@charlespierce charlespierce left a comment

Choose a reason for hiding this comment

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

Thanks for this @untitaker, and apologies for the delay in reviewing! I've unfortunately been increasingly busy with my day job and haven't had the time to dedicate to keeping up with reviews.

Left a couple of suggestions for code organization, but the overall approach is sound and I think will be a big help 🎉

@@ -89,6 +89,23 @@ pub fn create(shim_name: &str) -> Fallible<ShimResult> {
}
}

pub fn check_reachable(shim_name: &str) -> Fallible<()> {
Copy link
Contributor

Choose a reason for hiding this comment

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

Rather than make the public method fallible (and need to create a new error type), since this is intended to be purely informational, can we make this infallible and only show a message if we're able to successfully determine both the shim and the resolved and compare them?

Copy link
Contributor

Choose a reason for hiding this comment

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

Separately, also a slight preference for moving this into the tool/mod.rs file, rather than holding it here in shim.rs. The main reason for that is we can then use the tool helper functions for writing the message out (e.g. note_prefix() and similar that are used for other notes).

Alternatively, we could have this method be something like is_shadowed(shim_name: &str) -> ShadowStatus {} with an enum:

pub enum ShadowStatus {
    NotShadowed,
    Shadowed {
        expected: PathBuf,
        found: PathBuf,
    }
}

And then only build the message inside of the tool module.

)
})?;
if resolved != shim {
warn!("{} is shadowed by another binary of the same name at {}. Please ensure that {} is at the front of your PATH.", shim_name, resolved.display(), shim.display());
Copy link
Contributor

Choose a reason for hiding this comment

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

Given where this is used, rather than warn!, I would lean a little towards using info! and note_prefix, as that's the approach we've taken for a similar message when you install a global version of Node but the local version is different. In both cases, the message exists to let you know that while you just installed something, what you get when you run the command may not be what you expect.

@@ -429,6 +429,11 @@ pub enum ErrorKind {
name: String,
},

/// Thrown when Volta is unable to find the shimmed command.
ShimResolveError {
Copy link
Contributor

Choose a reason for hiding this comment

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

As mentioned below, if we make the lookup infallible by handling (i.e. ignoring) the error directly, we shouldn't need a new error type.

Comment on lines 463 to 465
/// Add an arbitrary file to the test project within the sandbox,
/// give it executable permissions,
/// and add its directory to the *front* of PATH, shadowing any volta binaries.
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: Can we update this doc comment to more accurately reflect what the method does? It appears that it doesn't work with any files, rather it only does the prepending. Can we also document the constraint that prepend_exec_dir_to_path is exclusive of add_exec_dir_to_path?

@felipecrs
Copy link
Contributor

I think this also fixes #1053.

@untitaker
Copy link
Author

@charlespierce i think i addressed all comments. initially i thought it would make sense to make volta hard-crash with exitcode 1 if the PATH can't be resolved to the shim (i think that would be useful when volta is used in CI), but when going back to this code i saw that only some error conditions were treated as fatal.

Copy link
Contributor

@charlespierce charlespierce left a comment

Choose a reason for hiding this comment

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

Thanks for continuing to iterate on this! A couple of small suggested tweaks to the language, to make sure that we are providing the best UX that we can in these situations.

There also appears to be a merge conflict with dependency updates.

Ok(resolved) => resolved,
Err(_) => {
info!(
"{} cannot find command {}. Please ensure that {} is at the front of your PATH.",
Copy link
Contributor

Choose a reason for hiding this comment

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

Apologies for multiple rounds of iteration, but for an error / info message, we try to take special care to be as helpful as possible. Three relatively minor things that jump out here:

  • Would it make sense to use the home.shim_dir() value for the CTA part? Using the shim path itself would mean that we would suggest putting ~/.volta/bin/node on the PATH, when what we're actually suggesting is having ~/.volta/bin on the PATH
  • Since Volta works on Windows as well (and we do these same checks), we should match Windows' casing for Path on those systems. So we should have PATH on Unix and Path on Windows.
  • Also related to Windows, with how the Environment variables are handled, I'm not sure "at the front of your Path" makes the most sense. For this case (the command couldn't be found at all), we can probably say something like "Please ensure that {} is available on your Path".

}
};
if resolved != shim {
info!("{} {} is shadowed by another binary of the same name at {}. Please ensure that {} is at the front of your PATH.", note_prefix(), shim_name, resolved.display(), shim.display());
Copy link
Contributor

Choose a reason for hiding this comment

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

Similar comments as above for this message re shim_dir and PATH/Path. I also wonder if it would make sense to expand the CTA somewhat, to make it clear why we're suggesting it? Perhaps something like:

To ensure your commands work as expected, please move {} to the start of your PATH.

@untitaker
Copy link
Author

@charlespierce I think I fixed both comments

@untitaker
Copy link
Author

@charlespierce could you take a look?

@chriskrycho
Copy link
Contributor

Sorry about the delay here, @untitaker – will see if we can get this reviewed and merged here shortly (at the start of the new year, if nothing else)!

Copy link
Contributor

@charlespierce charlespierce left a comment

Choose a reason for hiding this comment

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

LGTM! 🎉

@chriskrycho
Copy link
Contributor

I'll merge in main to make sure CI is still ✅ and we'll merge it! 🎉

@chriskrycho
Copy link
Contributor

Ah, I messed up the merge commit; I will re-create it and force push the correct version in a bit!

Using `#[cfg(...)]` attributes on expressions is unstable, so switch to
defining a constant with the relevant value behind a `cfg_if!()`, as we
do elsewhere.
@untitaker
Copy link
Author

I can try to fix the test

@chriskrycho
Copy link
Contributor

@untitaker that would be great! I fixed up the one build issue I saw, so you should be unblocked. Let us know when it's fixed and we'll get this merged. Thanks again, and thanks for your patience!

@untitaker
Copy link
Author

Running this locally:

RUST_BACKTRACE=1 cargo test --all --features mock-network

gives me this output for most tests:


thread 'volta_run::inherited_pnpm' panicked at /Users/untitaker/.cargo/registry/src/index.crates.io-6f17d22bba15001f/mockito-0.31.1/src/lib.rs:1184:72:
called `Result::unwrap()` on an `Err` value: Os { code: 2, kind: NotFound, message: "No such file or directory" }
stack backtrace:
   0: rust_begin_unwind
             at /rustc/82e1608dfa6e0b5569232559e3d385fea5a93112/library/std/src/panicking.rs:645:5
   1: core::panicking::panic_fmt
             at /rustc/82e1608dfa6e0b5569232559e3d385fea5a93112/library/core/src/panicking.rs:72:14
   2: core::result::unwrap_failed
             at /rustc/82e1608dfa6e0b5569232559e3d385fea5a93112/library/core/src/result.rs:1653:5
   3: core::result::Result<T,E>::unwrap
             at /rustc/82e1608dfa6e0b5569232559e3d385fea5a93112/library/core/src/result.rs:1077:23
   4: mockito::Mock::with_body_from_file
             at /Users/untitaker/.cargo/registry/src/index.crates.io-6f17d22bba15001f/mockito-0.31.1/src/lib.rs:1184:52
   5: acceptance::support::sandbox::SandboxBuilder::distro_mock
             at ./tests/acceptance/support/sandbox.rs:457:25
   6: acceptance::support::sandbox::SandboxBuilder::distro_mocks
             at ./tests/acceptance/support/sandbox.rs:470:20
   7: acceptance::volta_run::inherited_pnpm
             at ./tests/acceptance/volta_run.rs:475:13
   8: acceptance::volta_run::inherited_pnpm::{{closure}}
             at ./tests/acceptance/volta_run.rs:474:20
   9: core::ops::function::FnOnce::call_once
             at /rustc/82e1608dfa6e0b5569232559e3d385fea5a93112/library/core/src/ops/function.rs:250:5
  10: core::ops::function::FnOnce::call_once
             at /rustc/82e1608dfa6e0b5569232559e3d385fea5a93112/library/core/src/ops/function.rs:250:5
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.

@untitaker
Copy link
Author

@chriskrycho can you or somebody else help me figure out what is broken with my devenv? I can't figure out the broken tests before that. I am following the instructions in CONTRIBUTING

@chriskrycho
Copy link
Contributor

Huh. That should have been fixed by some of the work @rwjblue and I did a little while back, but it's possible that we missed something there or that I did the merge above wrong or that we caused a regression. The issue is that the test mock is asking for a path named "tests/fixtures/node-v10.99.1040-darwin-arm64.tar.gz" (and so on for the other failing tests), and there is no darwin-arm64 fixture for Node v10.99, because that would be a nonsense thing to ask for. What I am trying to figure out now is whether that error came from, because it should certainly be entirely unrelated to your changes here! My current best bet is that I messed up merging into your branch somehow!

@untitaker
Copy link
Author

untitaker commented Feb 17, 2024

there is no darwin-arm64 fixture for Node v10.99, because that would be a nonsense thing to ask for.

darwin-arm64 does make sense to me, that's just any new MacBook. So I suppose the devenv does not work on any M1 or M2 macbook? Not sure

I switched to an x86 laptop for this PR, and everything worked out. Fixed the remaining test failure, so I think this PR should be ready to merge.

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

Successfully merging this pull request may close these issues.

Suggestion: volta install node should error if node is being shadowed by another binary in PATH
4 participants