Skip to content

Commit

Permalink
Merge pull request #555 from Cloud-Code-AI/549-kaizen-cli-make-easy-s…
Browse files Browse the repository at this point in the history
…etup-with-ollama

549 kaizen cli make easy setup with ollama
  • Loading branch information
sauravpanda authored Sep 16, 2024
2 parents 6e3d8a8 + 3c893a3 commit 0a62cd9
Show file tree
Hide file tree
Showing 12 changed files with 242 additions and 108 deletions.
2 changes: 2 additions & 0 deletions cli/kaizen_cli/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from .commands.config_commands import config
from .commands.unit_test_commands import unit_test
from .commands.reviewer_commands import reviewer
from .hooks.setup import hooks
from kaizen.generator.e2e_tests import E2ETestGenerator


Expand All @@ -23,6 +24,7 @@ def ui_tests(url):
cli.add_command(config)
cli.add_command(unit_test)
cli.add_command(reviewer)
cli.add_command(hooks)

if __name__ == "__main__":
cli()
6 changes: 1 addition & 5 deletions cli/kaizen_cli/config/default_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,7 @@
"models": [
{
"model_name": "default",
"litellm_params": {
"model": "azure/gpt-4o-mini",
"api_key": "os.environ/AZURE_API_KEY",
"api_base": "os.environ/AZURE_API_BASE",
},
"litellm_params": {"model": "ollama/phi3"},
},
]
},
Expand Down
8 changes: 8 additions & 0 deletions cli/kaizen_cli/hooks/prepare-commit-msg
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#!/bin/sh
# hooks/prepare-commit-msg

# Run your CLI command and capture the output
commit_msg=$(kaizen-cli generate-commit-msg)

# Overwrite the commit message file with the generated message
echo "$commit_msg" > "$1"
58 changes: 58 additions & 0 deletions cli/kaizen_cli/hooks/setup.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import os
import shutil
import click

HOOK_TYPES = ["prepare-commit-msg"]


@click.group()
def hooks():
"""Manage git hooks"""
pass


@hooks.command()
@click.argument("hook_type", type=click.Choice(HOOK_TYPES))
def install(hook_type):
"""Install a specific git hook"""
source = os.path.join(os.path.dirname(__file__), "hooks", hook_type)
destination = os.path.join(".git", "hooks", hook_type)

if not os.path.exists(source):
click.echo(f"Error: Hook script for {hook_type} not found.")
return

try:
shutil.copy(source, destination)
os.chmod(destination, 0o755)
click.echo(f"{hook_type} hook installed successfully")
except IOError as e:
click.echo(f"Error installing {hook_type} hook: {str(e)}")


@hooks.command()
def install_all():
"""Install all available git hooks"""
for hook_type in HOOK_TYPES:
ctx = click.get_current_context()
ctx.invoke(install, hook_type=hook_type)


@hooks.command()
@click.argument("hook_type", type=click.Choice(HOOK_TYPES))
def uninstall(hook_type):
"""Uninstall a specific git hook"""
hook_path = os.path.join(".git", "hooks", hook_type)
if os.path.exists(hook_path):
os.remove(hook_path)
click.echo(f"{hook_type} hook uninstalled successfully")
else:
click.echo(f"{hook_type} hook not found")


@hooks.command()
def uninstall_all():
"""Uninstall all git hooks"""
for hook_type in HOOK_TYPES:
ctx = click.get_current_context()
ctx.invoke(uninstall, hook_type=hook_type)
4 changes: 2 additions & 2 deletions cli/poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion cli/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ readme = "README.md"
[tool.poetry.dependencies]
python = "^3.9.0"
click = "^8.1.3"
kaizen-cloudcode = "^0.4.11"
kaizen-cloudcode = "^0.4.12"

[tool.poetry.group.dev.dependencies]
kaizen-cloudcode = {path = "..", develop = true, optional = true}
Expand Down
100 changes: 84 additions & 16 deletions kaizen/retriever/code_chunker.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,43 +7,100 @@
def chunk_code(code: str, language: str) -> ParsedBody:
parser = ParserFactory.get_parser(language)
tree = parser.parse(code.encode("utf8"))

code_bytes = code.encode("utf8")
body: ParsedBody = {
"imports": [],
"global_variables": [],
"type_definitions": [],
"functions": {},
"async_functions": {},
"classes": {},
"hooks": {},
"components": {},
"jsx_elements": [],
"other_blocks": [],
}
# code_bytes = code.encode("utf8")

def process_node(node):
result = parse_code(code, language)
result = parse_code(node, code_bytes)
if result:
# Assuming parse_code is modified to return line numbers
start_line = result.get("start_line", 0)
end_line = result.get("end_line", 0)

if result["type"] == "function":
if result["type"] == "import_statement":
body["imports"].append(
{
"code": result["code"],
"start_line": start_line,
"end_line": end_line,
}
)
elif (
result["type"] == "variable_declaration"
and node.parent.type == "program"
):
body["global_variables"].append(
{
"code": result["code"],
"start_line": start_line,
"end_line": end_line,
}
)
elif result["type"] in ["type_alias", "interface_declaration"]:
body["type_definitions"].append(
{
"name": result["name"],
"code": result["code"],
"start_line": start_line,
"end_line": end_line,
}
)
elif result["type"] == "function":
if is_react_hook(result["name"]):
body["hooks"][result["name"]] = {
"code": result["code"],
"start_line": start_line,
"end_line": end_line,
}
elif is_react_component(result["code"]):
body["components"][result["name"]] = result["code"]
body["components"][result["name"]] = {
"code": result["code"],
"start_line": start_line,
"end_line": end_line,
}
elif "async" in result["code"].split()[0]:
body["async_functions"][result["name"]] = {
"code": result["code"],
"start_line": start_line,
"end_line": end_line,
}
else:
body["functions"][result["name"]] = result["code"]
body["functions"][result["name"]] = {
"code": result["code"],
"start_line": start_line,
"end_line": end_line,
}
elif result["type"] == "class":
if is_react_component(result["code"]):
body["components"][result["name"]] = result["code"]
body["components"][result["name"]] = {
"code": result["code"],
"start_line": start_line,
"end_line": end_line,
}
else:
body["classes"][result["name"]] = result["code"]
elif result["type"] == "component":
body["components"][result["name"]] = result["code"]
elif result["type"] == "impl":
body["classes"][result["name"]] = result["code"]
body["classes"][result["name"]] = {
"code": result["code"],
"start_line": start_line,
"end_line": end_line,
}
elif result["type"] == "jsx_element":
body["jsx_elements"].append(
{
"code": result["code"],
"start_line": start_line,
"end_line": end_line,
}
)
else:
for child in node.children:
process_node(child)
Expand All @@ -55,8 +112,14 @@ def process_node(node):
for section in body.values():
if isinstance(section, dict):
for code_block in section.values():
start = code.index(code_block)
collected_ranges.append((start, start + len(code_block)))
collected_ranges.append(
(code_block["start_line"], code_block["end_line"])
)
elif isinstance(section, list):
for code_block in section:
collected_ranges.append(
(code_block["start_line"], code_block["end_line"])
)

collected_ranges.sort()
last_end = 0
Expand All @@ -76,5 +139,10 @@ def is_react_hook(name: str) -> bool:

def is_react_component(code: str) -> bool:
return (
"React" in code or "jsx" in code.lower() or "tsx" in code.lower() or "<" in code
"React" in code
or "jsx" in code.lower()
or "tsx" in code.lower()
or "<" in code
or "props" in code
or "render" in code
)
Loading

0 comments on commit 0a62cd9

Please sign in to comment.