diff --git a/src/config.rs b/src/config.rs index efd7feb..d1b040b 100644 --- a/src/config.rs +++ b/src/config.rs @@ -291,13 +291,17 @@ impl Config { // Load raw config let raw_config: RawConfig = if config_file_path.exists() && config_file_path.is_file() { let mut config_file = - fs::File::open(config_file_path).map_err(map_io_err_to_config_err)?; + fs::File::open(&config_file_path).map_err(map_io_err_to_config_err)?; let mut contents = String::new(); let _ = config_file .read_to_string(&mut contents) .map_err(map_io_err_to_config_err)?; - toml::from_str(&contents) - .map_err(|err| ConfigError(format!("Failed to parse config file: {}", err)))? + toml::from_str(&contents).map_err(|err| { + ConfigError(format!( + "Failed to parse config file at {:?}:\n{}", + config_file_path, err + )) + })? } else { RawConfig::new() }; diff --git a/src/main.rs b/src/main.rs index e899d39..e2b4c87 100644 --- a/src/main.rs +++ b/src/main.rs @@ -18,7 +18,6 @@ use std::{env, path::PathBuf, process}; -use ansi_term::{Color, Style}; use app_dirs::AppInfo; use atty::Stream; use clap::{AppSettings, Parser}; @@ -33,6 +32,7 @@ mod formatter; mod line_iterator; mod output; mod types; +mod utils; use crate::{ cache::{Cache, CacheFreshness, PageLookupResult, TLDR_PAGES_DIR}, @@ -41,6 +41,7 @@ use crate::{ extensions::Dedup, output::print_page, types::{ColorOptions, PlatformType}, + utils::{print_error, print_warning}, }; const NAME: &str = "tealdeer"; @@ -49,8 +50,6 @@ const APP_INFO: AppInfo = AppInfo { author: NAME, }; const ARCHIVE_URL: &str = "https://tldr.sh/assets/tldr.zip"; -#[cfg(not(target_os = "windows"))] -const PAGER_COMMAND: &str = "less -R"; // Note: flag names are specified explicitly in clap attributes // to improve readability and allow contributors to grep names like "clear-cache" @@ -155,13 +154,13 @@ struct Args { /// Set up display pager #[cfg(not(target_os = "windows"))] -fn configure_pager() { - Pager::with_default_pager(PAGER_COMMAND).setup(); +fn configure_pager(_: bool) { + Pager::with_default_pager("less -R").setup(); } #[cfg(target_os = "windows")] -fn configure_pager() { - eprintln!("Warning: -p / --pager flag not available on Windows!"); +fn configure_pager(enable_styles: bool) { + print_warning(enable_styles, "-p / --pager flag not available on Windows!"); } /// The cache should get updated if this was requested by the user, or if auto @@ -184,32 +183,33 @@ fn check_cache(args: &Args, enable_styles: bool) -> CheckCacheResult { CacheFreshness::Fresh => CheckCacheResult::CacheFound, CacheFreshness::Stale(_) if args.quiet => CheckCacheResult::CacheFound, CacheFreshness::Stale(age) => { - let warning_style = if enable_styles { - Style::new().fg(Color::Yellow) - } else { - Style::default() - }; - eprintln!( - "{}", - warning_style.paint(format!( + print_warning( + enable_styles, + &format!( "The cache hasn't been updated for {} days.\n\ You should probably run `tldr --update` soon.", age.as_secs() / 24 / 3600 - )) + ), ); CheckCacheResult::CacheFound } CacheFreshness::Missing => { - eprintln!("Cache not found. Please run `tldr --update`."); + print_warning( + enable_styles, + "Cache not found. Please run `tldr --update`.", + ); CheckCacheResult::CacheMissing } } } /// Clear the cache -fn clear_cache(quietly: bool) { +fn clear_cache(quietly: bool, enable_styles: bool) { Cache::clear().unwrap_or_else(|e| { - eprintln!("Could not delete cache: {}", e.message()); + print_error( + enable_styles, + &format!("Could not delete cache: {}", e.message()), + ); process::exit(1); }); if !quietly { @@ -218,9 +218,12 @@ fn clear_cache(quietly: bool) { } /// Update the cache -fn update_cache(cache: &Cache, quietly: bool) { +fn update_cache(cache: &Cache, quietly: bool, enable_styles: bool) { cache.update().unwrap_or_else(|e| { - eprintln!("Could not update cache: {}", e.message()); + print_error( + enable_styles, + &format!("Could not update cache: {}", e.message()), + ); process::exit(1); }); if !quietly { @@ -229,17 +232,20 @@ fn update_cache(cache: &Cache, quietly: bool) { } /// Show the config path (DEPRECATED) -fn show_config_path() { +fn show_config_path(enable_styles: bool) { match get_config_path() { Ok((config_file_path, _)) => { println!("Config path is: {}", config_file_path.to_str().unwrap()); } Err(ConfigError(msg)) => { - eprintln!("Could not look up config_path: {}", msg); + print_error( + enable_styles, + &format!("Could not look up config_path: {}", msg), + ); process::exit(1); } Err(_) => { - eprintln!("Unknown error"); + print_error(enable_styles, "Unknown error"); process::exit(1); } } @@ -288,7 +294,7 @@ fn show_paths() { } /// Create seed config file and exit -fn create_config_and_exit() { +fn create_config_and_exit(enable_styles: bool) { match make_default_config() { Ok(config_file_path) => { eprintln!( @@ -298,11 +304,14 @@ fn create_config_and_exit() { process::exit(0); } Err(ConfigError(msg)) => { - eprintln!("Could not create seed config: {}", msg); + print_error( + enable_styles, + &format!("Could not create seed config: {}", msg), + ); process::exit(1); } Err(_) => { - eprintln!("Unknown error"); + print_error(enable_styles, "Unknown error"); process::exit(1); } } @@ -357,42 +366,13 @@ fn main() { init_log(); // Parse arguments - let args = { - let mut args = Args::parse(); - - // Handle renamed arguments - if args.markdown { - args.raw = true; - eprintln!("Warning: The -m / --markdown flag is deprecated, use -r / --raw instead"); - } - if args.os.is_some() { - eprintln!("Warning: The -o / --os flag is deprecated, use -p / --platform instead"); - } - args.platform = args.platform.or(args.os); - - args - }; - - // Show config file and path, pass through - if args.config_path { - eprintln!("Warning: The --config-path flag is deprecated, use --show-paths instead"); - show_config_path(); - } - if args.show_paths { - show_paths(); - } - - // Create a basic config and exit - if args.seed_config { - create_config_and_exit(); - } + let mut args = Args::parse(); // Determine the usage of styles #[cfg(target_os = "windows")] let ansi_support = ansi_term::enable_ansi_support().is_ok(); #[cfg(not(target_os = "windows"))] let ansi_support = true; - let enable_styles = match args.color.unwrap_or_default() { // Attempt to use styling if instructed ColorOptions::Always => true, @@ -407,21 +387,54 @@ fn main() { ColorOptions::Never => false, }; + // Handle renamed arguments + if args.markdown { + args.raw = true; + print_warning( + enable_styles, + "The -m / --markdown flag is deprecated, use -r / --raw instead", + ); + } + if args.os.is_some() { + print_warning( + enable_styles, + "The -o / --os flag is deprecated, use -p / --platform instead", + ); + } + args.platform = args.platform.or(args.os); + + // Show config file and path, pass through + if args.config_path { + print_warning( + enable_styles, + "The --config-path flag is deprecated, use --show-paths instead", + ); + show_config_path(enable_styles); + } + if args.show_paths { + show_paths(); + } + + // Create a basic config and exit + if args.seed_config { + create_config_and_exit(enable_styles); + } + // Look up config file, if none is found fall back to default config. let config = match Config::load(enable_styles) { Ok(config) => config, Err(ConfigError(msg)) => { - eprintln!("Could not load config: {}", msg); + print_error(enable_styles, &format!("Could not load config: {}", msg)); process::exit(1); } Err(e) => { - eprintln!("Could not load config: {}", e); + print_error(enable_styles, &format!("Could not load config: {}", e)); process::exit(1); } }; if args.pager || config.display.use_pager { - configure_pager(); + configure_pager(enable_styles); } // Specify target OS @@ -431,7 +444,7 @@ fn main() { if let Some(file) = args.render { let path = PageLookupResult::with_page(file); if let Err(msg) = print_page(&path, args.raw, &config) { - eprintln!("{}", msg); + print_error(enable_styles, &msg); process::exit(1); } else { process::exit(0); @@ -443,12 +456,12 @@ fn main() { // Clear cache, pass through if args.clear_cache { - clear_cache(args.quiet); + clear_cache(args.quiet, enable_styles); } // Cache update, pass through let cache_updated = if should_update_cache(&args, &config) { - update_cache(&cache, args.quiet); + update_cache(&cache, args.quiet, enable_styles); true } else { false @@ -466,7 +479,10 @@ fn main() { if args.list { // Get list of pages let pages = cache.list_pages().unwrap_or_else(|e| { - eprintln!("Could not get list of pages: {}", e.message()); + print_error( + enable_styles, + &format!("Could not get list of pages: {}", e.message()), + ); process::exit(1); }); @@ -490,15 +506,21 @@ fn main() { config.directories.custom_pages_dir.as_deref(), ) { if let Err(msg) = print_page(&page, args.raw, &config) { - eprintln!("{}", msg); + print_error(enable_styles, &msg); process::exit(1); } process::exit(0); } else { if !args.quiet { - eprintln!("Page {} not found in cache", &command); - eprintln!("Try updating with `tldr --update`, or submit a pull request to:"); - eprintln!("https://github.com/tldr-pages/tldr"); + print_warning( + enable_styles, + &format!( + "Page `{}` not found in cache.\n\ + Try updating with `tldr --update`, or submit a pull request to:\n\ + https://github.com/tldr-pages/tldr", + &command + ), + ); } process::exit(1); } diff --git a/src/utils.rs b/src/utils.rs new file mode 100644 index 0000000..e6f65f5 --- /dev/null +++ b/src/utils.rs @@ -0,0 +1,22 @@ +use ansi_term::{Color, Style}; + +/// Print a warning to stderr. If `enable_styles` is true, then a yellow +/// message will be printed. +pub fn print_warning(enable_styles: bool, message: &str) { + print_msg(enable_styles, message, "Warning: ", Color::Yellow); +} + +/// Print an error to stderr. If `enable_styles` is true, then a red message +/// will be printed. +pub fn print_error(enable_styles: bool, message: &str) { + print_msg(enable_styles, message, "Error: ", Color::Red); +} + +fn print_msg(enable_styles: bool, message: &str, prefix: &'static str, color: Color) { + if enable_styles { + let style = Style::new().fg(color); + eprintln!("{}{}", style.paint(prefix), style.paint(message)); + } else { + eprintln!("{}", message); + } +}