mirror of
				https://github.com/Theodor-Springmann-Stiftung/lenz-briefe.git
				synced 2025-10-30 09:25:29 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			107 lines
		
	
	
		
			3.8 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			107 lines
		
	
	
		
			3.8 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| import os
 | |
| import json
 | |
| from lxml import etree
 | |
| 
 | |
| REPO_ROOT = os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))
 | |
| XML_DIR = os.path.join(REPO_ROOT, 'data', 'xml')
 | |
| 
 | |
| def parse_xml_file(filepath):
 | |
|     try:
 | |
|         parser = etree.XMLParser(remove_blank_text=True)
 | |
|         tree = etree.parse(filepath, parser)
 | |
|         return tree.getroot()
 | |
|     except etree.ParseError as e:
 | |
|         print(f"Error parsing {filepath}: {e}")
 | |
|         return None
 | |
| 
 | |
| def get_all_ids(root, tag):
 | |
|     return set(elem.get('letter') for elem in root.xpath(f'.//{tag}'))
 | |
| 
 | |
| def get_all_refs(root, tag, attr):
 | |
|     return set(elem.get(attr) for elem in root.xpath(f'.//{tag}'))
 | |
| 
 | |
| def check_references(root, reference_data, filepath):
 | |
|     errors = []
 | |
|     relative_path = os.path.relpath(filepath, REPO_ROOT)
 | |
| 
 | |
|     def add_error(element, ref_type, ref_id):
 | |
|         line_number = element.sourceline
 | |
|         error_message = f"Invalid reference ({ref_type}:{ref_id})"
 | |
|         errors.append({
 | |
|             "file": relative_path,
 | |
|             "line": line_number,
 | |
|             "message": error_message
 | |
|         })
 | |
| 
 | |
|     # Check letterText in briefe to letterDesc in meta
 | |
|     for letter_text in root.xpath('//letterText'):
 | |
|         letter_id = letter_text.get('letter')
 | |
|         if letter_id not in reference_data['letterDesc']:
 | |
|             add_error(letter_text, 'letterText', letter_id)
 | |
| 
 | |
|     # Check letterTradition in traditions to letterDesc in meta
 | |
|     for letter_tradition in root.xpath('//letterTradition'):
 | |
|         letter_id = letter_tradition.get('letter')
 | |
|         if letter_id not in reference_data['letterDesc']:
 | |
|             add_error(letter_tradition, 'letterTradition', letter_id)
 | |
| 
 | |
|     # Check hand in briefe with personDef in references
 | |
|     for hand in root.xpath('//hand'):
 | |
|         ref = hand.get('ref')
 | |
|         if ref not in reference_data['personDef']:
 | |
|             add_error(hand, 'hand', ref)
 | |
| 
 | |
|     # Check sender and receiver in meta with personDef in references
 | |
|     for person in root.xpath('//sender | //receiver'):
 | |
|         ref = person.get('ref')
 | |
|         if ref not in reference_data['personDef']:
 | |
|             add_error(person, 'sender/receiver', ref)
 | |
| 
 | |
|     # Check location in meta with locationDef in references
 | |
|     for location in root.xpath('//location'):
 | |
|         ref = location.get('ref')
 | |
|         if ref not in reference_data['locationDef']:
 | |
|             add_error(location, 'location', ref)
 | |
| 
 | |
|     # Check app in traditions with appDef in references
 | |
|     for app in root.xpath('//app'):
 | |
|         ref = app.get('ref')
 | |
|         if ref not in reference_data['appDef']:
 | |
|             add_error(app, 'app', ref)
 | |
| 
 | |
|     return errors
 | |
| 
 | |
| def main():
 | |
|     reference_data = {
 | |
|         'letterDesc': get_all_ids(parse_xml_file(os.path.join(XML_DIR, 'meta.xml')), 'letterDesc'),
 | |
|         'personDef': get_all_refs(parse_xml_file(os.path.join(XML_DIR, 'references.xml')), 'personDef', 'index'),
 | |
|         'locationDef': get_all_refs(parse_xml_file(os.path.join(XML_DIR, 'references.xml')), 'locationDef', 'index'),
 | |
|         'appDef': get_all_refs(parse_xml_file(os.path.join(XML_DIR, 'references.xml')), 'appDef', 'index'),
 | |
|     }
 | |
| 
 | |
|     all_errors = []
 | |
| 
 | |
|     files_to_check = ['briefe.xml', 'meta.xml', 'traditions.xml']
 | |
|     for filename in files_to_check:
 | |
|         filepath = os.path.join(XML_DIR, filename)
 | |
|         root = parse_xml_file(filepath)
 | |
|         if root is not None:
 | |
|             errors = check_references(root, reference_data, filepath)
 | |
|             all_errors.extend(errors)
 | |
| 
 | |
|     if all_errors:
 | |
|         print("The linter found the following errors:")
 | |
|         for error in all_errors:
 | |
|             print(f"{error['file']}, Line {error['line']}: {error['message']}")
 | |
|         
 | |
|         # GitHub Actions output
 | |
|         for error in all_errors:
 | |
|             print(f"::error file={error['file']},line={error['line']}::{error['message']}")
 | |
|         
 | |
|         exit(1)  # Exit with error code if errors were found
 | |
|     else:
 | |
|         print("No errors found.")
 | |
| 
 | |
| if __name__ == "__main__":
 | |
|     main()
 | 
