Files
dbis_docs/scripts/fix_moved_file_references.py

137 lines
6.1 KiB
Python
Raw Normal View History

#!/usr/bin/env python3
"""
Script to fix references to files that were moved to subdirectories.
Updates relative paths in markdown files to reflect new file locations.
"""
import os
import re
from pathlib import Path
# Mapping of old paths to new paths
FILE_MOVES = {
# Project management files
'IMPLEMENTATION_STATUS.md': 'project_management/IMPLEMENTATION_STATUS.md',
'IMPLEMENTATION_TASK_LIST.md': 'project_management/IMPLEMENTATION_TASK_LIST.md',
'IMPLEMENTATION_READINESS_REPORT.md': 'project_management/IMPLEMENTATION_READINESS_REPORT.md',
'PHASE_1_COMPLETION_SUMMARY.md': 'project_management/PHASE_1_COMPLETION_SUMMARY.md',
'PHASE_2_PLANNING.md': 'project_management/PHASE_2_PLANNING.md',
'PHASE_2_QUICK_START.md': 'project_management/PHASE_2_QUICK_START.md',
'PHASE_2_PROGRESS_REPORT.md': 'project_management/PHASE_2_PROGRESS_REPORT.md',
'PHASE_2_CONTENT_COMPLETE.md': 'project_management/PHASE_2_CONTENT_COMPLETE.md',
'PHASE_2_FINAL_SUMMARY.md': 'project_management/PHASE_2_FINAL_SUMMARY.md',
'PROJECT_STATUS.md': 'project_management/PROJECT_STATUS.md',
'FINAL_PROJECT_STATUS.md': 'project_management/FINAL_PROJECT_STATUS.md',
'COMPREHENSIVE_FINAL_STATUS.md': 'project_management/COMPREHENSIVE_FINAL_STATUS.md',
'ALL_TASKS_COMPLETE_FINAL.md': 'project_management/ALL_TASKS_COMPLETE_FINAL.md',
'COMPLETE_PROJECT_SUMMARY.md': 'project_management/COMPLETE_PROJECT_SUMMARY.md',
'PROJECT_COMPLETION_CERTIFICATE.md': 'project_management/PROJECT_COMPLETION_CERTIFICATE.md',
'FINAL_EXECUTION_READINESS.md': 'project_management/FINAL_EXECUTION_READINESS.md',
'NEXT_STEPS_EXECUTION_SUMMARY.md': 'project_management/NEXT_STEPS_EXECUTION_SUMMARY.md',
'REMAINING_TASKS_EXECUTION_SUMMARY.md': 'project_management/REMAINING_TASKS_EXECUTION_SUMMARY.md',
'COMPLETION_REPORT.md': 'project_management/COMPLETION_REPORT.md',
'FINAL_COMPLETION_SUMMARY.md': 'project_management/FINAL_COMPLETION_SUMMARY.md',
'COMPREHENSIVE_FINAL_REPORT.md': 'project_management/COMPREHENSIVE_FINAL_REPORT.md',
'PROJECT_COMPLETE_SUMMARY.md': 'project_management/PROJECT_COMPLETE_SUMMARY.md',
'ALL_TASKS_COMPLETE.md': 'project_management/ALL_TASKS_COMPLETE.md',
# FAQ files
'FAQ_General.md': 'faq/FAQ_General.md',
'FAQ_Technical.md': 'faq/FAQ_Technical.md',
'FAQ_Compliance.md': 'faq/FAQ_Compliance.md',
'FAQ_Operational.md': 'faq/FAQ_Operational.md',
}
def get_relative_path(from_file, to_file):
"""Calculate relative path from one file to another."""
from_path = Path(from_file).parent
to_path = Path(to_file)
return os.path.relpath(to_path, from_path)
def fix_links_in_file(file_path, project_root):
"""Fix links in a single file."""
try:
with open(file_path, 'r', encoding='utf-8') as f:
content = f.read()
original_content = content
file_dir = os.path.dirname(file_path)
# Fix markdown links: [text](path/to/file.md)
for old_path, new_path in FILE_MOVES.items():
# Pattern for markdown links
pattern = r'(\[([^\]]+)\]\(([^)]*' + re.escape(old_path) + r'[^)]*)\))'
def replace_link(match):
full_match = match.group(0)
link_text = match.group(2)
link_path = match.group(3)
# Calculate correct relative path
if link_path == old_path:
# Simple case: just the filename
correct_path = get_relative_path(file_path, os.path.join(project_root, new_path))
elif link_path.startswith('./') or link_path.startswith('../'):
# Already a relative path, need to resolve it
resolved_old = os.path.normpath(os.path.join(file_dir, link_path))
if resolved_old == os.path.join(project_root, old_path):
correct_path = get_relative_path(file_path, os.path.join(project_root, new_path))
else:
return full_match # Don't change if path doesn't match
else:
# Absolute or other format
if old_path in link_path:
# Replace the old path with new path
link_path = link_path.replace(old_path, new_path)
correct_path = get_relative_path(file_path, os.path.join(project_root, link_path))
else:
return full_match
return f'[{link_text}]({correct_path})'
content = re.sub(pattern, replace_link, content)
# Also fix plain references without markdown syntax
# Pattern: `old_path` or "old_path" or 'old_path'
for quote in ['`', '"', "'"]:
pattern = quote + re.escape(old_path) + quote
correct_path = get_relative_path(file_path, os.path.join(project_root, new_path))
content = re.sub(pattern, quote + correct_path + quote, content)
if content != original_content:
with open(file_path, 'w', encoding='utf-8') as f:
f.write(content)
return True
return False
except Exception as e:
print(f"Error processing {file_path}: {e}")
return False
def main():
project_root = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
# Find all markdown files
md_files = []
for root, dirs, files in os.walk(project_root):
# Skip .git and other hidden directories
dirs[:] = [d for d in dirs if not d.startswith('.')]
for file in files:
if file.endswith('.md'):
md_files.append(os.path.join(root, file))
print(f"Found {len(md_files)} markdown files")
print("Fixing references to moved files...")
fixed_count = 0
for md_file in md_files:
if fix_links_in_file(md_file, project_root):
fixed_count += 1
print(f"Fixed: {os.path.relpath(md_file, project_root)}")
print(f"\nFixed {fixed_count} files")
if __name__ == '__main__':
main()