mirror of
				https://github.com/notepad-plus-plus/notepad-plus-plus.git
				synced 2025-10-31 03:24:04 +01:00 
			
		
		
		
	And fix the themes and javascript.js functionlist that don’t match XSD. Fix #16618, close #16619
		
			
				
	
	
		
			177 lines
		
	
	
		
			6.2 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			177 lines
		
	
	
		
			6.2 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| #!/usr/local/bin/python3
 | |
| 
 | |
| import os
 | |
| import io
 | |
| import sys
 | |
| 
 | |
| import requests
 | |
| from hashlib import sha256
 | |
| from lxml import etree
 | |
| 
 | |
| api_url = os.environ.get('APPVEYOR_API_URL')
 | |
| has_error = False
 | |
| 
 | |
| 
 | |
| def post_error(message):
 | |
|     global has_error
 | |
| 
 | |
|     has_error = True
 | |
| 
 | |
|     message = {
 | |
|         "message": message,
 | |
|         "category": "error",
 | |
|         "details": ""
 | |
|     }
 | |
| 
 | |
|     if api_url:
 | |
|         requests.post(api_url + "api/build/messages", json=message)
 | |
|     else:
 | |
|         from pprint import pprint
 | |
|         pprint(message)
 | |
| 
 | |
| 
 | |
| def parse_xml_file(filename_xml, filename_xsd = None):
 | |
| 
 | |
|     # parse xml
 | |
|     try:
 | |
|         doc = etree.parse(filename_xml)
 | |
|         #print(f'{filename_xml} XML well formed, syntax ok.')
 | |
| 
 | |
|     # check for file IO error
 | |
|     except IOError:
 | |
|         #print('Invalid File')
 | |
|         post_error(f'{filename_xml}: IOError Invalid File')
 | |
|         return
 | |
| 
 | |
|     # check for XML syntax errors
 | |
|     except etree.XMLSyntaxError as err:
 | |
|         #print('XML Syntax Error, see error_syntax.log')
 | |
|         post_error(f'{filename_xml}: {str(err.error_log)}: XMLSyntaxError Invalid File')
 | |
|         return
 | |
| 
 | |
|     # check for general XML errors
 | |
|     except etree.LxmlError as err:
 | |
|         #print('XML Error, see error_syntax.log')
 | |
|         post_error(f'{filename_xml}: {str(err.error_log)}: LxmlError Invalid File')
 | |
|         return
 | |
| 
 | |
|     # unknown error
 | |
|     except:
 | |
|         #print('Unknown error.')
 | |
|         post_error(f'{filename_xml}: Unknown error. Maybe check that no xml version is in the first line.')
 | |
|         return
 | |
| 
 | |
| 
 | |
| 
 | |
|     # now validate against correct schema
 | |
|     if doc and filename_xsd is not None:
 | |
|         try:
 | |
|             xmlschema_doc = etree.parse(filename_xsd)
 | |
| 
 | |
|         # error reading XSD
 | |
|         except IOError:
 | |
|             post_error(f'{filename_xml} | {filename_xsd}: IOError Invalid File')
 | |
|             return
 | |
| 
 | |
|         # error parsing XSD
 | |
|         except etree.XMLSyntaxError as err:
 | |
|             post_error(f'{filename_xml} | {filename_xsd}: {str(err.error_log)}: XMLSyntaxError Invalid File')
 | |
|             return
 | |
| 
 | |
|         # other error
 | |
|         except Exception as err:
 | |
|             post_error(f'{filename_xml} | {filename_xsd}: Unknown error {str(err.error_log)} reading Schema .xsd file.')
 | |
|             return
 | |
| 
 | |
|         # Next, extract the schema object from the schema_doc
 | |
|         try:
 | |
|             xmlschema = etree.XMLSchema(xmlschema_doc)
 | |
|             #print(f'{filename_xml} | {filename_xsd}: SCHEMA OBJECT OK')
 | |
| 
 | |
|         # error with Schema
 | |
|         except etree.XMLSchemaError as err:
 | |
|             post_error(f'{filename_xml} | {filename_xsd}: {str(err.error_log)}: XMLSchemaError')
 | |
|             return
 | |
| 
 | |
|         # other error
 | |
|         except Exception as err:
 | |
|             post_error(f'{filename_xml} | {filename_xsd}: Unknown error {str(err.error_log)} obtaining schema object')
 | |
|             return
 | |
| 
 | |
|         # finally, validate the XML against the schema
 | |
|         if not xmlschema.validate(doc):
 | |
|             post_error(f'{filename_xml} | {filename_xsd}: Validation error {str(xmlschema.error_log)}')
 | |
|             return
 | |
|         else:
 | |
|             #print(f'{filename_xml} vs schema: VALIDATION OK')
 | |
|             pass
 | |
| 
 | |
| 
 | |
| def parse_xml_files_from_APIs_dir():
 | |
| 
 | |
|     for file in os.listdir("PowerEditor/installer/APIs"):
 | |
|         if file.endswith(".xml"):
 | |
|             #print(os.path.join("PowerEditor/installer/APIs", file))
 | |
|             parse_xml_file(os.path.join("PowerEditor/installer/APIs", file), os.path.join("PowerEditor", "Test", "xmlValidator", "autoCompletion.xsd"))
 | |
| 
 | |
| def parse_xml_files_from_functionList_dir():
 | |
| 
 | |
|     for file in os.listdir("PowerEditor/installer/functionList"):
 | |
|         if file.endswith(".xml"):
 | |
|             #print(os.path.join("PowerEditor/installer/functionList", file))
 | |
|             xsd_filename = None
 | |
|             if not file.endswith("overrideMap.xml"):
 | |
|                 xsd_filename = os.path.join("PowerEditor", "Test", "xmlValidator", "functionList.xsd")
 | |
| 
 | |
|             parse_xml_file(os.path.join("PowerEditor/installer/functionList", file), xsd_filename)
 | |
| 
 | |
| def parse_xml_files_from_nativeLang_dir():
 | |
| 
 | |
|     for file in os.listdir("PowerEditor/installer/nativeLang"):
 | |
|         if file.endswith(".xml"):
 | |
|             #print(os.path.join("PowerEditor/installer/nativeLang", file))
 | |
|             parse_xml_file(os.path.join("PowerEditor/installer/nativeLang", file), os.path.join("PowerEditor", "Test", "xmlValidator", "nativeLang.xsd"))
 | |
| 
 | |
| def parse_xml_files_from_themes_dir():
 | |
| 
 | |
|     for file in os.listdir("PowerEditor/installer/themes"):
 | |
|         if file.endswith(".xml"):
 | |
|             #print(os.path.join("PowerEditor/installer/themes", file))
 | |
|             parse_xml_file(os.path.join("PowerEditor/installer/themes", file), os.path.join("PowerEditor", "Test", "xmlValidator", "theme.xsd"))
 | |
| 
 | |
| 
 | |
| def parse_xml_files_from_src_dir():
 | |
| 
 | |
|     for file in os.listdir("PowerEditor/src"):
 | |
|         if file.endswith(".xml"):
 | |
|             #print(os.path.join("PowerEditor/src", file))
 | |
|             xsd_filename = None
 | |
|             if file.endswith("stylers.model.xml"):
 | |
|                 xsd_filename = os.path.join("PowerEditor", "Test", "xmlValidator", "theme.xsd")
 | |
|             elif file.endswith("langs.model.xml"):
 | |
|                 xsd_filename = os.path.join("PowerEditor", "Test", "xmlValidator", "langs.xsd")
 | |
|             elif file.endswith("toolbarButtonsConf_example.xml"):
 | |
|                 xsd_filename = os.path.join("PowerEditor", "Test", "xmlValidator", "toolbarButtons.xsd")
 | |
|             elif file.endswith("tabContextMenu_example.xml"):
 | |
|                 xsd_filename = os.path.join("PowerEditor", "Test", "xmlValidator", "tabContext.xsd")
 | |
|             elif file.endswith("contextMenu.xml"):
 | |
|                 xsd_filename = os.path.join("PowerEditor", "Test", "xmlValidator", "contextMenu.xsd")
 | |
|             elif file.endswith("shortcuts.xml"):
 | |
|                 xsd_filename = os.path.join("PowerEditor", "Test", "xmlValidator", "shortcuts.xsd")
 | |
|             elif file.endswith("config.4zipPackage.xml"):
 | |
|                 xsd_filename = os.path.join("PowerEditor", "Test", "xmlValidator", "config.xsd")
 | |
|             parse_xml_file(os.path.join("PowerEditor/src", file), xsd_filename)
 | |
| 
 | |
| print('Start syntax check and validation for XML files.')
 | |
| parse_xml_files_from_APIs_dir()
 | |
| parse_xml_files_from_functionList_dir()
 | |
| parse_xml_files_from_nativeLang_dir()
 | |
| parse_xml_files_from_themes_dir()
 | |
| parse_xml_files_from_src_dir()
 | |
| print('Done.')
 | |
| 
 | |
| if has_error:
 | |
|     sys.exit(-2)
 | |
| else:
 | |
|     sys.exit()
 |