Skip to content

Commit

Permalink
chore: add --stdin-paths and -stdin-paths0
Browse files Browse the repository at this point in the history
  • Loading branch information
dpc committed Apr 6, 2023
1 parent 66d82e5 commit 06fc4ac
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 2 deletions.
8 changes: 8 additions & 0 deletions crates/typos-cli/src/bin/typos-cli/args.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,14 @@ pub(crate) struct Args {
#[arg(default_value = ".")]
pub(crate) path: Vec<std::path::PathBuf>,

/// Read the list of newline separated paths from stdin
#[arg(long, conflicts_with = "stdin_paths0")]
pub(crate) stdin_paths: bool,

/// Read the list of '\0' separated paths from stdin
#[arg(long, conflicts_with = "stdin_paths")]
pub(crate) stdin_paths0: bool,

/// Custom config file
#[arg(short = 'c', long = "config")]
pub(crate) custom_config: Option<std::path::PathBuf>,
Expand Down
61 changes: 59 additions & 2 deletions crates/typos-cli/src/bin/typos-cli/main.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
use std::io::Write;
use std::{
io::{self, Read, Write},
iter,
path::PathBuf,
};

use clap::Parser;

Expand Down Expand Up @@ -156,7 +160,20 @@ fn run_checks(args: &args::Args) -> proc_exit::ExitResult {

let mut typos_found = false;
let mut errors_found = false;
for path in args.path.iter() {

let paths_from_stdin = if args.stdin_paths {
io::stdin()
.lines()
.map(|res| res.map(PathBuf::from))
.collect::<Result<_, _>>()
.with_code(proc_exit::sysexits::IO_ERR)?
} else if args.stdin_paths0 {
unix_read_paths_from_stdin()?
} else {
vec![]
};

for path in args.path.iter().chain(&paths_from_stdin) {
let cwd = if path == std::path::Path::new("-") {
global_cwd.clone()
} else if path.is_file() {
Expand Down Expand Up @@ -269,6 +286,46 @@ fn run_checks(args: &args::Args) -> proc_exit::ExitResult {
}
}

#[cfg(target_family = "unix")]
fn unix_read_paths_from_stdin() -> Result<Vec<PathBuf>, proc_exit::Exit> {
use std::ffi::OsString;
use std::os::unix::ffi::OsStringExt;

let mut buf = Vec::new();
io::stdin()
.read_to_end(&mut buf)
.with_code(proc_exit::sysexits::IO_ERR)?;

Ok(buf
.into_iter()
// ensure we always end with a terminator
.chain(iter::once(0))
.fold(
(vec![], vec![]),
|(mut paths, mut cur_path): (Vec<PathBuf>, Vec<u8>), byte| {
if byte == 0 {
if cur_path.is_empty() {
// ignore duplicated \0
// TODO: is this OK? If not, we could not append trailing 0, and handle "rest" after `fold` ends
(paths, cur_path)
} else {
paths.push(PathBuf::from(OsString::from_vec(cur_path)));
(paths, vec![])
}
} else {
cur_path.push(byte);
(paths, cur_path)
}
},
)
.0)
}

#[cfg(not(target_family = "unix"))]
fn unix_read_paths_from_stdin() -> Result<Vec<PathBuf>, proc_exit::Exit> {
Err(proc_exit::sysexits::CONFIG_ERR)
}

fn init_logging(level: Option<log::Level>) {
if let Some(level) = level {
let mut builder = env_logger::Builder::new();
Expand Down

0 comments on commit 06fc4ac

Please sign in to comment.