Migrate from the failure crate to anyhow

The `anyhow` crate interoperates with the `std::error::Error` trait
rather than a custom `Fail` trait, and this is the general trend of
error handling in Rust as well.

Note that this is mostly mechanical (sed) and intended to get the test
suite passing. As usual there's still more idiomatic cleanup that can
happen, but that's left to later commits.
This commit is contained in:
Alex Crichton 2020-01-07 14:30:15 -08:00
parent 7059559d71
commit 3a18c89a55
94 changed files with 427 additions and 436 deletions

View file

@ -29,7 +29,7 @@ curl = { version = "0.4.23", features = ["http2"] }
curl-sys = "0.4.22"
env_logger = "0.7.0"
pretty_env_logger = { version = "0.3", optional = true }
failure = "0.1.5"
anyhow = "1.0"
filetime = "0.2"
flate2 = { version = "1.0.3", features = ["zlib"] }
fs2 = "0.4"
@ -51,7 +51,7 @@ num_cpus = "1.0"
opener = "0.4"
percent-encoding = "2.0"
remove_dir_all = "0.5.2"
rustfix = "0.4.6"
rustfix = "0.5.0"
same-file = "1"
semver = { version = "0.9.0", features = ["serde"] }
serde = { version = "1.0.82", features = ["derive"] }

View file

@ -916,11 +916,7 @@ impl Execs {
{
return self.match_output(out);
}
let mut s = format!("could not exec process {}: {}", process, e);
for cause in e.iter_causes() {
s.push_str(&format!("\ncaused by: {}", cause));
}
Err(s)
Err(format!("could not exec process {}: {:?}", process, e))
}
}
}

View file

@ -15,7 +15,7 @@ path = "lib.rs"
[dependencies]
curl = "0.4"
failure = "0.1.1"
anyhow = "1.0.0"
percent-encoding = "2.0"
serde = { version = "1.0", features = ['derive'] }
serde_derive = "1.0"

View file

@ -8,14 +8,12 @@ use std::io::Cursor;
use std::time::Instant;
use curl::easy::{Easy, List};
use failure::bail;
use anyhow::{bail, Result};
use percent_encoding::{percent_encode, NON_ALPHANUMERIC};
use serde::{Deserialize, Serialize};
use serde_json;
use url::Url;
pub type Result<T> = std::result::Result<T, failure::Error>;
pub struct Registry {
/// The base URL for issuing API requests.
host: String,

View file

@ -100,7 +100,7 @@ pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult {
match err {
None => Ok(()),
Some(err) => Err(match err.exit.as_ref().and_then(|e| e.code()) {
Some(i) => CliError::new(failure::format_err!("bench failed"), i),
Some(i) => CliError::new(anyhow::format_err!("bench failed"), i),
None => CliError::new(err.into(), 101),
}),
}

View file

@ -60,7 +60,7 @@ pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult {
Some("test") => true,
None => false,
Some(profile) => {
let err = failure::format_err!(
let err = anyhow::format_err!(
"unknown profile: `{}`, only `test` is \
currently supported",
profile

View file

@ -66,7 +66,7 @@ pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult {
args.compile_options(config, mode, Some(&ws), ProfileChecking::Checked)?;
if !config.cli_unstable().unstable_options {
return Err(failure::format_err!(
return Err(anyhow::format_err!(
"`clippy-preview` is unstable, pass `-Z unstable-options` to enable it"
)
.into());

View file

@ -120,7 +120,7 @@ pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult {
Some("test") => true,
None => false,
Some(profile) => {
let err = failure::format_err!(
let err = anyhow::format_err!(
"unknown profile: `{}`, only `test` is \
currently supported",
profile
@ -143,7 +143,7 @@ pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult {
.filter(|_| use_clippy);
if use_clippy && !config.cli_unstable().unstable_options {
return Err(failure::format_err!(
return Err(anyhow::format_err!(
"`cargo fix --clippy` is unstable, pass `-Z unstable-options` to enable it"
)
.into());

View file

@ -21,7 +21,7 @@ pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult {
let root = root
.to_str()
.ok_or_else(|| {
failure::format_err!(
anyhow::format_err!(
"your package path contains characters \
not representable in Unicode"
)

View file

@ -55,7 +55,7 @@ pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult {
Some("bench") => CompileMode::Bench,
Some("check") => CompileMode::Check { test: false },
Some(mode) => {
let err = failure::format_err!(
let err = anyhow::format_err!(
"unknown profile: `{}`, use dev,
test, or bench",
mode

View file

@ -1,7 +1,7 @@
use crate::command_prelude::*;
use anyhow::Error;
use cargo::ops::{self, CompileFilter, FilterRule, LibRule};
use cargo::util::errors;
use failure::Fail;
pub fn cli() -> App {
subcommand("test")
@ -126,13 +126,13 @@ pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult {
if doc {
if let CompileFilter::Only { .. } = compile_opts.filter {
return Err(CliError::new(
failure::format_err!("Can't mix --doc with other target selecting options"),
anyhow::format_err!("Can't mix --doc with other target selecting options"),
101,
));
}
if no_run {
return Err(CliError::new(
failure::format_err!("Can't skip running doc tests with --no-run"),
anyhow::format_err!("Can't skip running doc tests with --no-run"),
101,
));
}
@ -166,12 +166,12 @@ pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult {
match err {
None => Ok(()),
Some(err) => {
let context = failure::format_err!("{}", err.hint(&ws, &ops.compile_opts));
let context = anyhow::format_err!("{}", err.hint(&ws, &ops.compile_opts));
let e = match err.exit.as_ref().and_then(|e| e.code()) {
// Don't show "process didn't exit successfully" for simple errors.
Some(i) if errors::is_simple_exit_code(i) => CliError::new(context, i),
Some(i) => CliError::new(err.context(context).into(), i),
None => CliError::new(err.context(context).into(), 101),
Some(i) => CliError::new(Error::from(err).context(context), i),
None => CliError::new(Error::from(err).context(context), 101),
};
Err(e)
}

View file

@ -90,7 +90,7 @@ pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult {
None
};
if let Some(flag) = crates_io_cargo_vendor_flag {
return Err(failure::format_err!(
return Err(anyhow::format_err!(
"\
the crates.io `cargo vendor` command has now been merged into Cargo itself
and does not support the flag `{}` currently; to continue using the flag you

View file

@ -133,7 +133,7 @@ fn execute_external_subcommand(config: &Config, cmd: &str, args: &[&str]) -> Cli
let aliases = list_aliases(config);
let suggestions = commands.iter().chain(aliases.iter());
let did_you_mean = closest_msg(cmd, suggestions, |c| c);
let err = failure::format_err!("no such subcommand: `{}`{}", cmd, did_you_mean);
let err = anyhow::format_err!("no such subcommand: `{}`{}", cmd, did_you_mean);
return Err(CliError::new(err, 101));
}
};

View file

@ -78,7 +78,7 @@ impl BuildConfig {
};
if jobs == Some(0) {
failure::bail!("jobs must be at least 1")
anyhow::bail!("jobs must be at least 1")
}
if jobs.is_some() && config.jobserver_from_env().is_some() {
config.shell().warn(

View file

@ -137,7 +137,7 @@ impl TargetInfo {
let line = match lines.next() {
Some(line) => line,
None => failure::bail!(
None => anyhow::bail!(
"output of --print=sysroot missing when learning about \
target-specific information from rustc\n{}",
output_err_info(&process, &output, &error)
@ -329,7 +329,7 @@ fn parse_crate_type(
}
let line = match lines.next() {
Some(line) => line,
None => failure::bail!(
None => anyhow::bail!(
"malformed output when learning about crate-type {} information\n{}",
crate_type,
output_err_info(cmd, output, error)
@ -339,7 +339,7 @@ fn parse_crate_type(
let prefix = parts.next().unwrap();
let suffix = match parts.next() {
Some(part) => part,
None => failure::bail!(
None => anyhow::bail!(
"output of --print=file-names has changed in the compiler, cannot parse\n{}",
output_err_info(cmd, output, error)
),

View file

@ -74,13 +74,13 @@ impl Invocation {
self.program = cmd
.get_program()
.to_str()
.ok_or_else(|| failure::format_err!("unicode program string required"))?
.ok_or_else(|| anyhow::format_err!("unicode program string required"))?
.to_string();
self.cwd = Some(cmd.get_cwd().unwrap().to_path_buf());
for arg in cmd.get_args().iter() {
self.args.push(
arg.to_str()
.ok_or_else(|| failure::format_err!("unicode argument string required"))?
.ok_or_else(|| anyhow::format_err!("unicode argument string required"))?
.to_string(),
);
}
@ -93,7 +93,7 @@ impl Invocation {
var.clone(),
value
.to_str()
.ok_or_else(|| failure::format_err!("unicode environment value required"))?
.ok_or_else(|| anyhow::format_err!("unicode environment value required"))?
.to_string(),
);
}

View file

@ -304,7 +304,7 @@ fn target_runner(
.filter(|(key, _runner)| CfgExpr::matches_key(key, target_cfg));
let matching_runner = cfgs.next();
if let Some((key, runner)) = cfgs.next() {
failure::bail!(
anyhow::bail!(
"several matching instances of `target.'cfg(..)'.runner` in `.cargo/config`\n\
first match `{}` located in {}\n\
second match `{}` located in {}",

View file

@ -77,7 +77,7 @@ impl CompileTarget {
pub fn new(name: &str) -> CargoResult<CompileTarget> {
let name = name.trim();
if name.is_empty() {
failure::bail!("target was empty");
anyhow::bail!("target was empty");
}
if !name.ends_with(".json") {
return Ok(CompileTarget { name: name.into() });
@ -88,12 +88,12 @@ impl CompileTarget {
// with different paths always produce the same result.
let path = Path::new(name)
.canonicalize()
.chain_err(|| failure::format_err!("target path {:?} is not a valid file", name))?;
.chain_err(|| anyhow::format_err!("target path {:?} is not a valid file", name))?;
let name = path
.into_os_string()
.into_string()
.map_err(|_| failure::format_err!("target path is not valid unicode"))?;
.map_err(|_| anyhow::format_err!("target path is not valid unicode"))?;
Ok(CompileTarget { name: name.into() })
}

View file

@ -431,7 +431,7 @@ impl<'a, 'cfg: 'a> CompilationFiles<'a, 'cfg> {
}
if ret.is_empty() {
if !unsupported.is_empty() {
failure::bail!(
anyhow::bail!(
"cannot produce {} for `{}` as the target `{}` \
does not support these crate types",
unsupported.join(", "),
@ -439,7 +439,7 @@ impl<'a, 'cfg: 'a> CompilationFiles<'a, 'cfg> {
unit.kind.short_name(bcx),
)
}
failure::bail!(
anyhow::bail!(
"cannot compile `{}` as the target `{}` does not \
support any of the output crate types",
unit.pkg,

View file

@ -460,7 +460,7 @@ impl BuildOutput {
let (key, value) = match (key, value) {
(Some(a), Some(b)) => (a, b.trim_end()),
// Line started with `cargo:` but didn't match `key=value`.
_ => failure::bail!("Wrong output in {}: `{}`", whence, line),
_ => anyhow::bail!("Wrong output in {}: `{}`", whence, line),
};
// This will rewrite paths if the target directory has been moved.
@ -520,7 +520,7 @@ impl BuildOutput {
if value.is_empty() {
value = match flags_iter.next() {
Some(v) => v,
None => failure::bail! {
None => anyhow::bail! {
"Flag in rustc-flags has no value in {}: {}",
whence,
value
@ -536,7 +536,7 @@ impl BuildOutput {
_ => unreachable!(),
};
} else {
failure::bail!(
anyhow::bail!(
"Only `-l` and `-L` flags are allowed in {}: `{}`",
whence,
value
@ -552,7 +552,7 @@ impl BuildOutput {
let val = iter.next();
match (name, val) {
(Some(n), Some(v)) => Ok((n.to_owned(), v.to_owned())),
_ => failure::bail!("Variable rustc-env has no value in {}: {}", whence, value),
_ => anyhow::bail!("Variable rustc-env has no value in {}: {}", whence, value),
}
}
}

View file

@ -194,7 +194,7 @@ use std::path::{Path, PathBuf};
use std::sync::{Arc, Mutex};
use std::time::SystemTime;
use failure::{bail, format_err};
use anyhow::{bail, format_err};
use filetime::FileTime;
use log::{debug, info};
use serde::de;
@ -1414,11 +1414,7 @@ fn log_compare(unit: &Unit<'_>, compare: &CargoResult<()>) {
"fingerprint error for {}/{:?}/{:?}",
unit.pkg, unit.mode, unit.target,
);
info!(" err: {}", ce);
for cause in ce.iter_causes() {
info!(" cause: {}", cause);
}
info!(" err: {:?}", ce);
}
// Parse the dep-info into a list of paths

View file

@ -7,8 +7,8 @@ use std::sync::mpsc::{channel, Receiver, Sender};
use std::sync::Arc;
use std::time::Duration;
use anyhow::format_err;
use crossbeam_utils::thread::Scope;
use failure::format_err;
use jobserver::{Acquired, HelperThread};
use log::{debug, info, trace};
@ -393,7 +393,7 @@ impl<'a, 'cfg> JobQueue<'a, 'cfg> {
self.emit_warnings(Some(msg), &unit, cx)?;
if !self.active.is_empty() {
error = Some(failure::format_err!("build failed"));
error = Some(anyhow::format_err!("build failed"));
handle_error(&e, &mut *cx.bcx.config.shell());
cx.bcx.config.shell().warn(
"build failed, waiting for other \

View file

@ -39,7 +39,7 @@ pub fn validate_links(resolve: &Resolve, unit_graph: &UnitGraph<'_>) -> CargoRes
dep_path_desc
};
failure::bail!(
anyhow::bail!(
"multiple packages link to native library `{}`, \
but a native library can be linked only once\n\
\n\

View file

@ -23,7 +23,7 @@ use std::io::{BufRead, Write};
use std::path::PathBuf;
use std::sync::Arc;
use failure::Error;
use anyhow::Error;
use lazycell::LazyCell;
use log::debug;

View file

@ -161,12 +161,12 @@ fn detect_sysroot_src_path(ws: &Workspace<'_>) -> CargoResult<PathBuf> {
let rustc = ws.config().load_global_rustc(Some(ws))?;
let output = rustc.process().arg("--print=sysroot").exec_with_output()?;
let s = String::from_utf8(output.stdout)
.map_err(|e| failure::format_err!("rustc didn't return utf8 output: {:?}", e))?;
.map_err(|e| anyhow::format_err!("rustc didn't return utf8 output: {:?}", e))?;
let sysroot = PathBuf::from(s.trim());
let src_path = sysroot.join("lib").join("rustlib").join("src").join("rust");
let lock = src_path.join("Cargo.lock");
if !lock.exists() {
failure::bail!(
anyhow::bail!(
"{:?} does not exist, unable to build with the standard \
library, try:\n rustup component add rust-src",
lock

View file

@ -50,7 +50,7 @@ use std::env;
use std::fmt;
use std::str::FromStr;
use failure::{bail, Error};
use anyhow::{bail, Error};
use serde::{Deserialize, Serialize};
use crate::util::errors::CargoResult;

View file

@ -514,7 +514,7 @@ impl Manifest {
self.features
.require(Feature::test_dummy_unstable())
.chain_err(|| {
failure::format_err!(
anyhow::format_err!(
"the `im-a-teapot` manifest key is unstable and may \
not work properly in England"
)

View file

@ -7,10 +7,10 @@ use std::mem;
use std::path::{Path, PathBuf};
use std::time::{Duration, Instant};
use anyhow::Context;
use bytesize::ByteSize;
use curl::easy::{Easy, HttpVersion};
use curl::multi::{EasyHandle, Multi};
use failure::ResultExt;
use lazycell::LazyCell;
use log::{debug, warn};
use semver::Version;
@ -485,8 +485,8 @@ macro_rules! try_old_curl {
warn!("ignoring libcurl {} error: {}", $msg, e);
}
} else {
result.with_context(|_| {
failure::format_err!("failed to enable {}, is curl not built right?", $msg)
result.with_context(|| {
anyhow::format_err!("failed to enable {}, is curl not built right?", $msg)
})?;
}
};
@ -525,7 +525,7 @@ impl<'a, 'cfg> Downloads<'a, 'cfg> {
.ok_or_else(|| internal(format!("couldn't find source for `{}`", id)))?;
let pkg = source
.download(id)
.chain_err(|| failure::format_err!("unable to get packages from source"))?;
.chain_err(|| anyhow::format_err!("unable to get packages from source"))?;
let (url, descriptor) = match pkg {
MaybePackage::Ready(pkg) => {
debug!("{} doesn't need a download", id);

View file

@ -79,7 +79,7 @@ impl PackageIdSpec {
I: IntoIterator<Item = PackageId>,
{
let spec = PackageIdSpec::parse(spec)
.chain_err(|| failure::format_err!("invalid package ID specification: `{}`", spec))?;
.chain_err(|| anyhow::format_err!("invalid package ID specification: `{}`", spec))?;
spec.query(i)
}
@ -96,16 +96,16 @@ impl PackageIdSpec {
/// Tries to convert a valid `Url` to a `PackageIdSpec`.
fn from_url(mut url: Url) -> CargoResult<PackageIdSpec> {
if url.query().is_some() {
failure::bail!("cannot have a query string in a pkgid: {}", url)
anyhow::bail!("cannot have a query string in a pkgid: {}", url)
}
let frag = url.fragment().map(|s| s.to_owned());
url.set_fragment(None);
let (name, version) = {
let mut path = url
.path_segments()
.ok_or_else(|| failure::format_err!("pkgid urls must have a path: {}", url))?;
.ok_or_else(|| anyhow::format_err!("pkgid urls must have a path: {}", url))?;
let path_name = path.next_back().ok_or_else(|| {
failure::format_err!(
anyhow::format_err!(
"pkgid urls must have at least one path \
component: {}",
url
@ -183,7 +183,7 @@ impl PackageIdSpec {
let mut ids = i.into_iter().filter(|p| self.matches(*p));
let ret = match ids.next() {
Some(id) => id,
None => failure::bail!(
None => anyhow::bail!(
"package ID specification `{}` \
matched no packages",
self
@ -204,7 +204,7 @@ impl PackageIdSpec {
let mut vec = vec![ret, other];
vec.extend(ids);
minimize(&mut msg, &vec, self);
Err(failure::format_err!("{}", msg))
Err(anyhow::format_err!("{}", msg))
}
None => Ok(ret),
};

View file

@ -240,7 +240,7 @@ impl Profiles {
match &profile.inherits {
None => {}
Some(_) => {
failure::bail!(
anyhow::bail!(
"An 'inherits' must not specified root profile '{}'",
name
);
@ -278,7 +278,7 @@ impl Profiles {
Some(name) => {
let name = name.to_owned();
if set.get(&name).is_some() {
failure::bail!(
anyhow::bail!(
"Inheritance loop of profiles cycles with profile '{}'",
name
);
@ -287,13 +287,13 @@ impl Profiles {
set.insert(name.clone());
match profiles.get(&name) {
None => {
failure::bail!("Profile '{}' not found in Cargo.toml", name);
anyhow::bail!("Profile '{}' not found in Cargo.toml", name);
}
Some(parent) => self.process_chain(&name, parent, set, result, profiles),
}
}
None => {
failure::bail!(
anyhow::bail!(
"An 'inherits' directive is needed for all \
profiles that are not 'dev' or 'release'. Here \
it is missing from '{}'",
@ -415,7 +415,7 @@ impl Profiles {
};
match self.by_name.get(profile_name) {
None => failure::bail!("Profile `{}` undefined", profile_kind.name()),
None => anyhow::bail!("Profile `{}` undefined", profile_kind.name()),
Some(r) => Ok(r.get_profile(None, true, UnitFor::new_normal())),
}
}
@ -546,7 +546,7 @@ impl ProfileMaker {
.map(|spec| spec.to_string())
.collect::<Vec<_>>()
.join(", ");
failure::bail!(
anyhow::bail!(
"multiple package overrides in profile `{}` match package `{}`\n\
found package specs: {}",
self.default.name,
@ -1021,13 +1021,13 @@ impl ConfigProfiles {
if let Some(ref profile) = self.dev {
profile
.validate("dev", features, warnings)
.chain_err(|| failure::format_err!("config profile `profile.dev` is not valid"))?;
.chain_err(|| anyhow::format_err!("config profile `profile.dev` is not valid"))?;
}
if let Some(ref profile) = self.release {
profile
.validate("release", features, warnings)
.chain_err(|| {
failure::format_err!("config profile `profile.release` is not valid")
anyhow::format_err!("config profile `profile.release` is not valid")
})?;
}
Ok(())

View file

@ -1,6 +1,6 @@
use std::collections::{HashMap, HashSet};
use failure::bail;
use anyhow::bail;
use log::{debug, trace};
use semver::VersionReq;
use url::Url;
@ -255,7 +255,7 @@ impl<'cfg> PackageRegistry<'cfg> {
// corresponding to this `dep`.
self.ensure_loaded(dep.source_id(), Kind::Normal)
.chain_err(|| {
failure::format_err!(
anyhow::format_err!(
"failed to load source for a dependency \
on `{}`",
dep.package_name()
@ -271,7 +271,7 @@ impl<'cfg> PackageRegistry<'cfg> {
let summary = match summaries.next() {
Some(summary) => summary,
None => failure::bail!(
None => anyhow::bail!(
"patch for `{}` in `{}` did not resolve to any crates. If this is \
unexpected, you may wish to consult: \
https://github.com/rust-lang/cargo/issues/4678",
@ -280,14 +280,14 @@ impl<'cfg> PackageRegistry<'cfg> {
),
};
if summaries.next().is_some() {
failure::bail!(
anyhow::bail!(
"patch for `{}` in `{}` resolved to more than one candidate",
dep.package_name(),
url
)
}
if *summary.package_id().source_id().canonical_url() == canonical {
failure::bail!(
anyhow::bail!(
"patch for `{}` in `{}` points to the same source, but \
patches must point to different sources",
dep.package_name(),
@ -297,7 +297,7 @@ impl<'cfg> PackageRegistry<'cfg> {
Ok(summary)
})
.collect::<CargoResult<Vec<_>>>()
.chain_err(|| failure::format_err!("failed to resolve patches for `{}`", url))?;
.chain_err(|| anyhow::format_err!("failed to resolve patches for `{}`", url))?;
let mut name_and_version = HashSet::new();
for summary in unlocked_summaries.iter() {
@ -364,7 +364,7 @@ impl<'cfg> PackageRegistry<'cfg> {
let _p = profile::start(format!("updating: {}", source_id));
self.sources.get_mut(source_id).unwrap().update()
})()
.chain_err(|| failure::format_err!("Unable to update {}", source_id))?;
.chain_err(|| anyhow::format_err!("Unable to update {}", source_id))?;
Ok(())
}
@ -516,7 +516,7 @@ impl<'cfg> Registry for PackageRegistry<'cfg> {
// Ensure the requested source_id is loaded
self.ensure_loaded(dep.source_id(), Kind::Normal)
.chain_err(|| {
failure::format_err!(
anyhow::format_err!(
"failed to load source for a dependency \
on `{}`",
dep.package_name()
@ -525,7 +525,7 @@ impl<'cfg> Registry for PackageRegistry<'cfg> {
let source = self.sources.get_mut(dep.source_id());
match (override_summary, source) {
(Some(_), None) => failure::bail!("override found but no real ones"),
(Some(_), None) => anyhow::bail!("override found but no real ones"),
(None, None) => return Ok(()),
// If we don't have an override then we just ship
@ -565,7 +565,7 @@ impl<'cfg> Registry for PackageRegistry<'cfg> {
// the summaries it gives us though.
(Some(override_summary), Some(source)) => {
if !patches.is_empty() {
failure::bail!("found patches and a path override")
anyhow::bail!("found patches and a path override")
}
let mut n = 0;
let mut to_warn = None;
@ -587,7 +587,7 @@ impl<'cfg> Registry for PackageRegistry<'cfg> {
};
if n > 1 {
failure::bail!("found an override with a non-locked list");
anyhow::bail!("found an override with a non-locked list");
} else if let Some(summary) = to_warn {
self.warn_bad_override(&override_summary, &summary)?;
}

View file

@ -2,7 +2,7 @@ use std::collections::HashMap;
use std::num::NonZeroU64;
use std::rc::Rc;
use failure::format_err;
use anyhow::format_err;
use log::debug;
use crate::core::interning::InternedString;

View file

@ -104,7 +104,7 @@ impl<'a> RegistryQueryer<'a> {
let mut summaries = self.registry.query_vec(dep, false)?.into_iter();
let s = summaries.next().ok_or_else(|| {
failure::format_err!(
anyhow::format_err!(
"no matching package for override `{}` found\n\
location searched: {}\n\
version required: {}",
@ -119,7 +119,7 @@ impl<'a> RegistryQueryer<'a> {
.iter()
.map(|s| format!(" * {}", s.package_id()))
.collect::<Vec<_>>();
failure::bail!(
anyhow::bail!(
"the replacement specification `{}` matched \
multiple packages:\n * {}\n{}",
spec,
@ -144,7 +144,7 @@ impl<'a> RegistryQueryer<'a> {
// Make sure no duplicates
if let Some(&(ref spec, _)) = potential_matches.next() {
failure::bail!(
anyhow::bail!(
"overlapping replacement specifications found:\n\n \
* {}\n * {}\n\nboth specifications match: {}",
matched_spec,
@ -277,7 +277,7 @@ pub fn resolve_features<'b>(
.any(|d| d.is_optional() && d.name_in_toml() == dep.name_in_toml());
if always_required && base.0 {
return Err(match parent {
None => failure::format_err!(
None => anyhow::format_err!(
"Package `{}` does not have feature `{}`. It has a required dependency \
with that name, but only optional dependencies can be used as features.",
s.package_id(),
@ -295,7 +295,7 @@ pub fn resolve_features<'b>(
base.extend(dep.features().iter());
for feature in base.iter() {
if feature.contains('/') {
return Err(failure::format_err!(
return Err(anyhow::format_err!(
"feature names may not contain slashes: `{}`",
feature
)
@ -318,7 +318,7 @@ pub fn resolve_features<'b>(
if !remaining.is_empty() {
let features = remaining.join(", ");
return Err(match parent {
None => failure::format_err!(
None => anyhow::format_err!(
"Package `{}` does not have these features: `{}`",
s.package_id(),
features
@ -437,7 +437,7 @@ impl Requirements<'_> {
.expect("must be a valid feature")
{
match *fv {
FeatureValue::Feature(ref dep_feat) if **dep_feat == *feat => failure::bail!(
FeatureValue::Feature(ref dep_feat) if **dep_feat == *feat => anyhow::bail!(
"cyclic feature dependency: feature `{}` depends on itself",
feat
),

View file

@ -160,7 +160,7 @@ impl EncodableResolve {
};
if !all_pkgs.insert(enc_id.clone()) {
failure::bail!("package `{}` is specified twice in the lockfile", pkg.name);
anyhow::bail!("package `{}` is specified twice in the lockfile", pkg.name);
}
let id = match pkg.source.as_ref().or_else(|| path_deps.get(&pkg.name)) {
// We failed to find a local package in the workspace.
@ -474,7 +474,7 @@ impl fmt::Display for EncodablePackageId {
}
impl FromStr for EncodablePackageId {
type Err = failure::Error;
type Err = anyhow::Error;
fn from_str(s: &str) -> CargoResult<EncodablePackageId> {
let mut s = s.splitn(3, ' ');
@ -485,7 +485,7 @@ impl FromStr for EncodablePackageId {
if s.starts_with('(') && s.ends_with(')') {
Some(SourceId::from_url(&s[1..s.len() - 1])?)
} else {
failure::bail!("invalid serialized PackageId")
anyhow::bail!("invalid serialized PackageId")
}
}
None => None,

View file

@ -3,7 +3,7 @@ use std::fmt;
use crate::core::{Dependency, PackageId, Registry, Summary};
use crate::util::lev_distance::lev_distance;
use crate::util::Config;
use failure::{Error, Fail};
use anyhow::Error;
use semver;
use super::context::Context;
@ -30,9 +30,9 @@ impl ResolveError {
}
}
impl Fail for ResolveError {
fn cause(&self) -> Option<&dyn Fail> {
self.cause.as_fail().cause()
impl std::error::Error for ResolveError {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
self.cause.source()
}
}
@ -52,12 +52,12 @@ pub type ActivateResult<T> = Result<T, ActivateError>;
#[derive(Debug)]
pub enum ActivateError {
Fatal(failure::Error),
Fatal(anyhow::Error),
Conflict(PackageId, ConflictReason),
}
impl From<::failure::Error> for ActivateError {
fn from(t: ::failure::Error) -> Self {
impl From<::anyhow::Error> for ActivateError {
fn from(t: ::anyhow::Error) -> Self {
ActivateError::Fatal(t)
}
}
@ -185,7 +185,7 @@ pub(super) fn activation_error(
msg.push_str(&*dep.package_name());
msg.push_str("` which could resolve this conflict");
return to_resolve_err(failure::format_err!("{}", msg));
return to_resolve_err(anyhow::format_err!("{}", msg));
}
// We didn't actually find any candidates, so we need to
@ -324,7 +324,7 @@ pub(super) fn activation_error(
}
}
to_resolve_err(failure::format_err!("{}", msg))
to_resolve_err(anyhow::format_err!("{}", msg))
}
/// Returns String representation of dependency chain for a particular `pkgid`.

View file

@ -1012,7 +1012,7 @@ fn check_cycles(resolve: &Resolve) -> CargoResult<()> {
path.push(id);
// See if we visited ourselves
if !visited.insert(id) {
failure::bail!(
anyhow::bail!(
"cyclic package dependency: package `{}` depends on itself. Cycle:\n{}",
id,
errors::describe_path(&path.iter().rev().collect::<Vec<_>>()),
@ -1062,7 +1062,7 @@ fn check_duplicate_pkgs_in_lockfile(resolve: &Resolve) -> CargoResult<()> {
for pkg_id in resolve.iter() {
let encodable_pkd_id = encode::encodable_package_id(pkg_id, &state);
if let Some(prev_pkg_id) = unique_pkg_ids.insert(encodable_pkd_id, pkg_id) {
failure::bail!(
anyhow::bail!(
"package collision in the lockfile: packages {} and {} are different, \
but only one can be written to lockfile unambiguously",
prev_pkg_id,

View file

@ -150,7 +150,7 @@ impl Resolve {
// desires stronger checksum guarantees than can be afforded
// elsewhere.
if cksum.is_none() {
failure::bail!(
anyhow::bail!(
"\
checksum for `{}` was not previously calculated, but a checksum could now \
be calculated
@ -172,7 +172,7 @@ this could be indicative of a few possible situations:
// more realistically we were overridden with a source that does
// not have checksums.
} else if mine.is_none() {
failure::bail!(
anyhow::bail!(
"\
checksum for `{}` could not be calculated, but a checksum is listed in \
the existing lock file
@ -193,7 +193,7 @@ unable to verify that `{0}` is the same as when the lockfile was generated
// must both be Some, in which case the checksum now differs.
// That's quite bad!
} else {
failure::bail!(
anyhow::bail!(
"\
checksum for `{}` changed between lock files
@ -338,7 +338,7 @@ unable to verify that `{0}` is the same as when the lockfile was generated
});
let name = names.next().unwrap_or_else(|| crate_name.clone());
for n in names {
failure::ensure!(
anyhow::ensure!(
n == name,
"the crate `{}` depends on crate `{}` multiple times with different names",
from,

View file

@ -252,7 +252,7 @@ impl Shell {
Some("auto") | None => ColorChoice::CargoAuto,
Some(arg) => failure::bail!(
Some(arg) => anyhow::bail!(
"argument for --color must be auto, always, or \
never, but found `{}`",
arg

View file

@ -112,7 +112,7 @@ impl SourceId {
let kind = parts.next().unwrap();
let url = parts
.next()
.ok_or_else(|| failure::format_err!("invalid source `{}`", string))?;
.ok_or_else(|| anyhow::format_err!("invalid source `{}`", string))?;
match kind {
"git" => {
@ -141,10 +141,7 @@ impl SourceId {
let url = url.into_url()?;
SourceId::new(Kind::Path, url)
}
kind => Err(failure::format_err!(
"unsupported source protocol: {}",
kind
)),
kind => Err(anyhow::format_err!("unsupported source protocol: {}", kind)),
}
}

View file

@ -46,14 +46,14 @@ impl Summary {
for dep in dependencies.iter() {
let feature = dep.name_in_toml();
if !namespaced_features && features.get(&*feature).is_some() {
failure::bail!(
anyhow::bail!(
"Features and dependencies cannot have the \
same name: `{}`",
feature
)
}
if dep.is_optional() && !dep.is_transitive() {
failure::bail!(
anyhow::bail!(
"Dev-dependencies are not allowed to be optional: `{}`",
feature
)
@ -180,7 +180,7 @@ where
match dep_map.get(feature.borrow()) {
Some(dep_data) => {
if !dep_data.iter().any(|d| d.is_optional()) {
failure::bail!(
anyhow::bail!(
"Feature `{}` includes the dependency of the same name, but this is \
left implicit in the features included by this feature.\n\
Additionally, the dependency must be marked as optional to be \
@ -249,7 +249,7 @@ where
(&Feature(feat), dep_exists, false) => {
if namespaced && !features.contains_key(&*feat) {
if dep_exists {
failure::bail!(
anyhow::bail!(
"Feature `{}` includes `{}` which is not defined as a feature.\n\
A non-optional dependency of the same name is defined; consider \
adding `optional = true` to its definition",
@ -257,7 +257,7 @@ where
feat
)
} else {
failure::bail!(
anyhow::bail!(
"Feature `{}` includes `{}` which is not defined as a feature",
feature,
feat
@ -272,7 +272,7 @@ where
// just to provide the correct string for the crate dependency in the error.
(&Crate(ref dep), true, false) => {
if namespaced {
failure::bail!(
anyhow::bail!(
"Feature `{}` includes `crate:{}` which is not an \
optional dependency.\nConsider adding \
`optional = true` to the dependency",
@ -280,7 +280,7 @@ where
dep
)
} else {
failure::bail!(
anyhow::bail!(
"Feature `{}` depends on `{}` which is not an \
optional dependency.\nConsider adding \
`optional = true` to the dependency",
@ -295,14 +295,14 @@ where
// namespaced here is just to provide the correct string in the error.
(&Crate(ref dep), false, _) => {
if namespaced {
failure::bail!(
anyhow::bail!(
"Feature `{}` includes `crate:{}` which is not a known \
dependency",
feature,
dep
)
} else {
failure::bail!(
anyhow::bail!(
"Feature `{}` includes `{}` which is neither a dependency nor \
another feature",
feature,
@ -313,7 +313,7 @@ where
(&Crate(_), true, true) => {}
// If the value is a feature for one of the dependencies, bail out if no such
// dependency is actually defined in the manifest.
(&CrateFeature(ref dep, _), false, _) => failure::bail!(
(&CrateFeature(ref dep, _), false, _) => anyhow::bail!(
"Feature `{}` requires a feature of `{}` which is not a \
dependency",
feature,
@ -327,7 +327,7 @@ where
if !dependency_found {
// If we have not found the dependency of the same-named feature, we should
// bail here.
failure::bail!(
anyhow::bail!(
"Feature `{}` includes the optional dependency of the \
same name, but this is left implicit in the features \
included by this feature.\nConsider adding \

View file

@ -224,7 +224,7 @@ impl<'cfg> Workspace<'cfg> {
/// indicating that something else should be passed.
pub fn current(&self) -> CargoResult<&Package> {
let pkg = self.current_opt().ok_or_else(|| {
failure::format_err!(
anyhow::format_err!(
"manifest path `{}` is a virtual manifest, but this \
command requires running against an actual package in \
this workspace",
@ -467,7 +467,7 @@ impl<'cfg> Workspace<'cfg> {
None
};
}
_ => failure::bail!(
_ => anyhow::bail!(
"root of a workspace inferred but wasn't a root: {}",
root_manifest_path.display()
),
@ -482,7 +482,7 @@ impl<'cfg> Workspace<'cfg> {
for path in default {
let manifest_path = paths::normalize_path(&path.join("Cargo.toml"));
if !self.members.contains(&manifest_path) {
failure::bail!(
anyhow::bail!(
"package `{}` is listed in workspaces default-members \
but is not a member.",
path.display()
@ -592,7 +592,7 @@ impl<'cfg> Workspace<'cfg> {
MaybePackage::Virtual(_) => continue,
};
if let Some(prev) = names.insert(name, member) {
failure::bail!(
anyhow::bail!(
"two packages named `{}` in this workspace:\n\
- {}\n\
- {}",
@ -605,7 +605,7 @@ impl<'cfg> Workspace<'cfg> {
}
match roots.len() {
0 => failure::bail!(
0 => anyhow::bail!(
"`package.workspace` configuration points to a crate \
which is not configured with [workspace]: \n\
configuration at: {}\n\
@ -615,7 +615,7 @@ impl<'cfg> Workspace<'cfg> {
),
1 => {}
_ => {
failure::bail!(
anyhow::bail!(
"multiple workspace roots found in the same workspace:\n{}",
roots
.iter()
@ -634,7 +634,7 @@ impl<'cfg> Workspace<'cfg> {
match root {
Some(root) => {
failure::bail!(
anyhow::bail!(
"package `{}` is a member of the wrong workspace\n\
expected: {}\n\
actual: {}",
@ -644,7 +644,7 @@ impl<'cfg> Workspace<'cfg> {
);
}
None => {
failure::bail!(
anyhow::bail!(
"workspace member `{}` is not hierarchically below \
the workspace root `{}`",
member.display(),
@ -696,7 +696,7 @@ impl<'cfg> Workspace<'cfg> {
}
}
};
failure::bail!(
anyhow::bail!(
"current package believes it's in a workspace when it's not:\n\
current: {}\n\
workspace: {}\n\n{}\n\
@ -746,7 +746,7 @@ impl<'cfg> Workspace<'cfg> {
pub fn load(&self, manifest_path: &Path) -> CargoResult<Package> {
match self.packages.maybe_get(manifest_path) {
Some(&MaybePackage::Package(ref p)) => return Ok(p.clone()),
Some(&MaybePackage::Virtual(_)) => failure::bail!("cannot load workspace root"),
Some(&MaybePackage::Virtual(_)) => anyhow::bail!("cannot load workspace root"),
None => {}
}
@ -800,9 +800,9 @@ impl<'cfg> Workspace<'cfg> {
let path = path.join("Cargo.toml");
for warning in warnings {
if warning.is_critical {
let err = failure::format_err!("{}", warning.message);
let err = anyhow::format_err!("{}", warning.message);
let cx =
failure::format_err!("failed to parse manifest at `{}`", path.display());
anyhow::format_err!("failed to parse manifest at `{}`", path.display());
return Err(err.context(cx).into());
} else {
let msg = if self.root_manifest.is_none() {
@ -941,10 +941,10 @@ impl WorkspaceRootConfig {
None => return Ok(Vec::new()),
};
let res =
glob(path).chain_err(|| failure::format_err!("could not parse pattern `{}`", &path))?;
glob(path).chain_err(|| anyhow::format_err!("could not parse pattern `{}`", &path))?;
let res = res
.map(|p| {
p.chain_err(|| failure::format_err!("unable to match path to pattern `{}`", &path))
p.chain_err(|| anyhow::format_err!("unable to match path to pattern `{}`", &path))
})
.collect::<Result<Vec<_>, _>>()?;
Ok(res)

View file

@ -30,15 +30,12 @@
// https://github.com/rust-lang/cargo/pull/7251#pullrequestreview-274914270
#![allow(clippy::identity_conversion)]
use std::fmt;
use std::io;
use failure::Error;
use log::debug;
use serde::ser;
use crate::core::shell::Verbosity::Verbose;
use crate::core::Shell;
use anyhow::Error;
use log::debug;
use serde::ser;
use std::fmt;
pub use crate::util::errors::Internal;
pub use crate::util::{CargoResult, CliError, CliResult, Config};
@ -140,7 +137,7 @@ pub fn exit_with_error(err: CliError, shell: &mut Shell) -> ! {
std::process::exit(exit_code)
}
pub fn handle_error(err: &failure::Error, shell: &mut Shell) {
pub fn handle_error(err: &Error, shell: &mut Shell) {
debug!("handle_error; err={:?}", err);
let _ignored_result = shell.error(err);
@ -153,18 +150,10 @@ fn handle_cause(cargo_err: &Error, shell: &mut Shell) -> bool {
drop(writeln!(shell.err(), " {}", error));
}
fn print_stderror_causes(error: &dyn std::error::Error, shell: &mut Shell) {
let mut cur = std::error::Error::source(error);
while let Some(err) = cur {
print(&err.to_string(), shell);
cur = std::error::Error::source(err);
}
}
let verbose = shell.verbosity();
// The first error has already been printed to the shell.
for err in cargo_err.iter_causes() {
for err in cargo_err.chain().skip(1) {
// If we're not in verbose mode then print remaining errors until one
// marked as `Internal` appears.
if verbose != Verbose && err.downcast_ref::<Internal>().is_some() {
@ -172,19 +161,6 @@ fn handle_cause(cargo_err: &Error, shell: &mut Shell) -> bool {
}
print(&err.to_string(), shell);
// Using the `failure` crate currently means that when using
// `iter_causes` we're only iterating over the `failure` causes, but
// this doesn't include the causes from the standard library `Error`
// trait. We don't have a great way of getting an `&dyn Error` from a
// `&dyn Fail`, so we currently just special case a few errors that are
// known to maybe have causes and we try to print them here.
//
// Note that this isn't an exhaustive match since causes for
// `std::error::Error` aren't the most common thing in the world.
if let Some(io) = err.downcast_ref::<io::Error>() {
print_stderror_causes(io, shell);
}
}
true

View file

@ -155,13 +155,13 @@ fn rm_rf(path: &Path, config: &Config) -> CargoResult<()> {
.shell()
.verbose(|shell| shell.status("Removing", path.display()))?;
paths::remove_dir_all(path)
.chain_err(|| failure::format_err!("could not remove build directory"))?;
.chain_err(|| anyhow::format_err!("could not remove build directory"))?;
} else if m.is_ok() {
config
.shell()
.verbose(|shell| shell.status("Removing", path.display()))?;
paths::remove_file(path)
.chain_err(|| failure::format_err!("failed to remove build artifact"))?;
.chain_err(|| anyhow::format_err!("failed to remove build artifact"))?;
}
Ok(())
}

View file

@ -111,7 +111,7 @@ impl Packages {
Ok(match (all, exclude.len(), package.len()) {
(false, 0, 0) => Packages::Default,
(false, 0, _) => Packages::Packages(package),
(false, _, _) => failure::bail!("--exclude can only be used together with --workspace"),
(false, _, _) => anyhow::bail!("--exclude can only be used together with --workspace"),
(true, 0, _) => Packages::All,
(true, _, _) => Packages::OptOut(exclude),
})
@ -160,13 +160,13 @@ impl Packages {
};
if specs.is_empty() {
if ws.is_virtual() {
failure::bail!(
anyhow::bail!(
"manifest path `{}` contains no package: The manifest is virtual, \
and the workspace has no members.",
ws.root().display()
)
}
failure::bail!("no packages to compile")
anyhow::bail!("no packages to compile")
}
Ok(specs)
}
@ -185,7 +185,7 @@ impl Packages {
ws.members()
.find(|pkg| pkg.name().as_str() == name)
.ok_or_else(|| {
failure::format_err!(
anyhow::format_err!(
"package `{}` is not a member of the workspace",
name
)
@ -325,7 +325,7 @@ pub fn compile_ws<'a>(
// TODO: This should eventually be fixed. Unfortunately it is not
// easy to get the host triple in BuildConfig. Consider changing
// requested_target to an enum, or some other approach.
failure::bail!("-Zbuild-std requires --target");
anyhow::bail!("-Zbuild-std requires --target");
}
let (mut std_package_set, std_resolve) = standard_lib::resolve_std(ws, crates)?;
remove_dylib_crate_type(&mut std_package_set)?;
@ -359,7 +359,7 @@ pub fn compile_ws<'a>(
&& !ws.is_member(pkg)
&& pkg.dependencies().iter().any(|dep| !dep.is_transitive())
{
failure::bail!(
anyhow::bail!(
"package `{}` cannot be tested because it requires dev-dependencies \
and is not a member of the workspace",
pkg.name()
@ -430,7 +430,7 @@ pub fn compile_ws<'a>(
if let Some(args) = extra_args {
if units.len() != 1 {
failure::bail!(
anyhow::bail!(
"extra arguments to `{}` can only be passed to one \
target, consider filtering\nthe package by passing, \
e.g., `--lib` or `--bin NAME` to specify a single target",
@ -793,12 +793,9 @@ fn generate_targets<'a>(
if !all_targets && libs.is_empty() && *lib == LibRule::True {
let names = packages.iter().map(|pkg| pkg.name()).collect::<Vec<_>>();
if names.len() == 1 {
failure::bail!("no library targets found in package `{}`", names[0]);
anyhow::bail!("no library targets found in package `{}`", names[0]);
} else {
failure::bail!(
"no library targets found in packages: {}",
names.join(", ")
);
anyhow::bail!("no library targets found in packages: {}", names.join(", "));
}
}
proposals.extend(libs);
@ -887,7 +884,7 @@ fn generate_targets<'a>(
.iter()
.map(|s| format!("`{}`", s))
.collect();
failure::bail!(
anyhow::bail!(
"target `{}` in package `{}` requires the features: {}\n\
Consider enabling them by passing, e.g., `--features=\"{}\"`",
target.name(),
@ -991,7 +988,7 @@ fn find_named_targets<'a>(
.filter(|target| is_expected_kind(target))
});
let suggestion = closest_msg(target_name, targets, |t| t.name());
failure::bail!(
anyhow::bail!(
"no {} target named `{}`{}",
target_desc,
target_name,

View file

@ -2,8 +2,6 @@ use crate::core::resolver::ResolveOpts;
use crate::core::{Shell, Workspace};
use crate::ops;
use crate::util::CargoResult;
use failure::Fail;
use opener;
use std::collections::HashMap;
use std::path::Path;
use std::process::Command;
@ -41,7 +39,7 @@ pub fn doc(ws: &Workspace<'_>, options: &DocOptions<'_>) -> CargoResult<()> {
for target in package.targets().iter().filter(|t| t.documented()) {
if target.is_lib() {
if let Some(prev) = lib_names.insert(target.crate_name(), package) {
failure::bail!(
anyhow::bail!(
"The library `{}` is specified by packages `{}` and \
`{}` but can only be documented once. Consider renaming \
or marking one of the targets as `doc = false`.",
@ -51,7 +49,7 @@ pub fn doc(ws: &Workspace<'_>, options: &DocOptions<'_>) -> CargoResult<()> {
);
}
} else if let Some(prev) = bin_names.insert(target.crate_name(), package) {
failure::bail!(
anyhow::bail!(
"The binary `{}` is specified by packages `{}` and \
`{}` but can be documented only once. Consider renaming \
or marking one of the targets as `doc = false`.",
@ -100,7 +98,7 @@ fn open_docs(path: &Path, shell: &mut Shell) -> CargoResult<()> {
None => {
if let Err(e) = opener::open(&path) {
shell.warn(format!("Couldn't open docs: {}", e))?;
for cause in (&e as &dyn Fail).iter_chain() {
for cause in anyhow::Error::new(e).chain().skip(1) {
shell.warn(format!("Caused by:\n {}", cause))?;
}
}

View file

@ -36,15 +36,15 @@ pub fn generate_lockfile(ws: &Workspace<'_>) -> CargoResult<()> {
pub fn update_lockfile(ws: &Workspace<'_>, opts: &UpdateOptions<'_>) -> CargoResult<()> {
if opts.aggressive && opts.precise.is_some() {
failure::bail!("cannot specify both aggressive and precise simultaneously")
anyhow::bail!("cannot specify both aggressive and precise simultaneously")
}
if ws.members().count() == 0 {
failure::bail!("you can't generate a lockfile for an empty workspace.")
anyhow::bail!("you can't generate a lockfile for an empty workspace.")
}
if opts.config.offline() {
failure::bail!("you can't update in the offline mode");
anyhow::bail!("you can't update in the offline mode");
}
// Updates often require a lot of modifications to the registry, so ensure

View file

@ -3,7 +3,7 @@ use std::path::{Path, PathBuf};
use std::sync::Arc;
use std::{env, fs};
use failure::{bail, format_err};
use anyhow::{bail, format_err};
use tempfile::Builder as TempFileBuilder;
use crate::core::compiler::Freshness;

View file

@ -1,5 +1,5 @@
use crate::core::{compiler, Workspace};
use crate::util::errors::{self, CargoResult, CargoResultExt};
use crate::util::errors::{CargoResult, CargoResultExt};
use crate::util::{existing_vcs_repo, FossilRepo, GitRepo, HgRepo, PijulRepo};
use crate::util::{paths, validate_package_name, Config};
use git2::Config as GitConfig;
@ -26,16 +26,16 @@ pub enum VersionControl {
}
impl FromStr for VersionControl {
type Err = failure::Error;
type Err = anyhow::Error;
fn from_str(s: &str) -> Result<Self, failure::Error> {
fn from_str(s: &str) -> Result<Self, anyhow::Error> {
match s {
"git" => Ok(VersionControl::Git),
"hg" => Ok(VersionControl::Hg),
"pijul" => Ok(VersionControl::Pijul),
"fossil" => Ok(VersionControl::Fossil),
"none" => Ok(VersionControl::NoVcs),
other => failure::bail!("unknown vcs specification: `{}`", other),
other => anyhow::bail!("unknown vcs specification: `{}`", other),
}
}
}
@ -110,7 +110,7 @@ impl NewOptions {
registry: Option<String>,
) -> CargoResult<NewOptions> {
let kind = match (bin, lib) {
(true, true) => failure::bail!("can't specify both lib and binary outputs"),
(true, true) => anyhow::bail!("can't specify both lib and binary outputs"),
(false, true) => NewProjectKind::Lib,
// default to bin
(_, false) => NewProjectKind::Bin,
@ -142,14 +142,14 @@ fn get_name<'a>(path: &'a Path, opts: &'a NewOptions) -> CargoResult<&'a str> {
}
let file_name = path.file_name().ok_or_else(|| {
failure::format_err!(
anyhow::format_err!(
"cannot auto-detect package name from path {:?} ; use --name to override",
path.as_os_str()
)
})?;
file_name.to_str().ok_or_else(|| {
failure::format_err!(
anyhow::format_err!(
"cannot create package with a non-unicode name: {:?}",
file_name
)
@ -174,7 +174,7 @@ fn check_name(name: &str, opts: &NewOptions) -> CargoResult<()> {
"true", "type", "typeof", "unsafe", "unsized", "use", "virtual", "where", "while", "yield",
];
if blacklist.contains(&name) || (opts.kind.is_bin() && compiler::is_bad_artifact_name(name)) {
failure::bail!(
anyhow::bail!(
"The name `{}` cannot be used as a crate name{}",
name,
name_help
@ -183,7 +183,7 @@ fn check_name(name: &str, opts: &NewOptions) -> CargoResult<()> {
if let Some(ref c) = name.chars().nth(0) {
if c.is_digit(10) {
failure::bail!(
anyhow::bail!(
"Package names starting with a digit cannot be used as a crate name{}",
name_help
)
@ -283,7 +283,7 @@ fn detect_source_paths_and_types(
for i in detected_files {
if i.bin {
if let Some(x) = BTreeMap::get::<str>(&duplicates_checker, i.target_name.as_ref()) {
failure::bail!(
anyhow::bail!(
"\
multiple possible binary sources found:
{}
@ -296,7 +296,7 @@ cannot automatically generate Cargo.toml as the main target would be ambiguous",
duplicates_checker.insert(i.target_name.as_ref(), i);
} else {
if let Some(plp) = previous_lib_relpath {
failure::bail!(
anyhow::bail!(
"cannot have a package with \
multiple libraries, \
found both `{}` and `{}`",
@ -330,7 +330,7 @@ fn plan_new_source_file(bin: bool, package_name: String) -> SourceFileInformatio
pub fn new(opts: &NewOptions, config: &Config) -> CargoResult<()> {
let path = &opts.path;
if fs::metadata(path).is_ok() {
failure::bail!(
anyhow::bail!(
"destination `{}` already exists\n\n\
Use `cargo init` to initialize the directory",
path.display()
@ -351,7 +351,7 @@ pub fn new(opts: &NewOptions, config: &Config) -> CargoResult<()> {
};
mk(config, &mkopts).chain_err(|| {
failure::format_err!(
anyhow::format_err!(
"Failed to create package `{}` at `{}`",
name,
path.display()
@ -364,7 +364,7 @@ pub fn init(opts: &NewOptions, config: &Config) -> CargoResult<()> {
let path = &opts.path;
if fs::metadata(&path.join("Cargo.toml")).is_ok() {
failure::bail!("`cargo init` cannot be run on existing Cargo packages")
anyhow::bail!("`cargo init` cannot be run on existing Cargo packages")
}
let name = get_name(path, opts)?;
@ -410,7 +410,7 @@ pub fn init(opts: &NewOptions, config: &Config) -> CargoResult<()> {
// if none exists, maybe create git, like in `cargo new`
if num_detected_vsces > 1 {
failure::bail!(
anyhow::bail!(
"more than one of .hg, .git, .pijul, .fossil configurations \
found and the ignore file can't be filled in as \
a result. specify --vcs to override detection"
@ -429,7 +429,7 @@ pub fn init(opts: &NewOptions, config: &Config) -> CargoResult<()> {
};
mk(config, &mkopts).chain_err(|| {
failure::format_err!(
anyhow::format_err!(
"Failed to create package `{}` at `{}`",
name,
path.display()
@ -527,7 +527,7 @@ fn write_ignore_file(
let ignore: String = match fs::File::open(&fp_ignore) {
Err(why) => match why.kind() {
ErrorKind::NotFound => list.format_new(vcs),
_ => return Err(failure::format_err!("{}", why)),
_ => return Err(anyhow::format_err!("{}", why)),
},
Ok(file) => list.format_existing(BufReader::new(file), vcs),
};
@ -713,8 +713,8 @@ mod tests {
if let Err(e) = Workspace::new(&path.join("Cargo.toml"), config) {
let msg = format!(
"compiling this new crate may not work due to invalid \
workspace configuration\n\n{}",
errors::display_causes(&e)
workspace configuration\n\n{:?}",
e,
);
config.shell().warn(msg)?;
}
@ -752,7 +752,7 @@ fn discover_author() -> CargoResult<(String, Option<String>)> {
Some(name) => name,
None => {
let username_var = if cfg!(windows) { "USERNAME" } else { "USER" };
failure::bail!(
anyhow::bail!(
"could not determine the current user, please set ${}",
username_var
)

View file

@ -24,7 +24,7 @@ pub struct OutputMetadataOptions {
/// format to stdout.
pub fn output_metadata(ws: &Workspace<'_>, opt: &OutputMetadataOptions) -> CargoResult<ExportInfo> {
if opt.version != VERSION {
failure::bail!(
anyhow::bail!(
"metadata version {} not supported, only {} is currently supported",
opt.version,
VERSION

View file

@ -123,7 +123,7 @@ pub fn package(ws: &Workspace<'_>, opts: &PackageOpts<'_>) -> CargoResult<Option
.status("Packaging", pkg.package_id().to_string())?;
dst.file().set_len(0)?;
tar(ws, &src_files, vcs_info.as_ref(), dst.file(), &filename)
.chain_err(|| failure::format_err!("failed to prepare local package for uploading"))?;
.chain_err(|| anyhow::format_err!("failed to prepare local package for uploading"))?;
if opts.verify {
dst.seek(SeekFrom::Start(0))?;
run_verify(ws, &dst, opts).chain_err(|| "failed to verify package tarball")?
@ -214,7 +214,7 @@ fn check_metadata(pkg: &Package, config: &Config) -> CargoResult<()> {
fn verify_dependencies(pkg: &Package) -> CargoResult<()> {
for dep in pkg.dependencies() {
if dep.source_id().is_path() && !dep.specified_req() && dep.is_transitive() {
failure::bail!(
anyhow::bail!(
"all path dependencies must have a version specified \
when packaging.\ndependency `{}` does not specify \
a version.",
@ -321,7 +321,7 @@ fn check_repo_state(
Ok(Some(rev_obj.id().to_string()))
} else {
if !allow_dirty {
failure::bail!(
anyhow::bail!(
"{} files in the working directory contain changes that were \
not yet committed into git:\n\n{}\n\n\
to proceed despite this and include the uncommitted changes, pass the `--allow-dirty` flag",
@ -359,7 +359,7 @@ fn check_vcs_file_collision(pkg: &Package, src_files: &[PathBuf]) -> CargoResult
.iter()
.find(|&p| p.strip_prefix(root).unwrap() == vcs_info_path);
if collision.is_some() {
failure::bail!(
anyhow::bail!(
"Invalid inclusion of reserved file name \
{} in package source",
VCS_INFO_FILE
@ -391,7 +391,7 @@ fn tar(
let relative = src_file.strip_prefix(root)?;
check_filename(relative)?;
let relative_str = relative.to_str().ok_or_else(|| {
failure::format_err!("non-utf8 path in source directory: {}", relative.display())
anyhow::format_err!("non-utf8 path in source directory: {}", relative.display())
})?;
if relative_str == "Cargo.lock" {
// This is added manually below.
@ -671,7 +671,7 @@ fn run_verify(ws: &Workspace<'_>, tar: &FileLock, opts: &PackageOpts<'_>) -> Car
let ws_fingerprint = hash_all(&dst)?;
if pkg_fingerprint != ws_fingerprint {
let changes = report_hash_difference(&pkg_fingerprint, &ws_fingerprint);
failure::bail!(
anyhow::bail!(
"Source directory was modified by build.rs during cargo publish. \
Build scripts should not modify anything outside of OUT_DIR.\n\
{}\n\n\
@ -756,7 +756,7 @@ fn check_filename(file: &Path) -> CargoResult<()> {
};
let name = match name.to_str() {
Some(name) => name,
None => failure::bail!(
None => anyhow::bail!(
"path does not have a unicode filename which may not unpack \
on all platforms: {}",
file.display()
@ -764,7 +764,7 @@ fn check_filename(file: &Path) -> CargoResult<()> {
};
let bad_chars = ['/', '\\', '<', '>', ':', '"', '|', '?', '*'];
if let Some(c) = bad_chars.iter().find(|c| name.contains(**c)) {
failure::bail!(
anyhow::bail!(
"cannot package a filename with a special character `{}`: {}",
c,
file.display()

View file

@ -5,7 +5,7 @@ use crate::util::CargoResult;
pub fn pkgid(ws: &Workspace<'_>, spec: Option<&str>) -> CargoResult<PackageIdSpec> {
let resolve = match ops::load_pkg_lockfile(ws)? {
Some(resolve) => resolve,
None => failure::bail!("a Cargo.lock must exist for this command"),
None => anyhow::bail!("a Cargo.lock must exist for this command"),
};
let pkgid = match spec {

View file

@ -24,7 +24,7 @@ pub fn read_package(
let (manifest, nested) = read_manifest(path, source_id, config)?;
let manifest = match manifest {
EitherManifest::Real(manifest) => manifest,
EitherManifest::Virtual(..) => failure::bail!(
EitherManifest::Virtual(..) => anyhow::bail!(
"found a virtual manifest at `{}` instead of a package \
manifest",
path.display()
@ -41,7 +41,7 @@ pub fn read_packages(
) -> CargoResult<Vec<Package>> {
let mut all_packages = HashMap::new();
let mut visited = HashSet::<PathBuf>::new();
let mut errors = Vec::<failure::Error>::new();
let mut errors = Vec::<anyhow::Error>::new();
trace!(
"looking for root package: {}, source_id={}",
@ -88,7 +88,7 @@ pub fn read_packages(
if all_packages.is_empty() {
match errors.pop() {
Some(err) => Err(err),
None => Err(failure::format_err!(
None => Err(anyhow::format_err!(
"Could not find Cargo.toml in `{}`",
path.display()
)),
@ -111,7 +111,7 @@ fn walk(path: &Path, callback: &mut dyn FnMut(&Path) -> CargoResult<bool>) -> Ca
Err(ref e) if e.kind() == io::ErrorKind::PermissionDenied => return Ok(()),
Err(e) => {
let cx = format!("failed to read directory `{}`", path.display());
let e = failure::Error::from(e);
let e = anyhow::Error::from(e);
return Err(e.context(cx).into());
}
};
@ -134,7 +134,7 @@ fn read_nested_packages(
source_id: SourceId,
config: &Config,
visited: &mut HashSet<PathBuf>,
errors: &mut Vec<failure::Error>,
errors: &mut Vec<anyhow::Error>,
) -> CargoResult<()> {
if !visited.insert(path.to_path_buf()) {
return Ok(());

View file

@ -33,7 +33,7 @@ pub fn run(
if bins.is_empty() {
if !options.filter.is_specific() {
failure::bail!("a bin target must be available for `cargo run`")
anyhow::bail!("a bin target must be available for `cargo run`")
} else {
// This will be verified in `cargo_compile`.
}
@ -42,7 +42,7 @@ pub fn run(
if bins.len() == 1 {
let target = bins[0].1;
if let TargetKind::ExampleLib(..) = target.kind() {
failure::bail!(
anyhow::bail!(
"example target `{}` is a library and cannot be executed",
target.name()
)
@ -55,7 +55,7 @@ pub fn run(
.into_iter()
.map(|(_pkg, target)| target.name())
.collect();
failure::bail!(
anyhow::bail!(
"`cargo run` could not determine which binary to run. \
Use the `--bin` option to specify a binary, \
or the `default-run` manifest key.\n\
@ -63,7 +63,7 @@ pub fn run(
names.join(", ")
)
} else {
failure::bail!(
anyhow::bail!(
"`cargo run` can run at most one executable, but \
multiple were specified"
)

View file

@ -1,4 +1,4 @@
use failure::bail;
use anyhow::bail;
use std::collections::BTreeSet;
use std::env;

View file

@ -4,7 +4,7 @@ use std::io::prelude::*;
use std::io::SeekFrom;
use std::path::{Path, PathBuf};
use failure::{bail, format_err};
use anyhow::{bail, format_err};
use semver::VersionReq;
use serde::{Deserialize, Serialize};

View file

@ -46,7 +46,7 @@ use std::path::{Path, PathBuf};
use std::process::{self, Command, ExitStatus};
use std::str;
use failure::{Error, ResultExt};
use anyhow::{Context, Error};
use log::{debug, trace, warn};
use rustfix::diagnostics::Diagnostic;
use rustfix::{self, CodeFix};
@ -147,7 +147,7 @@ fn check_version_control(opts: &FixOptions<'_>) -> CargoResult<()> {
}
let config = opts.compile_opts.config;
if !existing_vcs_repo(config.cwd(), config.cwd()) {
failure::bail!(
anyhow::bail!(
"no VCS found for this package and `cargo fix` can potentially \
perform destructive changes; if you'd like to suppress this \
error pass `--allow-no-vcs`"
@ -202,7 +202,7 @@ fn check_version_control(opts: &FixOptions<'_>) -> CargoResult<()> {
files_list.push_str(" (staged)\n");
}
failure::bail!(
anyhow::bail!(
"the working directory of this package has uncommitted changes, and \
`cargo fix` can potentially perform destructive changes; if you'd \
like to suppress this error pass `--allow-dirty`, `--allow-staged`, \
@ -268,7 +268,7 @@ pub fn fix_maybe_exec_rustc() -> CargoResult<bool> {
if env::var_os(BROKEN_CODE_ENV).is_none() {
for (path, file) in fixes.files.iter() {
fs::write(path, &file.original_code)
.with_context(|_| format!("failed to write file `{}`", path))?;
.with_context(|| format!("failed to write file `{}`", path))?;
}
}
log_failed_fix(&output.stderr)?;
@ -415,7 +415,7 @@ fn rustfix_and_fix(
args.apply(&mut cmd);
let output = cmd
.output()
.with_context(|_| format!("failed to execute `{}`", rustc.display()))?;
.with_context(|| format!("failed to execute `{}`", rustc.display()))?;
// If rustc didn't succeed for whatever reasons then we're very likely to be
// looking at otherwise broken code. Let's not make things accidentally
@ -525,7 +525,7 @@ fn rustfix_and_fix(
}
}
let new_code = fixed.finish()?;
fs::write(&file, new_code).with_context(|_| format!("failed to write file `{}`", file))?;
fs::write(&file, new_code).with_context(|| format!("failed to write file `{}`", file))?;
}
Ok(())

View file

@ -47,7 +47,7 @@ pub fn write_pkg_lockfile(ws: &Workspace<'_>, resolve: &Resolve) -> CargoResult<
if !ws.config().lock_update_allowed() {
if ws.config().offline() {
failure::bail!("can't update in the offline mode");
anyhow::bail!("can't update in the offline mode");
}
let flag = if ws.config().network_allowed() {
@ -55,7 +55,7 @@ pub fn write_pkg_lockfile(ws: &Workspace<'_>, resolve: &Resolve) -> CargoResult<
} else {
"--frozen"
};
failure::bail!(
anyhow::bail!(
"the lock file {} needs to be updated but {} was passed to prevent this\n\
If you want to try to generate the lock file without accessing the network, \
use the --offline flag.",

View file

@ -6,9 +6,9 @@ use std::str;
use std::time::Duration;
use std::{cmp, env};
use anyhow::{bail, format_err};
use crates_io::{NewCrate, NewCrateDependency, Registry};
use curl::easy::{Easy, InfoType, SslOpt, SslVersion};
use failure::{bail, format_err};
use log::{log, Level};
use percent_encoding::{percent_encode, NON_ALPHANUMERIC};
@ -603,7 +603,7 @@ pub fn registry_login(
.lock()
.read_line(&mut line)
.chain_err(|| "failed to read stdin")
.map_err(failure::Error::from)?;
.map_err(anyhow::Error::from)?;
// Automatically remove `cargo login` from an inputted token to allow direct pastes from `registry.host()`/me.
line.replace("cargo login", "").trim().to_string()
}

View file

@ -265,7 +265,7 @@ pub fn resolve_with_previous<'cfg>(
members.extend(ws.members());
} else {
if specs.len() > 1 && !opts.features.is_empty() {
failure::bail!("cannot specify features for more than one package");
anyhow::bail!("cannot specify features for more than one package");
}
members.extend(
ws.members()
@ -276,7 +276,7 @@ pub fn resolve_with_previous<'cfg>(
// into the resolution graph.
if members.is_empty() {
if !(opts.features.is_empty() && !opts.all_features && opts.uses_default_features) {
failure::bail!("cannot specify features for packages outside of workspace");
anyhow::bail!("cannot specify features for packages outside of workspace");
}
members.extend(ws.members());
}

View file

@ -4,7 +4,7 @@ use crate::ops;
use crate::sources::path::PathSource;
use crate::util::Sha256;
use crate::util::{paths, CargoResult, CargoResultExt, Config};
use failure::bail;
use anyhow::bail;
use serde::Serialize;
use std::collections::HashSet;
use std::collections::{BTreeMap, BTreeSet, HashMap};

View file

@ -9,7 +9,7 @@ use crate::sources::{ReplacedSource, CRATES_IO_REGISTRY};
use crate::util::config::{self, ConfigRelativePath, OptValue};
use crate::util::errors::{CargoResult, CargoResultExt};
use crate::util::{Config, IntoUrl};
use failure::bail;
use anyhow::bail;
use log::debug;
use std::collections::{HashMap, HashSet};
use url::Url;

View file

@ -151,7 +151,7 @@ impl<'cfg> Source for DirectorySource<'cfg> {
.map(|p| &p.0)
.cloned()
.map(MaybePackage::Ready)
.ok_or_else(|| failure::format_err!("failed to find package with id: {}", id))
.ok_or_else(|| anyhow::format_err!("failed to find package with id: {}", id))
}
fn finish_download(&mut self, _id: PackageId, _data: Vec<u8>) -> CargoResult<Package> {
@ -165,7 +165,7 @@ impl<'cfg> Source for DirectorySource<'cfg> {
fn verify(&self, id: PackageId) -> CargoResult<()> {
let (pkg, cksum) = match self.packages.get(&id) {
Some(&(ref pkg, ref cksum)) => (pkg, cksum),
None => failure::bail!("failed to find entry for `{}` in directory source", id),
None => anyhow::bail!("failed to find entry for `{}` in directory source", id),
};
for (file, cksum) in cksum.files.iter() {
@ -175,7 +175,7 @@ impl<'cfg> Source for DirectorySource<'cfg> {
.chain_err(|| format!("failed to calculate checksum of: {}", file.display()))?
.finish_hex();
if &*actual != cksum {
failure::bail!(
anyhow::bail!(
"the listed checksum of `{}` has changed:\n\
expected: {}\n\
actual: {}\n\

View file

@ -118,7 +118,7 @@ impl<'cfg> Source for GitSource<'cfg> {
let db_path = git_path.join("db").join(&self.ident);
if self.config.offline() && !db_path.exists() {
failure::bail!(
anyhow::bail!(
"can't checkout from '{}': you are in the offline mode (--offline)",
self.remote.url()
);

View file

@ -67,7 +67,7 @@ pub struct GitDatabase {
/// `GitCheckout` is a local checkout of a particular revision. Calling
/// `clone_into` with a reference will resolve the reference into a revision,
/// and return a `failure::Error` if no revision for that reference was found.
/// and return a `anyhow::Error` if no revision for that reference was found.
#[derive(Serialize)]
pub struct GitCheckout<'a> {
database: &'a GitDatabase,
@ -219,7 +219,7 @@ impl GitReference {
.chain_err(|| format!("failed to find branch `{}`", s))?;
b.get()
.target()
.ok_or_else(|| failure::format_err!("branch `{}` did not have a target", s))?
.ok_or_else(|| anyhow::format_err!("branch `{}` did not have a target", s))?
}
GitReference::Rev(ref s) => {
let obj = repo.revparse_single(s)?;
@ -588,7 +588,7 @@ where
// In the case of an authentication failure (where we tried something) then
// we try to give a more helpful error message about precisely what we
// tried.
let res = res.map_err(failure::Error::from).chain_err(|| {
let res = res.map_err(anyhow::Error::from).chain_err(|| {
let mut msg = "failed to authenticate when downloading \
repository"
.to_string();
@ -669,13 +669,13 @@ pub fn fetch(
config: &Config,
) -> CargoResult<()> {
if config.frozen() {
failure::bail!(
anyhow::bail!(
"attempting to update a git repository, but --frozen \
was specified"
)
}
if !config.network_allowed() {
failure::bail!("can't update a git repository in the offline mode")
anyhow::bail!("can't update a git repository in the offline mode")
}
// If we're fetching from GitHub, attempt GitHub's special fast path for

View file

@ -290,7 +290,7 @@ impl<'cfg> PathSource<'cfg> {
warn!(" found submodule {}", file_path.display());
let rel = file_path.strip_prefix(root)?;
let rel = rel.to_str().ok_or_else(|| {
failure::format_err!("invalid utf-8 filename: {}", rel.display())
anyhow::format_err!("invalid utf-8 filename: {}", rel.display())
})?;
// Git submodules are currently only named through `/` path
// separators, explicitly not `\` which windows uses. Who knew?

View file

@ -628,21 +628,21 @@ impl<'a> SummariesCache<'a> {
// NB: keep this method in sync with `serialize` below
let (first_byte, rest) = data
.split_first()
.ok_or_else(|| failure::format_err!("malformed cache"))?;
.ok_or_else(|| anyhow::format_err!("malformed cache"))?;
if *first_byte != CURRENT_CACHE_VERSION {
failure::bail!("looks like a different Cargo's cache, bailing out");
anyhow::bail!("looks like a different Cargo's cache, bailing out");
}
let mut iter = split(rest, 0);
if let Some(update) = iter.next() {
if update != last_index_update.as_bytes() {
failure::bail!(
anyhow::bail!(
"cache out of date: current index ({}) != cache ({})",
last_index_update,
str::from_utf8(update)?,
)
}
} else {
failure::bail!("malformed file");
anyhow::bail!("malformed file");
}
let mut ret = SummariesCache::default();
while let Some(version) = iter.next() {

View file

@ -66,11 +66,11 @@ impl<'cfg> RegistryData for LocalRegistry<'cfg> {
// these directories exist.
let root = self.root.clone().into_path_unlocked();
if !root.is_dir() {
failure::bail!("local registry path is not a directory: {}", root.display())
anyhow::bail!("local registry path is not a directory: {}", root.display())
}
let index_path = self.index_path.clone().into_path_unlocked();
if !index_path.is_dir() {
failure::bail!(
anyhow::bail!(
"local registry index path is not a directory: {}",
index_path.display()
)
@ -100,7 +100,7 @@ impl<'cfg> RegistryData for LocalRegistry<'cfg> {
// verify the checksum matches the .crate file itself.
let actual = Sha256::new().update_file(&crate_file)?.finish_hex();
if actual != checksum {
failure::bail!("failed to verify the checksum of `{}`", pkg)
anyhow::bail!("failed to verify the checksum of `{}`", pkg)
}
crate_file.seek(SeekFrom::Start(0))?;

View file

@ -480,7 +480,7 @@ impl<'cfg> RegistrySource<'cfg> {
// crates.io should also block uploads with these sorts of tarballs,
// but be extra sure by adding a check here as well.
if !entry_path.starts_with(prefix) {
failure::bail!(
anyhow::bail!(
"invalid tarball downloaded, contains \
a file at {:?} which isn't under {:?}",
entry_path,

View file

@ -164,7 +164,7 @@ impl<'cfg> RegistryData for RemoteRegistry<'cfg> {
let object = entry.to_object(repo)?;
let blob = match object.as_blob() {
Some(blob) => blob,
None => failure::bail!("path `{}` is not a blob in the git repo", path.display()),
None => anyhow::bail!("path `{}` is not a blob in the git repo", path.display()),
};
data(blob.content())
}
@ -272,7 +272,7 @@ impl<'cfg> RegistryData for RemoteRegistry<'cfg> {
// Verify what we just downloaded
let actual = Sha256::new().update(data).finish_hex();
if actual != checksum {
failure::bail!("failed to verify the checksum of `{}`", pkg)
anyhow::bail!("failed to verify the checksum of `{}`", pkg)
}
let filename = self.filename(pkg);

View file

@ -22,7 +22,7 @@ impl CanonicalUrl {
// cannot-be-a-base-urls (e.g., `github.com:rust-lang-nursery/rustfmt.git`)
// are not supported.
if url.cannot_be_a_base() {
failure::bail!(
anyhow::bail!(
"invalid url `{}`: cannot-be-a-base-URLs are not supported",
url
)

View file

@ -9,8 +9,8 @@ use crate::util::{
print_available_tests,
};
use crate::CargoResult;
use anyhow::bail;
use clap::{self, SubCommand};
use failure::bail;
use std::ffi::{OsStr, OsString};
use std::fs;
use std::path::PathBuf;
@ -264,10 +264,10 @@ pub trait ArgMatchesExt {
// but in this particular case we need it to fix #3586.
let path = paths::normalize_path(&path);
if !path.ends_with("Cargo.toml") {
failure::bail!("the manifest-path must be a path to a Cargo.toml file")
anyhow::bail!("the manifest-path must be a path to a Cargo.toml file")
}
if fs::metadata(&path).is_err() {
failure::bail!(
anyhow::bail!(
"manifest path `{}` does not exist",
self._value_of("manifest-path").unwrap()
)
@ -327,7 +327,7 @@ pub trait ArgMatchesExt {
ProfileChecking::Unchecked => {}
ProfileChecking::Checked => {
if specified_profile.is_some() && !config.cli_unstable().unstable_options {
failure::bail!("Usage of `--profile` requires `-Z unstable-options`")
anyhow::bail!("Usage of `--profile` requires `-Z unstable-options`")
}
}
}
@ -338,7 +338,7 @@ pub trait ArgMatchesExt {
} else {
match specified_profile {
None | Some(ProfileKind::Release) => Ok(ProfileKind::Release),
_ => failure::bail!("Conflicting usage of --profile and --release"),
_ => anyhow::bail!("Conflicting usage of --profile and --release"),
}
}
} else if self._is_present("debug") {
@ -347,7 +347,7 @@ pub trait ArgMatchesExt {
} else {
match specified_profile {
None | Some(ProfileKind::Dev) => Ok(ProfileKind::Dev),
_ => failure::bail!("Conflicting usage of --profile and --debug"),
_ => anyhow::bail!("Conflicting usage of --profile and --debug"),
}
}
} else {

View file

@ -429,7 +429,7 @@ impl<'config> ValueDeserializer<'config> {
(false, Some(cv)) => cv.definition().clone(),
(false, None) => {
return Err(
failure::format_err!("failed to find definition of `{}`", de.key).into(),
anyhow::format_err!("failed to find definition of `{}`", de.key).into(),
)
}
}

View file

@ -63,8 +63,8 @@ use std::str::FromStr;
use std::sync::Once;
use std::time::Instant;
use anyhow::{anyhow, bail};
use curl::easy::Easy;
use failure::bail;
use lazycell::LazyCell;
use serde::Deserialize;
use url::Url;
@ -74,7 +74,7 @@ use crate::core::profiles::ConfigProfiles;
use crate::core::shell::Verbosity;
use crate::core::{nightly_features_allowed, CliUnstable, Shell, SourceId, Workspace};
use crate::ops;
use crate::util::errors::{self, internal, CargoResult, CargoResultExt};
use crate::util::errors::{internal, CargoResult, CargoResultExt};
use crate::util::toml as cargo_toml;
use crate::util::{paths, validate_package_name};
use crate::util::{FileLock, Filesystem, IntoUrl, IntoUrlWithBase, Rustc};
@ -257,7 +257,7 @@ impl Config {
let cwd =
env::current_dir().chain_err(|| "couldn't get the current directory of the process")?;
let homedir = homedir(&cwd).ok_or_else(|| {
failure::format_err!(
anyhow!(
"Cargo couldn't find your home directory. \
This probably means that $HOME was not set."
)
@ -360,7 +360,7 @@ impl Config {
let argv0 = env::args_os()
.map(PathBuf::from)
.next()
.ok_or_else(|| failure::format_err!("no argv[0]"))?;
.ok_or_else(|| anyhow!("no argv[0]"))?;
paths::resolve_executable(&argv0)
}
@ -469,6 +469,7 @@ impl Config {
/// This does NOT look at environment variables, the caller is responsible
/// for that.
fn get_cv(&self, key: &ConfigKey) -> CargoResult<Option<ConfigValue>> {
log::trace!("get cv {:?}", key);
let vals = self.values()?;
let mut parts = key.parts().enumerate();
let mut val = match vals.get(parts.next().unwrap().1) {
@ -614,7 +615,7 @@ impl Config {
/// Generate an error when the given value is the wrong type.
fn expected<T>(&self, ty: &str, key: &ConfigKey, val: &CV) -> CargoResult<T> {
val.expected(ty, &key.to_string())
.map_err(|e| failure::format_err!("invalid configuration for key `{}`\n{}", key, e))
.map_err(|e| anyhow!("invalid configuration for key `{}`\n{}", key, e))
}
/// Update the Config instance based on settings typically passed in on
@ -1180,8 +1181,8 @@ impl Config {
}
return Ok(PackageCacheLock(self));
fn maybe_readonly(err: &failure::Error) -> bool {
err.iter_chain().any(|err| {
fn maybe_readonly(err: &anyhow::Error) -> bool {
err.chain().any(|err| {
if let Some(io) = err.downcast_ref::<io::Error>() {
if io.kind() == io::ErrorKind::PermissionDenied {
return true;
@ -1202,21 +1203,21 @@ impl Config {
/// Internal error for serde errors.
#[derive(Debug)]
pub struct ConfigError {
error: failure::Error,
error: anyhow::Error,
definition: Option<Definition>,
}
impl ConfigError {
fn new(message: String, definition: Definition) -> ConfigError {
ConfigError {
error: failure::err_msg(message),
error: anyhow::Error::msg(message),
definition: Some(definition),
}
}
fn expected(key: &ConfigKey, expected: &str, found: &ConfigValue) -> ConfigError {
ConfigError {
error: failure::format_err!(
error: anyhow!(
"`{}` expected {}, but found a {}",
key,
expected,
@ -1228,32 +1229,31 @@ impl ConfigError {
fn missing(key: &ConfigKey) -> ConfigError {
ConfigError {
error: failure::format_err!("missing config key `{}`", key),
error: anyhow!("missing config key `{}`", key),
definition: None,
}
}
fn with_key_context(self, key: &ConfigKey, definition: Definition) -> ConfigError {
ConfigError {
error: failure::format_err!("could not load config key `{}`: {}", key, self),
error: anyhow!("could not load config key `{}`: {}", key, self),
definition: Some(definition),
}
}
}
impl std::error::Error for ConfigError {}
impl std::error::Error for ConfigError {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
self.error.source()
}
}
// Future note: currently, we cannot override `Fail::cause` (due to
// specialization) so we have no way to return the underlying causes. In the
// future, once this limitation is lifted, this should instead implement
// `cause` and avoid doing the cause formatting here.
impl fmt::Display for ConfigError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let message = errors::display_causes(&self.error);
if let Some(ref definition) = self.definition {
write!(f, "error in {}: {}", definition, message)
if let Some(definition) = &self.definition {
write!(f, "error in {}: {}", definition, self.error)
} else {
message.fmt(f)
self.error.fmt(f)
}
}
}
@ -1261,14 +1261,14 @@ impl fmt::Display for ConfigError {
impl serde::de::Error for ConfigError {
fn custom<T: fmt::Display>(msg: T) -> Self {
ConfigError {
error: failure::err_msg(msg.to_string()),
error: anyhow::Error::msg(msg.to_string()),
definition: None,
}
}
}
impl From<failure::Error> for ConfigError {
fn from(error: failure::Error) -> Self {
impl From<anyhow::Error> for ConfigError {
fn from(error: anyhow::Error) -> Self {
ConfigError {
error,
definition: None,

View file

@ -144,7 +144,7 @@ fn parse_links_overrides(
}
}
"warning" | "rerun-if-changed" | "rerun-if-env-changed" => {
failure::bail!("`{}` is not supported in build script overrides", key);
anyhow::bail!("`{}` is not supported in build script overrides", key);
}
_ => {
let val = value.string(key)?.0;

View file

@ -9,7 +9,7 @@ use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::Arc;
use std::thread::{self, JoinHandle};
use failure::{Error, ResultExt};
use anyhow::{Context, Error};
use log::warn;
use serde::{Deserialize, Serialize};
@ -229,7 +229,7 @@ pub struct StartedServer {
impl RustfixDiagnosticServer {
pub fn new() -> Result<Self, Error> {
let listener = TcpListener::bind("127.0.0.1:0")
.with_context(|_| "failed to bind TCP listener to manage locking")?;
.with_context(|| "failed to bind TCP listener to manage locking")?;
let addr = listener.local_addr()?;
Ok(RustfixDiagnosticServer { listener, addr })

View file

@ -4,18 +4,15 @@ use std::fmt;
use std::path::PathBuf;
use std::process::{ExitStatus, Output};
use std::str;
use clap;
use failure::{Context, Error, Fail};
use log::trace;
use anyhow::Error;
use crate::core::{TargetKind, Workspace};
use crate::ops::CompileOptions;
pub type CargoResult<T> = failure::Fallible<T>; // Alex's body isn't quite ready to give up "Result"
pub type CargoResult<T> = anyhow::Result<T>;
// TODO: should delete this trait and just use `with_context` instead
pub trait CargoResultExt<T, E> {
fn chain_err<F, D>(self, f: F) -> Result<T, Context<D>>
fn chain_err<F, D>(self, f: F) -> CargoResult<T>
where
F: FnOnce() -> D,
D: fmt::Display + Send + Sync + 'static;
@ -25,28 +22,33 @@ impl<T, E> CargoResultExt<T, E> for Result<T, E>
where
E: Into<Error>,
{
fn chain_err<F, D>(self, f: F) -> Result<T, Context<D>>
fn chain_err<F, D>(self, f: F) -> CargoResult<T>
where
F: FnOnce() -> D,
D: fmt::Display + Send + Sync + 'static,
{
self.map_err(|failure| {
let err = failure.into();
let context = f();
trace!("error: {}", err);
trace!("\tcontext: {}", context);
err.context(context)
})
self.map_err(|e| e.into().context(f()))
}
}
#[derive(Debug, Fail)]
#[fail(display = "failed to get 200 response from `{}`, got {}", url, code)]
#[derive(Debug)]
pub struct HttpNot200 {
pub code: u32,
pub url: String,
}
impl fmt::Display for HttpNot200 {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
f,
"failed to get 200 response from `{}`, got {}",
self.url, self.code
)
}
}
impl std::error::Error for HttpNot200 {}
pub struct Internal {
inner: Error,
}
@ -57,9 +59,9 @@ impl Internal {
}
}
impl Fail for Internal {
fn cause(&self) -> Option<&dyn Fail> {
self.inner.as_fail().cause()
impl std::error::Error for Internal {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
self.inner.source()
}
}
@ -103,9 +105,9 @@ impl ManifestError {
}
}
impl Fail for ManifestError {
fn cause(&self) -> Option<&dyn Fail> {
self.cause.as_fail().cause()
impl std::error::Error for ManifestError {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
self.cause.source()
}
}
@ -139,20 +141,26 @@ impl<'a> ::std::iter::FusedIterator for ManifestCauses<'a> {}
// =============================================================================
// Process errors
#[derive(Debug, Fail)]
#[fail(display = "{}", desc)]
#[derive(Debug)]
pub struct ProcessError {
pub desc: String,
pub exit: Option<ExitStatus>,
pub output: Option<Output>,
}
impl fmt::Display for ProcessError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.desc.fmt(f)
}
}
impl std::error::Error for ProcessError {}
// =============================================================================
// Cargo test errors.
/// Error when testcases fail
#[derive(Debug, Fail)]
#[fail(display = "{}", desc)]
#[derive(Debug)]
pub struct CargoTestError {
pub test: Test,
pub desc: String,
@ -160,6 +168,14 @@ pub struct CargoTestError {
pub causes: Vec<ProcessError>,
}
impl fmt::Display for CargoTestError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.desc.fmt(f)
}
}
impl std::error::Error for CargoTestError {}
#[derive(Debug)]
pub enum Test {
Multiple,
@ -232,14 +248,17 @@ pub type CliResult = Result<(), CliError>;
#[derive(Debug)]
pub struct CliError {
pub error: Option<failure::Error>,
pub error: Option<anyhow::Error>,
pub unknown: bool,
pub exit_code: i32,
}
impl CliError {
pub fn new(error: failure::Error, code: i32) -> CliError {
let unknown = error.downcast_ref::<Internal>().is_some();
pub fn new(error: anyhow::Error, code: i32) -> CliError {
// Specifically deref the error to a standard library error to only
// check the top-level error to see if it's an `Internal`, we don't want
// `anyhow::Error`'s behavior of recursively checking.
let unknown = (&*error).downcast_ref::<Internal>().is_some();
CliError {
error: Some(error),
exit_code: code,
@ -256,8 +275,8 @@ impl CliError {
}
}
impl From<failure::Error> for CliError {
fn from(err: failure::Error) -> CliError {
impl From<anyhow::Error> for CliError {
fn from(err: anyhow::Error) -> CliError {
CliError::new(err, 101)
}
}
@ -392,18 +411,10 @@ pub fn is_simple_exit_code(code: i32) -> bool {
code >= 0 && code <= 127
}
pub fn internal<S: fmt::Display>(error: S) -> failure::Error {
pub fn internal<S: fmt::Display>(error: S) -> anyhow::Error {
_internal(&error)
}
fn _internal(error: &dyn fmt::Display) -> failure::Error {
Internal::new(failure::format_err!("{}", error)).into()
}
pub fn display_causes(error: &Error) -> String {
error
.iter_chain()
.map(|e| e.to_string())
.collect::<Vec<_>>()
.join("\n\nCaused by:\n ")
fn _internal(error: &dyn fmt::Display) -> anyhow::Error {
Internal::new(anyhow::format_err!("{}", error)).into()
}

View file

@ -227,7 +227,7 @@ impl Filesystem {
paths::create_dir_all(path.parent().unwrap())?;
Ok(opts.open(&path)?)
} else {
Err(failure::Error::from(e))
Err(anyhow::Error::from(e))
}
})
.chain_err(|| format!("failed to open: {}", path.display()))?;
@ -318,7 +318,7 @@ fn acquire(
Err(e) => {
if e.raw_os_error() != lock_contended_error().raw_os_error() {
let e = failure::Error::from(e);
let e = anyhow::Error::from(e);
let cx = format!("failed to lock file: {}", path.display());
return Err(e.context(cx).into());
}

View file

@ -13,7 +13,7 @@ pub fn find_root_manifest_for_wd(cwd: &Path) -> CargoResult<PathBuf> {
}
}
failure::bail!(
anyhow::bail!(
"could not find `{}` in `{}` or any parent directory",
file,
cwd.display()
@ -27,6 +27,6 @@ pub fn find_project_manifest_exact(pwd: &Path, file: &str) -> CargoResult<PathBu
if manifest.exists() {
Ok(manifest)
} else {
failure::bail!("Could not find `{}` in `{}`", file, pwd.display())
anyhow::bail!("Could not find `{}` in `{}`", file, pwd.display())
}
}

View file

@ -12,14 +12,14 @@ pub trait IntoUrl {
impl<'a> IntoUrl for &'a str {
fn into_url(self) -> CargoResult<Url> {
Url::parse(self).map_err(|s| failure::format_err!("invalid url `{}`: {}", self, s))
Url::parse(self).map_err(|s| anyhow::format_err!("invalid url `{}`: {}", self, s))
}
}
impl<'a> IntoUrl for &'a Path {
fn into_url(self) -> CargoResult<Url> {
Url::from_file_path(self)
.map_err(|()| failure::format_err!("invalid path url `{}`", self.display()))
.map_err(|()| anyhow::format_err!("invalid path url `{}`", self.display()))
}
}

View file

@ -14,7 +14,7 @@ impl<'a> IntoUrlWithBase for &'a str {
let base_url = match base {
Some(base) => Some(
base.into_url()
.map_err(|s| failure::format_err!("invalid url `{}`: {}", self, s))?,
.map_err(|s| anyhow::format_err!("invalid url `{}`: {}", self, s))?,
),
None => None,
};
@ -22,7 +22,7 @@ impl<'a> IntoUrlWithBase for &'a str {
Url::options()
.base_url(base_url.as_ref())
.parse(self)
.map_err(|s| failure::format_err!("invalid url `{}`: {}", self, s))
.map_err(|s| anyhow::format_err!("invalid url `{}`: {}", self, s))
}
}

View file

@ -18,7 +18,7 @@ use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::{Arc, Mutex};
use std::thread::{self, JoinHandle};
use failure::{Error, ResultExt};
use anyhow::{Context, Error};
pub struct LockServer {
listener: TcpListener,
@ -45,7 +45,7 @@ struct ServerClient {
impl LockServer {
pub fn new() -> Result<LockServer, Error> {
let listener = TcpListener::bind("127.0.0.1:0")
.with_context(|_| "failed to bind TCP listener to manage locking")?;
.with_context(|| "failed to bind TCP listener to manage locking")?;
let addr = listener.local_addr()?;
Ok(LockServer {
listener,
@ -156,16 +156,16 @@ impl Drop for LockServerStarted {
impl LockServerClient {
pub fn lock(addr: &SocketAddr, name: impl AsRef<[u8]>) -> Result<LockServerClient, Error> {
let mut client = TcpStream::connect(&addr)
.with_context(|_| "failed to connect to parent lock server")?;
let mut client =
TcpStream::connect(&addr).with_context(|| "failed to connect to parent lock server")?;
client
.write_all(name.as_ref())
.and_then(|_| client.write_all(b"\n"))
.with_context(|_| "failed to write to lock server")?;
.with_context(|| "failed to write to lock server")?;
let mut buf = [0];
client
.read_exact(&mut buf)
.with_context(|_| "failed to acquire lock")?;
.with_context(|| "failed to acquire lock")?;
Ok(LockServerClient { _socket: client })
}
}

View file

@ -79,7 +79,7 @@ pub fn validate_package_name(name: &str, what: &str, help: &str) -> CargoResult<
.chars()
.find(|ch| !ch.is_alphanumeric() && *ch != '_' && *ch != '-')
{
failure::bail!("Invalid character `{}` in {}: `{}`{}", ch, what, name, help);
anyhow::bail!("Invalid character `{}` in {}: `{}`{}", ch, what, name, help);
}
Ok(())
}

View file

@ -1,7 +1,7 @@
use curl;
use git2;
use failure::Error;
use anyhow::Error;
use crate::util::errors::{CargoResult, HttpNot200};
use crate::util::Config;
@ -37,7 +37,7 @@ impl<'a> Retry<'a> {
}
fn maybe_spurious(err: &Error) -> bool {
for e in err.iter_chain() {
for e in err.chain() {
if let Some(git_err) = e.downcast_ref::<git2::Error>() {
match git_err.class() {
git2::ErrorClass::Net | git2::ErrorClass::Os => return true,
@ -121,16 +121,16 @@ fn with_retry_finds_nested_spurious_errors() {
//Error HTTP codes (5xx) are considered maybe_spurious and will prompt retry
//String error messages are not considered spurious
let error1 = failure::Error::from(HttpNot200 {
let error1 = anyhow::Error::from(HttpNot200 {
code: 501,
url: "Uri".to_string(),
});
let error1 = failure::Error::from(error1.context("A non-spurious wrapping err"));
let error2 = failure::Error::from(HttpNot200 {
let error1 = anyhow::Error::from(error1.context("A non-spurious wrapping err"));
let error2 = anyhow::Error::from(HttpNot200 {
code: 502,
url: "Uri".to_string(),
});
let error2 = failure::Error::from(error2.context("A second chained error"));
let error2 = anyhow::Error::from(error2.context("A second chained error"));
let mut results: Vec<CargoResult<()>> = vec![Ok(()), Err(error1), Err(error2)];
let config = Config::default().unwrap();
*config.shell() = Shell::from_write(Box::new(Vec::new()));

View file

@ -16,12 +16,12 @@ pub fn join_paths<T: AsRef<OsStr>>(paths: &[T], env: &str) -> CargoResult<OsStri
Err(e) => e,
};
let paths = paths.iter().map(Path::new).collect::<Vec<_>>();
let err = failure::Error::from(err);
let explain = Internal::new(failure::format_err!(
let err = anyhow::Error::from(err);
let explain = Internal::new(anyhow::format_err!(
"failed to join path array: {:?}",
paths
));
let err = failure::Error::from(err.context(explain));
let err = anyhow::Error::from(err.context(explain));
let more_explain = format!(
"failed to join search paths together\n\
Does ${} have an unterminated quote character?",
@ -91,7 +91,7 @@ pub fn normalize_path(path: &Path) -> PathBuf {
pub fn resolve_executable(exec: &Path) -> CargoResult<PathBuf> {
if exec.components().count() == 1 {
let paths = env::var_os("PATH").ok_or_else(|| failure::format_err!("no PATH"))?;
let paths = env::var_os("PATH").ok_or_else(|| anyhow::format_err!("no PATH"))?;
let candidates = env::split_paths(&paths).flat_map(|path| {
let candidate = path.join(&exec);
let with_exe = if env::consts::EXE_EXTENSION == "" {
@ -109,7 +109,7 @@ pub fn resolve_executable(exec: &Path) -> CargoResult<PathBuf> {
}
}
failure::bail!("no executable for `{}` found in PATH", exec.display())
anyhow::bail!("no executable for `{}` found in PATH", exec.display())
} else {
Ok(exec.canonicalize()?)
}
@ -118,7 +118,7 @@ pub fn resolve_executable(exec: &Path) -> CargoResult<PathBuf> {
pub fn read(path: &Path) -> CargoResult<String> {
match String::from_utf8(read_bytes(path)?) {
Ok(s) => Ok(s),
Err(_) => failure::bail!("path at `{}` was not valid utf-8", path.display()),
Err(_) => anyhow::bail!("path at `{}` was not valid utf-8", path.display()),
}
}
@ -209,7 +209,7 @@ pub fn path2bytes(path: &Path) -> CargoResult<&[u8]> {
pub fn path2bytes(path: &Path) -> CargoResult<&[u8]> {
match path.as_os_str().to_str() {
Some(s) => Ok(s.as_bytes()),
None => Err(failure::format_err!(
None => Err(anyhow::format_err!(
"invalid non-unicode path: {}",
path.display()
)),
@ -226,7 +226,7 @@ pub fn bytes2path(bytes: &[u8]) -> CargoResult<PathBuf> {
use std::str;
match str::from_utf8(bytes) {
Ok(s) => Ok(PathBuf::from(s)),
Err(..) => Err(failure::format_err!("invalid non-unicode path")),
Err(..) => Err(anyhow::format_err!("invalid non-unicode path")),
}
}

View file

@ -1,3 +1,7 @@
use crate::util::{process_error, read2, CargoResult, CargoResultExt};
use anyhow::bail;
use jobserver::Client;
use shell_escape::escape;
use std::collections::HashMap;
use std::env;
use std::ffi::{OsStr, OsString};
@ -5,12 +9,6 @@ use std::fmt;
use std::path::Path;
use std::process::{Command, Output, Stdio};
use failure::Fail;
use jobserver::Client;
use shell_escape::escape;
use crate::util::{process_error, read2, CargoResult, CargoResultExt};
/// A builder object for an external process, similar to `std::process::Command`.
#[derive(Clone, Debug)]
pub struct ProcessBuilder {
@ -290,14 +288,13 @@ impl ProcessBuilder {
Some(output.status),
to_print,
);
return Err(cx.context(e).into());
bail!(anyhow::Error::new(cx).context(e));
} else if !output.status.success() {
return Err(process_error(
bail!(process_error(
&format!("process didn't exit successfully: {}", self),
Some(output.status),
to_print,
)
.into());
));
}
}
@ -352,7 +349,7 @@ mod imp {
pub fn exec_replace(process_builder: &ProcessBuilder) -> CargoResult<()> {
let mut command = process_builder.build_command();
let error = command.exec();
Err(failure::Error::from(error)
Err(anyhow::Error::from(error)
.context(process_error(
&format!("could not execute process {}", process_builder),
None,

View file

@ -54,7 +54,7 @@ impl Rustc {
.find(|l| l.starts_with("host: "))
.map(|l| &l[6..])
.ok_or_else(|| {
failure::format_err!(
anyhow::format_err!(
"`rustc -vV` didn't have a line for `host:`, got:\n{}",
verbose_version
)
@ -250,7 +250,7 @@ fn rustc_fingerprint(path: &Path, rustup_rustc: &Path) -> CargoResult<u64> {
.with_extension(env::consts::EXE_EXTENSION);
paths::mtime(&real_rustc)?.hash(&mut hasher);
}
(true, _, _) => failure::bail!("probably rustup rustc, but without rustup's env vars"),
(true, _, _) => anyhow::bail!("probably rustup rustc, but without rustup's env vars"),
_ => (),
}

View file

@ -15,7 +15,7 @@ impl<'a> ToSemver for &'a str {
fn to_semver(self) -> CargoResult<Version> {
match Version::parse(self) {
Ok(v) => Ok(v),
Err(..) => Err(failure::format_err!("cannot parse '{}' as a semver", self)),
Err(..) => Err(anyhow::format_err!("cannot parse '{}' as a semver", self)),
}
}
}

View file

@ -5,8 +5,8 @@ use std::path::{Path, PathBuf};
use std::rc::Rc;
use std::str;
use anyhow::{anyhow, bail};
use cargo_platform::Platform;
use failure::bail;
use log::{debug, trace};
use semver::{self, VersionReq};
use serde::de;
@ -162,7 +162,7 @@ and this will become a hard error in the future.",
return Ok(ret);
}
let first_error = failure::Error::from(first_error);
let first_error = anyhow::Error::from(first_error);
Err(first_error.context("could not parse input as TOML").into())
}
@ -546,22 +546,22 @@ impl TomlProfile {
.chars()
.find(|ch| !ch.is_alphanumeric() && *ch != '_' && *ch != '-')
{
failure::bail!("Invalid character `{}` in {}: `{}`", ch, what, name);
bail!("Invalid character `{}` in {}: `{}`", ch, what, name);
}
match name {
"package" | "build" => {
failure::bail!("Invalid {}: `{}`", what, name);
bail!("Invalid {}: `{}`", what, name);
}
"debug" if what == "profile" => {
if what == "profile name" {
// Allowed, but will emit warnings
} else {
failure::bail!("Invalid {}: `{}`", what, name);
bail!("Invalid {}: `{}`", what, name);
}
}
"doc" if what == "dir-name" => {
failure::bail!("Invalid {}: `{}`", what, name);
bail!("Invalid {}: `{}`", what, name);
}
_ => {}
}
@ -973,7 +973,7 @@ impl TomlManifest {
let features = Features::new(cargo_features, &mut warnings)?;
let project = me.project.as_ref().or_else(|| me.package.as_ref());
let project = project.ok_or_else(|| failure::format_err!("no `package` section found"))?;
let project = project.ok_or_else(|| anyhow!("no `package` section found"))?;
let package_name = project.name.trim();
if package_name.is_empty() {
@ -1367,7 +1367,7 @@ impl TomlManifest {
let mut dep = replacement.to_dependency(spec.name().as_str(), cx, None)?;
{
let version = spec.version().ok_or_else(|| {
failure::format_err!(
anyhow!(
"replacements must specify a version \
to replace, but `{}` does not",
spec

View file

@ -54,7 +54,7 @@ pub fn targets(
.package
.as_ref()
.or_else(|| manifest.project.as_ref())
.ok_or_else(|| failure::format_err!("manifest has no `package` (or `project`)"))?;
.ok_or_else(|| anyhow::format_err!("manifest has no `package` (or `project`)"))?;
targets.extend(clean_bins(
features,
@ -101,7 +101,7 @@ pub fn targets(
// processing the custom build script
if let Some(custom_build) = manifest.maybe_custom_build(custom_build, package_root) {
if metabuild.is_some() {
failure::bail!("cannot specify both `metabuild` and `build`");
anyhow::bail!("cannot specify both `metabuild` and `build`");
}
let name = format!(
"build-script-{}",
@ -121,7 +121,7 @@ pub fn targets(
let bdeps = manifest.build_dependencies.as_ref();
for name in &metabuild.0 {
if !bdeps.map_or(false, |bd| bd.contains_key(name)) {
failure::bail!(
anyhow::bail!(
"metabuild package `{}` must be specified in `build-dependencies`",
name
);
@ -151,7 +151,7 @@ fn clean_lib(
if let Some(ref name) = lib.name {
// XXX: other code paths dodge this validation
if name.contains('-') {
failure::bail!("library target names cannot contain hyphens: {}", name)
anyhow::bail!("library target names cannot contain hyphens: {}", name)
}
}
Some(TomlTarget {
@ -187,7 +187,7 @@ fn clean_lib(
));
legacy_path
} else {
failure::bail!(
anyhow::bail!(
"can't find library `{}`, \
rename file to `src/lib.rs` or specify lib.path",
lib.name()
@ -219,12 +219,12 @@ fn clean_lib(
lib.name()
));
if kinds.len() > 1 {
failure::bail!("cannot mix `proc-macro` crate type with others");
anyhow::bail!("cannot mix `proc-macro` crate type with others");
}
vec![LibKind::ProcMacro]
}
(_, Some(true), Some(true)) => {
failure::bail!("`lib.plugin` and `lib.proc-macro` cannot both be `true`")
anyhow::bail!("`lib.plugin` and `lib.proc-macro` cannot both be `true`")
}
(Some(kinds), _, _) => kinds.iter().map(|s| s.into()).collect(),
(None, Some(true), _) => vec![LibKind::Dylib],
@ -287,7 +287,7 @@ fn clean_bins(
}
if compiler::is_bad_artifact_name(&name) {
failure::bail!("the binary target name `{}` is forbidden", name)
anyhow::bail!("the binary target name `{}` is forbidden", name)
}
}
@ -310,7 +310,7 @@ fn clean_bins(
});
let path = match path {
Ok(path) => path,
Err(e) => failure::bail!("{}", e),
Err(e) => anyhow::bail!("{}", e),
};
let mut target =
@ -727,10 +727,10 @@ fn validate_has_name(
match target.name {
Some(ref name) => {
if name.trim().is_empty() {
failure::bail!("{} target names cannot be empty", target_kind_human)
anyhow::bail!("{} target names cannot be empty", target_kind_human)
}
}
None => failure::bail!(
None => anyhow::bail!(
"{} target {}.name is required",
target_kind_human,
target_kind
@ -745,7 +745,7 @@ fn validate_unique_names(targets: &[TomlTarget], target_kind: &str) -> CargoResu
let mut seen = HashSet::new();
for name in targets.iter().map(|e| e.name()) {
if !seen.insert(name.clone()) {
failure::bail!(
anyhow::bail!(
"found duplicate {target_kind} name {name}, \
but all {target_kind} targets must have a unique name",
target_kind = target_kind,

View file

@ -1,7 +1,7 @@
use crate::core::{Target, Workspace};
use crate::ops::CompileOptions;
use crate::util::CargoResult;
use anyhow::bail;
use std::fmt::Write;
fn get_available_targets<'a>(
@ -46,7 +46,7 @@ fn print_available(
writeln!(output, " {}", target.name())?;
}
}
Err(failure::err_msg(output))
bail!("{}", output)
}
pub fn print_available_examples(

View file

@ -184,13 +184,20 @@ fn symlink_config_to_config_toml() {
t!(symlink_file(&toml_path, &symlink_path));
}
pub fn assert_error<E: Borrow<failure::Error>>(error: E, msgs: &str) {
pub fn assert_error<E: Borrow<anyhow::Error>>(error: E, msgs: &str) {
let causes = error
.borrow()
.iter_chain()
.map(|e| e.to_string())
.chain()
.enumerate()
.map(|(i, e)| {
if i == 0 {
e.to_string()
} else {
format!("Caused by:\n {}", e)
}
})
.collect::<Vec<_>>()
.join("\n");
.join("\n\n");
assert_match(msgs, &causes);
}
@ -516,7 +523,9 @@ c = ['c']
config.unwrap_err(),
"\
failed to merge --config key `a` into `[..]/.cargo/config`
failed to merge config value from `--config cli option` into `[..]/.cargo/config`: \
Caused by:
failed to merge config value from `--config cli option` into `[..]/.cargo/config`: \
expected boolean, but found array",
);

View file

@ -275,7 +275,9 @@ fn bad_parse() {
config.unwrap_err(),
"\
failed to parse --config argument `abc`
expected an equals, found eof at line 1 column 4",
Caused by:
expected an equals, found eof at line 1 column 4",
);
}
@ -306,8 +308,12 @@ fn bad_cv_convert() {
config.unwrap_err(),
"\
failed to convert --config argument `a=2019-12-01`
failed to parse key `a`
found TOML configuration value of unknown type `datetime`",
Caused by:
failed to parse key `a`
Caused by:
found TOML configuration value of unknown type `datetime`",
);
}
@ -323,8 +329,12 @@ fn fail_to_merge_multiple_args() {
config.unwrap_err(),
"\
failed to merge --config argument `foo=['a']`
failed to merge key `foo` between --config cli option and --config cli option
failed to merge config value from `--config cli option` into `--config cli option`: \
expected string, but found array",
Caused by:
failed to merge key `foo` between --config cli option and --config cli option
Caused by:
failed to merge config value from `--config cli option` into `--config cli option`: \
expected string, but found array",
);
}

View file

@ -169,9 +169,15 @@ fn cli_include_failed() {
&format!(
"\
failed to load --config include
failed to load config include `foobar` from `--config cli option`
failed to read configuration file `[..]/foobar`
{}",
Caused by:
failed to load config include `foobar` from `--config cli option`
Caused by:
failed to read configuration file `[..]/foobar`
Caused by:
{}",
NO_SUCH_FILE_ERR_MSG
),
);
@ -196,7 +202,9 @@ fn cli_merge_failed() {
config.unwrap_err(),
"\
failed to merge --config key `foo` into `[..]/.cargo/config`
failed to merge config value from `[..]/.cargo/other` into `[..]/.cargo/config`: \
expected array, but found string",
Caused by:
failed to merge config value from `[..]/.cargo/other` into `[..]/.cargo/config`: \
expected array, but found string",
);
}

View file

@ -1065,10 +1065,8 @@ fn new_warning_with_corrupt_ws() {
failed to parse manifest at `[..]foo/Cargo.toml`
Caused by:
could not parse input as TOML
Caused by:
expected an equals, found eof at line 1 column 5
0: could not parse input as TOML
1: expected an equals, found eof at line 1 column 5
Created binary (application) `bar` package
",
)