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.
This commit is contained in:
Niklas Mohrin 2025-02-26 23:04:41 +01:00 committed by GitHub
commit 009af7063f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -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<String> {
)
}
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<ExitCode> {
// 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.