refactor: rename update command to upgrade

- Align CLI verb with pipx/pip terminology (`pipx upgrade`).
- Rename internal `self_update` to `self_upgrade` for consistency.
- Update README and tests accordingly.
- Bump version to 2.0.4.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-16 18:50:14 +08:00
parent cdc90a9be1
commit b857ea33f3
5 changed files with 13 additions and 13 deletions

View File

@@ -91,11 +91,11 @@ coinhunter opportunity portfolio
coinhunter opportunity scan
coinhunter opportunity scan --symbols BTCUSDT ETHUSDT SOLUSDT
# Self-update
coinhunter update
# Self-upgrade
coinhunter upgrade
```
`update` will try `pipx upgrade coinhunter` first, and fall back to `pip install --upgrade coinhunter` if pipx is not available.
`upgrade` will try `pipx upgrade coinhunter` first, and fall back to `pip install --upgrade coinhunter` if pipx is not available.
## Architecture

View File

@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
[project]
name = "coinhunter"
version = "2.0.3"
version = "2.0.4"
description = "Binance-first trading CLI for balances, market data, opportunity scanning, and execution."
readme = "README.md"
license = {text = "MIT"}

View File

@@ -10,7 +10,7 @@ from . import __version__
from .binance.spot_client import SpotBinanceClient
from .binance.um_futures_client import UMFuturesClient
from .config import ensure_init_files, get_binance_credentials, load_config
from .runtime import get_runtime_paths, print_output, self_update
from .runtime import get_runtime_paths, print_output, self_upgrade
from .services import account_service, market_service, opportunity_service, trade_service
EPILOG = """\
@@ -22,7 +22,7 @@ examples:
coinhunter trade spot buy BTCUSDT -q 100 -d
coinhunter trade futures sell BTCUSDT -q 0.01 -r
coinhunter opportunity scan -s BTCUSDT ETHUSDT
coinhunter update
coinhunter upgrade
"""
@@ -120,7 +120,7 @@ def build_parser() -> argparse.ArgumentParser:
scan_parser = opportunity_subparsers.add_parser("scan", help="Scan market for opportunities")
scan_parser.add_argument("-s", "--symbols", nargs="*", metavar="SYM", help="Restrict scan to specific symbols")
subparsers.add_parser("update", help="Upgrade coinhunter to the latest version")
subparsers.add_parser("upgrade", help="Upgrade coinhunter to the latest version")
return parser
@@ -258,8 +258,8 @@ def main(argv: list[str] | None = None) -> int:
return 0
parser.error("opportunity requires `portfolio` or `scan`")
if args.command == "update":
print_output(self_update(), agent=args.agent)
if args.command == "upgrade":
print_output(self_upgrade(), agent=args.agent)
return 0
parser.error(f"Unsupported command {args.command}")

View File

@@ -58,7 +58,7 @@ def print_json(payload: Any) -> None:
print(json.dumps(payload, ensure_ascii=False, indent=2, sort_keys=True, default=json_default))
def self_update() -> dict[str, Any]:
def self_upgrade() -> dict[str, Any]:
if shutil.which("pipx"):
cmd = ["pipx", "upgrade", "coinhunter"]
else:

View File

@@ -37,11 +37,11 @@ class CLITestCase(unittest.TestCase):
self.assertEqual(result, 1)
self.assertIn("error: boom", stderr.getvalue())
def test_update_dispatches(self):
def test_upgrade_dispatches(self):
captured = {}
with patch.object(cli, "self_update", return_value={"command": "pipx upgrade coinhunter", "returncode": 0}), patch.object(
with patch.object(cli, "self_upgrade", return_value={"command": "pipx upgrade coinhunter", "returncode": 0}), patch.object(
cli, "print_output", side_effect=lambda payload, **kwargs: captured.setdefault("payload", payload)
):
result = cli.main(["update"])
result = cli.main(["upgrade"])
self.assertEqual(result, 0)
self.assertEqual(captured["payload"]["returncode"], 0)