90 lines
2.8 KiB
Rust
90 lines
2.8 KiB
Rust
use crate::common::{format_size, print_list, yesno};
|
|
use clap::Parser;
|
|
use indicatif::ProgressBar;
|
|
use packie::{
|
|
PackieBuilder, install::InstallOptions, package::PkgSpec, repo::DownloadPackageEvent,
|
|
};
|
|
use rust_i18n::t;
|
|
|
|
#[derive(Debug, Parser)]
|
|
pub struct Cli {
|
|
#[arg(short, long)]
|
|
file: bool,
|
|
|
|
#[arg(short, long)]
|
|
yes: bool,
|
|
|
|
items: Vec<String>,
|
|
}
|
|
|
|
pub fn main(cli: Cli) -> anyhow::Result<()> {
|
|
let mut packie = PackieBuilder::new().build()?;
|
|
if cli.file {
|
|
for item in cli.items {
|
|
packie.install_package_file(item, &InstallOptions::default())?;
|
|
}
|
|
return Ok(());
|
|
}
|
|
|
|
let mut packages = Vec::with_capacity(cli.items.len() * 4);
|
|
for i in cli.items {
|
|
packages.append(&mut packie.calculate_depgraph(i.parse::<PkgSpec>()?)?);
|
|
}
|
|
packages.dedup_by_key(|x| x.repo_pkg.pkg_manifest.pkg_ident());
|
|
|
|
if packages.is_empty() {
|
|
eprintln!("No packages to install.");
|
|
return Ok(());
|
|
}
|
|
|
|
let download_size: u64 = packages.iter().map(|x| x.repo_pkg.download_size).sum();
|
|
let installed_size: u64 = packages.iter().map(|x| x.repo_pkg.installed_size).sum();
|
|
|
|
println!("{}", t!("install.prompt_to_install"));
|
|
print_list(4, packages.iter().map(|x| x.pkgspec.to_string()));
|
|
println!(
|
|
"{}",
|
|
t!("install.download_size", size = format_size(download_size))
|
|
);
|
|
println!(
|
|
"{}",
|
|
t!("install.installed_size", size = format_size(installed_size))
|
|
);
|
|
if cli.yes {
|
|
eprintln!("y");
|
|
} else if !yesno(&t!("install.confirm_installation")) {
|
|
eprintln!("{}", t!("install.aborting"));
|
|
return Ok(());
|
|
}
|
|
|
|
let progress_bar = ProgressBar::new(download_size);
|
|
let mut package_files = Vec::with_capacity(packages.len());
|
|
for package in packages.iter() {
|
|
let init_pos = progress_bar.position();
|
|
progress_bar.println(format!("Downloading \"{}\"...", package.pkgspec));
|
|
let path = packie.download_package(
|
|
&package.repo_name,
|
|
&package.repo_pkg.pkg_manifest.pkg_ident(),
|
|
|ev| match ev {
|
|
DownloadPackageEvent::Progress(_, sum, _) => {
|
|
progress_bar.set_position(init_pos + sum);
|
|
}
|
|
DownloadPackageEvent::Error(url, err) => {
|
|
progress_bar
|
|
.println(format!("error: failed to download from \"{url}\": {err}"));
|
|
}
|
|
},
|
|
)?;
|
|
package_files.push(path);
|
|
}
|
|
|
|
let progress_bar = ProgressBar::new(package_files.len() as _);
|
|
for package in package_files.iter() {
|
|
progress_bar.println(format!("Installing \"{}\"...", package.display()));
|
|
packie.install_package_file(package, &InstallOptions::default())?;
|
|
progress_bar.inc(1);
|
|
}
|
|
|
|
Ok(())
|
|
}
|