@@ -15,6 +15,8 @@ use crate::builder::ext::Extension;
1515use crate :: builder:: ext:: Extensions ;
1616use crate :: builder:: ArgAction ;
1717use crate :: builder:: IntoResettable ;
18+ #[ cfg( all( feature = "env" , feature = "string" ) ) ]
19+ use crate :: builder:: OsStr ;
1820use crate :: builder:: PossibleValue ;
1921use crate :: builder:: Str ;
2022use crate :: builder:: StyledStr ;
@@ -101,6 +103,8 @@ pub struct Command {
101103 subcommands : Vec < Command > ,
102104 groups : Vec < ArgGroup > ,
103105 current_help_heading : Option < Str > ,
106+ #[ cfg( all( feature = "env" , feature = "string" ) ) ]
107+ current_env_prefix : Option < OsStr > ,
104108 current_disp_ord : Option < usize > ,
105109 subcommand_value_name : Option < Str > ,
106110 subcommand_heading : Option < Str > ,
@@ -185,6 +189,11 @@ impl Command {
185189
186190 arg. help_heading
187191 . get_or_insert_with ( || self . current_help_heading . clone ( ) ) ;
192+ #[ cfg( all( feature = "env" , feature = "string" ) ) ]
193+ {
194+ arg. env_prefix
195+ . get_or_insert_with ( || self . current_env_prefix . clone ( ) ) ;
196+ }
188197 self . args . push ( arg) ;
189198 }
190199
@@ -2376,6 +2385,41 @@ impl Command {
23762385 self
23772386 }
23782387
2388+ /// Sets a prefix to be prepended to the environment variable names of all
2389+ /// subsequent arguments added to this command.
2390+ ///
2391+ /// This is a stateful method that affects all future [`Arg`]s added via
2392+ /// [`Command::arg`]. An explicit [`Arg::env_prefix`] on an argument takes
2393+ /// precedence over this.
2394+ ///
2395+ /// The prefix and the argument's env name will be joined with `_`.
2396+ ///
2397+ /// This is modeled after [`Command::next_help_heading`].
2398+ ///
2399+ /// # Examples
2400+ ///
2401+ /// ```rust
2402+ /// # #[cfg(all(feature = "env", feature = "string"))] {
2403+ /// # use clap_builder as clap;
2404+ /// # use clap::{Command, Arg};
2405+ /// let cmd = Command::new("myapp")
2406+ /// .next_env_prefix("MYAPP")
2407+ /// .arg(Arg::new("config").long("config").env("CONFIG"))
2408+ /// .arg(Arg::new("verbose").long("verbose"));
2409+ /// // config's env var will be MYAPP_CONFIG
2410+ /// # }
2411+ /// ```
2412+ ///
2413+ /// [`Command::arg`]: Command::arg()
2414+ /// [`Arg::env_prefix`]: crate::Arg::env_prefix()
2415+ #[ cfg( all( feature = "env" , feature = "string" ) ) ]
2416+ #[ inline]
2417+ #[ must_use]
2418+ pub fn next_env_prefix ( mut self , prefix : impl IntoResettable < OsStr > ) -> Self {
2419+ self . current_env_prefix = prefix. into_resettable ( ) . into_option ( ) ;
2420+ self
2421+ }
2422+
23792423 /// Change the starting value for assigning future display orders for args.
23802424 ///
23812425 /// This will be used for any arg that hasn't had [`Arg::display_order`] called.
@@ -3832,6 +3876,13 @@ impl Command {
38323876 self . current_help_heading . as_deref ( )
38333877 }
38343878
3879+ /// Get the env prefix specified via [`Command::next_env_prefix`].
3880+ #[ cfg( all( feature = "env" , feature = "string" ) ) ]
3881+ #[ inline]
3882+ pub fn get_next_env_prefix ( & self ) -> Option < & std:: ffi:: OsStr > {
3883+ self . current_env_prefix . as_ref ( ) . map ( |s| s. as_os_str ( ) )
3884+ }
3885+
38353886 /// Iterate through the *visible* aliases for this subcommand.
38363887 #[ inline]
38373888 pub fn get_visible_aliases ( & self ) -> impl Iterator < Item = & str > + ' _ {
@@ -4436,6 +4487,21 @@ impl Command {
44364487 }
44374488 }
44384489
4490+ // Apply env prefix to env variable names
4491+ #[ cfg( all( feature = "env" , feature = "string" ) ) ]
4492+ if let Some ( Some ( ref prefix) ) = a. env_prefix {
4493+ if let Some ( ( ref env_name, _) ) = a. env {
4494+ let mut prefixed = prefix. to_os_string ( ) ;
4495+ prefixed. push ( "_" ) ;
4496+ prefixed. push ( env_name. as_os_str ( ) ) ;
4497+ let value = env:: var_os ( & prefixed) ;
4498+ a. env = Some ( (
4499+ OsStr :: from_string ( prefixed) ,
4500+ value,
4501+ ) ) ;
4502+ }
4503+ }
4504+
44394505 // Figure out implied settings
44404506 a. _build ( ) ;
44414507 if hide_pv && a. is_takes_value_set ( ) {
@@ -5216,6 +5282,8 @@ impl Default for Command {
52165282 subcommands : Default :: default ( ) ,
52175283 groups : Default :: default ( ) ,
52185284 current_help_heading : Default :: default ( ) ,
5285+ #[ cfg( all( feature = "env" , feature = "string" ) ) ]
5286+ current_env_prefix : Default :: default ( ) ,
52195287 current_disp_ord : Some ( 0 ) ,
52205288 subcommand_value_name : Default :: default ( ) ,
52215289 subcommand_heading : Default :: default ( ) ,
0 commit comments