Compare commits

...

4 Commits

Author SHA1 Message Date
ef2134a00b Add cache cleaning (#13)
All checks were successful
Build on Release / cargo-build (push) Successful in 10s
Reviewed-on: #13

Increment Version
2024-04-30 18:40:32 -04:00
842dba73ac Add gitea workflow and new README 2024-04-30 18:40:32 -04:00
318820105f Update README.md 2024-04-30 18:39:54 -04:00
6e846fb6c0 Basic Stuff 2024-04-30 18:39:54 -04:00
8 changed files with 361 additions and 7 deletions

View File

@ -0,0 +1,22 @@
name: Build on Release
run-name: ${{ gitea.actor }}
on:
push:
branches:
- main
jobs:
cargo-build:
runs-on: ubuntu-latest-rust
steps:
- name: Check out code repository
uses: https://gitea.com/actions/checkout@v4
- name: Build Binary
run: |
cargo build --release
- name: Push binary to artifact
uses: https://gitea.com/actions/gitea-release-action@v1
with:
draft: true
files: |-
target/release/rust-archlinux-update

87
Cargo.lock generated
View File

@ -2,6 +2,91 @@
# It is not intended for manual editing. # It is not intended for manual editing.
version = 3 version = 3
[[package]]
name = "colored"
version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cbf2150cce219b664a8a70df7a1f933836724b503f8a413af9365b4dcc4d90b8"
dependencies = [
"lazy_static",
"windows-sys",
]
[[package]]
name = "lazy_static"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
[[package]] [[package]]
name = "rust-archlinux-update" name = "rust-archlinux-update"
version = "0.1.0" version = "0.1.1"
dependencies = [
"colored",
]
[[package]]
name = "windows-sys"
version = "0.48.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9"
dependencies = [
"windows-targets",
]
[[package]]
name = "windows-targets"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c"
dependencies = [
"windows_aarch64_gnullvm",
"windows_aarch64_msvc",
"windows_i686_gnu",
"windows_i686_msvc",
"windows_x86_64_gnu",
"windows_x86_64_gnullvm",
"windows_x86_64_msvc",
]
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8"
[[package]]
name = "windows_aarch64_msvc"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc"
[[package]]
name = "windows_i686_gnu"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e"
[[package]]
name = "windows_i686_msvc"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406"
[[package]]
name = "windows_x86_64_gnu"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc"
[[package]]
name = "windows_x86_64_msvc"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"

View File

@ -1,8 +1,10 @@
[package] [package]
name = "rust-archlinux-update" name = "rust-archlinux-update"
version = "0.1.0" version = "0.1.1"
edition = "2021" edition = "2021"
license = "GPL-3"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies] [dependencies]
colored = "2.1.0"

View File

@ -1,3 +1,32 @@
# Rust Arch Linux Updater # Rust Arch Linux Updater
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
The current state requires that you build it yourself. The most up-to-date version will be on the development branch.
Just run `cargo build --release` and copy the executable from `./target/release/rust-archlinux-update` to wherever you
need it.
Distribution on pre-built binaries, cargo, etc. is in the works.
## Usage
The default behavior of the command is to use pacman to run a package update, auto-removal, and cache clear in that
order.
In the future the command will support AUR helpers like paru and those will need to be activated with a flag.
## Issue Reporting
I don't allow random sign-ups on my gitea instance. Please email me at [luke@lukeh990.io](mailto:luke@lukeh990.io).
If you have any suggestions for how to better handle issue reporting please email me.
## Contributing
If you are the one person to read this and want to copy the source and work on it please follow the GPLv3 license.
If you decide to contribute back email me, and we'll figure out the best way for you to contribute.

View File

@ -6,12 +6,67 @@
You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>. You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
fn main() -> Result<(), Box<dyn std::error::Error>> { /*
main.rs
This file contains the primary logic of the application
*/
use colored::{ColoredString, Colorize};
use wrappers::pacman;
mod shell_commands;
mod wrappers;
fn main() {
println!("{}", copyright_notice()); println!("{}", copyright_notice());
Ok(()) if let Err(e) = pacman::check() {
error_println(e.to_string());
return;
} else {
notice_println("Pacman is installed\n")
}
notice_println("Running pacman update");
if let Err(e) = pacman::update_all() {
error_println(e.to_string());
return;
}
notice_println("Getting orphaned packages");
let result = match pacman::get_unused() {
Ok(result) => result,
Err(e) => {
error_println(e.to_string());
return;
}
};
if result.is_empty() {
println!("No Orphaned Packages Found.")
} else if let Err(e) = pacman::remove_unused(result) {
error_println(e.to_string());
return;
}
notice_println("Clearing Cache");
if let Err(e) = pacman::clean_cache() {
error_println(e.to_string());
return;
}
notice_println("\nUpdate process complete!");
} }
fn copyright_notice() -> &'static str { 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" "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>) {
eprintln!("{}", msg.into().red().bold())
}
pub fn notice_println(msg: impl Into<String>) {
println!("{}", msg.into().green().bold())
} }

40
src/shell_commands.rs Normal file
View File

@ -0,0 +1,40 @@
/*
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/>.
*/
/*
shell_commands.rs
This file contains utility functions to interact with the shell.
*/
use std::ffi::OsStr;
use std::io;
use std::process::{Command, ExitStatus, Output};
pub fn execute_and_display<S: AsRef<OsStr>, I>(cmd: S, args: I) -> io::Result<ExitStatus>
where
I: IntoIterator,
I::Item: AsRef<OsStr>,
{
let mut child = Command::new(cmd).args(args).spawn()?;
let exit_status = child.wait()?;
Ok(exit_status)
}
pub fn execute_in_sh(cmd: impl Into<String>) -> io::Result<ExitStatus> {
execute_and_display("sh", ["-c", &cmd.into()])
}
pub fn execute_quiet<S: AsRef<OsStr>, I>(cmd: S, args: I) -> io::Result<Output>
where
I: IntoIterator,
I::Item: AsRef<OsStr>,
{
Command::new(cmd).args(args).output()
}

14
src/wrappers/mod.rs Normal file
View File

@ -0,0 +1,14 @@
/*
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/mod.rs
Just makes pacman accessible
*/
pub mod pacman;

107
src/wrappers/pacman.rs Normal file
View File

@ -0,0 +1,107 @@
/*
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/pacman.rs
This module provides a wrapper to make working with Pacman 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 PacmanError {
NotInstalled,
ExitCode(i32),
Other(&'static str),
}
impl fmt::Display for PacmanError {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
let out = match self {
PacmanError::NotInstalled => "Pacman not installed.".to_string(),
PacmanError::ExitCode(code) => format!("Pacman exited with an exit code: {}", code),
PacmanError::Other(msg) => msg.to_string(),
};
write!(f, "PacmanError: {}", out)
}
}
impl error::Error for PacmanError {}
pub fn check() -> Result<()> {
let out = shell_commands::execute_quiet("which", ["pacman"])?;
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/pacman")
};
let path = Path::new(&path);
if !path.exists() {
return Err(PacmanError::NotInstalled.into());
}
Ok(())
}
pub fn update_all() -> Result<()> {
let exit_status = shell_commands::execute_in_sh("sudo pacman -Syu")?;
check_exit_code(exit_status)
}
pub fn get_unused() -> Result<Vec<String>> {
let out = shell_commands::execute_quiet("pacman", ["-Qtdq"])?;
let result = String::from_utf8(out.stdout)?;
let pkgs_to_remove: Vec<String> = result.lines().map(|x| x.to_string()).collect();
Ok(pkgs_to_remove)
}
pub fn remove_unused(packages: Vec<String>) -> Result<()> {
let package_string = packages.join(" ");
let command = format!("sudo pacman -Rns {}", package_string);
let exit_status = shell_commands::execute_in_sh(command)?;
check_exit_code(exit_status)
}
pub fn clean_cache() -> Result<()> {
let exit_status = shell_commands::execute_in_sh("sudo pacman -Scc")?;
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(PacmanError::Other("No Exit Code Found").into()),
};
return Err(PacmanError::ExitCode(exit_code).into());
}
Ok(())
}