333 lines · 8.4 KB · Rust
RawDownload
use std::fmt::{Display, Formatter}; use crosstermion::crossterm::style::Stylize;use owo_colors::OwoColorize;use tabled::{Style, TableIteratorExt, Tabled}; #[derive(Clone)]enum Usage {    NotApplicable,    Planned {        note: Option<&'static str>,    },    NotPlanned {        reason: &'static str,    },    InModule {        name: &'static str,        deviation: Option<&'static str>,    },    /// Needs analysis    Puzzled,}use Usage::*; impl Display for Usage {    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {        match self {            Puzzled => f.write_str("❓")?,            NotApplicable => f.write_str("not applicable")?,            NotPlanned { reason } => {                write!(f, "{}", "not planned".blink())?;                write!(f, " ℹ {} ℹ", reason.bright_white())?;            }            Planned { note } => {                write!(f, "{}", "planned".blink())?;                if let Some(note) = note {                    write!(f, " ℹ {} ℹ", note.bright_white())?;                }            }            InModule { name, deviation } => {                write!(f, "mod {name}")?;                if let Some(deviation) = deviation {                    write!(f, "{}", format!(" ❗️{deviation}❗️").bright_white())?                }            }        }        Ok(())    }} impl Usage {    pub fn icon(&self) -> &'static str {        match self {            Puzzled => "?",            NotApplicable => "❌",            Planned { .. } => "🕒",            NotPlanned { .. } => "🤔",            InModule { deviation, .. } => deviation.is_some().then(|| "👌️").unwrap_or("✅"),        }    }} #[derive(Clone)]struct Record {    config: &'static str,    usage: Usage,} impl Tabled for Record {    const LENGTH: usize = 3;     fn fields(&self) -> Vec<String> {        let mut tokens = self.config.split('.');        let mut buf = vec![tokens.next().expect("present").bold().to_string()];        buf.extend(tokens.map(ToOwned::to_owned));         vec![self.usage.icon().into(), buf.join("."), self.usage.to_string()]    }     fn headers() -> Vec<String> {        vec![]    }} static GIT_CONFIG: &[Record] = &[    Record {        config: "core.bare",        usage: InModule {            name: "config::cache",            deviation: None,        },    },    Record {        config: "core.excludesFile",        usage: InModule {            name: "config::cache",            deviation: None,        },    },    Record {        config: "core.abbrev",        usage: InModule {            name: "config::cache",            deviation: None,        },    },    Record {        config: "core.ignoreCase",        usage: InModule {            name: "config::cache",            deviation: None,        },    },    Record {        config: "core.multiPackIndex",        usage: InModule {            name: "config::cache",            deviation: None,        },    },    Record {        config: "core.disambiguate",        usage: InModule {            name: "config::cache",            deviation: None,        },    },    Record {        config: "core.filesRefLockTimeout",        usage: InModule {name: "config::cache::access", deviation: None},    },    Record {        config: "core.packedRefsTimeout",        usage: InModule {name: "config::cache::access", deviation: None},    },    Record {        config: "core.logAllRefUpdates",        usage: InModule {            name: "config::cache",            deviation: None,        },    },    Record {        config: "core.repositoryFormatVersion",        usage: InModule {            name: "config::cache::incubate",            deviation: None,        },    },    Record {        config: "extensions.objectFormat",        usage: InModule {            name: "config::cache::incubate",            deviation: Some(                "Support for SHA256 is prepared but not fully implemented yet. For now we abort when encountered.",            ),        },    },    Record {        config: "committer.name",        usage: InModule {            name: "repository::identity",            deviation: None,        },    },    Record {        config: "committer.email",        usage: InModule {            name: "repository::identity",            deviation: None,        },    },    Record {        config: "author.name",        usage: InModule {            name: "repository::identity",            deviation: None,        },    },    Record {        config: "author.email",        usage: InModule {            name: "repository::identity",            deviation: None,        },    },    Record {        config: "user.name",        usage: InModule {            name: "repository::identity",            deviation: Some("defaults to 'gitoxide'"),        },    },    Record {        config: "user.email",        usage: InModule {            name: "repository::identity",            deviation: Some("defaults to 'gitoxide@localhost'"),        },    },    Record {    config: "clone.filterSubmodules,",        usage: Planned {            note: Some("currently object filtering isn't support, a prerequisite for this, see --filter=blob:none for more"),        },    },    Record {        config: "clone.defaultRemoteName",        usage: InModule {            name: "clone::prepare",            deviation: None        },    },    Record {        config: "clone.rejectShallow",        usage: NotPlanned {            reason: "it's not a use-case we consider important now, but once that changes it can be implemented",        },    },    Record {        config: "fetch.recurseSubmodules",        usage: Planned {            note: Some("Seems useful for cargo as well"),        },    },    Record {        config: "fetch.fsckObjects",        usage: Puzzled,    },    Record {        config: "fetch.fsck.<msg-id>",        usage: Puzzled,    },    Record {        config: "fetch.fsck.skipList",        usage: Puzzled,    },    Record {        config: "fetch.unpackLimit",        usage: Planned { note: None },    },    Record {        config: "fetch.prune",        usage: Planned { note: None },    },    Record {        config: "fetch.pruneTags",        usage: Planned { note: None },    },    Record {        config: "fetch.writeCommitGraph",        usage: Planned { note: None },    },    Record {        config: "fetch.parallel",        usage: Planned { note: None },    },    Record {        config: "fetch.showForcedUpdates",        usage: NotApplicable,    },    Record {        config: "fetch.output",        usage: NotApplicable,    },    Record {        config: "fetch.negotiationAlgorithm",        usage: Planned {            note: Some("Implements our own 'naive' algorithm, only"),        },    },    Record {        config: "pack.threads",        usage: InModule {            name: "remote::connection::fetch",            deviation: Some("if unset, it uses all threads as opposed to just 1"),        },    },    Record {        config: "pack.indexVersion",        usage: InModule {            name: "remote::connection::fetch",            deviation: None,        },    },    Record {        config: "protocol.allow",        usage: InModule {            name: "remote::url::scheme_permission",            deviation: None,        },    },    Record {        config: "protocol.<name>.allow",        usage: InModule {            name: "remote::url::scheme_permission",            deviation: None,        },    },    Record {        config: "remotes.<group>",        usage: Planned {            note: Some("useful for multi-remote fetches as part of the standard API, maybe just `group(name) -> Option<Vec<Remote>>`"),        },    },    Record {        config: "url.<base>.insteadOf",        usage: InModule {            name: "remote::url::rewrite",            deviation: None,        },    },    Record {        config: "url.<base>.pushInsteadOf",        usage: InModule {            name: "remote::url::rewrite",            deviation: None,        },    },]; /// A programmatic way to record and display progress.pub fn show_progress() -> anyhow::Result<()> {    let sorted = {        let mut v: Vec<_> = GIT_CONFIG.into();        v.sort_by_key(|r| r.config);        v    };     println!("{}", sorted.table().with(Style::blank()));    println!("\nTotal records: {}", GIT_CONFIG.len());    Ok(())}