Codebase and README.md were downgraded from 0.5.7 to 0.5.5
Some checks failed
Rust / build (push) Failing after 30s

This commit is contained in:
sinjuginas 2024-10-24 13:57:48 +03:00
parent d6186efea2
commit a33c7956d2
8 changed files with 76 additions and 68 deletions

View File

@ -1,5 +1,4 @@
![Crates.io Total Downloads](https://img.shields.io/crates/d/grip-grab) ![Crates.io Version](https://img.shields.io/crates/v/grip-grab) ![GitHub License](https://img.shields.io/github/license/alexpasmantier/grip-grab)
![Crates.io Total Downloads](https://img.shields.io/crates/d/grip-grab)
# grip-grab (`gg`) 🧤

View File

@ -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,
}
})
}

View File

@ -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)]

View File

@ -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
}
})

View File

@ -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))
})
}

View File

@ -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 {

View File

@ -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),
}
}
});

View File

@ -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()
}