Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add user edited PKGBUILD dependencies #226

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 24 additions & 25 deletions src/action_install.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ use crate::reviewing;
use crate::rua_paths::RuaPaths;
use crate::tar_check;
use crate::terminal_util;
use crate::to_install::DepthMap;
use crate::to_install::ToInstall;
use crate::wrapped;
use fs_extra::dir::CopyOptions;
use indexmap::IndexMap;
Expand All @@ -19,42 +21,37 @@ use std::path::PathBuf;

pub fn install(targets: &[String], rua_paths: &RuaPaths, is_offline: bool, asdeps: bool) {
let alpm = new_alpm_wrapper();
let (split_to_raur, pacman_deps, split_to_depth) =
aur_rpc_utils::recursive_info(targets, &*alpm).unwrap_or_else(|err| {
let mut to_install =
aur_rpc_utils::get_packages_to_install(targets, &*alpm).unwrap_or_else(|err| {
panic!("Failed to fetch info from AUR, {}", err);
});
let split_to_pkgbase: IndexMap<String, String> = split_to_raur
let split_to_pkgbase: IndexMap<String, String> = to_install
.infos()
.iter()
.map(|(split, raur)| (split.to_string(), raur.package_base.to_string()))
.map(|(split, info)| (split.to_string(), info.pkg_base().to_string()))
.collect();
let not_found = split_to_depth
.keys()
.filter(|pkg| !split_to_raur.contains_key(*pkg))
.collect_vec();
if !not_found.is_empty() {
let nf = to_install.not_found();
if !nf.is_empty() {
eprintln!(
"Need to install packages: {:?}, but they are not found on AUR.",
not_found
nf
);
std::process::exit(1)
}

show_install_summary(&pacman_deps, &split_to_depth);
show_install_summary(&to_install);
for pkgbase in split_to_pkgbase.values().collect::<HashSet<_>>() {
let dir = rua_paths.review_dir(pkgbase);
fs::create_dir_all(&dir).unwrap_or_else(|err| {
panic!("Failed to create repository dir for {}, {}", pkgbase, err)
});
reviewing::review_repo(&dir, pkgbase, rua_paths);
reviewing::review_repo(&dir, pkgbase, rua_paths, &mut to_install, &*alpm);
}
show_install_summary(&to_install);

let (_, pacman_deps, depths) = to_install.into_inner();
pacman::ensure_pacman_packages_installed(pacman_deps);
install_all(
rua_paths,
split_to_depth,
split_to_pkgbase,
is_offline,
asdeps,
);
install_all(rua_paths, depths, split_to_pkgbase, is_offline, asdeps);
for target in targets {
// Delete temp directories after successful build+install
if let Err(err) = rm_rf::remove(rua_paths.build_dir(target)) {
Expand All @@ -68,7 +65,9 @@ pub fn install(targets: &[String], rua_paths: &RuaPaths, is_offline: bool, asdep
}
}

fn show_install_summary(pacman_deps: &IndexSet<String>, aur_packages: &IndexMap<String, i32>) {
fn show_install_summary(to_install: &ToInstall) {
let pacman_deps = to_install.pacman_deps();
let aur_packages = to_install.depths();
if pacman_deps.len() + aur_packages.len() == 1 {
return;
}
Expand All @@ -81,7 +80,7 @@ fn show_install_summary(pacman_deps: &IndexSet<String>, aur_packages: &IndexMap<
};
eprintln!("\nAnd the following AUR packages will need to be built and installed:");
let mut aur_packages = aur_packages.iter().collect::<Vec<_>>();
aur_packages.sort_by_key(|pair| -*pair.1);
aur_packages.sort_by_key(|(_, depth)| -(**depth as isize));
for (aur, dep) in &aur_packages {
debug!("depth {}: {}", dep, aur);
}
Expand All @@ -100,7 +99,7 @@ fn show_install_summary(pacman_deps: &IndexSet<String>, aur_packages: &IndexMap<

fn install_all(
rua_paths: &RuaPaths,
split_to_depth: IndexMap<String, i32>,
split_to_depth: DepthMap,
split_to_pkgbase: IndexMap<String, String>,
offline: bool,
asdeps: bool,
Expand All @@ -118,18 +117,18 @@ fn install_all(
(pkgbase.to_string(), *depth, split.to_string())
});
// sort pairs in descending depth order
let packages = packages.sorted_by_key(|(_pkgbase, depth, _split)| -depth);
let packages = packages.sorted_by_key(|(_pkgbase, depth, _split)| -(*depth as isize));
// Note that a pkgbase can appear at multiple depths because
// multiple split pkgnames can be at multiple depths.
// In this case, we only take the first occurrence of pkgbase,
// which would be the maximum depth because of sort order.
// We only take one occurrence because we want the package to only be built once.
let packages: Vec<(String, i32, String)> = packages
let packages = packages
.unique_by(|(pkgbase, _depth, _split)| pkgbase.to_string())
.collect::<Vec<_>>();
// once we have a collection of pkgname-s and their depth, proceed straightforwardly.
for (depth, packages) in &packages.iter().group_by(|(_pkgbase, depth, _split)| *depth) {
let packages = packages.collect::<Vec<&(String, i32, String)>>();
let packages = packages.collect::<Vec<_>>();
for (pkgbase, _depth, _split) in &packages {
let review_dir = rua_paths.review_dir(pkgbase);
let build_dir = rua_paths.build_dir(pkgbase);
Expand Down
86 changes: 30 additions & 56 deletions src/aur_rpc_utils.rs
Original file line number Diff line number Diff line change
@@ -1,76 +1,50 @@
use crate::alpm_wrapper::AlpmWrapper;
use crate::to_install::PkgInfo;
use crate::to_install::ToInstall;
use anyhow::Context;
use anyhow::Result;
use indexmap::IndexMap;
use indexmap::IndexSet;
use itertools::Itertools;
use lazy_static::lazy_static;
use log::trace;
use raur::blocking::Handle;
use raur::blocking::Handle as RaurHandle;
use raur::blocking::Raur;
use raur::Package;
use regex::Regex;

type RaurInfo = IndexMap<String, Package>;
type PacmanDependencies = IndexSet<String>;
type DepthMap = IndexMap<String, i32>;
type RecursiveInfo = (RaurInfo, PacmanDependencies, DepthMap);

const BATCH_SIZE: usize = 200;

pub fn recursive_info(
pub fn get_packages_to_install(
root_packages_to_process: &[String],
alpm: &dyn AlpmWrapper,
) -> Result<RecursiveInfo> {
let raur_handle = Handle::default();
let mut queue: Vec<String> = Vec::from(root_packages_to_process);
let mut depth_map = IndexMap::new();
for pkg in &queue {
depth_map.insert(pkg.to_string(), 0);
}
let mut pacman_deps: IndexSet<String> = IndexSet::new();
let mut info_map: IndexMap<String, Package> = IndexMap::new();
) -> Result<ToInstall> {
let mut to_install = ToInstall::new(root_packages_to_process);
aur_info(root_packages_to_process.to_vec(), &mut to_install, alpm)
.context("Could not build the initial dependency tree")?;
Ok(to_install)
}

pub fn aur_info(
mut queue: Vec<String>,
to_install: &mut ToInstall,
alpm: &dyn AlpmWrapper,
) -> Result<()> {
let raur_handle = RaurHandle::default();
while !queue.is_empty() {
let split_at = queue.len().max(BATCH_SIZE) - BATCH_SIZE;
let to_process = queue.split_off(split_at);
trace!("to_process: {:?}", to_process);
for info in raur_handle.info(&to_process)? {
let make_deps = info.make_depends.iter();
let check_deps = info.check_depends.iter();
let flat_deps = info.depends.iter();
let deps = make_deps
.chain(flat_deps)
.chain(check_deps)
.map(|d| clean_and_check_package_name(d))
.collect_vec();

for dependency in deps.into_iter() {
if alpm.is_installed(&dependency)? {
// skip if already installed
} else if !alpm.is_installable(&dependency)? {
if !depth_map.contains_key(&dependency) {
eprintln!(
"Package {} depends on {}. Resolving...",
info.name, dependency
);
queue.push(dependency.to_string())
} else {
eprintln!("Skipping already resolved dependency {}", dependency);
}
let parent_depth = depth_map
.get(&info.name)
.expect("Internal error: queue element does not have depth");
let new_depth = depth_map
.get(&dependency)
.map_or(parent_depth + 1, |d| (*d).max(parent_depth + 1));
depth_map.insert(dependency.to_string(), new_depth);
} else {
pacman_deps.insert(dependency.to_owned());
}
}
info_map.insert(info.name.to_string(), info);
for info in raur_handle
.info(&to_process)
.context("Could not rertieve package info from AUR")?
{
let info = PkgInfo::from(info);
let new_deps = to_install
.add_package(info, alpm)
.context("Could not add package")?;
queue.extend(new_deps)
}
}
Ok((info_map, pacman_deps, depth_map))
Ok(())
}

/// Queries the AUR for the provided given package names and returns a map of all packages
Expand All @@ -79,7 +53,7 @@ pub fn recursive_info(
/// # Arguments
/// * `packages_to_query` - A slice of package names to find in the AUR
pub fn info_map<S: AsRef<str>>(packages_to_query: &[S]) -> Result<IndexMap<String, Package>> {
let raur_handle = Handle::new();
let raur_handle = RaurHandle::new();
let mut result = IndexMap::new();
for group in packages_to_query.chunks(BATCH_SIZE) {
let group_info = raur_handle.info(group)?;
Expand All @@ -90,7 +64,7 @@ pub fn info_map<S: AsRef<str>>(packages_to_query: &[S]) -> Result<IndexMap<Strin
Ok(result)
}

fn clean_and_check_package_name(name: &str) -> String {
pub fn clean_and_check_package_name(name: &str) -> String {
match clean_package_name(name) {
Some(name) => name,
None => {
Expand Down
1 change: 1 addition & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ mod rua_paths;
mod srcinfo_to_pkgbuild;
mod tar_check;
mod terminal_util;
mod to_install;
mod wrapped;

use crate::print_package_info::info;
Expand Down
11 changes: 10 additions & 1 deletion src/reviewing.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,20 @@
use crate::alpm_wrapper::AlpmWrapper;
use crate::git_utils;
use crate::rua_paths::RuaPaths;
use crate::terminal_util;
use crate::to_install::ToInstall;
use crate::wrapped;
use colored::Colorize;
use log::debug;
use std::path::Path;

pub fn review_repo(dir: &Path, pkgbase: &str, rua_paths: &RuaPaths) {
pub fn review_repo(
dir: &Path,
pkgbase: &str,
rua_paths: &RuaPaths,
to_install: &mut ToInstall,
alpm: &dyn AlpmWrapper,
) {
let mut dir_contents = dir.read_dir().unwrap_or_else(|err| {
panic!(
"{}:{} Failed to read directory for reviewing, {}",
Expand Down Expand Up @@ -101,6 +109,7 @@ pub fn review_repo(dir: &Path, pkgbase: &str, rua_paths: &RuaPaths) {
} else if &user_input == "m" && !is_upstream_merged {
git_utils::merge_upstream(dir, rua_paths);
} else if &user_input == "o" && is_upstream_merged {
to_install.update(dir, rua_paths, alpm);
break;
}
}
Expand Down
Loading