From 009af7063f2c8fc2b72fba02cbca5cd2bf12ad37 Mon Sep 17 00:00:00 2001 From: Niklas Mohrin Date: Wed, 26 Feb 2025 23:04:41 +0100 Subject: [PATCH] Move most of `main` to `try_main` (#400) Currently, `main` uses `print_error` and `process::exit` in several places. These could be unified by propagating errors via `Result`s. There is one place left that manually calls `print_error`, because the error should be followed by help instructions printed without any highlighting. --- src/main.rs | 131 +++++++++++++++++++++------------------------------- 1 file changed, 52 insertions(+), 79 deletions(-) diff --git a/src/main.rs b/src/main.rs index 74ab3d3..cfd00db 100644 --- a/src/main.rs +++ b/src/main.rs @@ -30,12 +30,10 @@ use std::{ fs::create_dir_all, io::{self, IsTerminal}, path::Path, - process, - process::Command, + process::{Command, ExitCode}, }; -use anyhow::anyhow; -use anyhow::Context; +use anyhow::{anyhow, Context, Result}; use app_dirs::AppInfo; use clap::Parser; @@ -119,11 +117,8 @@ fn check_cache(cache: &Cache, args: &Cli, enable_styles: bool) -> CheckCacheResu } /// Clear the cache -fn clear_cache(cache: &Cache, quietly: bool, enable_styles: bool) { - let cache_dir_found = cache.clear().unwrap_or_else(|e| { - print_error(enable_styles, &e.context("Could not clear cache")); - process::exit(1); - }); +fn clear_cache(cache: &Cache, quietly: bool) -> Result<()> { + let cache_dir_found = cache.clear().context("Could not clear cache")?; if !quietly { let cache_dir = cache.cache_dir().display(); if cache_dir_found { @@ -132,17 +127,18 @@ fn clear_cache(cache: &Cache, quietly: bool, enable_styles: bool) { eprintln!("Cache directory not found at `{cache_dir}`, nothing to do."); } } + Ok(()) } /// Update the cache -fn update_cache(cache: &Cache, archive_source: &str, quietly: bool, enable_styles: bool) { - cache.update(archive_source).unwrap_or_else(|e| { - print_error(enable_styles, &e.context("Could not update cache")); - process::exit(1); - }); +fn update_cache(cache: &Cache, archive_source: &str, quietly: bool) -> Result<()> { + cache + .update(archive_source) + .context("Could not update cache")?; if !quietly { eprintln!("Successfully updated cache."); } + Ok(()) } /// Show file paths @@ -179,21 +175,13 @@ fn show_paths(config: &Config) { println!("Custom pages dir: {custom_pages_dir}"); } -/// Create seed config file and exit -fn create_config_and_exit(enable_styles: bool) { - match make_default_config() { - Ok(config_file_path) => { - eprintln!( - "Successfully created seed config file here: {}", - config_file_path.to_str().unwrap() - ); - process::exit(0); - } - Err(e) => { - print_error(enable_styles, &e.context("Could not create seed config")); - process::exit(1); - } - } +fn create_config() -> Result<()> { + let config_file_path = make_default_config().context("Could not create seed config")?; + eprintln!( + "Successfully created seed config file here: {}", + config_file_path.to_str().unwrap() + ); + Ok(()) } #[cfg(feature = "logging")] @@ -240,7 +228,7 @@ fn get_languages_from_env() -> Vec { ) } -fn spawn_editor(custom_pages_dir: &Path, file_name: &str) -> anyhow::Result<()> { +fn spawn_editor(custom_pages_dir: &Path, file_name: &str) -> Result<()> { create_dir_all(custom_pages_dir).context("Failed to create custom pages directory")?; let custom_page_path = custom_pages_dir.join(file_name); @@ -261,7 +249,7 @@ fn spawn_editor(custom_pages_dir: &Path, file_name: &str) -> anyhow::Result<()> Ok(()) } -fn main() { +fn main() -> ExitCode { // Initialize logger init_log(); @@ -283,14 +271,15 @@ fn main() { ColorOptions::Never => false, }; + try_main(args, enable_styles).unwrap_or_else(|error| { + print_error(enable_styles, &error); + ExitCode::FAILURE + }) +} + +fn try_main(args: Cli, enable_styles: bool) -> Result { // Look up config file, if none is found fall back to default config. - let config = match Config::load(enable_styles) { - Ok(config) => config, - Err(e) => { - print_error(enable_styles, &e.context("Could not load config")); - process::exit(1); - } - }; + let config = Config::load(enable_styles).context("Could not load config")?; let custom_pages_dir = config .directories @@ -312,12 +301,9 @@ fn main() { custom_pages_dir .context("To edit custom pages/patches, please specify a custom pages directory.") - .and_then(|custom_pages_dir| spawn_editor(custom_pages_dir, &file_name)) - .unwrap_or_else(|err| { - print_error(enable_styles, &err); - process::exit(1); - }); - return; + .and_then(|custom_pages_dir| spawn_editor(custom_pages_dir, &file_name))?; + + return Ok(ExitCode::SUCCESS); } // Show various paths @@ -327,7 +313,8 @@ fn main() { // Create a basic config and exit if args.seed_config { - create_config_and_exit(enable_styles); + create_config()?; + return Ok(ExitCode::SUCCESS); } let platforms = compute_platforms(args.platforms.as_ref()); @@ -335,12 +322,8 @@ fn main() { // If a local file was passed in, render it and exit if let Some(file) = args.render { let path = PageLookupResult::with_page(file); - if let Err(ref e) = print_page(&path, args.raw, enable_styles, args.pager, &config) { - print_error(enable_styles, e); - process::exit(1); - } else { - process::exit(0); - }; + print_page(&path, args.raw, enable_styles, args.pager, &config)?; + return Ok(ExitCode::SUCCESS); } // Instantiate cache. This will not yet create the cache directory! @@ -352,25 +335,17 @@ fn main() { // Clear cache, pass through if args.clear_cache { - clear_cache(&cache, args.quiet, enable_styles); + clear_cache(&cache, args.quiet)?; } - // Cache update, pass through - let cache_updated = if should_update_cache(&cache, &args, &config) { - let archive_source = config.updates.archive_source.as_str(); - update_cache(&cache, archive_source, args.quiet, enable_styles); - true - } else { - false - }; - - // Check cache presence and freshness - if !cache_updated - && (args.list || !command.is_empty()) + if should_update_cache(&cache, &args, &config) { + update_cache(&cache, &config.updates.archive_source, args.quiet)?; + } else if (args.list || !args.command.is_empty()) && check_cache(&cache, &args, enable_styles) == CheckCacheResult::CacheMissing { - process::exit(1); - } + // Cache is needed, but missing + return Ok(ExitCode::FAILURE); + }; // List cached commands and exit if args.list { @@ -378,7 +353,8 @@ fn main() { "{}", cache.list_pages(custom_pages_dir, &platforms).join("\n") ); - process::exit(0); + + return Ok(ExitCode::SUCCESS); } // Show command from cache @@ -389,7 +365,7 @@ fn main() { .map_or_else(get_languages_from_env, |lang| vec![lang]); // Search for command in cache - if let Some(lookup_result) = cache.find_page( + let Some(lookup_result) = cache.find_page( &command, &languages, config @@ -398,15 +374,7 @@ fn main() { .as_ref() .map(PathWithSource::path), &platforms, - ) { - if let Err(ref e) = - print_page(&lookup_result, args.raw, enable_styles, args.pager, &config) - { - print_error(enable_styles, e); - process::exit(1); - } - process::exit(0); - } else { + ) else { if !args.quiet { print_warning( enable_styles, @@ -418,9 +386,14 @@ fn main() { ), ); } - process::exit(1); - } + + return Ok(ExitCode::FAILURE); + }; + + print_page(&lookup_result, args.raw, enable_styles, args.pager, &config)?; } + + Ok(ExitCode::SUCCESS) } /// Returns the passed or default platform types and appends `PlatformType::Common` as fallback.