You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
131 lines
4.3 KiB
Rust
131 lines
4.3 KiB
Rust
use async_recursion::async_recursion;
|
|
use aur_rpc::PackageInfo;
|
|
use crossterm::style::Stylize;
|
|
use futures::future;
|
|
use indicatif::ProgressBar;
|
|
use std::env;
|
|
use std::env::set_current_dir;
|
|
use std::path::{Path, PathBuf};
|
|
use std::process::Command;
|
|
use std::sync::Arc;
|
|
use std::time::Duration;
|
|
use tokio::fs;
|
|
|
|
use crate::builder::git::{GitCloneBuilder, GitPullBuilder};
|
|
use crate::internal::commands::ShellCommand;
|
|
use crate::internal::dependencies::DependencyInformation;
|
|
use crate::internal::error::{AppError, AppResult, SilentUnwrap};
|
|
use crate::internal::exit_code::AppExitCode;
|
|
use crate::internal::rpc::{self, rpcinfo};
|
|
use crate::internal::utils::get_cache_dir;
|
|
use crate::logging::get_logger;
|
|
use crate::{crash, internal::fs_utils::rmdir_recursive, prompt, Options};
|
|
|
|
/// Installs a given list of packages from the aur
|
|
#[tracing::instrument(level = "trace")]
|
|
#[async_recursion]
|
|
pub async fn aur_install(packages: Vec<String>, options: Options) {
|
|
let noconfirm = options.noconfirm;
|
|
|
|
tracing::debug!("Installing from AUR: {:?}", &packages);
|
|
|
|
tracing::info!("Installing packages {} from the AUR", packages.join(", "));
|
|
|
|
let pb = get_logger().new_progress_spinner();
|
|
pb.set_message("Fetching package information");
|
|
|
|
let package_info = aur_rpc::info(&packages)
|
|
.await
|
|
.map_err(AppError::from)
|
|
.silent_unwrap(AppExitCode::RpcError);
|
|
|
|
tracing::debug!("package info = {package_info:?}");
|
|
tokio::time::sleep(Duration::from_secs(1)).await;
|
|
|
|
if package_info.len() != packages.len() {
|
|
let mut not_found = packages.clone();
|
|
package_info
|
|
.iter()
|
|
.for_each(|pkg| not_found.retain(|p| pkg.metadata.name != *p));
|
|
crash!(
|
|
AppExitCode::MissingDeps,
|
|
"Could not find the package: {}",
|
|
not_found.join(",").italic(),
|
|
);
|
|
}
|
|
|
|
pb.finish_with_message("Found all packages in the aur");
|
|
|
|
get_logger().new_multi_progress();
|
|
|
|
future::try_join_all(package_info.iter().map(download_aur_source))
|
|
.await
|
|
.unwrap();
|
|
tokio::time::sleep(Duration::from_secs(1)).await;
|
|
|
|
let dependencies = future::try_join_all(package_info.iter().map(|pkg| async {
|
|
get_logger()
|
|
.new_progress_spinner()
|
|
.set_message(format!("{}: Fetching dependencies", pkg.metadata.name));
|
|
DependencyInformation::for_package(pkg).await
|
|
}))
|
|
.await
|
|
.silent_unwrap(AppExitCode::RpcError);
|
|
tokio::time::sleep(Duration::from_secs(1)).await;
|
|
|
|
let aur_build_dependencies: Vec<PackageInfo> = dependencies
|
|
.iter()
|
|
.flat_map(|d| d.make_depends.aur.clone())
|
|
.collect();
|
|
|
|
let aur_dependencies: Vec<PackageInfo> = dependencies
|
|
.iter()
|
|
.flat_map(|d| d.depends.aur.clone())
|
|
.collect();
|
|
|
|
get_logger().reset_output_type();
|
|
tracing::info!(
|
|
"Installing {} build dependencies",
|
|
aur_build_dependencies.len()
|
|
);
|
|
get_logger().new_multi_progress();
|
|
|
|
future::try_join_all(aur_build_dependencies.iter().map(download_aur_source))
|
|
.await
|
|
.unwrap();
|
|
}
|
|
|
|
#[tracing::instrument(level = "trace", skip_all)]
|
|
async fn download_aur_source(info: &PackageInfo) -> AppResult<PathBuf> {
|
|
let pb = get_logger().new_progress_spinner();
|
|
let pkg_name = &info.metadata.name;
|
|
pb.set_message(format!("{pkg_name}: Downloading sources"));
|
|
|
|
let cache_dir = get_cache_dir();
|
|
let pkg_dir = cache_dir.join(&pkg_name);
|
|
tokio::time::sleep(Duration::from_secs(1)).await;
|
|
|
|
if pkg_dir.exists() {
|
|
pb.set_message(format!("{pkg_name}: Pulling latest changes {pkg_name}"));
|
|
GitPullBuilder::default().directory(&pkg_dir).pull().await?;
|
|
tokio::time::sleep(Duration::from_secs(1)).await;
|
|
} else {
|
|
let aur_url = rpc::URL;
|
|
let repository_url = format!("{aur_url}/{pkg_name}");
|
|
pb.set_message(format!("{pkg_name}: Cloning aur repository"));
|
|
|
|
GitCloneBuilder::default()
|
|
.url(repository_url)
|
|
.directory(&pkg_dir)
|
|
.clone()
|
|
.await?;
|
|
tokio::time::sleep(Duration::from_secs(1)).await;
|
|
|
|
pb.set_message(format!("{pkg_name}: Downloading and extracting files"));
|
|
}
|
|
tokio::time::sleep(Duration::from_secs(1)).await;
|
|
pb.finish_with_message(format!("{pkg_name} is ready to build"));
|
|
|
|
Ok(pkg_dir)
|
|
}
|