From 3648018667740799a750730743f99244dee264b1 Mon Sep 17 00:00:00 2001 From: Joshua Goins Date: Sat, 21 Jan 2023 16:04:20 -0500 Subject: [PATCH] Add support for Gentoo, create extract_provides_information for extract --- src/main.rs | 148 +++++++++++++++++++++++++++++++++++----------------- 1 file changed, 99 insertions(+), 49 deletions(-) diff --git a/src/main.rs b/src/main.rs index d9785e6..f2c0074 100644 --- a/src/main.rs +++ b/src/main.rs @@ -6,109 +6,163 @@ use fancy_regex::Regex; use std::env; trait PackageManager { - fn provides(file: String) -> Vec; - fn transform_cmake(cmake_package: String) -> String; - fn transform_pkgconfig(cmake_package: String) -> String; + fn provides(file: &str) -> Vec; + fn transform_cmake(cmake_package: &str) -> String; + fn transform_pkgconfig(cmake_package: &str) -> String; + fn new() -> Self; + fn extract_provides_information(output: &str) -> Option; } struct ArchLinux {} impl PackageManager for ArchLinux { - fn provides(file: String) -> Vec { + fn new() -> Self { + Self {} + } + + fn provides(file: &str) -> Vec { 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 { + None + } } struct Fedora {} impl PackageManager for Fedora { - fn provides(file: String) -> Vec { + fn new() -> Self { + Self {} + } + + fn provides(file: &str) -> Vec { 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 { + 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 { + fn new() -> Self { + Self {} + } + + fn provides(file: &str) -> Vec { 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 { + None + } } struct OpenSUSE {} impl PackageManager for OpenSUSE { - fn provides(file: String) -> Vec { + fn new() -> Self { + Self {} + } + + fn provides(file: &str) -> Vec { 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 { + None + } } struct Gentoo {} impl PackageManager for Gentoo { - fn provides(file: String) -> Vec { + fn new() -> Self { + Self {} + } + + fn provides(file: &str) -> Vec { 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 { + 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) -> Vec { @@ -155,27 +198,34 @@ fn install_packages(package_list: &Vec) -> Vec { // 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;