OpenMiInk/third_party/kde-ci-utilities/validate-xml-files.py
Hellings b8c8ff98e2 Hi
2026-10-16 09:05:56 -04:00

79 lines
3 KiB
Python
Executable file

#!/usr/bin/python3
# Version in sysadmin/ci-utilities should be single source of truth
# SPDX-FileCopyrightText: 2023 Alexander Lohnau <alexander.lohnau@gmx.de>
# SPDX-FileCopyrightText: 2024 Johnny Jazeix <jazeix@gmail.com>
# SPDX-License-Identifier: BSD-2-Clause
import argparse
import glob
import os
import subprocess
import yaml
parser = argparse.ArgumentParser(description='Check XML files in repository')
parser.add_argument('--check-all', default=False, action='store_true', help='If all files should be checked or only the changed files')
parser.add_argument('--verbose', default=False, action='store_true')
args = parser.parse_args()
supported_extensions = (('.xml', '.kcfg', '.ui', '.qrc'))
def get_changed_files() -> list[str]:
result = subprocess.run(['git', 'diff', '--cached', '--name-only'], capture_output=True, text=True)
return [file for file in result.stdout.splitlines() if file.endswith(supported_extensions)]
def get_all_files() -> list[str]:
files = []
for root, _, filenames in os.walk('.'):
for filename in filenames:
if filename.endswith(supported_extensions):
files.append(os.path.join(root, filename))
return files
def filter_excluded_included_xml_files(files: list[str]) -> list[str]:
config_file = '.kde-ci.yml'
# Check if the file exists
if os.path.exists(config_file):
with open(config_file, 'r') as file:
config = yaml.safe_load(file)
else:
if args.verbose:
print(f'{config_file} does not exist in current directory')
config = {}
# Extract excluded files, used for tests that intentionally have broken files
excluded_files = []
if 'Options' in config and 'xml-validate-ignore' in config['Options']:
xml_files_to_ignore = config['Options']['xml-validate-ignore']
for xml in xml_files_to_ignore:
excluded_files += glob.glob(xml, recursive=True)
# Find XML files
filtered_files = []
for file_path in files:
if not any(excluded_file in file_path for excluded_file in excluded_files):
filtered_files.append(file_path)
# "include" overrides the "ignore" files, so if a file is both included and excluded, it will be included
if 'Options' in config and 'xml-validate-include' in config['Options']:
for filename in config['Options']['xml-validate-include']:
if os.path.isfile(filename):
filtered_files += [filename]
else:
print(f"warning: {filename} does not exist, please double check it and either fix the filename or update the .kde-ci.yml file to remove it")
return filtered_files
if args.check_all:
files = get_all_files()
else:
files = get_changed_files()
files = filter_excluded_included_xml_files(files)
if files:
files_option = ' '.join(files)
if args.verbose:
print(f"Validating {files_option}")
result = subprocess.run(['xmllint', *files], stdout=subprocess.DEVNULL)
# Fail the pipeline if command failed
if result.returncode != 0:
exit(1)