mirror of
https://github.com/crate-ci/typos.git
synced 2025-01-10 16:54:51 -05:00
Merge pull request #807 from epage/error
fix(cli): Add path to filesystem errors
This commit is contained in:
commit
ed607fcc7d
4 changed files with 44 additions and 15 deletions
|
@ -31,7 +31,13 @@ impl Config {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn from_file(path: &std::path::Path) -> Result<Self, anyhow::Error> {
|
pub fn from_file(path: &std::path::Path) -> Result<Self, anyhow::Error> {
|
||||||
let s = std::fs::read_to_string(path)?;
|
let s = std::fs::read_to_string(path).map_err(|err| {
|
||||||
|
let kind = err.kind();
|
||||||
|
std::io::Error::new(
|
||||||
|
kind,
|
||||||
|
format!("could not read config at `{}`", path.display()),
|
||||||
|
)
|
||||||
|
})?;
|
||||||
Self::from_toml(&s)
|
Self::from_toml(&s)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -431,10 +431,14 @@ fn read_file(
|
||||||
) -> Result<(Vec<u8>, content_inspector::ContentType), std::io::Error> {
|
) -> Result<(Vec<u8>, content_inspector::ContentType), std::io::Error> {
|
||||||
let buffer = if path == std::path::Path::new("-") {
|
let buffer = if path == std::path::Path::new("-") {
|
||||||
let mut buffer = Vec::new();
|
let mut buffer = Vec::new();
|
||||||
report_result(std::io::stdin().read_to_end(&mut buffer), reporter)?;
|
report_result(
|
||||||
|
std::io::stdin().read_to_end(&mut buffer),
|
||||||
|
Some(path),
|
||||||
|
reporter,
|
||||||
|
)?;
|
||||||
buffer
|
buffer
|
||||||
} else {
|
} else {
|
||||||
report_result(std::fs::read(path), reporter)?
|
report_result(std::fs::read(path), Some(path), reporter)?
|
||||||
};
|
};
|
||||||
|
|
||||||
let content_type = content_inspector::inspect(&buffer);
|
let content_type = content_inspector::inspect(&buffer);
|
||||||
|
@ -460,7 +464,7 @@ fn read_file(
|
||||||
encoding_rs::DecoderResult::InputEmpty => Ok(decoded),
|
encoding_rs::DecoderResult::InputEmpty => Ok(decoded),
|
||||||
_ => Err(format!("invalid UTF-16LE encoding at byte {} in {}", written, path.display())),
|
_ => Err(format!("invalid UTF-16LE encoding at byte {} in {}", written, path.display())),
|
||||||
};
|
};
|
||||||
let buffer = report_result(decoded, reporter)?;
|
let buffer = report_result(decoded, Some(path), reporter)?;
|
||||||
(buffer.into_bytes(), content_type)
|
(buffer.into_bytes(), content_type)
|
||||||
}
|
}
|
||||||
content_inspector::ContentType::UTF_16BE => {
|
content_inspector::ContentType::UTF_16BE => {
|
||||||
|
@ -473,7 +477,7 @@ fn read_file(
|
||||||
encoding_rs::DecoderResult::InputEmpty => Ok(decoded),
|
encoding_rs::DecoderResult::InputEmpty => Ok(decoded),
|
||||||
_ => Err(format!("invalid UTF-16BE encoding at byte {} in {}", written, path.display())),
|
_ => Err(format!("invalid UTF-16BE encoding at byte {} in {}", written, path.display())),
|
||||||
};
|
};
|
||||||
let buffer = report_result(decoded, reporter)?;
|
let buffer = report_result(decoded, Some(path), reporter)?;
|
||||||
(buffer.into_bytes(), content_type)
|
(buffer.into_bytes(), content_type)
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
@ -496,7 +500,7 @@ fn write_file(
|
||||||
| content_inspector::ContentType::UTF_8
|
| content_inspector::ContentType::UTF_8
|
||||||
| content_inspector::ContentType::UTF_8_BOM => buffer,
|
| content_inspector::ContentType::UTF_8_BOM => buffer,
|
||||||
content_inspector::ContentType::UTF_16LE => {
|
content_inspector::ContentType::UTF_16LE => {
|
||||||
let buffer = report_result(String::from_utf8(buffer), reporter)?;
|
let buffer = report_result(String::from_utf8(buffer), Some(path), reporter)?;
|
||||||
if buffer.is_empty() {
|
if buffer.is_empty() {
|
||||||
// Error occurred, don't clear out the file
|
// Error occurred, don't clear out the file
|
||||||
return Ok(());
|
return Ok(());
|
||||||
|
@ -509,7 +513,7 @@ fn write_file(
|
||||||
encoded.into_owned()
|
encoded.into_owned()
|
||||||
}
|
}
|
||||||
content_inspector::ContentType::UTF_16BE => {
|
content_inspector::ContentType::UTF_16BE => {
|
||||||
let buffer = report_result(String::from_utf8(buffer), reporter)?;
|
let buffer = report_result(String::from_utf8(buffer), Some(path), reporter)?;
|
||||||
if buffer.is_empty() {
|
if buffer.is_empty() {
|
||||||
// Error occurred, don't clear out the file
|
// Error occurred, don't clear out the file
|
||||||
return Ok(());
|
return Ok(());
|
||||||
|
@ -524,9 +528,9 @@ fn write_file(
|
||||||
};
|
};
|
||||||
|
|
||||||
if path == std::path::Path::new("-") {
|
if path == std::path::Path::new("-") {
|
||||||
report_result(std::io::stdout().write_all(&buffer), reporter)?;
|
report_result(std::io::stdout().write_all(&buffer), Some(path), reporter)?;
|
||||||
} else {
|
} else {
|
||||||
report_result(std::fs::write(path, buffer), reporter)?;
|
report_result(std::fs::write(path, buffer), Some(path), reporter)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -547,20 +551,26 @@ fn check_bytes<'a>(
|
||||||
|
|
||||||
fn report_result<T: Default, E: ToString>(
|
fn report_result<T: Default, E: ToString>(
|
||||||
value: Result<T, E>,
|
value: Result<T, E>,
|
||||||
|
path: Option<&std::path::Path>,
|
||||||
reporter: &dyn report::Report,
|
reporter: &dyn report::Report,
|
||||||
) -> Result<T, std::io::Error> {
|
) -> Result<T, std::io::Error> {
|
||||||
let buffer = match value {
|
let buffer = match value {
|
||||||
Ok(value) => value,
|
Ok(value) => value,
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
report_error(err, reporter)?;
|
report_error(err, path, reporter)?;
|
||||||
Default::default()
|
Default::default()
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
Ok(buffer)
|
Ok(buffer)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn report_error<E: ToString>(err: E, reporter: &dyn report::Report) -> Result<(), std::io::Error> {
|
fn report_error<E: ToString>(
|
||||||
let msg = report::Error::new(err.to_string());
|
err: E,
|
||||||
|
path: Option<&std::path::Path>,
|
||||||
|
reporter: &dyn report::Report,
|
||||||
|
) -> Result<(), std::io::Error> {
|
||||||
|
let mut msg = report::Error::new(err.to_string());
|
||||||
|
msg.context = path.map(|path| report::Context::Path(report::PathContext { path }));
|
||||||
reporter.report(msg.into())?;
|
reporter.report(msg.into())?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -672,7 +682,7 @@ fn walk_entry(
|
||||||
let entry = match entry {
|
let entry = match entry {
|
||||||
Ok(entry) => entry,
|
Ok(entry) => entry,
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
report_error(err, reporter)?;
|
report_error(err, None, reporter)?;
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -686,10 +696,15 @@ fn walk_entry(
|
||||||
let explicit = entry.depth() == 0;
|
let explicit = entry.depth() == 0;
|
||||||
let (path, lookup_path) = if entry.is_stdin() {
|
let (path, lookup_path) = if entry.is_stdin() {
|
||||||
let path = std::path::Path::new("-");
|
let path = std::path::Path::new("-");
|
||||||
(path, std::env::current_dir()?)
|
let cwd = std::env::current_dir().map_err(|err| {
|
||||||
|
let kind = err.kind();
|
||||||
|
std::io::Error::new(kind, "no current working directory".to_owned())
|
||||||
|
})?;
|
||||||
|
(path, cwd)
|
||||||
} else {
|
} else {
|
||||||
let path = entry.path();
|
let path = entry.path();
|
||||||
(path, path.canonicalize()?)
|
let abs_path = report_result(path.canonicalize(), Some(path), reporter)?;
|
||||||
|
(path, abs_path)
|
||||||
};
|
};
|
||||||
let policy = engine.policy(&lookup_path);
|
let policy = engine.policy(&lookup_path);
|
||||||
checks.check_file(path, explicit, &policy, reporter)?;
|
checks.check_file(path, explicit, &policy, reporter)?;
|
||||||
|
|
0
crates/typos-cli/tests/cmd/missing-config.in/.keep
Normal file
0
crates/typos-cli/tests/cmd/missing-config.in/.keep
Normal file
8
crates/typos-cli/tests/cmd/missing-config.toml
Normal file
8
crates/typos-cli/tests/cmd/missing-config.toml
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
bin.name = "typos"
|
||||||
|
args = "--config foo.toml"
|
||||||
|
status.code = 78
|
||||||
|
stdin = ""
|
||||||
|
# stdout doesn't have stable order
|
||||||
|
stderr = """
|
||||||
|
could not read config at `foo.toml`
|
||||||
|
"""
|
Loading…
Reference in a new issue