Skip to content

feat(update): add version check output to doctor and update#1836

Closed
reidliu41 wants to merge 1 commit into
Hmbown:mainfrom
reidliu41:feat/update-check-doctor
Closed

feat(update): add version check output to doctor and update#1836
reidliu41 wants to merge 1 commit into
Hmbown:mainfrom
reidliu41:feat/update-check-doctor

Conversation

@reidliu41
Copy link
Copy Markdown
Contributor

@reidliu41 reidliu41 commented May 20, 2026

Summary

Adds a lightweight way to check whether the installed binary is current.

Before this change, deepseek update could perform an update, but there was no check-only path, and deepseek doctor did not report whether a newer release was available. This made it harder for users to confirm whether local issues might already be fixed in a newer version.

This PR adds:

  • deepseek update --check to report the current version and latest release without downloading or replacing binaries
  • an Updates section in deepseek doctor
  • version comparison that handles v0.8.x, 0.8.x, and build suffixes like 0.8.x (commit)
  • async release checking in doctor so diagnostics continue to run normally inside the TUI runtime
deepseek doctor
DeepSeek TUI Doctor
==================

Version Information:
  deepseek-tui: 0.8.39 (eeccf7de6c3b)
  rust: rustc 1.93.1 (01f6ddf75 2026-02-11)

Updates:
  · current: v0.8.39
  ✓ latest: v0.8.39
    Already up to date.
....



deepseek update --check
Checking for updates...
Current binary: /home/reid/github/DeepSeek-TUI/target/debug/deepseek
Current version: v0.8.39
Latest release: v0.8.39
Already up to date.

Testing

  • cargo test --all-features
  • cargo fmt --all -- --check
  • cargo clippy --all-targets --all-features

Checklist

  • Updated docs or comments as needed
  • Added or updated tests where relevant
  • Verified TUI behavior manually if UI changes

  Add a check-only update path and surface version status in doctor.

  - Add `deepseek update --check` to report the latest release without downloading or replacing binaries
  - Show current/latest release status in `deepseek doctor`
  - Keep update installation behavior unchanged for `deepseek update`
  - Use async release checks in doctor so diagnostics do not panic inside the runtime
Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a --check flag to the update command, allowing users to verify the latest release without performing an update. It also integrates a version check into the doctor command to display the current and latest versions. Feedback focuses on significant code duplication between the CLI and TUI crates for version parsing and comparison logic, suggesting these be moved to a shared utility module. Additionally, the reviewer noted redundant function calls and macro invocations in the doctor command implementation that should be refactored for better efficiency.

Comment thread crates/tui/src/main.rs
Comment on lines +1478 to +1510
fn doctor_release_base_url_from_env() -> Option<String> {
std::env::var(DOCTOR_RELEASE_BASE_URL_ENV)
.ok()
.or_else(|| std::env::var(DOCTOR_LEGACY_RELEASE_BASE_URL_ENV).ok())
.map(|value| value.trim().to_string())
.filter(|value| !value.is_empty())
}

fn doctor_update_version_from_env() -> Option<String> {
std::env::var(DOCTOR_UPDATE_VERSION_ENV)
.ok()
.or_else(|| std::env::var(DOCTOR_LEGACY_UPDATE_VERSION_ENV).ok())
.map(|value| value.trim().trim_start_matches('v').to_string())
.filter(|value| !value.is_empty())
}

fn compare_release_versions(current: &str, latest_tag: &str) -> std::cmp::Ordering {
parse_version_components(current).cmp(&parse_version_components(latest_tag))
}

fn parse_version_components(version: &str) -> Vec<u64> {
let trimmed = version.trim().trim_start_matches('v');
let core = trimmed.split(['-', '+', ' ']).next().unwrap_or(trimmed);
core.split('.')
.map(|part| {
part.chars()
.take_while(|ch| ch.is_ascii_digit())
.collect::<String>()
.parse::<u64>()
.unwrap_or(0)
})
.collect()
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

There's significant code duplication between crates/tui/src/main.rs and crates/cli/src/update.rs. The functions doctor_release_base_url_from_env, doctor_update_version_from_env, compare_release_versions, and parse_version_components are nearly identical to their counterparts in update.rs.

To improve maintainability and avoid having to update logic in multiple places, this shared functionality should be extracted into a common utility module or a new shared crate (e.g., deepseek-version-utils). This would also apply to the related constants and test cases.

Comment thread crates/tui/src/main.rs
Comment on lines +1757 to +1773
let icon = match compare_release_versions(env!("CARGO_PKG_VERSION"), &latest_tag) {
std::cmp::Ordering::Less => "!".truecolor(sky_r, sky_g, sky_b),
std::cmp::Ordering::Equal => "✓".truecolor(aqua_r, aqua_g, aqua_b),
std::cmp::Ordering::Greater => "·".dimmed(),
};
println!(" {} latest: {}", icon, latest_tag);
match compare_release_versions(env!("CARGO_PKG_VERSION"), &latest_tag) {
std::cmp::Ordering::Less => {
println!(" Update available. Run `deepseek update` to install.");
}
std::cmp::Ordering::Equal => {
println!(" Already up to date.");
}
std::cmp::Ordering::Greater => {
println!(" Current build is newer than the latest published release.");
}
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The compare_release_versions function is called twice with the same arguments. To improve efficiency and readability, you should call it once and store the result in a variable. You can also store env!("CARGO_PKG_VERSION") in a variable before line 1754 to avoid repeating the macro invocation.

@Hmbown
Copy link
Copy Markdown
Owner

Hmbown commented May 27, 2026

Independent review:

The --check flag on update is a good UX addition — non-destructive version comparison via compare_release_versions is sound (correctly strips v prefix, ignores build SHAs, handles "newer than published"). However this PR is unmergeable as-is.

Critical:

  1. Branch is severely stale. It reverts the entire CodeWhale rebrand: removes process_hardening (sandbox/linux: process hardening at startup (PR_SET_DUMPABLE=0, NO_NEW_PRIVS, RLIMIT_CORE=0) #2183 — process hardening MUST run before tokio), removes theme_qa_audit, removes tool_output_receipts, removes swebench subcommand, downgrades --auto help text. These deletions are unrelated to the stated feature and would silently undo months of work.
  2. Doctor-side version check (doctor_latest_release_tag) duplicates the network/env/mirror logic from update.rs with DOCTOR_*-prefixed constants. Extract a shared release_check::latest_tag() helper rather than forking the implementation — two copies will drift.
  3. Doctor uses a 5s timeout for the HTTP request, but update.rs has no explicit timeout. Inconsistent. The doctor version is better; consider promoting it.

Recommendation: rebase on current main, drop everything outside update.rs / the targeted doctor integration, and refactor to share the latest-tag fetcher. After that, the --check flag is a clean win.

v0.8.48 (PR #2256): 2 conflicts in crates/cli/src/lib.rs and crates/cli/src/update.rs.

@reidliu41
Copy link
Copy Markdown
Contributor Author

This is opened with the old repo , so open a new branch to fix it in #2291, please help to check it.

@reidliu41 reidliu41 closed this May 27, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants