Skip to content

feat: introduce version info & update command#24

Open
irisyann wants to merge 7 commits intomainfrom
feat/version-info-and-update-cmd
Open

feat: introduce version info & update command#24
irisyann wants to merge 7 commits intomainfrom
feat/version-info-and-update-cmd

Conversation

@irisyann
Copy link
Copy Markdown
Contributor

@irisyann irisyann commented Apr 21, 2026

Summary

  • Adds cg update command to upgrade the CLI in-place, auto-detecting the install method (Homebrew, go install, or the install script) and prompting for confirmation before running
  • Adds a passive update-available nudge on cg startup: checks GitHub Releases and prints a one-liner hint when a newer version exists
  • Surfaces the current version in the welcome box header (◆ CoinGecko CLI v1.2.3)

Changes

internal/updater/checker.go (new)

Core update-check logic extracted into its own package:

  • Check(currentVersion) — passive checker used at startup. Reads a 24-hour cache at ~/.config/coingecko-cli/update_check.json before hitting the network; skips entirely when CG_NO_UPDATE_CHECK=1 is set, or when the build version is dev/empty (local builds). Times out at 2 s so it never blocks the prompt.
  • FetchLatest() — explicit fetch used by cg update. 10 s timeout, updates the cache on success.
  • Both functions strip the leading v from the GitHub tag so version strings are compared uniformly (e.g. "1.4.0").

cmd/update.go (new)

cg update command:

  • Detects install method from the resolved binary path (/Cellar/ or /opt/homebrew/ → Homebrew; $GOBIN prefix → go install; fallback → install.sh script). Can be overridden with --method homebrew|go|script.
  • Validates the fetched version string against a semver regex before acting on it.
  • Prompts for confirmation via huh.NewConfirm (Charm ecosystem, consistent with cg auth). Exits cleanly on Ctrl-C / "No".
  • Delegates the actual upgrade to the appropriate package manager; streams stdout/stderr so progress is visible.

internal/display/banner.go

  • PrintWelcomeBox now accepts the build version string and renders it in the header row.
  • PrintUpdateReminder(current, latest) — new helper that writes the update nudge to stderr, respecting NO_COLOR.
  • Fixed a latent padding bug: printColoredRow was calling len() on a string that may contain multi-byte runes (e.g. ); replaced with utf8.RuneCountInString so box borders align correctly on all terminals.

cmd/root.go

  • Passes version into PrintWelcomeBox.
  • Calls updater.Check after printing the welcome box and surfaces the reminder if an update is available.

Test plan

  • cg (no args) — welcome box shows current version in header; no update notice when already on latest
  • cg on an older build (spoof version string) — update notice appears below the welcome box
  • CG_NO_UPDATE_CHECK=1 cg — no network call, no notice
  • cg update when already on latest — prints "Already up to date"
  • cg update when a newer version exists — shows current → latest, confirms, runs the correct install command for the detected method
  • cg update --method homebrew|go|script — overrides detection, runs expected command
  • cg update --method invalid — returns a clear error
  • Cancel the confirmation prompt — exits cleanly with no error
  • Terminal with multi-byte characters in version string — welcome box borders stay aligned

@irisyann irisyann requested a review from a team April 21, 2026 08:26
@irisyann irisyann force-pushed the feat/version-info-and-update-cmd branch from 0a6f367 to 76070bc Compare April 21, 2026 08:28
@irisyann irisyann requested a review from cg-eesuhn April 21, 2026 08:51
@irisyann irisyann force-pushed the feat/version-info-and-update-cmd branch from 1e9f54d to b735dbf Compare April 22, 2026 04:29
@irisyann irisyann force-pushed the feat/version-info-and-update-cmd branch from b735dbf to f2f1417 Compare April 22, 2026 04:32
@irisyann irisyann force-pushed the feat/version-info-and-update-cmd branch from fbf21b0 to c56f82f Compare April 22, 2026 05:57
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Introduces CLI version surfacing plus an update mechanism: a passive “update available” reminder on startup and a new cg update command to upgrade in-place.

Changes:

  • Added internal/updater package to fetch/cache latest GitHub release and compare versions.
  • Added cg update command with install-method detection, confirmation prompt, and upgrade execution.
  • Updated welcome banner to show build version and added an update reminder helper; documented cg update in README.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
internal/updater/checker.go Implements cached update checks + version comparison utilities
internal/updater/checker_test.go Adds unit tests for version comparison, cache behavior, and fetch behavior
cmd/update.go Adds cg update command (method detection, confirmation, upgrade execution)
cmd/update_test.go Adds tests for update command behavior around version fetching/validation
internal/display/banner.go Shows version in welcome box header; adds update reminder output + padding fix
cmd/root.go Plumbs version into welcome box and triggers update check on startup
README.md Documents cg update and adds it to commands list

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread internal/display/banner.go
Comment thread internal/updater/checker.go
Comment thread cmd/update.go
Comment thread cmd/update.go
Comment thread cmd/root.go

_, _ = fmt.Fprintln(w, top)
_, _ = fmt.Fprintln(w, blank)
printColoredRow(w, brandGreen+"◆ CoinGecko CLI "+colorReset+version, versionVisible)
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

The goreleaser outputs the version number without v, this will return 1.2.3 instead of v1.2.3

Can u check if this is true?

Comment thread cmd/update.go
Comment on lines +126 to +128
case "go":
name = "go"
args = []string{"install", "github.com/coingecko/coingecko-cli@latest"}
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Can check if this install method is correct? It seems like it'll produce a binary with coingecko-cli instead of cg. So if user have cg installed, then it'll not update the correct one.

Comment thread cmd/update_test.go
@@ -0,0 +1,84 @@
package cmd
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Add test for detectInstallMethod And ClassifyInstallPath

current = strings.TrimPrefix(current, "v")
latest = strings.TrimPrefix(latest, "v")
if ColorEnabled() {
fmt.Fprintf(os.Stderr, " %sUpdate available:%s v%s → v%s. Run %scg update%s to upgrade.\n\n",
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

huh. does the linter not flag this? should be something like _, _ = fmt.Fprintf(os.Stderr, " %sUpdate available:%s v%s → v%s. cuz fmt.Fprintf returns (int, error);

Comment thread cmd/update.go
}

func runUpdate(cmd *cobra.Command, args []string) error {
display.PrintBanner()
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

don't think we should show banner when we run cg update

ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
v, err := fetchLatest(ctx)
if err != nil {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Should we add a check for version tag here?

So we don't cache pre-release build v1.2.3-rc1 (not sure if we'll ever use it

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Because from validVersion, it seemed to only accept v1.2.3 format as valid?

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.

4 participants