From faca509798e08b9a03fed360b3cc732f8e60232a Mon Sep 17 00:00:00 2001 From: Danny McClanahan <1305167+cosmicexplorer@users.noreply.github.com> Date: Wed, 14 Aug 2024 15:58:02 -0400 Subject: [PATCH] wrap all errors in compress command with eyre --- cli/clite/Cargo.toml | 2 +- cli/clite/src/main.rs | 4 +- cli/src/compress.rs | 117 ++++++++++++++++++++++++++++++------------ 3 files changed, 88 insertions(+), 35 deletions(-) diff --git a/cli/clite/Cargo.toml b/cli/clite/Cargo.toml index e4cfd056f..f2895859d 100644 --- a/cli/clite/Cargo.toml +++ b/cli/clite/Cargo.toml @@ -22,7 +22,7 @@ members = ["."] name = "zip-clite" [dependencies] -eyre = "0.6" +color-eyre = "0.6" [dependencies.zip-cli] path = ".." diff --git a/cli/clite/src/main.rs b/cli/clite/src/main.rs index 6a066aec2..c4d83b619 100644 --- a/cli/clite/src/main.rs +++ b/cli/clite/src/main.rs @@ -1,13 +1,15 @@ use std::env; use std::io; -use eyre::Report; +use color_eyre::eyre::{self, Report}; use zip_cli::args::*; use zip_cli::compress::execute_compress; use zip_cli::ErrHandle; fn main() -> Result<(), Report> { + color_eyre::install()?; + let ZipCli { verbose, command } = ZipCli::parse_argv(env::args_os())?; let mut err = if verbose { ErrHandle::Output(io::stderr()) diff --git a/cli/src/compress.rs b/cli/src/compress.rs index 6be418afa..bb8c9c198 100644 --- a/cli/src/compress.rs +++ b/cli/src/compress.rs @@ -4,7 +4,7 @@ use std::{ path::Path, }; -use color_eyre::eyre::{self, Report}; +use color_eyre::eyre::{eyre, Report, WrapErr}; use zip::{ unstable::path_to_string, @@ -59,9 +59,14 @@ fn enter_recursive_dir_entries( err, "writing top-level directory entry for {base_dirname:?}" )?; - writer.add_directory(&base_dirname, options)?; + writer + .add_directory(&base_dirname, options) + .wrap_err_with(|| eyre!("{base_dirname}"))?; - let mut readdir_stack: Vec<(fs::ReadDir, String)> = vec![(fs::read_dir(root)?, base_dirname)]; + let mut readdir_stack: Vec<(fs::ReadDir, String)> = vec![( + fs::read_dir(root).wrap_err_with(|| eyre!("{}", root.display()))?, + base_dirname, + )]; while let Some((mut readdir, top_component)) = readdir_stack.pop() { if let Some(dir_entry) = readdir.next().transpose()? { let mut components: Vec<&str> = readdir_stack.iter().map(|(_, s)| s.as_ref()).collect(); @@ -70,36 +75,51 @@ fn enter_recursive_dir_entries( let entry_basename: String = dir_entry .file_name() .into_string() - .map_err(|name| eyre::eyre!("failed to decode basename {name:?}"))?; + .map_err(|name| eyre!("failed to decode basename {name:?}"))?; components.push(&entry_basename); let full_path: String = components.join("/"); readdir_stack.push((readdir, top_component)); - let file_type = dir_entry.file_type()?; + let file_type = dir_entry + .file_type() + .wrap_err_with(|| eyre!("{}", dir_entry.path().display()))?; if file_type.is_symlink() { - let target: String = path_to_string(fs::read_link(dir_entry.path())?).into(); + let target: String = path_to_string( + fs::read_link(dir_entry.path()) + .wrap_err_with(|| eyre!("{}", dir_entry.path().display()))?, + ) + .into(); writeln!( err, "writing recursive symlink entry with name {full_path:?} and target {target:?}" )?; - writer.add_symlink(full_path, target, options)?; + writer + .add_symlink(&full_path, &target, options) + .wrap_err_with(|| eyre!("{full_path}->{target}"))?; } else if file_type.is_file() { writeln!(err, "writing recursive file entry with name {full_path:?}")?; - writer.start_file(full_path, options)?; - let mut f = fs::File::open(dir_entry.path())?; - io::copy(&mut f, writer)?; + writer + .start_file(&full_path, options) + .wrap_err_with(|| eyre!("{full_path}"))?; + let mut f = fs::File::open(dir_entry.path()) + .wrap_err_with(|| eyre!("{}", dir_entry.path().display()))?; + io::copy(&mut f, writer) + .wrap_err_with(|| eyre!("{}", dir_entry.path().display()))?; } else { assert!(file_type.is_dir()); writeln!( err, "writing recursive directory entry with name {full_path:?}" )?; - writer.add_directory(full_path, options)?; + writer + .add_directory(&full_path, options) + .wrap_err_with(|| eyre!("{full_path}"))?; writeln!( err, "adding subdirectories depth-first for recursive directory entry {entry_basename:?}" )?; - let new_readdir = fs::read_dir(dir_entry.path())?; + let new_readdir = fs::read_dir(dir_entry.path()) + .wrap_err_with(|| eyre!("{}", dir_entry.path().display()))?; readdir_stack.push((new_readdir, entry_basename)); } } @@ -121,7 +141,9 @@ pub fn execute_compress( let out = match output_path { Some(path) => { writeln!(err, "writing compressed zip to output file path {path:?}")?; - OutputHandle::File(fs::File::create(path)?) + OutputHandle::File( + fs::File::create(&path).wrap_err_with(|| eyre!("{}", path.display()))?, + ) } None => { writeln!( @@ -189,7 +211,9 @@ pub fn execute_compress( let dirname = last_name.take().unwrap_or_else(|| { Compress::exit_arg_invalid("no name provided before dir entry") }); - writer.add_directory(dirname, options)?; + writer + .add_directory(&dirname, options) + .wrap_err_with(|| eyre!("{dirname}"))?; } CompressionArg::Symlink => { writeln!(err, "setting symlink flag for next entry")?; @@ -215,7 +239,9 @@ pub fn execute_compress( "writing immediate symlink entry with name {name:?} and target {target:?}" )?; /* TODO: .add_symlink() should support OsString targets! */ - writer.add_symlink(name, target, options)?; + writer + .add_symlink(&name, &target, options) + .wrap_err_with(|| eyre!("{name}->{target}"))?; symlink_flag = false; } else { /* This is a file entry. */ @@ -224,8 +250,12 @@ pub fn execute_compress( "writing immediate file entry with name {name:?} and data {data:?}" )?; let data = data.into_encoded_bytes(); - writer.start_file(name, options)?; - writer.write_all(data.as_ref())?; + writer + .start_file(&name, options) + .wrap_err_with(|| eyre!("{name}"))?; + writer + .write_all(data.as_ref()) + .wrap_err_with(|| eyre!("{name}"))?; } } CompressionArg::FilePath(path) => { @@ -234,9 +264,14 @@ pub fn execute_compress( .unwrap_or_else(|| path_to_string(&path).into()); if symlink_flag { /* This is a symlink entry. */ - let target: String = path_to_string(fs::read_link(&path)?).into(); + let target: String = path_to_string( + fs::read_link(&path).wrap_err_with(|| eyre!("{}", path.display()))?, + ) + .into(); writeln!(err, "writing symlink entry from path {path:?} with name {name:?} and target {target:?}")?; - writer.add_symlink(name, target, options)?; + writer + .add_symlink(&name, &target, options) + .wrap_err_with(|| eyre!("{name}->{target}"))?; symlink_flag = false; } else { /* This is a file entry. */ @@ -244,9 +279,12 @@ pub fn execute_compress( err, "writing file entry from path {path:?} with name {name:?}" )?; - writer.start_file(name, options)?; - let mut f = fs::File::open(path)?; - io::copy(&mut f, &mut writer)?; + writer + .start_file(&name, options) + .wrap_err_with(|| eyre!("{name}"))?; + let mut f = + fs::File::open(&path).wrap_err_with(|| eyre!("{}", path.display()))?; + io::copy(&mut f, &mut writer).wrap_err_with(|| eyre!("{}", path.display()))?; } } CompressionArg::RecursiveDirPath(r) => { @@ -257,7 +295,8 @@ pub fn execute_compress( err, "writing recursive dir entries for path {r:?} with name {last_name:?}" )?; - enter_recursive_dir_entries(err, last_name.take(), &r, &mut writer, options)?; + enter_recursive_dir_entries(err, last_name.take(), &r, &mut writer, options) + .wrap_err_with(|| eyre!("{}", r.display()))?; } } } @@ -270,36 +309,48 @@ pub fn execute_compress( )) } for pos_arg in positional_paths.into_iter() { - let file_type = fs::symlink_metadata(&pos_arg)?.file_type(); + let file_type = fs::symlink_metadata(&pos_arg) + .wrap_err_with(|| eyre!("{}", pos_arg.display()))? + .file_type(); if file_type.is_symlink() { - let target = fs::read_link(&pos_arg)?; + let target = + fs::read_link(&pos_arg).wrap_err_with(|| eyre!("{}", pos_arg.display()))?; writeln!( err, "writing positional symlink entry with path {pos_arg:?} and target {target:?}" )?; - writer.add_symlink_from_path(pos_arg, target, options)?; + writer + .add_symlink_from_path(&pos_arg, &target, options) + .wrap_err_with(|| eyre!("{}->{}", pos_arg.display(), target.display()))?; } else if file_type.is_file() { writeln!(err, "writing positional file entry with path {pos_arg:?}")?; - writer.start_file_from_path(&pos_arg, options)?; - let mut f = fs::File::open(pos_arg)?; - io::copy(&mut f, &mut writer)?; + writer + .start_file_from_path(&pos_arg, options) + .wrap_err_with(|| eyre!("{}", pos_arg.display()))?; + let mut f = + fs::File::open(&pos_arg).wrap_err_with(|| eyre!("{}", pos_arg.display()))?; + io::copy(&mut f, &mut writer).wrap_err_with(|| eyre!("{}", pos_arg.display()))?; } else { assert!(file_type.is_dir()); writeln!( err, "writing positional recursive dir entry for {pos_arg:?}" )?; - enter_recursive_dir_entries(err, None, &pos_arg, &mut writer, options)?; + enter_recursive_dir_entries(err, None, &pos_arg, &mut writer, options) + .wrap_err_with(|| eyre!("{}", pos_arg.display()))?; } } - let handle = writer.finish()?; + let handle = writer + .finish() + .wrap_err("failed to write zip to output handle")?; match handle { OutputHandle::File(_) => (), OutputHandle::InMem(mut cursor) => { - cursor.rewind()?; + cursor.rewind().wrap_err("failed to rewind cursor")?; let mut stdout = io::stdout().lock(); - io::copy(&mut cursor, &mut stdout)?; + io::copy(&mut cursor, &mut stdout) + .wrap_err("failed to copy contents of cursor to stdout")?; } }