mirror of
https://github.com/crate-ci/typos.git
synced 2024-11-26 02:51:08 -05:00
feat: Support '-' for stdin
This helps with tool integration. Fixes #195
This commit is contained in:
parent
ed58935d02
commit
1c4d2ac32b
2 changed files with 51 additions and 16 deletions
|
@ -1,5 +1,7 @@
|
||||||
use bstr::ByteSlice;
|
use bstr::ByteSlice;
|
||||||
use encoding::Encoding;
|
use encoding::Encoding;
|
||||||
|
use std::io::Read;
|
||||||
|
use std::io::Write;
|
||||||
|
|
||||||
use crate::report;
|
use crate::report;
|
||||||
use typos::tokens;
|
use typos::tokens;
|
||||||
|
@ -207,7 +209,7 @@ impl FileChecker for FixTypos {
|
||||||
reporter.report(msg.into())?;
|
reporter.report(msg.into())?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if !fixes.is_empty() {
|
if !fixes.is_empty() || path == std::path::Path::new("-") {
|
||||||
let buffer = fix_buffer(buffer, fixes.into_iter());
|
let buffer = fix_buffer(buffer, fixes.into_iter());
|
||||||
write_file(path, content_type, buffer, reporter)?;
|
write_file(path, content_type, buffer, reporter)?;
|
||||||
}
|
}
|
||||||
|
@ -504,7 +506,13 @@ pub fn read_file(
|
||||||
path: &std::path::Path,
|
path: &std::path::Path,
|
||||||
reporter: &dyn report::Report,
|
reporter: &dyn report::Report,
|
||||||
) -> Result<(Vec<u8>, content_inspector::ContentType), std::io::Error> {
|
) -> Result<(Vec<u8>, content_inspector::ContentType), std::io::Error> {
|
||||||
let buffer = report_error(std::fs::read(path), reporter)?;
|
let buffer = if path == std::path::Path::new("-") {
|
||||||
|
let mut buffer = Vec::new();
|
||||||
|
report_result(std::io::stdin().read_to_end(&mut buffer), reporter)?;
|
||||||
|
buffer
|
||||||
|
} else {
|
||||||
|
report_result(std::fs::read(path), reporter)?
|
||||||
|
};
|
||||||
|
|
||||||
let content_type = content_inspector::inspect(&buffer);
|
let content_type = content_inspector::inspect(&buffer);
|
||||||
|
|
||||||
|
@ -520,11 +528,11 @@ pub fn read_file(
|
||||||
(buffer, content_type)
|
(buffer, content_type)
|
||||||
},
|
},
|
||||||
content_inspector::ContentType::UTF_16LE => {
|
content_inspector::ContentType::UTF_16LE => {
|
||||||
let buffer = report_error(encoding::all::UTF_16LE.decode(&buffer, encoding::DecoderTrap::Strict), reporter)?;
|
let buffer = report_result(encoding::all::UTF_16LE.decode(&buffer, encoding::DecoderTrap::Strict), reporter)?;
|
||||||
(buffer.into_bytes(), content_type)
|
(buffer.into_bytes(), content_type)
|
||||||
}
|
}
|
||||||
content_inspector::ContentType::UTF_16BE => {
|
content_inspector::ContentType::UTF_16BE => {
|
||||||
let buffer = report_error(encoding::all::UTF_16BE.decode(&buffer, encoding::DecoderTrap::Strict), reporter)?;
|
let buffer = report_result(encoding::all::UTF_16BE.decode(&buffer, encoding::DecoderTrap::Strict), reporter)?;
|
||||||
(buffer.into_bytes(), content_type)
|
(buffer.into_bytes(), content_type)
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
@ -547,49 +555,58 @@ pub 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_error(String::from_utf8(buffer), reporter)?;
|
let buffer = report_result(String::from_utf8(buffer), 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(());
|
||||||
}
|
}
|
||||||
report_error(
|
report_result(
|
||||||
encoding::all::UTF_16LE.encode(&buffer, encoding::EncoderTrap::Strict),
|
encoding::all::UTF_16LE.encode(&buffer, encoding::EncoderTrap::Strict),
|
||||||
reporter,
|
reporter,
|
||||||
)?
|
)?
|
||||||
}
|
}
|
||||||
content_inspector::ContentType::UTF_16BE => {
|
content_inspector::ContentType::UTF_16BE => {
|
||||||
let buffer = report_error(String::from_utf8(buffer), reporter)?;
|
let buffer = report_result(String::from_utf8(buffer), 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(());
|
||||||
}
|
}
|
||||||
report_error(
|
report_result(
|
||||||
encoding::all::UTF_16BE.encode(&buffer, encoding::EncoderTrap::Strict),
|
encoding::all::UTF_16BE.encode(&buffer, encoding::EncoderTrap::Strict),
|
||||||
reporter,
|
reporter,
|
||||||
)?
|
)?
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
report_error(std::fs::write(path, buffer), reporter)?;
|
if path == std::path::Path::new("-") {
|
||||||
|
report_result(std::io::stdout().write_all(&buffer), reporter)?;
|
||||||
|
} else {
|
||||||
|
report_result(std::fs::write(path, buffer), reporter)?;
|
||||||
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn report_error<T: Default, E: ToString>(
|
fn report_result<T: Default, E: ToString>(
|
||||||
value: Result<T, E>,
|
value: Result<T, E>,
|
||||||
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) => {
|
||||||
let msg = report::Error::new(err.to_string());
|
report_error(err, reporter)?;
|
||||||
reporter.report(msg.into())?;
|
|
||||||
Default::default()
|
Default::default()
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
Ok(buffer)
|
Ok(buffer)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn report_error<E: ToString>(err: E, reporter: &dyn report::Report) -> Result<(), std::io::Error> {
|
||||||
|
let msg = report::Error::new(err.to_string());
|
||||||
|
reporter.report(msg.into())?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
struct AccumulateLineNum {
|
struct AccumulateLineNum {
|
||||||
line_num: usize,
|
line_num: usize,
|
||||||
last_offset: usize,
|
last_offset: usize,
|
||||||
|
@ -697,10 +714,21 @@ fn walk_entry(
|
||||||
dictionary: &dyn typos::Dictionary,
|
dictionary: &dyn typos::Dictionary,
|
||||||
reporter: &dyn report::Report,
|
reporter: &dyn report::Report,
|
||||||
) -> Result<(), ignore::Error> {
|
) -> Result<(), ignore::Error> {
|
||||||
let entry = entry?;
|
let entry = match entry {
|
||||||
|
Ok(entry) => entry,
|
||||||
|
Err(err) => {
|
||||||
|
report_error(err, reporter)?;
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
};
|
||||||
if entry.file_type().map(|t| t.is_file()).unwrap_or(true) {
|
if entry.file_type().map(|t| t.is_file()).unwrap_or(true) {
|
||||||
let explicit = entry.depth() == 0;
|
let explicit = entry.depth() == 0;
|
||||||
checks.check_file(entry.path(), explicit, parser, dictionary, reporter)?;
|
let path = if entry.is_stdin() {
|
||||||
|
std::path::Path::new("-")
|
||||||
|
} else {
|
||||||
|
entry.path()
|
||||||
|
};
|
||||||
|
checks.check_file(path, explicit, parser, dictionary, reporter)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
11
src/main.rs
11
src/main.rs
|
@ -34,6 +34,7 @@ fn run() -> proc_exit::ExitResult {
|
||||||
};
|
};
|
||||||
|
|
||||||
init_logging(args.verbose.log_level());
|
init_logging(args.verbose.log_level());
|
||||||
|
let global_cwd = std::env::current_dir()?;
|
||||||
|
|
||||||
let config = if let Some(path) = args.custom_config.as_ref() {
|
let config = if let Some(path) = args.custom_config.as_ref() {
|
||||||
config::Config::from_file(path).with_code(proc_exit::Code::CONFIG_ERR)?
|
config::Config::from_file(path).with_code(proc_exit::Code::CONFIG_ERR)?
|
||||||
|
@ -44,8 +45,14 @@ fn run() -> proc_exit::ExitResult {
|
||||||
let mut typos_found = false;
|
let mut typos_found = false;
|
||||||
let mut errors_found = false;
|
let mut errors_found = false;
|
||||||
for path in args.path.iter() {
|
for path in args.path.iter() {
|
||||||
let path = path.canonicalize().with_code(proc_exit::Code::USAGE_ERR)?;
|
let path = if path == std::path::Path::new("-") {
|
||||||
let cwd = if path.is_file() {
|
path.to_owned()
|
||||||
|
} else {
|
||||||
|
path.canonicalize().with_code(proc_exit::Code::USAGE_ERR)?
|
||||||
|
};
|
||||||
|
let cwd = if path == std::path::Path::new("-") {
|
||||||
|
global_cwd.as_path()
|
||||||
|
} else if path.is_file() {
|
||||||
path.parent().unwrap()
|
path.parent().unwrap()
|
||||||
} else {
|
} else {
|
||||||
path.as_path()
|
path.as_path()
|
||||||
|
|
Loading…
Reference in a new issue