Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 25 additions & 8 deletions pr_agent/algo/git_patch_processing.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@
from pr_agent.config_loader import get_settings
from pr_agent.log import get_logger

_settings_cache = None

_patch_extensions_cache = None


def extend_patch(original_file_str, patch_str, patch_extra_lines_before=0,
patch_extra_lines_after=0, filename: str = "", new_file_str="") -> str:
Expand Down Expand Up @@ -47,9 +51,20 @@ def decode_if_bytes(original_file_str):


def should_skip_patch(filename):
patch_extension_skip_types = get_settings().config.patch_extension_skip_types
global _settings_cache, _patch_extensions_cache

if _settings_cache is None:
_settings_cache = get_settings()

if _patch_extensions_cache is None:
patch_extension_skip_types = _settings_cache.config.patch_extension_skip_types
if patch_extension_skip_types and not isinstance(patch_extension_skip_types, tuple):
patch_extension_skip_types = tuple(patch_extension_skip_types)
_patch_extensions_cache = patch_extension_skip_types

patch_extension_skip_types = _patch_extensions_cache
if patch_extension_skip_types and filename:
return any(filename.endswith(skip_type) for skip_type in patch_extension_skip_types)
return filename.endswith(patch_extension_skip_types)
return False


Expand Down Expand Up @@ -212,14 +227,16 @@ def check_if_hunk_lines_matches_to_file(i, original_lines, patch_lines, start1):


def extract_hunk_headers(match):
res = list(match.groups())
for i in range(len(res)):
if res[i] is None:
res[i] = 0
res = match.groups()
try:
start1, size1, start2, size2 = map(int, res[:4])
start1 = int(res[0]) if res[0] is not None else 0
size1 = int(res[1]) if res[1] is not None else 0
start2 = int(res[2]) if res[2] is not None else 0
size2 = int(res[3]) if res[3] is not None else 0
except: # '@@ -0,0 +1 @@' case
start1, size1, size2 = map(int, res[:3])
start1 = int(res[0]) if res[0] is not None else 0
size1 = int(res[1]) if res[1] is not None else 0
size2 = int(res[2]) if res[2] is not None else 0
start2 = 0
section_header = res[4]
return section_header, size1, size2, start1, start2
Expand Down
71 changes: 40 additions & 31 deletions pr_agent/config_loader.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,35 +5,38 @@
from dynaconf import Dynaconf
from starlette_context import context

PR_AGENT_TOML_KEY = 'pr-agent'
PR_AGENT_TOML_KEY = "pr-agent"

current_dir = dirname(abspath(__file__))
global_settings = Dynaconf(
envvar_prefix=False,
merge_enabled=True,
settings_files=[join(current_dir, f) for f in [
"settings/configuration.toml",
"settings/ignore.toml",
"settings/generated_code_ignore.toml",
"settings/language_extensions.toml",
"settings/pr_reviewer_prompts.toml",
"settings/pr_questions_prompts.toml",
"settings/pr_line_questions_prompts.toml",
"settings/pr_description_prompts.toml",
"settings/code_suggestions/pr_code_suggestions_prompts.toml",
"settings/code_suggestions/pr_code_suggestions_prompts_not_decoupled.toml",
"settings/code_suggestions/pr_code_suggestions_reflect_prompts.toml",
"settings/pr_information_from_user_prompts.toml",
"settings/pr_update_changelog_prompts.toml",
"settings/pr_custom_labels.toml",
"settings/pr_add_docs.toml",
"settings/custom_labels.toml",
"settings/pr_help_prompts.toml",
"settings/pr_help_docs_prompts.toml",
"settings/pr_help_docs_headings_prompts.toml",
"settings/.secrets.toml",
"settings_prod/.secrets.toml",
]]
settings_files=[
join(current_dir, f)
for f in [
"settings/configuration.toml",
"settings/ignore.toml",
"settings/generated_code_ignore.toml",
"settings/language_extensions.toml",
"settings/pr_reviewer_prompts.toml",
"settings/pr_questions_prompts.toml",
"settings/pr_line_questions_prompts.toml",
"settings/pr_description_prompts.toml",
"settings/code_suggestions/pr_code_suggestions_prompts.toml",
"settings/code_suggestions/pr_code_suggestions_prompts_not_decoupled.toml",
"settings/code_suggestions/pr_code_suggestions_reflect_prompts.toml",
"settings/pr_information_from_user_prompts.toml",
"settings/pr_update_changelog_prompts.toml",
"settings/pr_custom_labels.toml",
"settings/pr_add_docs.toml",
"settings/custom_labels.toml",
"settings/pr_help_prompts.toml",
"settings/pr_help_docs_prompts.toml",
"settings/pr_help_docs_headings_prompts.toml",
"settings/.secrets.toml",
"settings_prod/.secrets.toml",
]
],
)


Expand Down Expand Up @@ -81,7 +84,7 @@ def _find_pyproject() -> Optional[Path]:

pyproject_path = _find_pyproject()
if pyproject_path is not None:
get_settings().load_file(pyproject_path, env=f'tool.{PR_AGENT_TOML_KEY}')
get_settings().load_file(pyproject_path, env=f"tool.{PR_AGENT_TOML_KEY}")


def apply_secrets_manager_config():
Expand All @@ -90,15 +93,17 @@ def apply_secrets_manager_config():
"""
try:
# Dynamic imports to avoid circular dependency (secret_providers imports config_loader)
from pr_agent.secret_providers import get_secret_provider
from pr_agent.log import get_logger
from pr_agent.secret_providers import get_secret_provider

secret_provider = get_secret_provider()
if not secret_provider:
return

if (hasattr(secret_provider, 'get_all_secrets') and
get_settings().get("CONFIG.SECRET_PROVIDER") == 'aws_secrets_manager'):
if (
hasattr(secret_provider, "get_all_secrets")
and get_settings().get("CONFIG.SECRET_PROVIDER") == "aws_secrets_manager"
):
try:
secrets = secret_provider.get_all_secrets()
if secrets:
Expand All @@ -109,6 +114,7 @@ def apply_secrets_manager_config():
except Exception as e:
try:
from pr_agent.log import get_logger

get_logger().debug(f"Secret provider not configured: {e}")
except:
# Fail completely silently if log module is not available
Expand All @@ -123,14 +129,17 @@ def apply_secrets_to_config(secrets: dict):
# Dynamic import to avoid potential circular dependency
from pr_agent.log import get_logger
except:

def get_logger():
class DummyLogger:
def debug(self, msg): pass
def debug(self, msg):
pass

return DummyLogger()

for key, value in secrets.items():
if '.' in key: # nested key like "openai.key"
parts = key.split('.')
if "." in key: # nested key like "openai.key"
parts = key.split(".")
if len(parts) == 2:
section, setting = parts
section_upper = section.upper()
Expand Down