@@ -11,6 +11,8 @@ use std::path::Path;
1111// Internal
1212use crate :: builder:: ArgAction ;
1313use crate :: builder:: IntoResettable ;
14+ #[ cfg( all( feature = "env" , feature = "string" ) ) ]
15+ use crate :: builder:: OsStr ;
1416use crate :: builder:: PossibleValue ;
1517use crate :: builder:: Str ;
1618use 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
@@ -2378,6 +2387,41 @@ impl Command {
23782387 self
23792388 }
23802389
2390+ /// Sets a prefix to be prepended to the environment variable names of all
2391+ /// subsequent arguments added to this command.
2392+ ///
2393+ /// This is a stateful method that affects all future [`Arg`]s added via
2394+ /// [`Command::arg`]. An explicit [`Arg::env_prefix`] on an argument takes
2395+ /// precedence over this.
2396+ ///
2397+ /// The prefix and the argument's env name will be joined with `_`.
2398+ ///
2399+ /// This is modeled after [`Command::next_help_heading`].
2400+ ///
2401+ /// # Examples
2402+ ///
2403+ /// ```rust
2404+ /// # #[cfg(all(feature = "env", feature = "string"))] {
2405+ /// # use clap_builder as clap;
2406+ /// # use clap::{Command, Arg};
2407+ /// let cmd = Command::new("myapp")
2408+ /// .next_env_prefix("MYAPP")
2409+ /// .arg(Arg::new("config").long("config").env("CONFIG"))
2410+ /// .arg(Arg::new("verbose").long("verbose"));
2411+ /// // config's env var will be MYAPP_CONFIG
2412+ /// # }
2413+ /// ```
2414+ ///
2415+ /// [`Command::arg`]: Command::arg()
2416+ /// [`Arg::env_prefix`]: crate::Arg::env_prefix()
2417+ #[ cfg( all( feature = "env" , feature = "string" ) ) ]
2418+ #[ inline]
2419+ #[ must_use]
2420+ pub fn next_env_prefix ( mut self , prefix : impl IntoResettable < OsStr > ) -> Self {
2421+ self . current_env_prefix = prefix. into_resettable ( ) . into_option ( ) ;
2422+ self
2423+ }
2424+
23812425 /// Change the starting value for assigning future display orders for args.
23822426 ///
23832427 /// This will be used for any arg that hasn't had [`Arg::display_order`] called.
@@ -3834,6 +3878,13 @@ impl Command {
38343878 self . current_help_heading . as_deref ( )
38353879 }
38363880
3881+ /// Get the env prefix specified via [`Command::next_env_prefix`].
3882+ #[ cfg( all( feature = "env" , feature = "string" ) ) ]
3883+ #[ inline]
3884+ pub fn get_next_env_prefix ( & self ) -> Option < & std:: ffi:: OsStr > {
3885+ self . current_env_prefix . as_ref ( ) . map ( |s| s. as_os_str ( ) )
3886+ }
3887+
38373888 /// Iterate through the *visible* aliases for this subcommand.
38383889 #[ inline]
38393890 pub fn get_visible_aliases ( & self ) -> impl Iterator < Item = & str > + ' _ {
@@ -4440,6 +4491,18 @@ impl Command {
44404491 }
44414492 }
44424493
4494+ // Apply env prefix to env variable names
4495+ #[ cfg( all( feature = "env" , feature = "string" ) ) ]
4496+ if let Some ( Some ( ref prefix) ) = a. env_prefix {
4497+ if let Some ( ( ref env_name, _) ) = a. env {
4498+ let mut prefixed = prefix. to_os_string ( ) ;
4499+ prefixed. push ( "_" ) ;
4500+ prefixed. push ( env_name. as_os_str ( ) ) ;
4501+ let value = env:: var_os ( & prefixed) ;
4502+ a. env = Some ( ( OsStr :: from_string ( prefixed) , value) ) ;
4503+ }
4504+ }
4505+
44434506 // Figure out implied settings
44444507 a. _build ( ) ;
44454508 if hide_pv && a. is_takes_value_set ( ) {
@@ -5221,6 +5284,8 @@ impl Default for Command {
52215284 subcommands : Default :: default ( ) ,
52225285 groups : Default :: default ( ) ,
52235286 current_help_heading : Default :: default ( ) ,
5287+ #[ cfg( all( feature = "env" , feature = "string" ) ) ]
5288+ current_env_prefix : Default :: default ( ) ,
52245289 current_disp_ord : Some ( 0 ) ,
52255290 subcommand_value_name : Default :: default ( ) ,
52265291 subcommand_heading : Default :: default ( ) ,
0 commit comments