From 98e0e5aaf54474770cea9dcf6dde10c1f0b88e20 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Sat, 16 Jul 2016 22:46:43 +0200 Subject: [PATCH 01/13] Add StdoutViewer --- libimagentryview/src/builtin/mod.rs | 1 + libimagentryview/src/builtin/stdout.rs | 38 ++++++++++++++++++++++++++ 2 files changed, 39 insertions(+) create mode 100644 libimagentryview/src/builtin/stdout.rs diff --git a/libimagentryview/src/builtin/mod.rs b/libimagentryview/src/builtin/mod.rs index 6c83de88..248d8b25 100644 --- a/libimagentryview/src/builtin/mod.rs +++ b/libimagentryview/src/builtin/mod.rs @@ -1 +1,2 @@ pub mod plain; +pub mod stdout; diff --git a/libimagentryview/src/builtin/stdout.rs b/libimagentryview/src/builtin/stdout.rs new file mode 100644 index 00000000..7f6a8b28 --- /dev/null +++ b/libimagentryview/src/builtin/stdout.rs @@ -0,0 +1,38 @@ +use libimagstore::store::Entry; + +use toml::encode_str; + +use viewer::Viewer; +use result::Result; + +pub struct StdoutViewer { + view_header: bool, + view_content: bool, +} + +impl StdoutViewer { + + pub fn new(view_header: bool, view_content: bool) -> StdoutViewer { + StdoutViewer { + view_header: view_header, + view_content: view_content, + } + } + +} + +impl Viewer for StdoutViewer { + + fn view_entry(&self, e: &Entry) -> Result<()> { + if self.view_header { + println!("{}", encode_str(e.get_header().header())); + } + + if self.view_content { + println!("{}", e.get_content()); + } + + Ok(()) + } + +} From f50c54b6a4248e9ead96c45534cf8752de348628 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Sat, 16 Jul 2016 22:51:51 +0200 Subject: [PATCH 02/13] Add deps: log, toml --- imag-view/src/viewer/mod.rs | 16 -------------- imag-view/src/viewer/stdout.rs | 40 ---------------------------------- libimagentryview/Cargo.toml | 2 ++ libimagentryview/src/lib.rs | 3 +++ 4 files changed, 5 insertions(+), 56 deletions(-) delete mode 100644 imag-view/src/viewer/mod.rs delete mode 100644 imag-view/src/viewer/stdout.rs diff --git a/imag-view/src/viewer/mod.rs b/imag-view/src/viewer/mod.rs deleted file mode 100644 index f7e3653f..00000000 --- a/imag-view/src/viewer/mod.rs +++ /dev/null @@ -1,16 +0,0 @@ -pub mod stdout; - -use libimagstore::store::FileLockEntry; - -pub struct ViewInformation<'a> { - pub entry: FileLockEntry<'a>, - pub view_header: bool, - pub view_content: bool, - pub view_copy: bool, - pub keep_copy: bool, -} - -pub trait Viewer { - fn view(&self, vi: ViewInformation); -} - diff --git a/imag-view/src/viewer/stdout.rs b/imag-view/src/viewer/stdout.rs deleted file mode 100644 index 18536da6..00000000 --- a/imag-view/src/viewer/stdout.rs +++ /dev/null @@ -1,40 +0,0 @@ -use std::io::{Stdout, stdout}; - -use toml::encode_str; - -use viewer::{ViewInformation, Viewer}; - -pub struct StdoutViewer { - out: Stdout, -} - -impl StdoutViewer { - - pub fn new() -> StdoutViewer { - StdoutViewer { out: stdout() } - } - -} - -impl Viewer for StdoutViewer { - - fn view(&self, vi: ViewInformation) { - if vi.view_copy { - unimplemented!(); - } - - if vi.view_header { - debug!("Going to display header: {:?}", vi.entry.get_header().header()); - println!("{}", encode_str(vi.entry.get_header().header())); - } - - if vi.view_content { - println!("{}", vi.entry.get_content()); - } - - if vi.view_copy && !vi.keep_copy { - unimplemented!() - } - } - -} diff --git a/libimagentryview/Cargo.toml b/libimagentryview/Cargo.toml index c264e818..f827d414 100644 --- a/libimagentryview/Cargo.toml +++ b/libimagentryview/Cargo.toml @@ -4,6 +4,8 @@ version = "0.2.0" authors = ["Matthias Beyer "] [dependencies] +log = "0.3" +toml = "0.1.25" [dependencies.libimagstore] path = "../libimagstore" diff --git a/libimagentryview/src/lib.rs b/libimagentryview/src/lib.rs index 950332c5..76d0001e 100644 --- a/libimagentryview/src/lib.rs +++ b/libimagentryview/src/lib.rs @@ -14,6 +14,9 @@ while_true, )] +#[macro_use] extern crate log; +extern crate toml; + extern crate libimagstore; #[macro_use] extern crate libimagerror; From ccb686cea4bcf569f7c83b4a89f0ad56ed77a738 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Sat, 16 Jul 2016 22:52:25 +0200 Subject: [PATCH 03/13] Add dep: libimagentryview --- imag-view/Cargo.toml | 3 +++ imag-view/src/main.rs | 1 + 2 files changed, 4 insertions(+) diff --git a/imag-view/Cargo.toml b/imag-view/Cargo.toml index 1f655f46..699e0dbf 100644 --- a/imag-view/Cargo.toml +++ b/imag-view/Cargo.toml @@ -20,3 +20,6 @@ path = "../libimagrt" [dependencies.libimagerror] path = "../libimagerror" +[dependencies.libimagentryview] +path = "../libimagentryview" + diff --git a/imag-view/src/main.rs b/imag-view/src/main.rs index a8c5aede..c8550bbe 100644 --- a/imag-view/src/main.rs +++ b/imag-view/src/main.rs @@ -22,6 +22,7 @@ extern crate toml; extern crate libimagrt; extern crate libimagstore; +extern crate libimagentryview; #[macro_use] extern crate libimagerror; use std::result::Result as RResult; From 228f55bfd60f60848c9e293cee84f8bd843bbaa9 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Sat, 16 Jul 2016 22:52:41 +0200 Subject: [PATCH 04/13] ui: Remove copy support --- imag-view/src/main.rs | 2 -- imag-view/src/ui.rs | 13 ------------- 2 files changed, 15 deletions(-) diff --git a/imag-view/src/main.rs b/imag-view/src/main.rs index c8550bbe..9d664254 100644 --- a/imag-view/src/main.rs +++ b/imag-view/src/main.rs @@ -66,8 +66,6 @@ fn main() { let entry_version = rt.cli().value_of("version"); let view_header = rt.cli().is_present("view-header"); let view_content = rt.cli().is_present("view-content"); - let view_copy = rt.cli().is_present("view-copy"); - let keep_copy = rt.cli().is_present("keep-copy"); let scmd = rt.cli().subcommand_matches("view-in"); if scmd.is_none() { diff --git a/imag-view/src/ui.rs b/imag-view/src/ui.rs index 45c05ed1..ae9180b0 100644 --- a/imag-view/src/ui.rs +++ b/imag-view/src/ui.rs @@ -37,19 +37,6 @@ pub fn build_ui<'a>(app: App<'a, 'a>) -> App<'a, 'a> { .required(false) .help("View content")) - .arg(Arg::with_name("view-copy") - .long("copy") - .takes_value(false) - .required(false) - .help("Copy before opening (copies to /tmp/) and removes the file after viewing.")) - - .arg(Arg::with_name("keep-copy") - .long("keep-copy") - .short("k") - .takes_value(false) - .required(false) - .help("If --copy was passed, keep the copy after viewing.")) - .subcommand(SubCommand::with_name("view-in") .about("View the entry in ...") .version("0.1") From fb813005949cf5e3d10e8f2e5bd770ed9cce2c80 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Sat, 16 Jul 2016 22:53:12 +0200 Subject: [PATCH 05/13] Move to use libimagentryview for viewing entries --- imag-view/src/main.rs | 28 ++++++++-------------------- 1 file changed, 8 insertions(+), 20 deletions(-) diff --git a/imag-view/src/main.rs b/imag-view/src/main.rs index 9d664254..65cf5398 100644 --- a/imag-view/src/main.rs +++ b/imag-view/src/main.rs @@ -32,16 +32,14 @@ use libimagrt::runtime::Runtime; use libimagrt::setup::generate_runtime_setup; use libimagstore::store::FileLockEntry; use libimagerror::trace::{trace_error, trace_error_exit}; +use libimagentryview::builtin::stdout::StdoutViewer; +use libimagentryview::viewer::Viewer; mod error; mod ui; -mod viewer; use error::{ViewError, ViewErrorKind}; use ui::build_ui; -use viewer::Viewer; -use viewer::ViewInformation; -use viewer::stdout::StdoutViewer; type Result = RResult; @@ -76,22 +74,17 @@ fn main() { let viewer = { if scmd.is_present("view-in-stdout") { - Box::new(StdoutViewer::new()) } else if scmd.is_present("view-in-ui") { warn!("Viewing in UI is currently not supported, switch to stdout"); - Box::new(StdoutViewer::new()) } else if scmd.is_present("view-in-browser") { warn!("Viewing in browser is currently not supported, switch to stdout"); - Box::new(StdoutViewer::new()) } else if scmd.is_present("view-in-texteditor") { warn!("Viewing in texteditor is currently not supported, switch to stdout"); - Box::new(StdoutViewer::new()) } else if scmd.is_present("view-in-custom") { warn!("Viewing in custom is currently not supported, switch to stdout"); - Box::new(StdoutViewer::new()) - } else { - Box::new(StdoutViewer::new()) } + + StdoutViewer::new(view_header, view_content) }; let entry = load_entry(entry_id, entry_version, &rt); @@ -100,15 +93,10 @@ fn main() { } let entry = entry.unwrap(); - let view_info = ViewInformation { - entry: entry, - view_header: view_header, - view_content: view_content, - view_copy: view_copy, - keep_copy: keep_copy, - }; - - viewer.view(view_info); + if let Err(e) = viewer.view_entry(&entry) { + trace_error(&e); + exit(1); + } } } From d32a8b94797b9e39e84eddfab6e231e0478320a7 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Sat, 16 Jul 2016 23:34:59 +0200 Subject: [PATCH 06/13] Remove error module --- imag-view/src/error.rs | 12 ------------ imag-view/src/main.rs | 1 - 2 files changed, 13 deletions(-) delete mode 100644 imag-view/src/error.rs diff --git a/imag-view/src/error.rs b/imag-view/src/error.rs deleted file mode 100644 index 77c7b95d..00000000 --- a/imag-view/src/error.rs +++ /dev/null @@ -1,12 +0,0 @@ -generate_error_module!( - generate_error_types!(ViewError, ViewErrorKind, - StoreError => "Store error", - NoVersion => "No version specified", - PatternError => "Error in Pattern", - GlobBuildError => "Could not build glob() Argument" - ); -); - -pub use self::error::ViewError; -pub use self::error::ViewErrorKind; - diff --git a/imag-view/src/main.rs b/imag-view/src/main.rs index 65cf5398..3d18a45f 100644 --- a/imag-view/src/main.rs +++ b/imag-view/src/main.rs @@ -35,7 +35,6 @@ use libimagerror::trace::{trace_error, trace_error_exit}; use libimagentryview::builtin::stdout::StdoutViewer; use libimagentryview::viewer::Viewer; -mod error; mod ui; use error::{ViewError, ViewErrorKind}; From 53d819d7b6997d818893bccf5036ec9f778c6116 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Sat, 16 Jul 2016 23:35:19 +0200 Subject: [PATCH 07/13] Remove dep on glob() --- imag-view/Cargo.toml | 1 - imag-view/src/main.rs | 1 - 2 files changed, 2 deletions(-) diff --git a/imag-view/Cargo.toml b/imag-view/Cargo.toml index 699e0dbf..ee3bec7c 100644 --- a/imag-view/Cargo.toml +++ b/imag-view/Cargo.toml @@ -5,7 +5,6 @@ authors = ["Matthias Beyer "] [dependencies] clap = "2.1.1" -glob = "0.2.11" log = "0.3" semver = "0.2.1" toml = "0.1.25" diff --git a/imag-view/src/main.rs b/imag-view/src/main.rs index 3d18a45f..8fc85e2c 100644 --- a/imag-view/src/main.rs +++ b/imag-view/src/main.rs @@ -14,7 +14,6 @@ )] extern crate clap; -extern crate glob; #[macro_use] extern crate log; extern crate semver; extern crate toml; From 1e5548a247518cb21b910555416ab139963807da Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Sat, 16 Jul 2016 23:35:31 +0200 Subject: [PATCH 08/13] Remove seperate version passing --- imag-view/src/ui.rs | 8 -------- 1 file changed, 8 deletions(-) diff --git a/imag-view/src/ui.rs b/imag-view/src/ui.rs index ae9180b0..3d6592ad 100644 --- a/imag-view/src/ui.rs +++ b/imag-view/src/ui.rs @@ -10,14 +10,6 @@ pub fn build_ui<'a>(app: App<'a, 'a>) -> App<'a, 'a> { .help("View this entry at this store path") .value_name("ID")) - .arg(Arg::with_name("version") - .long("version") - .short("V") - .takes_value(true) - .required(true) - .help("View this version (youngest if not specified)") - .value_name("VERSION")) - .arg(Arg::with_name("versions") .long("versions") .takes_value(false) From 2eb1fc8151c51b7f75ef3228d641e2b918d74297 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Sat, 16 Jul 2016 23:35:53 +0200 Subject: [PATCH 09/13] Add glob()ing in libimagentryview --- libimagentryview/Cargo.toml | 1 + libimagentryview/src/lib.rs | 1 + 2 files changed, 2 insertions(+) diff --git a/libimagentryview/Cargo.toml b/libimagentryview/Cargo.toml index f827d414..43c2830c 100644 --- a/libimagentryview/Cargo.toml +++ b/libimagentryview/Cargo.toml @@ -6,6 +6,7 @@ authors = ["Matthias Beyer "] [dependencies] log = "0.3" toml = "0.1.25" +glob = "0.2.11" [dependencies.libimagstore] path = "../libimagstore" diff --git a/libimagentryview/src/lib.rs b/libimagentryview/src/lib.rs index 76d0001e..b31642f8 100644 --- a/libimagentryview/src/lib.rs +++ b/libimagentryview/src/lib.rs @@ -15,6 +15,7 @@ )] #[macro_use] extern crate log; +extern crate glob; extern crate toml; extern crate libimagstore; From 51bfb60bedfc2c5d523a441dcef9d2a728ff31ba Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Sat, 16 Jul 2016 23:36:23 +0200 Subject: [PATCH 10/13] Add error kinds for glob()ing errors --- libimagentryview/src/error.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libimagentryview/src/error.rs b/libimagentryview/src/error.rs index e54d2fcc..87a72641 100644 --- a/libimagentryview/src/error.rs +++ b/libimagentryview/src/error.rs @@ -1,6 +1,9 @@ generate_error_module!( generate_error_types!(ViewError, ViewErrorKind, - Unknown => "Unknown view error" + Unknown => "Unknown view error", + GlobError => "Error while glob()ing", + PatternError => "Error in glob() pattern", + PatternBuildingError => "Could not build glob() pattern" ); ); From 42aaf894dcbb577f2b9ae8eb16c53c9cea5d3718 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Sat, 16 Jul 2016 23:36:40 +0200 Subject: [PATCH 11/13] Pass MapErrInto trait out of error module --- libimagentryview/src/error.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libimagentryview/src/error.rs b/libimagentryview/src/error.rs index 87a72641..f26c6081 100644 --- a/libimagentryview/src/error.rs +++ b/libimagentryview/src/error.rs @@ -9,4 +9,4 @@ generate_error_module!( pub use self::error::ViewError; pub use self::error::ViewErrorKind; - +pub use self::error::MapErrInto; From 9c994b201163ad801434bb19d61c85e5353a0993 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Sat, 16 Jul 2016 23:36:56 +0200 Subject: [PATCH 12/13] Add VersionsViewer --- libimagentryview/src/builtin/mod.rs | 1 + libimagentryview/src/builtin/versions.rs | 54 ++++++++++++++++++++++++ 2 files changed, 55 insertions(+) create mode 100644 libimagentryview/src/builtin/versions.rs diff --git a/libimagentryview/src/builtin/mod.rs b/libimagentryview/src/builtin/mod.rs index 248d8b25..449d9b67 100644 --- a/libimagentryview/src/builtin/mod.rs +++ b/libimagentryview/src/builtin/mod.rs @@ -1,2 +1,3 @@ pub mod plain; pub mod stdout; +pub mod versions; diff --git a/libimagentryview/src/builtin/versions.rs b/libimagentryview/src/builtin/versions.rs new file mode 100644 index 00000000..11439c36 --- /dev/null +++ b/libimagentryview/src/builtin/versions.rs @@ -0,0 +1,54 @@ +use libimagstore::store::Entry; +use libimagstore::store::Store; +use libimagerror::into::IntoError; + +use viewer::Viewer; +use result::Result; +use error::ViewErrorKind as VEK; + +pub struct VersionsViewer<'a> { + store: &'a Store, +} + +impl<'a> VersionsViewer<'a> { + + pub fn new(store: &'a Store) -> VersionsViewer<'a> { + VersionsViewer { + store: store, + } + } + +} + +impl<'a> Viewer for VersionsViewer<'a> { + + fn view_entry(&self, entr: &Entry) -> Result<()> { + use glob::glob; + + entr.get_location() + .clone() + .storified(self.store) + .to_str() + .and_then(|s| s.split("~").next()) + .map(|component| { + glob(&format!("{}~*", component)[..]) + .map_err(|_| VEK::PatternError.into_error()) + .and_then(|paths| { + for entry in paths { + let p = match entry { + Err(_) => return Err(VEK::GlobError.into_error()), + Ok(p) => p, + }; + let p = p.file_name() + .and_then(|s| s.to_str()) + .unwrap(); // TODO + println!("{}", p); + }; + Ok(()) + }) + }) + .unwrap_or(Err(VEK::PatternBuildingError.into_error())) + } + +} + From 60863d2fe35b7263cf7da58cd91c5a91cd065876 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Sat, 16 Jul 2016 23:37:15 +0200 Subject: [PATCH 13/13] Rewrite main() --- imag-view/src/main.rs | 146 +++++++++--------------------------------- 1 file changed, 32 insertions(+), 114 deletions(-) diff --git a/imag-view/src/main.rs b/imag-view/src/main.rs index 8fc85e2c..9f4040b1 100644 --- a/imag-view/src/main.rs +++ b/imag-view/src/main.rs @@ -24,147 +24,65 @@ extern crate libimagstore; extern crate libimagentryview; #[macro_use] extern crate libimagerror; -use std::result::Result as RResult; use std::process::exit; +use std::path::PathBuf; -use libimagrt::runtime::Runtime; use libimagrt::setup::generate_runtime_setup; -use libimagstore::store::FileLockEntry; -use libimagerror::trace::{trace_error, trace_error_exit}; +use libimagerror::trace::trace_error; use libimagentryview::builtin::stdout::StdoutViewer; +use libimagentryview::builtin::versions::VersionsViewer; use libimagentryview::viewer::Viewer; mod ui; -use error::{ViewError, ViewErrorKind}; use ui::build_ui; -type Result = RResult; - fn main() { let rt = generate_runtime_setup( "imag-view", &version!()[..], "View entries (readonly)", build_ui); - let entry_id = rt.cli().value_of("id").unwrap(); // enforced by clap + let entry_id = rt.cli().value_of("id").unwrap(); // enforced by clap + let view_header = rt.cli().is_present("view-header"); + let view_content = rt.cli().is_present("view-content"); - if entry_id.contains("~") { - error!("The --id argument does not need the version part"); - exit(1); - } - - if rt.cli().is_present("versions") { - if let Err(e) = view_versions_of(entry_id, &rt) { - trace_error_exit(&e, 1); - } - } else { - let entry_version = rt.cli().value_of("version"); - let view_header = rt.cli().is_present("view-header"); - let view_content = rt.cli().is_present("view-content"); - - let scmd = rt.cli().subcommand_matches("view-in"); - if scmd.is_none() { + let scmd = match rt.cli().subcommand_matches("view-in") { + None => { debug!("No commandline call"); exit(1); // we can afford not-executing destructors here } - let scmd = scmd.unwrap(); + Some(s) => s, + }; - let viewer = { - if scmd.is_present("view-in-stdout") { - } else if scmd.is_present("view-in-ui") { - warn!("Viewing in UI is currently not supported, switch to stdout"); - } else if scmd.is_present("view-in-browser") { - warn!("Viewing in browser is currently not supported, switch to stdout"); - } else if scmd.is_present("view-in-texteditor") { - warn!("Viewing in texteditor is currently not supported, switch to stdout"); - } else if scmd.is_present("view-in-custom") { - warn!("Viewing in custom is currently not supported, switch to stdout"); - } - - StdoutViewer::new(view_header, view_content) - }; - - let entry = load_entry(entry_id, entry_version, &rt); - if entry.is_err() { - trace_error_exit(&entry.unwrap_err(), 1); - } - let entry = entry.unwrap(); - - if let Err(e) = viewer.view_entry(&entry) { + let entry = match rt.store().retrieve(PathBuf::from(entry_id)) { + Ok(fle) => fle, + Err(e) => { trace_error(&e); - exit(1); - } - } -} - -// TODO: This is a shameless adaption of imag-store/src/util.rs -fn load_entry<'a>(id: &str, - version: Option<&str>, - rt: &'a Runtime) - -> Result> -{ - debug!("Checking path element for version"); - - let version = { - if version.is_none() { - let r = id.split('~').last(); - if r.is_none() { - warn!("No version"); - return Err(ViewError::new(ViewErrorKind::NoVersion, None)); - } else { - r.unwrap() - } - } else { - version.unwrap() + exit(1); // we can afford not-executing destructors here } }; - debug!("Building path from {:?} and {:?}", id, version); - let mut path = rt.store().path().clone(); - - if id.starts_with('/') { - path.push(format!("{}~{}", &id[1..id.len()], version)); + let res = if rt.cli().is_present("versions") { + VersionsViewer::new(rt.store()).view_entry(&entry) } else { - path.push(format!("{}~{}", id, version)); - } - - // the above is the adaption... - - rt.store().retrieve(path) - .map_err(|e| ViewError::new(ViewErrorKind::StoreError, Some(Box::new(e)))) -} - -fn view_versions_of(id: &str, rt: &Runtime) -> Result<()> { - use glob::glob; - - let mut path = rt.store().path().clone(); - - if id.starts_with('/') { - path.push(format!("{}~*", &id[1..id.len()])); - } else { - path.push(format!("{}~*", id)); - } - - if let Some(path) = path.to_str() { - match glob(path) { - Ok(paths) => { - for entry in paths { - match entry { - Ok(path) => println!("{}", path.file_name().and_then(|s| s.to_str()).unwrap()), - Err(e) => trace_error(e.error()), - } - } - Ok(()) - }, - Err(e) => { - debug!("Error in pattern"); - Err(ViewError::new(ViewErrorKind::PatternError, Some(Box::new(e)))) - }, + if scmd.is_present("view-in-stdout") { + } else if scmd.is_present("view-in-ui") { + warn!("Viewing in UI is currently not supported, switch to stdout"); + } else if scmd.is_present("view-in-browser") { + warn!("Viewing in browser is currently not supported, switch to stdout"); + } else if scmd.is_present("view-in-texteditor") { + warn!("Viewing in texteditor is currently not supported, switch to stdout"); + } else if scmd.is_present("view-in-custom") { + warn!("Viewing in custom is currently not supported, switch to stdout"); } - } else { - warn!("Could not build glob() argument!"); - Err(ViewError::new(ViewErrorKind::GlobBuildError, None)) + + StdoutViewer::new(view_header, view_content).view_entry(&entry) + }; + + if let Err(e) = res { + trace_error(&e); + exit(1); } }