diff --git a/README.md b/README.md index c22fd6b..b4c3bd8 100644 --- a/README.md +++ b/README.md @@ -1159,9 +1159,17 @@ Shows: Python version, GPU availability, all dependency versions, and fix sugges # Basic version soup version +# Machine-readable output +soup version --json +# -> {"version": "0.24.0", "python": "3.11.5", "platform": "linux"} + # Full system info (useful for bug reports) soup version --full # -> soup v0.17.3 | Python 3.11.5 | CUDA 12.1 | extras: serve, data + +# Full system info in JSON +soup version --full --json +# -> {"version": "0.24.0", "python": "3.11.5", "platform": "linux", "torch": "2.2.0", ...} ``` ## Web UI @@ -1439,7 +1447,7 @@ soup runs compare Compare two runs soup ui [--port 7860] Web UI (experiments, training, data) soup doctor Check environment soup quickstart [--dry-run] Full demo -soup version [--full] Show version (--full: system info) +soup version [--full] [--json] Show version (--full: system info, --json: JSON output) soup --verbose Full traceback on errors ``` diff --git a/soup_cli/cli.py b/soup_cli/cli.py index e6bcff8..7b13f79 100644 --- a/soup_cli/cli.py +++ b/soup_cli/cli.py @@ -92,15 +92,47 @@ data.app.command(name="generate")(generate.generate) @app.command() def version( full: bool = typer.Option(False, "--full", "-f", help="Show system info and extras"), + is_json: bool = typer.Option(False, "--json", help="Output in JSON format"), ): """Show Soup CLI version.""" + import json + import platform + + if is_json: + info = { + "version": __version__, + "python": platform.python_version(), + "platform": platform.system().lower(), + } + + if full: + for lib in ["torch", "transformers", "peft", "trl", "datasets", "accelerate"]: + try: + mod = __import__(lib) + if hasattr(mod, "__version__"): + info[lib] = mod.__version__ + except ImportError: + pass + for name in ["fastapi", "vllm", "datasketch", "lm_eval", "deepspeed", "wandb"]: + try: + mod = __import__(name) + if hasattr(mod, "__version__"): + info[name] = mod.__version__ + elif hasattr(mod, "version"): + info[name] = mod.version + else: + info[name] = "installed" + except ImportError: + pass + + print(json.dumps(info)) + return + if not full: console.print(f"[bold green]soup[/] v{__version__}") console.print(f"[dim]{GITHUB_URL}[/]") return - import platform - parts = [f"[bold green]soup[/] v{__version__}"] parts.append(f"Python {platform.python_version()}") diff --git a/tests/test_cli.py b/tests/test_cli.py index a1357e6..8b498d0 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -84,3 +84,26 @@ def test_help_shows_all_commands(): assert "init" in result.output assert "export" in result.output assert "merge" in result.output + + +def test_version_json(): + import json + import platform + result = runner.invoke(app, ["version", "--json"]) + assert result.exit_code == 0 + data = json.loads(result.output) + assert data["version"] == __version__ + assert data["python"] == platform.python_version() + assert data["platform"] == platform.system().lower() + + +def test_version_full_json(): + import json + import platform + result = runner.invoke(app, ["version", "--full", "--json"]) + assert result.exit_code == 0 + data = json.loads(result.output) + assert data["version"] == __version__ + assert data["python"] == platform.python_version() + assert "platform" in data +