use std::process::Command;
use crate::core::Project;
use crate::error::Result;
use crate::output::{self, OutputFormat};
use crate::storage::db::load_all_issues_from_data_branch;
pub struct SearchArgs {
pub query: String,
pub all_branches: bool,
pub format: OutputFormat,
}
pub fn run(args: SearchArgs) -> Result<()> {
let project = Project::discover()?;
if args.all_branches {
search_all_branches(&args.query)?;
} else {
let data_branch = project
.config
.data_branch
.as_deref()
.unwrap_or("data/itack");
let issues = load_all_issues_from_data_branch(&project.repo_root, data_branch)?;
let query_lower = args.query.to_lowercase();
let matching: Vec<_> = issues
.into_iter()
.filter(|info| {
info.title.to_lowercase().contains(&query_lower)
|| info.body.to_lowercase().contains(&query_lower)
})
.collect();
match args.format {
OutputFormat::Table => {
output::print_issues_table(&matching);
}
OutputFormat::Json => {
output::print_issues_json(&matching)?;
}
}
}
Ok(())
}
fn search_all_branches(query: &str) -> Result<()> {
let output = Command::new("git")
.args([
"grep",
"-i", "-n", "--all-match", query,
"--",
".itack/",
])
.output()?;
if output.status.success() {
print!("{}", String::from_utf8_lossy(&output.stdout));
} else {
let stderr = String::from_utf8_lossy(&output.stderr);
if !stderr.is_empty() {
eprintln!("{}", stderr);
} else {
println!("No matches found.");
}
}
Ok(())
}