Initial Commit

This commit is contained in:
Beefki 2017-10-13 11:53:50 -05:00
commit d1fbeea1df
5 changed files with 303 additions and 0 deletions

6
Cargo.toml Normal file
View File

@ -0,0 +1,6 @@
[package]
name = "rux"
version = "0.1.0"
authors = ["Beefki <mousecar23@hotmail.com>"]
[dependencies]

71
src/config.rs Normal file
View File

@ -0,0 +1,71 @@
use super::*;
/// A struct to hold parsed arg data.
#[derive(Debug)]
pub struct Config {
pub action: Management,
pub term: Option<String>,
}
impl Config {
/// Actually runs the package manager. Checks what command was requested
/// and loads the appropriate data from the passed `PackageManager`.
/// Finally calls the program and passes the appropriate arguments
pub fn run(&self, pac: PackageManager) -> Child {
let prog = match self.action {
Management::Search => (pac.search.0, pac.search.1.unwrap_or_else(|| "".to_string())),
Management::Install => (
pac.install.0,
pac.install.1.unwrap_or_else(|| "".to_string()),
),
Management::Uninstall => (
pac.uninstall.0,
pac.uninstall.1.unwrap_or_else(|| "".to_string()),
),
Management::Remove => (pac.purge.0, pac.purge.1.unwrap_or_else(|| "".to_string())),
Management::Update => (pac.update.0, pac.update.1.unwrap_or_else(|| "".to_string())),
Management::Upgrade => (
pac.upgrade.0,
pac.upgrade.1.unwrap_or_else(|| "".to_string()),
),
Management::Full => (pac.sup.0, pac.sup.1.unwrap_or_else(|| "".to_string())),
Management::Clear => (
pac.cache_clear.0,
pac.cache_clear.1.unwrap_or_else(|| "".to_string()),
),
Management::CompleteClear => (
pac.complete_cache_clear.0,
pac.complete_cache_clear.1.unwrap_or_else(
|| "".to_string(),
),
),
};
let term = match self.term {
None => "",
Some(ref val) => val,
};
Command::new(&prog.0)
.arg(&prog.1)
.arg(term)
.spawn()
.expect("Failed to call package manager")
}
/// Creates a `Config` from passed arguments, parses the `Management` enum
/// and term (if any). Requires an action, while the term can be `None`.
pub fn new() -> Config {
let action = match Management::parse(std::env::args().nth(1)) {
None => {
println!("No command actions passed");
std::process::exit(0)
}
Some(command) => command,
};
let term = std::env::args().nth(2);
Config {
action: action,
term: term,
}
}
}

67
src/main.rs Normal file
View File

@ -0,0 +1,67 @@
mod packagemanager;
use packagemanager::*;
mod management;
use management::Management;
mod config;
use config::Config;
use std::process::{Command, Child};
use std::io;
use std::path::Path;
fn input() -> Result<String, io::Error> {
let mut val = String::new();
io::stdin().read_line(&mut val)?;
Ok(val)
}
fn main() {
let config = Config::new();
if Path::new("default.conf").is_file() {
let pac = read_default();
let mut child = config.run(pac);
child.wait().expect("Failed to wait on child");
std::process::exit(0);
}
let pacmatic = PackageManager::pacmatic();
let pacman = PackageManager::pacman();
let aptget = PackageManager::apt();
let xbps = PackageManager::xbps();
let managers: Vec<PackageManager> = vec![pacmatic, pacman, aptget, xbps];
let mut found: bool = false;
for prog in managers {
if found { break }
if prog.exe.is_file() {
println!("Found {}, is this the manager you want to use? [Y/n]", prog.name);
if input().unwrap().trim().to_lowercase() == "n" {
continue
}else {
found = true;
println!("Would you like to set {} as default? [y/N]", prog.name);
if input().unwrap().trim().to_lowercase() == "y" {
let check = prog.set_default();
match check {
Ok(_) => println!("Default set"),
Err(err) => println!("An error occured while setting default:\
{}", err)
}
}
//let mut child = call(prog, &config.action, &config.term.clone().unwrap_or_else(|| "".to_string()));
let mut child = config.run(prog);
child.wait().expect("Failed to wait on child");
}
}
}
if !found {
println!("Sorry, your desired package manager is not supported at this time");
std::process::exit(0);
}
}

36
src/management.rs Normal file
View File

@ -0,0 +1,36 @@
#[allow(dead_code)]
#[derive(Debug)]
/// enum for passing data around the program. Contains each option
/// that rux supports for package management.
pub enum Management {
Search,
Install,
Uninstall,
Remove,
Update,
Upgrade,
Full,
Clear,
CompleteClear,
}
impl Management {
/// Searches through the given commands to find the proper enum variant
/// Setup here to use the same commands `pacman` does though it's no
/// where near as robust. This is very basic and may be improved later
pub fn parse(man: Option<String>) -> Option<Management> {
match &*man.expect("No commands were passed") {
"-Ss" => Some(Management::Search),
"-S" => Some(Management::Install),
"-R" => Some(Management::Uninstall),
"-Rdns" => Some(Management::Remove),
"-Sy" => Some(Management::Upgrade),
"-Su" => Some(Management::Update),
"-Syu" => Some(Management::Full),
"-Sc" => Some(Management::Clear),
"-Scc" => Some(Management::CompleteClear),
_ => None,
}
}
}

123
src/packagemanager.rs Normal file
View File

@ -0,0 +1,123 @@
use std::path::PathBuf;
use std::io::BufReader;
use std::io::prelude::*;
use std::fs::File;
use super::*;
/// Creates a `PackageManager` struct to hold in the needed data
/// to run our commands.
// TODO: figure out a better way to store and access the data.
// Maybe a Vec?
// Currently actions that require multiple inputs will not work
// such as `apt-get update && apt-get upgrade`
#[derive(Debug, Clone, Default)]
pub struct PackageManager {
pub name: String,
pub search: (String, Option<String>),
pub install: (String, Option<String>),
pub uninstall: (String, Option<String>),
pub sup: (String, Option<String>),
pub purge: (String, Option<String>),
pub update: (String, Option<String>),
pub upgrade: (String, Option<String>),
pub cache_clear: (String, Option<String>),
pub complete_cache_clear: (String, Option<String>),
pub exe: PathBuf,
}
/// This holds the various implementations of `PackageManagers` so far.
impl PackageManager {
pub fn pacmatic() -> PackageManager {
PackageManager {
name: "pacmatic".to_string(),
search: ("pacmatic".to_string(), Some("-Ss".to_string())),
install: ("pacmatic".to_string(), Some("-S".to_string())),
uninstall: ("pacmatic".to_string(), Some("-R".to_string())),
sup: ("pacmatic".to_string(), Some("-Syu".to_string())),
purge: ("pacmatic".to_string(), Some("-Rdns".to_string())),
upgrade: ("pacmatic".to_string(), Some("-Su".to_string())),
update: ("pacmatic".to_string(), Some("-Sy".to_string())),
cache_clear: ("pacmatic".to_string(), Some("-Sc".to_string())),
complete_cache_clear: ("pacmatic".to_string(), Some("-Scc".to_string())),
exe: PathBuf::from("/bin/pacmatic"),
}
}
pub fn pacman() -> PackageManager {
PackageManager {
name: "pacman".to_string(),
search: ("pacman".to_string(), Some("-Ss".to_string())),
install: ("pacman".to_string(), Some("-S".to_string())),
uninstall: ("pacman".to_string(), Some("-R".to_string())),
sup: ("pacman".to_string(), Some("-Syu".to_string())),
purge: ("pacman".to_string(), Some("-Rdns".to_string())),
upgrade: ("pacman".to_string(), Some("-Su".to_string())),
update: ("pacman".to_string(), Some("-Sy".to_string())),
cache_clear: ("pacman".to_string(), Some("-Sc".to_string())),
complete_cache_clear: ("pacman".to_string(), Some("-Scc".to_string())),
exe: PathBuf::from("/bin/pacman"),
}
}
pub fn apt() -> PackageManager {
PackageManager {
name: "apt".to_string(),
search: ("apt".to_string(), Some("search".to_string())),
install: ("apt".to_string(), Some("install".to_string())),
uninstall: ("apt".to_string(), Some("remove".to_string())),
sup: ("apt".to_string(), Some("update".to_string())),
purge: ("apt".to_string(), Some("purge".to_string())),
upgrade: ("apt".to_string(), Some("upgrade".to_string())),
update: ("apt".to_string(), Some("update".to_string())),
cache_clear: ("apt".to_string(), Some("clean".to_string())),
complete_cache_clear: ("apt-get".to_string(), Some("autoclean".to_string())),
exe: PathBuf::from("/bin/apt"),
}
}
pub fn xbps() -> PackageManager {
PackageManager {
name: "xbps".to_string(),
search: ("xbps-query".to_string(), Some("-Rs".to_string())),
install: ("xbps-install".to_string(), Some("-S".to_string())),
uninstall: ("xbps-remove".to_string(), None),
sup: ("xbps-install".to_string(), Some("-Su".to_string())),
purge: ("xbps-remove".to_string(), Some("-R".to_string())),
upgrade: ("xbps-install".to_string(), Some("-Su".to_string())),
update: ("xbps-install".to_string(), None),
cache_clear: ("xbps-remove".to_string(), Some("-0".to_string())),
complete_cache_clear: ("xbps-remove".to_string(), Some("-0".to_string())),
exe: PathBuf::from("bin/xbps-install"),
}
}
// allows setting the default.conf
// TODO: put default.conf somewhere it actually belongs rather than in
// the current folder.
pub fn set_default(&self) -> std::io::Result<()> {
let mut file = File::create("default.conf")?;
file.write_all(format!("{}", self.name).as_bytes())?;
Ok(())
}
}
/// Reads from default.conf and returns the appropriate `PackageManager`
/// Pulls the first line out of the default.conf and loads that.
/// If it doesn't recognize the file it will tell the user that there's an
/// issue before exiting.
pub fn read_default() -> PackageManager {
let file = File::open("default.conf").unwrap();
let buffered = BufReader::new(file);
for line in buffered.lines() {
match &*line.unwrap() {
"pacmatic" => return PackageManager::pacmatic(),
"pacman" => return PackageManager::pacman(),
"apt" => return PackageManager::apt(),
"xbps" => return PackageManager::xbps(),
_ => {
println!("Default either not set or has been changed");
std::process::exit(1)
}
}
}
PackageManager::default()
}