Skip to content

Refactoring around use of Process #3860

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

Merged
merged 17 commits into from
Jun 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 8 additions & 5 deletions src/bin/rustup-init.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

#![recursion_limit = "1024"]

use anyhow::{anyhow, Result};
use anyhow::{anyhow, Context, Result};
use cfg_if::cfg_if;
// Public macros require availability of the internal symbols
use rs_tracing::{
Expand All @@ -29,6 +29,7 @@ use rustup::cli::self_update;
use rustup::cli::setup_mode;
use rustup::currentprocess::{process, with_runtime, Process};
use rustup::env_var::RUST_RECURSION_COUNT_MAX;
use rustup::errors::RustupError;
use rustup::is_proxyable_tools;
use rustup::utils::utils::{self, ExitCode};

Expand Down Expand Up @@ -115,17 +116,19 @@ async fn run_rustup_inner() -> Result<utils::ExitCode> {

// Before we do anything else, ensure we know where we are and who we
// are because otherwise we cannot proceed usefully.
utils::current_dir()?;
let current_dir = process()
.current_dir()
.context(RustupError::LocatingWorkingDir)?;
utils::current_exe()?;

match process().name().as_deref() {
Some("rustup") => rustup_mode::main().await,
Some("rustup") => rustup_mode::main(current_dir).await,
Some(n) if n.starts_with("rustup-setup") || n.starts_with("rustup-init") => {
// NB: The above check is only for the prefix of the file
// name. Browsers rename duplicates to
// e.g. rustup-setup(2), and this allows all variations
// to work.
setup_mode::main().await
setup_mode::main(current_dir).await
}
Some(n) if n.starts_with("rustup-gc-") => {
// This is the final uninstallation stage on windows where
Expand All @@ -140,7 +143,7 @@ async fn run_rustup_inner() -> Result<utils::ExitCode> {
}
Some(n) => {
is_proxyable_tools(n)?;
proxy_mode::main(n).await.map(ExitCode::from)
proxy_mode::main(n, current_dir).await.map(ExitCode::from)
}
None => {
// Weird case. No arg0, or it's unparsable.
Expand Down
19 changes: 11 additions & 8 deletions src/cli/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use std::cell::RefCell;
use std::fmt::Display;
use std::fs;
use std::io::{BufRead, ErrorKind, Write};
use std::path::Path;
use std::path::{Path, PathBuf};
use std::sync::Arc;
use std::{cmp, env};

Expand Down Expand Up @@ -168,19 +168,22 @@ impl NotifyOnConsole {
}

#[cfg_attr(feature = "otel", tracing::instrument)]
pub(crate) fn set_globals(verbose: bool, quiet: bool) -> Result<Cfg> {
pub(crate) fn set_globals(current_dir: PathBuf, verbose: bool, quiet: bool) -> Result<Cfg> {
let download_tracker = DownloadTracker::new_with_display_progress(!quiet);
let console_notifier = RefCell::new(NotifyOnConsole {
verbose,
..Default::default()
});

Cfg::from_env(Arc::new(move |n: Notification<'_>| {
if download_tracker.lock().unwrap().handle_notification(&n) {
return;
}
console_notifier.borrow_mut().handle(n);
}))
Cfg::from_env(
current_dir,
Arc::new(move |n: Notification<'_>| {
if download_tracker.lock().unwrap().handle_notification(&n) {
return;
}
console_notifier.borrow_mut().handle(n);
}),
)
}

pub(crate) fn show_channel_update(
Expand Down
30 changes: 11 additions & 19 deletions src/cli/proxy_mode.rs
Original file line number Diff line number Diff line change
@@ -1,18 +1,17 @@
use std::ffi::OsString;
use std::process::ExitStatus;
use std::{path::PathBuf, process::ExitStatus};

use anyhow::Result;

use crate::toolchain::toolchain::Toolchain;
use crate::{
cli::{common::set_globals, job, self_update},
command::run_command_for_dir,
config::Cfg,
currentprocess::process,
toolchain::names::{LocalToolchainName, ResolvableLocalToolchainName},
toolchain::names::ResolvableLocalToolchainName,
};

#[cfg_attr(feature = "otel", tracing::instrument)]
pub async fn main(arg0: &str) -> Result<ExitStatus> {
pub async fn main(arg0: &str, current_dir: PathBuf) -> Result<ExitStatus> {
self_update::cleanup_self_updater()?;

let _setup = job::setup();
Expand All @@ -35,24 +34,17 @@ pub async fn main(arg0: &str) -> Result<ExitStatus> {
.skip(1 + toolchain.is_some() as usize)
.collect();

let cfg = set_globals(false, true)?;
let cfg = set_globals(current_dir, false, true)?;
cfg.check_metadata_version()?;
let toolchain = toolchain
.map(|t| t.resolve(&cfg.get_default_host_triple()?))
.transpose()?;
direct_proxy(&cfg, arg0, toolchain, &cmd_args).await
}

#[cfg_attr(feature = "otel", tracing::instrument(skip(cfg)))]
async fn direct_proxy(
cfg: &Cfg,
arg0: &str,
toolchain: Option<LocalToolchainName>,
args: &[OsString],
) -> Result<ExitStatus> {
let cmd = match toolchain {
None => cfg.create_command_for_dir(arg0).await?,
Some(tc) => cfg.create_command_for_toolchain(&tc, false, arg0).await?,
let toolchain = match toolchain {
None => cfg.find_or_install_active_toolchain().await?.0,
Some(tc) => Toolchain::from_local(&tc, false, &cfg).await?,
};
run_command_for_dir(cmd, arg0, args)

let cmd = toolchain.command(arg0)?;
run_command_for_dir(cmd, arg0, &cmd_args)
}
28 changes: 15 additions & 13 deletions src/cli/rustup_mode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ use crate::{
topical_doc,
},
command,
config::{new_toolchain_with_reason, ActiveReason, Cfg},
config::{ActiveReason, Cfg},
currentprocess::{
process,
terminalsource::{self, ColorableTerminal},
Expand Down Expand Up @@ -524,7 +524,7 @@ enum SetSubcmd {
}

#[cfg_attr(feature = "otel", tracing::instrument(fields(args = format!("{:?}", process().args_os().collect::<Vec<_>>()))))]
pub async fn main() -> Result<utils::ExitCode> {
pub async fn main(current_dir: PathBuf) -> Result<utils::ExitCode> {
self_update::cleanup_self_updater()?;

use clap::error::ErrorKind::*;
Expand All @@ -539,8 +539,10 @@ pub async fn main() -> Result<utils::ExitCode> {
info!("This is the version for the rustup toolchain manager, not the rustc compiler.");

#[cfg_attr(feature = "otel", tracing::instrument)]
async fn rustc_version() -> std::result::Result<String, Box<dyn std::error::Error>> {
let cfg = &mut common::set_globals(false, true)?;
async fn rustc_version(
current_dir: PathBuf,
) -> std::result::Result<String, Box<dyn std::error::Error>> {
let cfg = &mut common::set_globals(current_dir, false, true)?;

if let Some(t) = process().args().find(|x| x.starts_with('+')) {
debug!("Fetching rustc version from toolchain `{}`", t);
Expand All @@ -552,7 +554,7 @@ pub async fn main() -> Result<utils::ExitCode> {
Ok(toolchain.rustc_version())
}

match rustc_version().await {
match rustc_version(current_dir).await {
Ok(version) => info!("The currently active `rustc` version is `{}`", version),
Err(err) => debug!("Wanted to tell you the current rustc version, too, but ran into this error: {}", err),
}
Expand All @@ -577,7 +579,7 @@ pub async fn main() -> Result<utils::ExitCode> {
Err(err)
}
}?;
let cfg = &mut common::set_globals(matches.verbose, matches.quiet)?;
let cfg = &mut common::set_globals(current_dir, matches.verbose, matches.quiet)?;

if let Some(t) = &matches.plus_toolchain {
cfg.set_toolchain_override(t);
Expand Down Expand Up @@ -898,9 +900,8 @@ async fn run(
install: bool,
) -> Result<ExitStatus> {
let toolchain = toolchain.resolve(&cfg.get_default_host_triple()?)?;
let cmd = cfg
.create_command_for_toolchain(&toolchain, install, &command[0])
.await?;
let toolchain = Toolchain::from_local(&toolchain, install, cfg).await?;
let cmd = toolchain.command(&command[0])?;
command::run_command_for_dir(cmd, &command[0], &command[1..])
}

Expand All @@ -913,7 +914,8 @@ async fn which(
let desc = toolchain.resolve(&cfg.get_default_host_triple()?)?;
Toolchain::new(cfg, desc.into())?.binary_file(binary)
} else {
cfg.which_binary(binary).await?
let (toolchain, _) = cfg.find_or_install_active_toolchain().await?;
toolchain.binary_file(binary)
};

utils::assert_is_file(&binary_path)?;
Expand Down Expand Up @@ -1020,7 +1022,7 @@ fn show(cfg: &Cfg, verbose: bool) -> Result<utils::ExitCode> {

match active_toolchain_and_reason {
Some((active_toolchain_name, active_reason)) => {
let active_toolchain = new_toolchain_with_reason(
let active_toolchain = Toolchain::with_reason(
cfg,
active_toolchain_name.clone().into(),
&active_reason,
Expand Down Expand Up @@ -1063,7 +1065,7 @@ fn show(cfg: &Cfg, verbose: bool) -> Result<utils::ExitCode> {
fn show_active_toolchain(cfg: &Cfg, verbose: bool) -> Result<utils::ExitCode> {
match cfg.find_active_toolchain()? {
Some((toolchain_name, reason)) => {
let toolchain = new_toolchain_with_reason(cfg, toolchain_name.clone(), &reason)?;
let toolchain = Toolchain::with_reason(cfg, toolchain_name.clone(), &reason)?;
writeln!(
process().stdout().lock(),
"{}\nactive because: {}",
Expand Down Expand Up @@ -1265,7 +1267,7 @@ async fn toolchain_link(

if true {
InstallMethod::Link {
src: &utils::to_absolute(src)?,
src: &cfg.current_dir.join(src),
dest,
cfg,
}
Expand Down
20 changes: 16 additions & 4 deletions src/cli/self_update.rs
Original file line number Diff line number Diff line change
Expand Up @@ -365,6 +365,7 @@ fn canonical_cargo_home() -> Result<Cow<'static, str>> {
/// `CARGO_HOME`/bin, hard-linking the various Rust tools to it,
/// and adding `CARGO_HOME`/bin to PATH.
pub(crate) async fn install(
current_dir: PathBuf,
no_prompt: bool,
verbose: bool,
quiet: bool,
Expand Down Expand Up @@ -458,7 +459,7 @@ pub(crate) async fn install(
}
}

let install_res = || async {
let install_res = move || async move {
install_bins()?;

#[cfg(unix)]
Expand All @@ -468,14 +469,24 @@ pub(crate) async fn install(
do_add_to_programs()?;
do_add_to_path()?;
}
utils::create_rustup_home()?;

// If RUSTUP_HOME is not set, make sure it exists
if process().var_os("RUSTUP_HOME").is_none() {
let home = utils::home_dir()
.map(|p| p.join(".rustup"))
.ok_or_else(|| anyhow::anyhow!("could not find home dir to put .rustup in"))?;

fs::create_dir_all(home).context("unable to create ~/.rustup")?;
}

maybe_install_rust(
opts.default_toolchain,
&opts.profile,
opts.default_host_triple.as_deref(),
!opts.no_update_toolchain,
opts.components,
opts.targets,
current_dir,
verbose,
quiet,
)
Expand Down Expand Up @@ -847,10 +858,11 @@ async fn maybe_install_rust(
update_existing_toolchain: bool,
components: &[&str],
targets: &[&str],
current_dir: PathBuf,
verbose: bool,
quiet: bool,
) -> Result<()> {
let mut cfg = common::set_globals(verbose, quiet)?;
let mut cfg = common::set_globals(current_dir, verbose, quiet)?;

let toolchain = _install_selection(
&mut cfg,
Expand Down Expand Up @@ -1329,7 +1341,7 @@ mod tests {
currentprocess::with(tp.clone().into(), || -> Result<()> {
// TODO: we could pass in a custom cfg to get notification
// callbacks rather than output to the tp sink.
let mut cfg = common::set_globals(false, false).unwrap();
let mut cfg = common::set_globals(tp.cwd.clone(), false, false).unwrap();
assert_eq!(
"stable"
.parse::<PartialToolchainDesc>()
Expand Down
6 changes: 4 additions & 2 deletions src/cli/setup_mode.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use std::path::PathBuf;

use anyhow::Result;
use clap::{builder::PossibleValuesParser, Parser};

Expand Down Expand Up @@ -74,7 +76,7 @@ struct RustupInit {
}

#[cfg_attr(feature = "otel", tracing::instrument)]
pub async fn main() -> Result<utils::ExitCode> {
pub async fn main(current_dir: PathBuf) -> Result<utils::ExitCode> {
use clap::error::ErrorKind;

let RustupInit {
Expand Down Expand Up @@ -122,5 +124,5 @@ pub async fn main() -> Result<utils::ExitCode> {
targets: &target.iter().map(|s| &**s).collect::<Vec<_>>(),
};

self_update::install(no_prompt, verbose, quiet, opts).await
self_update::install(current_dir, no_prompt, verbose, quiet, opts).await
}
Loading
Loading