Sebastian Thielmake fmt7cf35454 years agoHistory
577 lines · 22.1 KB · Rust
RawDownload
use std::{    io::{stdin, BufReader},    path::PathBuf,    sync::{        atomic::{AtomicBool, Ordering},        Arc,    },}; use anyhow::Result;use clap::Parser;use gitoxide_core as core;use gitoxide_core::pack::verify; #[cfg(any(feature = "gitoxide-core-async-client", feature = "gitoxide-core-blocking-client"))]use crate::plumbing::options::remote;use crate::{    plumbing::options::{commitgraph, index, mailmap, pack, pack::multi_index, repo, Args, Subcommands},    shared::pretty::prepare_and_run,}; #[cfg(feature = "gitoxide-core-async-client")]pub mod async_util {    use crate::shared::ProgressRange;     #[cfg(not(feature = "prodash-render-line"))]    compile_error!("BUG: Need at least a line renderer in async mode");     pub fn prepare(        verbose: bool,        name: &str,        range: impl Into<Option<ProgressRange>>,    ) -> (Option<prodash::render::line::JoinHandle>, Option<prodash::tree::Item>) {        use crate::shared::{self, STANDARD_RANGE};        crate::shared::init_env_logger();         if verbose {            let progress = crate::shared::progress_tree();            let sub_progress = progress.add_child(name);            let ui_handle = shared::setup_line_renderer_range(&progress, range.into().unwrap_or(STANDARD_RANGE));            (Some(ui_handle), Some(sub_progress))        } else {            (None, None)        }    }} pub fn main() -> Result<()> {    let args: Args = Args::parse_from(git_repository::env::args_os());    let thread_limit = args.threads;    let verbose = args.verbose;    let format = args.format;    let cmd = args.cmd;    let object_hash = args.object_hash;     let progress;    let progress_keep_open;    #[cfg(feature = "prodash-render-tui")]    {        progress = args.progress;        progress_keep_open = args.progress_keep_open;    }    #[cfg(not(feature = "prodash-render-tui"))]    {        progress = false;        progress_keep_open = false;    }     let should_interrupt = Arc::new(AtomicBool::new(false));    git_repository::interrupt::init_handler({        let should_interrupt = Arc::clone(&should_interrupt);        move || should_interrupt.store(true, Ordering::SeqCst)    })?;     match cmd {        Subcommands::Mailmap(mailmap::Platform { path, cmd }) => match cmd {            mailmap::Subcommands::Verify => prepare_and_run(                "mailmap-verify",                verbose,                progress,                progress_keep_open,                core::mailmap::PROGRESS_RANGE,                move |_progress, out, _err| core::mailmap::verify(path, format, out),            ),        },        Subcommands::Index(index::Platform {            object_hash,            index_path,            cmd,        }) => match cmd {            index::Subcommands::CheckoutExclusive {                directory,                empty_files,                repository,                keep_going,            } => prepare_and_run(                "index-checkout",                verbose,                progress,                progress_keep_open,                None,                move |progress, _out, err| {                    core::index::checkout_exclusive(                        index_path,                        directory,                        repository,                        err,                        progress,                        &should_interrupt,                        core::index::checkout_exclusive::Options {                            index: core::index::Options { object_hash, format },                            empty_files,                            keep_going,                            thread_limit,                        },                    )                },            ),            index::Subcommands::Info { no_details } => prepare_and_run(                "index-entries",                verbose,                progress,                progress_keep_open,                None,                move |_progress, out, err| {                    core::index::information(                        index_path,                        out,                        err,                        core::index::information::Options {                            index: core::index::Options { object_hash, format },                            extension_details: !no_details,                        },                    )                },            ),            index::Subcommands::Entries => prepare_and_run(                "index-entries",                verbose,                progress,                progress_keep_open,                None,                move |_progress, out, _err| {                    core::index::entries(index_path, out, core::index::Options { object_hash, format })                },            ),            index::Subcommands::Verify => prepare_and_run(                "index-verify",                verbose,                progress,                progress_keep_open,                None,                move |_progress, out, _err| {                    core::index::verify(index_path, out, core::index::Options { object_hash, format })                },            ),        },        Subcommands::Repository(repo::Platform { repository, cmd }) => match cmd {            repo::Subcommands::Mailmap { cmd } => match cmd {                repo::mailmap::Subcommands::Entries => prepare_and_run(                    "repository-mailmap-entries",                    verbose,                    progress,                    progress_keep_open,                    None,                    move |_progress, out, err| core::repository::mailmap::entries(repository, format, out, err),                ),            },            repo::Subcommands::Odb { cmd } => match cmd {                repo::odb::Subcommands::Entries => prepare_and_run(                    "repository-odb-entries",                    verbose,                    progress,                    progress_keep_open,                    None,                    move |_progress, out, _err| core::repository::odb::entries(repository, format, out),                ),                repo::odb::Subcommands::Info => prepare_and_run(                    "repository-odb-info",                    verbose,                    progress,                    progress_keep_open,                    None,                    move |_progress, out, err| core::repository::odb::info(repository, format, out, err),                ),            },            repo::Subcommands::Tree { cmd } => match cmd {                repo::tree::Subcommands::Entries {                    treeish,                    recursive,                    extended,                } => prepare_and_run(                    "repository-tree-entries",                    verbose,                    progress,                    progress_keep_open,                    None,                    move |_progress, out, _err| {                        core::repository::tree::entries(                            repository,                            treeish.as_deref(),                            recursive,                            extended,                            format,                            out,                        )                    },                ),                repo::tree::Subcommands::Info { treeish, extended } => prepare_and_run(                    "repository-tree-info",                    verbose,                    progress,                    progress_keep_open,                    None,                    move |_progress, out, err| {                        core::repository::tree::info(repository, treeish.as_deref(), extended, format, out, err)                    },                ),            },            repo::Subcommands::Verify {                args:                    pack::VerifyOptions {                        statistics,                        algorithm,                        decode,                        re_encode,                    },            } => prepare_and_run(                "repository-verify",                verbose,                progress,                progress_keep_open,                core::repository::verify::PROGRESS_RANGE,                move |progress, out, _err| {                    core::repository::verify::integrity(                        repository,                        out,                        progress,                        &should_interrupt,                        core::repository::verify::Context {                            output_statistics: statistics.then(|| format),                            algorithm,                            verify_mode: verify_mode(decode, re_encode),                            thread_limit,                        },                    )                },            ),        },        Subcommands::Pack(subcommands) => match subcommands {            pack::Subcommands::Create {                repository,                expansion,                thin,                statistics,                nondeterministic_count,                tips,                pack_cache_size_mb,                counting_threads,                object_cache_size_mb,                output_directory,            } => {                let has_tips = !tips.is_empty();                prepare_and_run(                    "pack-create",                    verbose,                    progress,                    progress_keep_open,                    core::pack::create::PROGRESS_RANGE,                    move |progress, out, _err| {                        let input = if has_tips {                            None                        } else {                            if atty::is(atty::Stream::Stdin) {                                anyhow::bail!(                                    "Refusing to read from standard input as no path is given, but it's a terminal."                                )                            }                            Some(BufReader::new(stdin()))                        };                        let repository = repository.unwrap_or_else(|| PathBuf::from("."));                        let context = core::pack::create::Context {                            thread_limit,                            thin,                            nondeterministic_thread_count: nondeterministic_count.then(|| counting_threads),                            pack_cache_size_in_bytes: pack_cache_size_mb.unwrap_or(0) * 1_000_000,                            object_cache_size_in_bytes: object_cache_size_mb.unwrap_or(0) * 1_000_000,                            statistics: if statistics { Some(format) } else { None },                            out,                            expansion: expansion.unwrap_or(if has_tips {                                core::pack::create::ObjectExpansion::TreeTraversal                            } else {                                core::pack::create::ObjectExpansion::None                            }),                        };                        core::pack::create(repository, tips, input, output_directory, progress, context)                    },                )            }            #[cfg(feature = "gitoxide-core-async-client")]            pack::Subcommands::Receive {                protocol,                url,                directory,                refs,                refs_directory,            } => {                let (_handle, progress) =                    async_util::prepare(verbose, "pack-receive", core::pack::receive::PROGRESS_RANGE);                let fut = core::pack::receive(                    protocol,                    &url,                    directory,                    refs_directory,                    refs.into_iter().map(|s| s.into()).collect(),                    git_features::progress::DoOrDiscard::from(progress),                    core::pack::receive::Context {                        thread_limit,                        format,                        out: std::io::stdout(),                        should_interrupt,                        object_hash,                    },                );                return futures_lite::future::block_on(fut);            }            #[cfg(feature = "gitoxide-core-blocking-client")]            pack::Subcommands::Receive {                protocol,                url,                directory,                refs,                refs_directory,            } => prepare_and_run(                "pack-receive",                verbose,                progress,                progress_keep_open,                core::pack::receive::PROGRESS_RANGE,                move |progress, out, _err| {                    core::pack::receive(                        protocol,                        &url,                        directory,                        refs_directory,                        refs.into_iter().map(|r| r.into()).collect(),                        git_features::progress::DoOrDiscard::from(progress),                        core::pack::receive::Context {                            thread_limit,                            format,                            should_interrupt,                            out,                            object_hash,                        },                    )                },            ),            pack::Subcommands::Explode {                check,                sink_compress,                delete_pack,                pack_path,                object_path,                verify,            } => prepare_and_run(                "pack-explode",                verbose,                progress,                progress_keep_open,                None,                move |progress, _out, _err| {                    core::pack::explode::pack_or_pack_index(                        pack_path,                        object_path,                        check,                        progress,                        core::pack::explode::Context {                            thread_limit,                            delete_pack,                            sink_compress,                            verify,                            should_interrupt,                            object_hash,                        },                    )                },            ),            pack::Subcommands::Verify {                args:                    pack::VerifyOptions {                        algorithm,                        decode,                        re_encode,                        statistics,                    },                path,            } => prepare_and_run(                "pack-verify",                verbose,                progress,                progress_keep_open,                verify::PROGRESS_RANGE,                move |progress, out, err| {                    let mode = verify_mode(decode, re_encode);                    let output_statistics = if statistics { Some(format) } else { None };                    verify::pack_or_pack_index(                        path,                        progress,                        verify::Context {                            output_statistics,                            out,                            err,                            thread_limit,                            mode,                            algorithm,                            should_interrupt: &should_interrupt,                            object_hash,                        },                    )                },            )            .map(|_| ()),            pack::Subcommands::MultiIndex(multi_index::Platform { multi_index_path, cmd }) => match cmd {                pack::multi_index::Subcommands::Entries => prepare_and_run(                    "pack-multi-index-entries",                    verbose,                    progress,                    progress_keep_open,                    core::pack::multi_index::PROGRESS_RANGE,                    move |_progress, out, _err| core::pack::multi_index::entries(multi_index_path, format, out),                ),                pack::multi_index::Subcommands::Info => prepare_and_run(                    "pack-multi-index-info",                    verbose,                    progress,                    progress_keep_open,                    core::pack::multi_index::PROGRESS_RANGE,                    move |_progress, out, err| core::pack::multi_index::info(multi_index_path, format, out, err),                ),                pack::multi_index::Subcommands::Verify => prepare_and_run(                    "pack-multi-index-verify",                    verbose,                    progress,                    progress_keep_open,                    core::pack::multi_index::PROGRESS_RANGE,                    move |progress, _out, _err| {                        core::pack::multi_index::verify(multi_index_path, progress, &should_interrupt)                    },                ),                pack::multi_index::Subcommands::Create { index_paths } => prepare_and_run(                    "pack-multi-index-create",                    verbose,                    progress,                    progress_keep_open,                    core::pack::multi_index::PROGRESS_RANGE,                    move |progress, _out, _err| {                        core::pack::multi_index::create(                            index_paths,                            multi_index_path,                            progress,                            &should_interrupt,                            object_hash,                        )                    },                ),            },            pack::Subcommands::Index(subcommands) => match subcommands {                pack::index::Subcommands::Create {                    iteration_mode,                    pack_path,                    directory,                } => prepare_and_run(                    "pack-index-create",                    verbose,                    progress,                    progress_keep_open,                    core::pack::index::PROGRESS_RANGE,                    move |progress, out, _err| {                        use gitoxide_core::pack::index::PathOrRead;                        let input = if let Some(path) = pack_path {                            PathOrRead::Path(path)                        } else {                            if atty::is(atty::Stream::Stdin) {                                anyhow::bail!(                                    "Refusing to read from standard input as no path is given, but it's a terminal."                                )                            }                            PathOrRead::Read(Box::new(std::io::stdin()))                        };                        core::pack::index::from_pack(                            input,                            directory,                            progress,                            core::pack::index::Context {                                thread_limit,                                iteration_mode,                                format,                                out,                                object_hash,                                should_interrupt: &git_repository::interrupt::IS_INTERRUPTED,

Lines 1–500 of 577.