How Arnis Detects and Reports Available Software Updates on Startup: Version Checking Explained
The Arnis binary performs a synchronous version check on startup by downloading the remote Cargo.toml from GitHub, parsing its version field, and comparing it against the locally compiled version using semantic versioning rules.
When the Arnis terrain generator initializes, it executes a lightweight version checking feature to determine if a newer release is available. This process runs before any heavy computational work begins, ensuring users are immediately notified of updates without impacting the application's core functionality.
How the Version Checking Feature Works on Startup
Triggering the Check in main.rs
The version detection sequence begins immediately after the application banner displays. In src/main.rs at lines 84-91, the main entry point invokes version_check::check_for_updates() and gracefully handles any errors that bubble up from the network stack.
// From src/main.rs
match version_check::check_for_updates() {
Ok(true) => println!("Update available"),
Ok(false) => println!("Running latest version"),
Err(e) => eprintln!("Version check failed: {}", e),
}
Fetching the Remote Cargo.toml
The check_for_updates() function in src/version_check.rs creates a blocking reqwest::Client at line 14 to perform a synchronous HTTP request. The client retrieves the raw Cargo.toml file from the canonical repository URL with a custom User-Agent header identifying the Arnis client.
// From src/version_check.rs:L16-L20
let client = reqwest::blocking::Client::new();
let response = client
.get("https://raw.githubusercontent.com/louis-e/arnis/main/Cargo.toml")
.header("User-Agent", "arnis-version-checker")
.send()?;
Parsing and Comparing Versions
Once the HTTP response returns successfully, the system extracts the version string through a multi-step validation process. The extract_version_from_cargo_toml function scans the downloaded TOML content for lines beginning with version, parsing the semantic version string using the semver crate.
The local version is determined at compile time using the env!("CARGO_PKG_VERSION") macro, ensuring the binary always reports the exact version it was built from without requiring runtime configuration files.
// From src/version_check.rs:L30-L44
let remote_version = extract_version_from_cargo_toml(&response.text()?)?;
let local_version = semver::Version::parse(env!("CARGO_PKG_VERSION"))?;
if remote_version > local_version {
println!("A new version is available: {} → {}",
local_version, remote_version);
return Ok(true);
}
Ok(false)
Error Handling and Graceful Degradation
The version checking feature implements comprehensive error handling to ensure network failures never prevent the application from running. The handle_http_error function at lines 22-28 catches non-2xx status codes and prints a friendly message before returning Ok(false) to indicate no update is available.
Network timeouts and connection errors are captured by handle_request_error at lines 48-52, which logs a concise message and treats the situation as if the user is running the latest version. This graceful degradation ensures that users behind firewalls or without internet access can continue using Arnis without interruption.
Implementation Details in version_check.rs
The src/version_check.rs module encapsulates all update detection logic. Developers can manually trigger version checks or integrate the functionality into custom scripts using the public API.
Manual Version Check Example
use arnis::version_check;
fn main() {
match version_check::check_for_updates() {
Ok(true) => println!("Update available – see the banner above."),
Ok(false) => println!("You are already on the latest version."),
Err(e) => eprintln!("Failed to check for updates: {}", e),
}
}
The function returns Result<bool, Box<dyn Error>>, where true indicates a newer release exists on GitHub.
Parsing Remote Versions Directly
For testing or custom implementations, the version extraction logic can be used independently without performing network requests.
use std::error::Error;
use arnis::version_check::extract_version_from_cargo_toml;
fn main() -> Result<(), Box<dyn Error>> {
let cargo_toml = std::fs::read_to_string("Cargo.toml")?;
let remote = extract_version_from_cargo_toml(&cargo_toml)?;
println!("Remote version: {}", remote);
Ok(())
}
This approach is useful for validating parsing logic against local TOML files before deploying network-dependent code.
Key Files and Functions
The version checking feature spans three primary locations in the Arnis codebase:
-
src/version_check.rs– Implements the full update-checking flow including the network request, TOML parsing, semantic version comparison, and error handling. View source -
src/main.rs– Invokescheck_for_updates()at program startup (lines 84-91) and displays any errors to the console. View source -
Cargo.toml(repository root) – Contains the canonical version string that the remote check reads to determine if updates are available. View source
Summary
- Arnis detects software updates by comparing the local binary version against the remote
Cargo.tomlhosted on GitHub. - The check runs synchronously in
main.rsbefore heavy operations begin, using a blockingreqwestclient to fetchhttps://raw.githubusercontent.com/louis-e/arnis/main/Cargo.toml. extract_version_from_cargo_tomlparses the semantic version from the remote TOML, whileenv!("CARGO_PKG_VERSION")provides the compile-time local version.- The system uses graceful degradation: network failures, HTTP errors, or parsing issues result in
Ok(false), allowing the application to continue uninterrupted. - When
remote_version > local_version, a colored console message notifies users of the available update.
Frequently Asked Questions
How does Arnis handle network failures during the version check?
Arnis treats all network failures as non-fatal events. The handle_request_error function catches timeouts and connection errors, logs a concise message, and returns Ok(false) to indicate no update is available. This ensures users behind corporate firewalls or offline can continue using the terrain generator without interruption.
Where does Arnis look to find the latest version number?
The application fetches the raw Cargo.toml file directly from the GitHub repository at https://raw.githubusercontent.com/louis-e/arnis/main/Cargo.toml. It parses the version field from this file to determine the latest release, comparing it against the local version compiled into the binary via env!("CARGO_PKG_VERSION").
Can I disable the automatic version check when starting Arnis?
Currently, the version check is hardcoded in src/main.rs and runs automatically on every startup. There is no configuration flag to disable it in the current implementation. However, because the check uses graceful degradation and returns immediately on network errors, it adds minimal overhead and never blocks execution for more than a few seconds.
What happens if the remote Cargo.toml contains an invalid version string?
If extract_version_from_cargo_toml cannot find a line starting with version or fails to parse the semantic version string, the function returns an error. This error propagates up to the caller in main.rs, where it is caught and logged. The application treats this as a failed check and continues execution assuming no update is available, preventing malformed remote files from crashing the program.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →