use crate::OutputFormat; pub struct Options { pub format: OutputFormat, pub statistics: bool,} pub(crate) mod function { use std::io; use anyhow::bail; use gix::prelude::FindExt; use crate::{ repository::attributes::query::{attributes_cache, Options}, OutputFormat, }; pub fn query( repo: gix::Repository, pathspecs: impl Iterator<Item = gix::path::Spec>, mut out: impl io::Write, mut err: impl io::Write, Options { format, statistics }: Options, ) -> anyhow::Result<()> { if format != OutputFormat::Human { bail!("JSON output isn't implemented yet"); } let mut cache = attributes_cache(&repo)?; let prefix = repo.prefix().expect("worktree - we have an index by now")?; let mut matches = cache.attribute_matches(); for mut spec in pathspecs { for path in spec.apply_prefix(&prefix).items() { let is_dir = gix::path::from_bstr(path).metadata().ok().map(|m| m.is_dir()); let entry = cache.at_entry(path, is_dir, |oid, buf| repo.objects.find_blob(oid, buf))?; if !entry.matching_attributes(&mut matches) { continue; } for m in matches.iter() { writeln!( out, "{}:{}:{}\t{}\t{}", m.location.source.map(|p| p.to_string_lossy()).unwrap_or_default(), m.location.sequence_number, m.pattern, path, m.assignment )?; } } } if let Some(stats) = statistics.then(|| cache.take_statistics()) { out.flush()?; writeln!(err, "{stats:#?}").ok(); } Ok(()) }} pub(crate) fn attributes_cache(repo: &gix::Repository) -> anyhow::Result<gix::worktree::Cache> { let index = repo.index_or_load_from_head()?; Ok(repo.attributes( &index, if repo.is_bare() { gix::worktree::cache::state::attributes::Source::IdMapping } else { gix::worktree::cache::state::attributes::Source::WorktreeThenIdMapping }, gix::worktree::cache::state::ignore::Source::IdMapping, None, )?)}
use crate::OutputFormat;
pub struct Options {
pub format: OutputFormat,
pub statistics: bool,
}
pub(crate) mod function {
use std::io;
use anyhow::bail;
use gix::prelude::FindExt;
use crate::{
repository::attributes::query::{attributes_cache, Options},
OutputFormat,
};
pub fn query(
repo: gix::Repository,
pathspecs: impl Iterator<Item = gix::path::Spec>,
mut out: impl io::Write,
mut err: impl io::Write,
Options { format, statistics }: Options,
) -> anyhow::Result<()> {
if format != OutputFormat::Human {
bail!("JSON output isn't implemented yet");
}
let mut cache = attributes_cache(&repo)?;
let prefix = repo.prefix().expect("worktree - we have an index by now")?;
let mut matches = cache.attribute_matches();
for mut spec in pathspecs {
for path in spec.apply_prefix(&prefix).items() {
let is_dir = gix::path::from_bstr(path).metadata().ok().map(|m| m.is_dir());
let entry = cache.at_entry(path, is_dir, |oid, buf| repo.objects.find_blob(oid, buf))?;
if !entry.matching_attributes(&mut matches) {
continue;
}
for m in matches.iter() {
writeln!(
out,
"{}:{}:{}\t{}\t{}",
m.location.source.map(|p| p.to_string_lossy()).unwrap_or_default(),
m.location.sequence_number,
m.pattern,
path,
m.assignment
)?;
}
}
}
if let Some(stats) = statistics.then(|| cache.take_statistics()) {
out.flush()?;
writeln!(err, "{stats:#?}").ok();
}
Ok(())
}
}
pub(crate) fn attributes_cache(repo: &gix::Repository) -> anyhow::Result<gix::worktree::Cache> {
let index = repo.index_or_load_from_head()?;
Ok(repo.attributes(
&index,
if repo.is_bare() {
gix::worktree::cache::state::attributes::Source::IdMapping
} else {
gix::worktree::cache::state::attributes::Source::WorktreeThenIdMapping
},
gix::worktree::cache::state::ignore::Source::IdMapping,
None,
)?)
}