@@ -2211,6 +2211,178 @@ impl Arg {
22112211 pub fn env_os ( self , name : impl Into < OsStr > ) -> Self {
22122212 self . env ( name)
22132213 }
2214+
2215+ /// Read from `names` environment variable when argument is not present.
2216+ ///
2217+ /// If it is not present in the environment, then default
2218+ /// rules will apply.
2219+ ///
2220+ /// If user sets the argument in the environment:
2221+ /// - When [`Arg::action(ArgAction::Set)`] is not set, the flag is considered raised.
2222+ /// - When [`Arg::action(ArgAction::Set)`] is set,
2223+ /// [`ArgMatches::get_one`][crate::ArgMatches::get_one] will
2224+ /// return value of the environment variable.
2225+ ///
2226+ /// If user doesn't set the argument in the environment:
2227+ /// - When [`Arg::action(ArgAction::Set)`] is not set, the flag is considered off.
2228+ /// - When [`Arg::action(ArgAction::Set)`] is set,
2229+ /// [`ArgMatches::get_one`][crate::ArgMatches::get_one] will
2230+ /// return the default specified.
2231+ ///
2232+ /// Like with command-line values, this will be split by [`Arg::value_delimiter`].
2233+ ///
2234+ /// # Examples
2235+ ///
2236+ /// In this example, we show the variable coming from the environment.
2237+ /// Note that because of the first `MY_FLAG` has a value, so the next environment variable is not valid again.
2238+ ///
2239+ /// ```rust
2240+ /// # use clap_builder as clap;
2241+ /// # use std::env;
2242+ /// # use clap::{Command, Arg, ArgAction};
2243+ ///
2244+ /// env::set_var("MY_FLAG", "one");
2245+ /// env::set_var("MY_SECOND_FLAG", "two");
2246+ ///
2247+ /// let m = Command::new("prog")
2248+ /// .arg(Arg::new("flag")
2249+ /// .long("flag")
2250+ /// .envs(["MY_FLAG", "MY_SECOND_FLAG"])
2251+ /// .action(ArgAction::Set))
2252+ /// .get_matches_from(vec![
2253+ /// "prog"
2254+ /// ]);
2255+ ///
2256+ /// assert_eq!(m.get_one::<String>("flag").unwrap(), "one");
2257+ /// ```
2258+ ///
2259+ /// In this example, because `prog` is a flag that accepts an optional, case-insensitive
2260+ /// boolean literal.
2261+ ///
2262+ /// Note that the value parser controls how flags are parsed. In this case we've selected
2263+ /// [`FalseyValueParser`][crate::builder::FalseyValueParser]. A `false` literal is `n`, `no`,
2264+ /// `f`, `false`, `off` or `0`. An absent environment variable will also be considered as
2265+ /// `false`. Anything else will considered as `true`.
2266+ ///
2267+ /// ```rust
2268+ /// # use clap_builder as clap;
2269+ /// # use std::env;
2270+ /// # use clap::{Command, Arg, ArgAction};
2271+ /// # use clap::builder::FalseyValueParser;
2272+ ///
2273+ /// env::set_var("TRUE_FLAG", "true");
2274+ /// env::set_var("FALSE_FLAG", "0");
2275+ ///
2276+ /// let m = Command::new("prog")
2277+ /// .arg(Arg::new("true_flag")
2278+ /// .long("true_flag")
2279+ /// .action(ArgAction::SetTrue)
2280+ /// .value_parser(FalseyValueParser::new())
2281+ /// .envs(["TRUE_FLAG"]))
2282+ /// .arg(Arg::new("false_flag")
2283+ /// .long("false_flag")
2284+ /// .action(ArgAction::SetTrue)
2285+ /// .value_parser(FalseyValueParser::new())
2286+ /// .envs(["FALSE_FLAG"]))
2287+ /// .arg(Arg::new("absent_flag")
2288+ /// .long("absent_flag")
2289+ /// .action(ArgAction::SetTrue)
2290+ /// .value_parser(FalseyValueParser::new())
2291+ /// .envs(["ABSENT_FLAG"]))
2292+ /// .get_matches_from(vec![
2293+ /// "prog"
2294+ /// ]);
2295+ ///
2296+ /// assert!(m.get_flag("true_flag"));
2297+ /// assert!(!m.get_flag("false_flag"));
2298+ /// assert!(!m.get_flag("absent_flag"));
2299+ /// ```
2300+ ///
2301+ /// In this example, we show the variable coming from an option on the CLI:
2302+ ///
2303+ /// ```rust
2304+ /// # use clap_builder as clap;
2305+ /// # use std::env;
2306+ /// # use clap::{Command, Arg, ArgAction};
2307+ ///
2308+ /// env::set_var("MY_FLAG", "env");
2309+ ///
2310+ /// let m = Command::new("prog")
2311+ /// .arg(Arg::new("flag")
2312+ /// .long("flag")
2313+ /// .envs(["MY_FLAG"])
2314+ /// .action(ArgAction::Set))
2315+ /// .get_matches_from(vec![
2316+ /// "prog", "--flag", "opt"
2317+ /// ]);
2318+ ///
2319+ /// assert_eq!(m.get_one::<String>("flag").unwrap(), "opt");
2320+ /// ```
2321+ ///
2322+ /// In this example, we show the variable coming from the environment even with the
2323+ /// presence of a default:
2324+ ///
2325+ /// ```rust
2326+ /// # use clap_builder as clap;
2327+ /// # use std::env;
2328+ /// # use clap::{Command, Arg, ArgAction};
2329+ ///
2330+ /// env::set_var("MY_FLAG", "env");
2331+ ///
2332+ /// let m = Command::new("prog")
2333+ /// .arg(Arg::new("flag")
2334+ /// .long("flag")
2335+ /// .envs(["MY_FLAG"])
2336+ /// .action(ArgAction::Set)
2337+ /// .default_value("default"))
2338+ /// .get_matches_from(vec![
2339+ /// "prog"
2340+ /// ]);
2341+ ///
2342+ /// assert_eq!(m.get_one::<String>("flag").unwrap(), "env");
2343+ /// ```
2344+ ///
2345+ /// In this example, we show the use of multiple values in a single environment variable:
2346+ ///
2347+ /// ```rust
2348+ /// # use clap_builder as clap;
2349+ /// # use std::env;
2350+ /// # use clap::{Command, Arg, ArgAction};
2351+ ///
2352+ /// env::set_var("MY_FLAG_MULTI", "env1,env2");
2353+ ///
2354+ /// let m = Command::new("prog")
2355+ /// .arg(Arg::new("flag")
2356+ /// .long("flag")
2357+ /// .envs(["MY_FLAG_MULTI"])
2358+ /// .action(ArgAction::Set)
2359+ /// .num_args(1..)
2360+ /// .value_delimiter(','))
2361+ /// .get_matches_from(vec![
2362+ /// "prog"
2363+ /// ]);
2364+ ///
2365+ /// assert_eq!(m.get_many::<String>("flag").unwrap().collect::<Vec<_>>(), vec!["env1", "env2"]);
2366+ /// ```
2367+ /// [`Arg::action(ArgAction::Set)`]: Arg::action()
2368+ /// [`Arg::value_delimiter(',')`]: Arg::value_delimiter()
2369+ #[ cfg( feature = "env" ) ]
2370+ #[ inline]
2371+ #[ must_use]
2372+ pub fn envs ( mut self , names : impl IntoIterator < Item = impl Into < OsStr > > ) -> Self {
2373+ for name in names {
2374+ if let Some ( name) = name. into_resettable ( ) . into_option ( ) {
2375+ if let Some ( value) = env:: var_os ( & name) {
2376+ self . env = Some ( ( name, Some ( value) ) ) ;
2377+ break ;
2378+ }
2379+ } else {
2380+ self . env = None ;
2381+ break ;
2382+ }
2383+ }
2384+ self
2385+ }
22142386}
22152387
22162388/// # Help
0 commit comments