From a1d78094cfc1be932c51edd389862c362dd6ac8e Mon Sep 17 00:00:00 2001 From: Thamirawaran <107134124+Thamirawaran@users.noreply.github.com> Date: Tue, 22 Jul 2025 16:36:47 +0530 Subject: [PATCH 1/6] Register jac command for info --- jvcli/__init__.py | 16 +++++++ jvcli/plugin/jac_commands.py | 87 ++++++++++++++++++++++++++++++++++++ setup.py | 2 +- 3 files changed, 104 insertions(+), 1 deletion(-) create mode 100644 jvcli/plugin/jac_commands.py diff --git a/jvcli/__init__.py b/jvcli/__init__.py index 52822f5..376a93e 100644 --- a/jvcli/__init__.py +++ b/jvcli/__init__.py @@ -6,3 +6,19 @@ __version__ = "2.1.0" __supported__jivas__versions__ = ["2.1.0"] + + +def load_plugin() -> str: + """Load the jvcli plugin by registering commands with jac.""" + try: + # Import command modules to register them with jac's cmd_registry + from jvcli.plugin.jac_commands import JacCmd # noqa: F401 + + return "jvcli plugin loaded successfully" + except ImportError as e: + return f"jvcli plugin could not be loaded: {e}" + + +# Don't auto-import the plugin class to avoid circular imports +# The plugin will be loaded by jac when needed via the entry point +__all__ = ["load_plugin"] diff --git a/jvcli/plugin/jac_commands.py b/jvcli/plugin/jac_commands.py new file mode 100644 index 0000000..92dfc73 --- /dev/null +++ b/jvcli/plugin/jac_commands.py @@ -0,0 +1,87 @@ +"""Module for registering ALL jvcli CLI commands as jac plugins.""" + +from __future__ import annotations + +from typing import Callable + +from jvcli.commands.info import info as jv_info + +try: + from click.testing import CliRunner + from jaclang.cli.cmdreg import cmd_registry + from jaclang.runtimelib.machine import hookimpl + + _jac_available = True +except ImportError: + _jac_available = False + + def hookimpl(func: Callable) -> Callable: + """Dummy hookimpl decorator if jaclang is not available.""" + return func + + cmd_registry = None # type: ignore + + +class JacCmd: + """Jvcli Jac Plugin - ALL CLI commands for Jivas Package Repository.""" + + @staticmethod + @hookimpl + def create_cmd() -> None: + """Create ALL jvcli CLI commands for jac.""" + if not _jac_available: + print("Warning: jaclang not available, jvcli commands not registered") + return + + # Helper function to run Click commands + def run_click_command( + click_func: Callable, + args: list[str] | None = None, + input_data: str | None = None, + ) -> None: + """Helper to run Click commands via CliRunner.""" + try: + runner = CliRunner() + result = runner.invoke(click_func, args or [], input=input_data) + + if result.output: + print(result.output.strip()) + if result.exit_code != 0: + print(f"Error: Command failed with exit code {result.exit_code}") + + except Exception as e: + print(f"Error executing command: {e}") + + @cmd_registry.register + def info_action(name: str, version: str = "") -> None: + """Get info for an action package by name and version. + + Args: + name: Name of the action package + version: Version of the package (optional) + + Examples: + jac jv-info-action myaction + jac jv-info-action myaction 1.0.0 + """ + args = ["action", name] + if version: + args.append(version) + run_click_command(jv_info, args) + + @cmd_registry.register + def info_agent(name: str, version: str = "") -> None: + """Get info for an agent package by name and version. + + Args: + name: Name of the agent package + version: Version of the package (optional) + + Examples: + jac jv-info-agent myagent + jac jv-info-agent myagent 1.0.0 + """ + args = ["agent", name] + if version: + args.append(version) + run_click_command(jv_info, args) diff --git a/setup.py b/setup.py index 5ee15bd..59283c7 100644 --- a/setup.py +++ b/setup.py @@ -64,7 +64,7 @@ def get_version() -> str: }, entry_points={ "console_scripts": [ - "jvcli = jvcli.cli:jvcli", + "jac = jvcli.cli:jvcli", ], }, python_requires=">=3.12", From 0c079c855b75d75547fc3f9642b42c461b593e18 Mon Sep 17 00:00:00 2001 From: Thamirawaran <107134124+Thamirawaran@users.noreply.github.com> Date: Tue, 22 Jul 2025 17:44:14 +0530 Subject: [PATCH 2/6] Add test file for jac commands --- tests/test_jac_commands.py | 1 + 1 file changed, 1 insertion(+) create mode 100644 tests/test_jac_commands.py diff --git a/tests/test_jac_commands.py b/tests/test_jac_commands.py new file mode 100644 index 0000000..565ef05 --- /dev/null +++ b/tests/test_jac_commands.py @@ -0,0 +1 @@ +"""Tests for jac command functionality""" \ No newline at end of file From b5a529a8d23f2a66118c76aff84ae294da17b23d Mon Sep 17 00:00:00 2001 From: Thamirawaran <107134124+Thamirawaran@users.noreply.github.com> Date: Tue, 22 Jul 2025 17:47:00 +0530 Subject: [PATCH 3/6] fix precommit --- tests/test_jac_commands.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_jac_commands.py b/tests/test_jac_commands.py index 565ef05..70dd398 100644 --- a/tests/test_jac_commands.py +++ b/tests/test_jac_commands.py @@ -1 +1 @@ -"""Tests for jac command functionality""" \ No newline at end of file +"""Tests for jac command functionality""" From aaff22bf336db97408621fc93e3d81e0c03798c2 Mon Sep 17 00:00:00 2001 From: Thamirawaran <107134124+Thamirawaran@users.noreply.github.com> Date: Wed, 23 Jul 2025 09:47:29 +0530 Subject: [PATCH 4/6] Updated --- jvcli/__init__.py | 6 +- jvcli/cli.py | 42 ------ jvcli/plugin/__init__.py | 6 + jvcli/plugin/cli.py | 249 +++++++++++++++++++++++++++++++++++ jvcli/plugin/jac_commands.py | 87 ------------ pyproject.toml | 55 ++++++++ setup.py | 71 ---------- tests/test_cli.py | 223 ++++++++++++++++++++++++++----- tests/test_render_basic.py | 8 +- 9 files changed, 508 insertions(+), 239 deletions(-) delete mode 100644 jvcli/cli.py create mode 100644 jvcli/plugin/__init__.py create mode 100644 jvcli/plugin/cli.py delete mode 100644 jvcli/plugin/jac_commands.py create mode 100644 pyproject.toml delete mode 100644 setup.py diff --git a/jvcli/__init__.py b/jvcli/__init__.py index 376a93e..a07aa77 100644 --- a/jvcli/__init__.py +++ b/jvcli/__init__.py @@ -1,10 +1,10 @@ """ jvcli package initialization. -This package provides the CLI tool for Jivas Package Repository. +This package provides the CLI plugin for Jivas Package Repository integration with jac. """ -__version__ = "2.1.0" +__version__ = "2.0.31" __supported__jivas__versions__ = ["2.1.0"] @@ -12,7 +12,7 @@ def load_plugin() -> str: """Load the jvcli plugin by registering commands with jac.""" try: # Import command modules to register them with jac's cmd_registry - from jvcli.plugin.jac_commands import JacCmd # noqa: F401 + from jvcli.plugin.cli import JacCmd # noqa: F401 return "jvcli plugin loaded successfully" except ImportError as e: diff --git a/jvcli/cli.py b/jvcli/cli.py deleted file mode 100644 index 6d01530..0000000 --- a/jvcli/cli.py +++ /dev/null @@ -1,42 +0,0 @@ -"""Jivas Package Repository CLI tool.""" - -import click - -from jvcli import __version__ -from jvcli.commands.auth import login, logout, signup -from jvcli.commands.client import client -from jvcli.commands.create import create -from jvcli.commands.download import download -from jvcli.commands.graph import graph -from jvcli.commands.info import info -from jvcli.commands.publish import publish -from jvcli.commands.server import server -from jvcli.commands.startproject import startproject -from jvcli.commands.update import update - - -@click.group() -@click.version_option(__version__, prog_name="jvcli") -def jvcli() -> None: - """Jivas Package Repository CLI tool.""" - pass # pragma: no cover - - -# Register command groups -jvcli.add_command(create) -jvcli.add_command(update) -jvcli.add_command(download) -jvcli.add_command(publish) -jvcli.add_command(info) -jvcli.add_command(graph) -jvcli.add_command(client) -jvcli.add_command(startproject) -jvcli.add_command(server) - -# Register standalone commands -jvcli.add_command(signup) -jvcli.add_command(login) -jvcli.add_command(logout) - -if __name__ == "__main__": - jvcli() # pragma: no cover diff --git a/jvcli/plugin/__init__.py b/jvcli/plugin/__init__.py new file mode 100644 index 0000000..5a564f1 --- /dev/null +++ b/jvcli/plugin/__init__.py @@ -0,0 +1,6 @@ +"""Plugin module for jvcli integration with jac.""" + +# Don't import JacCmd here to avoid circular imports +# It will be imported by jac when needed via the entry point + +__all__: list[str] = [] diff --git a/jvcli/plugin/cli.py b/jvcli/plugin/cli.py new file mode 100644 index 0000000..89a6eae --- /dev/null +++ b/jvcli/plugin/cli.py @@ -0,0 +1,249 @@ +"""Module for registering ALL jvcli CLI commands as jac plugins.""" + +from __future__ import annotations + +from typing import Any + +# Import only the needed jvcli command functions +from jvcli.commands.auth import logout as jvcli_logout +from jvcli.commands.create import create as jvcli_create +from jvcli.commands.download import download as jvcli_download +from jvcli.commands.info import info as jvcli_info +from jvcli.commands.publish import publish as jvcli_publish +from jvcli.commands.startproject import startproject as jvcli_startproject + +# Import jac components - if not available, skip plugin registration +try: + from click.testing import CliRunner + from jaclang.cli.cmdreg import cmd_registry + from jaclang.runtimelib.machine import hookimpl + + _jac_available = True +except ImportError: + _jac_available = False + + # Define dummy decorators to avoid syntax errors + def hookimpl(func: Any) -> Any: # type: ignore[misc] + """Dummy hookimpl decorator when jac is not available.""" + return func + + cmd_registry = None # type: ignore + + +class JacCmd: + """Jvcli Jac Plugin - ALL CLI commands for Jivas Package Repository.""" + + @staticmethod + @hookimpl + def create_cmd() -> None: + """Create ALL jvcli CLI commands for jac.""" + if not _jac_available: + print("Warning: jaclang not available, jvcli commands not registered") + return + + # Helper function to run Click commands + def run_click_command( + click_func: Any, + args: list[str] | None = None, + input_data: str | None = None, + ) -> Any: + """Helper to run Click commands via CliRunner.""" + try: + runner = CliRunner() + result = runner.invoke(click_func, args or [], input=input_data) + + if result.output: + print(result.output.strip()) + if result.exit_code != 0: + print(f"Error: Command failed with exit code {result.exit_code}") + + except Exception as e: + print(f"Error executing command: {e}") + + # Register all commands directly here + try: + # ===== STANDALONE COMMANDS ===== + + @cmd_registry.register + def jv_logout() -> None: + """Log out by clearing the saved token. + + Examples: + jac jv-logout + """ + run_click_command(jvcli_logout) + + @cmd_registry.register + def jv_startproject(project_name: str, template: str = "basic") -> None: + """Initialize a new Jivas project with the necessary structure. + + Args: + project_name: Name of the project to create + template: Template to use (default: basic) + + Examples: + jac jv-startproject myproject + jac jv-startproject myproject advanced + """ + args = [project_name] + if template != "basic": + args.extend(["--version", template]) + run_click_command(jvcli_startproject, args) + + # ===== INFO COMMANDS ===== + + @cmd_registry.register + def jv_info_action(name: str, version: str = "") -> None: + """Get info for an action package by name and version. + + Args: + name: Name of the action package + version: Version of the package (optional) + + Examples: + jac jv-info-action myaction + jac jv-info-action myaction 1.0.0 + """ + args = ["action", name] + if version: + args.append(version) + run_click_command(jvcli_info, args) + + @cmd_registry.register + def jv_info_agent(name: str, version: str = "") -> None: + """Get info for an agent package by name and version. + + Args: + name: Name of the agent package + version: Version of the package (optional) + + Examples: + jac jv-info-agent myagent + jac jv-info-agent myagent 1.0.0 + """ + args = ["agent", name] + if version: + args.append(version) + run_click_command(jvcli_info, args) + + # ===== CREATE COMMANDS ===== + + @cmd_registry.register + def jv_create_action( + name: str, description: str = "", version: str = "0.1.0" + ) -> None: + """Create a new action with its folder, associated files, and dependencies. + + Args: + name: Name of the action (must be snake_case) + description: Description of the action + version: Version of the action (default: 0.1.0) + + Examples: + jac jv-create-action my_action + """ + args = ["action", "--name", name] + if description: + args.extend(["--description", description]) + if version != "0.1.0": + args.extend(["--version", version]) + run_click_command(jvcli_create, args) + + @cmd_registry.register + def jv_create_agent( + name: str, description: str = "", version: str = "0.1.0" + ) -> None: + """Create a new agent with its folder and associated files. + + Args: + name: Name of the agent (must be snake_case) + description: Description of the agent + version: Version of the agent (default: 0.1.0) + + Examples: + jac jv-create-agent my_agent + """ + args = ["agent", "--name", name] + if description: + args.extend(["--description", description]) + if version != "0.1.0": + args.extend(["--version", version]) + run_click_command(jvcli_create, args) + + # ===== DOWNLOAD COMMANDS ===== + + @cmd_registry.register + def jv_download_action(name: str, version: str = "latest") -> None: + """Download a JIVAS action package. + + Args: + name: Name of the action package to download + version: Version to download (default: latest) + + Examples: + jac jv-download-action myaction + jac jv-download-action myaction 1.0.0 + """ + args = ["action", name] + if version != "latest": + args.extend(["--version", version]) + run_click_command(jvcli_download, args) + + @cmd_registry.register + def jv_download_agent(name: str, version: str = "latest") -> None: + """Download a JIVAS agent package. + + Args: + name: Name of the agent package to download + version: Version to download (default: latest) + + Examples: + jac jv-download-agent myagent + jac jv-download-agent myagent 1.0.0 + """ + args = ["agent", name] + if version != "latest": + args.extend(["--version", version]) + run_click_command(jvcli_download, args) + + # ===== PUBLISH COMMANDS ===== + + @cmd_registry.register + def jv_publish_action(path: str = ".") -> None: + """Publish an action to the Jivas repository. + + Args: + path: Path to the action directory (default: current directory) + + Examples: + jac jv-publish-action + jac jv-publish-action ./my-action + """ + args = ["action"] + if path != ".": + args.extend(["--path", path]) + run_click_command(jvcli_publish, args) + + @cmd_registry.register + def jv_publish_agent(path: str = ".") -> None: + """Publish an agent to the Jivas repository. + + Args: + path: Path to the agent directory (default: current directory) + + Examples: + jac jv-publish-agent + jac jv-publish-agent ./my-agent + """ + args = ["agent"] + if path != ".": + args.extend(["--path", path]) + run_click_command(jvcli_publish, args) + + print("All jvcli commands registered with jac CLI") + + except Exception as e: + print(f"Error registering jvcli commands: {e}") + import traceback + + traceback.print_exc() diff --git a/jvcli/plugin/jac_commands.py b/jvcli/plugin/jac_commands.py deleted file mode 100644 index 92dfc73..0000000 --- a/jvcli/plugin/jac_commands.py +++ /dev/null @@ -1,87 +0,0 @@ -"""Module for registering ALL jvcli CLI commands as jac plugins.""" - -from __future__ import annotations - -from typing import Callable - -from jvcli.commands.info import info as jv_info - -try: - from click.testing import CliRunner - from jaclang.cli.cmdreg import cmd_registry - from jaclang.runtimelib.machine import hookimpl - - _jac_available = True -except ImportError: - _jac_available = False - - def hookimpl(func: Callable) -> Callable: - """Dummy hookimpl decorator if jaclang is not available.""" - return func - - cmd_registry = None # type: ignore - - -class JacCmd: - """Jvcli Jac Plugin - ALL CLI commands for Jivas Package Repository.""" - - @staticmethod - @hookimpl - def create_cmd() -> None: - """Create ALL jvcli CLI commands for jac.""" - if not _jac_available: - print("Warning: jaclang not available, jvcli commands not registered") - return - - # Helper function to run Click commands - def run_click_command( - click_func: Callable, - args: list[str] | None = None, - input_data: str | None = None, - ) -> None: - """Helper to run Click commands via CliRunner.""" - try: - runner = CliRunner() - result = runner.invoke(click_func, args or [], input=input_data) - - if result.output: - print(result.output.strip()) - if result.exit_code != 0: - print(f"Error: Command failed with exit code {result.exit_code}") - - except Exception as e: - print(f"Error executing command: {e}") - - @cmd_registry.register - def info_action(name: str, version: str = "") -> None: - """Get info for an action package by name and version. - - Args: - name: Name of the action package - version: Version of the package (optional) - - Examples: - jac jv-info-action myaction - jac jv-info-action myaction 1.0.0 - """ - args = ["action", name] - if version: - args.append(version) - run_click_command(jv_info, args) - - @cmd_registry.register - def info_agent(name: str, version: str = "") -> None: - """Get info for an agent package by name and version. - - Args: - name: Name of the agent package - version: Version of the package (optional) - - Examples: - jac jv-info-agent myagent - jac jv-info-agent myagent 1.0.0 - """ - args = ["agent", name] - if version: - args.append(version) - run_click_command(jv_info, args) diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..6bec373 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,55 @@ +[build-system] +requires = ["setuptools>=61.0", "wheel"] +build-backend = "setuptools.build_meta" + +[project] +name = "jvcli" +version = "2.0.31" +description = "CLI plugin for Jivas Package Repository integration with jac" +readme = "README.md" +requires-python = ">=3.12" +license = {text = "MIT"} +authors = [ + {name = "TrueSelph Inc.", email = "admin@trueselph.com"}, +] +dependencies = [ + "jaclang", + "click>=8.1.8", + "requests>=2.32.3", + "packaging>=24.2", + "pyaml>=25.1.0", + "streamlit>=1.42.0", + "streamlit-elements>=0.1.0", + "streamlit-router>=0.1.8", + "streamlit-javascript>=0.1.5", + "python-dotenv>=1.0.0", + "semver>=3.0.4", + "node-semver>=0.9.0", + "jvgraph>=2.1.0", + "pymongo", + "jac-cloud", + "uvicorn", + "fastapi", +] + +[project.optional-dependencies] +dev = [ + "pre-commit", + "pytest", + "pytest-mock", + "pytest-cov", +] + +# Plugin entry points for jac integration +[project.entry-points."jac"] +jvcli = "jvcli.plugin.cli:JacCmd" + +[project.urls] +Homepage = "https://github.com/TrueSelph/jvcli" +Repository = "https://github.com/TrueSelph/jvcli.git" + +[tool.setuptools] +packages = ["jvcli", "jvcli.commands", "jvcli.client", "jvcli.plugin"] + +[tool.setuptools.package-data] +jvcli = ["client/**/*", "templates/**/*", "py.typed"] \ No newline at end of file diff --git a/setup.py b/setup.py deleted file mode 100644 index 59283c7..0000000 --- a/setup.py +++ /dev/null @@ -1,71 +0,0 @@ -"""Setup script for jvcli.""" - -import os - -from setuptools import find_packages, setup - -with open("README.md", "r", encoding="utf-8") as fh: - long_description = fh.read() - - -def get_version() -> str: - """Get the package version from the __init__ file.""" - version_file = os.path.join(os.path.dirname(__file__), "jvcli", "__init__.py") - with open(version_file) as f: - for line in f: - if line.startswith("__version__"): - delim = '"' if '"' in line else "'" - return line.split(delim)[1] - raise RuntimeError("Version not found.") - - -setup( - name="jvcli", - version=get_version(), - description="CLI tool for Jivas Package Repository", - long_description=long_description, - long_description_content_type="text/markdown", - author="TrueSelph Inc.", - author_email="admin@trueselph.com", - url="https://github.com/TrueSelph/jvcli", - packages=find_packages( - include=["jvcli", "jvcli.*"], - ), - include_package_data=True, - package_data={ - "jvcli": ["client/**/*"], - }, - install_requires=[ - "click>=8.1.8", - "requests>=2.32.3", - "packaging>=24.2", - "pyaml>=25.1.0", - "streamlit>=1.42.0", - "streamlit-elements>=0.1.0", - "streamlit-router>=0.1.8", - "streamlit-javascript>=0.1.5", - "python-dotenv>=1.0.0", - "semver>=3.0.4", - "node-semver>=0.9.0", - "jvgraph>=2.1.0", - "jaclang", - "pymongo", - "jac-cloud", - "uvicorn", - "fastapi", - ], - extras_require={ - "dev": [ - "pre-commit", - "pytest", - "pytest-mock", - "pytest-cov", - ], - }, - entry_points={ - "console_scripts": [ - "jac = jvcli.cli:jvcli", - ], - }, - python_requires=">=3.12", -) diff --git a/tests/test_cli.py b/tests/test_cli.py index 27028e6..9ace3ed 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -1,44 +1,201 @@ -"""Tests for the CLI module.""" +"""Tests for jvcli CLI plugin functionality without circular import issues.""" -import click.testing +# Get the full path to jac command +import shutil +import subprocess +import sys -from jvcli.cli import jvcli +import pytest +JAC_CMD = shutil.which("jac") or "/home/thami/personal/my/bin/jac" -class TestCli: - """Test cases for the CLI module.""" - def test_cli_initialization_registers_all_commands(self) -> None: - """Test that CLI initializes with all commands registered correctly.""" +class TestJvcliCliPlugin: + """Test jvcli CLI plugin integration without importing plugin directly.""" + + def test_jac_commands_available_in_help(self) -> None: + """Test that jvcli commands are available in jac --help output.""" # Act - runner = click.testing.CliRunner() - result = runner.invoke(jvcli, ["--help"]) + result = subprocess.run( + [JAC_CMD, "--help"], capture_output=True, text=True, timeout=30 + ) # Assert - assert result.exit_code == 0 - assert "create" in result.output - assert "update" in result.output - assert "download" in result.output - assert "publish" in result.output - assert "info" in result.output - assert "graph" in result.output - assert "signup" in result.output - assert "login" in result.output - assert "logout" in result.output - - def test_cli_version(self) -> None: - """Test that CLI version command works correctly.""" + assert result.returncode == 0 + assert "jv_logout" in result.stdout + assert "jv_startproject" in result.stdout + assert "jv_info_action" in result.stdout + assert "jv_info_agent" in result.stdout + assert "jv_create_action" in result.stdout + assert "jv_create_agent" in result.stdout + assert "jv_download_action" in result.stdout + assert "jv_download_agent" in result.stdout + assert "jv_publish_action" in result.stdout + assert "jv_publish_agent" in result.stdout + + def test_jac_logout_command_execution(self) -> None: + """Test that jac jv_logout command executes successfully.""" # Act - runner = click.testing.CliRunner() - result = runner.invoke(jvcli, ["--version"]) + result = subprocess.run( + [JAC_CMD, "jv_logout"], capture_output=True, text=True, timeout=30 + ) # Assert - assert result.exit_code == 0 - assert "jvcli, version" in result.output - - def test_cli_no_command(self) -> None: - """Test that CLI displays usage information when no command is provided.""" - runner = click.testing.CliRunner() - result = runner.invoke(jvcli) - assert "Usage:" in result.output - assert "Commands:" in result.output + assert result.returncode == 0 + assert "You have been logged out" in result.stdout + assert "All jvcli commands registered with jac CLI" in result.stdout + + @pytest.mark.parametrize( + "command,expected_text", + [ + ("jv_logout", "Log out by clearing the saved token"), + ("jv_startproject", "Initialize a new Jivas project"), + ("jv_info_action", "Get info for an action package"), + ("jv_info_agent", "Get info for an agent package"), + ("jv_create_action", "Create a new action"), + ("jv_create_agent", "Create a new agent"), + ("jv_download_action", "Download a JIVAS action package"), + ("jv_download_agent", "Download a JIVAS agent package"), + ("jv_publish_action", "Publish an action to the Jivas repository"), + ("jv_publish_agent", "Publish an agent to the Jivas repository"), + ], + ) + def test_command_descriptions(self, command: str, expected_text: str) -> None: + """Test that command descriptions are properly displayed.""" + result = subprocess.run( + [JAC_CMD, command, "--help"], capture_output=True, text=True, timeout=30 + ) + + assert result.returncode == 0 + assert expected_text in result.stdout + + def test_entry_point_registration(self) -> None: + """Test that jvcli is properly registered as a jac entry point.""" + try: + from importlib.metadata import entry_points + + # Use modern importlib.metadata + eps = entry_points(group="jac") + jvcli_entries = [ep for ep in eps if ep.name == "jvcli"] + assert len(jvcli_entries) == 1 + assert jvcli_entries[0].value == "jvcli.plugin.cli:JacCmd" + except ImportError: + # Fallback to pkg_resources for older Python + import pkg_resources + + jvcli_entries_iter = pkg_resources.iter_entry_points("jac", "jvcli") + jvcli_entries = list(jvcli_entries_iter) # type: ignore[arg-type] + assert len(jvcli_entries) == 1 + # For pkg_resources, entry points have different attributes + entry_point = jvcli_entries[0] + # Use the string representation which is standardized + assert str(entry_point).endswith("jvcli.plugin.cli:JacCmd") + + def test_package_imports_successfully(self) -> None: + """Test that the package can be imported without issues.""" + import jvcli + + # Check that the package has version info + assert hasattr(jvcli, "__version__") + assert jvcli.__version__ == "2.0.31" + + def test_no_circular_imports_during_runtime(self) -> None: + """Test that there are no circular import issues during plugin loading.""" + # This test runs the actual jac command to ensure plugin loads correctly + result = subprocess.run( + [ + sys.executable, + "-c", + "import jaclang; print('Plugin loading successful')", + ], + capture_output=True, + text=True, + timeout=30, + ) + + assert result.returncode == 0 + assert "Plugin loading successful" in result.stdout + + def test_all_commands_have_help(self) -> None: + """Test that all jvcli commands provide help output.""" + commands = [ + "jv_logout", + "jv_startproject", + "jv_info_action", + "jv_info_agent", + "jv_create_action", + "jv_create_agent", + "jv_download_action", + "jv_download_agent", + "jv_publish_action", + "jv_publish_agent", + ] + + for cmd in commands: + result = subprocess.run( + [JAC_CMD, cmd, "--help"], capture_output=True, text=True, timeout=30 + ) + + # Assert + assert result.returncode == 0, f"Command {cmd} --help failed" + assert ( + "usage:" in result.stdout.lower() + ), f"Command {cmd} help missing usage" + assert "All jvcli commands registered with jac CLI" in result.stdout + + def test_jac_startproject_help_shows_parameters(self) -> None: + """Test that jv_startproject command shows correct parameters.""" + result = subprocess.run( + [JAC_CMD, "jv_startproject", "--help"], + capture_output=True, + text=True, + timeout=30, + ) + + assert result.returncode == 0 + assert "project_name" in result.stdout + assert "-t TEMPLATE" in result.stdout or "--template" in result.stdout + + def test_jac_info_commands_show_parameters(self) -> None: + """Test that info commands show correct parameters.""" + for cmd in ["jv_info_action", "jv_info_agent"]: + result = subprocess.run( + [JAC_CMD, cmd, "--help"], capture_output=True, text=True, timeout=30 + ) + + assert result.returncode == 0 + assert "name" in result.stdout + assert "-v VERSION" in result.stdout or "--version" in result.stdout + + def test_jac_create_commands_show_parameters(self) -> None: + """Test that create commands show correct parameters.""" + for cmd in ["jv_create_action", "jv_create_agent"]: + result = subprocess.run( + [JAC_CMD, cmd, "--help"], capture_output=True, text=True, timeout=30 + ) + + assert result.returncode == 0 + assert "name" in result.stdout + assert "-d DESCRIPTION" in result.stdout or "--description" in result.stdout + assert "-v VERSION" in result.stdout or "--version" in result.stdout + + def test_jac_download_commands_show_parameters(self) -> None: + """Test that download commands show correct parameters.""" + for cmd in ["jv_download_action", "jv_download_agent"]: + result = subprocess.run( + [JAC_CMD, cmd, "--help"], capture_output=True, text=True, timeout=30 + ) + + assert result.returncode == 0 + assert "name" in result.stdout + assert "-v VERSION" in result.stdout or "--version" in result.stdout + + def test_jac_publish_commands_show_parameters(self) -> None: + """Test that publish commands show correct parameters.""" + for cmd in ["jv_publish_action", "jv_publish_agent"]: + result = subprocess.run( + [JAC_CMD, cmd, "--help"], capture_output=True, text=True, timeout=30 + ) + + assert result.returncode == 0 + assert "path" in result.stdout diff --git a/tests/test_render_basic.py b/tests/test_render_basic.py index 493fee6..7a3fb60 100644 --- a/tests/test_render_basic.py +++ b/tests/test_render_basic.py @@ -13,9 +13,11 @@ def test_render_basic() -> None: action_id = "B" info: dict[str, Any] = {} - with patch("fixtures.app.app.app_header") as m_header, patch( - "fixtures.app.app.app_controls" - ) as m_controls, patch("fixtures.app.app.app_update_action") as m_update: + with ( + patch("fixtures.app.app.app_header") as m_header, + patch("fixtures.app.app.app_controls") as m_controls, + patch("fixtures.app.app.app_update_action") as m_update, + ): m_header.return_value = ("model", "module") render(router, agent_id, action_id, info) m_header.assert_called_once_with(agent_id, action_id, info) From b7a4455a44d774395cbf4ae894883b405290f109 Mon Sep 17 00:00:00 2001 From: Thamirawaran <107134124+Thamirawaran@users.noreply.github.com> Date: Wed, 23 Jul 2025 09:49:20 +0530 Subject: [PATCH 5/6] updated --- tests/test_jac_commands.py | 1 - 1 file changed, 1 deletion(-) delete mode 100644 tests/test_jac_commands.py diff --git a/tests/test_jac_commands.py b/tests/test_jac_commands.py deleted file mode 100644 index 70dd398..0000000 --- a/tests/test_jac_commands.py +++ /dev/null @@ -1 +0,0 @@ -"""Tests for jac command functionality""" From 77818476ffc6269cb02713d6ab68a527b052f224 Mon Sep 17 00:00:00 2001 From: Thamirawaran <107134124+Thamirawaran@users.noreply.github.com> Date: Wed, 23 Jul 2025 09:56:29 +0530 Subject: [PATCH 6/6] pre-commit fix --- tests/test_cli.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_cli.py b/tests/test_cli.py index 9ace3ed..7ba1532 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -81,7 +81,7 @@ def test_entry_point_registration(self) -> None: assert jvcli_entries[0].value == "jvcli.plugin.cli:JacCmd" except ImportError: # Fallback to pkg_resources for older Python - import pkg_resources + import pkg_resources # type: ignore[import-untyped] jvcli_entries_iter = pkg_resources.iter_entry_points("jac", "jvcli") jvcli_entries = list(jvcli_entries_iter) # type: ignore[arg-type]