Identify which CLI an upgrade warning is about - #2670
Conversation
There was a problem hiding this comment.
🟡 Not ready to approve
Doctor can report false installation mismatches, omit single-install details, and hang on unresponsive executables.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
This review doesn't count toward merge requirements. Sign up for the private preview to control whether Copilot approvals count.
Pull request overview
Improves upgrade diagnostics for systems with multiple Stellar CLI installations.
Changes:
- Identifies the executable responsible for upgrade warnings and cache writes.
- Expands
doctordiagnostics to inspect PATH installations. - Adds request and shutdown timeouts for background upgrade checks.
File summaries
| File | Description |
|---|---|
cmd/soroban-cli/src/upgrade_check.rs |
Adds executable identification, cache attribution, and fetch timeout. |
cmd/soroban-cli/src/config/upgrade_check.rs |
Persists the cache writer with backward compatibility. |
cmd/soroban-cli/src/commands/doctor.rs |
Reports installations and cache-writer mismatches. |
cmd/soroban-cli/src/cli.rs |
Gives background checks a completion grace period. |
Review details
Suppressed comments (1)
cmd/soroban-cli/src/commands/doctor.rs:242
- The usual single-install case returns before printing the executable's path and version, so
doctordoes not actually list every PATH installation as promised. The zero-match case is also reported as “Only one.” Always enumerate nonempty results and handle zero separately.
if installs.len() <= 1 {
print.checkln("Only one Stellar CLI found on PATH".to_string());
return;
- Files reviewed: 4/4 changed files
- Comments generated: 3
- Review effort level: Balanced
We're testing this review assessment. Please use 👍 or 👎 to tell us if it's correct.
There was a problem hiding this comment.
🟡 Changes recommended
Some installation listings and cache-writer diagnostics are incomplete or misleading.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
This review doesn't count toward merge requirements. Sign up for the private preview to control whether Copilot approvals count.
Review details
Suppressed comments (3)
cmd/soroban-cli/src/upgrade_check.rs:140
- This assigns
last_checked_byafter a failed request without refreshing either cached version, butdoctorlater tells users the cache was “last refreshed by” this executable. That can falsely attribute version data to an install that never fetched it. Keep this assignment if the intended identity is the last writer/pacer, but update the field documentation and alldoctormessages to say “last checked/written by”; alternatively, record this field only after successful refreshes.
// A failed attempt still paces the next one, so record who
// paced it -- otherwise the file credits whichever install
// last succeeded, which may not be the one holding it back.
stats.last_checked_by = Some(check_performed_by());
cmd/soroban-cli/src/commands/doctor.rs:264
- The single-install branch does not call
list_installs, sodoctoromits that executable's PATH location and version. This contradicts the PR's stated behavior of listing every discoveredstellar/sorobanexecutable with its version; the separate “Running executable” line is not necessarily the PATH entry and has no version.
(1, _) => print.checkln("Only one Stellar CLI found on PATH".to_string()),
cmd/soroban-cli/src/commands/doctor.rs:277
common_version == Nonealso means one or more probes returnedNone, not necessarily that known versions differ. For example, two executables that cannot run are both listed as “unknown version” while this branch claims they reported different versions. Distinguish probe failures from genuinely distinct known versions so the diagnostic does not give a false cause.
(count, None) => {
print.warnln(format!(
"Found {count} Stellar CLI executables on PATH reporting different versions; \
an outdated one can report a version that disagrees with `stellar --version`:"
));
- Files reviewed: 6/6 changed files
- Comments generated: 0 new
- Review effort level: Balanced
We're testing this review assessment. Please use 👍 or 👎 to tell us if it's correct.
What: name the running executable in the upgrade warning; have `doctor` list every `stellar`/`soroban` on PATH with its version, and report which CLI last refreshed the shared version cache. Bound the crates.io request and give the background check a grace period to persist its result. Why: the warning only prints when the latest version exceeds the running one, so a stale cache cannot produce the output in stellar#2464 -- a 25.2.0 binary with a 25.1.0 cache prints nothing. `current_version` is `env!("CARGO_PKG_VERSION")`, so an older install reports its own version while looking like it speaks for the CLI the user thinks they run. The release dates agree: 22.1.0 predates the report by 15 months. Separately, returning from `main` dropped a still-running check, so a fast command never persisted the versions it had just fetched. Known limitations: the grace period is skipped on the error paths that call `process::exit`, and it can add up to 2s to the first command of the day, when the check actually goes to the network. Cache-writer reporting is diagnostic only -- no decision keys off it, so files written before the field existed behave exactly as before. Co-authored-by: Nearx-Labs <nearxlabs@nearx.com.br>
What: record the version-cache writer as separate version and executable fields, canonicalize the executable on both write and read, and compare only the path. Warn about several executables on PATH when their versions disagree rather than when there is more than one, and report finding none. Why: the writer was a single `"<version> (<executable>)"` string, so an in-place upgrade -- same path, new version -- read as a different install; the cache is only rewritten once a day, so that warning could repeat on every `doctor` run for up to 24h. The count was misleading in the same way: this crate ships both `stellar` and `soroban`, so one ordinary install puts two files on PATH and was warned about. Zero executables fell into the same branch and reported "Only one Stellar CLI found on PATH". Same path with an earlier version is now informational rather than a warning: it is the ordinary state after an upgrade, and it corrects itself at the next refresh. When either path is unknown there is no identity to compare, so the writer is reported without claiming a match either way. Co-authored-by: Nearx-Labs <nearxlabs@nearx.com.br>
What: add `soroban-test` integration coverage for zero, one, two agreeing and two disagreeing Stellar CLIs on PATH, and for cache writers that are this install, this install at an earlier version, a different install, and absent. Why: the externally visible behavior was covered only by parser unit tests, so nothing exercised the subprocess probing or the messages themselves -- both false positives fixed in the previous commit would have been caught here. PATH comes from fake CLIs in a temp dir, as in `plugin.rs`, and the version cache from `STELLAR_DATA_HOME`, so no production code had to change to make the inputs injectable. One fake rejects `version --only-version` so the `--version` banner fallback runs through a real subprocess. Unix only: the fake CLIs are shell scripts needing an execute bit. Assertions are on stderr, where `Print` writes. The seeded cache writer survives the run because `doctor` reads it before `has_available_upgrade` can overwrite it. Co-authored-by: Nearx-Labs <nearxlabs@nearx.com.br>
Motivation: Copilot's review of stellar#2670 found three `doctor` diagnostics claiming more than the data behind them supports, each able to send a user after a cause that was never observed. Behavior: - A check whose fetch failed still stamps the cache, but leaves the recorded versions untouched, so "last refreshed by" credited an install with version data it never fetched. Say "checked" instead, in the messages and the field docs: the writer paces the next check rather than vouching for the versions stored beside it. Recording it only after a successful fetch was the alternative, and it hides the install worth finding -- a stale one whose fetch fails still suppresses everyone else's check for a day. - The single-install branch printed a count without the listing, so the one case a listing would settle was the one case that omitted path and version. List every discovered install. - Absent agreement was reported as disagreement: two executables that cannot be run are both unknown, yet the message blamed differing versions. `InstalledVersions` now keeps Agreed, Disagree and Unanswered apart. An observed disagreement still wins over a failed probe alongside it, because that one is a fact. Tests: four unit cases for `summarize_versions`, and two integration cases driving real subprocesses through a fake `PATH` -- two unrunnable CLIs, and a disagreement sitting next to an unreadable binary. The lone-install listing and the reworded cache-writer lines are asserted too. Release impact: no breaking change and no migration. The `upgrade_check.json` shape is untouched and older files still load. Only `doctor`'s stderr wording changes -- no command, flag or help text does, so `FULL_HELP_DOCS.md` stands as is. Co-authored-by: Nearx-Labs <nearxlabs@nearx.com.br>
What problem does your feature solve?
The upgrade warning displays incorrect version information because of multiple
stellarinstallations on the same machine. An older binary prints the warning using its own version, which users then incorrectly compare againststellar --versionfrom a different binary. Additionally, fast commands abort the background version fetch before it can complete.What would you like to see?
doctorcommand updated to list everystellar/sorobanexecutable on the systemPATHalong with its version.doctorwarning if it was a different install.What alternatives are there?
Accepting the known limitations of this implementation: the grace period is skipped on error paths that call
process::exit; it may add up to 2 seconds to the first command of the day; and recording the cache writer is strictly diagnostic (it does not affect whether the warning is shown).fix: #2464