|
| 1 | +# appimageupdate |
| 2 | + |
| 3 | +A Rust implementation of AppImageUpdate - a tool for updating AppImages using efficient delta updates. |
| 4 | + |
| 5 | +## Features |
| 6 | + |
| 7 | +- **Delta Updates** - Only download the changed portions of the AppImage, saving bandwidth and time |
| 8 | +- **Decentralized** - No central repository required; updates come directly from the source |
| 9 | +- **Checksum Verification** - SHA1 verification ensures downloaded files are valid |
| 10 | +- **Permission Preservation** - Maintains executable permissions from the original AppImage |
| 11 | +- **Skip Unnecessary Updates** - Automatically skips update if the target file already exists with the correct checksum |
| 12 | + |
| 13 | +## Installation |
| 14 | + |
| 15 | +### From Source |
| 16 | + |
| 17 | +```bash |
| 18 | +git clone https://github.com/qaidvoid/appimageupdate.git |
| 19 | +cd appimageupdate |
| 20 | +cargo install --path . |
| 21 | +``` |
| 22 | + |
| 23 | +## Usage |
| 24 | + |
| 25 | +### Update an AppImage |
| 26 | + |
| 27 | +```bash |
| 28 | +appimageupdate update ./myapp.AppImage |
| 29 | +``` |
| 30 | + |
| 31 | +Output: |
| 32 | +``` |
| 33 | +Source: ./myapp.AppImage (85.3 MB) |
| 34 | +Target: ./myapp-2.0.AppImage (92.1 MB) |
| 35 | +
|
| 36 | +Performing delta update... |
| 37 | +
|
| 38 | +Reused: 42.1 MB (1247 blocks) |
| 39 | +Downloaded: 50.0 MB (1482 blocks) |
| 40 | +Saved: 42.1 MB (45%) |
| 41 | +
|
| 42 | +Updated: ./myapp-2.0.AppImage |
| 43 | +``` |
| 44 | + |
| 45 | +### Check for Updates |
| 46 | + |
| 47 | +```bash |
| 48 | +appimageupdate check ./myapp.AppImage |
| 49 | +``` |
| 50 | + |
| 51 | +Output: |
| 52 | +``` |
| 53 | +Source: ./myapp.AppImage (85.3 MB) |
| 54 | +Target: ./myapp-2.0.AppImage (92.1 MB) |
| 55 | +
|
| 56 | +Status: Update available |
| 57 | +``` |
| 58 | + |
| 59 | +### Options |
| 60 | + |
| 61 | +``` |
| 62 | +appimageupdate update [OPTIONS] <APPIMAGE> |
| 63 | +
|
| 64 | +Arguments: |
| 65 | + <APPIMAGE> Path to the AppImage to update |
| 66 | +
|
| 67 | +Options: |
| 68 | + -o, --output <DIR> Output directory for the updated AppImage |
| 69 | + -w, --overwrite Overwrite existing target file |
| 70 | + -h, --help Print help |
| 71 | +``` |
| 72 | + |
| 73 | +## How It Works |
| 74 | + |
| 75 | +1. **Reads Update Information** - Extracts embedded update info from the AppImage's `.upd-info` ELF section |
| 76 | +2. **Fetches Zsync Metadata** - Downloads the `.zsync` control file which contains block checksums and file metadata |
| 77 | +3. **Calculates Delta** - Compares local file blocks against remote blocks using rolling checksums |
| 78 | +4. **Downloads Only Changes** - Fetches only the blocks that differ from the local copy |
| 79 | +5. **Assembles & Verifies** - Reconstructs the file and verifies SHA1 checksum |
| 80 | + |
| 81 | +## Supported Update Formats |
| 82 | + |
| 83 | +- `zsync|<url>` - Direct zsync URL |
| 84 | +- `gh-releases-zsync|<user>|<repo>|<tag>|<filename>` - GitHub releases with glob pattern matching |
| 85 | + |
| 86 | +## Comparison with Upstream |
| 87 | + |
| 88 | +This is a Rust rewrite of the upstream [AppImageUpdate](https://github.com/AppImage/AppImageUpdate) (C++/Qt). |
| 89 | + |
| 90 | +Advantages: |
| 91 | +- Single binary with no runtime dependencies |
| 92 | +- Cleaner, more maintainable codebase |
| 93 | +- URL caching to avoid redundant API calls |
| 94 | +- Better error messages |
| 95 | + |
| 96 | +Differences: |
| 97 | +- No GPG signature verification (not implemented) |
| 98 | +- No pling integration (not implemented) |
| 99 | + |
| 100 | +## Library Usage |
| 101 | + |
| 102 | +```rust |
| 103 | +use appimageupdate::{Updater, Error}; |
| 104 | + |
| 105 | +fn main() -> Result<(), Error> { |
| 106 | + let updater = Updater::new("./myapp.AppImage")?; |
| 107 | + |
| 108 | + if updater.check_for_update()? { |
| 109 | + let (path, stats) = updater.perform_update()?; |
| 110 | + println!("Updated to: {}", path.display()); |
| 111 | + println!("Saved {}% bandwidth", stats.saved_percentage()); |
| 112 | + } else { |
| 113 | + println!("Already up to date!"); |
| 114 | + } |
| 115 | + |
| 116 | + Ok(()) |
| 117 | +} |
| 118 | +``` |
0 commit comments