Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/bin/bender.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

fn main() {
if let Err(e) = bender::cli::main() {
bender::errorln!("{}", e);
eprintln!("{e:?}");
std::process::exit(1);
}
}
118 changes: 59 additions & 59 deletions src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,18 +17,20 @@ use dunce::canonicalize;
use clap::builder::styling::{AnsiColor, Effects, Styles};
use clap::{ArgAction, CommandFactory, Parser, Subcommand, value_parser};
use indexmap::IndexSet;
use miette::{Context as _, IntoDiagnostic as _};
use serde_yaml_ng;
use tokio::runtime::Runtime;

use crate::Result;
use crate::cmd;
use crate::cmd::fusesoc::FusesocArgs;
use crate::config::{
Config, Manifest, Merge, PartialConfig, PrefixPaths, Validate, ValidationContext,
};
use crate::diagnostic::{Diagnostics, Warnings};
use crate::error::*;
use crate::diagnostic::{Diagnostics, ENABLE_DEBUG, Warnings};
use crate::lockfile::*;
use crate::sess::{Session, SessionArenas, SessionIo};
use crate::{bail, err};
use crate::{debugln, fmt_path, fmt_pkg, stageln};

#[derive(Parser, Debug)]
Expand Down Expand Up @@ -169,11 +171,12 @@ pub fn main() -> Result<()> {
// the -d/--dir switch, or by searching upwards in the file system
// hierarchy.
let root_dir: PathBuf = match &cli.dir {
Some(d) => canonicalize(d).map_err(|cause| {
Error::chain(format!("Failed to canonicalize path {:?}.", d), cause)
})?,
None => find_package_root(Path::new("."))
.map_err(|cause| Error::chain("Cannot find root directory of package.", cause))?,
Some(d) => canonicalize(d)
.into_diagnostic()
.wrap_err_with(|| format!("Failed to canonicalize path {:?}.", d))?,
None => {
find_package_root(Path::new(".")).wrap_err("Cannot find root directory of package.")?
}
};
debugln!("main: root dir {:?}", root_dir);

Expand Down Expand Up @@ -242,7 +245,7 @@ pub fn main() -> Result<()> {

// Checkout if we are running update or package path does not exist yet
if matches!(cli.command, Commands::Update(_)) || !pkg_path.clone().exists() {
let rt = Runtime::new()?;
let rt = Runtime::new().into_diagnostic()?;
rt.block_on(io.checkout(sess.dependency_with_name(pkg_name)?, false, &[]))?;
}

Expand All @@ -255,33 +258,28 @@ pub fn main() -> Result<()> {
// Check if there is something at the destination path that needs to be
// removed.
if path.exists() {
let meta = path.symlink_metadata().map_err(|cause| {
Error::chain(
format!("Failed to read metadata of path {:?}.", path),
cause,
)
})?;
let meta = path
.symlink_metadata()
.into_diagnostic()
.wrap_err_with(|| format!("Failed to read metadata of path {:?}.", path))?;
if !meta.file_type().is_symlink() {
Warnings::SkippingPackageLink(pkg_name.clone(), path.clone()).emit();
continue;
}
if path.read_link().map(|d| d != pkg_path).unwrap_or(true) {
debugln!("main: removing existing link {:?}", path);
remove_symlink_dir(path).map_err(|cause| {
Error::chain(
format!("Failed to remove symlink at path {:?}.", path),
cause,
)
remove_symlink_dir(path).wrap_err_with(|| {
format!("Failed to remove symlink at path {:?}.", path)
})?;
}
}

// Create the symlink if there is nothing at the destination.
if !path.exists() {
if let Some(parent) = path.parent() {
std::fs::create_dir_all(parent).map_err(|cause| {
Error::chain(format!("Failed to create directory {:?}.", parent), cause)
})?;
std::fs::create_dir_all(parent)
.into_diagnostic()
.wrap_err_with(|| format!("Failed to create directory {:?}.", parent))?;
}
let previous_dir = match path.parent() {
Some(parent) => {
Expand All @@ -291,13 +289,10 @@ pub fn main() -> Result<()> {
}
None => None,
};
symlink_dir(&pkg_path, path).map_err(|cause| {
Error::chain(
format!(
"Failed to create symlink to {:?} at path {:?}.",
pkg_path, path
),
cause,
symlink_dir(&pkg_path, path).wrap_err_with(|| {
format!(
"Failed to create symlink to {:?} at path {:?}.",
pkg_path, path
)
})?;
if let Some(d) = previous_dir {
Expand Down Expand Up @@ -332,7 +327,7 @@ pub fn main() -> Result<()> {
Commands::Plugin(args) => {
let (plugin_name, plugin_args) = args
.split_first()
.ok_or_else(|| Error::new("No command specified.".to_string()))?;
.ok_or_else(|| err!("No command specified."))?;
execute_plugin(&sess, plugin_name, plugin_args)
}
Commands::Completion(_) | Commands::Init | Commands::Clean(_) => {
Expand All @@ -343,22 +338,22 @@ pub fn main() -> Result<()> {

#[cfg(unix)]
pub fn symlink_dir(p: &Path, q: &Path) -> Result<()> {
Ok(std::os::unix::fs::symlink(p, q)?)
std::os::unix::fs::symlink(p, q).into_diagnostic()
}

#[cfg(windows)]
pub fn symlink_dir(p: &Path, q: &Path) -> Result<()> {
Ok(std::os::windows::fs::symlink_dir(p, q)?)
std::os::windows::fs::symlink_dir(p, q).into_diagnostic()
}

#[cfg(unix)]
pub fn remove_symlink_dir(path: &Path) -> Result<()> {
Ok(std::fs::remove_file(path)?)
std::fs::remove_file(path).into_diagnostic()
}

#[cfg(windows)]
pub fn remove_symlink_dir(path: &Path) -> Result<()> {
Ok(std::fs::remove_dir(path)?)
std::fs::remove_dir(path).into_diagnostic()
}

/// Find the root directory of a package.
Expand All @@ -370,7 +365,8 @@ fn find_package_root(from: &Path) -> Result<PathBuf> {

// Canonicalize the path. This will resolve any intermediate links.
let mut path = canonicalize(from)
.map_err(|cause| Error::chain(format!("Failed to canonicalize path {:?}.", from), cause))?;
.into_diagnostic()
.wrap_err_with(|| format!("Failed to canonicalize path {:?}.", from))?;
debugln!("find_package_root: canonicalized to {:?}", path);

// Look up the device at the current path. This information will then be
Expand All @@ -391,10 +387,10 @@ fn find_package_root(from: &Path) -> Result<PathBuf> {

// Abort if we have reached the filesystem root.
if !path.pop() {
return Err(Error::new(format!(
bail!(
"No manifest (`Bender.yml` file) found. Stopped searching at filesystem root {:?}.",
path
)));
);
}

// Abort if we have crossed the filesystem boundary.
Expand All @@ -403,15 +399,15 @@ fn find_package_root(from: &Path) -> Result<PathBuf> {
let rdev: Option<_> = metadata(&path).map(|m| m.dev()).ok();
debugln!("find_package_root: rdev = {:?}", rdev);
if rdev != limit_rdev {
return Err(Error::new(format!(
bail!(
"No manifest (`Bender.yml` file) found. Stopped searching at filesystem boundary {:?}.",
path
)));
);
}
}
}

Err(Error::new(
Err(err!(
"No manifest (`Bender.yml` file) found. Reached maximum number of search steps.",
))
}
Expand All @@ -422,14 +418,16 @@ pub fn read_manifest(path: &Path) -> Result<Manifest> {
use std::fs::File;
debugln!("read_manifest: {:?}", path);
let file = File::open(path)
.map_err(|cause| Error::chain(format!("Cannot open manifest {:?}.", path), cause))?;
.into_diagnostic()
.wrap_err_with(|| format!("Cannot open manifest {:?}.", path))?;
let partial: PartialManifest = serde_yaml_ng::from_reader(file)
.map_err(|cause| Error::chain(format!("Syntax error in manifest {:?}.", path), cause))?;
.into_diagnostic()
.wrap_err_with(|| format!("Syntax error in manifest {:?}.", path))?;
partial
.prefix_paths(path.parent().unwrap())
.map_err(|cause| Error::chain(format!("Error in manifest prefixing {:?}.", path), cause))?
.wrap_err_with(|| format!("Error in manifest prefixing {:?}.", path))?
.validate(&ValidationContext::default())
.map_err(|cause| Error::chain(format!("Error in manifest {:?}.", path), cause))
.wrap_err_with(|| format!("Error in manifest {:?}.", path))
}

/// Load a configuration by traversing a directory hierarchy upwards.
Expand All @@ -441,7 +439,8 @@ fn load_config(from: &Path, warn_config_loaded: bool) -> Result<Config> {

// Canonicalize the path. This will resolve any intermediate links.
let mut path = canonicalize(from)
.map_err(|cause| Error::chain(format!("Failed to canonicalize path {:?}.", from), cause))?;
.into_diagnostic()
.wrap_err_with(|| format!("Failed to canonicalize path {:?}.", from))?;
debugln!("load_config: canonicalized to {:?}", path);

// Look up the device at the current path. This information will then be
Expand Down Expand Up @@ -508,7 +507,7 @@ fn load_config(from: &Path, warn_config_loaded: bool) -> Result<Config> {
// Validate the configuration.
let mut out = out
.validate(&ValidationContext::default())
.map_err(|cause| Error::chain("Invalid configuration:", cause))?;
.wrap_err("Invalid configuration:")?;

out.overrides = out
.overrides
Expand All @@ -527,9 +526,11 @@ fn maybe_load_config(path: &Path, warn_config_loaded: bool) -> Result<Option<Par
return Ok(None);
}
let file = File::open(path)
.map_err(|cause| Error::chain(format!("Cannot open config {:?}.", path), cause))?;
.into_diagnostic()
.wrap_err_with(|| format!("Cannot open config {:?}.", path))?;
let partial: PartialConfig = serde_yaml_ng::from_reader(file)
.map_err(|cause| Error::chain(format!("Syntax error in config {:?}.", path), cause))?;
.into_diagnostic()
.wrap_err_with(|| format!("Syntax error in config {:?}.", path))?;
if warn_config_loaded {
Warnings::UsingConfigForOverride {
path: path.to_path_buf(),
Expand All @@ -544,14 +545,14 @@ fn execute_plugin(sess: &Session, plugin: &str, args: &[String]) -> Result<()> {
debugln!("main: execute plugin `{}`", plugin);

// Obtain a list of declared plugins.
let runtime = Runtime::new()?;
let runtime = Runtime::new().into_diagnostic()?;
let io = SessionIo::new(sess);
let plugins = runtime.block_on(io.plugins(false))?;

// Lookup the requested plugin and complain if it does not exist.
let plugin = match plugins.get(plugin) {
Some(p) => p,
None => return Err(Error::new(format!("Unknown command `{}`.", plugin))),
None => bail!("Unknown command `{}`.", plugin),
};
debugln!("main: found plugin {:#?}", plugin);

Expand All @@ -561,25 +562,24 @@ fn execute_plugin(sess: &Session, plugin: &str, args: &[String]) -> Result<()> {
cmd.env(
"BENDER",
std::env::current_exe()
.map_err(|cause| Error::chain("Failed to determine current executable.", cause))?,
.into_diagnostic()
.wrap_err("Failed to determine current executable.")?,
);
cmd.env(
"BENDER_CALL_DIR",
std::env::current_dir()
.map_err(|cause| Error::chain("Failed to determine current directory.", cause))?,
.into_diagnostic()
.wrap_err("Failed to determine current directory.")?,
);
cmd.env("BENDER_MANIFEST_DIR", sess.root);
cmd.current_dir(sess.root);
cmd.args(args);

debugln!("main: executing plugin {:#?}", cmd);
let stat = cmd.status().map_err(|cause| {
Error::chain(
format!(
"Unable to spawn process for plugin `{}`. Command was {:#?}.",
plugin.name, cmd
),
cause,
let stat = cmd.status().into_diagnostic().wrap_err_with(|| {
format!(
"Unable to spawn process for plugin `{}`. Command was {:#?}.",
plugin.name, cmd
)
})?;

Expand Down
5 changes: 3 additions & 2 deletions src/cmd/audit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,13 @@ use std::io::Write;

use clap::Args;
use futures::future::join_all;
use miette::IntoDiagnostic as _;
use semver::VersionReq;
use tabwriter::TabWriter;
use tokio::runtime::Runtime;

use crate::Result;
use crate::cmd::parents::get_parent_array;
use crate::error::*;
use crate::sess::{DependencyVersions, Session, SessionIo};

/// Get information about version conflicts and possible updates.
Expand All @@ -34,7 +35,7 @@ pub struct AuditArgs {

/// Execute the `audit` subcommand.
pub fn run(sess: &Session, args: &AuditArgs) -> Result<()> {
let rt = Runtime::new()?;
let rt = Runtime::new().into_diagnostic()?;
let io = SessionIo::new(sess);

let binding = sess.packages().clone();
Expand Down
5 changes: 3 additions & 2 deletions src/cmd/checkout.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@
//! The `checkout` subcommand.

use clap::Args;
use miette::IntoDiagnostic as _;
use tokio::runtime::Runtime;

use crate::error::*;
use crate::Result;
use crate::fmt_dim;
use crate::infoln;
use crate::sess::{Session, SessionIo};
Expand All @@ -27,7 +28,7 @@ pub fn run(sess: &Session, args: &CheckoutArgs) -> Result<()> {

/// Execute a checkout (for the `checkout` subcommand).
pub fn run_plain(sess: &Session, force: bool, update_list: &[String]) -> Result<()> {
let rt = Runtime::new()?;
let rt = Runtime::new().into_diagnostic()?;
let io = SessionIo::new(sess);
let start_time = std::time::Instant::now();
let _srcs = rt.block_on(io.sources(force, update_list))?;
Expand Down
Loading