Codebase and README.md were downgraded from 0.5.7 to 0.5.5
Some checks failed
Rust / build (push) Failing after 30s
Some checks failed
Rust / build (push) Failing after 30s
This commit is contained in:
parent
d6186efea2
commit
a33c7956d2
@ -1,5 +1,4 @@
|
||||
  
|
||||
|
||||

|
||||
|
||||
# grip-grab (`gg`) 🧤
|
||||
|
||||
|
21
src/cli.rs
21
src/cli.rs
@ -2,6 +2,7 @@ use std::path::PathBuf;
|
||||
|
||||
use crate::{printer::PrintMode, utils};
|
||||
use clap::{ArgAction, Parser, Subcommand};
|
||||
use thiserror::Error;
|
||||
|
||||
#[derive(Parser, Debug)]
|
||||
#[command(name = "grip-grab")]
|
||||
@ -148,7 +149,11 @@ impl Default for PostProcessedCli {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn process_cli_args(mut cli: Cli) -> PostProcessedCli {
|
||||
#[derive(Error, Debug)]
|
||||
#[error("Error processing CLI arguments")]
|
||||
pub struct CliProcessingError {}
|
||||
|
||||
pub fn process_cli_args(mut cli: Cli) -> Result<PostProcessedCli, CliProcessingError> {
|
||||
cli.validate();
|
||||
|
||||
if cli.paths.is_empty() {
|
||||
@ -156,16 +161,16 @@ pub fn process_cli_args(mut cli: Cli) -> PostProcessedCli {
|
||||
}
|
||||
|
||||
if let Some(Commands::Upgrade { force }) = cli.sub_command {
|
||||
return PostProcessedCli {
|
||||
return Ok(PostProcessedCli {
|
||||
sub_command: Some(Commands::Upgrade { force }),
|
||||
..Default::default()
|
||||
};
|
||||
});
|
||||
}
|
||||
PostProcessedCli {
|
||||
patterns: if cli.patterns.is_empty() {
|
||||
vec![cli.pattern.unwrap()]
|
||||
} else {
|
||||
Ok(PostProcessedCli {
|
||||
patterns: if !cli.patterns.is_empty() {
|
||||
cli.patterns
|
||||
} else {
|
||||
vec![cli.pattern.unwrap()]
|
||||
},
|
||||
paths: utils::resolve_paths(cli.paths),
|
||||
ignored_paths: utils::resolve_paths(cli.ignore_paths),
|
||||
@ -185,5 +190,5 @@ pub fn process_cli_args(mut cli: Cli) -> PostProcessedCli {
|
||||
disable_hyperlinks: cli.disable_hyperlinks,
|
||||
disable_devicons: cli.disable_devicons,
|
||||
sub_command: cli.sub_command,
|
||||
}
|
||||
})
|
||||
}
|
||||
|
27
src/fs.rs
27
src/fs.rs
@ -7,7 +7,7 @@ pub fn walk_builder(
|
||||
ignored_paths: &[PathBuf],
|
||||
n_threads: usize,
|
||||
respect_gitignore: bool,
|
||||
filter_filetypes: &[String],
|
||||
filter_filetypes: Vec<String>,
|
||||
) -> WalkBuilder {
|
||||
let mut builder = WalkBuilder::new(paths[0]);
|
||||
// add all paths to the builder
|
||||
@ -19,15 +19,15 @@ pub fn walk_builder(
|
||||
let mut types_builder = TypesBuilder::new();
|
||||
types_builder.add_defaults();
|
||||
add_custom_filetypes(&mut types_builder).unwrap();
|
||||
for ft in filter_filetypes {
|
||||
filter_filetypes.iter().for_each(|ft| {
|
||||
types_builder.select(ft);
|
||||
}
|
||||
});
|
||||
builder.types(types_builder.build().unwrap());
|
||||
|
||||
// path-based filtering
|
||||
let ignored_paths = ignored_paths.to_vec();
|
||||
builder.filter_entry(move |entry| {
|
||||
for ignore in &ignored_paths {
|
||||
for ignore in ignored_paths.iter() {
|
||||
if entry.path() == ignore {
|
||||
return false;
|
||||
}
|
||||
@ -43,7 +43,7 @@ pub fn walk_builder(
|
||||
}
|
||||
|
||||
fn add_custom_filetypes(types_builder: &mut TypesBuilder) -> Result<(), Error> {
|
||||
types_builder.add("pystrict", "*.py")
|
||||
Ok(types_builder.add("pystrict", "*.py")?)
|
||||
}
|
||||
|
||||
// Original code from https://github.com/BurntSushi/ripgrep/blob/e0f1000df67f82ab0e735bad40e9b45b2d774ef0/crates/cli/src/lib.rs#L249
|
||||
@ -58,18 +58,25 @@ pub fn is_readable_stdin() -> bool {
|
||||
};
|
||||
|
||||
let stdin = std::io::stdin();
|
||||
let Ok(fd) = stdin.as_fd().try_clone_to_owned() else {
|
||||
return false;
|
||||
let fd = match stdin.as_fd().try_clone_to_owned() {
|
||||
Ok(fd) => fd,
|
||||
Err(_) => {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
let file = File::from(fd);
|
||||
let Ok(md) = file.metadata() else {
|
||||
return false;
|
||||
let md = match file.metadata() {
|
||||
Ok(md) => md,
|
||||
Err(_) => {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
let ft = md.file_type();
|
||||
let is_file = ft.is_file();
|
||||
let is_fifo = ft.is_fifo();
|
||||
let is_socket = ft.is_socket();
|
||||
is_file || is_fifo || is_socket
|
||||
let is_readable = is_file || is_fifo || is_socket;
|
||||
is_readable
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
|
19
src/main.rs
19
src/main.rs
@ -4,7 +4,7 @@ use std::sync::{mpsc, Arc};
|
||||
|
||||
use clap::Parser;
|
||||
|
||||
use cli::Commands;
|
||||
use cli::{CliProcessingError, Commands};
|
||||
use fs::is_readable_stdin;
|
||||
use grep::regex::{self, RegexMatcher};
|
||||
use ignore::DirEntry;
|
||||
@ -27,6 +27,8 @@ mod utils;
|
||||
|
||||
#[derive(Error, Debug)]
|
||||
pub enum GGError {
|
||||
#[error("Erorr processing CLI arguments")]
|
||||
Cli(#[from] CliProcessingError),
|
||||
#[error(transparent)]
|
||||
Io(#[from] io::Error),
|
||||
#[error(transparent)]
|
||||
@ -34,7 +36,7 @@ pub enum GGError {
|
||||
}
|
||||
|
||||
pub fn main() -> Result<(), GGError> {
|
||||
let cli_args = process_cli_args(Cli::parse());
|
||||
let cli_args = process_cli_args(Cli::parse())?;
|
||||
|
||||
if let Some(subcommand) = cli_args.sub_command {
|
||||
match subcommand {
|
||||
@ -68,7 +70,7 @@ pub fn main() -> Result<(), GGError> {
|
||||
printer.wipeout()?;
|
||||
}
|
||||
Err(err) => {
|
||||
eprintln!("Error: {err}");
|
||||
eprintln!("Error: {}", err);
|
||||
}
|
||||
}
|
||||
return Ok(());
|
||||
@ -76,11 +78,11 @@ pub fn main() -> Result<(), GGError> {
|
||||
}
|
||||
|
||||
let haystack_builder = walk_builder(
|
||||
cli_args.paths.iter().map(PathBuf::as_path).collect(),
|
||||
cli_args.paths.iter().map(|p| p.as_path()).collect(),
|
||||
&cli_args.ignored_paths,
|
||||
cli_args.n_threads,
|
||||
!cli_args.disregard_gitignore,
|
||||
&cli_args.filter_filetypes,
|
||||
cli_args.filter_filetypes,
|
||||
);
|
||||
let matcher: Arc<RegexMatcher> = Arc::new(build_matcher(&cli_args.patterns)?);
|
||||
|
||||
@ -93,12 +95,13 @@ pub fn main() -> Result<(), GGError> {
|
||||
let tx = tx.clone();
|
||||
Box::new(move |entry: Result<DirEntry, ignore::Error>| match entry {
|
||||
Ok(entry) => {
|
||||
if !entry.path().is_dir() {
|
||||
let file_type = entry.file_type().unwrap();
|
||||
if !file_type.is_dir() {
|
||||
let path = entry.path().to_path_buf();
|
||||
match search_file(path, &matcher, &mut searcher) {
|
||||
Ok(file_results) => {
|
||||
if !file_results.is_empty() {
|
||||
tx.send(file_results).unwrap_or(());
|
||||
tx.send(file_results).unwrap();
|
||||
}
|
||||
}
|
||||
Err(_err) => (),
|
||||
@ -107,7 +110,7 @@ pub fn main() -> Result<(), GGError> {
|
||||
ignore::WalkState::Continue
|
||||
}
|
||||
Err(err) => {
|
||||
eprintln!("Error: {err}");
|
||||
eprintln!("Error: {}", err);
|
||||
ignore::WalkState::Continue
|
||||
}
|
||||
})
|
||||
|
@ -105,9 +105,9 @@ impl ResultsPrinter {
|
||||
self.buffer.flush()?;
|
||||
}
|
||||
match self.config.mode {
|
||||
PrintMode::Text => self.write_colored_text_results(&results.path, &results.results),
|
||||
PrintMode::Json => self.writeln_to_buffer(&serde_json::to_string(&FileResults {
|
||||
path: results.path.clone(),
|
||||
PrintMode::Text => self.write_colored_text_results(&results.path, results.results),
|
||||
PrintMode::Json => self.writeln_to_buffer(serde_json::to_string(&FileResults {
|
||||
path: results.path.to_path_buf(),
|
||||
results: results.results,
|
||||
})?),
|
||||
PrintMode::Files => self.write_colored_path(&results.path),
|
||||
@ -117,7 +117,7 @@ impl ResultsPrinter {
|
||||
fn write_colored_text_results(
|
||||
&mut self,
|
||||
path: &Path,
|
||||
search_results: &[SearchResult],
|
||||
search_results: Vec<SearchResult>,
|
||||
) -> Result<()> {
|
||||
self.write_colored_path(path)?;
|
||||
self.write_colored_search_results(search_results)?;
|
||||
@ -128,7 +128,7 @@ impl ResultsPrinter {
|
||||
if !self.config.disable_devicons {
|
||||
let icon = FileIcon::from(path);
|
||||
self.buffer.set_color(ColorSpec::new().set_fg(Some(
|
||||
devicons_to_termcolor_color(icon.color).unwrap_or(Color::White),
|
||||
devicons_to_termcolor_color(&icon.color).unwrap_or(Color::White),
|
||||
)))?;
|
||||
write!(&mut self.buffer, "{} ", icon.icon)?;
|
||||
}
|
||||
@ -142,17 +142,17 @@ impl ResultsPrinter {
|
||||
path.to_string_lossy()
|
||||
};
|
||||
if self.config.disable_hyperlinks {
|
||||
return writeln!(&mut self.buffer, "{display_path}");
|
||||
return write!(&mut self.buffer, "{}\n", display_path);
|
||||
}
|
||||
let path_str = path.to_string_lossy();
|
||||
let link = Hyperlink {
|
||||
uri: &format!("file://{path_str}"),
|
||||
uri: &format!("file://{}", path_str),
|
||||
id: None,
|
||||
};
|
||||
writeln!(&mut self.buffer, "{link}{display_path}{link:#}",)
|
||||
write!(&mut self.buffer, "{link}{}{link:#}\n", display_path)
|
||||
}
|
||||
|
||||
fn write_colored_search_results(&mut self, results: &[SearchResult]) -> Result<()> {
|
||||
fn write_colored_search_results(&mut self, results: Vec<SearchResult>) -> Result<()> {
|
||||
results.iter().try_for_each(|result| {
|
||||
self.write_colored_line(result)?;
|
||||
Ok(())
|
||||
@ -191,14 +191,12 @@ impl ResultsPrinter {
|
||||
write!(&mut self.buffer, "{}", &result.line[last_end_offset..])
|
||||
}
|
||||
|
||||
fn writeln_to_buffer(&mut self, text: &str) -> Result<()> {
|
||||
writeln!(self.buffer, "{text}")
|
||||
fn writeln_to_buffer(&mut self, text: String) -> Result<()> {
|
||||
writeln!(self.buffer, "{}", text)
|
||||
}
|
||||
|
||||
const EMPTY_STRING: &str = "";
|
||||
|
||||
fn write_newline_to_buffer(&mut self) -> Result<()> {
|
||||
writeln!(self.buffer, "{}", Self::EMPTY_STRING)
|
||||
writeln!(self.buffer, "")
|
||||
}
|
||||
|
||||
pub fn wipeout(&mut self) -> Result<()> {
|
||||
@ -215,13 +213,9 @@ impl ResultsPrinter {
|
||||
|
||||
fn devicons_to_termcolor_color(d_color: &str) -> Option<Color> {
|
||||
d_color.strip_prefix("#").and_then(|hex| {
|
||||
if hex.len() != 6 {
|
||||
return None;
|
||||
}
|
||||
let red = u8::from_str_radix(&hex[0..2], 16).ok()?;
|
||||
let green = u8::from_str_radix(&hex[2..4], 16).ok()?;
|
||||
let blue = u8::from_str_radix(&hex[4..6], 16).ok()?;
|
||||
Some(Color::Rgb(red, green, blue))
|
||||
u32::from_str_radix(hex, 16)
|
||||
.ok()
|
||||
.map(|c| Color::Rgb((c >> 16) as u8, (c >> 8) as u8, c as u8))
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,3 @@
|
||||
#![allow(clippy::module_name_repetitions)]
|
||||
use std::{fmt, io};
|
||||
use std::{path::PathBuf, slice::Iter};
|
||||
|
||||
@ -149,7 +148,7 @@ pub struct FileResults {
|
||||
|
||||
impl fmt::Display for FileResults {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
writeln!(f, "{}\n", self.path.to_string_lossy()).and_then(|()| {
|
||||
write!(f, "{}\n", self.path.to_string_lossy()).and_then(|_| {
|
||||
self.results
|
||||
.iter()
|
||||
.try_for_each(|r| write!(f, "{}: {}", r.line_number, r.line))
|
||||
@ -182,7 +181,7 @@ struct PartialSearchResult {
|
||||
pub m: MatchRange,
|
||||
}
|
||||
|
||||
pub fn search_file(
|
||||
pub fn search_file<'a>(
|
||||
path: PathBuf,
|
||||
matcher: &RegexMatcher,
|
||||
searcher: &mut Searcher,
|
||||
@ -190,7 +189,7 @@ pub fn search_file(
|
||||
let mut partial_results: Vec<PartialSearchResult> = Vec::new();
|
||||
|
||||
searcher.search_path(
|
||||
matcher,
|
||||
&matcher,
|
||||
&path,
|
||||
UTF8(|lnum, line| {
|
||||
matcher.find_iter(line.as_bytes(), |m| {
|
||||
@ -218,12 +217,9 @@ pub fn search_file(
|
||||
line_end: partial_results[0].line_number,
|
||||
matches: vec![partial_results[0].m.clone()],
|
||||
}];
|
||||
for partial_result in &partial_results[1..] {
|
||||
for partial_result in partial_results[1..].iter() {
|
||||
let last_result = results.last_mut().unwrap();
|
||||
if last_result.line_number == partial_result.line_number {
|
||||
last_result.matches.push(partial_result.m.clone());
|
||||
last_result.line_end = partial_result.line_number;
|
||||
} else {
|
||||
if last_result.line_number != partial_result.line_number {
|
||||
results.push(SearchResult {
|
||||
line_number: partial_result.line_number,
|
||||
line: partial_result.line.clone(),
|
||||
@ -231,13 +227,17 @@ pub fn search_file(
|
||||
line_end: partial_result.line_number,
|
||||
matches: vec![partial_result.m.clone()],
|
||||
});
|
||||
} else {
|
||||
last_result.matches.push(partial_result.m.clone());
|
||||
last_result.line_end = partial_result.line_number;
|
||||
}
|
||||
}
|
||||
|
||||
Ok(FileResults { path, results })
|
||||
}
|
||||
|
||||
#[allow(clippy::similar_names)]
|
||||
// io::Error
|
||||
// std::fmt::Display
|
||||
pub fn search_reader(
|
||||
reader: impl std::io::BufRead,
|
||||
matcher: &RegexMatcher,
|
||||
@ -268,10 +268,10 @@ pub fn search_reader(
|
||||
Ok(results)
|
||||
}
|
||||
|
||||
pub fn build_matcher(patterns: &[String]) -> Result<RegexMatcher, regex::Error> {
|
||||
pub fn build_matcher(patterns: &Vec<String>) -> Result<RegexMatcher, regex::Error> {
|
||||
let builder = RegexMatcherBuilder::new();
|
||||
// matcher Error
|
||||
builder.build_many(patterns)
|
||||
Ok(builder.build_many(patterns)?)
|
||||
}
|
||||
|
||||
pub fn build_searcher(multiline: bool) -> Searcher {
|
||||
|
@ -64,8 +64,8 @@ pub fn upgrade_gg(force: bool) {
|
||||
let reader = BufReader::new(stdout);
|
||||
for line in reader.lines() {
|
||||
match line {
|
||||
Ok(line) => println!("{line}"),
|
||||
Err(e) => eprintln!("Error reading stdout: {e}"),
|
||||
Ok(line) => println!("{}", line),
|
||||
Err(e) => eprintln!("Error reading stdout: {}", e),
|
||||
}
|
||||
}
|
||||
});
|
||||
@ -74,8 +74,8 @@ pub fn upgrade_gg(force: bool) {
|
||||
let reader = BufReader::new(stderr);
|
||||
for line in reader.lines() {
|
||||
match line {
|
||||
Ok(line) => eprintln!("{line}"),
|
||||
Err(e) => eprintln!("Error reading stderr: {e}"),
|
||||
Ok(line) => eprintln!("{}", line),
|
||||
Err(e) => eprintln!("Error reading stderr: {}", e),
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -1,9 +1,9 @@
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::path::PathBuf;
|
||||
|
||||
pub fn resolve_paths(paths: Vec<PathBuf>) -> Vec<PathBuf> {
|
||||
paths.into_iter().map(|pb| resolve_path(&pb)).collect()
|
||||
paths.into_iter().map(|path| resolve_path(path)).collect()
|
||||
}
|
||||
|
||||
pub fn resolve_path(path: &Path) -> PathBuf {
|
||||
pub fn resolve_path(path: PathBuf) -> PathBuf {
|
||||
path.canonicalize().unwrap()
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user