Skip to content

Commit

Permalink
add searching for patterns
Browse files Browse the repository at this point in the history
  • Loading branch information
aawsome committed Apr 28, 2024
1 parent d692fcd commit bd5843e
Show file tree
Hide file tree
Showing 3 changed files with 134 additions and 37 deletions.
71 changes: 62 additions & 9 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ convert_case = "0.6.0"
dialoguer = "0.11.0"
directories = "5"
gethostname = "0.4"
globset = "0.4.14"
human-panic = "1.2.3"
humantime = "2"
indicatif = "0.17"
Expand Down
99 changes: 71 additions & 28 deletions src/commands/find.rs
Original file line number Diff line number Diff line change
@@ -1,25 +1,30 @@
//! `find` subcommand
use std::path::PathBuf;
use std::path::{Path, PathBuf};

use crate::{commands::open_repository_indexed, status_err, Application, RUSTIC_APP};

use abscissa_core::{Command, Runnable, Shutdown};
use anyhow::Result;
use globset::{Glob, GlobSetBuilder};
use itertools::Itertools;

use rustic_core::SnapshotGroupCriterion;
use rustic_core::{repofile::Node, SnapshotGroupCriterion};

use super::ls::print_node;

/// `ls` subcommand
#[derive(clap::Parser, Command, Debug)]
pub(crate) struct FindCmd {
/// Snapshot/path to list
#[clap(value_name = "PATH")]
path: PathBuf,
/// pattern to find (can be specified multiple times)
#[clap(long, value_name = "PATTERN")]
patterns: Vec<String>,

/// Snapshots to show. If none is given, use filter options to filter from all snapshots
/// exact path to find
#[clap(long, value_name = "PATH", conflicts_with = "patterns")]
path: Option<PathBuf>,

/// Snapshots to serach in. If none is given, use filter options to filter from all snapshots
#[clap(value_name = "ID")]
ids: Vec<String>,

Expand All @@ -36,7 +41,7 @@ pub(crate) struct FindCmd {
#[clap(long)]
all: bool,

/// Also show snapshots which don't contain the searched path.
/// Also show snapshots which don't contain a search result.
#[clap(long)]
show_misses: bool,

Expand Down Expand Up @@ -72,31 +77,69 @@ impl FindCmd {
println!("\nsearching in snapshots group {group}");
}
let ids = snapshots.iter().map(|sn| sn.tree);
let (nodes, results) = repo.find_nodes_from_path(ids, &self.path)?;
for (idx, mut g) in &results
.iter()
.zip(snapshots.iter())
.group_by(|(idx, _)| *idx)
{
let not = if idx.is_none() { "not " } else { "" };
if self.show_misses || idx.is_some() {
if self.all {
for (_, sn) in g {
if let Some(path) = &self.path {
let (nodes, results) = repo.find_nodes_from_path(ids, path)?;
for (idx, mut g) in &results
.iter()
.zip(snapshots.iter())
.group_by(|(idx, _)| *idx)
{
let not = if idx.is_none() { "not " } else { "" };
if self.show_misses || idx.is_some() {
if self.all {
for (_, sn) in g {
let time = sn.time.format("%Y-%m-%d %H:%M:%S");
println!("{not}found in {} from {time}", sn.id);
}
} else {
let (_, sn) = g.next().unwrap();
let count = g.count();
let time = sn.time.format("%Y-%m-%d %H:%M:%S");
println!("{not}found in {} from {time}", sn.id);
match count {
0 => println!("{not}found in {} from {time}", sn.id),
count => println!("{not}found in {} from {time} (+{count})", sn.id),
};
}
} else {
let (_, sn) = g.next().unwrap();
let count = g.count();
let time = sn.time.format("%Y-%m-%d %H:%M:%S");
match count {
0 => println!("{not}found in {} from {time}", sn.id),
count => println!("{not}found in {} from {time} (+{count})", sn.id),
};
}
if let Some(idx) = idx {
print_node(&nodes[*idx], path, self.numeric_id);
}
}
if let Some(idx) = idx {
print_node(&nodes[*idx], &self.path, self.numeric_id);
} else {
let mut builder = GlobSetBuilder::new();
for pattern in &self.patterns {
_ = builder.add(Glob::new(pattern)?);
}
let globset = builder.build()?;
let matches = |path: &Path, _: &Node| {
globset.is_match(path) || path.file_name().is_some_and(|f| globset.is_match(f))
};
let (paths, nodes, results) = repo.find_matching_nodes(ids, &matches)?;
for (idx, mut g) in &results
.iter()
.zip(snapshots.iter())
.group_by(|(idx, _)| *idx)
{
let not = if idx.is_empty() { "not " } else { "" };
if self.show_misses || !idx.is_empty() {
if self.all {
for (_, sn) in g {
let time = sn.time.format("%Y-%m-%d %H:%M:%S");
println!("{not}found in {} from {time}", sn.id);
}
} else {
let (_, sn) = g.next().unwrap();
let count = g.count();
let time = sn.time.format("%Y-%m-%d %H:%M:%S");
match count {
0 => println!("{not}found in {} from {time}", sn.id),
count => println!("{not}found in {} from {time} (+{count})", sn.id),
};
}
}
for (path_idx, node_idx) in idx {
print_node(&nodes[*node_idx], &paths[*path_idx], self.numeric_id);
}
}
}
}
Expand Down

0 comments on commit bd5843e

Please sign in to comment.