diff --git a/backend/app/git/status/incoming_changes.py b/backend/app/git/status/incoming_changes.py index 8cb8053..ae770f6 100644 --- a/backend/app/git/status/incoming_changes.py +++ b/backend/app/git/status/incoming_changes.py @@ -2,33 +2,50 @@ import os import logging -from .utils import extract_data_from_yaml, determine_type +from .utils import extract_data_from_yaml, determine_type, parse_commit_message logger = logging.getLogger(__name__) + def get_incoming_changes(repo, branch): incoming_changes = [] diff = repo.git.diff(f'HEAD...origin/{branch}', name_only=True) changed_files = diff.split('\n') if diff else [] - + for file_path in changed_files: if file_path: full_path = os.path.join(repo.working_dir, file_path) - file_data = extract_data_from_yaml(full_path) if os.path.exists(full_path) else None - + file_data = extract_data_from_yaml(full_path) if os.path.exists( + full_path) else None + # Correcting the git show command - commit_message = repo.git.show(f'HEAD...origin/{branch}', '--format=%B', '-s', file_path).strip() - + raw_commit_message = repo.git.show(f'HEAD...origin/{branch}', + '--format=%B', '-s', + file_path).strip() + parsed_commit_message = parse_commit_message( + raw_commit_message + ) # Parse commit message using the util function + incoming_changes.append({ - 'name': file_data.get('name', os.path.basename(file_path)) if file_data else os.path.basename(file_path), - 'id': file_data.get('id') if file_data else None, - 'type': determine_type(file_path), - 'status': 'Incoming', - 'file_path': file_path, - 'commit_message': commit_message, # Include commit message here - 'staged': False, - 'modified': True, - 'deleted': False + 'name': + file_data.get('name', os.path.basename(file_path)) + if file_data else os.path.basename(file_path), + 'id': + file_data.get('id') if file_data else None, + 'type': + determine_type(file_path), + 'status': + 'Incoming', + 'file_path': + file_path, + 'commit_message': + parsed_commit_message, # Use parsed commit message + 'staged': + False, + 'modified': + True, + 'deleted': + False }) - - return incoming_changes \ No newline at end of file + + return incoming_changes diff --git a/backend/app/git/status/utils.py b/backend/app/git/status/utils.py index f8866f1..00d9784 100644 --- a/backend/app/git/status/utils.py +++ b/backend/app/git/status/utils.py @@ -3,31 +3,34 @@ import os import yaml import logging +import re logger = logging.getLogger(__name__) + def extract_data_from_yaml(file_path): logger.debug(f"Extracting data from file: {file_path}") try: with open(file_path, 'r') as f: content = yaml.safe_load(f) - logger.debug(f"File content: {content}") # Log the full file content + logger.debug( + f"File content: {content}") # Log the full file content if content is None: - logger.error(f"Failed to parse YAML file or file is empty: {file_path}") + logger.error( + f"Failed to parse YAML file or file is empty: {file_path}") return None - + # Check if expected keys are in the content if 'name' not in content or 'id' not in content: - logger.warning(f"'name' or 'id' not found in file: {file_path}") - - return { - 'name': content.get('name'), - 'id': content.get('id') - } + logger.warning( + f"'name' or 'id' not found in file: {file_path}") + + return {'name': content.get('name'), 'id': content.get('id')} except Exception as e: logger.warning(f"Error reading file {file_path}: {str(e)}") return None + def determine_type(file_path): if 'regex_patterns' in file_path: return 'Regex Pattern' @@ -37,6 +40,7 @@ def determine_type(file_path): return 'Quality Profile' return 'Unknown' + def interpret_git_status(x, y): if x == 'D' or y == 'D': return 'Deleted' @@ -54,3 +58,89 @@ def interpret_git_status(x, y): return 'Untracked' else: return 'Unknown' + + +def parse_commit_message(commit_message): + # Default placeholders for missing parts of the commit message + placeholders = { + 'type': 'Unknown Type', + 'scope': 'Unknown Scope', + 'subject': 'No subject provided', + 'body': 'No body provided', + 'footer': 'No footer provided' + } + + # Mapping of commit types and scopes to canonical forms + type_mapping = { + 'feat': 'New Feature', + 'feature': 'New Feature', + 'new': 'New Feature', + 'fix': 'BugFix', + 'bugfix': 'BugFix', + 'bug': 'BugFix', + 'docs': 'Documentation', + 'documentation': 'Documentation', + 'doc': 'Documentation', + 'style': 'Style Change', + 'formatting': 'Style Change', + 'format': 'Style Change', + 'lint': 'Style Change', + 'refactor': 'Refactor', + 'refactoring': 'Refactor', + 'restructure': 'Refactor', + 'redesign': 'Refactor', + 'perf': 'Performance Improvement', + 'performance': 'Performance Improvement', + 'optimize': 'Performance Improvement', + 'optimisation': 'Performance Improvement', + 'test': 'Test', + 'testing': 'Test', + 'chore': 'Maintenance', + 'maintenance': 'Maintenance', + 'maintain': 'Maintenance' + } + + scope_mapping = { + 'regex': 'Regex Pattern', + 'regex pattern': 'Regex Pattern', + 'format': 'Custom Format', + 'custom format': 'Custom Format', + 'profile': 'Quality Profile', + 'quality profile': 'Quality Profile' + } + + # Regex patterns for each part of the commit message + type_pattern = r'^(?Pfeat|feature|new|fix|bugfix|bug|docs|documentation|doc|style|formatting|format|lint|refactor|refactoring|restructure|redesign|perf|performance|optimize|optimisation|test|testing|chore|maintenance|maintain)' + scope_pattern = r'\((?Pregex|regex pattern|format|custom format|profile|quality profile)\)' + subject_pattern = r':\s(?P.+)' + body_pattern = r'(?P(?:- .+\n?)+)' # Handles multiple lines in the body + footer_pattern = r'(?P