1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120
|
# This is run sequentially, due to races. As clang-apply-replacements just applies all .yaml files it can find.
# We run a single clang-apply-replacements invocation, which changes all files in the tests/ directory.
import os
import shutil
from . import Args
from .checks import Check
from .os_utils import run_command, compare_files
def run_fixit_tests(requested_checks: list[Check], config: Args):
success = patch_yaml_files(requested_checks, is_standalone=False, no_standalone=config.no_standalone, only_standalone=config.only_standalone)
success = patch_yaml_files(requested_checks, is_standalone=True, no_standalone=config.no_standalone, only_standalone=config.only_standalone) and success
for check in requested_checks:
if not any(map(lambda test: test.should_run_fixits_test, check.tests)):
continue
# Call clazy-apply-replacements[.exe]
if not run_clang_apply_replacements(check):
return False
# Now compare all the *.fixed files with the *.fixed.expected counterparts
for test in check.tests:
if test.should_run_fixits_test:
# Check that the rewritten file is identical to the expected one
if not compare_fixit_results(test, is_standalone=False, no_standalone=config.no_standalone, only_standalone=config.only_standalone, verbose=config.verbose):
success = False
continue
if not compare_fixit_results(test, is_standalone=True, no_standalone=config.no_standalone, only_standalone=config.only_standalone, verbose=config.verbose):
success = False
continue
return success
def compare_fixit_results(test, is_standalone: bool, no_standalone: bool, only_standalone: bool, verbose: bool):
if (is_standalone and no_standalone) or (not is_standalone and only_standalone):
# Nothing to do
return True
# Check that the rewritten file is identical to the expected one
if not compare_files(False, test.expectedFixedFilename(), test.fixedFilename(is_standalone), test.printableName("", 0, is_standalone, False, True), verbose=verbose):
return False
# Some fixed cpp files have an header that was also fixed. Compare it here too.
possible_headerfile_expected = test.expectedFixedFilename().replace('.cpp', '.h')
if os.path.exists(possible_headerfile_expected):
possible_headerfile = test.fixedFilename(is_standalone).replace('.cpp', '.h')
if not compare_files(False, possible_headerfile_expected, possible_headerfile, test.printableName("", 0, is_standalone, False, True).replace('.cpp', '.h'), verbose=verbose):
return False
return True
# The yaml file references the test file in our git repo, but we don't want
# to rewrite that one, as we would need to discard git changes afterwards,
# so patch the yaml file and add a ".fixed" suffix to those files
def patch_fixit_yaml_file(test, is_standalone):
yamlfilename = test.yamlFilename(is_standalone)
fixedfilename = test.fixedFilename(is_standalone)
f = open(yamlfilename, 'r')
lines = f.readlines()
f.close()
f = open(yamlfilename, 'w')
possible_headerfile = test.relativeFilename().replace(".cpp", ".h")
for line in lines:
stripped = line.strip()
if stripped.startswith('MainSourceFile') or stripped.startswith("FilePath") or stripped.startswith("- FilePath"):
line = line.replace(test.relativeFilename(), fixedfilename)
# For Windows:
line = line.replace(test.relativeFilename().replace(
'/', '\\'), fixedfilename.replace('/', '\\'))
# Some tests also apply fix their to their headers:
if not test.relativeFilename().endswith(".hh"):
line = line.replace(possible_headerfile,
fixedfilename.replace(".cpp", ".h"))
f.write(line)
f.close()
shutil.copyfile(test.relativeFilename(), fixedfilename)
if os.path.exists(possible_headerfile):
shutil.copyfile(possible_headerfile,
fixedfilename.replace(".cpp", ".h"))
return True
def patch_yaml_files(requested_checks, is_standalone: bool, no_standalone: bool, only_standalone: bool):
if (is_standalone and no_standalone) or (not is_standalone and only_standalone):
# Nothing to do
return True
success = True
for check in requested_checks:
for test in check.tests:
if test.should_run_fixits_test:
yamlfilename = test.yamlFilename(is_standalone)
if not os.path.exists(yamlfilename):
print("[FAIL] " + yamlfilename + " is missing!!")
success = False
continue
if not patch_fixit_yaml_file(test, is_standalone):
print("[FAIL] Could not patch " + yamlfilename)
success = False
continue
return success
def run_clang_apply_replacements(check):
command = os.getenv('CLAZY_CLANG_APPLY_REPLACEMENTS', 'clang-apply-replacements')
return run_command(command + ' ' + check.name)
|