Verified Commit 79371cd2 authored by Morten Linderud's avatar Morten Linderud 🏄 Committed by Jelle van der Waa
Browse files

lib: Implement '--no-reverse-depends' that creates a dependency chain from stdin



When building closed loops of packages you sometime don't want the
entire chain to be resolved to just figure out the order of 5 packages.
This implement `--no-reverse-depends` which resolves the chain and
ensures only the packages from stdin are included in the output chain.

This is useful for rebuild lists or when building tight loops of
packages.

    $ arch-rebuild-order --no-reverse-depends cmake meson jsoncpp
    meson jsoncpp cmake
    $ arch-rebuild-order --no-reverse-depends  jsoncpp meson cmake
    meson jsoncpp cmake
Signed-off-by: Morten Linderud's avatarMorten Linderud <morten@linderud.pw>
Co-Authored-By: Jelle van der Waa's avatarJelle van der Waa <jelle@archlinux.org>
parent 80d95b48
Pipeline #24171 passed with stages
in 1 minute and 44 seconds
......@@ -16,6 +16,8 @@ Generate a rebuild order for given packages using pacman's local syncdb's.
**--repos=REPOS** the repositories to retrieve the package information from
**--no-reverse-depends** only use pkgnames provided as input to calculate the build order, does not expand reverse (make)dependencies
**-V, --version** prints version information
**-h, --help** prints help information
......
......@@ -22,4 +22,8 @@ pub struct Args {
/// Write a dotfile into the given file
#[structopt(short, long)]
pub dotfile: Option<String>,
/// Only use the pkgnames provided as input
#[structopt(long)]
pub no_reverse_depends: bool,
}
......@@ -79,6 +79,7 @@ pub fn run(
dbpath: Option<String>,
repos: Vec<String>,
dotfile: Option<String>,
no_reverse_depends: bool,
) -> Result<String> {
let pacman = match dbpath {
Some(path) => alpm::Alpm::new(ROOT_DIR, &path),
......@@ -165,15 +166,14 @@ pub fn run(
// shows it as last package
rebuild_order_packages.reverse();
let mut output = String::new();
for elem in rebuild_order_packages.iter() {
output.push_str(elem);
output.push(' ');
}
// We only retain the packages we want to when using `--no-reverse_depends`
// This logic is hard to parse because retain is an inverse filter,
// thus we use the negated form of: no_reverse_depends && !pkgnames.contains(&pkg.to_string()
rebuild_order_packages.retain(|pkg| !no_reverse_depends || pkgnames.contains(&pkg.to_string()));
if let Some(filename) = dotfile {
write_dotfile(filename, graph)?;
}
Ok(output)
Ok(rebuild_order_packages.join(" "))
}
......@@ -4,7 +4,13 @@ use arch_rebuild_order::args::Args;
fn main() {
let args = Args::from_args();
match arch_rebuild_order::run(args.pkgnames, args.dbpath, args.repos, args.dotfile) {
match arch_rebuild_order::run(
args.pkgnames,
args.dbpath,
args.repos,
args.dotfile,
args.no_reverse_depends,
) {
Ok(output) => {
println!("{output}");
std::process::exit(0);
......
......@@ -13,7 +13,7 @@ use fixtures::{
fn test_invalid_dbpath(invalid_dbpath: (Vec<String>, Option<String>)) {
let pkgnames = invalid_dbpath.0;
let dbpath = invalid_dbpath.1;
arch_rebuild_order::run(pkgnames, dbpath, vec![], None).unwrap();
arch_rebuild_order::run(pkgnames, dbpath, vec![], None, false).unwrap();
}
/// A package without any reverse dependencies should only print the given package
......@@ -26,6 +26,7 @@ fn test_no_reverse_deps(no_reverse_deps: (Vec<Package>, Option<String>, Vec<Stri
no_reverse_deps.1,
no_reverse_deps.2,
None,
false,
)
.unwrap();
assert_eq!(packages[0], res.trim());
......@@ -43,6 +44,7 @@ fn test_reverse_deps(reverse_deps: (Vec<String>, Option<String>, Vec<String>, Te
reverse_deps.1,
reverse_deps.2,
None,
false,
)
.unwrap();
let res_pkgs: Vec<&str> = res.trim().split_ascii_whitespace().collect();
......@@ -61,6 +63,7 @@ fn test_reverse_make_deps(reverse_make_deps: (Vec<Package>, Option<String>, Vec<
reverse_make_deps.1,
reverse_make_deps.2,
None,
false,
)
.unwrap();
let res_pkgs: Vec<&str> = res.trim().split_ascii_whitespace().collect();
......@@ -81,6 +84,7 @@ fn test_provides_make_depends(
provides_make_depends.1,
provides_make_depends.2,
None,
false,
)
.unwrap();
let res_pkgs: Vec<&str> = res.trim().split_ascii_whitespace().collect();
......@@ -99,6 +103,7 @@ fn test_multiple_deps(multiple_deps: (Vec<Package>, Option<String>, Vec<String>,
multiple_deps.1,
multiple_deps.2,
None,
false,
)
.unwrap();
let res_pkgs: Vec<&str> = res.trim().split_ascii_whitespace().collect();
......@@ -117,6 +122,7 @@ fn test_dependency_depth(dependency_depth: (Vec<Package>, Option<String>, Vec<St
dependency_depth.1,
dependency_depth.2,
None,
false,
)
.unwrap();
let res_pkgs: Vec<&str> = res.trim().split_ascii_whitespace().collect();
......@@ -137,6 +143,7 @@ fn test_dependency_cycle(dependency_cycle: (Vec<Package>, Option<String>, Vec<St
dependency_cycle.1,
dependency_cycle.2,
None,
false,
)
.unwrap();
let res_pkgs: Vec<&str> = res.trim().split_ascii_whitespace().collect();
......@@ -157,9 +164,35 @@ fn test_multiple_pkgnames(multiple_pkgnames: (Vec<Package>, Option<String>, Vec<
multiple_pkgnames.1,
multiple_pkgnames.2,
None,
false,
)
.unwrap();
let res_pkgs: Vec<&str> = res.trim().split_ascii_whitespace().collect();
let expected = vec!["testpkg1", "testpkg3", "testpkg2", "testpkg4"];
assert_eq!(res_pkgs, expected);
}
/// Given two packages names as input, with testpkg1 being a reverse dependency for testpkg2 and
/// testpkg3 and testpkg4 being a dependency of testpkg2. Providing "testpkg1 testpkg2" in
/// combination with the no reverse dependenies flag should
/// return "testpkg1 testpkg2"
#[rstest]
fn test_no_reverse_deps_flag(
multiple_pkgnames: (Vec<Package>, Option<String>, Vec<String>, TempDir),
) {
let packages = multiple_pkgnames.0;
let pkgname1 = &packages[0];
let pkgname2 = &packages[1];
let res = arch_rebuild_order::run(
vec![pkgname1.to_string(), pkgname2.to_string()],
multiple_pkgnames.1,
multiple_pkgnames.2,
None,
true,
)
.unwrap();
let res_pkgs: Vec<&str> = res.trim().split_ascii_whitespace().collect();
let expected = vec!["testpkg1", "testpkg2"];
assert_eq!(res_pkgs, expected);
}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment