mirror of
https://github.com/zyllian/pupdate.git
synced 2025-01-17 19:22:42 -08:00
configurable package managers, add pacman/yay support
This commit is contained in:
parent
405cf3aba8
commit
caa0cf6799
1 changed files with 111 additions and 47 deletions
114
src/main.rs
114
src/main.rs
|
@ -40,6 +40,41 @@ struct Config {
|
|||
/// the directory to log to, no logs if missing
|
||||
#[serde(default)]
|
||||
log_dir: Option<PathBuf>,
|
||||
/// the package managers to pupdate the local system with
|
||||
#[serde(default)]
|
||||
package_managers: Vec<PackageManager>,
|
||||
}
|
||||
|
||||
/// enum for supported package managers
|
||||
#[derive(Debug, Deserialize)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
enum PackageManager {
|
||||
AptGet,
|
||||
Homebrew,
|
||||
Pacman,
|
||||
Yay,
|
||||
}
|
||||
|
||||
impl PackageManager {
|
||||
/// gets the packaage manager's name
|
||||
pub fn get_name(&self) -> &'static str {
|
||||
match self {
|
||||
Self::AptGet => "apt-get",
|
||||
Self::Homebrew => "homebrew",
|
||||
Self::Pacman => "pacman",
|
||||
Self::Yay => "yay",
|
||||
}
|
||||
}
|
||||
|
||||
/// pupdates the local system
|
||||
pub async fn pupdate(&self, log_dir: Option<PathBuf>) -> eyre::Result<bool> {
|
||||
match self {
|
||||
Self::AptGet => pupdate_apt(log_dir).await,
|
||||
Self::Homebrew => pupdate_homebrew(log_dir).await,
|
||||
Self::Pacman => pupdate_pacman(log_dir).await,
|
||||
Self::Yay => pupdate_yay(log_dir).await,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// pupdates a remote target through ssh
|
||||
|
@ -77,14 +112,11 @@ async fn pupdate_remote(
|
|||
Ok((remote, success))
|
||||
}
|
||||
|
||||
/// helper for pupdates which both follow the "X update && X upgrade" set of commands (e.g. apt-get and brew)
|
||||
async fn update_and_upgrade(
|
||||
/// helper for writing log files from multiple processes
|
||||
async fn log_helper(
|
||||
outputs: &[std::process::Output],
|
||||
log_dir: Option<PathBuf>,
|
||||
command: &str,
|
||||
with_sudo: bool,
|
||||
yes: bool,
|
||||
) -> eyre::Result<bool> {
|
||||
async fn log(outputs: &[std::process::Output], log_dir: Option<PathBuf>) -> eyre::Result<bool> {
|
||||
if let Some(log_dir) = log_dir {
|
||||
let mut stdout = File::create(log_dir.join("local.stdout.log")).await?;
|
||||
let mut stderr = File::create(log_dir.join("local.stderr.log")).await?;
|
||||
|
@ -101,7 +133,8 @@ async fn update_and_upgrade(
|
|||
Ok(true)
|
||||
}
|
||||
|
||||
fn command_with_sudo(command: &str, with_sudo: bool) -> Command {
|
||||
/// helper to prefix a command with sudo if requested
|
||||
fn command_maybe_with_sudo(command: &str, with_sudo: bool) -> Command {
|
||||
if with_sudo {
|
||||
let mut cmd = Command::new("sudo");
|
||||
cmd.arg(command);
|
||||
|
@ -111,20 +144,27 @@ async fn update_and_upgrade(
|
|||
}
|
||||
}
|
||||
|
||||
let update_output = command_with_sudo(command, with_sudo)
|
||||
/// helper for pupdates which both follow the "X update && X upgrade" set of commands (e.g. apt-get and brew)
|
||||
async fn update_and_upgrade(
|
||||
log_dir: Option<PathBuf>,
|
||||
command: &str,
|
||||
with_sudo: bool,
|
||||
yes: bool,
|
||||
) -> eyre::Result<bool> {
|
||||
let update_output = command_maybe_with_sudo(command, with_sudo)
|
||||
.arg("update")
|
||||
.output()
|
||||
.await?;
|
||||
if !update_output.status.success() {
|
||||
return log(&[update_output], log_dir).await;
|
||||
return log_helper(&[update_output], log_dir).await;
|
||||
}
|
||||
let mut upgrade_command = command_with_sudo(command, with_sudo);
|
||||
let mut upgrade_command = command_maybe_with_sudo(command, with_sudo);
|
||||
upgrade_command.arg("upgrade");
|
||||
if yes {
|
||||
upgrade_command.arg("-y");
|
||||
}
|
||||
let upgrade_output = upgrade_command.output().await?;
|
||||
log(&[update_output, upgrade_output], log_dir).await
|
||||
log_helper(&[update_output, upgrade_output], log_dir).await
|
||||
}
|
||||
|
||||
/// pupdates the local system using apt-get
|
||||
|
@ -137,6 +177,32 @@ async fn pupdate_homebrew(log_dir: Option<PathBuf>) -> eyre::Result<bool> {
|
|||
update_and_upgrade(log_dir, "brew", false, false).await
|
||||
}
|
||||
|
||||
/// helper for pupdates which follow the pacman-style command format
|
||||
async fn syu(
|
||||
log_dir: Option<PathBuf>,
|
||||
command: &str,
|
||||
with_sudo: bool,
|
||||
yes: bool,
|
||||
) -> eyre::Result<bool> {
|
||||
let mut command = command_maybe_with_sudo(command, with_sudo);
|
||||
command.arg("-Syu");
|
||||
if yes {
|
||||
command.arg("--noconfirm");
|
||||
}
|
||||
let output = command.output().await?;
|
||||
log_helper(&[output], log_dir).await
|
||||
}
|
||||
|
||||
/// pupdates the local system using pacman
|
||||
async fn pupdate_pacman(log_dir: Option<PathBuf>) -> eyre::Result<bool> {
|
||||
syu(log_dir, "pacman", true, true).await
|
||||
}
|
||||
|
||||
/// pupdates the local system using yay
|
||||
async fn pupdate_yay(log_dir: Option<PathBuf>) -> eyre::Result<bool> {
|
||||
syu(log_dir, "yay", false, true).await
|
||||
}
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() -> eyre::Result<()> {
|
||||
let args = Args::parse();
|
||||
|
@ -147,9 +213,13 @@ async fn main() -> eyre::Result<()> {
|
|||
};
|
||||
let config_path = args.config.or(base_config_path);
|
||||
let config: Config = if let Some(config) = config_path {
|
||||
if config.exists() {
|
||||
serde_json::from_str(&std::fs::read_to_string(config)?)?
|
||||
} else {
|
||||
Config::default()
|
||||
}
|
||||
} else {
|
||||
Config::default()
|
||||
};
|
||||
|
||||
let log_dir = args.log_dir.or(config.log_dir).map(|log_dir| {
|
||||
|
@ -223,19 +293,15 @@ async fn main() -> eyre::Result<()> {
|
|||
|
||||
if !args.skip_local {
|
||||
println!("running local pupdates, you may be pawmpted for your password");
|
||||
|
||||
if config.package_managers.is_empty() {
|
||||
eprintln!("no package managers defined in config, skipping local pupdates");
|
||||
}
|
||||
|
||||
for package_manager in config.package_managers {
|
||||
println!("pupdating with {}", package_manager.get_name());
|
||||
let start = OffsetDateTime::now_utc();
|
||||
let result = if cfg!(target_os = "linux") {
|
||||
println!("pupdating with apt-get...");
|
||||
Some(pupdate_apt(log_dir).await)
|
||||
} else if cfg!(target_os = "macos") {
|
||||
println!("pupdating with brew...");
|
||||
Some(pupdate_homebrew(log_dir).await)
|
||||
} else {
|
||||
eprintln!("unsupported operating system for local pupdates, skipping");
|
||||
None
|
||||
};
|
||||
if let Some(result) = result {
|
||||
result?;
|
||||
package_manager.pupdate(log_dir.clone()).await?;
|
||||
let end = OffsetDateTime::now_utc();
|
||||
let duration = end - start;
|
||||
|
||||
|
@ -243,8 +309,6 @@ async fn main() -> eyre::Result<()> {
|
|||
"successfully pupdated the local system in {} seconds",
|
||||
duration.whole_seconds()
|
||||
);
|
||||
} else {
|
||||
println!("failed to pupdate the local system");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue