diff --git a/constants/dependency_files.py b/constants/dependency_files.py new file mode 100644 index 00000000..526c8c02 --- /dev/null +++ b/constants/dependency_files.py @@ -0,0 +1,133 @@ +CONFIGURATION_FILES_JS = [ + "angular.json", + "babel.config.js", + "next.config.js", + "nuxt.config.js", + "package.json", + "remix.config.js", + "rollup.config.js", + "svelte.config.js", + "tsconfig.json", + "vite.config.js", + "vue.config.js", + "webpack.config.js", +] + +CONFIGURATION_FILES_PYTHON = [ + "requirements.txt", # Standard, a dependency manager + "Pipfile", # by pipenv, a dependency manager + "pyproject.toml", # by poetry, a dependency manager + "conda.yaml", # by conda, a dependency manager + "environment.yml", # by conda, a dependency manager + "django.settings.py", # by django, a framework + "setup.py", # Traditional +] + +CONFIGURATION_FILES_RUBY = [ + "Gemfile", # Bundler, a dependency manager + "application.rb", # Rails, a framework +] + +CONFIGURATION_FILES_PHP = [ + "composer.json", # Composer, a dependency manager + "artisan", # Laravel, a framework + "wp-config.php", # WordPress, a CMS +] + +CONFIGURATION_FILES_JAVA = [ + "pom.xml", # Maven + "build.gradle", # Gradle build file + "build.gradle.kts", # Gradle Kotlin build file + "settings.gradle", # Gradle settings file + "settings.gradle.kts", # Gradle Kotlin settings file + "gradle.properties", # Gradle properties file + "ivy.xml", # Apache Ivy configuration + "build.xml", # Apache Ant build file + "AndroidManifest.xml", # Android manifest file +] + +CONFIGURATION_FILES_C = [ + "CMakeLists.txt", # CMake, a build system + "Makefile", # Makefile, a build system + "configure.ac", # Autotools, a build system + "*.vcxproj", # Visual Studio, a build system + "*.pro", # Qt, a build system + "conanfile.txt", # Conan, a build system + "meson.build", # Meson, a build system +] + +CONFIGURATION_FILES_DOTNET = [ + "packages.config", # NuGet, a dependency manager + "*.csproj", # C# project file + "*.fsproj", # F# project file + "*.vbproj", # VB.NET project file + "paket.dependencies", # Paket, a dependency manager + "nuget.config", # NuGet, a dependency manager + "appsettings.json", # ASP.NET Core, a framework + "web.config", # ASP.NET Core, a framework +] + +CONFIGURATION_FILES_GO = [ + "go.mod", # Go, a dependency manager + "go.sum", # Go, a dependency manager +] + +CONFIGURATION_FILES_RUST = [ + "Cargo.toml", # Cargo, a dependency manager +] + +CONFIGURATION_FILES_SWIFT = [ + "Package.swift", # Swift, a dependency manager + "Podfile", # CocoaPods, a dependency manager + "Cartfile", # Carthage, a dependency manager +] + +CONFIGURATION_FILES_ELIXIR = [ + "mix.exs", # Mix, a dependency manager +] + +CONFIGURATION_FILES_HASKELL = [ + "package.yaml", # Haskell, a dependency manager + "*.cabal", # Haskell, a dependency manager +] + +CONFIGURATION_FILES_SHELL = [ + ".bashrc", + ".zshrc", +] + +CONFIGURATION_FILES_AWS = [ + "*.tf", # Terraform, a configuration management tool + "terraform.tfstate", # Terraform, a configuration management tool +] + +CONFIGURATION_FILES_DOCKER = [ + "Dockerfile", # Dockerfile, a containerization tool + "docker-compose.yml", # Docker Compose, a containerization tool + "docker-compose.yaml", # Docker Compose, a containerization tool +] + +CONFIGURATION_FILES = [ + *CONFIGURATION_FILES_JS, + *CONFIGURATION_FILES_PYTHON, + *CONFIGURATION_FILES_RUBY, + *CONFIGURATION_FILES_PHP, + *CONFIGURATION_FILES_JAVA, + *CONFIGURATION_FILES_C, + *CONFIGURATION_FILES_DOTNET, + *CONFIGURATION_FILES_GO, + *CONFIGURATION_FILES_SWIFT, + *CONFIGURATION_FILES_RUST, + *CONFIGURATION_FILES_ELIXIR, + *CONFIGURATION_FILES_HASKELL, + *CONFIGURATION_FILES_AWS, + *CONFIGURATION_FILES_DOCKER, + "pubspec.yaml", # Dart/Flutter, a dependency manager + "DESCRIPTION", # R, a dependency manager + "build.sbt", # Scala, a build system + "project.clj", # Clojure, a build system + "rebar.config", # Erlang, a build system + "dune-project", # OCaml, a build system + "*.opam", # OCaml, a build system + "*.nimble", # Nim, a build system +] diff --git a/services/gitauto_handler.py b/services/gitauto_handler.py index 86fc3313..7e3f24d3 100644 --- a/services/gitauto_handler.py +++ b/services/gitauto_handler.py @@ -15,11 +15,13 @@ ) from services.github.asset_manager import get_base64, render_text from services.github.comment_manager import delete_my_comments +from services.github.file_manager import find_config_files from services.github.github_manager import ( create_pull_request, create_remote_branch, get_issue_comments, get_latest_remote_commit_sha, + get_remote_file_content, get_remote_file_content_by_url, get_remote_file_tree, create_comment, @@ -123,10 +125,17 @@ async def handle_gitauto( issue_number=issue_number, content="eyes", base_args=base_args ) - # Check out the issue comments, and root files/directories list - comment_body = "Checking the issue title, body, comments, and root files list..." + # Check out the issue comments, and file tree + comment_body = "Checking the issue title, body, comments, and file tree..." update_comment(body=comment_body, base_args=base_args, p=10) - root_files_and_dirs: list[str] = get_remote_file_tree(base_args=base_args) + file_tree: list[str] = get_remote_file_tree(base_args=base_args) + config_files: list[str] = find_config_files(file_tree=file_tree) + config_contents: list[str] = [] + for config_file in config_files: + content = get_remote_file_content(file_path=config_file, base_args=base_args) + config_contents.append(content) + + # Check out the issue comments issue_comments: list[str] = [] if input_from == "github": issue_comments = get_issue_comments( @@ -168,7 +177,9 @@ async def handle_gitauto( "issue_body": issue_body, "reference_contents": reference_contents, "issue_comments": issue_comments, - "root_files_and_dirs": root_files_and_dirs, + "file_tree": file_tree, + "config_contents": config_contents, + "metadata": base_args, } ), ) @@ -177,7 +188,12 @@ async def handle_gitauto( # Ask for help if needed like a human would do comment_body = "Checking if I can solve it or if I should just hit you up..." update_comment(body=comment_body, base_args=base_args, p=25) - messages = [{"role": "user", "content": pr_body}] + messages = [ + {"role": "user", "content": pr_body}, + {"role": "user", "content": f"File tree:\n{file_tree}"}, + {"role": "user", "content": f"Config contents:\n{config_contents}"}, + {"role": "user", "content": f"Metadata:\n{base_args}"}, + ] (*_, token_input, token_output, is_commented) = chat_with_agent( messages=messages, base_args=base_args, mode="comment" ) diff --git a/services/github/file_manager.py b/services/github/file_manager.py new file mode 100644 index 00000000..9017bbfa --- /dev/null +++ b/services/github/file_manager.py @@ -0,0 +1,23 @@ +from constants.dependency_files import CONFIGURATION_FILES +from utils.handle_exceptions import handle_exceptions + + +@handle_exceptions(default_return_value=[], raise_on_error=False) +def find_config_files(file_tree: list[str]) -> list[str]: + """Search for configuration files in the file tree""" + config_files = [] + + for file_path in file_tree: + file_name = file_path.split("/")[-1] + for dep_file in CONFIGURATION_FILES: + + # Wildcard matching (e.g., *.csproj) + if dep_file.startswith("*") and file_name.endswith(dep_file[1:]): + config_files.append(file_path) + + # Exact match + elif file_name == dep_file: + config_files.append(file_path) + + print(f"config_files: {config_files}") + return config_files diff --git a/services/github/github_manager.py b/services/github/github_manager.py index 9a11db92..16232bc3 100644 --- a/services/github/github_manager.py +++ b/services/github/github_manager.py @@ -705,7 +705,9 @@ def get_remote_file_tree(base_args: BaseArgs, max_files: int = 1000) -> list[str else: print(f"Found {total_files} files across {max_depth + 1} directory levels") - print(f"Found {len(result)} files") + # Sort the result by alphabetical order + result.sort() + return result