diff --git a/scarb/src/bin/scarb/commands/add.rs b/scarb/src/bin/scarb/commands/add.rs index 2cf9df3f3..84486bf2c 100644 --- a/scarb/src/bin/scarb/commands/add.rs +++ b/scarb/src/bin/scarb/commands/add.rs @@ -1,13 +1,14 @@ -use anyhow::{anyhow, Result}; +use anyhow::anyhow; use scarb::core::Config; use scarb::manifest_editor::{AddDependency, DepId, EditManifestOptions, Op}; use scarb::{manifest_editor, ops}; use crate::args::{AddArgs, AddSourceArgs}; +use crate::errors::ScarbResult; #[tracing::instrument(skip_all, level = "info")] -pub fn run(args: AddArgs, config: &mut Config) -> Result<()> { +pub fn run(args: AddArgs, config: &mut Config) -> ScarbResult<()> { let ws = ops::read_workspace(config.manifest_path(), config)?; // TODO(#127): Extract more generic pattern for this. See `Packages` struct in Cargo. diff --git a/scarb/src/bin/scarb/commands/build.rs b/scarb/src/bin/scarb/commands/build.rs index 8f9e49ef3..d50c68893 100644 --- a/scarb/src/bin/scarb/commands/build.rs +++ b/scarb/src/bin/scarb/commands/build.rs @@ -1,10 +1,9 @@ -use anyhow::Result; - +use crate::errors::ScarbResult; use scarb::core::Config; use scarb::ops; #[tracing::instrument(skip_all, level = "info")] -pub fn run(config: &Config) -> Result<()> { +pub fn run(config: &Config) -> ScarbResult<()> { let ws = ops::read_workspace(config.manifest_path(), config)?; - ops::compile(&ws) + ops::compile(&ws).map_err(Into::into) } diff --git a/scarb/src/bin/scarb/commands/clean.rs b/scarb/src/bin/scarb/commands/clean.rs index a0c59b232..b04b49a00 100644 --- a/scarb/src/bin/scarb/commands/clean.rs +++ b/scarb/src/bin/scarb/commands/clean.rs @@ -1,9 +1,9 @@ -use anyhow::Result; use scarb::core::Config; +use crate::errors::ScarbResult; use scarb::ops; #[tracing::instrument(skip_all, level = "info")] -pub fn run(config: &Config) -> Result<()> { - ops::clean(config) +pub fn run(config: &Config) -> ScarbResult<()> { + ops::clean(config).map_err(Into::into) } diff --git a/scarb/src/bin/scarb/commands/commands.rs b/scarb/src/bin/scarb/commands/commands.rs index 2a727de80..80886ea80 100644 --- a/scarb/src/bin/scarb/commands/commands.rs +++ b/scarb/src/bin/scarb/commands/commands.rs @@ -1,10 +1,10 @@ -use anyhow::Result; use serde::{Serialize, Serializer}; use std::collections::BTreeMap; use std::path::PathBuf; use std::{env, fmt, fs}; use crate::args::ScarbArgs; +use crate::errors::ScarbResult; use scarb::core::Config; use scarb::process::is_executable; use scarb::ui::Message; @@ -86,7 +86,7 @@ fn list_commands(config: &Config, builtins: &BTreeMap>) - } #[tracing::instrument(skip_all, level = "info")] -pub fn run(config: &Config) -> Result<()> { +pub fn run(config: &Config) -> ScarbResult<()> { let builtins = ScarbArgs::get_builtin_subcommands(); config.ui().print(list_commands(config, &builtins)); Ok(()) diff --git a/scarb/src/bin/scarb/commands/external.rs b/scarb/src/bin/scarb/commands/external.rs index 860a703f5..1badef4cd 100644 --- a/scarb/src/bin/scarb/commands/external.rs +++ b/scarb/src/bin/scarb/commands/external.rs @@ -1,17 +1,18 @@ use std::ffi::OsString; -use anyhow::{anyhow, Result}; +use anyhow::anyhow; +use crate::errors::ScarbResult; use scarb::core::Config; use scarb::ops::execute_external_subcommand; #[tracing::instrument(skip_all, level = "info")] -pub fn run(args: Vec, config: &Config) -> Result<()> { +pub fn run(args: Vec, config: &Config) -> ScarbResult<()> { assert!(!args.is_empty()); let cmd = &args[0] .clone() .into_string() .map_err(|_| anyhow!("command name must be valid UTF-8"))?; let args = &args.iter().skip(1).map(AsRef::as_ref).collect::>(); - execute_external_subcommand(cmd, args, config) + execute_external_subcommand(cmd, args, config).map_err(Into::into) } diff --git a/scarb/src/bin/scarb/commands/fmt.rs b/scarb/src/bin/scarb/commands/fmt.rs index bbd1c3509..f7fa2263a 100644 --- a/scarb/src/bin/scarb/commands/fmt.rs +++ b/scarb/src/bin/scarb/commands/fmt.rs @@ -1,21 +1,22 @@ -use anyhow::Result; - use crate::args::FmtArgs; +use crate::errors::{ErrorWithExitCode, ScarbResult}; use scarb::core::Config; use scarb::ops; #[tracing::instrument(skip_all, level = "info")] -pub fn run(args: FmtArgs, config: &Config) -> Result<()> { +pub fn run(args: FmtArgs, config: &Config) -> ScarbResult<()> { let ws = ops::read_workspace(config.manifest_path(), config)?; - match ops::format( + + if ops::format( ops::FmtOptions { check: args.check, pkg_name: args.package, color: !args.no_color, }, &ws, - ) { - Ok(true) => Ok(()), - _ => std::process::exit(1), + )? { + Ok(()) + } else { + Err(ErrorWithExitCode::code(1)) } } diff --git a/scarb/src/bin/scarb/commands/init.rs b/scarb/src/bin/scarb/commands/init.rs index bb8d9e46d..bc965746a 100644 --- a/scarb/src/bin/scarb/commands/init.rs +++ b/scarb/src/bin/scarb/commands/init.rs @@ -1,15 +1,16 @@ use std::env; -use anyhow::{anyhow, Result}; +use anyhow::anyhow; use camino::Utf8PathBuf; use scarb::core::Config; use scarb::ops::{self, VersionControl}; use crate::args::InitArgs; +use crate::errors::ScarbResult; #[tracing::instrument(skip_all, level = "info")] -pub fn run(args: InitArgs, config: &Config) -> Result<()> { +pub fn run(args: InitArgs, config: &Config) -> ScarbResult<()> { let path = Utf8PathBuf::from_path_buf(env::current_dir()?) .map_err(|path| anyhow!("path `{}` is not UTF-8 encoded", path.display()))?; diff --git a/scarb/src/bin/scarb/commands/manifest_path.rs b/scarb/src/bin/scarb/commands/manifest_path.rs index 068ef055b..bbfd2d53a 100644 --- a/scarb/src/bin/scarb/commands/manifest_path.rs +++ b/scarb/src/bin/scarb/commands/manifest_path.rs @@ -1,10 +1,9 @@ -use anyhow::Result; - +use crate::errors::ScarbResult; use scarb::core::Config; use scarb::ui::ValueMessage; #[tracing::instrument(skip_all, level = "info")] -pub fn run(config: &Config) -> Result<()> { +pub fn run(config: &Config) -> ScarbResult<()> { let canonical = dunce::canonicalize(config.manifest_path()) .unwrap_or_else(|_| config.manifest_path().into()); let canonical = canonical.to_string_lossy(); diff --git a/scarb/src/bin/scarb/commands/metadata.rs b/scarb/src/bin/scarb/commands/metadata.rs index 91dc8bd04..5bf470d61 100644 --- a/scarb/src/bin/scarb/commands/metadata.rs +++ b/scarb/src/bin/scarb/commands/metadata.rs @@ -1,14 +1,13 @@ -use anyhow::Result; - use scarb::core::Config; use scarb::metadata::{Metadata, MetadataOptions}; use scarb::ops; use scarb::ui::MachineMessage; use crate::args::MetadataArgs; +use crate::errors::ScarbResult; #[tracing::instrument(skip_all, level = "info")] -pub fn run(args: MetadataArgs, config: &Config) -> Result<()> { +pub fn run(args: MetadataArgs, config: &Config) -> ScarbResult<()> { let ws = ops::read_workspace(config.manifest_path(), config)?; let opts = MetadataOptions { diff --git a/scarb/src/bin/scarb/commands/mod.rs b/scarb/src/bin/scarb/commands/mod.rs index f9d1f1fef..7daff064d 100644 --- a/scarb/src/bin/scarb/commands/mod.rs +++ b/scarb/src/bin/scarb/commands/mod.rs @@ -1,10 +1,9 @@ #![allow(clippy::module_inception)] -use anyhow::Result; - use scarb::core::Config; use crate::args::Command; +use crate::errors::ScarbResult; pub mod add; pub mod build; @@ -18,7 +17,7 @@ pub mod metadata; pub mod new; pub mod remove; -pub fn run(command: Command, config: &mut Config) -> Result<()> { +pub fn run(command: Command, config: &mut Config) -> ScarbResult<()> { use Command::*; match command { diff --git a/scarb/src/bin/scarb/commands/new.rs b/scarb/src/bin/scarb/commands/new.rs index 1439bdd34..0dfa22b0c 100644 --- a/scarb/src/bin/scarb/commands/new.rs +++ b/scarb/src/bin/scarb/commands/new.rs @@ -1,12 +1,11 @@ -use anyhow::Result; - use scarb::core::Config; use scarb::ops::{self, VersionControl}; use crate::args::NewArgs; +use crate::errors::ScarbResult; #[tracing::instrument(skip_all, level = "info")] -pub fn run(args: NewArgs, config: &Config) -> Result<()> { +pub fn run(args: NewArgs, config: &Config) -> ScarbResult<()> { let result = ops::new_package( ops::InitOptions { name: args.init.name, diff --git a/scarb/src/bin/scarb/commands/remove.rs b/scarb/src/bin/scarb/commands/remove.rs index 2969a4d26..3c6b2083c 100644 --- a/scarb/src/bin/scarb/commands/remove.rs +++ b/scarb/src/bin/scarb/commands/remove.rs @@ -1,13 +1,14 @@ -use anyhow::{anyhow, Result}; +use anyhow::anyhow; use scarb::core::{Config, PackageName}; use scarb::manifest_editor::{EditManifestOptions, Op, RemoveDependency}; use scarb::{manifest_editor, ops}; use crate::args::RemoveArgs; +use crate::errors::ScarbResult; #[tracing::instrument(skip_all, level = "info")] -pub fn run(args: RemoveArgs, config: &mut Config) -> Result<()> { +pub fn run(args: RemoveArgs, config: &mut Config) -> ScarbResult<()> { let ws = ops::read_workspace(config.manifest_path(), config)?; // TODO(#127): Extract more generic pattern for this. See `Packages` struct in Cargo. diff --git a/scarb/src/bin/scarb/main.rs b/scarb/src/bin/scarb/main.rs index 898b30337..9c15df45f 100644 --- a/scarb/src/bin/scarb/main.rs +++ b/scarb/src/bin/scarb/main.rs @@ -1,10 +1,11 @@ use std::env; -use anyhow::Result; use clap::Parser; +use tracing::debug; use tracing_log::AsTrace; use tracing_subscriber::EnvFilter; +use crate::errors::{ErrorWithExitCode, ScarbResult}; use args::ScarbArgs; use scarb::core::Config; use scarb::ops; @@ -12,6 +13,7 @@ use scarb::ui::Ui; mod args; mod commands; +mod errors; fn main() { let args = ScarbArgs::parse(); @@ -30,12 +32,21 @@ fn main() { let ui = Ui::new(args.ui_verbosity(), args.output_format()); if let Err(err) = cli_main(args) { - ui.anyhow(&err); - std::process::exit(1); + exit_with_error(err, &ui); } } -fn cli_main(args: ScarbArgs) -> Result<()> { +fn exit_with_error(err: ErrorWithExitCode, ui: &Ui) { + debug!("exit_with_error; err={:?}", err); + + let ErrorWithExitCode { source, exit_code } = err; + if let Some(source_err) = source { + ui.anyhow(&source_err); + } + std::process::exit(exit_code); +} + +fn cli_main(args: ScarbArgs) -> ScarbResult<()> { let ui_verbosity = args.ui_verbosity(); let ui_output_format = args.output_format();