use clap::Parser;
use futures::{stream, StreamExt, TryStreamExt};
use miette::IntoDiagnostic;
use rattler_conda_types::{Channel, ChannelConfig, Platform};
use rattler_networking::AuthenticationMiddleware;
use std::sync::Arc;
use crate::repodata::fetch_sparse_repodata;
use super::{install::globally_install_package, list::list_global_packages};
const UPGRADE_ALL_CONCURRENCY: usize = 5;
#[derive(Parser, Debug)]
pub struct Args {
#[clap(short, long, default_values = ["conda-forge"])]
channel: Vec<String>,
}
pub async fn execute(args: Args) -> miette::Result<()> {
let channel_config = ChannelConfig::default();
let channels = args
.channel
.iter()
.map(|c| Channel::from_str(c, &channel_config))
.collect::<Result<Vec<Channel>, _>>()
.into_diagnostic()?;
let packages = list_global_packages().await?;
let authenticated_client = reqwest_middleware::ClientBuilder::new(reqwest::Client::new())
.with_arc(Arc::new(AuthenticationMiddleware::default()))
.build();
let platform_sparse_repodata =
fetch_sparse_repodata(&channels, [Platform::current()], &authenticated_client).await?;
let tasks = packages
.iter()
.map(|package| package.as_source().parse())
.collect::<Result<Vec<_>, _>>()
.into_diagnostic()?;
let task_stream = stream::iter(tasks)
.map(|matchspec| {
globally_install_package(
matchspec,
&platform_sparse_repodata,
&channel_config,
authenticated_client.clone(),
)
})
.buffered(UPGRADE_ALL_CONCURRENCY);
let res: Vec<_> = task_stream.try_collect().await?;
let mut packages_upgraded = 0;
for (prefix_record, _, upgraded) in res {
if upgraded {
packages_upgraded += 1;
let record = prefix_record.repodata_record.package_record;
eprintln!(
"Upgraded {} {}",
console::style(record.name.as_normalized()).bold(),
console::style(record.version).bold(),
);
}
}
if packages_upgraded == 0 {
eprintln!("Nothing to upgrade");
}
Ok(())
}