Sebastian Thieladapt to changes in `gix`2a6015b3 years agoHistory
76 lines · 2.3 KB · Rust
RawDownload
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,    )?)}