From b757d8f5f3c72422860ef10f191f5261f2d7106d Mon Sep 17 00:00:00 2001 From: Michal Date: Tue, 26 Jul 2022 01:53:16 +0100 Subject: [PATCH] Turns out we didn't even need the database after all --- Cargo.lock | 32 ++++++++ Cargo.toml | 1 + src/database/add.rs | 25 ------- src/database/initialise.rs | 44 ----------- src/database/mod.rs | 17 ----- src/database/query.rs | 66 ---------------- src/database/remove.rs | 26 ------- src/internal/initialise.rs | 137 +++++++--------------------------- src/main.rs | 21 +++--- src/operations/aur_install.rs | 3 - src/operations/uninstall.rs | 3 - src/operations/upgrade.rs | 44 +++++++++-- 12 files changed, 107 insertions(+), 312 deletions(-) delete mode 100644 src/database/add.rs delete mode 100644 src/database/initialise.rs delete mode 100644 src/database/mod.rs delete mode 100644 src/database/query.rs delete mode 100644 src/database/remove.rs diff --git a/Cargo.lock b/Cargo.lock index 4fc82ac..ced56bd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -12,6 +12,7 @@ dependencies = [ "mimalloc", "native-tls", "regex", + "rm_rf", "rusqlite", "serde", "ureq", @@ -455,6 +456,15 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "psm" +version = "0.1.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f446d0a6efba22928558c4fb4ce0b3fd6c89b0061343e390bf01a703742b8125" +dependencies = [ + "cc", +] + [[package]] name = "quote" version = "1.0.20" @@ -497,6 +507,15 @@ dependencies = [ "winapi", ] +[[package]] +name = "rm_rf" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3443b7a35aa12ed2e99edfc0ecbefe6a53b4848305cc83e29981dfa1aea1f71e" +dependencies = [ + "stacker", +] + [[package]] name = "rusqlite" version = "0.26.3" @@ -588,6 +607,19 @@ version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2fd0db749597d91ff862fd1d55ea87f7855a744a8425a64695b6fca237d1dad1" +[[package]] +name = "stacker" +version = "0.1.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c886bd4480155fd3ef527d45e9ac8dd7118a898a46530b7b94c3e21866259fce" +dependencies = [ + "cc", + "cfg-if", + "libc", + "psm", + "winapi", +] + [[package]] name = "strsim" version = "0.10.0" diff --git a/Cargo.toml b/Cargo.toml index fffaa8c..fb56b2e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -27,3 +27,4 @@ ureq = { version = "2.4.0", default-features = false, features = [ "native-tls", serde = { version = "1.0.138", default-features = false, features = [ "derive", "serde_derive" ] } native-tls = { version = "0.2.10", default-features = false } libc = { version = "0.2.126", default-features = false } +rm_rf = { version = "0.6.2", default-features = false } \ No newline at end of file diff --git a/src/database/add.rs b/src/database/add.rs deleted file mode 100644 index 7722c1f..0000000 --- a/src/database/add.rs +++ /dev/null @@ -1,25 +0,0 @@ -use crate::internal::exit_code::AppExitCode; -use crate::internal::rpc::Package; -use crate::{crash, log, Options}; - -use super::get_database_connection; - -pub fn add(pkg: Package, options: Options) { - // Initialise database connection - let conn = get_database_connection(); - - // Log the package name - if options.verbosity >= 1 { - log!("Adding package {} to database", pkg.name); - } - - // Push the package to the database - let pkg_description = pkg - .description - .unwrap_or_else(|| "No description found.".parse().unwrap()); - 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, &pkg.depends.join(" "), &pkg.make_depends.join(" ")], - ).unwrap_or_else(|e| - crash!(AppExitCode::FailedAddingPkg, "Failed adding package {} to the database: {}", pkg.name, e) - ); -} diff --git a/src/database/initialise.rs b/src/database/initialise.rs deleted file mode 100644 index 895bdc9..0000000 --- a/src/database/initialise.rs +++ /dev/null @@ -1,44 +0,0 @@ -use rusqlite::Connection; -use std::env; -use std::path::Path; - -use crate::internal::exit_code::AppExitCode; -use crate::{crash, log, Options}; - -pub fn init(options: Options) { - // Initialise variables - let path = format!("{}/.local/share/ame/db.sqlite", env::var("HOME").unwrap()); - let dbpath = Path::new(&path); - let verbosity = options.verbosity; - - // Log database path - if verbosity >= 1 { - log!("Creating database at {}", &path); - } - - // Initialise database connection - let conn = - Connection::open(dbpath).expect("Couldn't create database at ~/.local/share/ame/db.sqlite"); - if verbosity >= 1 { - log!("Populating database with table"); - } - - // Create 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| { - crash!( - AppExitCode::FailedInitDb, - "Couldn't initialise database: {}", - e, - ) - }); -} diff --git a/src/database/mod.rs b/src/database/mod.rs deleted file mode 100644 index 4eb9d9a..0000000 --- a/src/database/mod.rs +++ /dev/null @@ -1,17 +0,0 @@ -use std::{env, path::PathBuf}; - -pub mod add; -pub mod initialise; -pub mod query; -pub mod remove; - -pub use add::*; -pub use initialise::*; -pub use query::*; -pub use remove::*; -use rusqlite::Connection; - -fn get_database_connection() -> Connection { - let db_path = format!("{}/.local/share/ame/db.sqlite", env::var("HOME").unwrap()); - Connection::open(PathBuf::from(db_path)).expect("Couldn't connect to database") -} diff --git a/src/database/query.rs b/src/database/query.rs deleted file mode 100644 index d9587c7..0000000 --- a/src/database/query.rs +++ /dev/null @@ -1,66 +0,0 @@ -use rusqlite::Connection; -use std::env; -use std::path::Path; - -use crate::internal::rpc::Package; -use crate::{log, Options}; - -pub fn query(options: Options) -> Vec { - // Initialise variables - let verbosity = options.verbosity; - - if verbosity >= 1 { - log!("Connecting to database"); - } - - // Initialise database connection - 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 { - log!("Querying database for input"); - } - - // Get all database contents - let mut rs = conn.prepare("SELECT * FROM packages;").unwrap(); - let packages_iter = rs - .query_map([], |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 { - log!("Retrieved results"); - } - - // Convert to vector - let mut results: Vec = vec![]; - for package in packages_iter { - results.push(package.unwrap()); - } - - if verbosity >= 1 { - log!("Collected results"); - } - - results -} diff --git a/src/database/remove.rs b/src/database/remove.rs deleted file mode 100644 index 1cca51f..0000000 --- a/src/database/remove.rs +++ /dev/null @@ -1,26 +0,0 @@ -use crate::{log, Options}; - -use super::get_database_connection; - -pub fn remove(pkg: &str, options: Options) { - // Initialise database connection - let conn = get_database_connection(); - - // Initialise variables - let verbosity = options.verbosity; - - if verbosity >= 1 { - log!("Removing package {} from database", pkg); - } - - // Remove the package from the database - 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 9c3e717..42cdbbd 100644 --- a/src/internal/initialise.rs +++ b/src/internal/initialise.rs @@ -9,128 +9,43 @@ pub fn init(options: Options) { let verbosity = options.verbosity; let homedir = env::var("HOME").unwrap(); - // Initialise database path + // Initialise stateful directory 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 { - log!("Created path: {}/.local/share/ame", homedir); - } - } - Err(e) => { - crash!( - AppExitCode::FailedCreatingPaths, - "Couldn't create path: {}/.local/share/ame: {}", - homedir, - e, - ); - } - } - } - - // If database doesn't exist, create it - if !Path::new(&format!("{}/.local/share/ame/db.sqlite", homedir)).exists() { - crate::database::init(options); + std::fs::create_dir_all(format!("{}/.local/share/ame", homedir)).unwrap_or_else(|e| { + crash!( + AppExitCode::FailedCreatingPaths, + "Failed to create stateful directory: {}", + e + ); + }); } // If cache path doesn't exist, create it, if it does, delete it and recreate it 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 { - log!("Created path: {}/.cache/ame", homedir); - } - } - Err(e) => { - crash!( - AppExitCode::FailedCreatingPaths, - "Couldn't create path: {}/.cache/ame: {}", - homedir, - e, - ); - } - } - } else { - let r = std::fs::remove_dir_all(format!("{}/.cache/ame", homedir)); - match r { - Ok(_) => { - if verbosity >= 1 { - log!("Removing cache: {}/.cache/ame", homedir); - } - } - Err(e) => { - crash!( - AppExitCode::FailedCreatingPaths, - "Couldn't remove path: {}/.cache/ame: {}", - homedir, - e, - ); - } - } - let r2 = std::fs::create_dir_all(format!("{}/.cache/ame", homedir)); - match r2 { - Ok(_) => { - if verbosity >= 1 { - log!("Created path: {}/.cache/ame", homedir); - } - } - Err(e2) => { - crash!( - AppExitCode::FailedCreatingPaths, - "Couldn't create path: {}/.cache/ame: {}", - homedir, - e2, - ); - } - } - } - - // Ensure proper permissions on cache path - let r = Command::new("chmod") - .arg("-R") - .arg("770") - .arg(format!("{}/.cache/ame", homedir)) - .status(); - match r { - Ok(_) => { - if verbosity >= 1 { - log!("Set correct permissions for path: {}/.cache/ame", homedir); - } - } - Err(e) => { + std::fs::create_dir_all(format!("{}/.cache/ame", homedir)).unwrap_or_else(|e| { crash!( AppExitCode::FailedCreatingPaths, - "Couldn't set permissions for path: {}/.cache/ame: {}", + "Couldn't create path: {}/.cache/ame: {}", homedir, e, ); - } - }; - - // Ensure proper permissions on database path - let r = Command::new("chmod") - .arg("-R") - .arg("770") - .arg(format!("{}/.local/share/ame", homedir)) - .status(); - match r { - Ok(_) => { - if verbosity >= 1 { - log!( - "Set correct permissions for path: {}/.local/share/ame", - homedir - ); - } - } - Err(e) => { + }); + } else { + rm_rf::remove(format!("{}/.cache/ame", homedir)).unwrap_or_else(|e| { crash!( AppExitCode::FailedCreatingPaths, - "Couldn't set permissions for path: {}/.local/share/ame: {}", + "Couldn't remove path: {}/.cache/ame: {}", homedir, - e, - ); - } - }; + e + ) + }); + std::fs::create_dir_all(format!("{}/.cache/ame", homedir)).unwrap_or_else(|e| { + crash!( + AppExitCode::FailedCreatingPaths, + "Couldn't create path: {}/.cache/ame: {}", + homedir, + e + ) + }); + } } diff --git a/src/main.rs b/src/main.rs index 0e2e1bc..f3772f2 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,3 +1,6 @@ +#![warn(clippy::all, clippy::pedantic, clippy::nursery, clippy::cargo)] +#![allow(clippy::too_many_lines)] + use args::Args; use clap::Parser; use internal::commands::ShellCommand; @@ -12,7 +15,6 @@ use crate::internal::{init, sort, start_sudoloop, structs::Options}; static GLOBAL: mimalloc::MiMalloc = mimalloc::MiMalloc; mod args; -mod database; mod internal; mod operations; @@ -71,6 +73,15 @@ fn cmd_install(args: InstallArgs, options: Options) { info!("Attempting to install packages: {}", packages.join(", ")); + if !sorted.nf.is_empty() { + // If some packages are not found, crash + crash!( + AppExitCode::PacmanError, + "Couldn't find packages: {} in repos or the AUR", + sorted.nf.join(", ") + ); + } + if !sorted.repo.is_empty() { // If repo packages found, install them operations::install(sorted.repo, options); @@ -79,14 +90,6 @@ fn cmd_install(args: InstallArgs, options: Options) { // If AUR packages found, install them operations::aur_install(sorted.aur, options); } - if !sorted.nf.is_empty() { - // If some packages are not found, crash TODO: this check should happen first - crash!( - AppExitCode::PacmanError, - "Couldn't find packages: {} in repos or the AUR", - sorted.nf.join(", ") - ); - } } fn cmd_remove(args: RemoveArgs, options: Options) { diff --git a/src/operations/aur_install.rs b/src/operations/aur_install.rs index 26838e0..f8ed002 100644 --- a/src/operations/aur_install.rs +++ b/src/operations/aur_install.rs @@ -183,8 +183,5 @@ pub fn aur_install(a: Vec, options: Options) { // Remove package from cache remove_dir_all(format!("{}/{}", cachedir, &pkg)).unwrap(); - - // Pushes package to database - crate::database::add(rpcres.package.unwrap(), options); } } diff --git a/src/operations/uninstall.rs b/src/operations/uninstall.rs index 42a8e89..1a392ff 100644 --- a/src/operations/uninstall.rs +++ b/src/operations/uninstall.rs @@ -30,9 +30,6 @@ pub fn uninstall(packages: Vec, options: Options) { } for package in packages { - // Remove package from database - crate::database::remove(&package, options); - // Remove old cache directory if Path::new(&format!( "{}/.cache/ame/{}", diff --git a/src/operations/upgrade.rs b/src/operations/upgrade.rs index 64684ed..1ed3ed7 100644 --- a/src/operations/upgrade.rs +++ b/src/operations/upgrade.rs @@ -5,6 +5,12 @@ use crate::internal::rpc::rpcinfo; use crate::operations::aur_install::aur_install; use crate::{info, log, prompt, Options}; +#[derive(Debug)] +struct QueriedPackage { + pub name: String, + pub version: String, +} + pub fn upgrade(options: Options) { // Initialise variables let verbosity = options.verbosity; @@ -46,23 +52,45 @@ pub fn upgrade(options: Options) { log!("Upgrading AUR packages"); } - // Query database for AUR packages - let res = crate::database::query(options); + // List non-native packages using `pacman -Qm` and collect to a Vec + let mut non_native = ShellCommand::pacman() + .arg("-Qm") + .args(&["--color", "never"]) + .wait_with_output() + .silent_unwrap(AppExitCode::PacmanError); + let mut non_native = non_native.stdout.split('\n').collect::>(); + non_native.pop(); + + // Parse non-native packages into a Vec + let mut parsed_non_native: Vec = vec![]; + for pkg in non_native { + let split = pkg.split(' ').collect::>(); + if verbosity >= 1 { + log!("{:?}", split); + } + let name = split[0].to_string(); + let version = split[1].to_string(); + parsed_non_native.push(QueriedPackage { name, version }); + } if verbosity >= 1 { - log!("{:?}", &res); + log!("{:?}", &parsed_non_native); } // Check if AUR package versions are the same as installed let mut aur_upgrades = vec![]; - for r in res { + for pkg in parsed_non_native { // Query AUR - let re = r.clone(); - let ver = rpcinfo(r.name); + let rpc_result = rpcinfo((&*pkg.name).to_string()); + + if !rpc_result.found { + // If package not found, skip + continue; + } // If versions differ, push to a vector - if ver.package.unwrap().version != r.version { - aur_upgrades.push(re.name); + if rpc_result.package.unwrap().version != pkg.version { + aur_upgrades.push(pkg.name); } }