Merge pull request 'rewrite' (#16) from rewrite into main
Reviewed-on: https://git.getcryst.al/crystal/ame/pulls/16i18n
commit
96cc77950e
@ -1,6 +1,6 @@
|
||||
target/
|
||||
Cargo.lock
|
||||
ame
|
||||
ame.exe
|
||||
.vscode
|
||||
aur_pkgs.db
|
||||
test.sql
|
||||
.idea
|
||||
|
@ -0,0 +1,28 @@
|
||||
# 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
|
@ -1,19 +1,60 @@
|
||||
[package]
|
||||
name = "Amethyst"
|
||||
version = "3.0.0"
|
||||
authors = ["michal <michal@tar.black>", "axtlos <axtlos@tar.black>"]
|
||||
edition = "2021"
|
||||
description = "A fast and efficient AUR helper."
|
||||
license-file = "LICENSE.md"
|
||||
|
||||
[features]
|
||||
pkg-warner = []
|
||||
|
||||
[[bin]]
|
||||
name = "apt"
|
||||
path = "src/bin/apt.rs"
|
||||
required-features = ["pkg-warner"]
|
||||
|
||||
[[bin]]
|
||||
name = "apt-get"
|
||||
path = "src/bin/apt-get.rs"
|
||||
required-features = ["pkg-warner"]
|
||||
|
||||
[[bin]]
|
||||
name = "dnf"
|
||||
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/bin/yum.rs"
|
||||
required-features = ["pkg-warner"]
|
||||
|
||||
[[bin]]
|
||||
name = "zypper"
|
||||
path = "src/bin/zypper.rs"
|
||||
required-features = ["pkg-warner"]
|
||||
|
||||
[[bin]]
|
||||
name = "ame"
|
||||
version = "0.0.0"
|
||||
authors = [ "jnats <michal@tar.black>", "axtlos <axtlos@tar.black>" ]
|
||||
edition = "2018"
|
||||
description = "a fast and efficient aur helper."
|
||||
path = "src/main.rs"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
[profile.release]
|
||||
incremental = true
|
||||
debug = false
|
||||
lto = "fat"
|
||||
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"] }
|
||||
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"
|
||||
reqwest = { version = "0.11.7", default-features = false, features = [ "blocking", "json", "default-tls" ] }
|
||||
serde = { version = "1.0.90", default-features = false, features = [ "derive" ] }
|
||||
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"] }
|
||||
native-tls = "0.2.8"
|
@ -0,0 +1,23 @@
|
||||
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.
|
@ -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
|
@ -0,0 +1,14 @@
|
||||
use std::env;
|
||||
|
||||
fn main() {
|
||||
let arg = &env::args().collect::<Vec<String>>()[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::<Vec<&str>>()
|
||||
.last()
|
||||
.unwrap()
|
||||
);
|
||||
std::process::exit(0);
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
use std::env;
|
||||
|
||||
fn main() {
|
||||
let arg = &env::args().collect::<Vec<String>>()[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::<Vec<&str>>()
|
||||
.last()
|
||||
.unwrap()
|
||||
);
|
||||
std::process::exit(0);
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
use std::env;
|
||||
|
||||
fn main() {
|
||||
let arg = &env::args().collect::<Vec<String>>()[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::<Vec<&str>>()
|
||||
.last()
|
||||
.unwrap()
|
||||
);
|
||||
std::process::exit(0);
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
use std::env;
|
||||
|
||||
fn main() {
|
||||
let arg = &env::args().collect::<Vec<String>>()[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::<Vec<&str>>()
|
||||
.last()
|
||||
.unwrap()
|
||||
);
|
||||
std::process::exit(0);
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
use std::env;
|
||||
|
||||
fn main() {
|
||||
let arg = &env::args().collect::<Vec<String>>()[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::<Vec<&str>>()
|
||||
.last()
|
||||
.unwrap()
|
||||
);
|
||||
std::process::exit(0);
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
use std::env;
|
||||
|
||||
fn main() {
|
||||
let arg = &env::args().collect::<Vec<String>>()[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::<Vec<&str>>()
|
||||
.last()
|
||||
.unwrap()
|
||||
);
|
||||
std::process::exit(0);
|
||||
}
|
@ -0,0 +1,26 @@
|
||||
use std::env;
|
||||
use std::path::Path;
|
||||
|
||||
use rusqlite::Connection;
|
||||
|
||||
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");
|
||||
|
||||
if options.verbosity >= 1 {
|
||||
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| {
|
||||
crash(format!("Failed adding package {} to the database: {}", pkg.name, e), 2);
|
||||
1
|
||||
});
|
||||
}
|
@ -0,0 +1,38 @@
|
||||
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);
|
||||
let verbosity = options.verbosity;
|
||||
|
||||
if verbosity >= 1 {
|
||||
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 {
|
||||
log("Populating database with table".to_string());
|
||||
}
|
||||
|
||||
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(format!("Couldn't initialise database: {}", e), 3);
|
||||
1
|
||||
});
|
||||
}
|
@ -0,0 +1,23 @@
|
||||
use crate::internal::rpc::Package;
|
||||
use crate::Options;
|
||||
|
||||
mod add;
|
||||
mod initialise;
|
||||
mod query;
|
||||
mod remove;
|
||||
|
||||
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(options: Options) -> Vec<Package> {
|
||||
query::query(options)
|
||||
}
|
@ -0,0 +1,64 @@
|
||||
use std::env;
|
||||
use std::path::Path;
|
||||
|
||||
use rusqlite::Connection;
|
||||
|
||||
use crate::{log, Options};
|
||||
use crate::internal::rpc::Package;
|
||||
|
||||
pub fn query(options: Options) -> Vec<Package> {
|
||||
let verbosity = options.verbosity;
|
||||
|
||||
if verbosity >= 1 {
|
||||
log("Connecting to database".to_string());
|
||||
}
|
||||
|
||||
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".to_string());
|
||||
}
|
||||
|
||||
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".to_string());
|
||||
}
|
||||
|
||||
let mut results: Vec<Package> = vec![];
|
||||
|
||||
for package in packages_iter {
|
||||
results.push(package.unwrap());
|
||||
}
|
||||
|
||||
if verbosity >= 1 {
|
||||
log("Collected results".to_string());
|
||||
}
|
||||
|
||||
results
|
||||
}
|
@ -0,0 +1,30 @@
|
||||
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",
|
||||
env::var("HOME").unwrap()
|
||||
)))
|
||||
.expect("Couldn't connect to database");
|
||||
|
||||
let verbosity = options.verbosity;
|
||||
|
||||
if verbosity >= 1 {
|
||||
log(format!("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");
|
||||
}
|
@ -0,0 +1,25 @@
|
||||
use regex::Regex;
|
||||
|
||||
use crate::internal::strings::log;
|
||||
use crate::Options;
|
||||
|
||||
pub fn clean(a: &[String], options: Options) -> Vec<String> {
|
||||
let r = Regex::new(r"(\S+)((?:>=|<=|>|<)\S+$)").unwrap();
|
||||
let mut cleaned: Vec<String> = vec![];
|
||||
let verbosity = options.verbosity;
|
||||
|
||||
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 {
|
||||
log(format!("Cleaned: {:?}\nInto: {:?}", a, cleaned));
|
||||
}
|
||||
|
||||
cleaned
|
||||
}
|
@ -0,0 +1,48 @@
|
||||
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();
|
||||
|
||||
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(format!("Created path: {}/.local/share/ame", homedir));
|
||||
}
|
||||
}
|
||||
Err(e) => {
|
||||
crash(
|
||||
format!("Couldn't create path: {}/.local/share/ame: {}", homedir, e),
|
||||
4,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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 {
|
||||
Ok(_) => {
|
||||
if verbosity >= 1 {
|
||||
log(format!("Created path: {}/.cache/ame", homedir));
|
||||
}
|
||||
}
|
||||
Err(e) => {
|
||||
crash(
|
||||
format!("Couldn't create path: {}/.cache/ame: {}", homedir, e),
|
||||
4,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,53 @@
|
||||
use crate::Options;
|
||||
|
||||
mod clean;
|
||||
mod initialise;
|
||||
pub mod rpc;
|
||||
mod sort;
|
||||
mod strings;
|
||||
pub mod structs;
|
||||
|
||||
pub fn sort(a: &[String], options: Options) -> structs::Sorted {
|
||||
sort::sort(a, options)
|
||||
}
|
||||
|
||||
pub fn clean(a: &[String], options: Options) -> Vec<String> {
|
||||
clean::clean(a, options)
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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
|
||||
}};
|
||||
}
|
@ -0,0 +1,75 @@
|
||||
use std::sync::Arc;
|
||||
|
||||
#[derive(serde::Deserialize, Debug, Clone)]
|
||||
pub struct Package {
|
||||
#[serde(rename = "Name")]
|
||||
pub name: String,
|
||||
#[serde(rename = "Version")]
|
||||
pub version: String,
|
||||
#[serde(rename = "Description")]
|
||||
pub description: Option<String>,
|
||||
#[serde(rename = "Depends")]
|
||||
#[serde(default)]
|
||||
pub depends: Vec<String>,
|
||||
#[serde(rename = "MakeDepends")]
|
||||
#[serde(default)]
|
||||
pub make_depends: Vec<String>,
|
||||
}
|
||||
|
||||
#[derive(serde::Deserialize)]
|
||||
pub struct SearchResults {
|
||||
pub resultcount: u32,
|
||||
pub results: Vec<Package>,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct InfoResults {
|
||||
pub found: bool,
|
||||
pub package: Option<Package>,
|
||||
}
|
||||
|
||||
pub const URL: &str = "https://aur.archlinux.org/";
|
||||
|
||||
pub fn rpcinfo(pkg: String) -> InfoResults {
|
||||
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 {
|
||||
found: false,
|
||||
package: None,
|
||||
}
|
||||
} else {
|
||||
InfoResults {
|
||||
found: true,
|
||||
package: Some(res.results[0].clone()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn rpcsearch(pkg: String) -> SearchResults {
|
||||
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::<SearchResults>()
|
||||
.unwrap()
|
||||
}
|
@ -0,0 +1,46 @@
|
||||
use std::process::{Command, Stdio};
|
||||
|
||||
use crate::internal::{clean, rpc, structs};
|
||||
use crate::internal::strings::log;
|
||||
use crate::Options;
|
||||
|
||||
pub fn sort(input: &[String], options: Options) -> structs::Sorted {
|
||||
let mut repo: Vec<String> = vec![];
|
||||
let mut aur: Vec<String> = vec![];
|
||||
let mut nf: Vec<String> = vec![];
|
||||
let verbosity = options.verbosity;
|
||||
|
||||
let a = clean(input, options);
|
||||
|
||||
if verbosity >= 1 {
|
||||
log(format!("Sorting: {:?}", a.join(" ")));
|
||||
}
|
||||
|
||||
for b in a {
|
||||
let rs = Command::new("pacman")
|
||||
.arg("-Ss")
|
||||
.arg(format!("^{}$", &b))
|
||||
.stdout(Stdio::null())
|
||||
.status()
|
||||
.expect("Something has gone wrong");
|
||||
|
||||
if rpc::rpcinfo(b.to_string()).found {
|
||||
if verbosity >= 1 {
|
||||
log(format!("{} found in AUR", b));
|
||||
}
|
||||
aur.push(b.to_string());
|
||||
} else if let Some(0) = rs.code() {
|
||||
if verbosity >= 1 {
|
||||
log(format!("{} found in repos", b));
|
||||
}
|
||||
repo.push(b.to_string());
|
||||
} else {
|
||||
if verbosity >= 1 {
|
||||
log(format!("{} not found", b));
|
||||
}
|
||||
nf.push(b.to_string());
|
||||
}
|
||||
}
|
||||
|
||||
structs::Sorted::new(repo, aur, nf)
|
||||
}
|
@ -0,0 +1,76 @@
|
||||
use std::{env, io};
|
||||
use std::io::Write;
|
||||
use std::process::exit;
|
||||
use std::str::FromStr;
|
||||
use std::time::UNIX_EPOCH;
|
||||
|
||||
use crate::uwu;
|
||||
|
||||
pub fn info(a: String) {
|
||||
let a = if env::var("AME_UWU").unwrap_or_else(|_| "".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_else(|_| "".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_else(|_| "".to_string()) == "true"
|
||||
&& env::var("AME_UWU_DEBUG").unwrap_or_else(|_| "".to_string()) == "true"
|
||||
{
|
||||
uwu!(&a)
|
||||
} else {
|
||||
a
|
||||
};
|
||||
|
||||
eprintln!(
|
||||
"{} {}",
|
||||
std::time::SystemTime::now()
|
||||
.duration_since(UNIX_EPOCH)
|
||||
.unwrap()
|
||||
.as_secs(),
|
||||
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_else(|_| "".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
|
||||
}
|
||||
}
|
@ -0,0 +1,23 @@
|
||||
#[derive(Debug, serde::Serialize)]
|
||||
pub struct Sorted {
|
||||
#[allow(dead_code)]
|
||||
pub repo: Vec<String>,
|
||||
#[allow(dead_code)]
|
||||
pub aur: Vec<String>,
|
||||
#[allow(dead_code)]
|
||||
pub nf: Vec<String>,
|
||||
}
|
||||
|
||||
impl Sorted {
|
||||
pub fn new(repo: Vec<String>, aur: Vec<String>, nf: Vec<String>) -> Self {
|
||||
let a: Sorted = Sorted { repo, aur, nf };
|
||||
a
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
pub struct Options {
|
||||
pub verbosity: i32,
|
||||
pub noconfirm: bool,
|
||||
pub asdeps: bool,
|
||||
}
|
@ -1,17 +0,0 @@
|
||||
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;
|
@ -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();
|
||||
}
|
@ -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::<Vec<&str>>();
|
||||
|
||||
let mut rem_pkgs: Vec<String> = 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));
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
@ -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 <pkg> - install a package
|
||||
ame -R(n) / rm <pkg> - remove a package
|
||||
ame -Rs(n) / purge <pkg> - remove a package with it dependencies
|
||||
ame -Syu(n) / upg - upgrade all packages to latest version
|
||||
ame -Ss / sea <pkg> - search for a package
|
||||
ame -Sa / aursea <pkg> - search for a package in the aur
|
||||
ame -Sr / repsea <pkg> - search for a package in the repos
|
||||
ame -v / ver - contributors and version info
|
||||
ame -h / help - display this help message
|
||||
|
||||
ame <any valid pacman flags> - 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!();
|
||||
}
|
@ -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<String>) {
|
||||
// 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::<Vec<&str>>()[0] == "aur" {
|
||||
true => {
|
||||
aur.push(pkg.split('/').collect::<Vec<&str>>()[1].to_string());
|
||||
}
|
||||
false => {
|
||||
let out = Command::new("bash")
|
||||
.arg("-c")
|
||||
.arg(format!(
|
||||
"pacman -Sl {} | grep {}",
|
||||
pkg.split('/').collect::<Vec<&str>>()[0],
|
||||
pkg.split('/').collect::<Vec<&str>>()[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::<Vec<&str>>()[1],
|
||||
pkg.split('/').collect::<Vec<&str>>()[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<String> = 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::<Vec<&str>>()[0] == "aur" {
|
||||
true => {
|
||||
aur.push(pkg.split('/').collect::<Vec<&str>>()[1].to_string());
|
||||
}
|
||||
false => {
|
||||
let out = Command::new("bash")
|
||||
.arg("-c")
|
||||
.arg(format!(
|
||||
"pacman -Sl {} | grep {}",
|
||||
pkg.split('/').collect::<Vec<&str>>()[0],
|
||||
pkg.split('/').collect::<Vec<&str>>()[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::<Vec<&str>>()[1],
|
||||
pkg.split('/').collect::<Vec<&str>>()[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);
|
||||
}
|
||||
}
|
||||
}
|
@ -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)),
|
||||
};
|
||||
}
|
||||
}
|
@ -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<String>) {
|
||||
// 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<String> = 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)),
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
@ -1,39 +0,0 @@
|
||||
#[derive(serde::Deserialize, Debug, Clone)]
|
||||
pub struct Package {
|
||||
#[serde(rename = "Name")]
|
||||
pub name: String,
|
||||
#[serde(rename = "Version")]
|
||||
pub version: String,
|
||||
#[serde(rename = "Description")]
|
||||
pub description: Option<String>,
|
||||
#[serde(default)]
|
||||
#[serde(rename = "Depends")]
|
||||
pub depends: Vec<String>,
|
||||
#[serde(default)]
|
||||
#[serde(rename = "MakeDepends")]
|
||||
pub make_depends: Vec<String>,
|
||||
}
|
||||
|
||||
#[derive(serde::Deserialize)]
|
||||
pub struct SearchResults {
|
||||
pub resultcount: u32,
|
||||
pub results: Vec<Package>,
|
||||
}
|
||||
|
||||
pub fn rpcinfo(pkg: &str) -> Package {
|
||||
let res = reqwest::blocking::get(&format!(
|
||||
"https://aur.archlinux.org/rpc/?v=5&type=info&arg={}",
|
||||
pkg
|
||||
)).unwrap();
|
||||
|
||||
res.json::<SearchResults>().unwrap().results[0].clone()
|
||||
}
|
||||
|
||||
pub fn rpcsearch(pkg: &str) -> SearchResults {
|
||||
let res = reqwest::blocking::get(&format!(
|
||||
"https://aur.archlinux.org/rpc/?v=5&type=search&arg={}",
|
||||
pkg
|
||||
)).unwrap();
|
||||
|
||||
res.json().unwrap()
|
||||
}
|
@ -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()),
|
||||
};
|
||||
}
|
@ -1,100 +0,0 @@
|
||||
use crate::{err_unrec, inf};
|
||||
use std::env;
|
||||
|
||||
pub fn stat_dump_dat() -> Vec<String> {
|
||||
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)),
|
||||
}
|
||||
}
|
@ -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::<toml::Value>().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<String>> = Vec::new();
|
||||
let mut pkgs_to_install: Vec<String> = 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<String> = 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());
|
||||
}
|
||||
}
|
@ -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)
|
||||
);
|
||||
}
|
||||
}
|
@ -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<String>) {
|
||||
// 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<String> = 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<String> = 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<String> = 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)),
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
@ -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()),
|
||||
}
|
||||
}
|
@ -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::<toml::Value>().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));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -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 <axtlos@tar.black>");
|
||||
println!("- jnats <michal@tar.black>");
|
||||
println!("- jasio <jasiobene@icloud.com>");
|
||||
println!("- generic <mdc028@bucknell.edu>");
|
||||
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!();
|
||||
}
|
@ -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<String>) -> &Vec<String> {
|
||||
// sort the args
|
||||
if args.contains(&"--noconfirm".to_string()) {
|
||||
args.retain(|x| x != &"--noconfirm".to_string());
|
||||
return args;
|
||||
}
|
||||
args
|
||||
}
|
@ -0,0 +1,145 @@
|
||||
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::{info, log, Options};
|
||||
use crate::internal::{crash, prompt};
|
||||
use crate::internal::rpc::rpcinfo;
|
||||
|
||||
pub fn aur_install(a: Vec<String>, 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;
|
||||
|
||||
if verbosity >= 1 {
|
||||
log(format!("Installing from AUR: {:?}", &a));
|
||||
}
|
||||
|
||||
info(format!("Installing packages {} from the AUR", a.join(", ")));
|
||||
|
||||
for package in a {
|
||||
let rpcres = rpcinfo(package);
|
||||
|
||||
if !rpcres.found {
|
||||
break;
|
||||
}
|
||||
|
||||
let pkg = &rpcres.package.as_ref().unwrap().name;
|
||||
|
||||
if verbosity >= 1 {
|
||||
log(format!("Cloning {} into cachedir", pkg));
|
||||
}
|
||||
|
||||
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");
|
||||
|
||||
if verbosity >= 1 {
|
||||
log(format!(
|
||||
"Cloned {} into cachedir, moving on to resolving dependencies",
|
||||
pkg
|
||||
));
|
||||
log(format!(
|
||||
"Raw dependencies for package {} are:\n{:?}",
|
||||
pkg,
|
||||
rpcres.package.as_ref().unwrap().depends.join(", ")
|
||||
));
|
||||
}
|
||||
|
||||
// dep sorting
|
||||
info("Sorting dependencies".to_string());
|
||||
let sorted = crate::internal::sort(&rpcres.package.as_ref().unwrap().depends, options);
|
||||
|
||||
if verbosity >= 1 {
|
||||
log(format!(
|
||||
"Sorted dependencies for {} are:\n{:?}",
|
||||
pkg, &sorted
|
||||
));
|
||||
}
|
||||
|
||||
let newopts = Options {
|
||||
verbosity,
|
||||
noconfirm,
|
||||
asdeps: true,
|
||||
};
|
||||
|
||||
if !sorted.nf.is_empty() {
|
||||
crash(
|
||||
format!(
|
||||
"Could not find dependencies {} for package {}, aborting",
|
||||
sorted.nf.join(", "),
|
||||
pkg
|
||||
),
|
||||
5,
|
||||
);
|
||||
}
|
||||
|
||||
if !noconfirm {
|
||||
let p1 = prompt(
|
||||
format!("Would you like to review {}'s PKGBUILD?", pkg),
|
||||
false,
|
||||
);
|
||||
let editor = env::var("PAGER").unwrap_or_else(|_| "less".parse().unwrap());
|
||||
|
||||
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());
|
||||
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 {
|
||||
makepkg_args.push("--asdeps")
|
||||
}
|
||||
if options.noconfirm {
|
||||
makepkg_args.push("--noconfirm")
|
||||
}
|
||||
|
||||
// package building and installing
|
||||
info("Building time!".to_string());
|
||||
set_current_dir(format!("{}/{}", cachedir, pkg)).unwrap();
|
||||
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),
|
||||
7,
|
||||
);
|
||||
}
|
||||
|
||||
set_current_dir(&cachedir).unwrap();
|
||||
remove_dir_all(format!("{}/{}", cachedir, &pkg)).unwrap();
|
||||
|
||||
// pushes package to database
|
||||
crate::database::add(rpcres.package.unwrap(), options);
|
||||
}
|
||||
}
|
@ -0,0 +1,38 @@
|
||||
use crate::{crash, info, log, Options};
|
||||
|
||||
pub fn install(a: Vec<String>, options: Options) {
|
||||
info(format!("Installing packages {} from repos", &a.join(", ")));
|
||||
let mut opers = vec![];
|
||||
if options.noconfirm {
|
||||
opers.push("--noconfirm".to_string());
|
||||
}
|
||||
if options.asdeps {
|
||||
opers.push("--asdeps".to_string());
|
||||
}
|
||||
let verbosity = options.verbosity;
|
||||
if verbosity >= 1 {
|
||||
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 r.code() != Some(0) {
|
||||
crash(
|
||||
format!(
|
||||
"An error occured while installing packages: {}, aborting",
|
||||
a.join(", ")
|
||||
),
|
||||
7,
|
||||
);
|
||||
}
|
||||
|
||||
if verbosity >= 1 {
|
||||
log(format!("Installing packages: {:?} was successful", &a));
|
||||
}
|
||||
}
|
@ -0,0 +1,31 @@
|
||||
use crate::Options;
|
||||
|
||||
mod aur_install;
|
||||
mod install;
|
||||
mod search;
|
||||
mod uninstall;
|
||||
mod upgrade;
|
||||
|
||||
pub fn install(a: Vec<String>, options: Options) {
|
||||
install::install(a, options);
|
||||
}
|
||||
|
||||
pub fn uninstall(a: Vec<String>, options: Options) {
|
||||
uninstall::uninstall(a, options);
|
||||
}
|
||||
|
||||
pub fn search(a: &str, options: Options) {
|
||||
search::repo_search(a, options);
|
||||
}
|
||||
|
||||
pub fn aur_install(a: Vec<String>, options: Options) {
|
||||
aur_install::aur_install(a, options);
|
||||
}
|
||||
|
||||
pub fn aur_search(a: &str, options: Options) {
|
||||
search::aur_search(a, options);
|
||||
}
|
||||
|
||||
pub fn upgrade(options: Options) {
|
||||
upgrade::upgrade(options);
|
||||
}
|
@ -0,0 +1,48 @@
|
||||
use std::process::Command;
|
||||
|
||||
use crate::{log, Options};
|
||||
use crate::internal::rpc::rpcsearch;
|
||||
|
||||
pub fn aur_search(a: &str, options: Options) {
|
||||
let verbosity = options.verbosity;
|
||||
let res = rpcsearch(a.to_string());
|
||||
|
||||
if verbosity >= 1 {
|
||||
log(format!(
|
||||
"Found {} resuls 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 {
|
||||
log(format!(
|
||||
"Found {} results for \"{}\" in repos",
|
||||
&str.split('\n').count() / 2,
|
||||
&a
|
||||
));
|
||||
}
|
||||
|
||||
print!("{}", str);
|
||||
}
|
@ -0,0 +1,45 @@
|
||||
use std::{env, fs};
|
||||
use std::path::Path;
|
||||
|
||||
use crate::{log, Options};
|
||||
|
||||
pub fn uninstall(mut a: Vec<String>, options: Options) {
|
||||
let b = a.clone();
|
||||
if options.noconfirm {
|
||||
a.push("--noconfirm".to_string());
|
||||
}
|
||||
let verbosity = options.verbosity;
|
||||
if verbosity >= 1 {
|
||||
log(format!("Uninstalling: {:?}", &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 {
|
||||
log(format!(
|
||||
"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 {
|
||||
log("Old cache directory found, deleting".to_string());
|
||||
}
|
||||
fs::remove_dir_all(Path::new(&format!(
|
||||
"{}/.cache/ame/{}",
|
||||
env::var("HOME").unwrap(),
|
||||
b
|
||||
)))
|
||||
.unwrap();
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,49 @@
|
||||
use runas::Command;
|
||||
|
||||
use crate::{info, log, Options};
|
||||
use crate::internal::rpc::rpcinfo;
|
||||
use crate::operations::aur_install::aur_install;
|
||||
|
||||
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 {
|
||||
log("Upgrading repo packages".to_string());
|
||||
}
|
||||
|
||||
Command::new("pacman")
|
||||
.args(&pacman_args)
|
||||
.status()
|
||||
.expect("Something has gone wrong");
|
||||
|
||||
if verbosity >= 1 {
|
||||
log("Upgrading AUR packages".to_string());
|
||||
}
|
||||
|
||||
let res = crate::database::query(options);
|
||||
|
||||
if verbosity >= 1 {
|
||||
log(format!("{:?}", &res));
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
if !aur_upgrades.is_empty() {
|
||||
aur_install(aur_upgrades, options);
|
||||
} else {
|
||||
info("No upgrades available for installed AUR packages".to_string());
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue