Compare commits

7 Commits

Author SHA1 Message Date
7587815818 version and pkgbuild bump 2024-08-04 22:59:26 +02:00
085debe43c refactor and choose install 2024-08-04 22:53:15 +02:00
f2f3997469 readme update 2024-07-24 19:51:08 +02:00
d3d1b38f7e pkgbuild 2024-07-24 19:38:44 +02:00
610f94d1d4 initial prototype complete 2024-07-24 19:29:18 +02:00
b11271cf82 package upgrade, refacror 2024-07-24 18:58:11 +02:00
0d0c544088 find package 2024-07-24 16:11:33 +02:00
16 changed files with 714 additions and 72 deletions

2
.gitignore vendored
View File

@@ -1 +1,3 @@
/target /target
*.tar.zst
/pkg

153
Cargo.lock generated
View File

@@ -4,16 +4,17 @@ version = 3
[[package]] [[package]]
name = "ah" name = "ah"
version = "0.1.0" version = "0.2.0"
dependencies = [ dependencies = [
"clap", "clap",
"colored",
] ]
[[package]] [[package]]
name = "anstream" name = "anstream"
version = "0.6.14" version = "0.6.15"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "418c75fa768af9c03be99d17643f93f79bbba589895012a80e3452a19ddda15b" checksum = "64e15c1ab1f89faffbf04a634d5e1962e9074f2741eef6d97f3c4e322426d526"
dependencies = [ dependencies = [
"anstyle", "anstyle",
"anstyle-parse", "anstyle-parse",
@@ -26,43 +27,43 @@ dependencies = [
[[package]] [[package]]
name = "anstyle" name = "anstyle"
version = "1.0.7" version = "1.0.8"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "038dfcf04a5feb68e9c60b21c9625a54c2c0616e79b72b0fd87075a056ae1d1b" checksum = "1bec1de6f59aedf83baf9ff929c98f2ad654b97c9510f4e70cf6f661d49fd5b1"
[[package]] [[package]]
name = "anstyle-parse" name = "anstyle-parse"
version = "0.2.4" version = "0.2.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c03a11a9034d92058ceb6ee011ce58af4a9bf61491aa7e1e59ecd24bd40d22d4" checksum = "eb47de1e80c2b463c735db5b217a0ddc39d612e7ac9e2e96a5aed1f57616c1cb"
dependencies = [ dependencies = [
"utf8parse", "utf8parse",
] ]
[[package]] [[package]]
name = "anstyle-query" name = "anstyle-query"
version = "1.1.0" version = "1.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ad186efb764318d35165f1758e7dcef3b10628e26d41a44bc5550652e6804391" checksum = "6d36fc52c7f6c869915e99412912f22093507da8d9e942ceaf66fe4b7c14422a"
dependencies = [ dependencies = [
"windows-sys", "windows-sys 0.52.0",
] ]
[[package]] [[package]]
name = "anstyle-wincon" name = "anstyle-wincon"
version = "3.0.3" version = "3.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "61a38449feb7068f52bb06c12759005cf459ee52bb4adc1d5a7c4322d716fb19" checksum = "5bf74e1b6e971609db8ca7a9ce79fd5768ab6ae46441c572e46cf596f59e57f8"
dependencies = [ dependencies = [
"anstyle", "anstyle",
"windows-sys", "windows-sys 0.52.0",
] ]
[[package]] [[package]]
name = "clap" name = "clap"
version = "4.5.10" version = "4.5.13"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f6b81fb3c84f5563d509c59b5a48d935f689e993afa90fe39047f05adef9142" checksum = "0fbb260a053428790f3de475e304ff84cdbc4face759ea7a3e64c1edd938a7fc"
dependencies = [ dependencies = [
"clap_builder", "clap_builder",
"clap_derive", "clap_derive",
@@ -70,9 +71,9 @@ dependencies = [
[[package]] [[package]]
name = "clap_builder" name = "clap_builder"
version = "4.5.10" version = "4.5.13"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5ca6706fd5224857d9ac5eb9355f6683563cc0541c7cd9d014043b57cbec78ac" checksum = "64b17d7ea74e9f833c7dbf2cbe4fb12ff26783eda4782a8975b72f895c9b4d99"
dependencies = [ dependencies = [
"anstream", "anstream",
"anstyle", "anstyle",
@@ -82,9 +83,9 @@ dependencies = [
[[package]] [[package]]
name = "clap_derive" name = "clap_derive"
version = "4.5.8" version = "4.5.13"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2bac35c6dafb060fd4d275d9a4ffae97917c13a6327903a8be2153cd964f7085" checksum = "501d359d5f3dcaf6ecdeee48833ae73ec6e42723a1e52419c79abf9507eec0a0"
dependencies = [ dependencies = [
"heck", "heck",
"proc-macro2", "proc-macro2",
@@ -94,15 +95,25 @@ dependencies = [
[[package]] [[package]]
name = "clap_lex" name = "clap_lex"
version = "0.7.1" version = "0.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4b82cf0babdbd58558212896d1a4272303a57bdb245c2bf1147185fb45640e70" checksum = "1462739cb27611015575c0c11df5df7601141071f07518d56fcc1be504cbec97"
[[package]] [[package]]
name = "colorchoice" name = "colorchoice"
version = "1.0.1" version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b6a852b24ab71dffc585bcb46eaf7959d175cb865a7152e35b348d1b2960422" checksum = "d3fd119d74b830634cea2a0f58bbd0d54540518a14397557951e79340abc28c0"
[[package]]
name = "colored"
version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cbf2150cce219b664a8a70df7a1f933836724b503f8a413af9365b4dcc4d90b8"
dependencies = [
"lazy_static",
"windows-sys 0.48.0",
]
[[package]] [[package]]
name = "heck" name = "heck"
@@ -112,9 +123,15 @@ checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
[[package]] [[package]]
name = "is_terminal_polyfill" name = "is_terminal_polyfill"
version = "1.70.0" version = "1.70.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f8478577c03552c21db0e2724ffb8986a5ce7af88107e6be5d2ee6e158c12800" checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf"
[[package]]
name = "lazy_static"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
[[package]] [[package]]
name = "proc-macro2" name = "proc-macro2"
@@ -142,9 +159,9 @@ checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
[[package]] [[package]]
name = "syn" name = "syn"
version = "2.0.71" version = "2.0.72"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b146dcf730474b4bcd16c311627b31ede9ab149045db4d6088b3becaea046462" checksum = "dc4b9b9bf2add8093d3f2c0204471e951b2285580335de42f9d2534f3ae7a8af"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
@@ -163,13 +180,37 @@ version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
[[package]]
name = "windows-sys"
version = "0.48.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9"
dependencies = [
"windows-targets 0.48.5",
]
[[package]] [[package]]
name = "windows-sys" name = "windows-sys"
version = "0.52.0" version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
dependencies = [ dependencies = [
"windows-targets", "windows-targets 0.52.6",
]
[[package]]
name = "windows-targets"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c"
dependencies = [
"windows_aarch64_gnullvm 0.48.5",
"windows_aarch64_msvc 0.48.5",
"windows_i686_gnu 0.48.5",
"windows_i686_msvc 0.48.5",
"windows_x86_64_gnu 0.48.5",
"windows_x86_64_gnullvm 0.48.5",
"windows_x86_64_msvc 0.48.5",
] ]
[[package]] [[package]]
@@ -178,28 +219,46 @@ version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
dependencies = [ dependencies = [
"windows_aarch64_gnullvm", "windows_aarch64_gnullvm 0.52.6",
"windows_aarch64_msvc", "windows_aarch64_msvc 0.52.6",
"windows_i686_gnu", "windows_i686_gnu 0.52.6",
"windows_i686_gnullvm", "windows_i686_gnullvm",
"windows_i686_msvc", "windows_i686_msvc 0.52.6",
"windows_x86_64_gnu", "windows_x86_64_gnu 0.52.6",
"windows_x86_64_gnullvm", "windows_x86_64_gnullvm 0.52.6",
"windows_x86_64_msvc", "windows_x86_64_msvc 0.52.6",
] ]
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8"
[[package]] [[package]]
name = "windows_aarch64_gnullvm" name = "windows_aarch64_gnullvm"
version = "0.52.6" version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
[[package]]
name = "windows_aarch64_msvc"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc"
[[package]] [[package]]
name = "windows_aarch64_msvc" name = "windows_aarch64_msvc"
version = "0.52.6" version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
[[package]]
name = "windows_i686_gnu"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e"
[[package]] [[package]]
name = "windows_i686_gnu" name = "windows_i686_gnu"
version = "0.52.6" version = "0.52.6"
@@ -212,24 +271,48 @@ version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
[[package]]
name = "windows_i686_msvc"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406"
[[package]] [[package]]
name = "windows_i686_msvc" name = "windows_i686_msvc"
version = "0.52.6" version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
[[package]]
name = "windows_x86_64_gnu"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e"
[[package]] [[package]]
name = "windows_x86_64_gnu" name = "windows_x86_64_gnu"
version = "0.52.6" version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc"
[[package]] [[package]]
name = "windows_x86_64_gnullvm" name = "windows_x86_64_gnullvm"
version = "0.52.6" version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
[[package]]
name = "windows_x86_64_msvc"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"
[[package]] [[package]]
name = "windows_x86_64_msvc" name = "windows_x86_64_msvc"
version = "0.52.6" version = "0.52.6"

View File

@@ -1,7 +1,17 @@
[package] [package]
name = "ah" name = "ah"
version = "0.1.0" version = "0.2.0"
authors = ["Michał Czyż <mike@c2yz.com>"]
edition = "2021" edition = "2021"
description = "A declarative package manager for Arch Linux"
homepage = "https://github.com/eRgo35/ah"
repository = "https://github.com/eRgo35/ah"
documentation = "https://github.com/eRgo35/ah"
license = "MIT"
keywords = ["archlinux", "declarative", "package", "aur", "paru"]
readme = "README.md"
[dependencies] [dependencies]
clap = { version = "4.5.10", features = ["derive"] } clap = { version = "4.5.10", features = ["derive"] }
colored = "2.1.0"

18
PKGBUILD Normal file
View File

@@ -0,0 +1,18 @@
# Maintainer: Michał Czyż <mike@c2yz.com>
pkgname=ah
pkgver=0.2.0
pkgrel=1
makedepends=('rust' 'cargo')
arch=('i686' 'x86_64' 'armv6h' 'armv7h')
pkgdesc="A declarative package manager for Arch Linux"
url="https://github.com/eRgo35/ah"
license=('MIT')
build() {
return 0
}
package() {
cd $srcdir
cargo install --root="$pkgdir" --git=https://github.com/eRgo35/ah
}

View File

@@ -1,9 +1,63 @@
# ah # ah
Yet another AUR helper A declarative package manager for Arch Linux
## What is ah? ## What is ah?
AH is a wrapper for paru that allows for declarative management of packages on your system. Arch Helper is a declarative package management tool for Arch Linux. It leverages paru or other package managers for seamless integration.
It is currently in early development phase so watch out for bugs! It is currently in early development phase so watch out for bugs!
## Installation
Install Rust :crab:
```sh
$ sudo pacman -S rustup
```
Initialize default stable
```sh
$ rustup default stable
```
Clone this repo
```sh
$ git clone https://github.com/eRgo35/ah
```
Change directory
```sh
$ cd ah
```
Install package
```sh
$ makepkg -si
```
## Usage
```txt
$ ah --help
Arch Helper is a declarative package management tool for Arch Linux. It leverages paru or other package managers for seamless integration.
Usage: ah [COMMAND]
Commands:
install Install packages
upgrade Upgrade packages
sync Synchronize packages
remove Remove packages
find Find packages
help Print this message or the help of the given subcommand(s)
Options:
-h, --help
Print help (see a summary with '-h')
-V, --version
Print version
```

53
src/cli.rs Normal file
View File

@@ -0,0 +1,53 @@
use clap::{Args, Parser, Subcommand};
#[derive(Parser)]
#[command(
name = "ah",
author = "Michał Czyż",
version = "0.1.0",
about = "A declarative package manager for Arch Linux",
long_about = "Arch Helper is a declarative package management tool for Arch Linux. It leverages paru or other package managers for seamless integration."
)]
pub struct Cli {
#[command(subcommand)]
pub command: Option<Commands>,
}
#[derive(Subcommand)]
pub enum Commands {
#[command(alias = "i", about = "Install packages")]
Install(PackageList),
#[command(alias = "u", about = "Upgrade packages")]
Upgrade {
#[arg(help = "Don't prompt for confirmation", default_value_t = false)]
noconfirm: bool,
},
#[command(alias = "s", about = "Synchronize packages")]
Sync {
#[arg(help = "Don't prompt for confirmation", default_value_t = false)]
noconfirm: bool,
},
#[command(alias = "r", about = "Remove packages")]
Remove(PackageList),
#[command(alias = "f", about = "Find packages")]
Find(Query),
#[command(alias = "fi", about = "Find and install packages")]
ChooseInstall(Query),
}
#[derive(Args)]
pub struct PackageList {
#[arg(help = "Name(s) of the package(s), separated by spaces")]
pub packages: Vec<String>,
}
#[derive(Args)]
pub struct Query {
#[arg(help = "Search term for finding packages")]
pub query: Vec<String>,
}

46
src/file.rs Normal file
View File

@@ -0,0 +1,46 @@
use std::{
fs::{File, OpenOptions},
io::{prelude::*, BufReader},
path::PathBuf,
};
// pub fn read_config(path: &str) -> Vec<String> {
// todo!();
// }
// pub fn write_config(path: &str, content: &str) {
// todo!();
// }
pub fn read_packages(path: PathBuf) -> Vec<String> {
let file = File::open(path).expect("Failed to open file");
let buf = BufReader::new(file);
buf.lines()
.map(|l| l.expect("Failed to read line"))
.collect()
}
pub fn append_package(path: PathBuf, package: &str) {
let mut file = OpenOptions::new()
.write(true)
.append(true)
.open(path)
.expect("Failed to open file");
if let Err(err) = writeln!(file, "{}", package) {
eprintln!("Couldn't write to file: {}", err);
}
}
pub fn write_packages(path: PathBuf, content: &str) {
let mut file = OpenOptions::new()
.write(true)
.truncate(true)
.open(path)
.expect("Failed to open file");
if let Err(err) = writeln!(file, "{}", content) {
eprintln!("Couldn't write to file: {}", err);
}
}

View File

@@ -1,40 +1,26 @@
use clap::{Command, Parser, Subcommand, Args}; use clap::Parser;
use cli::{PackageList, Query};
use colored::Colorize;
#[derive(Parser, Debug)] mod cli;
#[command(version, about, long_about = None)] mod file;
struct Cli { mod packages;
#[command(subcommand)]
pub command: Option<SubCommands>,
}
#[derive(Subcommand, Debug)]
enum SubCommands {
#[command(alias = "i")]
Install(PackageArg),
#[command(alias = "u")]
Upgrade {},
#[command(alias = "s")]
Sync {},
#[command(alias = "r")]
Remove(PackageArg),
#[command(alias = "f")]
Find(PackageArg),
}
#[derive(Args, Debug)]
struct PackageArg {
package: String,
}
fn main() { fn main() {
let cli = Cli::parse(); let cli = cli::Cli::parse();
match cli.command { let result = match cli.command {
Some(SubCommands::Install(arg)) => println!("Installing package: {}", arg.package), Some(cli::Commands::Install(PackageList { packages })) => packages::install(packages),
Some(SubCommands::Upgrade {}) => todo!(), Some(cli::Commands::Upgrade { noconfirm }) => packages::upgrade(noconfirm),
Some(SubCommands::Sync {}) => todo!(), Some(cli::Commands::Sync { noconfirm }) => packages::sync(noconfirm),
Some(SubCommands::Remove(arg)) => println!("Removing package: {}", arg.package), Some(cli::Commands::Remove(PackageList { packages })) => packages::remove(packages),
Some(SubCommands::Find(arg)) => println!("Looking for package: {}", arg.package), Some(cli::Commands::Find(Query { query })) => packages::find(query),
None => println!("No subcommand was used"), Some(cli::Commands::ChooseInstall(Query { query })) => packages::choose_install(query),
None => packages::upgrade(true),
};
if let Err(err) = result {
eprintln!("{} {}", "::".bold().red(), err.to_string().bold());
std::process::exit(1);
} }
} }

View File

@@ -0,0 +1,50 @@
use colored::Colorize;
use std::io::Write;
use std::process::{Command, Stdio};
use crate::packages::PACKAGE_MANAGER;
pub fn choose_install(query: Vec<String>) -> Result<(), Box<dyn std::error::Error>> {
println!(
"{} {}",
"::".bold().green(),
"Looking for package...".bold()
);
if query.is_empty() {
return Err("No query provided".into());
}
let mut child = Command::new(PACKAGE_MANAGER)
.arg("--color")
.arg("always")
.arg("s")
.arg("-")
.stdin(Stdio::piped())
.stdout(Stdio::inherit())
.stderr(Stdio::inherit())
.spawn()
.expect("Failed to execute command");
if let Some(mut stdin) = child.stdin.take() {
for word in query.clone() {
writeln!(stdin, "{}", word).unwrap();
}
}
let status = child.wait().expect("Failed to wait on child");
if !status.success() {
return Err("Failed to install packages".into());
}
println!("{} {}", "::".bold().green(), "Packages installed".bold());
println!(
"{} {}",
"::".bold().red(),
"Package index has not been updated!".bold()
);
Ok(())
}

28
src/packages/find.rs Normal file
View File

@@ -0,0 +1,28 @@
use colored::Colorize;
use std::process::Command;
use crate::packages::PACKAGE_MANAGER;
pub fn find(query: Vec<String>) -> Result<(), Box<dyn std::error::Error>> {
println!(
"{} {}",
"::".bold().green(),
"Looking for package...".bold()
);
if query.is_empty() {
return Err("No query provided".into());
}
let output = Command::new(PACKAGE_MANAGER)
.arg("--color")
.arg("always")
.arg("-Ss")
.args(query)
.output()
.expect("Failed to execute command");
print!("{}", String::from_utf8_lossy(&output.stdout));
Ok(())
}

60
src/packages/install.rs Normal file
View File

@@ -0,0 +1,60 @@
use crate::packages::PACKAGE_MANAGER;
use crate::{file, packages::get_package_path};
use colored::Colorize;
use std::io::Write;
use std::process::{Command, Stdio};
pub fn install(new_packages: Vec<String>) -> Result<(), Box<dyn std::error::Error>> {
println!(
"{} {}",
"::".bold().green(),
"Installing packages...".bold()
);
let packages = file::read_packages(get_package_path());
let packages = packages
.into_iter()
.filter(|p| !p.contains("#") && !p.is_empty())
.collect::<Vec<String>>();
let mut child = Command::new(PACKAGE_MANAGER)
.arg("--color")
.arg("always")
.arg("-S")
.arg("--needed")
.arg("-")
.stdin(Stdio::piped())
.stdout(Stdio::inherit())
.stderr(Stdio::inherit())
.spawn()
.expect("Failed to execute command");
if let Some(mut stdin) = child.stdin.take() {
for new_package in new_packages.clone() {
writeln!(stdin, "{}", new_package).unwrap();
}
}
let status = child.wait().expect("Failed to wait on child");
if !status.success() {
return Err("Failed to install packages".into());
}
println!("{} {}", "::".bold().green(), "Packages installed".bold());
println!(
"{} {}",
"::".bold().blue(),
"Updating package index...".bold()
);
for new_package in new_packages {
if !packages.contains(&new_package) {
file::append_package(get_package_path(), &new_package);
}
}
Ok(())
}

42
src/packages/mod.rs Normal file
View File

@@ -0,0 +1,42 @@
use colored::Colorize;
use std::io::{self, Write};
use std::path::PathBuf;
pub mod choose_install;
pub mod find;
pub mod install;
pub mod rebuild;
pub mod remove;
pub mod sync;
pub mod upgrade;
pub use choose_install::choose_install;
pub use find::find;
pub use install::install;
pub use rebuild::rebuild;
pub use remove::remove;
pub use sync::sync;
pub use upgrade::upgrade;
const PACKAGE_MANAGER: &str = "paru";
fn get_package_path() -> PathBuf {
let home_dir = std::env::var("HOME").unwrap();
PathBuf::from(home_dir).join("packages")
}
fn ask_confirmation() -> Result<bool, io::Error> {
print!(
"{} {}",
"::".bold().blue(),
"Do you want to continue? [Y/n] "
);
io::stdout().flush()?;
let mut input = String::new();
io::stdin().read_line(&mut input)?;
let input = input.trim().to_lowercase();
Ok(input.is_empty() || input == "y")
}

63
src/packages/rebuild.rs Normal file
View File

@@ -0,0 +1,63 @@
use colored::Colorize;
use std::io::Write;
use std::process::{Command, Stdio};
use crate::file;
use crate::packages::{ask_confirmation, get_package_path, PACKAGE_MANAGER};
pub fn rebuild(noconfirm: bool) -> Result<(), Box<dyn std::error::Error>> {
println!(
"{} {}",
"::".bold().green(),
"Upgrading & syncing packages...".bold()
);
if !ask_confirmation()? {
return Err("Operation aborted".into());
}
let packages = file::read_packages(get_package_path());
let packages = packages
.into_iter()
.filter(|p| !p.contains("#") && !p.is_empty())
.collect::<Vec<String>>();
let noconfirm = if noconfirm {
"--noconfirm"
} else {
"--confirm"
};
let mut child = Command::new(PACKAGE_MANAGER)
.arg("--color")
.arg("always")
.arg("-Syu")
.arg("--needed")
.arg(noconfirm)
.arg("-")
.stdin(Stdio::piped())
.stdout(Stdio::inherit())
.stderr(Stdio::inherit())
.spawn()
.expect("Failed to execute command");
if let Some(mut stdin) = child.stdin.take() {
for package in packages {
writeln!(stdin, "{}", package).unwrap();
}
}
let status = child.wait().expect("Failed to wait on child");
if !status.success() {
return Err("Failed to upgrade & sync packages".into());
}
println!(
"{} {}",
"::".bold().green(),
"Packages upgraded & synced".bold()
);
Ok(())
}

57
src/packages/remove.rs Normal file
View File

@@ -0,0 +1,57 @@
use crate::packages::PACKAGE_MANAGER;
use crate::{file, packages::get_package_path};
use colored::Colorize;
use std::io::Write;
use std::process::{Command, Stdio};
pub fn remove(unwanted_packages: Vec<String>) -> Result<(), Box<dyn std::error::Error>> {
println!("{} {}", "::".bold().green(), "Removing packages...".bold());
let packages = file::read_packages(get_package_path());
let mut packages = packages
.into_iter()
.filter(|p| !p.contains("#") && !p.is_empty())
.collect::<Vec<String>>();
let mut child = Command::new(PACKAGE_MANAGER)
.arg("--color")
.arg("always")
.arg("-R")
// .arg("--needed")
// .arg(noconfirm)
.arg("-")
.stdin(Stdio::piped())
.stdout(Stdio::inherit())
.stderr(Stdio::inherit())
.spawn()
.expect("Failed to execute command");
if let Some(mut stdin) = child.stdin.take() {
for unwanted_package in unwanted_packages.clone() {
writeln!(stdin, "{}", unwanted_package).unwrap();
}
}
let status = child.wait().expect("Failed to wait on child");
if !status.success() {
return Err("Failed to remove packages".into());
}
println!("{} {}", "::".bold().green(), "Packages removed".bold());
println!(
"{} {}",
"::".bold().blue(),
"Updating package index...".bold()
);
for unwanted_package in unwanted_packages {
packages.retain(|p| *p != unwanted_package);
}
file::write_packages(get_package_path(), &packages.join("\n"));
Ok(())
}

55
src/packages/sync.rs Normal file
View File

@@ -0,0 +1,55 @@
use colored::Colorize;
use std::io::Write;
use std::process::{Command, Stdio};
use crate::file;
use crate::packages::{ask_confirmation, get_package_path, PACKAGE_MANAGER};
pub fn sync(noconfirm: bool) -> Result<(), Box<dyn std::error::Error>> {
println!("{} {}", "::".bold().green(), "Syncing packages...".bold());
if !ask_confirmation()? {
return Err("Operation aborted".into());
}
let packages = file::read_packages(get_package_path());
let packages = packages
.into_iter()
.filter(|p| !p.contains("#") && !p.is_empty())
.collect::<Vec<String>>();
let noconfirm = if noconfirm {
"--noconfirm"
} else {
"--confirm"
};
let mut child = Command::new(PACKAGE_MANAGER)
.arg("--color")
.arg("always")
.arg("-S")
.arg("--needed")
.arg(noconfirm)
.arg("-")
.stdin(Stdio::piped())
.stdout(Stdio::inherit())
.stderr(Stdio::inherit())
.spawn()
.expect("Failed to execute command");
if let Some(mut stdin) = child.stdin.take() {
for package in packages {
writeln!(stdin, "{}", package).unwrap();
}
}
let status = child.wait().expect("Failed to wait on child");
if !status.success() {
return Err("Failed to sync packages".into());
}
println!("{} {}", "::".bold().green(), "Packages synced".bold());
Ok(())
}

35
src/packages/upgrade.rs Normal file
View File

@@ -0,0 +1,35 @@
use colored::Colorize;
use std::process::Command;
use crate::packages::{ask_confirmation, PACKAGE_MANAGER};
pub fn upgrade(noconfirm: bool) -> Result<(), Box<dyn std::error::Error>> {
println!("{} {}", "::".bold().green(), "Upgrading packages...".bold());
if !ask_confirmation()? {
return Err("Operation aborted".into());
}
let noconfirm = if noconfirm {
"--noconfirm"
} else {
"--confirm"
};
let mut child = Command::new(PACKAGE_MANAGER)
.arg("--color")
.arg("always")
.arg("-Syu")
.arg(noconfirm)
.spawn()
.expect("Failed to execute command");
let status = child.wait().expect("Failed to wait on child");
if !status.success() {
return Err("Failed to upgrade packages".into());
}
println!("{} {}", "::".bold().green(), "Packages upgraded".bold());
Ok(())
}