From 668a3f684133442598f126bb9210b78cd6276bb1 Mon Sep 17 00:00:00 2001 From: James Knight Date: Sat, 20 Jul 2024 02:22:20 -0400 Subject: [PATCH] introduce no-path-check for install command Provides the option to allow a user to trigger an install request that will not generate a warning if an installed program is not available in the `PATH`. This can be helpful when the install root is configured to an interim location (e.g. cross-compiling) and there is a desire to suppress any path checks warnings not relevant for the install case. Signed-off-by: James Knight --- src/bin/cargo/commands/install.rs | 9 +++++++++ src/cargo/ops/cargo_install.rs | 8 +++++++- src/cargo/util/context/mod.rs | 13 +++++++++++++ src/doc/man/cargo-install.md | 6 ++++++ src/doc/src/commands/cargo-install.md | 6 ++++++ src/doc/src/reference/config.md | 14 ++++++++++++++ src/doc/src/reference/environment-variables.md | 2 ++ src/etc/cargo.bashcomp.sh | 2 +- 8 files changed, 58 insertions(+), 2 deletions(-) diff --git a/src/bin/cargo/commands/install.rs b/src/bin/cargo/commands/install.rs index 8aaaeb87b0e..5cda53f344f 100644 --- a/src/bin/cargo/commands/install.rs +++ b/src/bin/cargo/commands/install.rs @@ -8,6 +8,7 @@ use cargo::ops; use cargo::util::IntoUrl; use cargo::util::VersionExt; use cargo::CargoResult; +use clap::parser::ValueSource; use itertools::Itertools; use semver::VersionReq; @@ -69,6 +70,7 @@ pub fn cli() -> Command { ) .arg(opt("root", "Directory to install packages into").value_name("DIR")) .arg(flag("force", "Force overwriting existing crates or binaries").short('f')) + .arg(flag("no-path-check", "Do not perform a PATH check")) .arg(flag("no-track", "Do not save tracking information")) .arg(flag( "list", @@ -176,6 +178,12 @@ pub fn exec(gctx: &mut GlobalContext, args: &ArgMatches) -> CliResult { let root = args.get_one::("root").map(String::as_str); + let no_path_check = if args.value_source("no-path-check") != Some(ValueSource::DefaultValue) { + args.flag("no-path-check") + } else { + gctx.install_config()?.no_path_check.is_some_and(|f| f) + }; + // We only provide workspace information for local crate installation from // one of the following sources: // - From current working directory (only work for edition 2015). @@ -213,6 +221,7 @@ pub fn exec(gctx: &mut GlobalContext, args: &ArgMatches) -> CliResult { &compile_opts, args.flag("force"), args.flag("no-track"), + no_path_check, )?; } Ok(()) diff --git a/src/cargo/ops/cargo_install.rs b/src/cargo/ops/cargo_install.rs index 7abc1b39375..7f8a2412540 100644 --- a/src/cargo/ops/cargo_install.rs +++ b/src/cargo/ops/cargo_install.rs @@ -620,6 +620,7 @@ pub fn install( opts: &ops::CompileOptions, force: bool, no_track: bool, + no_path_check: bool, ) -> CargoResult<()> { let root = resolve_root(root, gctx)?; let dst = root.join("bin").into_path_unlocked(); @@ -739,7 +740,12 @@ pub fn install( (!succeeded.is_empty(), !failed.is_empty()) }; - if installed_anything { + let skip_path_check = match gctx.get_env_os("CARGO_INSTALL_NO_PATH_CHECK") { + Some(v) => Some(v == "1"), + None => Some(no_path_check), + }; + + if installed_anything && !skip_path_check.is_some_and(|f| f) { // Print a warning that if this directory isn't in PATH that they won't be // able to run these commands. let path = gctx.get_env_os("PATH").unwrap_or_default(); diff --git a/src/cargo/util/context/mod.rs b/src/cargo/util/context/mod.rs index c4fa1a5947d..61ea34c48db 100644 --- a/src/cargo/util/context/mod.rs +++ b/src/cargo/util/context/mod.rs @@ -224,6 +224,7 @@ pub struct GlobalContext { future_incompat_config: LazyCell, net_config: LazyCell, build_config: LazyCell, + install_config: LazyCell, target_cfgs: LazyCell>, doc_extern_map: LazyCell, progress_config: ProgressConfig, @@ -318,6 +319,7 @@ impl GlobalContext { future_incompat_config: LazyCell::new(), net_config: LazyCell::new(), build_config: LazyCell::new(), + install_config: LazyCell::new(), target_cfgs: LazyCell::new(), doc_extern_map: LazyCell::new(), progress_config: ProgressConfig::default(), @@ -1824,6 +1826,11 @@ impl GlobalContext { .try_borrow_with(|| self.get::("build")) } + pub fn install_config(&self) -> CargoResult<&CargoInstallConfig> { + self.install_config + .try_borrow_with(|| self.get::("install")) + } + pub fn progress_config(&self) -> &ProgressConfig { &self.progress_config } @@ -2617,6 +2624,12 @@ pub struct CargoBuildConfig { pub artifact_dir: Option, } +#[derive(Debug, Deserialize)] +#[serde(rename_all = "kebab-case")] +pub struct CargoInstallConfig { + pub no_path_check: Option, +} + /// Configuration for `build.target`. /// /// Accepts in the following forms: diff --git a/src/doc/man/cargo-install.md b/src/doc/man/cargo-install.md index fa593206612..1b7a8fca6d9 100644 --- a/src/doc/man/cargo-install.md +++ b/src/doc/man/cargo-install.md @@ -128,6 +128,12 @@ useful if something has changed on the system that you want to rebuild with, such as a newer version of `rustc`. {{/option}} +{{#option "`--no-path-check`" }} +By default, Cargo will check if installed programs are available in the +configured `PATH` and generate a warning if this is not the case. This flag +tells Cargo not to perform any path checks. +{{/option}} + {{#option "`--no-track`" }} By default, Cargo keeps track of the installed packages with a metadata file stored in the installation root directory. This flag tells Cargo not to use or diff --git a/src/doc/src/commands/cargo-install.md b/src/doc/src/commands/cargo-install.md index 78efb92e8c0..a8d46c199f1 100644 --- a/src/doc/src/commands/cargo-install.md +++ b/src/doc/src/commands/cargo-install.md @@ -132,6 +132,12 @@ useful if something has changed on the system that you want to rebuild with, such as a newer version of rustc. +
--no-path-check
+
By default, Cargo will check if installed programs are available in the +configured PATH and generate a warning if this is not the case. This flag +tells Cargo not to perform any path checks.
+ +
--no-track
By default, Cargo keeps track of the installed packages with a metadata file stored in the installation root directory. This flag tells Cargo not to use or diff --git a/src/doc/src/reference/config.md b/src/doc/src/reference/config.md index 965642cafc5..64414cf956b 100644 --- a/src/doc/src/reference/config.md +++ b/src/doc/src/reference/config.md @@ -757,6 +757,20 @@ string that includes Cargo's version. The `[install]` table defines defaults for the [`cargo install`] command. +#### `install.no-path-check` +* Type: boolean +* Default: false +* Environment: `CARGO_INSTALL_NO_PATH_CHECK` + +If this is `true`, then Cargo will not perform any checks if an installed +command is not available on the configured `PATH`. + +Setting this to `true` can be helpful when the install root is configured +to an interim location (e.g. cross-compiling) and an installer wishes to +suppress any path checks warnings not relevant for their use case. + +Can be overridden with the `--no-path-check` command-line option. + #### `install.root` * Type: string (path) * Default: Cargo's home directory diff --git a/src/doc/src/reference/environment-variables.md b/src/doc/src/reference/environment-variables.md index 3a7053675cc..e683e588393 100644 --- a/src/doc/src/reference/environment-variables.md +++ b/src/doc/src/reference/environment-variables.md @@ -110,6 +110,7 @@ In summary, the supported environment variables are: * `CARGO_HTTP_LOW_SPEED_LIMIT` --- The HTTP low-speed limit, see [`http.low-speed-limit`]. * `CARGO_HTTP_MULTIPLEXING` --- Whether HTTP/2 multiplexing is used, see [`http.multiplexing`]. * `CARGO_HTTP_USER_AGENT` --- The HTTP user-agent header, see [`http.user-agent`]. +* `CARGO_INSTALL_NO_PATH_CHECK` --- Disables any path checks when using [`cargo install`], see [`install.no-path-check`]. * `CARGO_INSTALL_ROOT` --- The default directory for [`cargo install`], see [`install.root`]. * `CARGO_NET_RETRY` --- Number of times to retry network errors, see [`net.retry`]. * `CARGO_NET_GIT_FETCH_WITH_CLI` --- Enables the use of the `git` executable to fetch, see [`net.git-fetch-with-cli`]. @@ -176,6 +177,7 @@ In summary, the supported environment variables are: [`http.low-speed-limit`]: config.md#httplow-speed-limit [`http.multiplexing`]: config.md#httpmultiplexing [`http.user-agent`]: config.md#httpuser-agent +[`install.no-path-check`]: config.md#installno-path-check [`install.root`]: config.md#installroot [`net.retry`]: config.md#netretry [`net.git-fetch-with-cli`]: config.md#netgit-fetch-with-cli diff --git a/src/etc/cargo.bashcomp.sh b/src/etc/cargo.bashcomp.sh index 398fc6f9fad..0725f57e76d 100644 --- a/src/etc/cargo.bashcomp.sh +++ b/src/etc/cargo.bashcomp.sh @@ -64,7 +64,7 @@ _cargo() local opt__generate_lockfile="$opt_common $opt_mani $opt_lock" local opt__help="$opt_help" local opt__init="$opt_common $opt_lock --bin --lib --name --vcs --edition --registry" - local opt__install="$opt_common $opt_feat $opt_parallel $opt_lock $opt_force --bin --bins --branch --debug --example --examples --git --list --path --rev --root --tag --version --registry --target --profile --no-track --ignore-rust-version" + local opt__install="$opt_common $opt_feat $opt_parallel $opt_lock $opt_force --bin --bins --branch --debug --example --examples --git --list --path --rev --root --tag --version --registry --target --profile --no-path-check --no-track --ignore-rust-version" local opt__locate_project="$opt_common $opt_mani $opt_lock --message-format --workspace" local opt__login="$opt_common $opt_lock --registry" local opt__metadata="$opt_common $opt_feat $opt_mani $opt_lock --format-version=1 --no-deps --filter-platform"