mirror of
				https://github.com/sharkdp/bat.git
				synced 2025-11-04 00:51:56 +00:00 
			
		
		
		
	Add error handling
This commit is contained in:
		
							
								
								
									
										15
									
								
								src/app.rs
									
									
									
									
									
								
							
							
						
						
									
										15
									
								
								src/app.rs
									
									
									
									
									
								
							@@ -81,19 +81,19 @@ pub struct App {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl App {
 | 
			
		||||
    pub fn new() -> Self {
 | 
			
		||||
    pub fn new() -> Result<Self> {
 | 
			
		||||
        #[cfg(windows)]
 | 
			
		||||
        let _ = ansi_term::enable_ansi_support();
 | 
			
		||||
 | 
			
		||||
        let interactive_output = atty::is(Stream::Stdout);
 | 
			
		||||
 | 
			
		||||
        App {
 | 
			
		||||
            matches: Self::matches(interactive_output),
 | 
			
		||||
        Ok(App {
 | 
			
		||||
            matches: Self::matches(interactive_output)?,
 | 
			
		||||
            interactive_output,
 | 
			
		||||
        }
 | 
			
		||||
        })
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn matches(interactive_output: bool) -> ArgMatches<'static> {
 | 
			
		||||
    fn matches(interactive_output: bool) -> Result<ArgMatches<'static>> {
 | 
			
		||||
        let args = if wild::args_os().nth(1) == Some("cache".into())
 | 
			
		||||
            || wild::args_os().any(|arg| arg == OsStr::new("--no-config"))
 | 
			
		||||
        {
 | 
			
		||||
@@ -104,7 +104,8 @@ impl App {
 | 
			
		||||
            let mut cli_args = wild::args_os();
 | 
			
		||||
 | 
			
		||||
            // Read arguments from bats config file
 | 
			
		||||
            let mut args = get_args_from_config_file();
 | 
			
		||||
            let mut args =
 | 
			
		||||
                get_args_from_config_file().chain_err(|| "Could not parse configuration file")?;
 | 
			
		||||
 | 
			
		||||
            // Put the zero-th CLI argument (program name) first
 | 
			
		||||
            args.insert(0, cli_args.next().unwrap());
 | 
			
		||||
@@ -115,7 +116,7 @@ impl App {
 | 
			
		||||
            args
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        clap_app::build_app(interactive_output).get_matches_from(args)
 | 
			
		||||
        Ok(clap_app::build_app(interactive_output).get_matches_from(args))
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn config(&self) -> Result<Config> {
 | 
			
		||||
 
 | 
			
		||||
@@ -1,44 +1,54 @@
 | 
			
		||||
use std::env;
 | 
			
		||||
use std::ffi::OsString;
 | 
			
		||||
use std::fs;
 | 
			
		||||
 | 
			
		||||
use shell_words;
 | 
			
		||||
 | 
			
		||||
use dirs::PROJECT_DIRS;
 | 
			
		||||
use util::transpose;
 | 
			
		||||
 | 
			
		||||
pub fn get_args_from_config_file() -> Vec<OsString> {
 | 
			
		||||
pub fn get_args_from_config_file() -> Result<Vec<OsString>, shell_words::ParseError> {
 | 
			
		||||
    let config_file = PROJECT_DIRS.config_dir().join("config");
 | 
			
		||||
    fs::read_to_string(config_file)
 | 
			
		||||
        .map(|content| get_args_from_str(&content))
 | 
			
		||||
        .unwrap_or(vec![])
 | 
			
		||||
    Ok(transpose(
 | 
			
		||||
        fs::read_to_string(config_file)
 | 
			
		||||
            .ok()
 | 
			
		||||
            .map(|content| get_args_from_str(&content)),
 | 
			
		||||
    )?
 | 
			
		||||
    .unwrap_or(vec![]))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn get_args_from_str<'a>(content: &'a str) -> Vec<OsString> {
 | 
			
		||||
    content
 | 
			
		||||
fn get_args_from_str<'a>(content: &'a str) -> Result<Vec<OsString>, shell_words::ParseError> {
 | 
			
		||||
    let args_per_line = content
 | 
			
		||||
        .split('\n')
 | 
			
		||||
        .map(|line| line.trim())
 | 
			
		||||
        .filter(|line| !line.is_empty())
 | 
			
		||||
        .filter(|line| !line.starts_with("#"))
 | 
			
		||||
        .flat_map(|line| shell_words::split(line).unwrap())
 | 
			
		||||
        .map(|line| shell_words::split(line))
 | 
			
		||||
        .collect::<Result<Vec<_>, _>>()?;
 | 
			
		||||
 | 
			
		||||
    Ok(args_per_line
 | 
			
		||||
        .iter()
 | 
			
		||||
        .flatten()
 | 
			
		||||
        .map(|line| line.into())
 | 
			
		||||
        .collect()
 | 
			
		||||
        .collect())
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[test]
 | 
			
		||||
fn empty() {
 | 
			
		||||
    let args = get_args_from_str("");
 | 
			
		||||
    let args = get_args_from_str("").unwrap();
 | 
			
		||||
    assert!(args.is_empty());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[test]
 | 
			
		||||
fn single() {
 | 
			
		||||
    assert_eq!(vec!["--plain"], get_args_from_str("--plain"));
 | 
			
		||||
    assert_eq!(vec!["--plain"], get_args_from_str("--plain").unwrap());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[test]
 | 
			
		||||
fn multiple() {
 | 
			
		||||
    assert_eq!(
 | 
			
		||||
        vec!["--plain", "--language=cpp"],
 | 
			
		||||
        get_args_from_str("--plain --language=cpp")
 | 
			
		||||
        get_args_from_str("--plain --language=cpp").unwrap()
 | 
			
		||||
    );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -46,7 +56,7 @@ fn multiple() {
 | 
			
		||||
fn quotes() {
 | 
			
		||||
    assert_eq!(
 | 
			
		||||
        vec!["--theme", "Sublime Snazzy"],
 | 
			
		||||
        get_args_from_str("--theme \"Sublime Snazzy\"")
 | 
			
		||||
        get_args_from_str("--theme \"Sublime Snazzy\"").unwrap()
 | 
			
		||||
    );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -60,7 +70,7 @@ fn multi_line() {
 | 
			
		||||
    ";
 | 
			
		||||
    assert_eq!(
 | 
			
		||||
        vec!["-p", "--style", "numbers,changes", "--color=always"],
 | 
			
		||||
        get_args_from_str(config)
 | 
			
		||||
        get_args_from_str(config).unwrap()
 | 
			
		||||
    );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -78,6 +88,6 @@ fn comments() {
 | 
			
		||||
    ";
 | 
			
		||||
    assert_eq!(
 | 
			
		||||
        vec!["-p", "--style", "numbers,changes", "--color=always"],
 | 
			
		||||
        get_args_from_str(config)
 | 
			
		||||
        get_args_from_str(config).unwrap()
 | 
			
		||||
    );
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -196,7 +196,7 @@ fn run_controller(config: &Config) -> Result<bool> {
 | 
			
		||||
/// Returns `Err(..)` upon fatal errors. Otherwise, returns `Some(true)` on full success and
 | 
			
		||||
/// `Some(false)` if any intermediate errors occurred (were printed).
 | 
			
		||||
fn run() -> Result<bool> {
 | 
			
		||||
    let app = App::new();
 | 
			
		||||
    let app = App::new()?;
 | 
			
		||||
 | 
			
		||||
    match app.matches.subcommand() {
 | 
			
		||||
        ("cache", Some(cache_matches)) => {
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user