blob: 9fc507ba1fe85b8c26649c732b432b9ef96cd03c [file] [log] [blame] [raw]
# -*- coding: utf-8 -*-
# Copyright (c) 2022, Compiler Explorer Authors
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# * Redistributions of source code must retain the above copyright notice,
# this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
import sys
from os import listdir
from os.path import isfile, join
import re
COMPILERS_LIST_RE = re.compile(r'compilers=(.*)')
ALIAS_LIST_RE = re.compile(r'compiler.\.*?\.alias=(.*)')
GROUP_NAME_RE = re.compile(r'group\.(.*?)\.')
COMPILER_EXE_RE = re.compile(r'compiler\.(.*?)\.exe')
DISABLED_RE = re.compile(r'^# Disabled:\s*(.*)')
def process_file(file: str):
listed_groups = set()
seen_groups = set()
listed_compilers = set()
seen_compilers = set()
disabled = set()
with open(file) as f:
for line in f:
match_compilers = COMPILERS_LIST_RE.search(line)
if match_compilers:
ids = match_compilers.group(1).split(':')
for elem_id in ids:
if elem_id.startswith('&'):
listed_groups.add(elem_id[1:])
elif '@' not in elem_id:
listed_compilers.add(elem_id)
match_aliases = ALIAS_LIST_RE.match(line)
if match_aliases:
seen_compilers.update(match_aliases.group(1).split(':'))
continue
match_group = GROUP_NAME_RE.match(line)
if match_group:
seen_groups.add(match_group.group(1))
continue
match_compiler = COMPILER_EXE_RE.match(line)
if match_compiler:
seen_compilers.add(match_compiler.group(1))
continue
match_disabled = DISABLED_RE.match(line)
if match_disabled:
disabled.update(match_disabled.group(1).split(' '))
bad_compilers = listed_compilers.symmetric_difference(seen_compilers)
bad_groups = listed_groups.symmetric_difference(seen_groups)
return file, bad_compilers - disabled, bad_groups - disabled
def process_folder(folder: str):
return [process_file(join(folder, f))
for f in listdir(folder)
if isfile(join(folder, f))
and not (f.endswith('.defaults.properties') or f.endswith('.local.properties'))
and f.endswith('.properties')]
def problems_found(file_result):
return len(file_result[1]) > 0 or len(file_result[2]) > 0
def find_orphans(folder: str):
result = sorted([r for r in process_folder(folder) if problems_found(r)], key=lambda x: x[0])
if result:
print(f"Found {len(result)} property file(s) with mismatching ids:")
sep = "\n\t"
for r in result:
print(r[0])
if len(r[1]) > 0:
print(f"COMPILERS:\n\t{sep.join(sorted(r[1]))}")
if len(r[2]) > 0:
print(f"GROUPS:\n\t{sep.join(sorted(r[2]))}")
print("")
print("To suppress this warning on IDs that are temporally disabled, "
"add one or more comments to each listed file:")
print("# Disabled: id1 id2 ...")
else:
print("No configuration mismatches found")
return result
if __name__ == '__main__':
if find_orphans('./etc/config/'):
sys.exit(1)