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