1
Fork 0

Add support for Gentoo, create extract_provides_information for extract

This commit is contained in:
Joshua Goins 2023-01-21 16:04:20 -05:00
parent bd6ae53767
commit 3648018667

View file

@ -6,109 +6,163 @@ use fancy_regex::Regex;
use std::env; use std::env;
trait PackageManager { trait PackageManager {
fn provides(file: String) -> Vec<String>; fn provides(file: &str) -> Vec<String>;
fn transform_cmake(cmake_package: String) -> String; fn transform_cmake(cmake_package: &str) -> String;
fn transform_pkgconfig(cmake_package: String) -> String; fn transform_pkgconfig(cmake_package: &str) -> String;
fn new() -> Self;
fn extract_provides_information(output: &str) -> Option<String>;
} }
struct ArchLinux {} struct ArchLinux {}
impl PackageManager for ArchLinux { impl PackageManager for ArchLinux {
fn provides(file: String) -> Vec<String> { fn new() -> Self {
Self {}
}
fn provides(file: &str) -> Vec<String> {
vec![ vec![
"pacman".to_string(), "pacman".to_string(),
"-F".to_string(), "-F".to_string(),
file file.to_string()
] ]
} }
fn transform_cmake(cmake_package: String) -> String { fn transform_cmake(cmake_package: &str) -> String {
format!("*/{}.cmake", cmake_package) format!("*/{}.cmake", cmake_package)
} }
fn transform_pkgconfig(cmake_package: String) -> String { fn transform_pkgconfig(cmake_package: &str) -> String {
format!("*/{}.pc", cmake_package) format!("*/{}.pc", cmake_package)
} }
fn extract_provides_information(output: &str) -> Option<String> {
None
}
} }
struct Fedora {} struct Fedora {}
impl PackageManager for Fedora { impl PackageManager for Fedora {
fn provides(file: String) -> Vec<String> { fn new() -> Self {
Self {}
}
fn provides(file: &str) -> Vec<String> {
vec![ vec![
"dnf".to_string(), "dnf".to_string(),
"provides".to_string(), "provides".to_string(),
file file.to_string()
] ]
} }
fn transform_cmake(cmake_package: String) -> String { fn transform_cmake(cmake_package: &str) -> String {
format!("cmake({})", cmake_package) format!("cmake({})", cmake_package)
} }
fn transform_pkgconfig(cmake_package: String) -> String { fn transform_pkgconfig(cmake_package: &str) -> String {
format!("pkgconfig({})", cmake_package) format!("pkgconfig({})", cmake_package)
} }
fn extract_provides_information(output: &str) -> Option<String> {
let re = Regex::new(r"[^\s]+(?=\s:\s)").unwrap();
return Some(re.captures(output).unwrap().unwrap().get(0).unwrap().as_str().parse().unwrap());
}
} }
struct Debian {} struct Debian {}
impl PackageManager for Debian { impl PackageManager for Debian {
fn provides(file: String) -> Vec<String> { fn new() -> Self {
Self {}
}
fn provides(file: &str) -> Vec<String> {
vec![ vec![
"dpkg".to_string(), "dpkg".to_string(),
"-S".to_string(), "-S".to_string(),
file file.to_string()
] ]
} }
fn transform_cmake(cmake_package: String) -> String { fn transform_cmake(cmake_package: &str) -> String {
format!("*/{}.cmake", cmake_package) format!("*/{}.cmake", cmake_package)
} }
fn transform_pkgconfig(cmake_package: String) -> String { fn transform_pkgconfig(cmake_package: &str) -> String {
format!("*/{}.pc", cmake_package) format!("*/{}.pc", cmake_package)
} }
fn extract_provides_information(output: &str) -> Option<String> {
None
}
} }
struct OpenSUSE {} struct OpenSUSE {}
impl PackageManager for OpenSUSE { impl PackageManager for OpenSUSE {
fn provides(file: String) -> Vec<String> { fn new() -> Self {
Self {}
}
fn provides(file: &str) -> Vec<String> {
vec![ vec![
"zypper".to_string(), "zypper".to_string(),
"se".to_string(), "se".to_string(),
"--provides".to_string(), "--provides".to_string(),
"--match-exact".to_string(), "--match-exact".to_string(),
file file.to_string()
] ]
} }
fn transform_cmake(cmake_package: String) -> String { fn transform_cmake(cmake_package: &str) -> String {
format!("cmake({})", cmake_package) format!("cmake({})", cmake_package)
} }
fn transform_pkgconfig(cmake_package: String) -> String { fn transform_pkgconfig(cmake_package: &str) -> String {
format!("pkgconfig({})", cmake_package) format!("pkgconfig({})", cmake_package)
} }
fn extract_provides_information(output: &str) -> Option<String> {
None
}
} }
struct Gentoo {} struct Gentoo {}
impl PackageManager for Gentoo { impl PackageManager for Gentoo {
fn provides(file: String) -> Vec<String> { fn new() -> Self {
Self {}
}
fn provides(file: &str) -> Vec<String> {
vec![ vec![
"e-file".to_string(), "e-file".to_string(),
file file.to_string()
] ]
} }
fn transform_cmake(cmake_package: String) -> String { fn transform_cmake(cmake_package: &str) -> String {
format!("{}.cmake", cmake_package) format!("{}.cmake", cmake_package)
} }
fn transform_pkgconfig(cmake_package: String) -> String { fn transform_pkgconfig(cmake_package: &str) -> String {
format!("{}.pc", cmake_package) format!("{}.pc", cmake_package)
} }
fn extract_provides_information(output: &str) -> Option<String> {
let re = Regex::new(r"(\s\*|\[I\])\s+([^\n]+)").unwrap();
return if let Ok(captures) = re.captures(output) {
if let Some(inner_captures) = captures {
Some(inner_captures.get(2).unwrap().as_str().to_string())
} else {
None
}
} else {
None
}
}
} }
#[derive(Debug)] #[derive(Debug)]
@ -120,7 +174,7 @@ enum PackageType {
#[derive(Debug)] #[derive(Debug)]
struct Package { struct Package {
package_type: PackageType, package_type: PackageType,
name: String pub name: String
} }
impl Package { impl Package {
@ -137,17 +191,6 @@ impl Package {
name: name.to_string() name: name.to_string()
} }
} }
pub fn getFilename(&self) -> String {
match self.package_type {
PackageType::PkgConfigModule => {
format!("pkgconfig({})", self.name.to_lowercase())
}
PackageType::CMakeModule => {
format!("cmake({})", self.name)
}
}
}
} }
fn install_packages(package_list: &Vec<Package>) -> Vec<String> { fn install_packages(package_list: &Vec<Package>) -> Vec<String> {
@ -155,27 +198,34 @@ fn install_packages(package_list: &Vec<Package>) -> Vec<String> {
// we must first find which packages provide these: // we must first find which packages provide these:
for package in package_list { for package in package_list {
println!("Finding {}", package.getFilename()); let transformed_name = match package.package_type {
PackageType::CMakeModule => {
Gentoo::transform_cmake(&package.name)
}
PackageType::PkgConfigModule => {
Gentoo::transform_pkgconfig(&package.name)
}
};
let output = Command::new("dnf") let provideCmd = Gentoo::provides(&transformed_name);
.arg("provides")
.arg(package.getFilename()) let mut providesCommand = Command::new(&provideCmd[0]);
.output()
let providesCommand = providesCommand.args(&provideCmd[1..]);
let output = providesCommand.output()
.expect("Failed to execute command"); .expect("Failed to execute command");
let output = String::from_utf8(output.stdout).unwrap(); let output = String::from_utf8(output.stdout).unwrap();
println!("output: {}", output); println!("output: {}", output);
let first_line = output.lines().next().unwrap();
println!("First line: {}", first_line);
let re = Regex::new(r"[^\s]+(?=\s:\s)").unwrap();
let package : &str = re.captures(first_line).unwrap().unwrap().get(0).unwrap().as_str();
if let Some(package) = Gentoo::extract_provides_information(&output) {
println!("FOUND PACKAGE TO INSTALL: {}", package); println!("FOUND PACKAGE TO INSTALL: {}", package);
installable_packages.push(package.parse().unwrap()); installable_packages.push(package.parse().unwrap());
} else {
println!("Failed to find package for {:#?}", package);
}
} }
return installable_packages; return installable_packages;