refactor: migrate self-update to the update-rs crate#1885
Merged
Conversation
Replace the hand-rolled `src/update/` module (the three-phase download/replace/relaunch state machine, GitHub source, retrying filesystem and process launcher) with the external `update-rs` crate, which was extracted from this project. The whole module becomes a 22-line `src/update.rs` that just configures the updater for Git-Tool's releases. - Cargo.toml: depend on `update-rs` 0.3 with the `opentelemetry` feature. The shared `human-errors`, `opentelemetry` and `tracing-opentelemetry` versions unify with the existing telemetry stack, so `update_rs::Error` is our `engine::Error` (no conversion) and the global trace propagator is shared across the three update processes. - src/update.rs: `manager()` builds a `GitHubSource` for `SierraSoftworks/git-tool` using the Go-style `git-tool-<os>-<arch>[.exe]` asset naming (`naming::go`) and the `v` tag prefix — unchanged from before. - main.rs: detect the resume flag by scanning argv at the top of `host()` (before clap) and hand off to `resume_from_arg`. This stays compatible with older binaries that relaunch with a trailing `update --state` sub-command, and lets the updater continue the distributed trace carried in the state. Removes the legacy rewrite branch and the `--update-resume-internal` arg. - commands/update.rs: drop the internal `--state` flag (resume now lives in main); select/install via the crate's `Release`/`get_variant`. The `--list` formatting moves to a pure `format_release_list` helper with a network-independent unit test (replacing the old live-GitHub test). - commands/open.rs: the passive update check uses the new manager. Trace-context propagation across the update phases is now handled natively by update-rs (inside the serialized state), so the bespoke `--trace-context` relaunch wiring is gone. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #1885 +/- ##
==========================================
+ Coverage 89.66% 90.07% +0.40%
==========================================
Files 107 102 -5
Lines 9307 8653 -654
==========================================
- Hits 8345 7794 -551
+ Misses 962 859 -103
🚀 New features to boost your workflow:
|
Adopt update-rs 0.4's customizable launcher to restore Git-Tool's original relaunch convention: a `GitToolLauncher` (overriding `resume_args`) relaunches the binary as `gt update --state <json>` rather than with the library's default `--update-resume-internal` flag. This keeps resume handling in the `update` command (parsed by clap, and unit-testable) instead of an argv pre-scan in `main`. - Cargo.toml: update-rs 0.3 -> 0.4. - src/update.rs: install `GitToolLauncher` on the manager. - commands/update.rs: re-add the hidden `--state` arg; `run` resumes from it via `resume_from_arg`. Add a (network-free) test that resume failures bubble up without being reported to Sentry by the command. - main.rs: drop the argv pre-scan; keep `--update-resume-internal` as a tolerated hidden global so clap still accepts the relaunch emitted by currently-installed releases (which pass `--update-resume-internal <s> --trace-context <c> update --state <s>`) — the `update --state` sub-command drives the resume. The trace context still rides inside the serialized state (update-rs's `opentelemetry` feature), so the relaunch needs no `--trace-context` argument. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Now that update-rs 0.4.1 exposes `GitHubSource::with_client`, build a reqwest client carrying Git-Tool's `User-Agent` (`Git-Tool/<version>`) and pass it to the updater, so self-update requests are attributed to Git-Tool and pick up its client configuration rather than update-rs's generic default client. `http_client` is a single place to grow that configuration (proxy, timeouts, ...) later. Bumps the dependency to update-rs 0.4.1. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Instead of the updater constructing its own reqwest client, hand it Git-Tool's central one. `update::manager` now takes `&Core` and passes `core.http_client().reqwest_client()` to update-rs, so self-update requests share Git-Tool's client configuration and connection pool. To make that possible the central `TrueHttpClient` now owns a single reqwest client (built once, with a default `Git-Tool/<version>` User-Agent) rather than creating one per request, and the `HttpClient` trait exposes it via `reqwest_client()`. Call sites that set a per-request User-Agent (the GitHub registry/service) still override the default, so their behaviour is unchanged. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Replaces the hand-rolled
src/update/self-update module with the externalupdate-rscrate (0.4.0) — which was extracted from this project. The ~1,400-line module collapses to a smallsrc/update.rsplus the dependency, with no change to thegt updateUX or the Go-style release asset naming, and keeping Git-Tool's originalupdate --staterelaunch convention.What changed
Cargo.toml—update-rs = { version = "0.4", features = ["opentelemetry"] }. The sharedhuman-errors 0.2.3,opentelemetry 0.32andtracing-opentelemetry 0.33all unify to single versions with the existingtracing-batteriesstack, soupdate_rs::Erroris ourengine::Error(no conversion) and the global trace propagator is shared across the three update processes.src/update.rs—manager()builds aGitHubSourceforSierraSoftworks/git-tool(naming::go("git-tool")→git-tool-<os>-<arch>[.exe],vtag prefix) and installs aGitToolLauncherthat relaunches viagt update --state <json>(overriding update-rs'sresume_args).commands/update.rs— the hidden--statearg drives resume (resume_from_arg); list/select/rollback go through the crate'sRelease/get_variant. The--listformatting is a pureformat_release_listhelper, and resume is covered by a network-free test (resume failures bubble up without the command reporting to Sentry).main.rs— no argv scanning.--update-resume-internalis kept as a tolerated hidden global so clap still accepts relaunches emitted by currently-installed releases (--update-resume-internal <s> --trace-context <c> update --state <s>); theupdate --statesub-command drives the resume.commands/open.rs— the passive "update available" check uses the new manager.Telemetry & trace continuity
Trace-context propagation across the three update phases is handled natively by update-rs (the context rides inside the serialized update state), so no
--trace-contextargument is needed on the relaunch. update-rs emits its own#[instrument]spans for the update (itsopentelemetryfeature), which flow into the existing tracing → Honeycomb pipeline. The previous test-onlyGITHUB_TOKENinjection is no longer needed: production was already unauthenticated (no regression), and the update path's only mandatory-network test is now a pure unit test.Verification
cargo test --features pure-tests→ 226 passed, 27 ignored; the new resume test and the list-formatting test are network-free.commands::open::tests::run(live update check) passes and correctly reports the latest release.gt update --listagainst real GitHub lists releases with correct markers.gt update --state '{"phase":"no-update"}'exits 0, and the legacy--update-resume-internal <s> --trace-context <c> update --state <s>form (what installed v3.11 binaries emit) is tolerated and resumes via the sub-command — so in-flight cross-version updates keep working.cargo fmt --checkclean; no new clippy warnings.Recommended before release: a manual end-to-end three-phase update on each OS (e.g.
gt update v3.11.0to roll back, thengt updateto roll forward) to exercise download → replace → cleanup and confirm no UAC prompt on Windows.🤖 Generated with Claude Code