Turns out we didn't even need the database after all

i18n
Michal 2 years ago
parent 21f958d0fe
commit b757d8f5f3
No known key found for this signature in database
GPG Key ID: A6A1A4DCB22279B9

32
Cargo.lock generated

@ -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"

@ -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 }

@ -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)
);
}

@ -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,
)
});
}

@ -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")
}

@ -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<Package> {
// 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::<usize, String>(3)
.unwrap()
.split(' ')
.map(|s| s.to_string())
.collect::<Vec<String>>(),
make_depends: row
.get::<usize, String>(4)
.unwrap()
.split(' ')
.map(|s| s.to_string())
.collect::<Vec<String>>(),
})
})
.expect("Couldn't query database for packages");
if verbosity >= 1 {
log!("Retrieved results");
}
// Convert to vector
let mut results: Vec<Package> = vec![];
for package in packages_iter {
results.push(package.unwrap());
}
if verbosity >= 1 {
log!("Collected results");
}
results
}

@ -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");
}

@ -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
)
});
}
}

@ -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) {

@ -183,8 +183,5 @@ pub fn aur_install(a: Vec<String>, options: Options) {
// Remove package from cache
remove_dir_all(format!("{}/{}", cachedir, &pkg)).unwrap();
// Pushes package to database
crate::database::add(rpcres.package.unwrap(), options);
}
}

@ -30,9 +30,6 @@ pub fn uninstall(packages: Vec<String>, 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/{}",

@ -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<String>
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::<Vec<&str>>();
non_native.pop();
// Parse non-native packages into a Vec<QueriedPackage>
let mut parsed_non_native: Vec<QueriedPackage> = vec![];
for pkg in non_native {
let split = pkg.split(' ').collect::<Vec<&str>>();
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);
}
}

Loading…
Cancel
Save