From 49de025af922138e00bc90ab5cb3b8d1cbb8ef11 Mon Sep 17 00:00:00 2001 From: Anders Bennehag Date: Fri, 4 Nov 2016 09:23:22 -0400 Subject: [PATCH] First try with adding parsing of args in env-var. Refs #712. --- src/app/mod.rs | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/src/app/mod.rs b/src/app/mod.rs index 481e920a729a..861871d5ceda 100644 --- a/src/app/mod.rs +++ b/src/app/mod.rs @@ -9,6 +9,7 @@ mod help; use std::borrow::Borrow; use std::env; use std::ffi::OsString; +use osstringext::OsStrExt2; use std::fmt; use std::io::{self, BufRead, BufWriter, Write}; use std::path::Path; @@ -1227,6 +1228,32 @@ impl<'a, 'b> App<'a, 'b> { self.get_matches_from_safe(&mut env::args_os()) } + /// Similar to [`App::get_matches`] but also reads args from + /// env-var `env_var_name`. + /// + /// Defaults to read from "VAR" if `env_var_name` is `None`. + pub fn get_matches_with_env(self, env_var_name: Option) + -> ArgMatches<'a> { + let mut env_var = "VAR".to_string(); + if let Some(name) = env_var_name { + env_var = name; + } + // Build `args` by chaining `args_os()` and `var_os()` + let mut args: Vec = env::args_os().collect(); + // Handle first env-format: + // VAR="--option1=val1 --option2=val2" ./prog + if let Some(vargs) = env::var_os(&env_var) { + // TODO: Split on space below is ugly. How to split on all + // utf-8-whitespace? Must use regex? + args = args.into_iter() + .chain(vargs.split(0x20) + .into_iter() + .map(|s| s.to_os_string())) + .collect(); + } + self.get_matches_from(&mut args.into_iter()) + } + /// Starts the parsing process. Like [`App::get_matches`] this method does not return a [`clap::Result`] /// and will automatically exit with an error message. This method, however, lets you specify /// what iterator to use when performing matches, such as a [`Vec`] of your making.