From eeb0f1cce6661f5058467f75859f078caa695bac Mon Sep 17 00:00:00 2001 From: Stan Date: Fri, 23 Aug 2024 15:37:51 +0200 Subject: [PATCH] Make checkrefs and called scripts return an error --- source/tools/entity/checkrefs.py | 20 +++++++++++++------ source/tools/xmlvalidator/validate_grammar.py | 8 ++++++-- source/tools/xmlvalidator/validator.py | 9 ++++++++- 3 files changed, 28 insertions(+), 9 deletions(-) diff --git a/source/tools/entity/checkrefs.py b/source/tools/entity/checkrefs.py index 48a567f530..e6b70d0d3c 100644 --- a/source/tools/entity/checkrefs.py +++ b/source/tools/entity/checkrefs.py @@ -37,6 +37,7 @@ class CheckRefs: self.supportedAudioFormats = ('ogg') self.mods = [] self.__init_logger + self.inError = False @property def __init_logger(self): @@ -103,12 +104,16 @@ class CheckRefs: sys.path.append("../xmlvalidator/") from validate_grammar import RelaxNGValidator validate = RelaxNGValidator(self.vfs_root, self.mods) - validate.run() + if not validate.run(): + self.inError = True if args.validate_actors: sys.path.append("../xmlvalidator/") from validator import Validator validator = Validator(self.vfs_root, self.mods) - validator.run() + if not validator.run(): + self.inError = True + + return self.inError def get_mod_dependencies(self, *mods): modjsondeps = [] @@ -171,7 +176,8 @@ class CheckRefs: # ignore terrains.xml if name != 'terrains': if name in terrains: - self.logger.warning(f"Duplicate terrain name '{name}' (from '{terrains[name]}' and '{ffp}')") + self.inError = True + self.logger.error(f"Duplicate terrain name '{name}' (from '{terrains[name]}' and '{ffp}')") terrains[name] = str(fp) mapfiles = self.find_files('maps/scenarios', 'pmp') mapfiles.extend(self.find_files('maps/skirmishes', 'pmp')) @@ -411,7 +417,7 @@ class CheckRefs: material_elem = ElementTree.parse(ffp).getroot() for alternative in material_elem.findall('alternative'): material = alternative.get('material') - if material: + if material is not None: self.deps.append((str(fp), f'art/materials/{material}')) def add_particles(self): @@ -642,7 +648,8 @@ class CheckRefs: continue callers = [str(self.vfs_to_relative_to_mods(ref)) for ref in reverse_deps[dep]] - self.logger.warning(f"Missing file '{dep}' referenced by: {', '.join(sorted(callers))}") + self.logger.error(f"Missing file '{dep}' referenced by: {', '.join(sorted(callers))}") + self.inError = True if dep.lower() in lower_case_files: self.logger.warning(f"### Case-insensitive match (found '{lower_case_files[dep.lower()]}')") @@ -684,4 +691,5 @@ class CheckRefs: if __name__ == '__main__': check_ref = CheckRefs() - check_ref.main() + if not check_ref.main(): + sys.exit(1) diff --git a/source/tools/xmlvalidator/validate_grammar.py b/source/tools/xmlvalidator/validate_grammar.py index 45a66165a0..12476b0c6d 100644 --- a/source/tools/xmlvalidator/validate_grammar.py +++ b/source/tools/xmlvalidator/validate_grammar.py @@ -47,6 +47,7 @@ class RelaxNGValidator: errorch.setFormatter(Formatter('%(levelname)s - %(message)s')) logger.addHandler(errorch) self.logger = logger + self.inError = False def run (self): self.validate_actors() @@ -59,13 +60,14 @@ class RelaxNGValidator: self.validate_soundgroups() self.validate_terrains() self.validate_textures() + return self.inError def main(self): """ Program entry point, parses command line arguments and launches the validation """ # ordered uniq mods (dict maintains ordered keys from python 3.6) self.logger.info(f"Checking {'|'.join(self.mods)}'s integrity.") self.logger.info(f"The following mods will be loaded: {'|'.join(self.mods)}.") - self.run() + return self.run() def find_files(self, vfs_root, mods, vfs_path, *ext_list): """ @@ -177,6 +179,7 @@ class RelaxNGValidator: self.logger.info(f"{error_count} {name} validation errors") elif error_count > 0: self.logger.error(f"{error_count} {name} validation errors") + self.inError = True def get_mod_dependencies(vfs_root, *mods): @@ -204,4 +207,5 @@ if __name__ == '__main__': args = ap.parse_args() mods = list(dict.fromkeys([*args.mods, *get_mod_dependencies(args.root, *args.mods), 'mod']).keys()) relax_ng_validator = RelaxNGValidator(args.root, mods=mods, verbose=args.verbose) - relax_ng_validator.main() \ No newline at end of file + if not relax_ng_validator.main(): + sys.exit(1) diff --git a/source/tools/xmlvalidator/validator.py b/source/tools/xmlvalidator/validator.py index ef00444555..f1e0675a26 100644 --- a/source/tools/xmlvalidator/validator.py +++ b/source/tools/xmlvalidator/validator.py @@ -111,6 +111,7 @@ class Validator: errorch.setFormatter(Formatter('%(levelname)s - %(message)s')) logger.addHandler(errorch) self.logger = logger + self.inError = False def get_mod_path(self, mod_name, vfs_path): return os.path.join(mod_name, vfs_path) @@ -178,6 +179,7 @@ class Validator: self.get_mod_path(actor.mod_name, actor.vfs_path), actor.material )) + self.inError = True if actor.material not in self.materials: continue material = self.materials[actor.material] @@ -189,6 +191,7 @@ class Validator: missing_textures, material.name )) + self.inError = True extra_textures = ', '.join(set([extra_texture for extra_texture in actor.textures if extra_texture not in material.required_textures])) if len(extra_textures) > 0: @@ -197,6 +200,9 @@ class Validator: extra_textures, material.name )) + self.inError = True + + return self.inError if __name__ == '__main__': script_dir = os.path.dirname(os.path.realpath(__file__)) @@ -206,4 +212,5 @@ if __name__ == '__main__': parser.add_argument('-m', '--mods', action='store', dest='mods', default='mod,public') args = parser.parse_args() validator = Validator(args.root, args.mods.split(',')) - validator.run() + if not validator.run(): + sys.exit(1)