79 lines
3 KiB
Python
Executable file
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)
|
|
|