From 38e94b6a8c4f7ed0bc9fde0a940f9f5a25ad0427 Mon Sep 17 00:00:00 2001 From: michal Date: Thu, 23 Dec 2021 18:22:48 +0000 Subject: [PATCH 01/33] beginning a longgg process --- Cargo.toml | 12 +-- Makefile | 11 -- src/main.rs | 146 ++++++-------------------- src/mods.rs | 18 +--- src/mods/clearcache.rs | 12 --- src/mods/clone.rs | 180 -------------------------------- src/mods/database.rs | 127 ----------------------- src/mods/help.rs | 24 ----- src/mods/inssort.rs | 208 ------------------------------------- src/mods/install.rs | 59 ----------- src/mods/purge.rs | 121 ---------------------- src/mods/rpc.rs | 2 + src/mods/search.rs | 44 -------- src/mods/stat_database.rs | 100 ------------------ src/mods/statpkgs.rs | 79 -------------- src/mods/strs.rs | 109 ------------------- src/mods/uninstall.rs | 160 ---------------------------- src/mods/update.rs | 17 --- src/mods/upgrade.rs | 213 -------------------------------------- src/mods/ver.rs | 27 ----- src/mods/xargs.rs | 13 --- 21 files changed, 39 insertions(+), 1643 deletions(-) delete mode 100644 Makefile delete mode 100644 src/mods/clearcache.rs delete mode 100644 src/mods/clone.rs delete mode 100644 src/mods/database.rs delete mode 100644 src/mods/help.rs delete mode 100644 src/mods/inssort.rs delete mode 100644 src/mods/install.rs delete mode 100644 src/mods/purge.rs delete mode 100644 src/mods/search.rs delete mode 100644 src/mods/stat_database.rs delete mode 100644 src/mods/statpkgs.rs delete mode 100644 src/mods/strs.rs delete mode 100644 src/mods/uninstall.rs delete mode 100644 src/mods/update.rs delete mode 100644 src/mods/upgrade.rs delete mode 100644 src/mods/ver.rs delete mode 100644 src/mods/xargs.rs diff --git a/Cargo.toml b/Cargo.toml index cbbfd3d..0514545 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,19 +1,13 @@ [package] name = "ame" -version = "0.0.0" +version = "3.0.0" authors = [ "jnats ", "axtlos " ] edition = "2018" -description = "a fast and efficient aur helper." +description = "A fast and efficient aur helper." # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -runas = "0.2.1" -ansi_term = "0.12.1" -uwuizer = "0.2.1" -moins = "0.5.0" -regex = { version = "1.5.4", default-features = false } -toml = "0.5.8" -sqlite = "0.26.0" +clap = "*" reqwest = { version = "0.11.7", default-features = false, features = [ "blocking", "json", "default-tls" ] } serde = { version = "1.0.90", default-features = false, features = [ "derive" ] } \ No newline at end of file diff --git a/Makefile b/Makefile deleted file mode 100644 index c8c0e52..0000000 --- a/Makefile +++ /dev/null @@ -1,11 +0,0 @@ -debug: - cargo build - ln -sf target/debug/ame . -release: - cargo build --release - ln -sf target/release/ame . -clean: - rm -rf target/ Cargo.lock ame -install: - cargo build --release - sudo cp target/release/ame /usr/bin/ame diff --git a/src/main.rs b/src/main.rs index c38eba5..3daa1de 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,118 +1,38 @@ mod mods; -use mods::{ - clearcache::clearcache, - clone::clone, - database::create_database, - help::help, - inssort::{inssort, inssort_from_file}, - install::install, - purge::{purge, purge_from_file}, - search::{a_search, r_search}, - stat_database::*, - statpkgs::*, - strs::err_rec, - strs::err_unrec, - strs::inf, - uninstall::{uninstall, uninstall_from_file}, - update::update, - upgrade::upgrade, - ver::ver, - xargs::*, -}; -use std::{env, process::exit}; +use clap::{App, Arg, SubCommand}; fn main() { - extern "C" { - fn geteuid() -> u32; - } - - if unsafe { geteuid() } == 0 { - // check if user runs ame as root - err_unrec( - "Do not run ame as root! this can cause serious damage to your system!".to_string(), - ); - } - - let args: Vec = env::args().skip(1).collect(); - let mut pkgs: Vec = env::args().skip(2).collect(); - - if args.is_empty() { - help(); - exit(1); - } - - let file = format!("{}/.local/share/ame/aur_pkgs.db", env::var("HOME").unwrap()); - if !std::path::Path::new(&file).exists() { - create_database(); - } - - let oper = &args[0]; - let noconfirm: bool = noconf(&args); - - argssort(&mut pkgs); - match oper.as_str() { - // match oper - "-S" | "-Sn" | "ins" => { - inssort(noconfirm, false, pkgs); // install - } - "-Sl" | "-Sln" | "insl" => { - inssort_from_file(noconfirm, false, &pkgs[0]); // install from file - } - "-B" | "-Bn" | "build" => { - rebuild(noconfirm); // install as a dependency - } - "-R" | "-Rn" | "rm" => { - uninstall(noconfirm, pkgs); // uninstall - } - "-Rs" | "-Rsn" | "purge" => { - purge(noconfirm, pkgs); // purge - } - "-Rl" | "-Rln" | "rml" => { - uninstall_from_file(noconfirm, &pkgs[0]); // uninstall from file - } - "-Rsl" | "-Rsln" | "purgel" => { - purge_from_file(noconfirm, &pkgs[0]); // purge from file - } - "-Syu" | "-Syun" | "upg" => { - upgrade(noconfirm); // upgrade - } - "-Sy" | "upd" => { - update(); // update - } - "-Ss" | "sea" => { - r_search(&args[1]); // search for packages in the repository - a_search(&args[1]); // search for packages in the aur - } - "-Sa" | "aursea" => { - a_search(&args[1]); // search for packages in the aur - } - "-Sr" | "repsea" => { - r_search(&args[1]); // search for packages in the repository - } - "-Cc" | "clr" => { - clearcache(); // clear cache - } - "-v" | "-V" | "ver" => { - ver(); // version - } - "-h" | "help" => { - help(); // help - } - _ => { - // if oper is not valid it either passes the args to pacman or prints an error - let pass = runas::Command::new("pacman") - .args(&args) - .status() - .expect("Something has gone wrong."); - - match pass.code() { - Some(1) => { - err_rec(format!("No such operation \"{}\"", args.join(" "))); - inf("Try running \"ame help\" for an overview of how to use ame".to_string()) - } - Some(_) => {} - None => err_unrec("Something has gone terribly wrong.".to_string()), - } + let matches = App::new("Amethyst") + .version(env!("CARGO_PKG_VERSION")) + .about(env!("CARGO_PKG_DESCRIPTION")) + .arg( + Arg::with_name("verbose") + .short("v") + .multiple(true) + .help("Sets the level of verbosity"), + ) + .subcommand( + SubCommand::with_name ("install") + .about("Installs a package from either the AUR or the PacMan-defined repositories") + .arg( + Arg::with_name("noconfirm") + .short("y") + .long("noconfirm") + .help("Do not ask for confirmation before installing the package") + ) + .arg( + Arg::with_name("package") + .help("The name of the package to install") + .required(true) + .index(1) + ) + ) + .get_matches(); + + match matches.occurrences_of("verbose") { + 0 => println!("No verbosity"), + 1 => println!("Some extra information"), + 2 => println!("Plenty of debug text"), + _ => println!("Screensaver mode"), } - } } diff --git a/src/mods.rs b/src/mods.rs index f87e8c6..25849ae 100644 --- a/src/mods.rs +++ b/src/mods.rs @@ -1,17 +1 @@ -pub mod clearcache; -pub mod clone; -pub mod database; -pub mod help; -pub mod inssort; -pub mod install; -pub mod purge; -pub mod rpc; -pub mod search; -pub mod stat_database; -pub mod statpkgs; -pub mod strs; -pub mod uninstall; -pub mod update; -pub mod upgrade; -pub mod ver; -pub mod xargs; +pub mod rpc; \ No newline at end of file diff --git a/src/mods/clearcache.rs b/src/mods/clearcache.rs deleted file mode 100644 index 86fcf46..0000000 --- a/src/mods/clearcache.rs +++ /dev/null @@ -1,12 +0,0 @@ -use crate::mods::strs::err_rec; -use std::fs; - -pub fn clearcache() { - // delete all files in cache - let path = format!("{}/.cache/ame/", std::env::var("HOME").unwrap()); - - err_rec("Clearing cache".to_string()); - - fs::remove_dir_all(&path).unwrap(); - fs::create_dir(&path).unwrap(); -} diff --git a/src/mods/clone.rs b/src/mods/clone.rs deleted file mode 100644 index 264cd1d..0000000 --- a/src/mods/clone.rs +++ /dev/null @@ -1,180 +0,0 @@ -use crate::{ - err_unrec, inf, mods::database::add_pkg, mods::purge::purge, mods::rpc::*, mods::strs::prompt, - mods::strs::sec, mods::strs::succ, inssort -}; -use moins::Moins; -use std::{env, fs, path::Path, process::Command}; - -fn uninstall_make_depend(pkg: &str) { - // uninstall make depends of a package - let make_depends = rpcinfo(pkg).make_depends; - - let explicit_packages = Command::new("pacman") - .arg("-Qetq") - .stdout(std::process::Stdio::piped()) - .output() - .expect("Something has gone terribly wrong"); - - let expl_pkgs_parse = String::from_utf8(explicit_packages.stdout).unwrap(); - let expl_pkgs_parse = expl_pkgs_parse.split('\n').collect::>(); - - let mut rem_pkgs: Vec = Vec::new(); - for pkg in expl_pkgs_parse { - for md in &make_depends { - if let false = md.contains(pkg) { - if let false = rem_pkgs.contains(md) { - rem_pkgs.push(md.as_str().to_string()); - } - }; - } - } - - if !rem_pkgs.is_empty() { - inf(format!( - "{} installed following make dependencies: {}", - pkg, - rem_pkgs.join(", ") - )); - let remove = prompt("Would you like to remove them?".to_string()); - if remove { - purge(true, rem_pkgs); - } - } - succ(format!("Succesfully installed {}", pkg)); -} - -pub fn clone(noconfirm: bool, as_dep: bool, pkg: &str) { - // clone a package from aur - let cachedir = format!("{}/.cache/ame", env::var("HOME").unwrap()); - let path = Path::new(&cachedir); - let pkgdir = format!("{}/{}", &cachedir, &pkg); - let search = rpcsearch(pkg).results; - let package = search.first().unwrap(); - if search.is_empty() { - err_unrec("No matching AUR packages found".to_string()); - } - - let url = format!("https://aur.archlinux.org/{}.git", pkg); - - if !Path::new(&format!("{}/.cache", env::var("HOME").unwrap())).exists() { - fs::create_dir_all(format!("{}/.cache", env::var("HOME").unwrap())) - .expect("Failed to create ~/.cache directory"); - } - if !path.is_dir() { - let cache_result = fs::create_dir(&path); - match cache_result { - Ok(_) => inf("Created cache path (first run)".to_string()), - Err(_) => err_unrec("Could not create cache path".to_string()), - } - } - - inf(format!("Cloning {} ...", pkg)); - - if Path::new(&pkgdir).is_dir() { - let rm_result = fs::remove_dir_all(&pkgdir); - match rm_result { - Ok(_) => inf(format!( - "Package path for {} already found. Removing to reinstall", - pkg - )), - Err(_) => err_unrec(format!( - "Package path for {} already found, but could not remove to reinstall", - pkg - )), - } - } - - let dir_result = fs::create_dir(&pkgdir); - match dir_result { - Ok(_) => inf(format!("Created package directory for {}", pkg)), - Err(_) => err_unrec(format!("Couldn't create package directory for {}", pkg)), - } - - let cd_result = env::set_current_dir(&pkgdir); - match cd_result { - Ok(_) => inf("Entered package directory".to_string()), - Err(_) => err_unrec("Could not enter package directory".to_string()), - } - - sec("Installing AUR package depends".to_string()); - - let clone = std::process::Command::new("git") - .arg("clone") - .arg(&url) - .arg(&pkgdir) - .status() - .expect("Couldn't clone repository"); - match clone.code() { - Some(0) => { - inf(format!("Cloning {} into package directory", pkg)); - } - Some(_) => err_unrec(format!("Failed cloning {} into package directory", pkg)), - _ => err_unrec(format!("Failed cloning {} into package directory", pkg)), - } - if !as_dep { - if !noconfirm { - let pkgbuild = prompt("View PKGBUILD?".to_string()); - - if pkgbuild { - let mut pkgbld = fs::read_to_string(format!("{}/PKGBUILD", &pkgdir)).unwrap(); - Moins::run(&mut pkgbld, None); - } - } - - sec(format!("Installing {} ...", pkg)); - if noconfirm { - let install_result = Command::new("makepkg") - .arg("-si") - .arg("--noconfirm") - .arg("--needed") - .status(); - match install_result { - Ok(_) => { - uninstall_make_depend(pkg); - let vec = vec![pkg]; - add_pkg(false, &vec); - } - Err(_) => { - err_unrec(format!("Couldn't install {}", pkg)); - } - }; - } else { - let install_result = Command::new("makepkg") - .arg("-si") - .arg("--needed") - .status() - .expect("Couldn't call makepkg"); - match install_result.code() { - Some(0) => { - uninstall_make_depend(pkg); - let vec = vec![pkg]; - add_pkg(false, &vec); - } - Some(_) => { - err_unrec(format!("Couldn't install {}", pkg)); - } - None => { - err_unrec(format!("Couldn't install {}", pkg)); - } - }; - } - } else { - sec(format!("Installing {} ...", pkg)); - let install_result = Command::new("makepkg") - .arg("-si") - .arg("--noconfirm") - .arg("--needed") - .arg("--asdeps") - .status(); - match install_result { - Ok(_) => { - uninstall_make_depend(pkg); - let vec = vec![pkg]; - add_pkg(false, &vec); - } - Err(_) => { - err_unrec(format!("Couldn't install {}", pkg)); - } - }; - } -} diff --git a/src/mods/database.rs b/src/mods/database.rs deleted file mode 100644 index 53f5715..0000000 --- a/src/mods/database.rs +++ /dev/null @@ -1,127 +0,0 @@ -use crate::{err_unrec, inf, mods::rpc::*}; -use std::{env, fs}; - -pub fn create_database() { - let homepath = env::var("HOME").unwrap(); - let file = format!("{}/.local/share/ame/aur_pkgs.db", env::var("HOME").unwrap()); - if !std::path::Path::new(&format!("{}/.local", env::var("HOME").unwrap())).exists() { - fs::create_dir_all(format!("{}/.local", env::var("HOME").unwrap())) - .expect("Failed to create ~/.local"); - } - if !std::path::Path::new(&format!("{}/.local/share/ame/", env::var("HOME").unwrap())).is_dir() { - let _cdar = fs::create_dir_all(format!("/{}/.local/ame/", homepath)); - match _cdar { - Ok(_) => { - inf("Created path for database (previously missing)".to_string()); - } - Err(_) => { - err_unrec("Couldn't create path for database (~/.local/share/ame)".to_string()) - } - } - } - let connection = sqlite::open(file).unwrap(); - connection - .execute( - " - CREATE TABLE pkgs (name TEXT, version TEXT); - ", - ) - .unwrap(); -} - -pub fn get_value(pkg: &str, sear_value: &str) -> String { - let file = format!("{}/.local/share/ame/aur_pkgs.db", env::var("HOME").unwrap()); - let connection = sqlite::open(file).unwrap(); - let mut return_val = String::new(); - match sear_value { - "name" => { - let result = connection.iterate( - format!("SELECT name FROM pkgs WHERE name = {};", &pkg), - |pairs| { - for &(_column, value) in pairs.iter() { - return_val = value.unwrap().to_string(); - } - true - }, - ); - match result { - Ok(_) => {} - Err(_) => err_unrec("Couldn't get value from database".to_string()), - } - } - "version" => { - let result = connection.iterate( - format!("SELECT version FROM pkgs WHERE name = {};", &pkg), - |pairs| { - for &(_column, value) in pairs.iter() { - return_val = value.unwrap().to_string(); - } - true - }, - ); - match result { - Ok(_) => {} - Err(_) => err_unrec("Couldn't get value from database".to_string()), - } - } - _ => { - return_val = "error".to_string(); - } - } - return_val -} - -pub fn rem_pkg(pkgs: &[String]) { - let file = format!("{}/.local/share/ame/aur_pkgs.db", env::var("HOME").unwrap()); - let connection = sqlite::open(file).unwrap(); - - for i in pkgs { - let result = connection.execute(format!( - " - DELETE FROM pkgs WHERE name = \"{}\"; - ", - i - )); - match result { - Ok(_) => inf(format!("Removed {} from database", i)), - Err(_) => err_unrec(format!("Couldn't remove {} from database", i)), - } - } -} - -pub fn add_pkg(from_repo: bool, pkgs: &[&str]) { - for pkg in pkgs { - let file = format!("{}/.local/share/ame/aur_pkgs.db", env::var("HOME").unwrap()); - let connection = sqlite::open(file).unwrap(); - let results = rpcsearch(pkg).results; - let mut package_name = String::new(); - let mut package_version = String::new(); - for res in &results { - package_name = res.name.clone(); - package_version = res.version.clone(); - } - if !from_repo{ - let result = connection.execute(format!( - " - INSERT INTO pkgs (name, version) VALUES (\"{}\", \"{}\"); - ", - package_name, package_version - )); - match result { - Ok(_) => inf(format!("Added {} to database", package_name)), - Err(_) => err_unrec(format!("Couldn't add {} to database", package_name)), - } - } else { - let result = connection.execute(format!( - " - INSERT INTO pkgs (name, version) VALUES (\"{}\", \"{}\"); - ", - pkg, "from_repo" - )); - match result { - Ok(_) => inf(format!("Added {} to database", pkg)), - Err(_) => err_unrec(format!("Couldn't add {} to database", pkg)), - } - } - } -} diff --git a/src/mods/help.rs b/src/mods/help.rs deleted file mode 100644 index 5cd2bee..0000000 --- a/src/mods/help.rs +++ /dev/null @@ -1,24 +0,0 @@ -use crate::mods::strs::{err_rec, inf}; - -pub fn help() { - // print help message - println!(); - inf("Usage:".to_string()); - println!( - " -ame -S(n) / ins - install a package -ame -R(n) / rm - remove a package -ame -Rs(n) / purge - remove a package with it dependencies -ame -Syu(n) / upg - upgrade all packages to latest version -ame -Ss / sea - search for a package -ame -Sa / aursea - search for a package in the aur -ame -Sr / repsea - search for a package in the repos -ame -v / ver - contributors and version info -ame -h / help - display this help message - -ame - passes said flags to be processed by pacman" - ); - println!(); - err_rec("Appending 'n' where (n) is present passes '--noconfirm' to pacman. Use at your own risk. (alternatively, using '--noconfirm' as a flag works too.)".to_string()); - println!(); -} diff --git a/src/mods/inssort.rs b/src/mods/inssort.rs deleted file mode 100644 index d24f97f..0000000 --- a/src/mods/inssort.rs +++ /dev/null @@ -1,208 +0,0 @@ -use crate::{clone, err_unrec, install, mods::strs::sec, mods::rpc::*}; -use regex::Regex; -use std::process::{Command, Stdio}; - -pub fn inssort(noconfirm: bool, as_dep: bool, pkgs: Vec) { - // TODO: understand what the fuck is actually going on here - let mut repo = vec![]; - let mut aur = vec![]; - let re = Regex::new(r"(\S+)((?:>=|<=|>|<)\S+$)").unwrap(); - let reg = Regex::new(r"((?:>=|<=|>|<)\S+$)").unwrap(); - for pkg in pkgs { - match pkg.contains('/') { - true => match pkg.split('/').collect::>()[0] == "aur" { - true => { - aur.push(pkg.split('/').collect::>()[1].to_string()); - } - false => { - let out = Command::new("bash") - .arg("-c") - .arg(format!( - "pacman -Sl {} | grep {}", - pkg.split('/').collect::>()[0], - pkg.split('/').collect::>()[1] - )) - .stdout(Stdio::null()) - .status() - .expect("Something has gone wrong."); - match out.code() { - Some(0) => repo.push(reg.replace_all(&pkg, "").to_string()), - Some(1) => err_unrec(format!( - "Package {} not found in repository {}", - pkg.split('/').collect::>()[1], - pkg.split('/').collect::>()[0] - )), - Some(_) => err_unrec("Something has gone terribly wrong".to_string()), - None => err_unrec("Process terminated".to_string()), - } - } - }, - false => { - let caps = re.captures(&pkg); - match caps { - Some(_) => { - let out = Command::new("pacman") - .arg("-Ss") - .arg(format!( - "^{}$", - caps.unwrap().get(1).map_or("", |m| m.as_str()) - )) - .stdout(Stdio::null()) - .status() - .expect("Something has gone wrong."); - match out.code() { - Some(0) => repo.push(reg.replace_all(&pkg, "").to_string()), - Some(1) => aur.push(pkg), - Some(_) => err_unrec("Something has gone terribly wrong".to_string()), - None => err_unrec("Process terminated".to_string()), - } - } - None => { - let out = Command::new("pacman") - .arg("-Ss") - .arg(format!("^{}$", &pkg)) - .stdout(Stdio::null()) - .status() - .expect("Something has gone wrong."); - match out.code() { - Some(0) => repo.push(pkg), - Some(1) => aur.push(pkg), - Some(_) => err_unrec("Something has gone terribly wrong".to_string()), - None => err_unrec("Process terminated".to_string()), - } - } - } - } - } - } - if !as_dep { - if !repo.is_empty() { - sec(format!("Installing repo packages: {}", &repo.join(", "))); - install(noconfirm, false, &repo.join(" ")); - } - - for a in aur { - sec(format!("Couldn't find {} in repos. Searching AUR", a)); - let md = &rpcinfo(&a).make_depends; - inssort(noconfirm, true, md.to_vec()); - clone(noconfirm, false, &a); - } - } else { - if !repo.is_empty() { - sec(format!("Installing repo packages: {}", &repo.join(", "))); - install(noconfirm, true, &repo.join(" ")); - } - - for a in aur { - sec(format!("Couldn't find {} in repos. Searching AUR", a)); - let md = &rpcinfo(&a).make_depends; - inssort(noconfirm, true, md.to_vec()); - clone(noconfirm, true, &a); - } - } -} - -pub fn inssort_from_file(noconfirm: bool, as_dep: bool, file: &str) { - // same thing as above but with a list of packages from a file - let mut pkgs: Vec = Vec::new(); - let contents = std::fs::read_to_string(&file).expect("Couldn't read file"); - for line in contents.lines() { - pkgs.push(line.to_string()); - } - let mut repo = vec![]; - let mut aur = vec![]; - let re = Regex::new(r"(\S+)((?:>=|<=)\S+$)").unwrap(); - let reg = Regex::new(r"((?:>=|<=)\S+$)").unwrap(); - for pkg in pkgs { - match pkg.contains('/') { - true => match pkg.split('/').collect::>()[0] == "aur" { - true => { - aur.push(pkg.split('/').collect::>()[1].to_string()); - } - false => { - let out = Command::new("bash") - .arg("-c") - .arg(format!( - "pacman -Sl {} | grep {}", - pkg.split('/').collect::>()[0], - pkg.split('/').collect::>()[1] - )) - .stdout(Stdio::null()) - .status() - .expect("Something has gone wrong."); - match out.code() { - Some(0) => repo.push(reg.replace_all(&pkg, "").to_string()), - Some(1) => err_unrec(format!( - "Package {} not found in repository {}", - pkg.split('/').collect::>()[1], - pkg.split('/').collect::>()[0] - )), - Some(_) => err_unrec("Something has gone terribly wrong".to_string()), - None => err_unrec("Process terminated".to_string()), - } - } - }, - false => { - let caps = re.captures(&pkg); - match caps { - Some(_) => { - let out = Command::new("pacman") - .arg("-Ss") - .arg(format!( - "^{}$", - caps.unwrap().get(1).map_or("", |m| m.as_str()) - )) - .stdout(Stdio::null()) - .status() - .expect("Something has gone wrong."); - match out.code() { - Some(0) => repo.push(reg.replace_all(&pkg, "").to_string()), - Some(1) => aur.push(pkg), - Some(_) => err_unrec("Something has gone terribly wrong".to_string()), - None => err_unrec("Process terminated".to_string()), - } - } - None => { - let out = Command::new("pacman") - .arg("-Ss") - .arg(format!("^{}$", &pkg)) - .stdout(Stdio::null()) - .status() - .expect("Something has gone wrong."); - match out.code() { - Some(0) => repo.push(pkg), - Some(1) => aur.push(pkg), - Some(_) => err_unrec("Something has gone terribly wrong".to_string()), - None => err_unrec("Process terminated".to_string()), - } - } - } - } - } - } - if !as_dep { - if !repo.is_empty() { - sec(format!("Installing repo packages: {}", &repo.join(", "))); - install(noconfirm, false, &repo.join(" ")); - } - - for a in aur { - sec(format!("Couldn't find {} in repos. Searching AUR", a)); - let md = &rpcinfo(&a).make_depends; - inssort(noconfirm, true, md.to_vec()); - clone(noconfirm, false, &a); - } - } else { - if !repo.is_empty() { - sec(format!("Installing repo packages: {}", &repo.join(", "))); - install(noconfirm, true, &repo.join(" ")); - } - - for a in aur { - sec(format!("Couldn't find {} in repos. Searching AUR", a)); - let md = &rpcinfo(&a).make_depends; - inssort(noconfirm, true, md.to_vec()); - clone(noconfirm, true, &a); - } - } -} diff --git a/src/mods/install.rs b/src/mods/install.rs deleted file mode 100644 index 2c13edf..0000000 --- a/src/mods/install.rs +++ /dev/null @@ -1,59 +0,0 @@ -use crate::mods::database::add_pkg; -use crate::mods::strs::{err_unrec, succ}; -use runas::Command; - -pub fn install(noconfirm: bool, as_dep: bool, pkg: &str) { - // install a package - let pkgs: Vec<&str> = pkg.split(' ').collect(); - if !as_dep { - if noconfirm { - let result = Command::new("pacman") - .arg("-S") - .arg("--noconfirm") - .arg("--needed") - .args(&pkgs) - .status() - .expect("Couldn't call pacman"); - match result.code() { - Some(0) => { - succ(format!("Succesfully installed packages: {}", pkg)); - add_pkg(true, &pkgs); - } - Some(_) => err_unrec(format!("Couldn't install packages: {}", pkg)), - None => err_unrec(format!("Couldn't install packages: {}", pkg)), - }; - } else { - let result = Command::new("pacman") - .arg("-S") - .arg("--needed") - .args(&pkgs) - .status() - .expect("Couldn't call pacman"); - match result.code() { - Some(0) => { - succ(format!("Succesfully installed packages: {}", pkg)); - add_pkg(true, &pkgs); - } - Some(_) => err_unrec(format!("Couldn't install packages: {}", pkg)), - None => err_unrec(format!("Couldn't install packages: {}", pkg)), - }; - } - } else { - let result = Command::new("pacman") - .arg("-S") - .arg("--noconfirm") - .arg("--needed") - .arg("--asdeps") - .args(&pkgs) - .status() - .expect("Couldn't call pacman"); - match result.code() { - Some(0) => { - succ(format!("Succesfully installed packages: {}", pkg)); - add_pkg(true, &pkgs); - } - Some(_) => err_unrec(format!("Couldn't install packages: {}", pkg)), - None => err_unrec(format!("Couldn't install packages: {}", pkg)), - }; - } -} diff --git a/src/mods/purge.rs b/src/mods/purge.rs deleted file mode 100644 index 6879507..0000000 --- a/src/mods/purge.rs +++ /dev/null @@ -1,121 +0,0 @@ -use crate::mods::{ - database::rem_pkg, - strs::{err_rec, err_unrec, sec, succ}, -}; -use runas::Command; -use std::{fs, path::Path}; - -pub fn purge(noconfirm: bool, pkgs: Vec) { - // purge packages - sec(format!( - "Attempting to uninstall packages: {}", - &pkgs.join(" ") - )); - if noconfirm { - let result = Command::new("pacman") - .arg("-Rsu") - .args(&pkgs) - .arg("--noconfirm") - .status() - .expect("Couldn't call pacman"); - match result.code() { - Some(0) => { - succ(format!( - "Succesfully uninstalled packages: {}", - &pkgs.join(" ") - )); - rem_pkg(&pkgs); - } - Some(_) => err_rec(format!("Couldn't uninstall packages: {}", &pkgs.join(" "))), - None => err_rec(format!("Couldn't uninstall packages: {}", &pkgs.join(" "))), - }; - } else { - let result = Command::new("pacman") - .arg("-Rsu") - .args(&pkgs) - .status() - .expect("Couldn't call pacman"); - match result.code() { - Some(0) => { - succ(format!( - "Succesfully uninstalled packages: {}", - &pkgs.join(" ") - )); - rem_pkg(&pkgs); - } - Some(_) => err_rec(format!("Couldn't uninstall packages: {}", &pkgs.join(" "))), - None => err_rec(format!("Couldn't uninstall packages: {}", &pkgs.join(" "))), - }; - } - for pkg in &pkgs { - let pkgdir = format!("{}/.cache/ame/{}", std::env::var("HOME").unwrap(), pkg); - let path = Path::new(&pkgdir); - if path.is_dir() { - let rm_result = fs::remove_dir_all(&path); - match rm_result { - Ok(_) => succ(format!("Removed AUR cache directory for {}", pkg)), - Err(_) => err_unrec(format!("Failed to remove AUR cache directory for {}", pkg)), - }; - } - } -} - -pub fn purge_from_file(noconfirm: bool, file: &str) { - // purge packages from list of packages - let mut pkgs: Vec = Vec::new(); - let contents = std::fs::read_to_string(&file).expect("Couldn't read file"); - for line in contents.lines() { - pkgs.push(line.to_string()); - } - sec(format!( - "Attempting to uninstall packages: {}", - &pkgs.join(" ") - )); - if noconfirm { - let result = Command::new("pacman") - .arg("-Rsu") - .args(&pkgs) - .arg("--noconfirm") - .status() - .expect("Couldn't call pacman"); - match result.code() { - Some(0) => { - succ(format!( - "Succesfully uninstalled packages: {}", - &pkgs.join(" ") - )); - rem_pkg(&pkgs); - } - Some(_) => err_rec(format!("Couldn't uninstall packages: {}", &pkgs.join(" "))), - None => err_rec(format!("Couldn't uninstall packages: {}", &pkgs.join(" "))), - }; - } else { - let result = Command::new("pacman") - .arg("-Rsu") - .args(&pkgs) - .status() - .expect("Couldn't call pacman"); - match result.code() { - Some(0) => { - succ(format!( - "Succesfully uninstalled packages: {}", - &pkgs.join(" ") - )); - rem_pkg(&pkgs); - } - Some(_) => err_rec(format!("Couldn't uninstall packages: {}", &pkgs.join(" "))), - None => err_rec(format!("Couldn't uninstall packages: {}", &pkgs.join(" "))), - }; - } - for pkg in &pkgs { - let pkgdir = format!("{}/.cache/ame/{}", std::env::var("HOME").unwrap(), pkg); - let path = Path::new(&pkgdir); - if path.is_dir() { - let rm_result = fs::remove_dir_all(&path); - match rm_result { - Ok(_) => succ(format!("Removed AUR cache directory for {}", pkg)), - Err(_) => err_unrec(format!("Failed to remove AUR cache directory for {}", pkg)), - }; - } - } -} diff --git a/src/mods/rpc.rs b/src/mods/rpc.rs index be9cc13..ab9ab35 100644 --- a/src/mods/rpc.rs +++ b/src/mods/rpc.rs @@ -1,3 +1,5 @@ +#![allow(dead_code)] + #[derive(serde::Deserialize, Debug, Clone)] pub struct Package { #[serde(rename = "Name")] diff --git a/src/mods/search.rs b/src/mods/search.rs deleted file mode 100644 index f3c0e31..0000000 --- a/src/mods/search.rs +++ /dev/null @@ -1,44 +0,0 @@ -use crate::mods::rpc::*; -use crate::mods::strs::{err_rec, err_unrec, succ}; -use ansi_term::Colour; -use std::process::Command; - -pub fn a_search(pkg: &str) { - // search for a package in the AUR - let results = rpcsearch(pkg).results; - - for r in &results { - if results.is_empty() { - err_rec("No matching AUR packages found".to_string()); - } - println!( - "{}{} {}\n {}", - Colour::Cyan.bold().paint("aur/"), - Colour::White.bold().paint(&r.name), - Colour::Green.bold().paint(&r.version), - Colour::White.paint( - r.description - .as_ref() - .unwrap_or(&"No description available".to_string()) - ) - ); - } - if !results.is_empty() { - succ("AUR search successful".to_string()); - } -} - -pub fn r_search(pkg: &str) { - // search for a package in the repositories - let result = Command::new("pacman") - .arg("-Ss") - .arg(&pkg) - .status() - .unwrap(); - match result.code() { - Some(0) => succ("Repo search successful".to_string()), - Some(1) => err_rec("No matching repo packages found".to_string()), - Some(_) => err_unrec("Someting went terribly wrong".to_string()), - None => err_unrec("Couldn't search pacman repos".to_string()), - }; -} diff --git a/src/mods/stat_database.rs b/src/mods/stat_database.rs deleted file mode 100644 index cec1b91..0000000 --- a/src/mods/stat_database.rs +++ /dev/null @@ -1,100 +0,0 @@ -use crate::{err_unrec, inf}; -use std::env; - -pub fn stat_dump_dat() -> Vec { - let file = format!("{}/.local/share/ame/aur_pkgs.db", env::var("HOME").unwrap()); - let connection = sqlite::open(file).unwrap(); - let mut dat_pkgs = Vec::new(); - let result = connection.iterate("SELECT name FROM static_pkgs", |pairs| { - for &(_column, value) in pairs.iter() { - dat_pkgs.push(value.unwrap().to_string()); - } - true - }); - match result { - Ok(_) => { - //inf("Dumped static packages".to_string()); - } - Err(_) => err_unrec("Couldn't dump packages from database".to_string()), - } - dat_pkgs -} - -pub fn stat_get_value(pkg: &str, sear_value: &str) -> bool { - let file = format!("{}/.local/share/ame/aur_pkgs.db", env::var("HOME").unwrap()); - let connection = sqlite::open(file).unwrap(); - let mut return_val = false; - match sear_value { - "name" => { - let result = connection.iterate( - format!("SELECT name FROM static_pkgs WHERE name = \"{}\";", &pkg), - |pairs| { - for &(_column, _value) in pairs.iter() { - return_val = true; - } - return_val - }, - ); - match result { - Ok(_) => {} - Err(_) => err_unrec("Couldn't get value from database".to_string()), - } - return return_val; - } - "update" => { - let result = connection.iterate( - format!("SELECT pin FROM static_pkgs WHERE name = \"{}\";", &pkg), - |pairs| { - for &(_column, _value) in pairs.iter() { - return_val = true; - } - return_val - }, - ); - match result { - Ok(_) => {} - Err(_) => err_unrec("Couldn't get value from database".to_string()), - } - return return_val; - } - _ => return_val = false, - } - return_val -} - -pub fn stat_rem_pkg(static_pkgs: &[String]) { - let file = format!("{}/.local/share/ame/aur_pkgs.db", env::var("HOME").unwrap()); - let connection = sqlite::open(file).unwrap(); - print!("{:?}", static_pkgs); - for i in static_pkgs { - let result = connection.execute(format!( - " - DELETE FROM static_pkgs WHERE name = \"{}\"; - ", - i - )); - match result { - Ok(_) => inf(format!("Removed {} from database", i)), - Err(_) => err_unrec(format!( - "Couldn't remove {} from database (static packages table)", - i - )), - } - } -} - -pub fn stat_add_pkg(update: &str, pkg: &str) { - let file = format!("{}/.local/share/ame/aur_pkgs.db", env::var("HOME").unwrap()); - let connection = sqlite::open(file).unwrap(); - let pin = if update == "true" { 1 } else { 0 }; - let result = connection.execute(format!( - " - INSERT INTO static_pkgs (name, pin) VALUES (\"{}\", {}); - ", - pkg, pin - )); - match result { - Ok(_) => inf(format!("Added {} to database", pkg)), - Err(_) => err_unrec(format!("Couldn't add {} to database", pkg)), - } -} diff --git a/src/mods/statpkgs.rs b/src/mods/statpkgs.rs deleted file mode 100644 index 50db5b5..0000000 --- a/src/mods/statpkgs.rs +++ /dev/null @@ -1,79 +0,0 @@ -use crate::inf; -use crate::{ - err_rec, inssort, stat_add_pkg, stat_dump_dat, stat_get_value, stat_rem_pkg, uninstall, -}; -use std::{env, fs}; - -pub fn rebuild(noconfirm: bool) { - let file = format!("{}/.config/ame/pkgs.toml", env::var("HOME").unwrap()); - let database = fs::read_to_string(&file).expect("Can't Open Database"); - inf("installing crystal config".to_string()); - - let file = format!("{}/.local/share/ame/aur_pkgs.db", env::var("HOME").unwrap()); - let connection = sqlite::open(file).unwrap(); - connection - .execute( - " - CREATE TABLE IF NOT EXISTS static_pkgs (name TEXT, pin INTEGER); - ", - ) - .unwrap(); - - let db_parsed = database.parse::().expect("Invalid Database"); - let mut pkgs = Vec::new(); - if let Some(entry) = db_parsed.as_table() { - for (key, value) in &*entry { - let mut tempvec = Vec::new(); - // println!("{}", key); - // println!("{}", format!("{}",value).replace("update = ", "")); - tempvec.push(key.to_string()); - tempvec.push(format!("{}", value).replace("update = ", "")); - pkgs.push(tempvec); - } - } - let mut pkgs_to_add: Vec> = Vec::new(); - let mut pkgs_to_install: Vec = Vec::new(); - for i in pkgs { - if !stat_get_value(&i[0], "name") { - let tempvec = vec![i[0].to_string(), i[1].to_string()]; - pkgs_to_add.push(tempvec); - pkgs_to_install.push(i[0].to_string()); - } - } - let mut config_no_change = 0; - if !pkgs_to_install.is_empty() { - inf(format!("Installing {}", pkgs_to_install.join(", "))); - inssort(noconfirm, false, pkgs_to_install); - for i in pkgs_to_add { - stat_add_pkg(&i[1], &i[0]); - } - config_no_change += 1; - } - let dat_pkgs = stat_dump_dat(); - - let mut pkgs = Vec::new(); - if let Some(entry) = db_parsed.as_table() { - for (key, _value) in &*entry { - pkgs.push(key); - } - } - - let mut pkgs_to_remove: Vec = Vec::new(); - for i in dat_pkgs { - if !pkgs.contains(&&i) { - pkgs_to_remove.push(i.to_string()); - } - config_no_change += 1; - } - if !pkgs_to_remove.is_empty() { - inf(format!("Removing {}", pkgs_to_remove.join(", "))); - stat_rem_pkg(&pkgs_to_remove); - uninstall(noconfirm, pkgs_to_remove); - } - - if config_no_change != 0 { - inf("Rebuild Complete".to_string()); - } else { - err_rec("Configuration not changed!".to_string()); - } -} diff --git a/src/mods/strs.rs b/src/mods/strs.rs deleted file mode 100644 index 6cc5e50..0000000 --- a/src/mods/strs.rs +++ /dev/null @@ -1,109 +0,0 @@ -use ansi_term::Colour; -use std::{env, io, io::Write, process, string}; -use uwuizer::*; - -pub fn inf(a: string::String) { - // info - if env::var("AME_UWU").unwrap_or_else(|_| "n/a".to_string()) == "YES" { - println!( - "{} {}", - Colour::Purple.paint("❖"), - Colour::White.paint(uwuize!(&a)) - ); - } else { - println!("{} {}", Colour::Purple.paint("❖"), Colour::White.paint(a)); - } -} - -pub fn sec(a: string::String) { - if env::var("AME_UWU").unwrap_or_else(|_| "n/a".to_string()) == "YES" { - println!( - "{} {}", - Colour::Purple.bold().paint("❖"), - Colour::White.bold().paint(uwuize!(&a)) - ); - } else { - println!( - "{} {}", - Colour::Purple.bold().paint("❖"), - Colour::White.bold().paint(a) - ); - } -} - -pub fn succ(a: string::String) { - // success - if env::var("AME_UWU").unwrap_or_else(|_| "n/a".to_string()) == "YES" { - println!( - "{} {}", - Colour::Green.bold().paint("✓"), - Colour::Green.paint(uwuize!(&a)) - ); - } else { - println!( - "{} {}", - Colour::Green.bold().paint("✓"), - Colour::Green.paint(&a) - ); - } -} - -pub fn prompt(a: string::String) -> bool { - // prompt - if env::var("AME_UWU").unwrap_or_else(|_| "n/a".to_string()) == "YES" { - print!( - "{} {} {}", - Colour::Purple.bold().paint("❖"), - Colour::White.bold().paint(uwuize!(&a)), - Colour::White.bold().paint("(Y/n): ") - ); - } else { - print!( - "{} {} {}", - Colour::Purple.bold().paint("❖"), - Colour::White.bold().paint(&a), - Colour::White.bold().paint("(Y/n): ") - ); - } - io::stdout().flush().ok(); - let mut yn: String = String::new(); - let _ = std::io::stdin().read_line(&mut yn); - !(yn.trim() == "n" || yn.trim() == "N" || yn.trim() == "no" || yn.trim() == "No") -} - -pub fn err_unrec(a: string::String) { - // unrecoverable error - if env::var("AME_UWU").unwrap_or_else(|_| "n/a".to_string()) == "YES" { - println!( - "{} {} {}", - Colour::Red.bold().paint(uwuize!("✖ Unrecoverable error:")), - Colour::Red.paint(uwuize!(&a)), - Colour::Red.bold().paint(uwuize!("Terminating.")) - ); - } else { - println!( - "{} {} {}", - Colour::Red.bold().paint("✖ Unrecoverable error:"), - Colour::Red.paint(a), - Colour::Red.bold().paint("Terminating.") - ); - } - process::exit(1); -} - -pub fn err_rec(a: string::String) { - // recoverable error - if env::var("AME_UWU").unwrap_or_else(|_| "n/a".to_string()) == "YES" { - println!( - "{} {}", - Colour::Yellow.bold().paint(uwuize!("⚠ WARNING:")), - Colour::Yellow.paint(uwuize!(&a)) - ); - } else { - println!( - "{} {}", - Colour::Yellow.bold().paint("⚠ WARNING:"), - Colour::Yellow.paint(a) - ); - } -} diff --git a/src/mods/uninstall.rs b/src/mods/uninstall.rs deleted file mode 100644 index 6b04845..0000000 --- a/src/mods/uninstall.rs +++ /dev/null @@ -1,160 +0,0 @@ -use crate::mods::{ - database::rem_pkg, - strs::{err_rec, err_unrec, sec, succ}, -}; -use runas::Command; -use std::{fs, path::Path}; - -pub fn uninstall(noconfirm: bool, pkgs: Vec) { - // uninstall a package - sec(format!( - "Attempting to uninstall packages: {}", - &pkgs.join(" ") - )); - - let important = [ - "base", - "linux", - "linux-firmware", - "systemd-sysvcompat", - "networkmanager", - "man-db", - "man-pages", - "texinfo", - "sudo", - "curl", - "archlinux-keyring", - "btrfs-progs", - "timeshift", - "timeshift-autosnap", - ]; - - let mut overrides: Vec = Vec::new(); - if Path::new("/etc/ame/overrides.conf").exists() { - overrides = fs::read_to_string("/etc/ame/overrides.conf") - .expect("Failed to read overrides.conf") - .lines() - .map(|s| s.to_string()) - .collect(); - } - - let mut matches: Vec = Vec::new(); - for pkg in pkgs.iter() { - for imp in important.iter() { - if pkg == imp && !overrides.contains(pkg) { - matches.push(pkg.to_string()); - } - } - } - if !matches.is_empty() { - err_unrec(format!("The action you called for tries to uninstall packages: {} . This is disallowed by default as these are important system packages. If you fully know what you are doing and would like to uninstall these, please create an override in /etc/ame/overrides.conf.", matches.join(" "))); - } - - if noconfirm { - let result = Command::new("pacman") - .arg("-Ru") - .args(&pkgs) - .arg("--noconfirm") - .status() - .expect("Couldn't call pacman"); - match result.code() { - Some(0) => { - succ(format!( - "Succesfully uninstalled packages: {}", - &pkgs.join(" ") - )); - rem_pkg(&pkgs); - } - Some(_) => err_rec(format!("Couldn't uninstall packages: {}", &pkgs.join(" "))), - None => err_rec(format!("Couldn't uninstall packages: {}", &pkgs.join(" "))), - }; - } else { - let result = Command::new("pacman") - .arg("-Ru") - .args(&pkgs) - .status() - .expect("Couldn't call pacman"); - match result.code() { - Some(0) => { - succ(format!( - "Succesfully uninstalled packages: {}", - &pkgs.join(" ") - )); - rem_pkg(&pkgs); - } - Some(_) => err_rec(format!("Couldn't uninstall packages: {}", &pkgs.join(" "))), - None => err_rec(format!("Couldn't uninstall packages: {}", &pkgs.join(" "))), - }; - } - for pkg in &pkgs { - let pkgdir = format!("{}/.cache/ame/{}", std::env::var("HOME").unwrap(), pkg); - let path = Path::new(&pkgdir); - if path.is_dir() { - let rm_result = fs::remove_dir_all(&path); - match rm_result { - Ok(_) => succ(format!("Removed AUR cache directory for {}", pkg)), - Err(_) => err_unrec(format!("Failed to remove AUR cache directory for {}", pkg)), - }; - } - } -} - -pub fn uninstall_from_file(noconfirm: bool, file: &str) { - // uninstall a package from a list of packages - let mut pkgs: Vec = Vec::new(); - let contents = std::fs::read_to_string(&file).expect("Couldn't read file"); - for line in contents.lines() { - pkgs.push(line.to_string()); - } - sec(format!( - "Attempting to uninstall packages: {}", - &pkgs.join(" ") - )); - if noconfirm { - let result = Command::new("pacman") - .arg("-Ru") - .args(&pkgs) - .arg("--noconfirm") - .status() - .expect("Couldn't call pacman"); - match result.code() { - Some(0) => { - succ(format!( - "Succesfully uninstalled packages: {}", - &pkgs.join(" ") - )); - rem_pkg(&pkgs); - } - Some(_) => err_rec(format!("Couldn't uninstall packages: {}", &pkgs.join(" "))), - None => err_rec(format!("Couldn't uninstall packages: {}", &pkgs.join(" "))), - }; - } else { - let result = Command::new("pacman") - .arg("-Ru") - .args(&pkgs) - .status() - .expect("Couldn't call pacman"); - match result.code() { - Some(0) => { - succ(format!( - "Succesfully uninstalled packages: {}", - &pkgs.join(" ") - )); - rem_pkg(&pkgs); - } - Some(_) => err_rec(format!("Couldn't uninstall packages: {}", &pkgs.join(" "))), - None => err_rec(format!("Couldn't uninstall packages: {}", &pkgs.join(" "))), - }; - } - for pkg in &pkgs { - let pkgdir = format!("{}/.cache/ame/{}", std::env::var("HOME").unwrap(), pkg); - let path = Path::new(&pkgdir); - if path.is_dir() { - let rm_result = fs::remove_dir_all(&path); - match rm_result { - Ok(_) => succ(format!("Removed AUR cache directory for {}", pkg)), - Err(_) => err_unrec(format!("Failed to remove AUR cache directory for {}", pkg)), - }; - } - } -} diff --git a/src/mods/update.rs b/src/mods/update.rs deleted file mode 100644 index 8b76034..0000000 --- a/src/mods/update.rs +++ /dev/null @@ -1,17 +0,0 @@ -use crate::mods::strs::{err_unrec, sec, succ}; -use runas::Command; - -pub fn update() { - // update the repositories - sec("Syncing package repos".to_string()); - - let result = Command::new("pacman") - .arg("-Sy") - .status() - .expect("Couldn't call pacman"); - match result.code() { - Some(0) => succ("Repos succesfully synced".to_string()), - Some(_) => err_unrec("Couldn't sync package repos".to_string()), - None => err_unrec("Couldn't sync package repos".to_string()), - } -} diff --git a/src/mods/upgrade.rs b/src/mods/upgrade.rs deleted file mode 100644 index 7fdf94f..0000000 --- a/src/mods/upgrade.rs +++ /dev/null @@ -1,213 +0,0 @@ -use crate::{ - err_rec, err_unrec, inf, inssort, mods::database::get_value, mods::rpc::*, mods::strs::prompt, - mods::strs::sec, mods::strs::succ, uninstall, -}; -use runas::Command; -use std::{env, fs, path::Path}; -use toml; - -fn uninstall_make_depend(pkg: &str) { - // uninstall make depends installed by ame itself - let make_depends = rpcinfo(pkg).make_depends; - - if !make_depends.is_empty() { - inf(format!( - "{} installed following make dependencies: {}", - pkg, - make_depends.join(", ") - )); - let remove = prompt("Would you like to remove them?".to_string()); - if remove { - uninstall(true, make_depends); - } - } - succ(format!("Succesfully upgraded {}", pkg)); -} - -pub fn upgrade(noconfirm: bool) { - // upgrade all packages - let homepath = env::var("HOME").unwrap(); - let cachedir = format!("/{}/.cache/ame/", homepath); - let cache_exists = Path::new(&format!("/{}/.cache/ame/", homepath)).is_dir(); - let file = format!("{}/.local/ame/aurPkgs.db", env::var("HOME").unwrap()); - let database = String::new(); - if Path::new(&file).exists() { - let _db = fs::read_to_string(&file).expect("Can't Open Database"); - } else { - let _cdar = fs::create_dir_all(format!("/{}/.local/ame/", homepath)); - match _cdar { - Ok(_) => inf("Created cache directory (previously missing)".to_string()), - Err(_) => err_unrec("Couldn't create cache directory".to_string()), - } - err_rec(String::from("Database wasn't found, creating new one")); - let _dbfile = fs::File::create(&file); - let _db = String::new(); - } - let db_parsed = database.parse::().expect("Invalid Database"); - - if !cache_exists { - let cachecreate = fs::create_dir_all(&cachedir); - match cachecreate { - Ok(_) => inf("Creating cachedir. (didn't exist previously)".to_string()), - Err(_) => err_unrec("Couldn't create cachedir".to_string()), - } - } - sec("Performing system upgrade".to_string()); - if noconfirm { - let result = Command::new("pacman") - .arg("-Syu") - .arg("--noconfirm") - .status() - .expect("Couldn't call pacman"); - match result.code() { - Some(0) => succ("All repo packages upgraded".to_string()), - Some(_) => err_unrec("Couldn't upgrade packages".to_string()), - None => err_unrec("Couldn't upgrade packages".to_string()), - }; - } else { - let result = Command::new("pacman") - .arg("-Syu") - .status() - .expect("Couldn't call pacman"); - match result.code() { - Some(0) => succ("All repo packages upgraded".to_string()), - Some(_) => err_unrec("Couldn't upgrade packages".to_string()), - None => err_unrec("Couldn't upgrade packages".to_string()), - }; - } - - if let Some(entry) = db_parsed.as_table() { - for (key, _value) in &*entry { - let results = rpcsearch(&key.to_string()).results; - let url = format!("https://aur.archlinux.org/{}.git", key); - let package = rpcinfo(&key.to_string()); - let version = get_value(key, "version"); - if results[0].version.contains(&version) { - let keydir = format!("{}{}", &cachedir, &key); - if Path::new(&keydir).is_dir() { - let cd_result = env::set_current_dir(&keydir); - match cd_result { - Ok(_) => inf("Entered package directory".to_string()), - Err(_) => err_unrec("Could not enter package directory".to_string()), - } - inssort(true, true, package.depends.clone()); - - sec(format!("Installing {} ...", &key)); - let install_result = std::process::Command::new("makepkg") - .arg("-si") - .arg("--noconfirm") - .arg("--needed") - .status(); - match install_result { - Ok(_) => { - uninstall_make_depend(key); - } - Err(_) => { - err_unrec(format!("Couldn't install {}", &key)); - } - }; - - sec(format!("Installing {} ...", &key)); - let install_result = std::process::Command::new("makepkg") - .arg("-si") - .arg("--needed") - .status() - .expect("Couldn't call makepkg"); - match install_result.code() { - Some(0) => { - uninstall_make_depend(key); - } - Some(_) => { - err_unrec(format!("Couldn't install {}", &key)); - } - None => { - err_unrec(format!("Couldn't install {}", &key)); - } - }; - } else { - inf(format!("Cloning {} ...", &key)); - - if Path::new(&keydir).is_dir() { - let rm_result = fs::remove_dir_all(&keydir); - match rm_result { - Ok(_) => inf(format!( - "Package path for {} already found. Removing to reinstall", - &key - )), - Err(_) => err_unrec(format!( - "Package path for {} already found, but could not remove to reinstall", - &key - )), - } - } - - let dir_result = fs::create_dir(&keydir); - match dir_result { - Ok(_) => inf(format!("Created package directory for {}", &key)), - Err(_) => { - err_unrec(format!("Couldn't create package directory for {}", &key)) - } - } - - let cd_result = env::set_current_dir(&keydir); - match cd_result { - Ok(_) => inf("Entered package directory".to_string()), - Err(_) => err_unrec("Could not enter package directory".to_string()), - } - - inssort(true, true, package.depends.clone()); - - let clone = std::process::Command::new("git") - .arg("clone") - .arg(&url) - .arg(&keydir) - .status() - .expect("Couldn't clone repo"); - match clone.code() { - Some(0) => { - inf(format!("Cloning {} into package directory", &key)); - } - Some(_) => { - err_unrec(format!("Failed cloning {} into package directory", &key)) - } - _ => err_unrec(format!("Failed cloning {} into package directory", &key)), - } - } - - sec(format!("Installing {} ...", &key)); - let install_result = std::process::Command::new("makepkg") - .arg("-si") - .arg("--noconfirm") - .arg("--needed") - .status(); - match install_result { - Ok(_) => { - uninstall_make_depend(key); - } - Err(_) => { - err_unrec(format!("Couldn't install {}", &key)); - } - }; - sec(format!("Installing {} ...", &key)); - let install_result = std::process::Command::new("makepkg") - .arg("-si") - .arg("--needed") - .status() - .expect("Couldn't call makepkg"); - match install_result.code() { - Some(0) => { - uninstall_make_depend(key); - } - Some(_) => { - err_unrec(format!("Couldn't install {}", &key)); - } - None => { - err_unrec(format!("Couldn't install {}", &key)); - } - }; - } else { - inf(format!("Package {} already up to date", &key)); - } - } - } -} diff --git a/src/mods/ver.rs b/src/mods/ver.rs deleted file mode 100644 index 251802d..0000000 --- a/src/mods/ver.rs +++ /dev/null @@ -1,27 +0,0 @@ -use crate::inf; -use ansi_term::Colour; - -pub fn ver() { - const VERSION: &str = env!("CARGO_PKG_VERSION"); - - // print version and contributors - println!(); - inf(format!("ame - {}", VERSION)); - println!(); - inf("Contributors:".to_string()); - println!("- axtlos "); - println!("- jnats "); - println!("- jasio "); - println!("- generic "); - println!(); - inf("This software is licensed under the BSD 3-Clause license.".to_string()); - inf("All source code is available at:".to_string()); - println!(); - println!( - "{}", - Colour::Purple - .bold() - .paint("https://git.getcryst.al/crystal/ame") - ); - println!(); -} diff --git a/src/mods/xargs.rs b/src/mods/xargs.rs deleted file mode 100644 index 4728659..0000000 --- a/src/mods/xargs.rs +++ /dev/null @@ -1,13 +0,0 @@ -pub fn noconf(args: &[String]) -> bool { - // noconfirm if user passed --noconfirm or added n to the end of the arg - args.contains(&"--noconfirm".to_string()) || args[0].ends_with(&"n".to_string()) -} - -pub fn argssort(args: &mut Vec) -> &Vec { - // sort the args - if args.contains(&"--noconfirm".to_string()) { - args.retain(|x| x != &"--noconfirm".to_string()); - return args; - } - args -} From 45402a21006854dbdca4023db16f30c32afd4d24 Mon Sep 17 00:00:00 2001 From: michal Date: Thu, 23 Dec 2021 18:25:24 +0000 Subject: [PATCH 02/33] restructure --- src/main.rs | 2 +- src/mods.rs | 1 - src/{mods => }/rpc.rs | 0 3 files changed, 1 insertion(+), 2 deletions(-) delete mode 100644 src/mods.rs rename src/{mods => }/rpc.rs (100%) diff --git a/src/main.rs b/src/main.rs index 3daa1de..cf733f5 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,4 +1,4 @@ -mod mods; +mod rpc; use clap::{App, Arg, SubCommand}; fn main() { diff --git a/src/mods.rs b/src/mods.rs deleted file mode 100644 index 25849ae..0000000 --- a/src/mods.rs +++ /dev/null @@ -1 +0,0 @@ -pub mod rpc; \ No newline at end of file diff --git a/src/mods/rpc.rs b/src/rpc.rs similarity index 100% rename from src/mods/rpc.rs rename to src/rpc.rs From 5b8aa7ff765a210f480503f8a51b50f2899d3bf4 Mon Sep 17 00:00:00 2001 From: michal Date: Mon, 17 Jan 2022 13:26:31 +0000 Subject: [PATCH 03/33] initial sorting algorithm --- src/internal/mod.rs | 9 +++++ src/{ => internal}/rpc.rs | 29 +++++++++++----- src/internal/sort.rs | 22 ++++++++++++ src/internal/structs.rs | 20 +++++++++++ src/main.rs | 67 ++++++++++++++++++++++++++++++------- src/operations/install.rs | 3 ++ src/operations/mod.rs | 7 ++++ src/operations/query.rs | 0 src/operations/uninstall.rs | 0 9 files changed, 136 insertions(+), 21 deletions(-) create mode 100644 src/internal/mod.rs rename src/{ => internal}/rpc.rs (59%) create mode 100644 src/internal/sort.rs create mode 100644 src/internal/structs.rs create mode 100644 src/operations/install.rs create mode 100644 src/operations/mod.rs create mode 100644 src/operations/query.rs create mode 100644 src/operations/uninstall.rs diff --git a/src/internal/mod.rs b/src/internal/mod.rs new file mode 100644 index 0000000..984ebd0 --- /dev/null +++ b/src/internal/mod.rs @@ -0,0 +1,9 @@ +pub mod rpc; +pub mod structs; +mod sort; + +pub fn sort(a: &[String]) -> structs::Sorted { + sort::sort(a) +} + + diff --git a/src/rpc.rs b/src/internal/rpc.rs similarity index 59% rename from src/rpc.rs rename to src/internal/rpc.rs index ab9ab35..9972e76 100644 --- a/src/rpc.rs +++ b/src/internal/rpc.rs @@ -22,20 +22,33 @@ pub struct SearchResults { pub results: Vec, } -pub fn rpcinfo(pkg: &str) -> Package { +pub struct InfoResults { + pub found: bool, + pub package: Option +} + +pub fn rpcinfo(pkg: String) -> InfoResults { let res = reqwest::blocking::get(&format!( "https://aur.archlinux.org/rpc/?v=5&type=info&arg={}", pkg - )).unwrap(); + )).unwrap().json::().unwrap(); - res.json::().unwrap().results[0].clone() + if res.results.is_empty() { + InfoResults { + found: false, + package: None + } + } else { + InfoResults { + found: true, + package: Some(res.results[0].clone()) + } + } } -pub fn rpcsearch(pkg: &str) -> SearchResults { - let res = reqwest::blocking::get(&format!( +pub fn rpcsearch(pkg: String) -> SearchResults { + reqwest::blocking::get(&format!( "https://aur.archlinux.org/rpc/?v=5&type=search&arg={}", pkg - )).unwrap(); - - res.json().unwrap() + )).unwrap().json().unwrap() } diff --git a/src/internal/sort.rs b/src/internal/sort.rs new file mode 100644 index 0000000..3000f7f --- /dev/null +++ b/src/internal/sort.rs @@ -0,0 +1,22 @@ +use crate::internal::{structs, rpc}; + +pub fn sort(a: &[String]) -> structs::Sorted { + #[allow(unused_mut)] + let mut repo: Vec = vec![]; + let mut aur: Vec = vec![]; + let mut nf: Vec = vec![]; + + for b in a { + if rpc::rpcinfo(b.to_string()).found { + aur.push(b.to_string()); + } else { + nf.push(b.to_string()); + } + } + + structs::Sorted::new( + repo, + aur, + nf + ) +} \ No newline at end of file diff --git a/src/internal/structs.rs b/src/internal/structs.rs new file mode 100644 index 0000000..5b2fccd --- /dev/null +++ b/src/internal/structs.rs @@ -0,0 +1,20 @@ +#[derive(Debug)] +pub struct Sorted { + #[allow(dead_code)] + repo: Vec, + #[allow(dead_code)] + aur: Vec, + #[allow(dead_code)] + nf: Vec +} + +impl Sorted { + pub fn new(repo: Vec, aur: Vec, nf: Vec) -> Self { + let a: Sorted = Sorted { + repo, + aur, + nf + }; + a + } +} \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index cf733f5..6c3dfd5 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,5 +1,8 @@ -mod rpc; +mod operations; +mod internal; + use clap::{App, Arg, SubCommand}; +use crate::internal::sort; fn main() { let matches = App::new("Amethyst") @@ -12,27 +15,65 @@ fn main() { .help("Sets the level of verbosity"), ) .subcommand( - SubCommand::with_name ("install") + SubCommand::with_name("install") .about("Installs a package from either the AUR or the PacMan-defined repositories") + .aliases(&["-S", "ins"]) + .arg( + Arg::with_name("noconfirm") + .short("y") + .long("noconfirm") + .help("Do not ask for confirmation before installing packages"), + ) + .arg( + Arg::with_name("package(s)") + .help("The name of the package(s) to install") + .required(true) + .multiple(true) + .index(1), + ), + ) + .subcommand( + SubCommand::with_name("remove") + .about("Removes a previously installed package") + .aliases(&["-R", "rm"]) .arg( Arg::with_name("noconfirm") .short("y") .long("noconfirm") - .help("Do not ask for confirmation before installing the package") + .help("Do not ask for confirmation before removing packages"), ) .arg( - Arg::with_name("package") - .help("The name of the package to install") + Arg::with_name("recursive") + .short("s") + .long("recursive") + .help("Recursively uninstall orphaned dependencies"), + ) + .arg( + Arg::with_name("package(s)") + .help("The name of the package(s) to remove") .required(true) - .index(1) - ) + .multiple(true) + .index(1), + ), ) .get_matches(); - match matches.occurrences_of("verbose") { - 0 => println!("No verbosity"), - 1 => println!("Some extra information"), - 2 => println!("Plenty of debug text"), - _ => println!("Screensaver mode"), - } + let verbosity = matches.occurrences_of("verbose"); + + let packages: Vec = matches + .subcommand_matches("install") + .unwrap() + .values_of("package(s)") + .unwrap() + .into_iter().map(|s| s.to_string()).collect(); + + if let true = matches.is_present("install") { + println!( + "Installing: {}\nVerbosity: {}\n{:?}", + packages.join(", "), + verbosity, + sort(&packages) + ); + operations::install(packages); + } } diff --git a/src/operations/install.rs b/src/operations/install.rs new file mode 100644 index 0000000..dcc1ce4 --- /dev/null +++ b/src/operations/install.rs @@ -0,0 +1,3 @@ +pub fn install(a: Vec) { + println!("{:?}", &a); +} \ No newline at end of file diff --git a/src/operations/mod.rs b/src/operations/mod.rs new file mode 100644 index 0000000..7d75b7b --- /dev/null +++ b/src/operations/mod.rs @@ -0,0 +1,7 @@ +mod install; +mod uninstall; +mod query; + +pub fn install(a: Vec) { + install::install(a); +} \ No newline at end of file diff --git a/src/operations/query.rs b/src/operations/query.rs new file mode 100644 index 0000000..e69de29 diff --git a/src/operations/uninstall.rs b/src/operations/uninstall.rs new file mode 100644 index 0000000..e69de29 From 4b2272009fc0717370a3db64a07378e24a5aa86a Mon Sep 17 00:00:00 2001 From: michal Date: Mon, 17 Jan 2022 13:56:43 +0000 Subject: [PATCH 04/33] added verbosity parsing and debug messages --- src/internal/mod.rs | 4 ++-- src/internal/sort.rs | 22 +++++++++++++++++++++- src/internal/structs.rs | 6 +++--- src/main.rs | 11 +++-------- src/operations/install.rs | 16 ++++++++++++++-- src/operations/mod.rs | 4 ++-- 6 files changed, 45 insertions(+), 18 deletions(-) diff --git a/src/internal/mod.rs b/src/internal/mod.rs index 984ebd0..4343937 100644 --- a/src/internal/mod.rs +++ b/src/internal/mod.rs @@ -2,8 +2,8 @@ pub mod rpc; pub mod structs; mod sort; -pub fn sort(a: &[String]) -> structs::Sorted { - sort::sort(a) +pub fn sort(a: &[String], verbosity: i32) -> structs::Sorted { + sort::sort(a, verbosity) } diff --git a/src/internal/sort.rs b/src/internal/sort.rs index 3000f7f..9fc69db 100644 --- a/src/internal/sort.rs +++ b/src/internal/sort.rs @@ -1,15 +1,35 @@ use crate::internal::{structs, rpc}; -pub fn sort(a: &[String]) -> structs::Sorted { +pub fn sort(a: &[String], verbosity: i32) -> structs::Sorted { #[allow(unused_mut)] let mut repo: Vec = vec![]; let mut aur: Vec = vec![]; let mut nf: Vec = vec![]; + match verbosity { + 0 => {} + 1 => { + eprintln!("Sorting:"); + eprintln!("{:?}", a); + } + _ => { + eprintln!("Sorting:"); + for b in a { + eprintln!("{:?}", b); + } + } + } + for b in a { if rpc::rpcinfo(b.to_string()).found { + if verbosity >= 1 { + eprintln!("{} found in AUR.", b); + } aur.push(b.to_string()); } else { + if verbosity >= 1 { + eprintln!("{} not found.", b); + } nf.push(b.to_string()); } } diff --git a/src/internal/structs.rs b/src/internal/structs.rs index 5b2fccd..78ff67b 100644 --- a/src/internal/structs.rs +++ b/src/internal/structs.rs @@ -1,11 +1,11 @@ #[derive(Debug)] pub struct Sorted { #[allow(dead_code)] - repo: Vec, + pub repo: Vec, #[allow(dead_code)] - aur: Vec, + pub aur: Vec, #[allow(dead_code)] - nf: Vec + pub nf: Vec } impl Sorted { diff --git a/src/main.rs b/src/main.rs index 6c3dfd5..2b5b539 100644 --- a/src/main.rs +++ b/src/main.rs @@ -58,7 +58,7 @@ fn main() { ) .get_matches(); - let verbosity = matches.occurrences_of("verbose"); + let verbosity: i32 = matches.occurrences_of("verbose") as i32; let packages: Vec = matches .subcommand_matches("install") @@ -68,12 +68,7 @@ fn main() { .into_iter().map(|s| s.to_string()).collect(); if let true = matches.is_present("install") { - println!( - "Installing: {}\nVerbosity: {}\n{:?}", - packages.join(", "), - verbosity, - sort(&packages) - ); - operations::install(packages); + let sorted = sort(&packages, verbosity); + operations::install(sorted.repo, verbosity); } } diff --git a/src/operations/install.rs b/src/operations/install.rs index dcc1ce4..b69dd38 100644 --- a/src/operations/install.rs +++ b/src/operations/install.rs @@ -1,3 +1,15 @@ -pub fn install(a: Vec) { - println!("{:?}", &a); +pub fn install(a: Vec, verbosity: i32) { + match verbosity { + 0 => {}, + 1 => { + eprintln!("Installing from repos:"); + eprintln!("{:?}", &a); + } + _ => { + eprintln!("Installing from repos:"); + for b in a { + eprintln!("{:?}", b); + } + } + } } \ No newline at end of file diff --git a/src/operations/mod.rs b/src/operations/mod.rs index 7d75b7b..89dda79 100644 --- a/src/operations/mod.rs +++ b/src/operations/mod.rs @@ -2,6 +2,6 @@ mod install; mod uninstall; mod query; -pub fn install(a: Vec) { - install::install(a); +pub fn install(a: Vec, verbosity: i32) { + install::install(a, verbosity); } \ No newline at end of file From 880c65f73ff294cc8b152d71077a3ded7488dee2 Mon Sep 17 00:00:00 2001 From: michal Date: Mon, 17 Jan 2022 14:08:01 +0000 Subject: [PATCH 05/33] edited gitignore --- .gitignore | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index 0c99807..502c7fe 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,6 @@ target/ Cargo.lock ame +ame.exe .vscode -aur_pkgs.db -test.sql +.idea From 13009935f675aac7a9485dcad9393a9a70e4cdca Mon Sep 17 00:00:00 2001 From: michal Date: Mon, 17 Jan 2022 17:06:49 +0000 Subject: [PATCH 06/33] testing initial repo package sorting --- src/internal/sort.rs | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/src/internal/sort.rs b/src/internal/sort.rs index 9fc69db..3adf350 100644 --- a/src/internal/sort.rs +++ b/src/internal/sort.rs @@ -1,4 +1,5 @@ -use crate::internal::{structs, rpc}; +use crate::internal::{rpc, structs}; +use std::process::{Command, Stdio}; pub fn sort(a: &[String], verbosity: i32) -> structs::Sorted { #[allow(unused_mut)] @@ -21,6 +22,16 @@ pub fn sort(a: &[String], verbosity: i32) -> structs::Sorted { } for b in a { + let out = Command::new("pacman") + .arg("-Ss") + .arg(format!("^{}$", &b)) + .stdout(Stdio::null()) + .status() + .expect("Something has gone wrong."); + if let Some(0) = out.code() { + repo.push(b.to_string()); + } + if rpc::rpcinfo(b.to_string()).found { if verbosity >= 1 { eprintln!("{} found in AUR.", b); @@ -34,9 +45,5 @@ pub fn sort(a: &[String], verbosity: i32) -> structs::Sorted { } } - structs::Sorted::new( - repo, - aur, - nf - ) -} \ No newline at end of file + structs::Sorted::new(repo, aur, nf) +} From 046aac029b799856ecf7937410def5bbc2b1b551 Mon Sep 17 00:00:00 2001 From: michal Date: Mon, 17 Jan 2022 17:46:33 +0000 Subject: [PATCH 07/33] fmt and set clap ver --- Cargo.toml | 2 +- src/main.rs | 8 +++++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 0514545..79508e1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,6 +8,6 @@ description = "A fast and efficient aur helper." # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -clap = "*" +clap = "2.34.0" reqwest = { version = "0.11.7", default-features = false, features = [ "blocking", "json", "default-tls" ] } serde = { version = "1.0.90", default-features = false, features = [ "derive" ] } \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index 2b5b539..0b9edb9 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,8 +1,8 @@ -mod operations; mod internal; +mod operations; -use clap::{App, Arg, SubCommand}; use crate::internal::sort; +use clap::{App, Arg, SubCommand}; fn main() { let matches = App::new("Amethyst") @@ -65,7 +65,9 @@ fn main() { .unwrap() .values_of("package(s)") .unwrap() - .into_iter().map(|s| s.to_string()).collect(); + .into_iter() + .map(|s| s.to_string()) + .collect(); if let true = matches.is_present("install") { let sorted = sort(&packages, verbosity); From e7e107bd466b01d24b016bb421d9039501580528 Mon Sep 17 00:00:00 2001 From: michal Date: Mon, 17 Jan 2022 18:00:30 +0000 Subject: [PATCH 08/33] fixed up the repo debug code --- src/internal/sort.rs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/internal/sort.rs b/src/internal/sort.rs index 3adf350..3930f0c 100644 --- a/src/internal/sort.rs +++ b/src/internal/sort.rs @@ -22,21 +22,23 @@ pub fn sort(a: &[String], verbosity: i32) -> structs::Sorted { } for b in a { - let out = Command::new("pacman") + let rs = Command::new("pacman") .arg("-Ss") .arg(format!("^{}$", &b)) .stdout(Stdio::null()) .status() .expect("Something has gone wrong."); - if let Some(0) = out.code() { - repo.push(b.to_string()); - } if rpc::rpcinfo(b.to_string()).found { if verbosity >= 1 { eprintln!("{} found in AUR.", b); } aur.push(b.to_string()); + } else if let Some(0) = rs.code() { + if verbosity >= 1 { + eprintln!("{} found in repos.", b) + } + repo.push(b.to_string()); } else { if verbosity >= 1 { eprintln!("{} not found.", b); From 0e7e086f55006f002d2f964d9fe8f90901814d48 Mon Sep 17 00:00:00 2001 From: michal Date: Mon, 17 Jan 2022 18:57:20 +0000 Subject: [PATCH 09/33] added proper cleaning to the sort process + a workaround for me on windows --- Cargo.toml | 1 + src/internal/clean.rs | 22 ++++++++++++++++++++++ src/internal/mod.rs | 7 +++++-- src/internal/sort.rs | 19 ++++++++++++++++--- 4 files changed, 44 insertions(+), 5 deletions(-) create mode 100644 src/internal/clean.rs diff --git a/Cargo.toml b/Cargo.toml index 79508e1..84e6926 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,5 +9,6 @@ description = "A fast and efficient aur helper." [dependencies] clap = "2.34.0" +regex = "1.5.4" reqwest = { version = "0.11.7", default-features = false, features = [ "blocking", "json", "default-tls" ] } serde = { version = "1.0.90", default-features = false, features = [ "derive" ] } \ No newline at end of file diff --git a/src/internal/clean.rs b/src/internal/clean.rs new file mode 100644 index 0000000..46ffe23 --- /dev/null +++ b/src/internal/clean.rs @@ -0,0 +1,22 @@ +use regex::Regex; + +pub fn clean(a: &[String], verbosity: i32) -> Vec { + let r = Regex::new(r"(\S+)((?:>=|<=|>|<|=>|=<)\S+$)").unwrap(); + + let mut cleaned: Vec = vec![]; + + for b in a { + if r.captures_iter(b).count() > 0 { + let c = r.captures(b).unwrap().get(1).map_or("", |m| m.as_str()); + cleaned.push(c.to_string()); + } else { + cleaned.push(b.to_string()); + } + } + + if verbosity >= 1 { + eprintln!("Cleaned {:?}\nInto: {:?}", a, cleaned); + } + + cleaned +} diff --git a/src/internal/mod.rs b/src/internal/mod.rs index 4343937..27f2af2 100644 --- a/src/internal/mod.rs +++ b/src/internal/mod.rs @@ -1,9 +1,12 @@ +mod clean; pub mod rpc; -pub mod structs; mod sort; +pub mod structs; pub fn sort(a: &[String], verbosity: i32) -> structs::Sorted { sort::sort(a, verbosity) } - +pub fn clean(a: &[String], verbosity: i32) -> Vec { + clean::clean(a, verbosity) +} diff --git a/src/internal/sort.rs b/src/internal/sort.rs index 3930f0c..0596360 100644 --- a/src/internal/sort.rs +++ b/src/internal/sort.rs @@ -1,12 +1,14 @@ -use crate::internal::{rpc, structs}; +use crate::internal::{clean, rpc, structs}; use std::process::{Command, Stdio}; -pub fn sort(a: &[String], verbosity: i32) -> structs::Sorted { +pub fn sort(input: &[String], verbosity: i32) -> structs::Sorted { #[allow(unused_mut)] let mut repo: Vec = vec![]; let mut aur: Vec = vec![]; let mut nf: Vec = vec![]; + let a = clean(input, verbosity); + match verbosity { 0 => {} 1 => { @@ -15,13 +17,14 @@ pub fn sort(a: &[String], verbosity: i32) -> structs::Sorted { } _ => { eprintln!("Sorting:"); - for b in a { + for b in &a { eprintln!("{:?}", b); } } } for b in a { + #[cfg(linux)] let rs = Command::new("pacman") .arg("-Ss") .arg(format!("^{}$", &b)) @@ -29,6 +32,16 @@ pub fn sort(a: &[String], verbosity: i32) -> structs::Sorted { .status() .expect("Something has gone wrong."); + #[cfg(windows)] + let rs = Command::new("pwsh") + .arg("-nop") + .arg("-c") + .arg("exit") + .arg("1") + .stdout(Stdio::null()) + .status() + .expect("Something has gone wrong."); + if rpc::rpcinfo(b.to_string()).found { if verbosity >= 1 { eprintln!("{} found in AUR.", b); From 45fd45433b96edd2bdf820ed5fcca0c2ba18644c Mon Sep 17 00:00:00 2001 From: michal Date: Mon, 17 Jan 2022 19:03:13 +0000 Subject: [PATCH 10/33] stfu clippy --- src/internal/sort.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/internal/sort.rs b/src/internal/sort.rs index 0596360..29ab902 100644 --- a/src/internal/sort.rs +++ b/src/internal/sort.rs @@ -24,7 +24,7 @@ pub fn sort(input: &[String], verbosity: i32) -> structs::Sorted { } for b in a { - #[cfg(linux)] + #[cfg(unix)] let rs = Command::new("pacman") .arg("-Ss") .arg(format!("^{}$", &b)) From 4383066b9e54df434e2a45fbaeceec3e38a6c7db Mon Sep 17 00:00:00 2001 From: michal Date: Mon, 17 Jan 2022 21:39:17 +0000 Subject: [PATCH 11/33] reworked verbosity for existing functions and tweaked regex --- src/internal/clean.rs | 19 ++++++++++++++++--- src/internal/sort.rs | 2 +- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/src/internal/clean.rs b/src/internal/clean.rs index 46ffe23..5df6056 100644 --- a/src/internal/clean.rs +++ b/src/internal/clean.rs @@ -1,7 +1,7 @@ use regex::Regex; pub fn clean(a: &[String], verbosity: i32) -> Vec { - let r = Regex::new(r"(\S+)((?:>=|<=|>|<|=>|=<)\S+$)").unwrap(); + let r = Regex::new(r"(\S+)((?:>=|<=|>|<)\S+$)").unwrap(); let mut cleaned: Vec = vec![]; @@ -14,8 +14,21 @@ pub fn clean(a: &[String], verbosity: i32) -> Vec { } } - if verbosity >= 1 { - eprintln!("Cleaned {:?}\nInto: {:?}", a, cleaned); + match verbosity { + 0 => {} + 1 => { + eprintln!("Cleaned: {:?}\nInto: {:?}", a, cleaned); + } + _ => { + eprintln!("Cleaned:"); + for b in a { + eprintln!("{}", b); + } + eprintln!("Into:"); + for c in &cleaned { + eprintln!("{}", c); + } + } } cleaned diff --git a/src/internal/sort.rs b/src/internal/sort.rs index 29ab902..4b87157 100644 --- a/src/internal/sort.rs +++ b/src/internal/sort.rs @@ -18,7 +18,7 @@ pub fn sort(input: &[String], verbosity: i32) -> structs::Sorted { _ => { eprintln!("Sorting:"); for b in &a { - eprintln!("{:?}", b); + eprintln!("{}", b); } } } From 284a0bd21caea35cc4c8b0a14306cf9c730ced9c Mon Sep 17 00:00:00 2001 From: michal Date: Mon, 17 Jan 2022 21:43:38 +0000 Subject: [PATCH 12/33] more prep code --- src/main.rs | 6 ++++++ src/operations/aur_install.rs | 15 +++++++++++++++ src/operations/mod.rs | 9 +++++++-- 3 files changed, 28 insertions(+), 2 deletions(-) create mode 100644 src/operations/aur_install.rs diff --git a/src/main.rs b/src/main.rs index 0b9edb9..9f22af5 100644 --- a/src/main.rs +++ b/src/main.rs @@ -71,6 +71,12 @@ fn main() { if let true = matches.is_present("install") { let sorted = sort(&packages, verbosity); + operations::install(sorted.repo, verbosity); + operations::aur_install(sorted.aur, verbosity); + eprintln!( + "Couldn't find packages: {} in repos or the AUR.", + sorted.nf.join(", ") + ) } } diff --git a/src/operations/aur_install.rs b/src/operations/aur_install.rs new file mode 100644 index 0000000..9389007 --- /dev/null +++ b/src/operations/aur_install.rs @@ -0,0 +1,15 @@ +pub fn aur_install(a: Vec, verbosity: i32) { + match verbosity { + 0 => {} + 1 => { + eprintln!("Installing from AUR:"); + eprintln!("{:?}", &a); + } + _ => { + eprintln!("Installing from AUR:"); + for b in a { + eprintln!("{:?}", b); + } + } + } +} diff --git a/src/operations/mod.rs b/src/operations/mod.rs index 89dda79..632a742 100644 --- a/src/operations/mod.rs +++ b/src/operations/mod.rs @@ -1,7 +1,12 @@ +mod aur_install; mod install; -mod uninstall; mod query; +mod uninstall; pub fn install(a: Vec, verbosity: i32) { install::install(a, verbosity); -} \ No newline at end of file +} + +pub fn aur_install(a: Vec, verbosity: i32) { + aur_install::aur_install(a, verbosity); +} From 62a9b40d48c3a254b0a016eba280c57a3684e20c Mon Sep 17 00:00:00 2001 From: michal Date: Tue, 18 Jan 2022 01:48:10 +0000 Subject: [PATCH 13/33] lots of stuff --- Cargo.toml | 5 +- src/internal/clean.rs | 5 +- src/internal/mod.rs | 10 +-- src/internal/sort.rs | 7 +- src/internal/structs.rs | 27 ++++++-- src/main.rs | 120 ++++++++++++++++++++++++++-------- src/operations/aur_install.rs | 5 +- src/operations/install.rs | 29 ++++++-- src/operations/mod.rs | 24 +++++-- src/operations/query.rs | 0 src/operations/search.rs | 44 +++++++++++++ src/operations/uninstall.rs | 34 ++++++++++ 12 files changed, 254 insertions(+), 56 deletions(-) delete mode 100644 src/operations/query.rs create mode 100644 src/operations/search.rs diff --git a/Cargo.toml b/Cargo.toml index 84e6926..9398ff4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,7 +2,7 @@ name = "ame" version = "3.0.0" authors = [ "jnats ", "axtlos " ] -edition = "2018" +edition = "2021" description = "A fast and efficient aur helper." # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html @@ -10,5 +10,6 @@ description = "A fast and efficient aur helper." [dependencies] clap = "2.34.0" regex = "1.5.4" +runas = "0.2.1" reqwest = { version = "0.11.7", default-features = false, features = [ "blocking", "json", "default-tls" ] } -serde = { version = "1.0.90", default-features = false, features = [ "derive" ] } \ No newline at end of file +serde = { version = "1.0.90", default-features = false, features = [ "derive", "serde_derive" ] } \ No newline at end of file diff --git a/src/internal/clean.rs b/src/internal/clean.rs index 5df6056..a6bf46a 100644 --- a/src/internal/clean.rs +++ b/src/internal/clean.rs @@ -1,9 +1,10 @@ +use crate::Options; use regex::Regex; -pub fn clean(a: &[String], verbosity: i32) -> Vec { +pub fn clean(a: &[String], options: Options) -> Vec { let r = Regex::new(r"(\S+)((?:>=|<=|>|<)\S+$)").unwrap(); - let mut cleaned: Vec = vec![]; + let verbosity = options.verbosity; for b in a { if r.captures_iter(b).count() > 0 { diff --git a/src/internal/mod.rs b/src/internal/mod.rs index 27f2af2..641289b 100644 --- a/src/internal/mod.rs +++ b/src/internal/mod.rs @@ -1,12 +1,14 @@ +use crate::Options; + mod clean; pub mod rpc; mod sort; pub mod structs; -pub fn sort(a: &[String], verbosity: i32) -> structs::Sorted { - sort::sort(a, verbosity) +pub fn sort(a: &[String], options: Options) -> structs::Sorted { + sort::sort(a, options) } -pub fn clean(a: &[String], verbosity: i32) -> Vec { - clean::clean(a, verbosity) +pub fn clean(a: &[String], options: Options) -> Vec { + clean::clean(a, options) } diff --git a/src/internal/sort.rs b/src/internal/sort.rs index 4b87157..d8050d8 100644 --- a/src/internal/sort.rs +++ b/src/internal/sort.rs @@ -1,13 +1,14 @@ use crate::internal::{clean, rpc, structs}; +use crate::Options; use std::process::{Command, Stdio}; -pub fn sort(input: &[String], verbosity: i32) -> structs::Sorted { - #[allow(unused_mut)] +pub fn sort(input: &[String], options: Options) -> structs::Sorted { let mut repo: Vec = vec![]; let mut aur: Vec = vec![]; let mut nf: Vec = vec![]; + let verbosity = options.verbosity; - let a = clean(input, verbosity); + let a = clean(input, options); match verbosity { 0 => {} diff --git a/src/internal/structs.rs b/src/internal/structs.rs index 78ff67b..39c2a3e 100644 --- a/src/internal/structs.rs +++ b/src/internal/structs.rs @@ -1,20 +1,33 @@ -#[derive(Debug)] +#[derive(Debug, serde::Serialize)] pub struct Sorted { #[allow(dead_code)] pub repo: Vec, #[allow(dead_code)] pub aur: Vec, #[allow(dead_code)] - pub nf: Vec + pub nf: Vec, } impl Sorted { pub fn new(repo: Vec, aur: Vec, nf: Vec) -> Self { - let a: Sorted = Sorted { - repo, - aur, - nf + let a: Sorted = Sorted { repo, aur, nf }; + a + } +} + +#[derive(Clone, Copy)] +pub struct Options { + pub verbosity: i32, + pub noconfirm: bool, +} + +impl Options { + #[allow(dead_code)] + pub fn new(verbosity: i32, noconfirm: bool) -> Self { + let a: Options = Options { + verbosity, + noconfirm, }; a } -} \ No newline at end of file +} diff --git a/src/main.rs b/src/main.rs index 9f22af5..41484dd 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,8 +1,9 @@ mod internal; mod operations; -use crate::internal::sort; -use clap::{App, Arg, SubCommand}; +use crate::internal::{sort, structs::Options}; +use clap::{App, AppSettings, Arg, ArgSettings, SubCommand}; +use std::process::exit; fn main() { let matches = App::new("Amethyst") @@ -11,19 +12,21 @@ fn main() { .arg( Arg::with_name("verbose") .short("v") + .long("verbose") .multiple(true) + .set(ArgSettings::Global) .help("Sets the level of verbosity"), ) + .arg( + Arg::with_name("noconfirm") + .long("noconfirm") + .set(ArgSettings::Global) + .help("Complete operation without prompting user"), + ) .subcommand( SubCommand::with_name("install") .about("Installs a package from either the AUR or the PacMan-defined repositories") .aliases(&["-S", "ins"]) - .arg( - Arg::with_name("noconfirm") - .short("y") - .long("noconfirm") - .help("Do not ask for confirmation before installing packages"), - ) .arg( Arg::with_name("package(s)") .help("The name of the package(s) to install") @@ -35,33 +38,57 @@ fn main() { .subcommand( SubCommand::with_name("remove") .about("Removes a previously installed package") - .aliases(&["-R", "rm"]) + .aliases(&["-R", "-Rs", "rm"]) + .arg( + Arg::with_name("package(s)") + .help("The name of the package(s) to remove") + .required(true) + .multiple(true) + .index(1), + ), + ) + .subcommand( + SubCommand::with_name("search") + .about("Searches for the relevant packages in both the AUR and repos.") + .aliases(&["-Ss", "sea"]) .arg( - Arg::with_name("noconfirm") - .short("y") - .long("noconfirm") - .help("Do not ask for confirmation before removing packages"), + Arg::with_name("aur") + .short("a") + .long("aur") + .help("Search only the AUR for the package"), ) .arg( - Arg::with_name("recursive") - .short("s") - .long("recursive") - .help("Recursively uninstall orphaned dependencies"), + Arg::with_name("repo") + .short("r") + .long("repo") + .help("Searches only local repos for the package"), ) .arg( Arg::with_name("package(s)") - .help("The name of the package(s) to remove") + .help("The name of the package to search for") .required(true) - .multiple(true) + .multiple(false) .index(1), ), ) + .settings(&[ + AppSettings::GlobalVersion, + AppSettings::VersionlessSubcommands, + AppSettings::ArgRequiredElseHelp, + ]) .get_matches(); let verbosity: i32 = matches.occurrences_of("verbose") as i32; + let noconfirm: bool = matches.is_present("noconfirm"); + + let options = Options { + verbosity, + noconfirm, + }; let packages: Vec = matches - .subcommand_matches("install") + .subcommand() + .1 .unwrap() .values_of("package(s)") .unwrap() @@ -70,13 +97,52 @@ fn main() { .collect(); if let true = matches.is_present("install") { - let sorted = sort(&packages, verbosity); + let sorted = sort(&packages, options); - operations::install(sorted.repo, verbosity); - operations::aur_install(sorted.aur, verbosity); - eprintln!( - "Couldn't find packages: {} in repos or the AUR.", - sorted.nf.join(", ") - ) + operations::install(sorted.repo, options); + operations::aur_install(sorted.aur, options); + if !sorted.nf.is_empty() { + eprintln!( + "Couldn't find packages: {} in repos or the AUR.", + sorted.nf.join(", ") + ); + } + exit(0); + } + + if let true = matches.is_present("remove") { + operations::uninstall(packages, options); + exit(0); + } + + if let true = matches.is_present("search") { + if matches + .subcommand_matches("search") + .unwrap() + .is_present("aur") + { + operations::aur_search(&packages[0], options); + } + if matches + .subcommand_matches("search") + .unwrap() + .is_present("repo") + { + operations::search(&packages[0], options); + } + + if !matches + .subcommand_matches("search") + .unwrap() + .is_present("repo") + && !matches + .subcommand_matches("search") + .unwrap() + .is_present("aur") + { + operations::search(&packages[0], options); + operations::aur_search(&packages[0], options); + } + exit(0); } } diff --git a/src/operations/aur_install.rs b/src/operations/aur_install.rs index 9389007..4f82c10 100644 --- a/src/operations/aur_install.rs +++ b/src/operations/aur_install.rs @@ -1,4 +1,7 @@ -pub fn aur_install(a: Vec, verbosity: i32) { +use crate::Options; + +pub fn aur_install(a: Vec, options: Options) { + let verbosity = options.verbosity; match verbosity { 0 => {} 1 => { diff --git a/src/operations/install.rs b/src/operations/install.rs index b69dd38..115b8a3 100644 --- a/src/operations/install.rs +++ b/src/operations/install.rs @@ -1,15 +1,34 @@ -pub fn install(a: Vec, verbosity: i32) { +use crate::Options; + +pub fn install(mut a: Vec, options: Options) { + let b = a.clone(); + if options.noconfirm { + a.push("--noconfirm".to_string()); + } + let verbosity = options.verbosity; match verbosity { - 0 => {}, + 0 => {} 1 => { eprintln!("Installing from repos:"); - eprintln!("{:?}", &a); + eprintln!("{:?}", &b); } _ => { eprintln!("Installing from repos:"); - for b in a { + for b in &a { eprintln!("{:?}", b); } } } -} \ No newline at end of file + + let r = runas::Command::new("pacman") + .arg("-S") + .args(&a) + .status() + .expect("Something has gone wrong."); + + if let Some(x) = r.code() { + if verbosity >= 1 { + eprintln!("Installing packages: {:?} exited with code {}.", &b, x) + } + } +} diff --git a/src/operations/mod.rs b/src/operations/mod.rs index 632a742..7021e82 100644 --- a/src/operations/mod.rs +++ b/src/operations/mod.rs @@ -1,12 +1,26 @@ +use crate::Options; + mod aur_install; mod install; -mod query; +mod search; mod uninstall; -pub fn install(a: Vec, verbosity: i32) { - install::install(a, verbosity); +pub fn install(a: Vec, options: Options) { + install::install(a, options); +} + +pub fn uninstall(a: Vec, options: Options) { + uninstall::uninstall(a, options); +} + +pub fn search(a: &str, options: Options) { + search::repo_search(a, options); +} + +pub fn aur_install(a: Vec, options: Options) { + aur_install::aur_install(a, options); } -pub fn aur_install(a: Vec, verbosity: i32) { - aur_install::aur_install(a, verbosity); +pub fn aur_search(a: &str, options: Options) { + search::aur_search(a, options); } diff --git a/src/operations/query.rs b/src/operations/query.rs deleted file mode 100644 index e69de29..0000000 diff --git a/src/operations/search.rs b/src/operations/search.rs new file mode 100644 index 0000000..28d7a55 --- /dev/null +++ b/src/operations/search.rs @@ -0,0 +1,44 @@ +use crate::internal::rpc::rpcsearch; +use crate::Options; +use std::process::Command; + +pub fn aur_search(a: &str, options: Options) { + let verbosity = options.verbosity; + let res = rpcsearch(a.to_string()); + + if verbosity >= 1 { + eprintln!("Found {} results for \"{}\" in AUR.", res.resultcount, a); + } + + for r in &res.results { + println!( + "aur/{} {}\n {}", + r.name, + r.version, + r.description + .as_ref() + .unwrap_or(&"No description.".to_string()) + ) + } +} + +pub fn repo_search(a: &str, options: Options) { + let verbosity = options.verbosity; + let rs = Command::new("pacman") + .arg("-Ss") + .arg(format!("^{}$", &a)) + .output() + .expect("Something has gone wrong."); + + let str = String::from_utf8(rs.stdout).unwrap(); + + if verbosity >= 1 { + eprintln!( + "Found {} results for \"{}\" in repos.", + &str.split('\n').count() / 2, + &a + ); + } + + print!("{}", str); +} diff --git a/src/operations/uninstall.rs b/src/operations/uninstall.rs index e69de29..7fa4864 100644 --- a/src/operations/uninstall.rs +++ b/src/operations/uninstall.rs @@ -0,0 +1,34 @@ +use crate::Options; + +pub fn uninstall(mut a: Vec, options: Options) { + let b = a.clone(); + if options.noconfirm { + a.push("--noconfirm".to_string()); + } + let verbosity = options.verbosity; + match verbosity { + 0 => {} + 1 => { + eprintln!("Uninstalling:"); + eprintln!("{:?}", &b); + } + _ => { + eprintln!("Uninstalling:"); + for b in &a { + eprintln!("{}", b); + } + } + } + + let r = runas::Command::new("pacman") + .arg("-Rs") + .args(&a) + .status() + .expect("Something has gone wrong."); + + if let Some(x) = r.code() { + if verbosity >= 1 { + eprintln!("Uninstalling packages: {:?} exited with code {}.", &b, x) + } + } +} From e9247e15e7e26c198725989435e9703e3870878e Mon Sep 17 00:00:00 2001 From: michal Date: Tue, 18 Jan 2022 02:15:05 +0000 Subject: [PATCH 14/33] database template code + first run dir creation --- src/database/add.rs | 5 +++++ src/database/mod.rs | 7 +++++++ src/internal/initialise.rs | 36 ++++++++++++++++++++++++++++++++++++ src/internal/mod.rs | 5 +++++ src/main.rs | 5 ++++- 5 files changed, 57 insertions(+), 1 deletion(-) create mode 100644 src/database/add.rs create mode 100644 src/database/mod.rs create mode 100644 src/internal/initialise.rs diff --git a/src/database/add.rs b/src/database/add.rs new file mode 100644 index 0000000..d813198 --- /dev/null +++ b/src/database/add.rs @@ -0,0 +1,5 @@ +use crate::Options; + +pub fn add(a: String, options: Options) { + // TODO: the actual database code lmao +} diff --git a/src/database/mod.rs b/src/database/mod.rs new file mode 100644 index 0000000..47c984b --- /dev/null +++ b/src/database/mod.rs @@ -0,0 +1,7 @@ +use crate::Options; + +mod add; + +pub fn add(a: String, options: Options) { + add::add(a, options); +} diff --git a/src/internal/initialise.rs b/src/internal/initialise.rs new file mode 100644 index 0000000..3620092 --- /dev/null +++ b/src/internal/initialise.rs @@ -0,0 +1,36 @@ +use crate::Options; +use std::env; +use std::path::Path; + +pub fn init(options: Options) { + let verbosity = options.verbosity; + let homedir = env::var("HOME").unwrap(); + + if !Path::new(&format!("{}/.local/share/ame", homedir)).exists() { + let r = std::fs::create_dir_all(format!("{}/.local/share/ame", homedir)); + match r { + Ok(_) => { + if verbosity >= 1 { + eprintln!("Created path: {}/.local/share/ame", homedir); + } + } + Err(e) => { + panic!("Couldn't create path: {}/.local/share/ame: {}", homedir, e); + } + } + } + + if !Path::new(&format!("{}/.cache/ame/", homedir)).exists() { + let r = std::fs::create_dir_all(format!("{}/.cache/ame", homedir)); + match r { + Ok(_) => { + if verbosity >= 1 { + eprintln!("Created path: {}/.cache/ame", homedir); + } + } + Err(e) => { + panic!("Couldn't create path: {}/.cache/ame: {}", homedir, e); + } + } + } +} diff --git a/src/internal/mod.rs b/src/internal/mod.rs index 641289b..ef0fcbd 100644 --- a/src/internal/mod.rs +++ b/src/internal/mod.rs @@ -1,6 +1,7 @@ use crate::Options; mod clean; +mod initialise; pub mod rpc; mod sort; pub mod structs; @@ -12,3 +13,7 @@ pub fn sort(a: &[String], options: Options) -> structs::Sorted { pub fn clean(a: &[String], options: Options) -> Vec { clean::clean(a, options) } + +pub fn init(options: Options) { + initialise::init(options); +} diff --git a/src/main.rs b/src/main.rs index 41484dd..936496d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,7 +1,8 @@ +mod database; mod internal; mod operations; -use crate::internal::{sort, structs::Options}; +use crate::internal::{init, sort, structs::Options}; use clap::{App, AppSettings, Arg, ArgSettings, SubCommand}; use std::process::exit; @@ -86,6 +87,8 @@ fn main() { noconfirm, }; + init(options); + let packages: Vec = matches .subcommand() .1 From 79340f2e6bbc7634dcf3916ff624cd99e334d990 Mon Sep 17 00:00:00 2001 From: michal Date: Tue, 18 Jan 2022 02:28:41 +0000 Subject: [PATCH 15/33] put the linter to rest --- src/database/add.rs | 2 ++ src/database/mod.rs | 1 + 2 files changed, 3 insertions(+) diff --git a/src/database/add.rs b/src/database/add.rs index d813198..f3a4676 100644 --- a/src/database/add.rs +++ b/src/database/add.rs @@ -1,5 +1,7 @@ use crate::Options; +#[allow(dead_code)] +#[allow(unused_variables)] pub fn add(a: String, options: Options) { // TODO: the actual database code lmao } diff --git a/src/database/mod.rs b/src/database/mod.rs index 47c984b..8923ff6 100644 --- a/src/database/mod.rs +++ b/src/database/mod.rs @@ -2,6 +2,7 @@ use crate::Options; mod add; +#[allow(dead_code)] pub fn add(a: String, options: Options) { add::add(a, options); } From bba02caf7d31538dfbcdd12e94e308ed76b84357 Mon Sep 17 00:00:00 2001 From: michal Date: Tue, 18 Jan 2022 18:39:10 +0000 Subject: [PATCH 16/33] everything pretty much --- Cargo.toml | 1 + README.md | 22 +++---- src/database/add.rs | 24 ++++++-- src/database/initialise.rs | 35 ++++++++++++ src/database/mod.rs | 19 ++++++- src/database/query.rs | 64 +++++++++++++++++++++ src/database/remove.rs | 28 +++++++++ src/internal/initialise.rs | 4 ++ src/internal/rpc.rs | 23 +++++--- src/internal/sort.rs | 11 ---- src/internal/structs.rs | 12 +--- src/main.rs | 19 ++++++- src/operations/aur_install.rs | 104 +++++++++++++++++++++++++++++++++- src/operations/install.rs | 4 ++ src/operations/mod.rs | 5 ++ src/operations/uninstall.rs | 17 ++++++ src/operations/upgrade.rs | 40 +++++++++++++ 17 files changed, 380 insertions(+), 52 deletions(-) create mode 100644 src/database/initialise.rs create mode 100644 src/database/query.rs create mode 100644 src/database/remove.rs create mode 100644 src/operations/upgrade.rs diff --git a/Cargo.toml b/Cargo.toml index 9398ff4..d1c1cdb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,5 +11,6 @@ description = "A fast and efficient aur helper." clap = "2.34.0" regex = "1.5.4" runas = "0.2.1" +rusqlite = "0.26.3" reqwest = { version = "0.11.7", default-features = false, features = [ "blocking", "json", "default-tls" ] } serde = { version = "1.0.90", default-features = false, features = [ "derive", "serde_derive" ] } \ No newline at end of file diff --git a/README.md b/README.md index ae91791..21cecc4 100644 --- a/README.md +++ b/README.md @@ -15,18 +15,13 @@ Made for Crystal, compatible with any Arch-based Linux distribution.

![](screenshot.png) ## Basic usage -| Action | FreeBSD pkg-style alias | Pacman-style flag(s) | -| ------ | ------ | ------ | -| Install a package | ame ins | ame -S | -| Remove a package | ame rm | ame -R | -| Remove a package with its dependencies | ame purge | ame -Rs | -| Update repository | ame upd | ame -Sy | -| Upgrade a package | ame upg | ame -Syu | -| Search for a package in general | ame sea | ame -Ss | -| Search for a package in the official arch repos | ame repsea | ame -Sr | -| Search for a package in aur | ame aursea | ame -Sa | - -You can also use any pacman flag! +| Action | FreeBSD pkg-style alias | Pacman-style flag(s) | +|----------------------|-------------------------|----------------------| +| Install a package | ame ins/install | ame -S | +| Remove a package | ame rm/remove | ame -R/-Rs | +| Upgrade a package | ame upg/upgrade | ame -Syu | +| Search for a package | ame sea | ame -Ss | + ## How to build: (Install cargo) @@ -47,5 +42,4 @@ Clean all build directories: echo "AME_UWU=YES" >> ~/.zshrc # for zsh echo "AME_UWU=YES" >> ~/.bashrc # for bash set -Ux AME_UWU YES # for fish -``` -self explanatory +``` \ No newline at end of file diff --git a/src/database/add.rs b/src/database/add.rs index f3a4676..00920db 100644 --- a/src/database/add.rs +++ b/src/database/add.rs @@ -1,7 +1,23 @@ +use crate::internal::rpc::Package; use crate::Options; +use rusqlite::Connection; +use std::env; +use std::path::Path; -#[allow(dead_code)] -#[allow(unused_variables)] -pub fn add(a: String, options: Options) { - // TODO: the actual database code lmao +pub fn add(pkg: Package, options: Options) { + let conn = Connection::open(Path::new(&format!( + "{}/.local/share/ame/db.sqlite", + env::var("HOME").unwrap() + ))) + .expect("Couldn't connect to database."); + + if options.verbosity >= 1 { + eprintln!("Adding package {} to database", pkg.name); + } + + conn.execute("INSERT OR REPLACE INTO packages (name, version, description, depends, make_depends) VALUES (?1, ?2, ?3, ?4, ?5)", + [&pkg.name, &pkg.version, &pkg.description.unwrap_or_else(|| "No description found.".parse().unwrap()), &pkg.depends.join(" "), &pkg.make_depends.join(" ")] + ).unwrap_or_else(|e| { + panic!("Failed adding package {} to the database: {}", pkg.name, e); + }); } diff --git a/src/database/initialise.rs b/src/database/initialise.rs new file mode 100644 index 0000000..73a0e79 --- /dev/null +++ b/src/database/initialise.rs @@ -0,0 +1,35 @@ +use crate::Options; +use rusqlite::Connection; +use std::env; +use std::path::Path; + +pub fn init(options: Options) { + let path = format!("{}/.local/share/ame/db.sqlite", env::var("HOME").unwrap()); + let dbpath = Path::new(&path); + let verbosity = options.verbosity; + + if verbosity >= 1 { + eprintln!("Creating database at {}", &path); + } + + let conn = + Connection::open(dbpath).expect("Couldn't create database at ~/.local/share/ame/db.sqlite"); + + if verbosity >= 1 { + eprintln!("Populating database with table") + } + + conn.execute( + "CREATE TABLE packages ( + name TEXT PRIMARY KEY NOT NULL, + version TEXT NOT NULL, + description TEXT, + depends BLOB, + make_depends BLOB + )", + [], + ) + .unwrap_or_else(|e| { + panic!("Couldn't initialise database: {}", e); + }); +} diff --git a/src/database/mod.rs b/src/database/mod.rs index 8923ff6..f37d309 100644 --- a/src/database/mod.rs +++ b/src/database/mod.rs @@ -1,8 +1,23 @@ +use crate::internal::rpc::Package; use crate::Options; mod add; +mod initialise; +mod query; +mod remove; -#[allow(dead_code)] -pub fn add(a: String, options: Options) { +pub fn add(a: Package, options: Options) { add::add(a, options); } + +pub fn remove(a: &str, options: Options) { + remove::remove(a, options); +} + +pub fn init(options: Options) { + initialise::init(options); +} + +pub fn query(a: &str, options: Options) -> Vec { + query::query(a, options) +} diff --git a/src/database/query.rs b/src/database/query.rs new file mode 100644 index 0000000..b27416a --- /dev/null +++ b/src/database/query.rs @@ -0,0 +1,64 @@ +use crate::internal::rpc::Package; +use crate::Options; +use rusqlite::Connection; +use std::env; +use std::path::Path; + +pub fn query(a: &str, options: Options) -> Vec { + let verbosity = options.verbosity; + + if verbosity >= 1 { + eprintln!("Connecting to database"); + } + + let conn = Connection::open(Path::new(&format!( + "{}/.local/share/ame/db.sqlite", + env::var("HOME").unwrap() + ))) + .expect("Couldn't connect to database."); + + if verbosity >= 1 { + eprintln!("Querying database for input") + } + + let mut rs = conn + .prepare("SELECT name, version, description, depends, make_depends FROM packages WHERE name LIKE \"?\"") + .unwrap(); + let packages_iter = rs + .query_map([a], |row| { + Ok(Package { + name: row.get(0).unwrap(), + version: row.get(1).unwrap(), + description: row.get(2).unwrap(), + depends: row + .get::(3) + .unwrap() + .split(' ') + .map(|s| s.to_string()) + .collect::>(), + make_depends: row + .get::(4) + .unwrap() + .split(' ') + .map(|s| s.to_string()) + .collect::>(), + }) + }) + .expect("Couldn't query database for packages."); + + if verbosity >= 1 { + eprintln!("Retrieved results"); + } + + let mut results: Vec = vec![]; + + for package in packages_iter { + results.push(package.unwrap()); + } + + if verbosity >= 1 { + eprintln!("Collected results") + } + + results +} diff --git a/src/database/remove.rs b/src/database/remove.rs new file mode 100644 index 0000000..44c8a00 --- /dev/null +++ b/src/database/remove.rs @@ -0,0 +1,28 @@ +use crate::Options; +use rusqlite::Connection; +use std::env; +use std::path::Path; + +pub fn remove(pkg: &str, options: Options) { + let conn = Connection::open(Path::new(&format!( + "{}/.local/share/ame/db.sqlite", + env::var("HOME").unwrap() + ))) + .expect("Couldn't connect to database."); + + let verbosity = options.verbosity; + + if verbosity >= 1 { + eprintln!("Removing package {} from database", pkg); + } + + conn.execute( + "DELETE FROM packages + WHERE EXISTS + (SELECT * + FROM packages + WHERE name = ?);", + [pkg], + ) + .expect("Couldn't delete package from database."); +} diff --git a/src/internal/initialise.rs b/src/internal/initialise.rs index 3620092..8e6d355 100644 --- a/src/internal/initialise.rs +++ b/src/internal/initialise.rs @@ -20,6 +20,10 @@ pub fn init(options: Options) { } } + if !Path::new(&format!("{}/.local/share/ame/db.sqlite", homedir)).exists() { + crate::database::init(options); + } + if !Path::new(&format!("{}/.cache/ame/", homedir)).exists() { let r = std::fs::create_dir_all(format!("{}/.cache/ame", homedir)); match r { diff --git a/src/internal/rpc.rs b/src/internal/rpc.rs index 9972e76..01e1aa9 100644 --- a/src/internal/rpc.rs +++ b/src/internal/rpc.rs @@ -8,11 +8,11 @@ pub struct Package { pub version: String, #[serde(rename = "Description")] pub description: Option, - #[serde(default)] #[serde(rename = "Depends")] - pub depends: Vec, #[serde(default)] + pub depends: Vec, #[serde(rename = "MakeDepends")] + #[serde(default)] pub make_depends: Vec, } @@ -22,26 +22,32 @@ pub struct SearchResults { pub results: Vec, } +#[derive(Clone)] pub struct InfoResults { pub found: bool, - pub package: Option + pub package: Option, } +pub const URL: &str = "https://aur.archlinux.org/"; + pub fn rpcinfo(pkg: String) -> InfoResults { let res = reqwest::blocking::get(&format!( "https://aur.archlinux.org/rpc/?v=5&type=info&arg={}", pkg - )).unwrap().json::().unwrap(); + )) + .unwrap() + .json::() + .unwrap(); if res.results.is_empty() { InfoResults { found: false, - package: None + package: None, } } else { InfoResults { found: true, - package: Some(res.results[0].clone()) + package: Some(res.results[0].clone()), } } } @@ -50,5 +56,8 @@ pub fn rpcsearch(pkg: String) -> SearchResults { reqwest::blocking::get(&format!( "https://aur.archlinux.org/rpc/?v=5&type=search&arg={}", pkg - )).unwrap().json().unwrap() + )) + .unwrap() + .json() + .unwrap() } diff --git a/src/internal/sort.rs b/src/internal/sort.rs index d8050d8..a1fb26d 100644 --- a/src/internal/sort.rs +++ b/src/internal/sort.rs @@ -25,7 +25,6 @@ pub fn sort(input: &[String], options: Options) -> structs::Sorted { } for b in a { - #[cfg(unix)] let rs = Command::new("pacman") .arg("-Ss") .arg(format!("^{}$", &b)) @@ -33,16 +32,6 @@ pub fn sort(input: &[String], options: Options) -> structs::Sorted { .status() .expect("Something has gone wrong."); - #[cfg(windows)] - let rs = Command::new("pwsh") - .arg("-nop") - .arg("-c") - .arg("exit") - .arg("1") - .stdout(Stdio::null()) - .status() - .expect("Something has gone wrong."); - if rpc::rpcinfo(b.to_string()).found { if verbosity >= 1 { eprintln!("{} found in AUR.", b); diff --git a/src/internal/structs.rs b/src/internal/structs.rs index 39c2a3e..7fd8007 100644 --- a/src/internal/structs.rs +++ b/src/internal/structs.rs @@ -19,15 +19,5 @@ impl Sorted { pub struct Options { pub verbosity: i32, pub noconfirm: bool, -} - -impl Options { - #[allow(dead_code)] - pub fn new(verbosity: i32, noconfirm: bool) -> Self { - let a: Options = Options { - verbosity, - noconfirm, - }; - a - } + pub asdeps: bool, } diff --git a/src/main.rs b/src/main.rs index 936496d..baa9e8b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -72,6 +72,11 @@ fn main() { .index(1), ), ) + .subcommand( + SubCommand::with_name("upgrade") + .about("Upgrades locally installed packages to their latest versions") + .aliases(&["-Syu", "upg"]), + ) .settings(&[ AppSettings::GlobalVersion, AppSettings::VersionlessSubcommands, @@ -85,6 +90,7 @@ fn main() { let options = Options { verbosity, noconfirm, + asdeps: false, }; init(options); @@ -102,8 +108,12 @@ fn main() { if let true = matches.is_present("install") { let sorted = sort(&packages, options); - operations::install(sorted.repo, options); - operations::aur_install(sorted.aur, options); + if !sorted.repo.is_empty() { + operations::install(sorted.repo, options); + } + if !sorted.aur.is_empty() { + operations::aur_install(sorted.aur, options); + } if !sorted.nf.is_empty() { eprintln!( "Couldn't find packages: {} in repos or the AUR.", @@ -118,6 +128,11 @@ fn main() { exit(0); } + if let true = matches.is_present("upgrade") { + operations::upgrade(options); + exit(0); + } + if let true = matches.is_present("search") { if matches .subcommand_matches("search") diff --git a/src/operations/aur_install.rs b/src/operations/aur_install.rs index 4f82c10..5ede818 100644 --- a/src/operations/aur_install.rs +++ b/src/operations/aur_install.rs @@ -1,7 +1,16 @@ +use crate::internal::rpc::rpcinfo; use crate::Options; +use std::env; +use std::env::set_current_dir; +use std::fs::remove_dir_all; +use std::path::Path; +use std::process::Command; pub fn aur_install(a: Vec, options: Options) { + let url = crate::internal::rpc::URL; + let cachedir = format!("{}/.cache/ame/", env::var("HOME").unwrap()); let verbosity = options.verbosity; + let noconfirm = options.noconfirm; match verbosity { 0 => {} 1 => { @@ -10,9 +19,102 @@ pub fn aur_install(a: Vec, options: Options) { } _ => { eprintln!("Installing from AUR:"); - for b in a { + for b in &a { eprintln!("{:?}", b); } } } + + for package in a { + let rpcres = rpcinfo(package); + + if !rpcres.found { + break; + } + + let pkg = &rpcres.package.as_ref().unwrap().name; + + if verbosity >= 1 { + eprintln!("Cloning {} into cachedir", pkg); + } + + // cloning + set_current_dir(Path::new(&cachedir)).unwrap(); + Command::new("git") + .arg("clone") + .arg(format!("{}/{}", url, pkg)) + .status() + .expect("Something has gone wrong."); + + if verbosity >= 1 { + eprintln!( + "Cloned {} into cachedir, moving on to resolving dependencies", + pkg + ); + eprintln!( + "Raw dependencies for package {} are:\n{:?}", + pkg, + rpcres.package.as_ref().unwrap().depends.join(", ") + ) + } + + // dep sorting + let sorted = crate::internal::sort(&rpcres.package.as_ref().unwrap().depends, options); + + if verbosity >= 1 { + eprintln!("Sorted depndencies for {} are:\n{:?}", pkg, &sorted) + } + + let newopts = Options { + verbosity, + noconfirm, + asdeps: true, + }; + + if !sorted.nf.is_empty() { + panic!( + "Could not find dependencies {} for package {}. Aborting", + sorted.nf.join(", "), + pkg + ); + } + + if !noconfirm { + let editor = env::var("EDITOR").unwrap_or_else(|_| "nano".parse().unwrap()); + + Command::new(editor) + .arg(format!("{}/PKGBUILD", pkg)) + .spawn() + .unwrap() + .wait() + .unwrap(); + } + + // dep installing + crate::operations::install(sorted.repo, newopts); + crate::operations::aur_install(sorted.aur, newopts); + + let mut makepkg_args = vec!["-rsic", "--needed"]; + if options.asdeps { + makepkg_args.push("--asdeps") + } + if options.noconfirm { + makepkg_args.push("--noconfirm") + } + + // package building and installing + set_current_dir(format!("{}/{}", cachedir, pkg)).unwrap(); + Command::new("makepkg") + .args(&makepkg_args) + .status() + .expect("Something has gone wrong."); + + if makepkg_args.contains(&"--asdeps") { + set_current_dir(&cachedir).unwrap(); + remove_dir_all(format!("{}/{}", cachedir, pkg)).unwrap(); + } + + // pushes package to database + crate::database::add(rpcres.package.unwrap(), options); + } } diff --git a/src/operations/install.rs b/src/operations/install.rs index 115b8a3..45796d7 100644 --- a/src/operations/install.rs +++ b/src/operations/install.rs @@ -5,6 +5,9 @@ pub fn install(mut a: Vec, options: Options) { if options.noconfirm { a.push("--noconfirm".to_string()); } + if options.asdeps { + a.push("--asdeps".to_string()); + } let verbosity = options.verbosity; match verbosity { 0 => {} @@ -22,6 +25,7 @@ pub fn install(mut a: Vec, options: Options) { let r = runas::Command::new("pacman") .arg("-S") + .arg("--needed") .args(&a) .status() .expect("Something has gone wrong."); diff --git a/src/operations/mod.rs b/src/operations/mod.rs index 7021e82..cb6f241 100644 --- a/src/operations/mod.rs +++ b/src/operations/mod.rs @@ -4,6 +4,7 @@ mod aur_install; mod install; mod search; mod uninstall; +mod upgrade; pub fn install(a: Vec, options: Options) { install::install(a, options); @@ -24,3 +25,7 @@ pub fn aur_install(a: Vec, options: Options) { pub fn aur_search(a: &str, options: Options) { search::aur_search(a, options); } + +pub fn upgrade(options: Options) { + upgrade::upgrade(options); +} diff --git a/src/operations/uninstall.rs b/src/operations/uninstall.rs index 7fa4864..f95a49e 100644 --- a/src/operations/uninstall.rs +++ b/src/operations/uninstall.rs @@ -1,4 +1,6 @@ use crate::Options; +use std::path::Path; +use std::{env, fs}; pub fn uninstall(mut a: Vec, options: Options) { let b = a.clone(); @@ -31,4 +33,19 @@ pub fn uninstall(mut a: Vec, options: Options) { eprintln!("Uninstalling packages: {:?} exited with code {}.", &b, x) } } + + for b in a { + crate::database::remove(&b, options); + if Path::new(&format!("{}/.cache/ame/{}", env::var("HOME").unwrap(), b)).exists() { + if verbosity >= 1 { + eprintln!("Old cache directory found, deleting") + } + fs::remove_dir_all(Path::new(&format!( + "{}/.cache/ame/{}", + env::var("HOME").unwrap(), + b + ))) + .unwrap(); + } + } } diff --git a/src/operations/upgrade.rs b/src/operations/upgrade.rs new file mode 100644 index 0000000..c287157 --- /dev/null +++ b/src/operations/upgrade.rs @@ -0,0 +1,40 @@ +use crate::internal::rpc::rpcinfo; +use crate::operations::aur_install::aur_install; +use crate::Options; +use runas::Command; + +pub fn upgrade(options: Options) { + let verbosity = options.verbosity; + let noconfirm = options.noconfirm; + + let mut pacman_args = vec!["-Syu"]; + if noconfirm { + pacman_args.push("--noconfirm"); + } + + if verbosity >= 1 { + eprintln!("Upgrading repo packages") + } + + Command::new("pacman") + .args(&pacman_args) + .status() + .expect("Something has gone wrong."); + + if verbosity >= 1 { + eprintln!("Upgrading AUR packages") + } + + let res = crate::database::query("\"%\"", options); + + let mut aur_upgrades = vec![]; + for r in res { + let re = r.clone(); + let ver = rpcinfo(r.name); + if ver.package.unwrap().version != r.version { + aur_upgrades.push(re.name); + } + } + + aur_install(aur_upgrades, options); +} From 4376b8efbffa1a12f84d162a67ee0fa236fb0444 Mon Sep 17 00:00:00 2001 From: michal Date: Tue, 18 Jan 2022 19:19:07 +0000 Subject: [PATCH 17/33] superuser check + infersubcommands --- src/main.rs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/main.rs b/src/main.rs index baa9e8b..56daa13 100644 --- a/src/main.rs +++ b/src/main.rs @@ -7,6 +7,14 @@ use clap::{App, AppSettings, Arg, ArgSettings, SubCommand}; use std::process::exit; fn main() { + extern "C" { + fn geteuid() -> u32; + } + + if unsafe { geteuid() } == 0 { + panic!("Running amethyst as root is disallowed as it can lead to system breakage. Instead, amethyst will prompt you when it needs superuser permissions.") + } + let matches = App::new("Amethyst") .version(env!("CARGO_PKG_VERSION")) .about(env!("CARGO_PKG_DESCRIPTION")) @@ -81,6 +89,7 @@ fn main() { AppSettings::GlobalVersion, AppSettings::VersionlessSubcommands, AppSettings::ArgRequiredElseHelp, + AppSettings::InferSubcommands, ]) .get_matches(); From f045f86f3e945ae9f6c5f0aa779b754a4135e34c Mon Sep 17 00:00:00 2001 From: michal Date: Tue, 18 Jan 2022 19:25:29 +0000 Subject: [PATCH 18/33] string consistency --- src/database/add.rs | 2 +- src/database/query.rs | 4 ++-- src/database/remove.rs | 4 ++-- src/internal/sort.rs | 8 ++++---- src/main.rs | 6 +++--- src/operations/aur_install.rs | 6 +++--- src/operations/install.rs | 2 +- src/operations/search.rs | 8 ++++---- src/operations/uninstall.rs | 4 ++-- src/operations/upgrade.rs | 2 +- 10 files changed, 23 insertions(+), 23 deletions(-) diff --git a/src/database/add.rs b/src/database/add.rs index 00920db..cfbcecd 100644 --- a/src/database/add.rs +++ b/src/database/add.rs @@ -9,7 +9,7 @@ pub fn add(pkg: Package, options: Options) { "{}/.local/share/ame/db.sqlite", env::var("HOME").unwrap() ))) - .expect("Couldn't connect to database."); + .expect("Couldn't connect to database"); if options.verbosity >= 1 { eprintln!("Adding package {} to database", pkg.name); diff --git a/src/database/query.rs b/src/database/query.rs index b27416a..b84ee6a 100644 --- a/src/database/query.rs +++ b/src/database/query.rs @@ -15,7 +15,7 @@ pub fn query(a: &str, options: Options) -> Vec { "{}/.local/share/ame/db.sqlite", env::var("HOME").unwrap() ))) - .expect("Couldn't connect to database."); + .expect("Couldn't connect to database"); if verbosity >= 1 { eprintln!("Querying database for input") @@ -44,7 +44,7 @@ pub fn query(a: &str, options: Options) -> Vec { .collect::>(), }) }) - .expect("Couldn't query database for packages."); + .expect("Couldn't query database for packages"); if verbosity >= 1 { eprintln!("Retrieved results"); diff --git a/src/database/remove.rs b/src/database/remove.rs index 44c8a00..a189e40 100644 --- a/src/database/remove.rs +++ b/src/database/remove.rs @@ -8,7 +8,7 @@ pub fn remove(pkg: &str, options: Options) { "{}/.local/share/ame/db.sqlite", env::var("HOME").unwrap() ))) - .expect("Couldn't connect to database."); + .expect("Couldn't connect to database"); let verbosity = options.verbosity; @@ -24,5 +24,5 @@ pub fn remove(pkg: &str, options: Options) { WHERE name = ?);", [pkg], ) - .expect("Couldn't delete package from database."); + .expect("Couldn't delete package from database"); } diff --git a/src/internal/sort.rs b/src/internal/sort.rs index a1fb26d..71a9966 100644 --- a/src/internal/sort.rs +++ b/src/internal/sort.rs @@ -30,21 +30,21 @@ pub fn sort(input: &[String], options: Options) -> structs::Sorted { .arg(format!("^{}$", &b)) .stdout(Stdio::null()) .status() - .expect("Something has gone wrong."); + .expect("Something has gone wrong"); if rpc::rpcinfo(b.to_string()).found { if verbosity >= 1 { - eprintln!("{} found in AUR.", b); + eprintln!("{} found in AUR", b); } aur.push(b.to_string()); } else if let Some(0) = rs.code() { if verbosity >= 1 { - eprintln!("{} found in repos.", b) + eprintln!("{} found in repos", b) } repo.push(b.to_string()); } else { if verbosity >= 1 { - eprintln!("{} not found.", b); + eprintln!("{} not found", b); } nf.push(b.to_string()); } diff --git a/src/main.rs b/src/main.rs index 56daa13..4126aa4 100644 --- a/src/main.rs +++ b/src/main.rs @@ -12,7 +12,7 @@ fn main() { } if unsafe { geteuid() } == 0 { - panic!("Running amethyst as root is disallowed as it can lead to system breakage. Instead, amethyst will prompt you when it needs superuser permissions.") + panic!("Running amethyst as root is disallowed as it can lead to system breakage. Instead, amethyst will prompt you when it needs superuser permissions") } let matches = App::new("Amethyst") @@ -58,7 +58,7 @@ fn main() { ) .subcommand( SubCommand::with_name("search") - .about("Searches for the relevant packages in both the AUR and repos.") + .about("Searches for the relevant packages in both the AUR and repos") .aliases(&["-Ss", "sea"]) .arg( Arg::with_name("aur") @@ -125,7 +125,7 @@ fn main() { } if !sorted.nf.is_empty() { eprintln!( - "Couldn't find packages: {} in repos or the AUR.", + "Couldn't find packages: {} in repos or the AUR", sorted.nf.join(", ") ); } diff --git a/src/operations/aur_install.rs b/src/operations/aur_install.rs index 5ede818..4e7ad5c 100644 --- a/src/operations/aur_install.rs +++ b/src/operations/aur_install.rs @@ -44,7 +44,7 @@ pub fn aur_install(a: Vec, options: Options) { .arg("clone") .arg(format!("{}/{}", url, pkg)) .status() - .expect("Something has gone wrong."); + .expect("Something has gone wrong"); if verbosity >= 1 { eprintln!( @@ -73,7 +73,7 @@ pub fn aur_install(a: Vec, options: Options) { if !sorted.nf.is_empty() { panic!( - "Could not find dependencies {} for package {}. Aborting", + "Could not find dependencies {} for package {}, aborting", sorted.nf.join(", "), pkg ); @@ -107,7 +107,7 @@ pub fn aur_install(a: Vec, options: Options) { Command::new("makepkg") .args(&makepkg_args) .status() - .expect("Something has gone wrong."); + .expect("Something has gone wrong"); if makepkg_args.contains(&"--asdeps") { set_current_dir(&cachedir).unwrap(); diff --git a/src/operations/install.rs b/src/operations/install.rs index 45796d7..44bff47 100644 --- a/src/operations/install.rs +++ b/src/operations/install.rs @@ -32,7 +32,7 @@ pub fn install(mut a: Vec, options: Options) { if let Some(x) = r.code() { if verbosity >= 1 { - eprintln!("Installing packages: {:?} exited with code {}.", &b, x) + eprintln!("Installing packages: {:?} exited with code {}", &b, x) } } } diff --git a/src/operations/search.rs b/src/operations/search.rs index 28d7a55..8ad115b 100644 --- a/src/operations/search.rs +++ b/src/operations/search.rs @@ -7,7 +7,7 @@ pub fn aur_search(a: &str, options: Options) { let res = rpcsearch(a.to_string()); if verbosity >= 1 { - eprintln!("Found {} results for \"{}\" in AUR.", res.resultcount, a); + eprintln!("Found {} results for \"{}\" in AUR", res.resultcount, a); } for r in &res.results { @@ -17,7 +17,7 @@ pub fn aur_search(a: &str, options: Options) { r.version, r.description .as_ref() - .unwrap_or(&"No description.".to_string()) + .unwrap_or(&"No description".to_string()) ) } } @@ -28,13 +28,13 @@ pub fn repo_search(a: &str, options: Options) { .arg("-Ss") .arg(format!("^{}$", &a)) .output() - .expect("Something has gone wrong."); + .expect("Something has gone wrong"); let str = String::from_utf8(rs.stdout).unwrap(); if verbosity >= 1 { eprintln!( - "Found {} results for \"{}\" in repos.", + "Found {} results for \"{}\" in repos", &str.split('\n').count() / 2, &a ); diff --git a/src/operations/uninstall.rs b/src/operations/uninstall.rs index f95a49e..6d6b79a 100644 --- a/src/operations/uninstall.rs +++ b/src/operations/uninstall.rs @@ -26,11 +26,11 @@ pub fn uninstall(mut a: Vec, options: Options) { .arg("-Rs") .args(&a) .status() - .expect("Something has gone wrong."); + .expect("Something has gone wrong"); if let Some(x) = r.code() { if verbosity >= 1 { - eprintln!("Uninstalling packages: {:?} exited with code {}.", &b, x) + eprintln!("Uninstalling packages: {:?} exited with code {}", &b, x) } } diff --git a/src/operations/upgrade.rs b/src/operations/upgrade.rs index c287157..f98b242 100644 --- a/src/operations/upgrade.rs +++ b/src/operations/upgrade.rs @@ -19,7 +19,7 @@ pub fn upgrade(options: Options) { Command::new("pacman") .args(&pacman_args) .status() - .expect("Something has gone wrong."); + .expect("Something has gone wrong"); if verbosity >= 1 { eprintln!("Upgrading AUR packages") From f7f3a3e866434ab9ce4d73abdb8a33a43ec77108 Mon Sep 17 00:00:00 2001 From: michal Date: Tue, 18 Jan 2022 20:37:52 +0000 Subject: [PATCH 19/33] shell completion, fixed search, cargo.toml stuff --- Cargo.toml | 13 ++- LICENSE.md | 18 ++++ src/database/query.rs | 4 +- src/main.rs | 222 +++++++++++++++++++++++++----------------- 4 files changed, 163 insertions(+), 94 deletions(-) create mode 100644 LICENSE.md diff --git a/Cargo.toml b/Cargo.toml index d1c1cdb..b9feb28 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,16 +1,19 @@ [package] -name = "ame" +name = "Amethyst" version = "3.0.0" authors = [ "jnats ", "axtlos " ] edition = "2021" description = "A fast and efficient aur helper." +license-file = "LICENSE.md" -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html +[[bin]] +name = "ame" +path = "src/main.rs" [dependencies] -clap = "2.34.0" -regex = "1.5.4" +clap = { version = "2.34.0", default-features = false, features = [ "suggestions"] } +regex = { version = "1.5.4", default-features = false, features = [ "std" ] } runas = "0.2.1" -rusqlite = "0.26.3" +rusqlite = { version = "0.26.3", default-features = false } reqwest = { version = "0.11.7", default-features = false, features = [ "blocking", "json", "default-tls" ] } serde = { version = "1.0.90", default-features = false, features = [ "derive", "serde_derive" ] } \ No newline at end of file diff --git a/LICENSE.md b/LICENSE.md new file mode 100644 index 0000000..d8f1f21 --- /dev/null +++ b/LICENSE.md @@ -0,0 +1,18 @@ +The Nolicense +Revision 2.1 - Monday 15th November 2021 + +Copyright (c) 2022 Crystal Linux Team + +Everyone is permitted to freely copy and distribute this license document. +Modified redistributions are subject to the following license agreement. + +The Nolicense terms and conditions for copying, distribution and modification of software and any created assets are as follows: + +- Any unmodified redistributions in either source code or binary form must retain this copyright notice in its entirety. + +- Any and all redistributions or derivative works, whether modified or unmodified, must credit the original author(s) of the source code, and provide an easily accessible way to find the original author's source code, wherever it may be published. + +- Derivative works and modified redistributions cannot be published under the same name as the original software, nor can it be presented as an extension of or newer revision of said software, and unless explicitly permitted, the original authors name(s) shall not be used to endorse said derivative works. + +This software is provided as-is; Neither the copyright holders nor any contributors to the software are to be held liable for any damages caused by any files attached. +By modifying or redistributing the software in any way, you automatically agree to the terms of the license agreement. diff --git a/src/database/query.rs b/src/database/query.rs index b84ee6a..1cddbdc 100644 --- a/src/database/query.rs +++ b/src/database/query.rs @@ -22,10 +22,10 @@ pub fn query(a: &str, options: Options) -> Vec { } let mut rs = conn - .prepare("SELECT name, version, description, depends, make_depends FROM packages WHERE name LIKE \"?\"") + .prepare("SELECT name, version, description, depends, make_depends FROM packages WHERE name LIKE :a;") .unwrap(); let packages_iter = rs - .query_map([a], |row| { + .query_map(&[(":a", &a)], |row| { Ok(Package { name: row.get(0).unwrap(), version: row.get(1).unwrap(), diff --git a/src/main.rs b/src/main.rs index 4126aa4..bab3f5e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -3,7 +3,8 @@ mod internal; mod operations; use crate::internal::{init, sort, structs::Options}; -use clap::{App, AppSettings, Arg, ArgSettings, SubCommand}; +use clap::{App, AppSettings, Arg, ArgMatches, ArgSettings, Shell, SubCommand}; +use std::io; use std::process::exit; fn main() { @@ -15,83 +16,100 @@ fn main() { panic!("Running amethyst as root is disallowed as it can lead to system breakage. Instead, amethyst will prompt you when it needs superuser permissions") } - let matches = App::new("Amethyst") - .version(env!("CARGO_PKG_VERSION")) - .about(env!("CARGO_PKG_DESCRIPTION")) - .arg( - Arg::with_name("verbose") - .short("v") - .long("verbose") - .multiple(true) - .set(ArgSettings::Global) - .help("Sets the level of verbosity"), - ) - .arg( - Arg::with_name("noconfirm") - .long("noconfirm") - .set(ArgSettings::Global) - .help("Complete operation without prompting user"), - ) - .subcommand( - SubCommand::with_name("install") - .about("Installs a package from either the AUR or the PacMan-defined repositories") - .aliases(&["-S", "ins"]) - .arg( - Arg::with_name("package(s)") - .help("The name of the package(s) to install") - .required(true) - .multiple(true) - .index(1), - ), - ) - .subcommand( - SubCommand::with_name("remove") - .about("Removes a previously installed package") - .aliases(&["-R", "-Rs", "rm"]) - .arg( - Arg::with_name("package(s)") - .help("The name of the package(s) to remove") - .required(true) - .multiple(true) - .index(1), - ), - ) - .subcommand( - SubCommand::with_name("search") - .about("Searches for the relevant packages in both the AUR and repos") - .aliases(&["-Ss", "sea"]) - .arg( - Arg::with_name("aur") - .short("a") - .long("aur") - .help("Search only the AUR for the package"), - ) - .arg( - Arg::with_name("repo") - .short("r") - .long("repo") - .help("Searches only local repos for the package"), - ) - .arg( - Arg::with_name("package(s)") - .help("The name of the package to search for") - .required(true) - .multiple(false) - .index(1), - ), - ) - .subcommand( - SubCommand::with_name("upgrade") - .about("Upgrades locally installed packages to their latest versions") - .aliases(&["-Syu", "upg"]), - ) - .settings(&[ - AppSettings::GlobalVersion, - AppSettings::VersionlessSubcommands, - AppSettings::ArgRequiredElseHelp, - AppSettings::InferSubcommands, - ]) - .get_matches(); + fn build_app() -> App<'static, 'static> { + let app = App::new("Amethyst") + .version(env!("CARGO_PKG_VERSION")) + .about(env!("CARGO_PKG_DESCRIPTION")) + .arg( + Arg::with_name("verbose") + .short("v") + .long("verbose") + .multiple(true) + .set(ArgSettings::Global) + .help("Sets the level of verbosity"), + ) + .arg( + Arg::with_name("noconfirm") + .long("noconfirm") + .set(ArgSettings::Global) + .help("Complete operation without prompting user"), + ) + .subcommand( + SubCommand::with_name("install") + .about( + "Installs a package from either the AUR or the PacMan-defined repositories", + ) + .aliases(&["-S", "ins"]) + .arg( + Arg::with_name("package(s)") + .help("The name of the package(s) to install") + .required(true) + .multiple(true) + .index(1), + ), + ) + .subcommand( + SubCommand::with_name("remove") + .about("Removes a previously installed package") + .aliases(&["-R", "-Rs", "rm"]) + .arg( + Arg::with_name("package(s)") + .help("The name of the package(s) to remove") + .required(true) + .multiple(true) + .index(1), + ), + ) + .subcommand( + SubCommand::with_name("search") + .about("Searches for the relevant packages in both the AUR and repos") + .aliases(&["-Ss", "sea"]) + .arg( + Arg::with_name("aur") + .short("a") + .long("aur") + .help("Search only the AUR for the package"), + ) + .arg( + Arg::with_name("repo") + .short("r") + .long("repo") + .help("Searches only local repos for the package"), + ) + .arg( + Arg::with_name("package(s)") + .help("The name of the package to search for") + .required(true) + .multiple(false) + .index(1), + ), + ) + .subcommand( + SubCommand::with_name("upgrade") + .about("Upgrades locally installed packages to their latest versions") + .aliases(&["-Syu", "upg"]), + ) + .subcommand( + SubCommand::with_name("compgen") + .about("Generates shell completions for given shell (bash by default)") + .aliases(&["-G", "cg"]) + .arg( + Arg::with_name("shell") + .help("The name of the shell you want to generate completions for") + .possible_values(&["bash", "fish", "zsh", "pwsh", "elvish"]) + .required(true), + ), + ) + .settings(&[ + AppSettings::GlobalVersion, + AppSettings::VersionlessSubcommands, + AppSettings::ArgRequiredElseHelp, + AppSettings::InferSubcommands, + ]); + app + } + + let matches = build_app().get_matches(); let verbosity: i32 = matches.occurrences_of("verbose") as i32; let noconfirm: bool = matches.is_present("noconfirm"); @@ -104,17 +122,19 @@ fn main() { init(options); - let packages: Vec = matches - .subcommand() - .1 - .unwrap() - .values_of("package(s)") - .unwrap() - .into_iter() - .map(|s| s.to_string()) - .collect(); + fn collect_matches(a: &ArgMatches) -> Vec { + a.subcommand() + .1 + .unwrap() + .values_of("package(s)") + .unwrap() + .into_iter() + .map(|s| s.to_string()) + .collect() + } if let true = matches.is_present("install") { + let packages = collect_matches(&matches); let sorted = sort(&packages, options); if !sorted.repo.is_empty() { @@ -133,6 +153,7 @@ fn main() { } if let true = matches.is_present("remove") { + let packages = collect_matches(&matches); operations::uninstall(packages, options); exit(0); } @@ -143,6 +164,7 @@ fn main() { } if let true = matches.is_present("search") { + let packages = collect_matches(&matches); if matches .subcommand_matches("search") .unwrap() @@ -172,4 +194,30 @@ fn main() { } exit(0); } + if let true = &matches.is_present("compgen") { + let mut app = build_app(); + match matches + .subcommand_matches("compgen") + .unwrap() + .value_of("shell") + .unwrap() + { + "bash" => { + app.gen_completions_to("ame", Shell::Bash, &mut io::stdout()); + } + "fish" => { + app.gen_completions_to("ame", Shell::Fish, &mut io::stdout()); + } + "zsh" => { + app.gen_completions_to("ame", Shell::Zsh, &mut io::stdout()); + } + "pwsh" => { + app.gen_completions_to("ame", Shell::PowerShell, &mut io::stdout()); + } + "elvish" => { + app.gen_completions_to("ame", Shell::Elvish, &mut io::stdout()); + } + _ => {} + } + } } From 9e7df5d1b4cc420ce80649efb5483b955192c103 Mon Sep 17 00:00:00 2001 From: michal Date: Thu, 20 Jan 2022 15:32:33 +0000 Subject: [PATCH 20/33] prettifying --- Cargo.toml | 46 +++++++++++++++++++++++++++++++---- src/internal/mod.rs | 9 +++++++ src/internal/strings.rs | 10 ++++++++ src/main.rs | 15 +++++++++++- src/operations/aur_install.rs | 25 +++++++++++++++---- src/operations/install.rs | 5 ++-- src/warn.rs | 14 +++++++++++ 7 files changed, 111 insertions(+), 13 deletions(-) create mode 100644 src/internal/strings.rs create mode 100644 src/warn.rs diff --git a/Cargo.toml b/Cargo.toml index b9feb28..5213662 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,19 +1,55 @@ [package] name = "Amethyst" version = "3.0.0" -authors = [ "jnats ", "axtlos " ] +authors = [ "michal ", "axtlos " ] edition = "2021" -description = "A fast and efficient aur helper." +description = "A fast and efficient AUR helper." license-file = "LICENSE.md" [[bin]] name = "ame" path = "src/main.rs" +[features] +pkg-warner = [] + +[[bin]] +name = "apt" +path = "src/warn.rs" +required-features = [ "pkg-warner" ] + +[[bin]] +name = "apt-get" +path = "src/warn.rs" +required-features = [ "pkg-warner" ] + +[[bin]] +name = "dnf" +path = "src/warn.rs" +required-features = [ "pkg-warner" ] + +[[bin]] +name = "yum" +path = "src/warn.rs" +required-features = [ "pkg-warner" ] + +[[bin]] +name = "zypper" +path = "src/warn.rs" +required-features = [ "pkg-warner" ] + +[profile.release] +incremental = true +debug = true +lto = "fat" +codegen-units = 1 + [dependencies] -clap = { version = "2.34.0", default-features = false, features = [ "suggestions"] } -regex = { version = "1.5.4", default-features = false, features = [ "std" ] } +mimalloc = { version = "0.1.27", default-features = false } +clap = { version = "2.34.0", default-features = false, features = [ "suggestions" ] } +regex = { version = "1.5.4", default-features = false, features = [ "std", "unicode-perl" ] } runas = "0.2.1" rusqlite = { version = "0.26.3", default-features = false } reqwest = { version = "0.11.7", default-features = false, features = [ "blocking", "json", "default-tls" ] } -serde = { version = "1.0.90", default-features = false, features = [ "derive", "serde_derive" ] } \ No newline at end of file +serde = { version = "1.0.90", default-features = false, features = [ "derive", "serde_derive" ] } +throbber = { version = "0.1.4", default-features = false } \ No newline at end of file diff --git a/src/internal/mod.rs b/src/internal/mod.rs index ef0fcbd..d642b4a 100644 --- a/src/internal/mod.rs +++ b/src/internal/mod.rs @@ -4,6 +4,7 @@ mod clean; mod initialise; pub mod rpc; mod sort; +mod strings; pub mod structs; pub fn sort(a: &[String], options: Options) -> structs::Sorted { @@ -17,3 +18,11 @@ pub fn clean(a: &[String], options: Options) -> Vec { pub fn init(options: Options) { initialise::init(options); } + +pub fn info(a: String) { + strings::info(a); +} + +pub fn crash(a: String, b: i32) { + strings::crash(a, b); +} diff --git a/src/internal/strings.rs b/src/internal/strings.rs new file mode 100644 index 0000000..417dbe8 --- /dev/null +++ b/src/internal/strings.rs @@ -0,0 +1,10 @@ +use std::process::exit; + +pub fn info(a: String) { + println!("\x1b[2;22;35m❖\x1b[0m \x1b[1;37m{}\x1b[0m", a) +} + +pub fn crash(a: String, b: i32) { + println!("\x1b[2;22;31m❌\x1b[0m \x1b[1;91m{}\x1b[0m", a); + exit(b); +} diff --git a/src/main.rs b/src/main.rs index bab3f5e..b6a10ff 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,8 +1,11 @@ +#[global_allocator] +static GLOBAL: mimalloc::MiMalloc = mimalloc::MiMalloc; + mod database; mod internal; mod operations; -use crate::internal::{init, sort, structs::Options}; +use crate::internal::{info, init, sort, structs::Options}; use clap::{App, AppSettings, Arg, ArgMatches, ArgSettings, Shell, SubCommand}; use std::io; use std::process::exit; @@ -137,6 +140,11 @@ fn main() { let packages = collect_matches(&matches); let sorted = sort(&packages, options); + info(format!( + "Attempting to install packages: {}", + packages.join(", ") + )); + if !sorted.repo.is_empty() { operations::install(sorted.repo, options); } @@ -154,11 +162,13 @@ fn main() { if let true = matches.is_present("remove") { let packages = collect_matches(&matches); + info(format!("Uninstalling packages: {}", &packages.join(", "))); operations::uninstall(packages, options); exit(0); } if let true = matches.is_present("upgrade") { + info("Performing system upgrade".to_string()); operations::upgrade(options); exit(0); } @@ -170,6 +180,7 @@ fn main() { .unwrap() .is_present("aur") { + info(format!("Searching AUR for {}", &packages[0])); operations::aur_search(&packages[0], options); } if matches @@ -177,6 +188,7 @@ fn main() { .unwrap() .is_present("repo") { + info(format!("Searching repos for {}", &packages[0])); operations::search(&packages[0], options); } @@ -189,6 +201,7 @@ fn main() { .unwrap() .is_present("aur") { + info(format!("Searching AUR and repos for {}", &packages[0])); operations::search(&packages[0], options); operations::aur_search(&packages[0], options); } diff --git a/src/operations/aur_install.rs b/src/operations/aur_install.rs index 4e7ad5c..c3bc172 100644 --- a/src/operations/aur_install.rs +++ b/src/operations/aur_install.rs @@ -1,10 +1,11 @@ +use crate::internal::crash; use crate::internal::rpc::rpcinfo; -use crate::Options; +use crate::{info, Options}; use std::env; use std::env::set_current_dir; use std::fs::remove_dir_all; use std::path::Path; -use std::process::Command; +use std::process::{Command, Stdio}; pub fn aur_install(a: Vec, options: Options) { let url = crate::internal::rpc::URL; @@ -25,6 +26,8 @@ pub fn aur_install(a: Vec, options: Options) { } } + info(format!("Installing packages {} from the AUR", a.join(", "))); + for package in a { let rpcres = rpcinfo(package); @@ -38,11 +41,13 @@ pub fn aur_install(a: Vec, options: Options) { eprintln!("Cloning {} into cachedir", pkg); } - // cloning + info("Cloning package source".to_string()); + set_current_dir(Path::new(&cachedir)).unwrap(); Command::new("git") .arg("clone") .arg(format!("{}/{}", url, pkg)) + .stdout(Stdio::null()) .status() .expect("Something has gone wrong"); @@ -59,10 +64,11 @@ pub fn aur_install(a: Vec, options: Options) { } // dep sorting + info("Sorting dependencies".to_string()); let sorted = crate::internal::sort(&rpcres.package.as_ref().unwrap().depends, options); if verbosity >= 1 { - eprintln!("Sorted depndencies for {} are:\n{:?}", pkg, &sorted) + eprintln!("Sorted dependencies for {} are:\n{:?}", pkg, &sorted) } let newopts = Options { @@ -91,6 +97,7 @@ pub fn aur_install(a: Vec, options: Options) { } // dep installing + info("Moving on to install dependencies".to_string()); crate::operations::install(sorted.repo, newopts); crate::operations::aur_install(sorted.aur, newopts); @@ -103,12 +110,20 @@ pub fn aur_install(a: Vec, options: Options) { } // package building and installing + info("Building time!".to_string()); set_current_dir(format!("{}/{}", cachedir, pkg)).unwrap(); - Command::new("makepkg") + let out = Command::new("makepkg") .args(&makepkg_args) .status() .expect("Something has gone wrong"); + if out.code() != Some(0) { + crash( + format!("Error encountered while installing {}, aborting", pkg), + 1, + ); + } + if makepkg_args.contains(&"--asdeps") { set_current_dir(&cachedir).unwrap(); remove_dir_all(format!("{}/{}", cachedir, pkg)).unwrap(); diff --git a/src/operations/install.rs b/src/operations/install.rs index 44bff47..0380ddc 100644 --- a/src/operations/install.rs +++ b/src/operations/install.rs @@ -1,6 +1,7 @@ -use crate::Options; +use crate::{info, Options}; pub fn install(mut a: Vec, options: Options) { + info(format!("Installing packages {} from repos", &a.join(", "))); let b = a.clone(); if options.noconfirm { a.push("--noconfirm".to_string()); @@ -28,7 +29,7 @@ pub fn install(mut a: Vec, options: Options) { .arg("--needed") .args(&a) .status() - .expect("Something has gone wrong."); + .expect("Something has gone wrong"); if let Some(x) = r.code() { if verbosity >= 1 { diff --git a/src/warn.rs b/src/warn.rs new file mode 100644 index 0000000..db60a1d --- /dev/null +++ b/src/warn.rs @@ -0,0 +1,14 @@ +use std::env; + +fn main() { + let arg = &env::args().collect::>()[0]; + + println!( + "Sorry for the bother, we don't use \x1b[2;22;35m{}\x1b[0m on Crystal, we use \x1b[2;22;35mame\x1b[0m! Please use that instead!", + arg.split('/') + .collect::>() + .last() + .unwrap() + ); + std::process::exit(0); +} From 041f8e21b2068a16314d22aa9c164ee891be6cbb Mon Sep 17 00:00:00 2001 From: michal Date: Thu, 20 Jan 2022 17:41:28 +0000 Subject: [PATCH 21/33] replaced panic! and eprintln! with crash! and log! reworked pkg-warner slightly --- Cargo.toml | 20 +++++++++------ src/{warn.rs => bin/apt-get.rs} | 0 src/bin/apt.rs | 14 +++++++++++ src/bin/dnf.rs | 14 +++++++++++ src/bin/eopkg.rs | 14 +++++++++++ src/bin/yum.rs | 14 +++++++++++ src/bin/zypper.rs | 14 +++++++++++ src/database/add.rs | 7 +++--- src/database/initialise.rs | 9 ++++--- src/database/query.rs | 10 ++++---- src/database/remove.rs | 4 +-- src/internal/clean.rs | 18 +++----------- src/internal/initialise.rs | 15 +++++++++--- src/internal/mod.rs | 4 +++ src/internal/rpc.rs | 12 ++++----- src/internal/sort.rs | 21 +++++----------- src/internal/strings.rs | 12 +++++++++ src/main.rs | 8 +++--- src/operations/aur_install.rs | 43 +++++++++++++++------------------ src/operations/install.rs | 21 ++++++---------- src/operations/search.rs | 11 ++++++--- src/operations/uninstall.rs | 23 ++++++------------ src/operations/upgrade.rs | 6 ++--- 23 files changed, 189 insertions(+), 125 deletions(-) rename src/{warn.rs => bin/apt-get.rs} (100%) create mode 100644 src/bin/apt.rs create mode 100644 src/bin/dnf.rs create mode 100644 src/bin/eopkg.rs create mode 100644 src/bin/yum.rs create mode 100644 src/bin/zypper.rs diff --git a/Cargo.toml b/Cargo.toml index 5213662..e34d3d3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,27 +15,32 @@ pkg-warner = [] [[bin]] name = "apt" -path = "src/warn.rs" +path = "src/bin/apt.rs" required-features = [ "pkg-warner" ] [[bin]] name = "apt-get" -path = "src/warn.rs" +path = "src/bin/apt-get.rs" required-features = [ "pkg-warner" ] [[bin]] name = "dnf" -path = "src/warn.rs" +path = "src/bin/dnf.rs" +required-features = [ "pkg-warner" ] + +[[bin]] +name = "eopkg" +path = "src/bin/eopkg.rs" required-features = [ "pkg-warner" ] [[bin]] name = "yum" -path = "src/warn.rs" +path = "src/bin/yum.rs" required-features = [ "pkg-warner" ] [[bin]] name = "zypper" -path = "src/warn.rs" +path = "src/bin/zypper.rs" required-features = [ "pkg-warner" ] [profile.release] @@ -50,6 +55,5 @@ clap = { version = "2.34.0", default-features = false, features = [ "suggestions regex = { version = "1.5.4", default-features = false, features = [ "std", "unicode-perl" ] } runas = "0.2.1" rusqlite = { version = "0.26.3", default-features = false } -reqwest = { version = "0.11.7", default-features = false, features = [ "blocking", "json", "default-tls" ] } -serde = { version = "1.0.90", default-features = false, features = [ "derive", "serde_derive" ] } -throbber = { version = "0.1.4", default-features = false } \ No newline at end of file +ureq = { version = "2.4.0", default-features = false, features = [ "native-tls", "json" ] } +serde = { version = "1.0.90", default-features = false, features = [ "derive", "serde_derive" ] } \ No newline at end of file diff --git a/src/warn.rs b/src/bin/apt-get.rs similarity index 100% rename from src/warn.rs rename to src/bin/apt-get.rs diff --git a/src/bin/apt.rs b/src/bin/apt.rs new file mode 100644 index 0000000..db60a1d --- /dev/null +++ b/src/bin/apt.rs @@ -0,0 +1,14 @@ +use std::env; + +fn main() { + let arg = &env::args().collect::>()[0]; + + println!( + "Sorry for the bother, we don't use \x1b[2;22;35m{}\x1b[0m on Crystal, we use \x1b[2;22;35mame\x1b[0m! Please use that instead!", + arg.split('/') + .collect::>() + .last() + .unwrap() + ); + std::process::exit(0); +} diff --git a/src/bin/dnf.rs b/src/bin/dnf.rs new file mode 100644 index 0000000..db60a1d --- /dev/null +++ b/src/bin/dnf.rs @@ -0,0 +1,14 @@ +use std::env; + +fn main() { + let arg = &env::args().collect::>()[0]; + + println!( + "Sorry for the bother, we don't use \x1b[2;22;35m{}\x1b[0m on Crystal, we use \x1b[2;22;35mame\x1b[0m! Please use that instead!", + arg.split('/') + .collect::>() + .last() + .unwrap() + ); + std::process::exit(0); +} diff --git a/src/bin/eopkg.rs b/src/bin/eopkg.rs new file mode 100644 index 0000000..db60a1d --- /dev/null +++ b/src/bin/eopkg.rs @@ -0,0 +1,14 @@ +use std::env; + +fn main() { + let arg = &env::args().collect::>()[0]; + + println!( + "Sorry for the bother, we don't use \x1b[2;22;35m{}\x1b[0m on Crystal, we use \x1b[2;22;35mame\x1b[0m! Please use that instead!", + arg.split('/') + .collect::>() + .last() + .unwrap() + ); + std::process::exit(0); +} diff --git a/src/bin/yum.rs b/src/bin/yum.rs new file mode 100644 index 0000000..db60a1d --- /dev/null +++ b/src/bin/yum.rs @@ -0,0 +1,14 @@ +use std::env; + +fn main() { + let arg = &env::args().collect::>()[0]; + + println!( + "Sorry for the bother, we don't use \x1b[2;22;35m{}\x1b[0m on Crystal, we use \x1b[2;22;35mame\x1b[0m! Please use that instead!", + arg.split('/') + .collect::>() + .last() + .unwrap() + ); + std::process::exit(0); +} diff --git a/src/bin/zypper.rs b/src/bin/zypper.rs new file mode 100644 index 0000000..db60a1d --- /dev/null +++ b/src/bin/zypper.rs @@ -0,0 +1,14 @@ +use std::env; + +fn main() { + let arg = &env::args().collect::>()[0]; + + println!( + "Sorry for the bother, we don't use \x1b[2;22;35m{}\x1b[0m on Crystal, we use \x1b[2;22;35mame\x1b[0m! Please use that instead!", + arg.split('/') + .collect::>() + .last() + .unwrap() + ); + std::process::exit(0); +} diff --git a/src/database/add.rs b/src/database/add.rs index cfbcecd..8b1497d 100644 --- a/src/database/add.rs +++ b/src/database/add.rs @@ -1,5 +1,5 @@ use crate::internal::rpc::Package; -use crate::Options; +use crate::{crash, log, Options}; use rusqlite::Connection; use std::env; use std::path::Path; @@ -12,12 +12,13 @@ pub fn add(pkg: Package, options: Options) { .expect("Couldn't connect to database"); if options.verbosity >= 1 { - eprintln!("Adding package {} to database", pkg.name); + log(format!("Adding package {} to database", pkg.name)); } conn.execute("INSERT OR REPLACE INTO packages (name, version, description, depends, make_depends) VALUES (?1, ?2, ?3, ?4, ?5)", [&pkg.name, &pkg.version, &pkg.description.unwrap_or_else(|| "No description found.".parse().unwrap()), &pkg.depends.join(" "), &pkg.make_depends.join(" ")] ).unwrap_or_else(|e| { - panic!("Failed adding package {} to the database: {}", pkg.name, e); + crash(format!("Failed adding package {} to the database: {}", pkg.name, e), 1); + 1 }); } diff --git a/src/database/initialise.rs b/src/database/initialise.rs index 73a0e79..8eac1b2 100644 --- a/src/database/initialise.rs +++ b/src/database/initialise.rs @@ -1,4 +1,4 @@ -use crate::Options; +use crate::{crash, log, Options}; use rusqlite::Connection; use std::env; use std::path::Path; @@ -9,14 +9,14 @@ pub fn init(options: Options) { let verbosity = options.verbosity; if verbosity >= 1 { - eprintln!("Creating database at {}", &path); + log(format!("Creating database at {}", &path)); } let conn = Connection::open(dbpath).expect("Couldn't create database at ~/.local/share/ame/db.sqlite"); if verbosity >= 1 { - eprintln!("Populating database with table") + log("Populating database with table".to_string()); } conn.execute( @@ -30,6 +30,7 @@ pub fn init(options: Options) { [], ) .unwrap_or_else(|e| { - panic!("Couldn't initialise database: {}", e); + crash(format!("Couldn't initialise database: {}", e), 1); + 1 }); } diff --git a/src/database/query.rs b/src/database/query.rs index 1cddbdc..a9289df 100644 --- a/src/database/query.rs +++ b/src/database/query.rs @@ -1,5 +1,5 @@ use crate::internal::rpc::Package; -use crate::Options; +use crate::{log, Options}; use rusqlite::Connection; use std::env; use std::path::Path; @@ -8,7 +8,7 @@ pub fn query(a: &str, options: Options) -> Vec { let verbosity = options.verbosity; if verbosity >= 1 { - eprintln!("Connecting to database"); + log("Connecting to database".to_string()); } let conn = Connection::open(Path::new(&format!( @@ -18,7 +18,7 @@ pub fn query(a: &str, options: Options) -> Vec { .expect("Couldn't connect to database"); if verbosity >= 1 { - eprintln!("Querying database for input") + log("Querying database for input".to_string()); } let mut rs = conn @@ -47,7 +47,7 @@ pub fn query(a: &str, options: Options) -> Vec { .expect("Couldn't query database for packages"); if verbosity >= 1 { - eprintln!("Retrieved results"); + log("Retrieved results".to_string()); } let mut results: Vec = vec![]; @@ -57,7 +57,7 @@ pub fn query(a: &str, options: Options) -> Vec { } if verbosity >= 1 { - eprintln!("Collected results") + log("Collected results".to_string()); } results diff --git a/src/database/remove.rs b/src/database/remove.rs index a189e40..bb7a5ab 100644 --- a/src/database/remove.rs +++ b/src/database/remove.rs @@ -1,4 +1,4 @@ -use crate::Options; +use crate::{log, Options}; use rusqlite::Connection; use std::env; use std::path::Path; @@ -13,7 +13,7 @@ pub fn remove(pkg: &str, options: Options) { let verbosity = options.verbosity; if verbosity >= 1 { - eprintln!("Removing package {} from database", pkg); + log(format!("Removing package {} from database", pkg)); } conn.execute( diff --git a/src/internal/clean.rs b/src/internal/clean.rs index a6bf46a..ee20893 100644 --- a/src/internal/clean.rs +++ b/src/internal/clean.rs @@ -1,3 +1,4 @@ +use crate::internal::strings::log; use crate::Options; use regex::Regex; @@ -15,21 +16,8 @@ pub fn clean(a: &[String], options: Options) -> Vec { } } - match verbosity { - 0 => {} - 1 => { - eprintln!("Cleaned: {:?}\nInto: {:?}", a, cleaned); - } - _ => { - eprintln!("Cleaned:"); - for b in a { - eprintln!("{}", b); - } - eprintln!("Into:"); - for c in &cleaned { - eprintln!("{}", c); - } - } + if verbosity >= 1 { + log(format!("Cleaned: {:?}\nInto: {:?}", a, cleaned)); } cleaned diff --git a/src/internal/initialise.rs b/src/internal/initialise.rs index 8e6d355..5e8b071 100644 --- a/src/internal/initialise.rs +++ b/src/internal/initialise.rs @@ -1,3 +1,4 @@ +use crate::internal::strings::{crash, log}; use crate::Options; use std::env; use std::path::Path; @@ -11,11 +12,14 @@ pub fn init(options: Options) { match r { Ok(_) => { if verbosity >= 1 { - eprintln!("Created path: {}/.local/share/ame", homedir); + log(format!("Created path: {}/.local/share/ame", homedir)); } } Err(e) => { - panic!("Couldn't create path: {}/.local/share/ame: {}", homedir, e); + crash( + format!("Couldn't create path: {}/.local/share/ame: {}", homedir, e), + 1, + ); } } } @@ -29,11 +33,14 @@ pub fn init(options: Options) { match r { Ok(_) => { if verbosity >= 1 { - eprintln!("Created path: {}/.cache/ame", homedir); + log(format!("Created path: {}/.cache/ame", homedir)); } } Err(e) => { - panic!("Couldn't create path: {}/.cache/ame: {}", homedir, e); + crash( + format!("Couldn't create path: {}/.cache/ame: {}", homedir, e), + 1, + ); } } } diff --git a/src/internal/mod.rs b/src/internal/mod.rs index d642b4a..1965fd1 100644 --- a/src/internal/mod.rs +++ b/src/internal/mod.rs @@ -26,3 +26,7 @@ pub fn info(a: String) { pub fn crash(a: String, b: i32) { strings::crash(a, b); } + +pub fn log(a: String) { + strings::log(a); +} diff --git a/src/internal/rpc.rs b/src/internal/rpc.rs index 01e1aa9..d578113 100644 --- a/src/internal/rpc.rs +++ b/src/internal/rpc.rs @@ -1,5 +1,3 @@ -#![allow(dead_code)] - #[derive(serde::Deserialize, Debug, Clone)] pub struct Package { #[serde(rename = "Name")] @@ -31,12 +29,13 @@ pub struct InfoResults { pub const URL: &str = "https://aur.archlinux.org/"; pub fn rpcinfo(pkg: String) -> InfoResults { - let res = reqwest::blocking::get(&format!( + let res: SearchResults = ureq::get(&format!( "https://aur.archlinux.org/rpc/?v=5&type=info&arg={}", pkg )) + .call() .unwrap() - .json::() + .into_json() .unwrap(); if res.results.is_empty() { @@ -53,11 +52,12 @@ pub fn rpcinfo(pkg: String) -> InfoResults { } pub fn rpcsearch(pkg: String) -> SearchResults { - reqwest::blocking::get(&format!( + ureq::get(&format!( "https://aur.archlinux.org/rpc/?v=5&type=search&arg={}", pkg )) + .call() .unwrap() - .json() + .into_json::() .unwrap() } diff --git a/src/internal/sort.rs b/src/internal/sort.rs index 71a9966..977d5cd 100644 --- a/src/internal/sort.rs +++ b/src/internal/sort.rs @@ -1,3 +1,4 @@ +use crate::internal::strings::log; use crate::internal::{clean, rpc, structs}; use crate::Options; use std::process::{Command, Stdio}; @@ -10,18 +11,8 @@ pub fn sort(input: &[String], options: Options) -> structs::Sorted { let a = clean(input, options); - match verbosity { - 0 => {} - 1 => { - eprintln!("Sorting:"); - eprintln!("{:?}", a); - } - _ => { - eprintln!("Sorting:"); - for b in &a { - eprintln!("{}", b); - } - } + if verbosity >= 1 { + log(format!("Sorting: {:?}", a.join(" "))); } for b in a { @@ -34,17 +25,17 @@ pub fn sort(input: &[String], options: Options) -> structs::Sorted { if rpc::rpcinfo(b.to_string()).found { if verbosity >= 1 { - eprintln!("{} found in AUR", b); + log(format!("{} found in AUR", b)); } aur.push(b.to_string()); } else if let Some(0) = rs.code() { if verbosity >= 1 { - eprintln!("{} found in repos", b) + log(format!("{} found in repos", b)); } repo.push(b.to_string()); } else { if verbosity >= 1 { - eprintln!("{} not found", b); + log(format!("{} not found", b)); } nf.push(b.to_string()); } diff --git a/src/internal/strings.rs b/src/internal/strings.rs index 417dbe8..29f03e4 100644 --- a/src/internal/strings.rs +++ b/src/internal/strings.rs @@ -1,4 +1,5 @@ use std::process::exit; +use std::time::UNIX_EPOCH; pub fn info(a: String) { println!("\x1b[2;22;35m❖\x1b[0m \x1b[1;37m{}\x1b[0m", a) @@ -8,3 +9,14 @@ pub fn crash(a: String, b: i32) { println!("\x1b[2;22;31m❌\x1b[0m \x1b[1;91m{}\x1b[0m", a); exit(b); } + +pub fn log(a: String) { + eprintln!( + "{} {}", + std::time::SystemTime::now() + .duration_since(UNIX_EPOCH) + .unwrap() + .as_secs(), + a + ); +} diff --git a/src/main.rs b/src/main.rs index b6a10ff..1999d6b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -5,7 +5,7 @@ mod database; mod internal; mod operations; -use crate::internal::{info, init, sort, structs::Options}; +use crate::internal::{crash, info, init, log, sort, structs::Options}; use clap::{App, AppSettings, Arg, ArgMatches, ArgSettings, Shell, SubCommand}; use std::io; use std::process::exit; @@ -16,7 +16,7 @@ fn main() { } if unsafe { geteuid() } == 0 { - panic!("Running amethyst as root is disallowed as it can lead to system breakage. Instead, amethyst will prompt you when it needs superuser permissions") + crash("Running amethyst as root is disallowed as it can lead to system breakage. Instead, amethyst will prompt you when it needs superuser permissions".to_string(), 1); } fn build_app() -> App<'static, 'static> { @@ -152,10 +152,10 @@ fn main() { operations::aur_install(sorted.aur, options); } if !sorted.nf.is_empty() { - eprintln!( + log(format!( "Couldn't find packages: {} in repos or the AUR", sorted.nf.join(", ") - ); + )); } exit(0); } diff --git a/src/operations/aur_install.rs b/src/operations/aur_install.rs index c3bc172..a5f7b72 100644 --- a/src/operations/aur_install.rs +++ b/src/operations/aur_install.rs @@ -1,6 +1,6 @@ use crate::internal::crash; use crate::internal::rpc::rpcinfo; -use crate::{info, Options}; +use crate::{info, log, Options}; use std::env; use std::env::set_current_dir; use std::fs::remove_dir_all; @@ -12,18 +12,9 @@ pub fn aur_install(a: Vec, options: Options) { let cachedir = format!("{}/.cache/ame/", env::var("HOME").unwrap()); let verbosity = options.verbosity; let noconfirm = options.noconfirm; - match verbosity { - 0 => {} - 1 => { - eprintln!("Installing from AUR:"); - eprintln!("{:?}", &a); - } - _ => { - eprintln!("Installing from AUR:"); - for b in &a { - eprintln!("{:?}", b); - } - } + + if verbosity >= 1 { + log(format!("Installing from AUR: {:?}", &a)); } info(format!("Installing packages {} from the AUR", a.join(", "))); @@ -38,7 +29,7 @@ pub fn aur_install(a: Vec, options: Options) { let pkg = &rpcres.package.as_ref().unwrap().name; if verbosity >= 1 { - eprintln!("Cloning {} into cachedir", pkg); + log(format!("Cloning {} into cachedir", pkg)); } info("Cloning package source".to_string()); @@ -52,15 +43,15 @@ pub fn aur_install(a: Vec, options: Options) { .expect("Something has gone wrong"); if verbosity >= 1 { - eprintln!( + log(format!( "Cloned {} into cachedir, moving on to resolving dependencies", pkg - ); - eprintln!( + )); + log(format!( "Raw dependencies for package {} are:\n{:?}", pkg, rpcres.package.as_ref().unwrap().depends.join(", ") - ) + )); } // dep sorting @@ -68,7 +59,10 @@ pub fn aur_install(a: Vec, options: Options) { let sorted = crate::internal::sort(&rpcres.package.as_ref().unwrap().depends, options); if verbosity >= 1 { - eprintln!("Sorted dependencies for {} are:\n{:?}", pkg, &sorted) + log(format!( + "Sorted dependencies for {} are:\n{:?}", + pkg, &sorted + )); } let newopts = Options { @@ -78,10 +72,13 @@ pub fn aur_install(a: Vec, options: Options) { }; if !sorted.nf.is_empty() { - panic!( - "Could not find dependencies {} for package {}, aborting", - sorted.nf.join(", "), - pkg + crash( + format!( + "Could not find dependencies {} for package {}, aborting", + sorted.nf.join(", "), + pkg + ), + 1, ); } diff --git a/src/operations/install.rs b/src/operations/install.rs index 0380ddc..91c7b63 100644 --- a/src/operations/install.rs +++ b/src/operations/install.rs @@ -1,4 +1,4 @@ -use crate::{info, Options}; +use crate::{info, log, Options}; pub fn install(mut a: Vec, options: Options) { info(format!("Installing packages {} from repos", &a.join(", "))); @@ -10,18 +10,8 @@ pub fn install(mut a: Vec, options: Options) { a.push("--asdeps".to_string()); } let verbosity = options.verbosity; - match verbosity { - 0 => {} - 1 => { - eprintln!("Installing from repos:"); - eprintln!("{:?}", &b); - } - _ => { - eprintln!("Installing from repos:"); - for b in &a { - eprintln!("{:?}", b); - } - } + if verbosity >= 1 { + log(format!("Installing from repos: {:?}", &b)); } let r = runas::Command::new("pacman") @@ -33,7 +23,10 @@ pub fn install(mut a: Vec, options: Options) { if let Some(x) = r.code() { if verbosity >= 1 { - eprintln!("Installing packages: {:?} exited with code {}", &b, x) + log(format!( + "Installing packages: {:?} exited with code {}", + &b, x + )); } } } diff --git a/src/operations/search.rs b/src/operations/search.rs index 8ad115b..90027f2 100644 --- a/src/operations/search.rs +++ b/src/operations/search.rs @@ -1,5 +1,5 @@ use crate::internal::rpc::rpcsearch; -use crate::Options; +use crate::{log, Options}; use std::process::Command; pub fn aur_search(a: &str, options: Options) { @@ -7,7 +7,10 @@ pub fn aur_search(a: &str, options: Options) { let res = rpcsearch(a.to_string()); if verbosity >= 1 { - eprintln!("Found {} results for \"{}\" in AUR", res.resultcount, a); + log(format!( + "Found {} resuls for \"{}\" in AUR", + res.resultcount, a + )); } for r in &res.results { @@ -33,11 +36,11 @@ pub fn repo_search(a: &str, options: Options) { let str = String::from_utf8(rs.stdout).unwrap(); if verbosity >= 1 { - eprintln!( + log(format!( "Found {} results for \"{}\" in repos", &str.split('\n').count() / 2, &a - ); + )); } print!("{}", str); diff --git a/src/operations/uninstall.rs b/src/operations/uninstall.rs index 6d6b79a..888109f 100644 --- a/src/operations/uninstall.rs +++ b/src/operations/uninstall.rs @@ -1,4 +1,4 @@ -use crate::Options; +use crate::{log, Options}; use std::path::Path; use std::{env, fs}; @@ -8,18 +8,8 @@ pub fn uninstall(mut a: Vec, options: Options) { a.push("--noconfirm".to_string()); } let verbosity = options.verbosity; - match verbosity { - 0 => {} - 1 => { - eprintln!("Uninstalling:"); - eprintln!("{:?}", &b); - } - _ => { - eprintln!("Uninstalling:"); - for b in &a { - eprintln!("{}", b); - } - } + if verbosity >= 1 { + log(format!("Uninstalling: {:?}", &b)); } let r = runas::Command::new("pacman") @@ -30,7 +20,10 @@ pub fn uninstall(mut a: Vec, options: Options) { if let Some(x) = r.code() { if verbosity >= 1 { - eprintln!("Uninstalling packages: {:?} exited with code {}", &b, x) + log(format!( + "Uninstalling packages: {:?} exited with code {}", + &b, x + )); } } @@ -38,7 +31,7 @@ pub fn uninstall(mut a: Vec, options: Options) { crate::database::remove(&b, options); if Path::new(&format!("{}/.cache/ame/{}", env::var("HOME").unwrap(), b)).exists() { if verbosity >= 1 { - eprintln!("Old cache directory found, deleting") + log("Old cache directory found, deleting".to_string()); } fs::remove_dir_all(Path::new(&format!( "{}/.cache/ame/{}", diff --git a/src/operations/upgrade.rs b/src/operations/upgrade.rs index f98b242..b86e906 100644 --- a/src/operations/upgrade.rs +++ b/src/operations/upgrade.rs @@ -1,6 +1,6 @@ use crate::internal::rpc::rpcinfo; use crate::operations::aur_install::aur_install; -use crate::Options; +use crate::{log, Options}; use runas::Command; pub fn upgrade(options: Options) { @@ -13,7 +13,7 @@ pub fn upgrade(options: Options) { } if verbosity >= 1 { - eprintln!("Upgrading repo packages") + log("Upgrading repo packages".to_string()); } Command::new("pacman") @@ -22,7 +22,7 @@ pub fn upgrade(options: Options) { .expect("Something has gone wrong"); if verbosity >= 1 { - eprintln!("Upgrading AUR packages") + log("Upgrading AUR packages".to_string()); } let res = crate::database::query("\"%\"", options); From 6475eacbba04a57d4174818cfcef7615802b1acc Mon Sep 17 00:00:00 2001 From: michal Date: Thu, 20 Jan 2022 19:13:15 +0000 Subject: [PATCH 22/33] replaced reqwest with ureq --- Cargo.toml | 11 ++++++----- src/internal/rpc.rs | 44 ++++++++++++++++++++++++++++---------------- 2 files changed, 34 insertions(+), 21 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index e34d3d3..1678aaf 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,10 +6,6 @@ edition = "2021" description = "A fast and efficient AUR helper." license-file = "LICENSE.md" -[[bin]] -name = "ame" -path = "src/main.rs" - [features] pkg-warner = [] @@ -43,6 +39,10 @@ name = "zypper" path = "src/bin/zypper.rs" required-features = [ "pkg-warner" ] +[[bin]] +name = "ame" +path = "src/main.rs" + [profile.release] incremental = true debug = true @@ -56,4 +56,5 @@ regex = { version = "1.5.4", default-features = false, features = [ "std", "unic runas = "0.2.1" rusqlite = { version = "0.26.3", default-features = false } ureq = { version = "2.4.0", default-features = false, features = [ "native-tls", "json" ] } -serde = { version = "1.0.90", default-features = false, features = [ "derive", "serde_derive" ] } \ No newline at end of file +serde = { version = "1.0.90", default-features = false, features = [ "derive", "serde_derive" ] } +native-tls = "0.2.8" \ No newline at end of file diff --git a/src/internal/rpc.rs b/src/internal/rpc.rs index d578113..341d32a 100644 --- a/src/internal/rpc.rs +++ b/src/internal/rpc.rs @@ -1,3 +1,5 @@ +use std::sync::Arc; + #[derive(serde::Deserialize, Debug, Clone)] pub struct Package { #[serde(rename = "Name")] @@ -29,14 +31,19 @@ pub struct InfoResults { pub const URL: &str = "https://aur.archlinux.org/"; pub fn rpcinfo(pkg: String) -> InfoResults { - let res: SearchResults = ureq::get(&format!( - "https://aur.archlinux.org/rpc/?v=5&type=info&arg={}", - pkg - )) - .call() - .unwrap() - .into_json() - .unwrap(); + let tls_connector = Arc::new(native_tls::TlsConnector::new().unwrap()); + let agent = ureq::AgentBuilder::new() + .tls_connector(tls_connector) + .build(); + let res: SearchResults = agent + .get(&format!( + "https://aur.archlinux.org/rpc/?v=5&type=info&arg={}", + pkg + )) + .call() + .unwrap() + .into_json() + .unwrap(); if res.results.is_empty() { InfoResults { @@ -52,12 +59,17 @@ pub fn rpcinfo(pkg: String) -> InfoResults { } pub fn rpcsearch(pkg: String) -> SearchResults { - ureq::get(&format!( - "https://aur.archlinux.org/rpc/?v=5&type=search&arg={}", - pkg - )) - .call() - .unwrap() - .into_json::() - .unwrap() + let tls_connector = Arc::new(native_tls::TlsConnector::new().unwrap()); + let agent = ureq::AgentBuilder::new() + .tls_connector(tls_connector) + .build(); + agent + .get(&format!( + "https://aur.archlinux.org/rpc/?v=5&type=search&arg={}", + pkg + )) + .call() + .unwrap() + .into_json::() + .unwrap() } From 59b443c607f09d82d12a653dd0c7ed26ea7960ff Mon Sep 17 00:00:00 2001 From: michal Date: Thu, 20 Jan 2022 19:20:20 +0000 Subject: [PATCH 23/33] general code cleanup --- Cargo.toml | 22 +++++++++++----------- LICENSE.md | 23 ++++++++++++++--------- README.md | 14 +++++++++----- src/database/add.rs | 12 +++++++----- src/database/initialise.rs | 6 ++++-- src/database/query.rs | 8 +++++--- src/database/remove.rs | 6 ++++-- src/internal/clean.rs | 3 ++- src/internal/initialise.rs | 5 +++-- src/internal/sort.rs | 3 ++- src/main.rs | 12 +++++++----- src/operations/aur_install.rs | 7 ++++--- src/operations/search.rs | 3 ++- src/operations/uninstall.rs | 3 ++- src/operations/upgrade.rs | 3 ++- 15 files changed, 78 insertions(+), 52 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 1678aaf..0d21729 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "Amethyst" version = "3.0.0" -authors = [ "michal ", "axtlos " ] +authors = ["michal ", "axtlos "] edition = "2021" description = "A fast and efficient AUR helper." license-file = "LICENSE.md" @@ -12,32 +12,32 @@ pkg-warner = [] [[bin]] name = "apt" path = "src/bin/apt.rs" -required-features = [ "pkg-warner" ] +required-features = ["pkg-warner"] [[bin]] name = "apt-get" path = "src/bin/apt-get.rs" -required-features = [ "pkg-warner" ] +required-features = ["pkg-warner"] [[bin]] name = "dnf" path = "src/bin/dnf.rs" -required-features = [ "pkg-warner" ] +required-features = ["pkg-warner"] [[bin]] name = "eopkg" path = "src/bin/eopkg.rs" -required-features = [ "pkg-warner" ] +required-features = ["pkg-warner"] [[bin]] name = "yum" path = "src/bin/yum.rs" -required-features = [ "pkg-warner" ] +required-features = ["pkg-warner"] [[bin]] name = "zypper" path = "src/bin/zypper.rs" -required-features = [ "pkg-warner" ] +required-features = ["pkg-warner"] [[bin]] name = "ame" @@ -51,10 +51,10 @@ codegen-units = 1 [dependencies] mimalloc = { version = "0.1.27", default-features = false } -clap = { version = "2.34.0", default-features = false, features = [ "suggestions" ] } -regex = { version = "1.5.4", default-features = false, features = [ "std", "unicode-perl" ] } +clap = { version = "2.34.0", default-features = false, features = ["suggestions"] } +regex = { version = "1.5.4", default-features = false, features = ["std", "unicode-perl"] } runas = "0.2.1" rusqlite = { version = "0.26.3", default-features = false } -ureq = { version = "2.4.0", default-features = false, features = [ "native-tls", "json" ] } -serde = { version = "1.0.90", default-features = false, features = [ "derive", "serde_derive" ] } +ureq = { version = "2.4.0", default-features = false, features = ["native-tls", "json"] } +serde = { version = "1.0.90", default-features = false, features = ["derive", "serde_derive"] } native-tls = "0.2.8" \ No newline at end of file diff --git a/LICENSE.md b/LICENSE.md index d8f1f21..ba4c143 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -1,18 +1,23 @@ -The Nolicense -Revision 2.1 - Monday 15th November 2021 +The Nolicense Revision 2.1 - Monday 15th November 2021 Copyright (c) 2022 Crystal Linux Team -Everyone is permitted to freely copy and distribute this license document. -Modified redistributions are subject to the following license agreement. +Everyone is permitted to freely copy and distribute this license document. Modified redistributions are subject to the +following license agreement. -The Nolicense terms and conditions for copying, distribution and modification of software and any created assets are as follows: +The Nolicense terms and conditions for copying, distribution and modification of software and any created assets are as +follows: - Any unmodified redistributions in either source code or binary form must retain this copyright notice in its entirety. -- Any and all redistributions or derivative works, whether modified or unmodified, must credit the original author(s) of the source code, and provide an easily accessible way to find the original author's source code, wherever it may be published. +- Any and all redistributions or derivative works, whether modified or unmodified, must credit the original author(s) of + the source code, and provide an easily accessible way to find the original author's source code, wherever it may be + published. -- Derivative works and modified redistributions cannot be published under the same name as the original software, nor can it be presented as an extension of or newer revision of said software, and unless explicitly permitted, the original authors name(s) shall not be used to endorse said derivative works. +- Derivative works and modified redistributions cannot be published under the same name as the original software, nor + can it be presented as an extension of or newer revision of said software, and unless explicitly permitted, the + original authors name(s) shall not be used to endorse said derivative works. -This software is provided as-is; Neither the copyright holders nor any contributors to the software are to be held liable for any damages caused by any files attached. -By modifying or redistributing the software in any way, you automatically agree to the terms of the license agreement. +This software is provided as-is; Neither the copyright holders nor any contributors to the software are to be held +liable for any damages caused by any files attached. By modifying or redistributing the software in any way, you +automatically agree to the terms of the license agreement. diff --git a/README.md b/README.md index 21cecc4..de983e0 100644 --- a/README.md +++ b/README.md @@ -15,6 +15,7 @@ Made for Crystal, compatible with any Arch-based Linux distribution.

![](screenshot.png) ## Basic usage + | Action | FreeBSD pkg-style alias | Pacman-style flag(s) | |----------------------|-------------------------|----------------------| | Install a package | ame ins/install | ame -S | @@ -22,18 +23,21 @@ Made for Crystal, compatible with any Arch-based Linux distribution.

| Upgrade a package | ame upg/upgrade | ame -Syu | | Search for a package | ame sea | ame -Ss | - ## How to build: + (Install cargo) For release: - - `make clean release` - + +- `make clean release` + For general debug/test: - - `make debug` + +- `make debug` Clean all build directories: - - `make clean` + +- `make clean`

diff --git a/src/database/add.rs b/src/database/add.rs index 8b1497d..b6fea36 100644 --- a/src/database/add.rs +++ b/src/database/add.rs @@ -1,9 +1,11 @@ -use crate::internal::rpc::Package; -use crate::{crash, log, Options}; -use rusqlite::Connection; use std::env; use std::path::Path; +use rusqlite::Connection; + +use crate::internal::rpc::Package; +use crate::{crash, log, Options}; + pub fn add(pkg: Package, options: Options) { let conn = Connection::open(Path::new(&format!( "{}/.local/share/ame/db.sqlite", @@ -15,8 +17,8 @@ pub fn add(pkg: Package, options: Options) { log(format!("Adding package {} to database", pkg.name)); } - conn.execute("INSERT OR REPLACE INTO packages (name, version, description, depends, make_depends) VALUES (?1, ?2, ?3, ?4, ?5)", - [&pkg.name, &pkg.version, &pkg.description.unwrap_or_else(|| "No description found.".parse().unwrap()), &pkg.depends.join(" "), &pkg.make_depends.join(" ")] + conn.execute("INSERT OR REPLACE INTO packages (name, version, description, depends, make_depends) VALUES (?1, ?2, ?3, ?4, ?5)", + [&pkg.name, &pkg.version, &pkg.description.unwrap_or_else(|| "No description found.".parse().unwrap()), &pkg.depends.join(" "), &pkg.make_depends.join(" ")], ).unwrap_or_else(|e| { crash(format!("Failed adding package {} to the database: {}", pkg.name, e), 1); 1 diff --git a/src/database/initialise.rs b/src/database/initialise.rs index 8eac1b2..d4f0610 100644 --- a/src/database/initialise.rs +++ b/src/database/initialise.rs @@ -1,8 +1,10 @@ -use crate::{crash, log, Options}; -use rusqlite::Connection; use std::env; use std::path::Path; +use rusqlite::Connection; + +use crate::{crash, log, Options}; + pub fn init(options: Options) { let path = format!("{}/.local/share/ame/db.sqlite", env::var("HOME").unwrap()); let dbpath = Path::new(&path); diff --git a/src/database/query.rs b/src/database/query.rs index a9289df..89e3016 100644 --- a/src/database/query.rs +++ b/src/database/query.rs @@ -1,9 +1,11 @@ -use crate::internal::rpc::Package; -use crate::{log, Options}; -use rusqlite::Connection; use std::env; use std::path::Path; +use rusqlite::Connection; + +use crate::internal::rpc::Package; +use crate::{log, Options}; + pub fn query(a: &str, options: Options) -> Vec { let verbosity = options.verbosity; diff --git a/src/database/remove.rs b/src/database/remove.rs index bb7a5ab..c213e3b 100644 --- a/src/database/remove.rs +++ b/src/database/remove.rs @@ -1,8 +1,10 @@ -use crate::{log, Options}; -use rusqlite::Connection; use std::env; use std::path::Path; +use rusqlite::Connection; + +use crate::{log, Options}; + pub fn remove(pkg: &str, options: Options) { let conn = Connection::open(Path::new(&format!( "{}/.local/share/ame/db.sqlite", diff --git a/src/internal/clean.rs b/src/internal/clean.rs index ee20893..f6fbcc5 100644 --- a/src/internal/clean.rs +++ b/src/internal/clean.rs @@ -1,6 +1,7 @@ +use regex::Regex; + use crate::internal::strings::log; use crate::Options; -use regex::Regex; pub fn clean(a: &[String], options: Options) -> Vec { let r = Regex::new(r"(\S+)((?:>=|<=|>|<)\S+$)").unwrap(); diff --git a/src/internal/initialise.rs b/src/internal/initialise.rs index 5e8b071..bf5b004 100644 --- a/src/internal/initialise.rs +++ b/src/internal/initialise.rs @@ -1,8 +1,9 @@ -use crate::internal::strings::{crash, log}; -use crate::Options; use std::env; use std::path::Path; +use crate::internal::strings::{crash, log}; +use crate::Options; + pub fn init(options: Options) { let verbosity = options.verbosity; let homedir = env::var("HOME").unwrap(); diff --git a/src/internal/sort.rs b/src/internal/sort.rs index 977d5cd..64d6430 100644 --- a/src/internal/sort.rs +++ b/src/internal/sort.rs @@ -1,7 +1,8 @@ +use std::process::{Command, Stdio}; + use crate::internal::strings::log; use crate::internal::{clean, rpc, structs}; use crate::Options; -use std::process::{Command, Stdio}; pub fn sort(input: &[String], options: Options) -> structs::Sorted { let mut repo: Vec = vec![]; diff --git a/src/main.rs b/src/main.rs index 1999d6b..a724c27 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,3 +1,10 @@ +use std::io; +use std::process::exit; + +use clap::{App, AppSettings, Arg, ArgMatches, ArgSettings, Shell, SubCommand}; + +use crate::internal::{crash, info, init, log, sort, structs::Options}; + #[global_allocator] static GLOBAL: mimalloc::MiMalloc = mimalloc::MiMalloc; @@ -5,11 +12,6 @@ mod database; mod internal; mod operations; -use crate::internal::{crash, info, init, log, sort, structs::Options}; -use clap::{App, AppSettings, Arg, ArgMatches, ArgSettings, Shell, SubCommand}; -use std::io; -use std::process::exit; - fn main() { extern "C" { fn geteuid() -> u32; diff --git a/src/operations/aur_install.rs b/src/operations/aur_install.rs index a5f7b72..ad97ae4 100644 --- a/src/operations/aur_install.rs +++ b/src/operations/aur_install.rs @@ -1,12 +1,13 @@ -use crate::internal::crash; -use crate::internal::rpc::rpcinfo; -use crate::{info, log, Options}; use std::env; use std::env::set_current_dir; use std::fs::remove_dir_all; use std::path::Path; use std::process::{Command, Stdio}; +use crate::internal::crash; +use crate::internal::rpc::rpcinfo; +use crate::{info, log, Options}; + pub fn aur_install(a: Vec, options: Options) { let url = crate::internal::rpc::URL; let cachedir = format!("{}/.cache/ame/", env::var("HOME").unwrap()); diff --git a/src/operations/search.rs b/src/operations/search.rs index 90027f2..08d5006 100644 --- a/src/operations/search.rs +++ b/src/operations/search.rs @@ -1,6 +1,7 @@ +use std::process::Command; + use crate::internal::rpc::rpcsearch; use crate::{log, Options}; -use std::process::Command; pub fn aur_search(a: &str, options: Options) { let verbosity = options.verbosity; diff --git a/src/operations/uninstall.rs b/src/operations/uninstall.rs index 888109f..0e2ef05 100644 --- a/src/operations/uninstall.rs +++ b/src/operations/uninstall.rs @@ -1,7 +1,8 @@ -use crate::{log, Options}; use std::path::Path; use std::{env, fs}; +use crate::{log, Options}; + pub fn uninstall(mut a: Vec, options: Options) { let b = a.clone(); if options.noconfirm { diff --git a/src/operations/upgrade.rs b/src/operations/upgrade.rs index b86e906..7cbea10 100644 --- a/src/operations/upgrade.rs +++ b/src/operations/upgrade.rs @@ -1,7 +1,8 @@ +use runas::Command; + use crate::internal::rpc::rpcinfo; use crate::operations::aur_install::aur_install; use crate::{log, Options}; -use runas::Command; pub fn upgrade(options: Options) { let verbosity = options.verbosity; From de15c98432d79e7f2c98c50d49ecb5ae18e484ee Mon Sep 17 00:00:00 2001 From: michal Date: Thu, 20 Jan 2022 23:02:18 +0000 Subject: [PATCH 24/33] AME_UWU --- src/database/mod.rs | 4 +-- src/database/query.rs | 8 ++---- src/internal/mod.rs | 21 ++++++++++++++ src/internal/strings.rs | 53 +++++++++++++++++++++++++++++++++++ src/operations/aur_install.rs | 26 +++++++++-------- src/operations/upgrade.rs | 14 +++++++-- 6 files changed, 105 insertions(+), 21 deletions(-) diff --git a/src/database/mod.rs b/src/database/mod.rs index f37d309..0e79ed6 100644 --- a/src/database/mod.rs +++ b/src/database/mod.rs @@ -18,6 +18,6 @@ pub fn init(options: Options) { initialise::init(options); } -pub fn query(a: &str, options: Options) -> Vec { - query::query(a, options) +pub fn query(options: Options) -> Vec { + query::query(options) } diff --git a/src/database/query.rs b/src/database/query.rs index 89e3016..d12470d 100644 --- a/src/database/query.rs +++ b/src/database/query.rs @@ -6,7 +6,7 @@ use rusqlite::Connection; use crate::internal::rpc::Package; use crate::{log, Options}; -pub fn query(a: &str, options: Options) -> Vec { +pub fn query(options: Options) -> Vec { let verbosity = options.verbosity; if verbosity >= 1 { @@ -23,11 +23,9 @@ pub fn query(a: &str, options: Options) -> Vec { log("Querying database for input".to_string()); } - let mut rs = conn - .prepare("SELECT name, version, description, depends, make_depends FROM packages WHERE name LIKE :a;") - .unwrap(); + let mut rs = conn.prepare("SELECT * FROM packages;").unwrap(); let packages_iter = rs - .query_map(&[(":a", &a)], |row| { + .query_map([], |row| { Ok(Package { name: row.get(0).unwrap(), version: row.get(1).unwrap(), diff --git a/src/internal/mod.rs b/src/internal/mod.rs index 1965fd1..06c7006 100644 --- a/src/internal/mod.rs +++ b/src/internal/mod.rs @@ -30,3 +30,24 @@ pub fn crash(a: String, b: i32) { pub fn log(a: String) { strings::log(a); } + +pub fn prompt(a: String, b: bool) -> bool { + strings::prompt(a, b) +} + +#[macro_export] +macro_rules! uwu { + ($x:expr) => {{ + let uwu: String = String::from_str($x).unwrap(); + + let uwu = uwu.replace("l", "w"); + let uwu = uwu.replace("L", "W"); + let uwu = uwu.replace("r", "w"); + let uwu = uwu.replace("R", "W"); + let uwu = uwu.replace("na", "nya"); + let uwu = uwu.replace("Na", "Nya"); + let uwu = uwu.replace("NA", "NYA"); + + uwu + }}; +} diff --git a/src/internal/strings.rs b/src/internal/strings.rs index 29f03e4..516b391 100644 --- a/src/internal/strings.rs +++ b/src/internal/strings.rs @@ -1,16 +1,40 @@ +use crate::uwu; +use std::io::Write; use std::process::exit; +use std::str::FromStr; use std::time::UNIX_EPOCH; +use std::{env, io}; pub fn info(a: String) { + let a = if env::var("AME_UWU").unwrap_or("".to_string()) == "true" { + uwu!(&a) + } else { + a + }; + println!("\x1b[2;22;35m❖\x1b[0m \x1b[1;37m{}\x1b[0m", a) } pub fn crash(a: String, b: i32) { + let a = if env::var("AME_UWU").unwrap_or("".to_string()) == "true" { + uwu!(&a) + } else { + a + }; + println!("\x1b[2;22;31m❌\x1b[0m \x1b[1;91m{}\x1b[0m", a); exit(b); } pub fn log(a: String) { + let a = if env::var("AME_UWU").unwrap_or("".to_string()) == "true" + && env::var("AME_UWU_DEBUG").unwrap_or("".to_string()) == "true" + { + uwu!(&a) + } else { + a + }; + eprintln!( "{} {}", std::time::SystemTime::now() @@ -20,3 +44,32 @@ pub fn log(a: String) { a ); } + +pub fn prompt(a: String, b: bool) -> bool { + let default = ["[Y/n]", "[y/N]"]; + let i = if b { 0 } else { 1 }; + + let a = if env::var("AME_UWU").unwrap_or("".to_string()) == "true" { + uwu!(&a) + } else { + a + }; + + print!( + "\x1b[2;22;35m?\x1b[0m \x1b[1;37m{}\x1b[0m \x1b[2;22;37m{}\x1b[0m: ", + a, default[i] + ); + + let mut yn: String = String::new(); + + io::stdout().flush().ok(); + let _ = std::io::stdin().read_line(&mut yn); + + if yn.trim().to_lowercase() == "n" || yn.trim().to_lowercase() == "no" { + false + } else if yn.trim().to_lowercase() == "y" || yn.trim().to_lowercase() == "yes" { + true + } else { + b + } +} diff --git a/src/operations/aur_install.rs b/src/operations/aur_install.rs index ad97ae4..eb124fa 100644 --- a/src/operations/aur_install.rs +++ b/src/operations/aur_install.rs @@ -4,8 +4,8 @@ use std::fs::remove_dir_all; use std::path::Path; use std::process::{Command, Stdio}; -use crate::internal::crash; use crate::internal::rpc::rpcinfo; +use crate::internal::{crash, prompt}; use crate::{info, log, Options}; pub fn aur_install(a: Vec, options: Options) { @@ -84,14 +84,20 @@ pub fn aur_install(a: Vec, options: Options) { } if !noconfirm { + let p = prompt( + "Would you like to view or edit {}'s PKGBUILD?".to_string(), + false, + ); let editor = env::var("EDITOR").unwrap_or_else(|_| "nano".parse().unwrap()); - Command::new(editor) - .arg(format!("{}/PKGBUILD", pkg)) - .spawn() - .unwrap() - .wait() - .unwrap(); + if p { + Command::new(editor) + .arg(format!("{}/PKGBUILD", pkg)) + .spawn() + .unwrap() + .wait() + .unwrap(); + } } // dep installing @@ -122,10 +128,8 @@ pub fn aur_install(a: Vec, options: Options) { ); } - if makepkg_args.contains(&"--asdeps") { - set_current_dir(&cachedir).unwrap(); - remove_dir_all(format!("{}/{}", cachedir, pkg)).unwrap(); - } + set_current_dir(&cachedir).unwrap(); + remove_dir_all(format!("{}/{}", cachedir, &pkg)).unwrap(); // pushes package to database crate::database::add(rpcres.package.unwrap(), options); diff --git a/src/operations/upgrade.rs b/src/operations/upgrade.rs index 7cbea10..d80c824 100644 --- a/src/operations/upgrade.rs +++ b/src/operations/upgrade.rs @@ -2,7 +2,7 @@ use runas::Command; use crate::internal::rpc::rpcinfo; use crate::operations::aur_install::aur_install; -use crate::{log, Options}; +use crate::{info, log, Options}; pub fn upgrade(options: Options) { let verbosity = options.verbosity; @@ -26,7 +26,11 @@ pub fn upgrade(options: Options) { log("Upgrading AUR packages".to_string()); } - let res = crate::database::query("\"%\"", options); + let res = crate::database::query(options); + + if verbosity >= 1 { + log(format!("{:?}", &res)); + } let mut aur_upgrades = vec![]; for r in res { @@ -37,5 +41,9 @@ pub fn upgrade(options: Options) { } } - aur_install(aur_upgrades, options); + if !aur_upgrades.is_empty() { + aur_install(aur_upgrades, options); + } else { + info("No upgrades available for installed AUR packages".to_string()); + } } From 52df05752b32254344b0e904c593ab37d10d0246 Mon Sep 17 00:00:00 2001 From: michal Date: Thu, 20 Jan 2022 23:03:11 +0000 Subject: [PATCH 25/33] import optimisation --- src/internal/strings.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/internal/strings.rs b/src/internal/strings.rs index 516b391..a91becc 100644 --- a/src/internal/strings.rs +++ b/src/internal/strings.rs @@ -1,10 +1,11 @@ -use crate::uwu; use std::io::Write; use std::process::exit; use std::str::FromStr; use std::time::UNIX_EPOCH; use std::{env, io}; +use crate::uwu; + pub fn info(a: String) { let a = if env::var("AME_UWU").unwrap_or("".to_string()) == "true" { uwu!(&a) From dba4ede596a808ea0c30cd6fabf1062f7c09b76b Mon Sep 17 00:00:00 2001 From: michal Date: Thu, 20 Jan 2022 23:23:28 +0000 Subject: [PATCH 26/33] finalising some stuff --- src/internal/strings.rs | 10 +++++----- src/operations/aur_install.rs | 2 +- src/operations/install.rs | 32 +++++++++++++++++++------------- 3 files changed, 25 insertions(+), 19 deletions(-) diff --git a/src/internal/strings.rs b/src/internal/strings.rs index a91becc..2850ee8 100644 --- a/src/internal/strings.rs +++ b/src/internal/strings.rs @@ -7,7 +7,7 @@ use std::{env, io}; use crate::uwu; pub fn info(a: String) { - let a = if env::var("AME_UWU").unwrap_or("".to_string()) == "true" { + let a = if env::var("AME_UWU").unwrap_or_else(|_| "".to_string()) == "true" { uwu!(&a) } else { a @@ -17,7 +17,7 @@ pub fn info(a: String) { } pub fn crash(a: String, b: i32) { - let a = if env::var("AME_UWU").unwrap_or("".to_string()) == "true" { + let a = if env::var("AME_UWU").unwrap_or_else(|_| "".to_string()) == "true" { uwu!(&a) } else { a @@ -28,8 +28,8 @@ pub fn crash(a: String, b: i32) { } pub fn log(a: String) { - let a = if env::var("AME_UWU").unwrap_or("".to_string()) == "true" - && env::var("AME_UWU_DEBUG").unwrap_or("".to_string()) == "true" + let a = if env::var("AME_UWU").unwrap_or_else(|_| "".to_string()) == "true" + && env::var("AME_UWU_DEBUG").unwrap_or_else(|_| "".to_string()) == "true" { uwu!(&a) } else { @@ -50,7 +50,7 @@ pub fn prompt(a: String, b: bool) -> bool { let default = ["[Y/n]", "[y/N]"]; let i = if b { 0 } else { 1 }; - let a = if env::var("AME_UWU").unwrap_or("".to_string()) == "true" { + let a = if env::var("AME_UWU").unwrap_or_else(|_| "".to_string()) == "true" { uwu!(&a) } else { a diff --git a/src/operations/aur_install.rs b/src/operations/aur_install.rs index eb124fa..15c0ecc 100644 --- a/src/operations/aur_install.rs +++ b/src/operations/aur_install.rs @@ -85,7 +85,7 @@ pub fn aur_install(a: Vec, options: Options) { if !noconfirm { let p = prompt( - "Would you like to view or edit {}'s PKGBUILD?".to_string(), + format!("Would you like to view or edit {}'s PKGBUILD?", pkg), false, ); let editor = env::var("EDITOR").unwrap_or_else(|_| "nano".parse().unwrap()); diff --git a/src/operations/install.rs b/src/operations/install.rs index 91c7b63..eddf68a 100644 --- a/src/operations/install.rs +++ b/src/operations/install.rs @@ -1,32 +1,38 @@ -use crate::{info, log, Options}; +use crate::{crash, info, log, Options}; -pub fn install(mut a: Vec, options: Options) { +pub fn install(a: Vec, options: Options) { info(format!("Installing packages {} from repos", &a.join(", "))); - let b = a.clone(); + let mut opers = vec![]; if options.noconfirm { - a.push("--noconfirm".to_string()); + opers.push("--noconfirm".to_string()); } if options.asdeps { - a.push("--asdeps".to_string()); + opers.push("--asdeps".to_string()); } let verbosity = options.verbosity; if verbosity >= 1 { - log(format!("Installing from repos: {:?}", &b)); + log(format!("Installing from repos: {:?}", &a)); } let r = runas::Command::new("pacman") .arg("-S") .arg("--needed") .args(&a) + .args(&opers) .status() .expect("Something has gone wrong"); - if let Some(x) = r.code() { - if verbosity >= 1 { - log(format!( - "Installing packages: {:?} exited with code {}", - &b, x - )); - } + if r.code() != Some(0) { + crash( + format!( + "An error occured while installing packages: {}, aborting", + a.join(", ") + ), + 1, + ); + } + + if verbosity >= 1 { + log(format!("Installing packages: {:?} was successful", &a)); } } From bc57a9020d74bc7d15c53acf7ae7501cc250cb9a Mon Sep 17 00:00:00 2001 From: michal Date: Thu, 20 Jan 2022 23:51:11 +0000 Subject: [PATCH 27/33] added CONTRIBUTING.md --- CONTRIBUTING.md | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 CONTRIBUTING.md diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..f41443c --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,27 @@ +# Crystal Linux Contributing Guidelines + +--- + +####!! Always make sure to `git pull` before doing any work to avoid commit hell !! + +### Pre-Commit Checks + +- Make sure to `cargo fmt` your code before every commit push +- Unless in specific edge cases, don't push code that doesn't pass `cargo check` +- Try to correct any code with `cargo clippy` before you push + +### Formatting + +- UNIX line endings (LF instead of CRLF) +- 4 spaces per TAB + +### Good Practices + +- Try to use .unwrap() as little as possible +- Try to never use panic!() in production code, always try to have a possible way to resolve errors, even if it's just unwrap_or/_else() +- Never use println!() or eprintln!() in finalised code. Using string functions (e.g. info() in Amethyst v3.0.0) is preferred +- Compartmentalise as much as you can, avoid writing the exact same line of code 50 times if you can turn it into a function + +### Examples of these guidelines in practice + +- https://git.getcryst.al/crystal/ame/src/branch/rewrite \ No newline at end of file From 59ca883f66d8849f05f81e63b324d6bc17633055 Mon Sep 17 00:00:00 2001 From: michal Date: Thu, 20 Jan 2022 23:51:58 +0000 Subject: [PATCH 28/33] Update 'CONTRIBUTING.md' --- CONTRIBUTING.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index f41443c..dfc9c38 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,8 +1,6 @@ # Crystal Linux Contributing Guidelines ---- - -####!! Always make sure to `git pull` before doing any work to avoid commit hell !! +#### !! Always make sure to `git pull` before doing any work to avoid commit hell !! ### Pre-Commit Checks From 54f3c87f9d4b24bae30249815520ab85516db591 Mon Sep 17 00:00:00 2001 From: michal Date: Fri, 21 Jan 2022 15:13:00 +0000 Subject: [PATCH 29/33] clearer crashing + readme --- README.md | 58 ++++++++++++++++++++++------------- src/database/add.rs | 2 +- src/database/initialise.rs | 2 +- src/internal/initialise.rs | 4 +-- src/operations/aur_install.rs | 24 ++++++++++----- src/operations/install.rs | 2 +- 6 files changed, 58 insertions(+), 34 deletions(-) diff --git a/README.md b/README.md index de983e0..98d072e 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,6 @@ Logo

-

Amethyst

@@ -12,38 +11,55 @@

Amethyst is a fast, efficient and lightweight AUR helper and Pacman wrapper. Made for Crystal, compatible with any Arch-based Linux distribution.

-![](screenshot.png) - ## Basic usage -| Action | FreeBSD pkg-style alias | Pacman-style flag(s) | -|----------------------|-------------------------|----------------------| -| Install a package | ame ins/install | ame -S | -| Remove a package | ame rm/remove | ame -R/-Rs | -| Upgrade a package | ame upg/upgrade | ame -Syu | -| Search for a package | ame sea | ame -Ss | +| Action | FreeBSD pkg-style alias | Pacman-style flags | +|----------------------|-------------------------|--------------------| +| Install a package | ame ins/install | ame -S | +| Remove a package | ame rm/remove | ame -R/-Rs | +| Upgrade a package | ame upg/upgrade | ame -Syu | +| Search for a package | ame sea | ame -Ss | + +## Exit codes overview + +| Exit Code (i32) | Reason | +|-----------------|----------------------------------------------------------| +| 1 | Running ame as UID 0 / root | +| 2 | Failed adding package to database | +| 3 | Failed initialising database | +| 4 | Error creating cache and/or database paths | +| 5 | Could not find one or more required package dependencies | +| 6 | User cancelled package installation | +| 7 | Pacman error when installing package | + ## How to build: -(Install cargo) +Tested on latest Cargo (1.60.0-nightly) -For release: +
-- `make clean release` +#### Debug/development builds -For general debug/test: +- `cargo build` -- `make debug` +#### Optimised/release builds -Clean all build directories: +- `cargo build --release` -- `make clean` +#### Pkg-warner included + +- `cargo build (--release) --all --features=pkg-warner`

-```sh -echo "AME_UWU=YES" >> ~/.zshrc # for zsh -echo "AME_UWU=YES" >> ~/.bashrc # for bash -set -Ux AME_UWU YES # for fish -``` \ No newline at end of file + \ No newline at end of file diff --git a/src/database/add.rs b/src/database/add.rs index b6fea36..bf4620b 100644 --- a/src/database/add.rs +++ b/src/database/add.rs @@ -20,7 +20,7 @@ pub fn add(pkg: Package, options: Options) { conn.execute("INSERT OR REPLACE INTO packages (name, version, description, depends, make_depends) VALUES (?1, ?2, ?3, ?4, ?5)", [&pkg.name, &pkg.version, &pkg.description.unwrap_or_else(|| "No description found.".parse().unwrap()), &pkg.depends.join(" "), &pkg.make_depends.join(" ")], ).unwrap_or_else(|e| { - crash(format!("Failed adding package {} to the database: {}", pkg.name, e), 1); + crash(format!("Failed adding package {} to the database: {}", pkg.name, e), 2); 1 }); } diff --git a/src/database/initialise.rs b/src/database/initialise.rs index d4f0610..01d92b9 100644 --- a/src/database/initialise.rs +++ b/src/database/initialise.rs @@ -32,7 +32,7 @@ pub fn init(options: Options) { [], ) .unwrap_or_else(|e| { - crash(format!("Couldn't initialise database: {}", e), 1); + crash(format!("Couldn't initialise database: {}", e), 3); 1 }); } diff --git a/src/internal/initialise.rs b/src/internal/initialise.rs index bf5b004..d48eec6 100644 --- a/src/internal/initialise.rs +++ b/src/internal/initialise.rs @@ -19,7 +19,7 @@ pub fn init(options: Options) { Err(e) => { crash( format!("Couldn't create path: {}/.local/share/ame: {}", homedir, e), - 1, + 4, ); } } @@ -40,7 +40,7 @@ pub fn init(options: Options) { Err(e) => { crash( format!("Couldn't create path: {}/.cache/ame: {}", homedir, e), - 1, + 4, ); } } diff --git a/src/operations/aur_install.rs b/src/operations/aur_install.rs index 15c0ecc..aa1c209 100644 --- a/src/operations/aur_install.rs +++ b/src/operations/aur_install.rs @@ -79,31 +79,39 @@ pub fn aur_install(a: Vec, options: Options) { sorted.nf.join(", "), pkg ), - 1, + 5, ); } if !noconfirm { - let p = prompt( - format!("Would you like to view or edit {}'s PKGBUILD?", pkg), + let p1 = prompt( + format!("Would you like to review {}'s PKGBUILD?", pkg), false, ); - let editor = env::var("EDITOR").unwrap_or_else(|_| "nano".parse().unwrap()); + let editor = env::var("PAGER").unwrap_or_else(|_| "less".parse().unwrap()); - if p { + if p1 { Command::new(editor) .arg(format!("{}/PKGBUILD", pkg)) .spawn() .unwrap() .wait() .unwrap(); + let p2 = prompt(format!("Would you still like to install {}?", pkg), true); + if !p2 { + crash("Not proceeding".to_string(), 6); + } } } // dep installing info("Moving on to install dependencies".to_string()); - crate::operations::install(sorted.repo, newopts); - crate::operations::aur_install(sorted.aur, newopts); + if !sorted.repo.is_empty() { + crate::operations::install(sorted.repo, newopts); + } + if !sorted.aur.is_empty() { + crate::operations::aur_install(sorted.aur, newopts); + } let mut makepkg_args = vec!["-rsic", "--needed"]; if options.asdeps { @@ -124,7 +132,7 @@ pub fn aur_install(a: Vec, options: Options) { if out.code() != Some(0) { crash( format!("Error encountered while installing {}, aborting", pkg), - 1, + 7, ); } diff --git a/src/operations/install.rs b/src/operations/install.rs index eddf68a..95f1ddf 100644 --- a/src/operations/install.rs +++ b/src/operations/install.rs @@ -28,7 +28,7 @@ pub fn install(a: Vec, options: Options) { "An error occured while installing packages: {}, aborting", a.join(", ") ), - 1, + 7, ); } From 52b893a06391cbcd2a8af5c0c95761057106e5d5 Mon Sep 17 00:00:00 2001 From: michal Date: Fri, 21 Jan 2022 17:26:36 +0000 Subject: [PATCH 30/33] honestly not sure what i've done to anger the vcs gods today --- CONTRIBUTING.md | 9 ++++++--- README.md | 1 - src/database/add.rs | 4 ++-- src/database/initialise.rs | 8 ++++---- src/database/query.rs | 4 ++-- src/database/remove.rs | 4 ++-- src/internal/mod.rs | 2 +- src/internal/sort.rs | 2 +- src/internal/strings.rs | 2 +- src/main.rs | 6 +++--- src/operations/aur_install.rs | 4 ++-- src/operations/search.rs | 2 +- src/operations/uninstall.rs | 4 ++-- src/operations/upgrade.rs | 2 +- 14 files changed, 28 insertions(+), 26 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index dfc9c38..161f3a0 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -16,9 +16,12 @@ ### Good Practices - Try to use .unwrap() as little as possible -- Try to never use panic!() in production code, always try to have a possible way to resolve errors, even if it's just unwrap_or/_else() -- Never use println!() or eprintln!() in finalised code. Using string functions (e.g. info() in Amethyst v3.0.0) is preferred -- Compartmentalise as much as you can, avoid writing the exact same line of code 50 times if you can turn it into a function +- Try to never use panic!() in production code, always try to have a possible way to resolve errors, even if it's just + unwrap_or/_else() +- Never use println!() or eprintln!() in finalised code. Using string functions (e.g. info() in Amethyst v3.0.0) is + preferred +- Compartmentalise as much as you can, avoid writing the exact same line of code 50 times if you can turn it into a + function ### Examples of these guidelines in practice diff --git a/README.md b/README.md index 98d072e..455dfb0 100644 --- a/README.md +++ b/README.md @@ -32,7 +32,6 @@ Made for Crystal, compatible with any Arch-based Linux distribution.

| 6 | User cancelled package installation | | 7 | Pacman error when installing package | - ## How to build: Tested on latest Cargo (1.60.0-nightly) diff --git a/src/database/add.rs b/src/database/add.rs index bf4620b..7947578 100644 --- a/src/database/add.rs +++ b/src/database/add.rs @@ -3,15 +3,15 @@ use std::path::Path; use rusqlite::Connection; -use crate::internal::rpc::Package; use crate::{crash, log, Options}; +use crate::internal::rpc::Package; pub fn add(pkg: Package, options: Options) { let conn = Connection::open(Path::new(&format!( "{}/.local/share/ame/db.sqlite", env::var("HOME").unwrap() ))) - .expect("Couldn't connect to database"); + .expect("Couldn't connect to database"); if options.verbosity >= 1 { log(format!("Adding package {} to database", pkg.name)); diff --git a/src/database/initialise.rs b/src/database/initialise.rs index 01d92b9..2f4e558 100644 --- a/src/database/initialise.rs +++ b/src/database/initialise.rs @@ -31,8 +31,8 @@ pub fn init(options: Options) { )", [], ) - .unwrap_or_else(|e| { - crash(format!("Couldn't initialise database: {}", e), 3); - 1 - }); + .unwrap_or_else(|e| { + crash(format!("Couldn't initialise database: {}", e), 3); + 1 + }); } diff --git a/src/database/query.rs b/src/database/query.rs index d12470d..7ec0ccc 100644 --- a/src/database/query.rs +++ b/src/database/query.rs @@ -3,8 +3,8 @@ use std::path::Path; use rusqlite::Connection; -use crate::internal::rpc::Package; use crate::{log, Options}; +use crate::internal::rpc::Package; pub fn query(options: Options) -> Vec { let verbosity = options.verbosity; @@ -17,7 +17,7 @@ pub fn query(options: Options) -> Vec { "{}/.local/share/ame/db.sqlite", env::var("HOME").unwrap() ))) - .expect("Couldn't connect to database"); + .expect("Couldn't connect to database"); if verbosity >= 1 { log("Querying database for input".to_string()); diff --git a/src/database/remove.rs b/src/database/remove.rs index c213e3b..d538415 100644 --- a/src/database/remove.rs +++ b/src/database/remove.rs @@ -10,7 +10,7 @@ pub fn remove(pkg: &str, options: Options) { "{}/.local/share/ame/db.sqlite", env::var("HOME").unwrap() ))) - .expect("Couldn't connect to database"); + .expect("Couldn't connect to database"); let verbosity = options.verbosity; @@ -26,5 +26,5 @@ pub fn remove(pkg: &str, options: Options) { WHERE name = ?);", [pkg], ) - .expect("Couldn't delete package from database"); + .expect("Couldn't delete package from database"); } diff --git a/src/internal/mod.rs b/src/internal/mod.rs index 06c7006..66bdeae 100644 --- a/src/internal/mod.rs +++ b/src/internal/mod.rs @@ -50,4 +50,4 @@ macro_rules! uwu { uwu }}; -} +} \ No newline at end of file diff --git a/src/internal/sort.rs b/src/internal/sort.rs index 64d6430..56c3cac 100644 --- a/src/internal/sort.rs +++ b/src/internal/sort.rs @@ -1,7 +1,7 @@ use std::process::{Command, Stdio}; -use crate::internal::strings::log; use crate::internal::{clean, rpc, structs}; +use crate::internal::strings::log; use crate::Options; pub fn sort(input: &[String], options: Options) -> structs::Sorted { diff --git a/src/internal/strings.rs b/src/internal/strings.rs index 2850ee8..33ee359 100644 --- a/src/internal/strings.rs +++ b/src/internal/strings.rs @@ -1,8 +1,8 @@ +use std::{env, io}; use std::io::Write; use std::process::exit; use std::str::FromStr; use std::time::UNIX_EPOCH; -use std::{env, io}; use crate::uwu; diff --git a/src/main.rs b/src/main.rs index a724c27..3489c17 100644 --- a/src/main.rs +++ b/src/main.rs @@ -199,9 +199,9 @@ fn main() { .unwrap() .is_present("repo") && !matches - .subcommand_matches("search") - .unwrap() - .is_present("aur") + .subcommand_matches("search") + .unwrap() + .is_present("aur") { info(format!("Searching AUR and repos for {}", &packages[0])); operations::search(&packages[0], options); diff --git a/src/operations/aur_install.rs b/src/operations/aur_install.rs index aa1c209..4a8533e 100644 --- a/src/operations/aur_install.rs +++ b/src/operations/aur_install.rs @@ -4,9 +4,9 @@ use std::fs::remove_dir_all; use std::path::Path; use std::process::{Command, Stdio}; -use crate::internal::rpc::rpcinfo; -use crate::internal::{crash, prompt}; use crate::{info, log, Options}; +use crate::internal::{crash, prompt}; +use crate::internal::rpc::rpcinfo; pub fn aur_install(a: Vec, options: Options) { let url = crate::internal::rpc::URL; diff --git a/src/operations/search.rs b/src/operations/search.rs index 08d5006..053d9fd 100644 --- a/src/operations/search.rs +++ b/src/operations/search.rs @@ -1,7 +1,7 @@ use std::process::Command; -use crate::internal::rpc::rpcsearch; use crate::{log, Options}; +use crate::internal::rpc::rpcsearch; pub fn aur_search(a: &str, options: Options) { let verbosity = options.verbosity; diff --git a/src/operations/uninstall.rs b/src/operations/uninstall.rs index 0e2ef05..405f7ce 100644 --- a/src/operations/uninstall.rs +++ b/src/operations/uninstall.rs @@ -1,5 +1,5 @@ -use std::path::Path; use std::{env, fs}; +use std::path::Path; use crate::{log, Options}; @@ -39,7 +39,7 @@ pub fn uninstall(mut a: Vec, options: Options) { env::var("HOME").unwrap(), b ))) - .unwrap(); + .unwrap(); } } } diff --git a/src/operations/upgrade.rs b/src/operations/upgrade.rs index d80c824..1a761a0 100644 --- a/src/operations/upgrade.rs +++ b/src/operations/upgrade.rs @@ -1,8 +1,8 @@ use runas::Command; +use crate::{info, log, Options}; use crate::internal::rpc::rpcinfo; use crate::operations::aur_install::aur_install; -use crate::{info, log, Options}; pub fn upgrade(options: Options) { let verbosity = options.verbosity; From 9e5599917464618ed047bc700f7a1c1369354a76 Mon Sep 17 00:00:00 2001 From: michal Date: Fri, 21 Jan 2022 17:40:33 +0000 Subject: [PATCH 31/33] fmt + import optimisation --- Cargo.toml | 2 +- src/database/add.rs | 2 +- src/database/initialise.rs | 10 +++++----- src/database/query.rs | 2 +- src/database/remove.rs | 4 ++-- src/internal/mod.rs | 2 +- src/internal/strings.rs | 2 +- src/main.rs | 6 +++--- src/operations/uninstall.rs | 2 +- 9 files changed, 16 insertions(+), 16 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 0d21729..f68234a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -45,7 +45,7 @@ path = "src/main.rs" [profile.release] incremental = true -debug = true +debug = false lto = "fat" codegen-units = 1 diff --git a/src/database/add.rs b/src/database/add.rs index 7947578..eaea9d6 100644 --- a/src/database/add.rs +++ b/src/database/add.rs @@ -11,7 +11,7 @@ pub fn add(pkg: Package, options: Options) { "{}/.local/share/ame/db.sqlite", env::var("HOME").unwrap() ))) - .expect("Couldn't connect to database"); + .expect("Couldn't connect to database"); if options.verbosity >= 1 { log(format!("Adding package {} to database", pkg.name)); diff --git a/src/database/initialise.rs b/src/database/initialise.rs index 2f4e558..d7121a6 100644 --- a/src/database/initialise.rs +++ b/src/database/initialise.rs @@ -31,8 +31,8 @@ pub fn init(options: Options) { )", [], ) - .unwrap_or_else(|e| { - crash(format!("Couldn't initialise database: {}", e), 3); - 1 - }); -} + .unwrap_or_else(|e| { + crash(format!("Couldn't initialise database: {}", e), 3); + 1 + }); +} \ No newline at end of file diff --git a/src/database/query.rs b/src/database/query.rs index 7ec0ccc..6626fa7 100644 --- a/src/database/query.rs +++ b/src/database/query.rs @@ -17,7 +17,7 @@ pub fn query(options: Options) -> Vec { "{}/.local/share/ame/db.sqlite", env::var("HOME").unwrap() ))) - .expect("Couldn't connect to database"); + .expect("Couldn't connect to database"); if verbosity >= 1 { log("Querying database for input".to_string()); diff --git a/src/database/remove.rs b/src/database/remove.rs index d538415..c213e3b 100644 --- a/src/database/remove.rs +++ b/src/database/remove.rs @@ -10,7 +10,7 @@ pub fn remove(pkg: &str, options: Options) { "{}/.local/share/ame/db.sqlite", env::var("HOME").unwrap() ))) - .expect("Couldn't connect to database"); + .expect("Couldn't connect to database"); let verbosity = options.verbosity; @@ -26,5 +26,5 @@ pub fn remove(pkg: &str, options: Options) { WHERE name = ?);", [pkg], ) - .expect("Couldn't delete package from database"); + .expect("Couldn't delete package from database"); } diff --git a/src/internal/mod.rs b/src/internal/mod.rs index 66bdeae..06c7006 100644 --- a/src/internal/mod.rs +++ b/src/internal/mod.rs @@ -50,4 +50,4 @@ macro_rules! uwu { uwu }}; -} \ No newline at end of file +} diff --git a/src/internal/strings.rs b/src/internal/strings.rs index 33ee359..1883226 100644 --- a/src/internal/strings.rs +++ b/src/internal/strings.rs @@ -23,7 +23,7 @@ pub fn crash(a: String, b: i32) { a }; - println!("\x1b[2;22;31m❌\x1b[0m \x1b[1;91m{}\x1b[0m", a); + println!("\x1b[2;22;31m❌:\x1b[0m \x1b[1;91m{}\x1b[0m", a); exit(b); } diff --git a/src/main.rs b/src/main.rs index 3489c17..a724c27 100644 --- a/src/main.rs +++ b/src/main.rs @@ -199,9 +199,9 @@ fn main() { .unwrap() .is_present("repo") && !matches - .subcommand_matches("search") - .unwrap() - .is_present("aur") + .subcommand_matches("search") + .unwrap() + .is_present("aur") { info(format!("Searching AUR and repos for {}", &packages[0])); operations::search(&packages[0], options); diff --git a/src/operations/uninstall.rs b/src/operations/uninstall.rs index 405f7ce..208943d 100644 --- a/src/operations/uninstall.rs +++ b/src/operations/uninstall.rs @@ -39,7 +39,7 @@ pub fn uninstall(mut a: Vec, options: Options) { env::var("HOME").unwrap(), b ))) - .unwrap(); + .unwrap(); } } } From 7b79bcdfb32ba96d8b5901390747e61241cdefc2 Mon Sep 17 00:00:00 2001 From: michal Date: Sat, 22 Jan 2022 14:47:56 +0000 Subject: [PATCH 32/33] added feature request: list aur/repo packages installd (issue #11) --- src/main.rs | 70 +++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 68 insertions(+), 2 deletions(-) diff --git a/src/main.rs b/src/main.rs index a724c27..3a7f7f2 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,5 +1,5 @@ use std::io; -use std::process::exit; +use std::process::{exit, Command}; use clap::{App, AppSettings, Arg, ArgMatches, ArgSettings, Shell, SubCommand}; @@ -89,6 +89,21 @@ fn main() { .index(1), ), ) + .subcommand( + SubCommand::with_name("query") + .about("Queries installed packages") + .aliases(&["-Q", "ls"]) + .arg( + Arg::with_name("aur") + .short("a") + .help("Lists AUR/foreign packages"), + ) + .arg( + Arg::with_name("repo") + .short("r") + .help("Lists repo/native packages"), + ), + ) .subcommand( SubCommand::with_name("upgrade") .about("Upgrades locally installed packages to their latest versions") @@ -209,6 +224,57 @@ fn main() { } exit(0); } + + if let true = matches.is_present("query") { + if matches + .subcommand_matches("query") + .unwrap() + .is_present("aur") + { + Command::new("pacman") + .arg("-Qm") + .spawn() + .expect("Something has gone wrong") + .wait() + .unwrap(); + } + if matches + .subcommand_matches("query") + .unwrap() + .is_present("repo") + { + Command::new("pacman") + .arg("-Qn") + .spawn() + .expect("Something has gone wrong") + .wait() + .unwrap(); + } + if !matches + .subcommand_matches("query") + .unwrap() + .is_present("aur") + && !matches + .subcommand_matches("query") + .unwrap() + .is_present("repo") + { + Command::new("pacman") + .arg("-Qn") + .spawn() + .expect("Something has gone wrong") + .wait() + .unwrap(); + Command::new("pacman") + .arg("-Qm") + .spawn() + .expect("Something has gone wrong") + .wait() + .unwrap(); + } + exit(0); + } + if let true = &matches.is_present("compgen") { let mut app = build_app(); match matches @@ -235,4 +301,4 @@ fn main() { _ => {} } } -} +} \ No newline at end of file From e148cda408f86ac25519ff8a0ca8883d2bcb05f2 Mon Sep 17 00:00:00 2001 From: michal Date: Sat, 22 Jan 2022 20:26:08 +0000 Subject: [PATCH 33/33] sanitised readme --- README.md | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 455dfb0..7c005af 100644 --- a/README.md +++ b/README.md @@ -3,15 +3,19 @@ Logo

+

Amethyst

-

+

-Discord

+ Discord +

-

Amethyst is a fast, efficient and lightweight AUR helper and Pacman wrapper. -Made for Crystal, compatible with any Arch-based Linux distribution.

+

+Amethyst is a fast, efficient and lightweight AUR helper and Pacman wrapper.
+Made for Crystal, compatible with any Arch-based Linux distribution. +

-## Basic usage +### Basic usage | Action | FreeBSD pkg-style alias | Pacman-style flags | |----------------------|-------------------------|--------------------| @@ -20,7 +24,7 @@ Made for Crystal, compatible with any Arch-based Linux distribution.

| Upgrade a package | ame upg/upgrade | ame -Syu | | Search for a package | ame sea | ame -Ss | -## Exit codes overview +### Exit codes overview | Exit Code (i32) | Reason | |-----------------|----------------------------------------------------------| @@ -32,7 +36,7 @@ Made for Crystal, compatible with any Arch-based Linux distribution.

| 6 | User cancelled package installation | | 7 | Pacman error when installing package | -## How to build: +### How to build: Tested on latest Cargo (1.60.0-nightly)