1pub mod dpkg;
2pub mod elf;
3pub mod search;
4
5use std::collections::HashSet;
6
7use anyhow::Result;
8
9use crate::{
10 dpkg::{find_packages_for_paths, get_package_versions},
11 elf::get_file_dependencies,
12 search::get_ld_cache,
13};
14
15pub fn analyze_dependencies(
17 paths: impl Iterator<Item = impl AsRef<std::path::Path>>,
18) -> Result<Vec<String>> {
19 let mut libraries = HashSet::new();
20
21 for path in paths {
22 let deps = get_file_dependencies(path.as_ref())?;
23 libraries.extend(deps);
24 }
25
26 let ld_cache = get_ld_cache()?;
27 let library_paths = libraries
28 .iter()
29 .flat_map(|l| ld_cache.get(l))
30 .map(|s| s.as_str())
31 .collect::<HashSet<&str>>();
32
33 let path_to_package = find_packages_for_paths(library_paths.iter())?;
34 let packages: HashSet<&str> = library_paths
35 .iter()
36 .filter_map(|path| path_to_package.get(*path))
37 .map(|s| s.as_str())
38 .collect();
39
40 let package_versions = get_package_versions(packages.iter())?;
41 let deps = packages
42 .iter()
43 .map(|p| {
44 if let Some(version) = package_versions.get(*p) {
45 format!("{p} (>={version})")
46 } else {
47 p.to_string()
48 }
49 })
50 .collect::<Vec<String>>();
51
52 Ok(deps)
53}
54
55pub fn get_dependency_string(
57 paths: impl Iterator<Item = impl AsRef<std::path::Path>>,
58) -> Result<String> {
59 let deps = analyze_dependencies(paths)?;
60 Ok(deps.join(", "))
61}