knott 0.1.7

Fast Rust package manager helper for Arch Linux repos and the AUR
Documentation
mod aur;
mod cli;
mod dep;
mod download;
mod info;
mod install;
mod localdb;
mod menu;
mod output;
mod pacman;
mod resolver;
mod search;
mod upgrade;
mod version;

use anyhow::Result;

pub async fn run(args: Vec<String>) -> Result<i32> {
    let parsed = cli::parse(args)?;

    match &parsed.command {
        cli::Command::Help => {
            cli::print_help();
            return Ok(0);
        }
        cli::Command::Version => {
            println!("knott {}", env!("CARGO_PKG_VERSION"));
            return Ok(0);
        }
        cli::Command::Diagnostics => {
            print_diagnostics();
            return Ok(0);
        }
        _ => {}
    }

    let tools = pacman::Toolchain::from_env();
    let aur = aur::AurClient::from_env_with_progress(
        !parsed.options.quiet && !parsed.options.no_progress,
    )?;

    match parsed.command {
        cli::Command::DefaultUpgrade => {
            install::sync(&parsed.options, &tools, &aur, &[], true, true).await
        }
        cli::Command::Search { terms } => {
            search::print_search(&parsed.options, &tools, &aur, &terms).await
        }
        cli::Command::Info { targets } => {
            info::print_info(&parsed.options, &tools, &aur, &targets).await
        }
        cli::Command::Install {
            targets,
            refresh,
            sysupgrade,
        } => install::sync(&parsed.options, &tools, &aur, &targets, refresh, sysupgrade).await,
        cli::Command::Get { targets, print } => {
            download::get_pkgbuilds(&parsed.options, &tools, &aur, &targets, print).await
        }
        cli::Command::QueryForeign => upgrade::print_foreign(&parsed.options, &tools).await,
        cli::Command::QueryAurUpdates => {
            upgrade::print_aur_updates(&parsed.options, &tools, &aur).await
        }
        cli::Command::Forward(args) => tools.forward(&args).await,
        cli::Command::Interactive { terms } => {
            let selected =
                search::interactive_select(&parsed.options, &tools, &aur, &terms).await?;
            if selected.is_empty() {
                return Ok(0);
            }
            install::sync(&parsed.options, &tools, &aur, &selected, false, false).await
        }
        cli::Command::Help | cli::Command::Version | cli::Command::Diagnostics => unreachable!(),
    }
}

pub fn sanitize_for_terminal(input: &str) -> String {
    output::text(input)
}

fn print_diagnostics() {
    println!("knott diagnostics");
    println!("version: {}", env!("CARGO_PKG_VERSION"));
    println!("aur_info_batch_size: {}", aur::INFO_CHUNK);
    println!("aur_info_cache_limit: {}", aur::INFO_CACHE_LIMIT);
    println!("aur_search_cache_limit: {}", aur::SEARCH_CACHE_LIMIT);
    println!(
        "aur_search_cache_result_limit: {}",
        aur::SEARCH_CACHE_RESULT_LIMIT
    );
    println!("pkgbuild_byte_limit: {}", aur::MAX_PKG_BUILD_BYTES);
    println!("resolver_node_limit: {}", resolver::MAX_RESOLVE_NODES);
    println!("local_desc_byte_limit: {}", localdb::MAX_DESC_BYTES);
    println!("spawned_tokio_tasks: 0");
    println!("channels: 0");
    println!("output_sanitization: ansi-and-control-stripped");
    println!("progress_loader: aisling:tqdm");
    match current_rss_kib() {
        Some(rss) => println!("rss_kib: {rss}"),
        None => println!("rss_kib: unavailable"),
    }
}

fn current_rss_kib() -> Option<u64> {
    let status = std::fs::read_to_string("/proc/self/status").ok()?;
    status.lines().find_map(|line| {
        line.strip_prefix("VmRSS:")?
            .split_whitespace()
            .next()?
            .parse()
            .ok()
    })
}