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:
@@ -91,11 +91,11 @@ coinhunter opportunity portfolio
|
|||||||
coinhunter opportunity scan
|
coinhunter opportunity scan
|
||||||
coinhunter opportunity scan --symbols BTCUSDT ETHUSDT SOLUSDT
|
coinhunter opportunity scan --symbols BTCUSDT ETHUSDT SOLUSDT
|
||||||
|
|
||||||
# Self-update
|
# Self-upgrade
|
||||||
coinhunter update
|
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
|
## Architecture
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|||||||
|
|
||||||
[project]
|
[project]
|
||||||
name = "coinhunter"
|
name = "coinhunter"
|
||||||
version = "2.0.3"
|
version = "2.0.4"
|
||||||
description = "Binance-first trading CLI for balances, market data, opportunity scanning, and execution."
|
description = "Binance-first trading CLI for balances, market data, opportunity scanning, and execution."
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
license = {text = "MIT"}
|
license = {text = "MIT"}
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ from . import __version__
|
|||||||
from .binance.spot_client import SpotBinanceClient
|
from .binance.spot_client import SpotBinanceClient
|
||||||
from .binance.um_futures_client import UMFuturesClient
|
from .binance.um_futures_client import UMFuturesClient
|
||||||
from .config import ensure_init_files, get_binance_credentials, load_config
|
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
|
from .services import account_service, market_service, opportunity_service, trade_service
|
||||||
|
|
||||||
EPILOG = """\
|
EPILOG = """\
|
||||||
@@ -22,7 +22,7 @@ examples:
|
|||||||
coinhunter trade spot buy BTCUSDT -q 100 -d
|
coinhunter trade spot buy BTCUSDT -q 100 -d
|
||||||
coinhunter trade futures sell BTCUSDT -q 0.01 -r
|
coinhunter trade futures sell BTCUSDT -q 0.01 -r
|
||||||
coinhunter opportunity scan -s BTCUSDT ETHUSDT
|
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 = 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")
|
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
|
return parser
|
||||||
|
|
||||||
@@ -258,8 +258,8 @@ def main(argv: list[str] | None = None) -> int:
|
|||||||
return 0
|
return 0
|
||||||
parser.error("opportunity requires `portfolio` or `scan`")
|
parser.error("opportunity requires `portfolio` or `scan`")
|
||||||
|
|
||||||
if args.command == "update":
|
if args.command == "upgrade":
|
||||||
print_output(self_update(), agent=args.agent)
|
print_output(self_upgrade(), agent=args.agent)
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
parser.error(f"Unsupported command {args.command}")
|
parser.error(f"Unsupported command {args.command}")
|
||||||
|
|||||||
@@ -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))
|
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"):
|
if shutil.which("pipx"):
|
||||||
cmd = ["pipx", "upgrade", "coinhunter"]
|
cmd = ["pipx", "upgrade", "coinhunter"]
|
||||||
else:
|
else:
|
||||||
|
|||||||
@@ -37,11 +37,11 @@ class CLITestCase(unittest.TestCase):
|
|||||||
self.assertEqual(result, 1)
|
self.assertEqual(result, 1)
|
||||||
self.assertIn("error: boom", stderr.getvalue())
|
self.assertIn("error: boom", stderr.getvalue())
|
||||||
|
|
||||||
def test_update_dispatches(self):
|
def test_upgrade_dispatches(self):
|
||||||
captured = {}
|
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)
|
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(result, 0)
|
||||||
self.assertEqual(captured["payload"]["returncode"], 0)
|
self.assertEqual(captured["payload"]["returncode"], 0)
|
||||||
|
|||||||
Reference in New Issue
Block a user