diff --git a/rust/Cargo.lock b/rust/Cargo.lock --- a/rust/Cargo.lock +++ b/rust/Cargo.lock @@ -286,9 +286,9 @@ [[package]] name = "format-bytes" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8030ff4b04f0ca1c612d6fe49f2fc18caf56fb01497cb370b41cfd36d89b3b06" +checksum = "1c4e89040c7fd7b4e6ba2820ac705a45def8a0c098ec78d170ae88f1ef1d5762" dependencies = [ "format-bytes-macros", "proc-macro-hack", diff --git a/rust/hg-core/Cargo.toml b/rust/hg-core/Cargo.toml --- a/rust/hg-core/Cargo.toml +++ b/rust/hg-core/Cargo.toml @@ -28,7 +28,7 @@ memmap = "0.7.0" zstd = "0.5.3" rust-crypto = "0.2.36" -format-bytes = "0.2.0" +format-bytes = "0.2.2" # We don't use the `miniz-oxide` backend to not change rhg benchmarks and until # we have a clearer view of which backend is the fastest. diff --git a/rust/hg-core/src/config/layer.rs b/rust/hg-core/src/config/layer.rs --- a/rust/hg-core/src/config/layer.rs +++ b/rust/hg-core/src/config/layer.rs @@ -7,7 +7,7 @@ // This software may be used and distributed according to the terms of the // GNU General Public License version 2 or any later version. -use crate::errors::{HgError, IoResultExt}; +use crate::errors::HgError; use crate::utils::files::{get_bytes_from_path, get_path_from_bytes}; use format_bytes::{format_bytes, write_bytes, DisplayBytes}; use lazy_static::lazy_static; @@ -74,7 +74,7 @@ layer.add(section, item, value, None); } else { Err(HgError::abort(format!( - "malformed --config option: '{}' \ + "abort: malformed --config option: '{}' \ (use --config section.name=value)", String::from_utf8_lossy(arg), )))? @@ -147,6 +147,7 @@ let mut section = b"".to_vec(); while let Some((index, bytes)) = lines_iter.next() { + let line = Some(index + 1); if let Some(m) = INCLUDE_RE.captures(&bytes) { let filename_bytes = &m[1]; // `Path::parent` only fails for the root directory, @@ -158,8 +159,17 @@ // `Path::join` with an absolute argument correctly ignores the // base path let filename = dir.join(&get_path_from_bytes(&filename_bytes)); - let data = - std::fs::read(&filename).when_reading_file(&filename)?; + let data = std::fs::read(&filename).map_err(|io_error| { + ConfigParseError { + origin: ConfigOrigin::File(src.to_owned()), + line, + message: format_bytes!( + b"cannot include {} ({})", + filename_bytes, + format_bytes::Utf8(io_error) + ), + } + })?; layers.push(current_layer); layers.extend(Self::parse(&filename, &data)?); current_layer = Self::new(ConfigOrigin::File(src.to_owned())); @@ -184,12 +194,7 @@ }; lines_iter.next(); } - current_layer.add( - section.clone(), - item, - value, - Some(index + 1), - ); + current_layer.add(section.clone(), item, value, line); } else if let Some(m) = UNSET_RE.captures(&bytes) { if let Some(map) = current_layer.sections.get_mut(§ion) { map.remove(&m[1]); @@ -202,7 +207,7 @@ }; return Err(ConfigParseError { origin: ConfigOrigin::File(src.to_owned()), - line: Some(index + 1), + line, message, } .into()); diff --git a/rust/hg-core/src/errors.rs b/rust/hg-core/src/errors.rs --- a/rust/hg-core/src/errors.rs +++ b/rust/hg-core/src/errors.rs @@ -81,7 +81,7 @@ write!(f, "abort: {}: {}", context, error) } HgError::CorruptedRepository(explanation) => { - write!(f, "abort: corrupted repository: {}", explanation) + write!(f, "abort: {}", explanation) } HgError::UnsupportedFeature(explanation) => { write!(f, "unsupported feature: {}", explanation) diff --git a/rust/hg-core/src/repo.rs b/rust/hg-core/src/repo.rs --- a/rust/hg-core/src/repo.rs +++ b/rust/hg-core/src/repo.rs @@ -141,20 +141,22 @@ if share_safe && !source_is_share_safe { return Err(match config - .get(b"safe-mismatch", b"source-not-safe") + .get(b"share", b"safe-mismatch.source-not-safe") { Some(b"abort") | None => HgError::abort( - "share source does not support share-safe requirement", + "abort: share source does not support share-safe requirement\n\ + (see `hg help config.format.use-share-safe` for more information)", ), _ => HgError::unsupported("share-safe downgrade"), } .into()); } else if source_is_share_safe && !share_safe { return Err( - match config.get(b"safe-mismatch", b"source-safe") { + match config.get(b"share", b"safe-mismatch.source-safe") { Some(b"abort") | None => HgError::abort( - "version mismatch: source uses share-safe \ - functionality while the current share does not", + "abort: version mismatch: source uses share-safe \ + functionality while the current share does not\n\ + (see `hg help config.format.use-share-safe` for more information)", ), _ => HgError::unsupported("share-safe upgrade"), } diff --git a/rust/rhg/src/error.rs b/rust/rhg/src/error.rs --- a/rust/rhg/src/error.rs +++ b/rust/rhg/src/error.rs @@ -72,7 +72,7 @@ match error { RepoError::NotFound { at } => CommandError::Abort { message: format_bytes!( - b"repository {} not found", + b"abort: repository {} not found", get_bytes_from_path(at) ), }, diff --git a/tests/test-rhg.t b/tests/test-rhg.t --- a/tests/test-rhg.t +++ b/tests/test-rhg.t @@ -187,7 +187,7 @@ $ echo -e '\xFF' >> .hg/requires $ $NO_FALLBACK rhg debugrequirements - abort: corrupted repository: parse error in 'requires' file + abort: parse error in 'requires' file [255] Persistent nodemap