Finish features for 1.0
Add option parsing Add AUR update with paru Update README Update Cargo.toml
This commit is contained in:
parent
9215820374
commit
05de93b988
2
Cargo.lock
generated
2
Cargo.lock
generated
@ -20,7 +20,7 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rust-archlinux-update"
|
name = "rust-archlinux-update"
|
||||||
version = "0.1.1"
|
version = "1.0.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"colored",
|
"colored",
|
||||||
]
|
]
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "rust-archlinux-update"
|
name = "rust-archlinux-update"
|
||||||
version = "0.1.1"
|
version = "1.0.0"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
license = "GPL-3"
|
license = "GPL-3"
|
||||||
|
|
||||||
|
35
README.md
35
README.md
@ -2,27 +2,42 @@
|
|||||||
|
|
||||||
A program that automates the arch update process with cleanup and auto removal.
|
A program that automates the arch update process with cleanup and auto removal.
|
||||||
|
|
||||||
***Currently, a WIP. USE AT OWN RISK***
|
|
||||||
|
|
||||||
## Setup
|
## Setup
|
||||||
|
|
||||||
The current state requires that you build it yourself. The most up-to-date version will be on the development branch.
|
Download the binary from the releases tab. The pre-compiled binary works on x86_64 only.
|
||||||
|
|
||||||
Just run `cargo build --release` and copy the executable from `./target/release/rust-archlinux-update` to wherever you
|
Recommended Installation:
|
||||||
need it.
|
|
||||||
|
|
||||||
Distribution on pre-built binaries, cargo, etc. is in the works.
|
1. Place the binary in the `~/local/bin` folder
|
||||||
|
2. Run `chmod +x` on the binary
|
||||||
|
3. Add `/home/<USER>/local/bin` to your PATH variable
|
||||||
|
|
||||||
|
This installation allows it to be run anywhere on your system.
|
||||||
|
|
||||||
|
If you need a different target please see the next section on compilation.
|
||||||
|
|
||||||
|
## Compilation
|
||||||
|
|
||||||
|
It's simple.
|
||||||
|
|
||||||
|
Steps:
|
||||||
|
|
||||||
|
1. Download the source code. (git clone or release tarball)
|
||||||
|
2. Ensure that rustup is up-to-date and has the correct toolchain installed and selected.
|
||||||
|
3. Run `cargo build --release` and find the binary at `./target/release/rust-archlinux-update`
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
The default behavior of the command is to use pacman to run a package update, auto-removal, and cache clear in that
|
rust-archlinux-updater [OPTIONS]
|
||||||
order.
|
|
||||||
|
|
||||||
In the future the command will support AUR helpers like paru and those will need to be activated with a flag.
|
Options:
|
||||||
|
-h, --help | Show this help message
|
||||||
|
-u | preform a regular update
|
||||||
|
-p | Use paru to update the AUR packages on your system
|
||||||
|
|
||||||
## Issue Reporting
|
## Issue Reporting
|
||||||
|
|
||||||
I don't allow random sign-ups on my gitea instance. Please email me at [luke@lukeh990.io](mailto:luke@lukeh990.io).
|
I don't allow random sign-ups on my gitea instance. Please email me at <luke@lukeh990.io>.
|
||||||
|
|
||||||
If you have any suggestions for how to better handle issue reporting please email me.
|
If you have any suggestions for how to better handle issue reporting please email me.
|
||||||
|
|
||||||
|
120
src/main.rs
120
src/main.rs
@ -11,33 +11,142 @@
|
|||||||
This file contains the primary logic of the application
|
This file contains the primary logic of the application
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
use std::{env, error};
|
||||||
|
|
||||||
use colored::{ColoredString, Colorize};
|
use colored::{ColoredString, Colorize};
|
||||||
|
|
||||||
use wrappers::pacman;
|
use wrappers::pacman;
|
||||||
|
|
||||||
|
use crate::wrappers::paru;
|
||||||
|
|
||||||
mod shell_commands;
|
mod shell_commands;
|
||||||
mod wrappers;
|
mod wrappers;
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
struct RunOptions {
|
||||||
|
pub help: bool,
|
||||||
|
pub update: bool,
|
||||||
|
pub paru: bool,
|
||||||
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
println!("{}", copyright_notice());
|
println!("{}", copyright_notice());
|
||||||
|
|
||||||
update();
|
match get_run_options() {
|
||||||
|
Ok(options) => {
|
||||||
|
if options.help {
|
||||||
|
print_help_text();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if options.update {
|
||||||
|
update(options.paru);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
print_help_text();
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
error_println("Failed to detect arguments.");
|
||||||
|
eprintln!("{}", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update() {
|
fn get_run_options() -> Result<RunOptions, Box<dyn error::Error>> {
|
||||||
|
let mut args = env::args();
|
||||||
|
|
||||||
|
// Remove unneeded first entry
|
||||||
|
if args.next().is_none() {
|
||||||
|
return Err("No args found".into());
|
||||||
|
}
|
||||||
|
|
||||||
|
let args: Vec<String> = args.collect();
|
||||||
|
|
||||||
|
let blank_options = RunOptions {
|
||||||
|
help: false,
|
||||||
|
update: false,
|
||||||
|
paru: false,
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut options = blank_options.clone();
|
||||||
|
|
||||||
|
if args.is_empty() {
|
||||||
|
return Ok(blank_options);
|
||||||
|
}
|
||||||
|
|
||||||
|
for arg in args {
|
||||||
|
if arg[..2].eq("--") {
|
||||||
|
let flag = &arg[2..];
|
||||||
|
if flag.eq("help") {
|
||||||
|
options.help = true;
|
||||||
|
} else {
|
||||||
|
return Ok(blank_options);
|
||||||
|
}
|
||||||
|
} else if arg[..1].eq("-") {
|
||||||
|
let mut selected: Vec<&str> = arg[1..].split("").collect();
|
||||||
|
|
||||||
|
selected.retain_mut(|x| !x.is_empty());
|
||||||
|
|
||||||
|
for selected_option in selected {
|
||||||
|
match selected_option {
|
||||||
|
"h" => options.help = true,
|
||||||
|
"u" => options.update = true,
|
||||||
|
"p" => options.paru = true,
|
||||||
|
_ => return Ok(blank_options),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return Ok(blank_options);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(options)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn print_help_text() {
|
||||||
|
println!(
|
||||||
|
"rust-archlinux-updater [OPTIONS]\n\n\
|
||||||
|
Options:\n\
|
||||||
|
-h, --help | Show this help message\n\
|
||||||
|
-u | preform a regular update\n\
|
||||||
|
-p | Use paru to update the AUR packages on your system"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn update(paru: bool) {
|
||||||
if let Err(e) = pacman::check() {
|
if let Err(e) = pacman::check() {
|
||||||
error_println(e.to_string());
|
error_println(e.to_string());
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
notice_println("Pacman is installed\n")
|
notice_println("Pacman is installed")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if paru {
|
||||||
|
if let Err(e) = paru::check() {
|
||||||
|
error_println(e.to_string());
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
notice_println("Paru is installed")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
println!();
|
||||||
|
|
||||||
notice_println("Running pacman update");
|
notice_println("Running pacman update");
|
||||||
if let Err(e) = pacman::update_all() {
|
if let Err(e) = pacman::update_all() {
|
||||||
error_println(e.to_string());
|
error_println(e.to_string());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if paru {
|
||||||
|
notice_println("Updating AUR with paru");
|
||||||
|
if let Err(e) = paru::update_aur() {
|
||||||
|
error_println(e.to_string());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
notice_println("Getting orphaned packages");
|
notice_println("Getting orphaned packages");
|
||||||
let result = match pacman::get_unused() {
|
let result = match pacman::get_unused() {
|
||||||
Ok(result) => result,
|
Ok(result) => result,
|
||||||
@ -64,7 +173,10 @@ fn update() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn copyright_notice() -> ColoredString {
|
fn copyright_notice() -> ColoredString {
|
||||||
"Rust Arch Linux Updater Copyright (C) 2024 Luke Harding <luke@lukeh990.io>\nThis program comes with ABSOLUTELY NO WARRANTY\nThis is free software, and you are welcome to redistribute it under certain conditions\n".italic()
|
"Rust Arch Linux Updater Copyright (C) 2024 Luke Harding <luke@lukeh990.io>\
|
||||||
|
\nThis program comes with ABSOLUTELY NO WARRANTY\
|
||||||
|
\nThis is free software, and you are welcome to redistribute it under certain conditions\n"
|
||||||
|
.italic()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn error_println(msg: impl Into<String>) {
|
pub fn error_println(msg: impl Into<String>) {
|
||||||
|
@ -12,3 +12,4 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
pub mod pacman;
|
pub mod pacman;
|
||||||
|
pub mod paru;
|
||||||
|
82
src/wrappers/paru.rs
Normal file
82
src/wrappers/paru.rs
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
/*
|
||||||
|
Rust Arch Linux Updater
|
||||||
|
Copyright (C) 2024 Luke Harding <luke@lukeh990.io>
|
||||||
|
This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
||||||
|
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||||
|
You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
wrappers/paru.rs
|
||||||
|
This module provides a wrapper to make working with paru much easier.
|
||||||
|
*/
|
||||||
|
|
||||||
|
use std::{error, fmt, result};
|
||||||
|
use std::fmt::Formatter;
|
||||||
|
use std::path::Path;
|
||||||
|
use std::process::ExitStatus;
|
||||||
|
|
||||||
|
use crate::shell_commands;
|
||||||
|
|
||||||
|
type Result<T> = result::Result<T, Box<dyn error::Error>>;
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
enum ParuError {
|
||||||
|
NotInstalled,
|
||||||
|
ExitCode(i32),
|
||||||
|
Other(&'static str),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl fmt::Display for ParuError {
|
||||||
|
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
|
||||||
|
let out = match self {
|
||||||
|
ParuError::NotInstalled => "Paru not installed.".to_string(),
|
||||||
|
ParuError::ExitCode(code) => format!("Paru exited with an exit code: {}", code),
|
||||||
|
ParuError::Other(msg) => msg.to_string(),
|
||||||
|
};
|
||||||
|
|
||||||
|
write!(f, "ParuError: {}", out)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl error::Error for ParuError {}
|
||||||
|
|
||||||
|
pub fn check() -> Result<()> {
|
||||||
|
let out = shell_commands::execute_quiet("which", ["paru"])?;
|
||||||
|
|
||||||
|
let path = if out.status.success() {
|
||||||
|
let mut stdout = out.stdout;
|
||||||
|
stdout.pop(); // Remove \n from stdout
|
||||||
|
|
||||||
|
String::from_utf8(stdout)?
|
||||||
|
} else {
|
||||||
|
String::from("/usr/bin/paru")
|
||||||
|
};
|
||||||
|
|
||||||
|
let path = Path::new(&path);
|
||||||
|
|
||||||
|
if !path.exists() {
|
||||||
|
return Err(ParuError::NotInstalled.into());
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn update_aur() -> Result<()> {
|
||||||
|
let exit_status = shell_commands::execute_in_sh("paru -Sua")?;
|
||||||
|
|
||||||
|
check_exit_code(exit_status)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn check_exit_code(exit_status: ExitStatus) -> Result<()> {
|
||||||
|
if !exit_status.success() {
|
||||||
|
let exit_code = match exit_status.code() {
|
||||||
|
Some(exit_code) => exit_code,
|
||||||
|
None => return Err(ParuError::Other("No Exit Code Found").into()),
|
||||||
|
};
|
||||||
|
|
||||||
|
return Err(ParuError::ExitCode(exit_code).into());
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user