pub struct SelfUpdater { /* private fields */ }Expand description
Core self-update manager for AGPM binary upgrades.
SelfUpdater handles the entire process of checking for and installing AGPM updates
from GitHub releases. It provides a safe, reliable way to upgrade the running binary
with proper error handling and version management.
§Features
- GitHub Integration: Fetches releases from the official AGPM repository
- Version Comparison: Uses semantic versioning for intelligent update detection
- Force Updates: Allows forcing updates even when already on latest version
- Target Versions: Supports upgrading to specific versions or latest
- Progress Tracking: Shows download progress during updates
- Security: URL validation, path traversal protection, configurable checksum verification
§Safety
The updater itself only handles the download and binary replacement. For full
safety, it should be used in conjunction with BackupManager
to create backups before updates.
§Examples
§Check for Updates
use agpm_cli::upgrade::SelfUpdater;
let updater = SelfUpdater::new();
if let Some(latest_version) = updater.check_for_update().await? {
println!("Update available: {} -> {}",
updater.current_version(), latest_version);
} else {
println!("Already on latest version: {}", updater.current_version());
}§Update to Latest Version
use agpm_cli::upgrade::SelfUpdater;
let updater = SelfUpdater::new();
match updater.update_to_latest().await? {
true => println!("Successfully updated to latest version"),
false => println!("Already on latest version"),
}§Force Update with Required Checksums
use agpm_cli::upgrade::{SelfUpdater, ChecksumPolicy};
let updater = SelfUpdater::new()
.force(true)
.checksum_policy(ChecksumPolicy::Required);
// This will update even if already on the latest version
// and require checksum verification
updater.update_to_latest().await?;§Repository Configuration
By default, updates are fetched from aig787/agpm on GitHub. This is configured
in the Default implementation and targets the official AGPM repository.
§Error Handling
All methods return Result<T, anyhow::Error> for comprehensive error handling:
- Network errors during GitHub API calls
- Version parsing errors for invalid semver
- File system errors during binary replacement
- Permission errors on locked or protected files
- Security validation failures
Implementations§
Source§impl SelfUpdater
impl SelfUpdater
Sourcepub fn new() -> Self
pub fn new() -> Self
Create a new SelfUpdater with default settings.
This is equivalent to Default::default() but provides a more
conventional constructor-style interface.
§Examples
use agpm_cli::upgrade::SelfUpdater;
let updater = SelfUpdater::new();
assert_eq!(updater.current_version(), env!("CARGO_PKG_VERSION"));Sourcepub fn with_repo(repo_owner: &str, repo_name: &str) -> Result<Self>
pub fn with_repo(repo_owner: &str, repo_name: &str) -> Result<Self>
Create a new SelfUpdater with custom repository settings.
This constructor allows specifying a custom GitHub repository for updates, with security validation to prevent URL injection attacks.
§Arguments
repo_owner- GitHub repository owner (e.g., “aig787”)repo_name- GitHub repository name (e.g., “agpm”)
§Errors
Returns an error if the repository identifiers contain invalid characters that could be used for URL injection or other attacks.
§Examples
use agpm_cli::upgrade::SelfUpdater;
// Valid repository identifiers
let updater = SelfUpdater::with_repo("aig787", "agpm")?;
let custom = SelfUpdater::with_repo("my-org", "my_fork")?;
// This would fail due to invalid characters
// let bad = SelfUpdater::with_repo("../evil", "repo");Sourcepub const fn force(self, force: bool) -> Self
pub const fn force(self, force: bool) -> Self
Configure whether to force updates regardless of version comparison.
When force mode is enabled, the updater will attempt to download and install updates even if the current version is already the latest or newer than the target version.
§Use Cases
- Reinstalling: Fix corrupted binary installations
- Downgrading: Install older versions for compatibility
- Testing: Verify update mechanism functionality
- Recovery: Restore from problematic versions
§Arguments
force-trueto enable force mode,falseto respect version comparisons
§Examples
use agpm_cli::upgrade::SelfUpdater;
// Normal update (respects versions)
let updater = SelfUpdater::new();
// Force update (ignores version comparison)
let force_updater = SelfUpdater::new().force(true);Sourcepub const fn checksum_policy(self, policy: ChecksumPolicy) -> Self
pub const fn checksum_policy(self, policy: ChecksumPolicy) -> Self
Configure the checksum verification policy for downloads.
This setting controls how the updater handles checksum verification during binary downloads, allowing you to balance security with usability.
§Security Implications
- Required: Maximum security, but updates may fail if checksums are unavailable
WarnOnFailure: Good balance of security and usability (default)- Skip: Least secure, not recommended for production use
§Arguments
policy- The checksum verification policy to use
§Examples
use agpm_cli::upgrade::{SelfUpdater, ChecksumPolicy};
// Require checksum verification (most secure)
let secure_updater = SelfUpdater::new()
.checksum_policy(ChecksumPolicy::Required);
// Skip checksum verification (least secure)
let fast_updater = SelfUpdater::new()
.checksum_policy(ChecksumPolicy::Skip);Sourcepub fn current_version(&self) -> &str
pub fn current_version(&self) -> &str
Get the current version of the running AGPM binary.
This version is determined at compile time from the crate’s Cargo.toml
and represents the version of the currently executing binary.
§Returns
A string slice containing the semantic version (e.g., “0.3.14”).
§Examples
use agpm_cli::upgrade::SelfUpdater;
let updater = SelfUpdater::new();
println!("Current AGPM version: {}", updater.current_version());Sourcepub async fn check_for_update(&self) -> Result<Option<String>>
pub async fn check_for_update(&self) -> Result<Option<String>>
Check if a newer version is available on GitHub.
Queries the GitHub API to fetch the latest release information and compares it with the current version using semantic versioning rules. This method does not download or install anything.
§Returns
Ok(Some(version))- A newer version is availableOk(None)- Already on the latest version or no releases foundErr(error)- Network error, API failure, or version parsing error
§Errors
This method can fail if:
- Network connectivity issues prevent GitHub API access
- GitHub API rate limiting is exceeded
- Release version tags are not valid semantic versions
- Repository is not found or access is denied
§Examples
use agpm_cli::upgrade::SelfUpdater;
let updater = SelfUpdater::new();
match updater.check_for_update().await? {
Some(latest) => {
println!("Update available: {} -> {}",
updater.current_version(), latest);
}
None => {
println!("Already on latest version: {}",
updater.current_version());
}
}Sourcepub async fn update(&self, target_version: Option<&str>) -> Result<bool>
pub async fn update(&self, target_version: Option<&str>) -> Result<bool>
Update the AGPM binary to a specific version or latest.
Downloads and installs the specified version from GitHub releases, replacing the current binary. This is the core update method used by both version-specific and latest update operations.
§Arguments
target_version- Specific version to install (e.g., “0.4.0”), orNonefor latest
§Returns
Ok(true)- Successfully updated to the target versionOk(false)- Already on target version (no update needed)Err(error)- Update failed due to download, permission, or file system error
§Force Mode Behavior
When force mode is enabled via force():
- Bypasses version comparison checks
- Downloads and installs even if already on target version
- Useful for reinstalling or recovery scenarios
§Errors
This method can fail if:
- Network issues prevent downloading the release
- Insufficient permissions to replace the binary
- Target version doesn’t exist or has no binary assets
- File system errors during binary replacement
- The downloaded binary is corrupted or invalid
§Platform Considerations
- Windows: May require retries due to file locking
- Unix: Preserves executable permissions
- macOS: Works with both Intel and Apple Silicon binaries
§Examples
use agpm_cli::upgrade::SelfUpdater;
let updater = SelfUpdater::new();
// Update to latest version
if updater.update(None).await? {
println!("Successfully updated!");
} else {
println!("Already on latest version");
}
// Update to specific version
if updater.update(Some("0.4.0")).await? {
println!("Successfully updated to v0.4.0!");
}Sourcepub async fn update_to_latest(&self) -> Result<bool>
pub async fn update_to_latest(&self) -> Result<bool>
Update to the latest available version from GitHub releases.
This is a convenience method that calls update() with None
as the target version, instructing it to find and install the most recent release.
§Returns
Ok(true)- Successfully updated to a newer versionOk(false)- Already on the latest version (no update performed)Err(error)- Update failed (seeupdate()for error conditions)
§Examples
use agpm_cli::upgrade::SelfUpdater;
let updater = SelfUpdater::new();
match updater.update_to_latest().await? {
true => println!("Successfully updated to latest version!"),
false => println!("Already on the latest version"),
}§See Also
update_to_version()- Update to a specific versioncheck_for_update()- Check for updates without installing
Sourcepub async fn update_to_version(&self, version: &str) -> Result<bool>
pub async fn update_to_version(&self, version: &str) -> Result<bool>
Update to a specific version from GitHub releases.
Downloads and installs the specified version, regardless of whether it’s newer or older than the current version. The version string will be automatically prefixed with ‘v’ if not already present.
§Arguments
version- The target version string (e.g., “0.4.0” or “v0.4.0”)
§Returns
Ok(true)- Successfully updated to the specified versionOk(false)- Already on the specified version (no update needed)Err(error)- Update failed (seeupdate()for error conditions)
§Version Format
The version parameter accepts multiple formats:
"0.4.0"- Semantic version number"v0.4.0"- Version with ‘v’ prefix (GitHub tag format)"0.4.0-beta.1"- Pre-release versions
§Examples
use agpm_cli::upgrade::SelfUpdater;
let updater = SelfUpdater::new();
// Update to specific stable version
updater.update_to_version("0.4.0").await?;
// Update to pre-release version
updater.update_to_version("v0.5.0-beta.1").await?;
// Force downgrade to older version
let force_updater = updater.force(true);
force_updater.update_to_version("0.3.0").await?;§See Also
update_to_latest()- Update to the newest available versioncheck_for_update()- Check what version is available
Trait Implementations§
Source§impl Default for SelfUpdater
impl Default for SelfUpdater
Source§fn default() -> Self
fn default() -> Self
Create a new SelfUpdater with default configuration.
§Default Configuration
- Repository:
aig787/agpm(official AGPM repository) - Binary Name:
agpm - Current Version: Detected from build-time crate version
- Force Mode: Disabled (respects version comparisons)
§Examples
use agpm_cli::upgrade::SelfUpdater;
let updater = SelfUpdater::default();
println!("Current version: {}", updater.current_version());Auto Trait Implementations§
impl Freeze for SelfUpdater
impl RefUnwindSafe for SelfUpdater
impl Send for SelfUpdater
impl Sync for SelfUpdater
impl Unpin for SelfUpdater
impl UnwindSafe for SelfUpdater
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more