diff --git a/.vscode/topgrade.code-snippets b/.vscode/topgrade.code-snippets index 40af7213..c10c3d33 100644 --- a/.vscode/topgrade.code-snippets +++ b/.vscode/topgrade.code-snippets @@ -32,6 +32,14 @@ "}" ] }, + "Require Binary": { + "scope": "rust", + "prefix": "req", + "description": "Require a binary to be installed", + "body": [ + "let ${1:binary} = require(\"${1:binary}\")?;" + ] + }, "macos": { "scope": "rust", "prefix": "macos", diff --git a/src/config.rs b/src/config.rs index a211e6b2..46b51fcd 100644 --- a/src/config.rs +++ b/src/config.rs @@ -124,6 +124,7 @@ pub enum Step { Sheldon, Shell, Snap, + Sparkle, Spicetify, Stack, System, diff --git a/src/main.rs b/src/main.rs index 97987239..88d0f605 100644 --- a/src/main.rs +++ b/src/main.rs @@ -386,6 +386,7 @@ fn run() -> Result<()> { #[cfg(target_os = "macos")] { + runner.execute(Step::Sparkle, "Sparkle", || macos::run_sparkle(&ctx))?; runner.execute(Step::Mas, "App Store", || macos::run_mas(run_type))?; runner.execute(Step::System, "System upgrade", || macos::upgrade_macos(&ctx))?; } diff --git a/src/steps/os/macos.rs b/src/steps/os/macos.rs index d5cb36b7..14c7e281 100644 --- a/src/steps/os/macos.rs +++ b/src/steps/os/macos.rs @@ -1,9 +1,10 @@ use crate::execution_context::ExecutionContext; -use crate::executor::RunType; +use crate::executor::{CommandExt, RunType}; use crate::terminal::{print_separator, prompt_yesno}; use crate::{error::TopgradeError, utils::require, Step}; use anyhow::Result; use log::debug; +use std::fs; use std::process::Command; pub fn run_macports(ctx: &ExecutionContext) -> Result<()> { @@ -72,3 +73,23 @@ fn system_update_available() -> Result { debug!("{:?}", string_output); Ok(!string_output.contains("No new software available")) } + +pub fn run_sparkle(ctx: &ExecutionContext) -> Result<()> { + let sparkle = require("sparkle")?; + + print_separator("Sparkle"); + + for application in (fs::read_dir("/Applications")?).flatten() { + let probe = Command::new(&sparkle) + .args(&["--probe", "--application"]) + .arg(application.path()) + .check_output(); + if probe.is_ok() { + let mut command = ctx.run_type().execute(&sparkle); + command.args(&["bundle", "--check-immediately", "--application"]); + command.arg(application.path()); + command.spawn()?.wait()?; + } + } + Ok(()) +}