Skip to content

Commit

Permalink
Add support for Go language (#42)
Browse files Browse the repository at this point in the history
* fix saving structure

* allow processing go files

* remove debugging lines

* add go agreggator
  • Loading branch information
betogaona7 authored Sep 11, 2023
1 parent deec693 commit f340a31
Show file tree
Hide file tree
Showing 4 changed files with 101 additions and 4 deletions.
11 changes: 9 additions & 2 deletions cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
import click
from dotenv import load_dotenv

from devtale.aggregators import PHPAggregator, PythonAggregator
from devtale.aggregators import GoAggregator, PHPAggregator, PythonAggregator
from devtale.constants import ALLOWED_EXTENSIONS, LANGUAGES
from devtale.utils import (
build_project_tree,
Expand Down Expand Up @@ -59,6 +59,8 @@ def process_repository(

for folder_path in folders:
try:
if folder_path == root_path:
folder_path += "/"
folder_tale = process_folder(folder_path, output_path, model_name, fuse)
except Exception as e:
folder_name = os.path.basename(folder_path)
Expand All @@ -69,7 +71,10 @@ def process_repository(

if folder_tale is not None:
# add root folder summary information
if folder_path == root_path:
if (
os.path.basename(folder_path) == os.path.basename(root_path)
or folder_path == ""
):
folder_tales["folders"].append(
{
"folder_name": os.path.basename(os.path.abspath(root_path)),
Expand Down Expand Up @@ -247,6 +252,8 @@ def process_file(
aggregator = PythonAggregator()
elif file_ext == ".php":
aggregator = PHPAggregator()
elif file_ext == ".go":
aggregator = GoAggregator()

fused_tale = aggregator.document(code=code, documentation=tale)
with open(save_path, "w") as file:
Expand Down
3 changes: 2 additions & 1 deletion devtale/aggregators/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from .go import GoAggregator
from .php import PHPAggregator
from .python import PythonAggregator

__all__ = ["PHPAggregator", "PythonAggregator"]
__all__ = ["PHPAggregator", "PythonAggregator", "GoAggregator"]
87 changes: 87 additions & 0 deletions devtale/aggregators/go.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
import re


class GoAggregator:
def __init__(self):
pass

def document(self, documentation, code):
documented_code = code
documented_code = self._document_file(documentation, documented_code)
documented_code = self._add_docstrings(
documentation, documented_code, type="method"
)
documented_code = self._add_docstrings(
documentation, documented_code, type="class"
)
return documented_code

def _add_docstrings(self, documentation, code, type="method"):
if type == "method":
pattern = r"func \([\w\s\*]+\) (\w+)[^\n]*{|\bfunc (\w+)[^\n]*{"
docstrings = {
item["method_name"]: item["method_docstring"]
for item in documentation["methods"]
}
else:
pattern = r"type\s+([A-Z][a-zA-Z0-9_]*)\s+(struct|interface)\s*\{"
docstrings = {
item["class_name"]: item["class_docstring"]
for item in documentation["classes"]
}

updated_code_lines = []
matches = re.finditer(pattern, code)
last_end = 0

for match in matches:
name = match.group(1) or match.group(2)
index = match.start()

opening_brace_index = code.find("{", index)

if opening_brace_index != -1:
signature = code[index : opening_brace_index + 1]
lines_before = code[:index].split("\n")[-3:]
existing_docstring = any(
line.strip().startswith("//") or "*/" in line
for line in lines_before
)

if name in docstrings:
docstring = docstrings[name]
if not existing_docstring:
fixed_docstring = self._break_large_strings(docstring)
signature = f"{fixed_docstring}\n{signature}"

updated_code_lines.append(code[last_end:index])
updated_code_lines.append(signature)
last_end = opening_brace_index + 1

# append any remaining code
updated_code_lines.append(code[last_end:])
documented_code = "".join(updated_code_lines)
return documented_code

def _break_large_strings(self, string, max_lenght=90):
words = string.split()
lines = []
current_line = ""
for word in words:
if len(current_line) + len(word) + 1 <= max_lenght:
if current_line:
current_line += " "
current_line += word
else:
lines.append(current_line)
current_line = word
if current_line:
lines.append(current_line)

return "\n".join(["// " + line for line in lines])

def _document_file(self, documentation, code):
file_description = self._break_large_strings(documentation["file_docstring"])
code = file_description + "\n" + code

return code
4 changes: 3 additions & 1 deletion devtale/constants.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
from langchain.text_splitter import Language

# we are only documenting the file that ends with the following extensions:
ALLOWED_EXTENSIONS = [".php", ".py", ""]
ALLOWED_EXTENSIONS = [".go", ".php", ".py", ""]

# split code files according the programming language
LANGUAGES = {
".php": Language.PHP,
".py": Language.PYTHON,
".go": Language.GO,
".cpp": Language.CPP,
".java": Language.JAVA,
".js": Language.JS,
Expand All @@ -16,6 +17,7 @@
IDENTIFIERS = {
"php": [["class"], ["function"]],
"python": [["class"], ["def"]],
"go": [["struct"], ["func"]],
"cpp": [["class"], ["void", "int", "float", "double"]],
"java": [["class"], ["public", "protected", "private", "static"]],
"js": [["class"], ["function", "const", "let", "var"]],
Expand Down

0 comments on commit f340a31

Please sign in to comment.