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

criticalup run without proxies #71

Merged
merged 10 commits into from
Jan 23, 2025
Merged

Conversation

Hoverbear
Copy link
Member

@Hoverbear Hoverbear commented Dec 3, 2024

Currently criticalup run can be used to invoke different binary proxies, which are themselves criticalup in disguise. Then, those disguised criticalup instances go and replace-exec the correct binary from the project themselves.

Along the way, it manipulates the user's $PATH (or equivalent on other OS):

let additional_lib_path = config
.paths
.installation_dir
.clone()
.join(installation_id)
.join("lib");
#[cfg(target_os = "macos")]
prepend_path_to_var_for_command(
&mut command,
"DYLD_FALLBACK_LIBRARY_PATH",
vec![additional_lib_path],
)?;
#[cfg(target_os = "linux")]
prepend_path_to_var_for_command(&mut command, "LD_LIBRARY_PATH", vec![additional_lib_path])?;
#[cfg(any(target_os = "linux", target_os = "macos"))]
prepend_path_to_var_for_command(&mut command, "PATH", vec![additional_bin_path])?;

A consequence of this strategy means running criticalup run $TOOL where $TOOL is not part of the criticalup.toml results in an error:

$ criticalup run hyperfine
error: 'hyperfine' is not installed for this project.

Please make sure that the correct package for 'hyperfine' is listed in the packages section of your project's criticalup.toml and run 'criticalup install' command again.

This is in contrast to the behavor seen in, for example, in uv:

$ uv run cargo --version
cargo 1.83.0 (5ffbef321 2024-10-29)

Or rustup:

$ rustup run stable hyperfine --version
hyperfine 1.19.0

This PR rethinks that strategy, mostly inspired by using these tools. With this PR, criticalup run skips the execution of the binary proxies, then manipulates the path as needed before doing an exec-replace on the target command. This means the command the user runs does not necessarily need to be part of their criticalup.toml.

It means this is valid:

$ target/release/criticalup run hyperfine --version
hyperfine 1.19.0

Performance

The current strategy doesn't take long:

(main) $ hyperfine "target/release/criticalup run rustc --version"
Benchmark 1: target/release/criticalup run rustc --version
  Time (mean ± σ):      29.7 ms ±   1.0 ms    [User: 9.1 ms, System: 30.5 ms]
  Range (min … max):    28.2 ms …  34.6 ms    84 runs

This strategy is measurably faster, but the difference is minor:

(changed) $ hyperfine "target/release/criticalup run rustc --version"
Benchmark 1: target/release/criticalup run rustc --version
  Time (mean ± σ):      22.2 ms ±   1.2 ms    [User: 7.2 ms, System: 19.7 ms]
  Range (min … max):    20.6 ms …  29.4 ms    125 runs

Open questions

Question: Is this a feature we want? (Should criticalup run interact with non-managed binaries?)

Consideration: Users can always clear their PATH (or equivalent) variable before running:

$ PATH="" target/release/criticalup run rustc --version
rustc 1.81.0 (ff44b0db3 2024-11-25) (Ferrocene by Ferrous Systems)
$ LD_LIBRARY_PATH="" PATH="" target/release/criticalup run cargo build
   Compiling criticaltrust v0.4.0 (/home/ana/git/ferrocene/criticalup/crates/criticaltrust)
   Compiling criticalup-core v0.0.0 (/home/ana/git/ferrocene/criticalup/crates/criticalup-core)
   Compiling criticalup-cli v1.2.0 (/home/ana/git/ferrocene/criticalup/crates/criticalup-cli)
   Compiling criticalup v1.2.0 (/home/ana/git/ferrocene/criticalup/crates/criticalup)
error: linker `cc` not found
  |
  = note: No such file or directory (os error 2)

error: could not compile `criticalup` (bin "criticalup") due to 1 previous error

@Hoverbear Hoverbear self-assigned this Dec 3, 2024
@Hoverbear Hoverbear force-pushed the hoverbear/run-without-proxies branch from dffcda3 to 4e7e0ed Compare December 3, 2024 18:58
@Hoverbear Hoverbear force-pushed the hoverbear/run-without-proxies branch from 75907c1 to fee32bc Compare December 3, 2024 20:42
@pietroalbini
Copy link
Member

I think this will be useful, especially to execute things like scripts and similar.

My only worry about the feature is what would happen if you don't have a component installed through criticalup (like rustfmt) but that is installed globally on the system. In that case, this would execute an outside rustfmt.

I personally lean towards consistency with other tools here though.

@Hoverbear
Copy link
Member Author

That's basically my worry too. I was considering if a warning would improve the situation, but I'm unsure. I'll get this tidied up and green and we can make a final call.

@Hoverbear
Copy link
Member Author

I am adding a --strict flag that will only (directly, still) run binaries present within the installations. This should mitigate our concerns for customers where this is important.

@Hoverbear Hoverbear marked this pull request as ready for review January 8, 2025 19:37
@Hoverbear Hoverbear requested a review from pietroalbini January 8, 2025 19:54
@jonathanpallant
Copy link
Contributor

With the --strict flag, this sounds like a good change that I can easily teach to people.

It allows for criticalup run make, for example, where make will have the right rustc in the $PATH.

@Hoverbear
Copy link
Member Author

That's pretty much the use case I intended. :)

@Hoverbear Hoverbear requested review from amanjeev and removed request for pietroalbini January 22, 2025 20:05
@Hoverbear Hoverbear force-pushed the hoverbear/run-without-proxies branch from e728912 to 1ac297f Compare January 22, 2025 20:07
@Hoverbear Hoverbear force-pushed the hoverbear/run-without-proxies branch from e3a4ab1 to c271faa Compare January 23, 2025 18:20
@amanjeev
Copy link
Member

amanjeev commented Jan 23, 2025

Testing this First pass:

Used manifest:

manifest-version = 1

[products.ferrocene]
release = "stable-24.08.0"
packages = [
    "rustc-${rustc-host}",
]

Then ran the following:

  • criticalup install -> installs this toolchain with only rustc.
  • criticalup run rustc --version -> outputs: rustc 1.79.0 (02baf75fd 2024-08-23) (Ferrocene by Ferrous Systems).
  • criticalup run --strict rustc --version -> outputs: rustc 1.79.0 (02baf75fd 2024-08-23) (Ferrocene by Ferrous Systems).
  • criticalup run cargo --version -> outputs: cargo 1.84.0 (66221abde 2024-11-19). No --strict so it uses system cargo. This is checked next -
  • criticalup run which cargo -> outputs: ~/.cargo/bin/cargo
  • criticalup run --strict cargo --version -> outputs: error: 'cargo' is not installed for this project.

@amanjeev
Copy link
Member

amanjeev commented Jan 23, 2025

Testing this Second pass (in a Docker container):

Downloaded criticalup binary from the CI and created the following manifest.

manifest-version = 1

[products.ferrocene]
release = "stable-24.08.0"
packages = [
    "rustc-${rustc-host}",
]
FROM debian
ADD criticalup /
ADD criticalup.toml /
CMD ["/criticalup"]
  • criticalup install -> installs this toolchain with only rustc.
  • ./criticalup run rustc --version -> outputs: rustc 1.79.0 (02baf75fd 2024-08-23) (Ferrocene by Ferrous Systems
  • ./criticalup run --strict rustc --version -> outputs: rustc 1.79.0 (02baf75fd 2024-08-23) (Ferrocene by Ferrous Systems)
  • ./criticalup run --strict cargo --version -> outputs: error: 'cargo' is not installed for this project
  • ./criticalup run cargo --version -> outputs: error: Failed to invoke proxied command cargo. caused by: No such file or directory (os error 2)
  • ./criticalup run ls -> outputs the directory listing.
  • ./criticalup run --strict ls -> outputs: error: 'ls' is not installed for this project.

Copy link
Member

@amanjeev amanjeev left a comment

Choose a reason for hiding this comment

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

I hereby approve this message.

@Hoverbear
Copy link
Member Author

bors merge

@bors-ferrocene
Copy link
Contributor

Build succeeded:

@bors-ferrocene bors-ferrocene bot merged commit ec53739 into main Jan 23, 2025
13 checks passed
@bors-ferrocene bors-ferrocene bot deleted the hoverbear/run-without-proxies branch January 23, 2025 20:03
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.

4 participants