utils.py•3.29 kB
from datetime import datetime
def format_date(iso_date_string):
"""Convert ISO date to human-readable format"""
try:
dt = datetime.fromisoformat(iso_date_string.replace('Z', '+00:00'))
return dt.strftime('%Y-%m-%d %H:%M UTC')
except ValueError:
return iso_date_string
def get_state_explanation(state):
"""Get human-readable explanation of MR state"""
explanations = {
'opened': 'Ready for review',
'merged': 'Successfully merged',
'closed': 'Closed without merging',
'locked': 'Locked (no new discussions)',
'draft': 'Work in progress'
}
return explanations.get(state, state)
def get_pipeline_status_icon(status):
"""Get emoji for pipeline status"""
if not status:
return '⚪'
icons = {
'success': '✅',
'failed': '❌',
'running': '🔄',
'pending': '⏳',
'canceled': '⏹️',
'skipped': '⏭️',
'manual': '👤'
}
return icons.get(status, '❓')
def calculate_change_stats(changes):
"""Calculate lines added/removed from changes"""
if not changes or 'changes' not in changes:
return "No changes"
additions = 0
deletions = 0
for change in changes['changes']:
if 'diff' in change:
diff_lines = change['diff'].split('\n')
for line in diff_lines:
if line.startswith('+') and not line.startswith('+++'):
additions += 1
elif line.startswith('-') and not line.startswith('---'):
deletions += 1
return f"+{additions}/-{deletions}"
def analyze_mr_readiness(mr_data, pipeline_data=None, approvals=None):
"""Analyze if MR is ready to merge and what's blocking it"""
blockers = []
if mr_data.get('draft') or mr_data.get('work_in_progress'):
blockers.append("🚧 Draft/WIP status")
if mr_data.get('has_conflicts'):
blockers.append("⚠️ Merge conflicts")
if pipeline_data and pipeline_data.get('status') == 'failed':
blockers.append("❌ Pipeline failed")
elif pipeline_data and pipeline_data.get('status') == 'running':
blockers.append("🔄 Pipeline running")
if approvals and 'approvals_required' in approvals:
approved_count = len(approvals.get('approved_by', []))
required_count = approvals.get('approvals_required', 0)
if approved_count < required_count:
msg = f"👥 Needs approval ({approved_count}/{required_count})"
blockers.append(msg)
if mr_data.get('merge_status') == 'cannot_be_merged':
blockers.append("🚫 Cannot be merged")
if not blockers:
return "✅ Ready to merge"
else:
return f"🚫 Blocked by: {', '.join(blockers)}"
def get_mr_priority(mr_data):
"""Determine MR priority based on labels and other factors"""
labels = mr_data.get('labels', [])
for label in labels:
if 'critical' in label.lower() or 'urgent' in label.lower():
return '🔴 Critical'
elif 'high' in label.lower():
return '🟡 High'
elif 'low' in label.lower():
return '🟢 Low'
return '⚪ Normal'