agpm_cli/upgrade/
mod.rs

1//! Self-update functionality for AGPM.
2//!
3//! This module provides comprehensive self-update capabilities for the AGPM binary,
4//! allowing users to upgrade to newer versions directly from the command line.
5//! The implementation follows safety-first principles with automatic backups,
6//! rollback capabilities, and robust error handling.
7//!
8//! # Architecture Overview
9//!
10//! The upgrade system consists of four main components working together:
11//!
12//! ## Core Components
13//!
14//! - **[`SelfUpdater`]**: The main updater that handles GitHub release fetching and binary replacement
15//! - **[`backup::BackupManager`]**: Creates and manages backups of the current binary before upgrades
16//! - **[`VersionChecker`]**: Provides version comparison and caching for update checks
17//! - **[`config::UpgradeConfig`]**: Configuration options for controlling upgrade behavior
18//!
19//! ## Update Process Flow
20//!
21//! ```text
22//! 1. Version Check
23//!    ├── Check cache for recent version info
24//!    └── Fetch latest release from GitHub if needed
25//!
26//! 2. Backup Creation (unless --no-backup)
27//!    ├── Copy current binary to .backup file
28//!    └── Preserve file permissions on Unix systems
29//!
30//! 3. Binary Update
31//!    ├── Download new binary from GitHub releases
32//!    ├── Verify download integrity
33//!    └── Replace current binary atomically
34//!
35//! 4. Post-Update
36//!    ├── Clear version cache
37//!    ├── Clean up backup on success
38//!    └── Restore from backup on failure
39//! ```
40//!
41//! # Safety Mechanisms
42//!
43//! The upgrade system implements multiple safety mechanisms:
44//!
45//! ## Automatic Backups
46//! - Creates backups before any binary modification
47//! - Preserves file permissions and metadata
48//! - Automatic restoration on upgrade failure
49//! - Manual rollback capability via `--rollback` flag
50//!
51//! ## Robust Error Handling
52//! - Validates downloads before replacement
53//! - Atomic file operations where possible
54//! - Graceful degradation on permission issues
55//! - Detailed error messages for troubleshooting
56//!
57//! ## Cross-Platform Compatibility
58//! - Handles Windows file locking issues with retry logic
59//! - Preserves Unix executable permissions
60//! - Works with various file system layouts
61//! - Supports different installation methods
62//!
63//! # Security Considerations
64//!
65//! The upgrade system includes several security measures:
66//!
67//! - **Verified Downloads**: All downloads are verified against expected checksums
68//! - **GitHub Integration**: Only downloads from official GitHub releases
69//! - **Permission Preservation**: Maintains original file permissions and ownership
70//! - **Atomic Operations**: Minimizes windows of vulnerability during updates
71//!
72//! # Usage Patterns
73//!
74//! ## Basic Update Check
75//! ```bash
76//! agpm upgrade --check          # Check for updates without installing
77//! agpm upgrade --status         # Show current and latest versions
78//! ```
79//!
80//! ## Safe Upgrade
81//! ```bash
82//! agpm upgrade                  # Upgrade to latest with automatic backup
83//! agpm upgrade v0.4.0          # Upgrade to specific version
84//! ```
85//!
86//! ## Advanced Options
87//! ```bash
88//! agpm upgrade --force          # Force upgrade even if on latest
89//! agpm upgrade --no-backup      # Skip backup creation (not recommended)
90//! agpm upgrade --rollback       # Restore from backup
91//! ```
92//!
93//! # Module Structure
94//!
95//! Each submodule has a specific responsibility:
96//!
97//! - [`self_updater`]: Core update logic and GitHub integration
98//! - [`backup`]: Backup creation, restoration, and management
99//! - [`version_check`]: Version comparison and caching
100//! - [`config`]: Configuration structures and defaults
101//!
102//! # Error Handling
103//!
104//! All functions return `Result<T, E>` for proper error propagation:
105//!
106//! ```rust,no_run
107//! use agpm_cli::upgrade::SelfUpdater;
108//!
109//! # async fn example() -> anyhow::Result<()> {
110//! let updater = SelfUpdater::new();
111//! match updater.update_to_latest().await {
112//!     Ok(true) => println!("Updated successfully"),
113//!     Ok(false) => println!("Already on latest version"),
114//!     Err(e) => eprintln!("Update failed: {}", e),
115//! }
116//! # Ok(())
117//! # }
118//! ```
119//!
120//! # Implementation Notes
121//!
122//! - Direct GitHub API integration for fetching releases
123//! - Implements async/await for non-blocking operations
124//! - Supports semver version parsing and comparison
125//! - Includes comprehensive logging for debugging
126//! - Designed for minimal external dependencies
127
128/// Backup management for AGPM binary upgrades.
129///
130/// The backup module provides functionality to create, manage, and restore backups
131/// of the AGPM binary during upgrade operations. This ensures safe upgrades with
132/// the ability to rollback if issues occur.
133pub mod backup;
134/// Configuration structures for upgrade behavior.
135///
136/// Defines configuration options that control how AGPM handles self-updates,
137/// including backup settings, version checking preferences, and security options.
138pub mod config;
139/// Core self-update implementation.
140///
141/// Contains the main `SelfUpdater` struct that handles downloading and installing
142/// AGPM updates from GitHub releases with proper version management and safety checks.
143pub mod self_updater;
144/// Download verification and integrity checking.
145///
146/// Provides checksum verification and integrity validation for downloaded
147/// AGPM binaries to ensure secure and reliable upgrades.
148pub mod verification;
149/// Version checking and comparison utilities.
150///
151/// Handles checking for available AGPM updates, comparing versions, and
152/// maintaining update check caches to avoid unnecessary network requests.
153pub mod version_check;
154
155#[cfg(test)]
156mod tests;
157
158pub use self_updater::{ChecksumPolicy, SelfUpdater};
159pub use verification::ChecksumVerifier;
160pub use version_check::VersionChecker;