#!/usr/bin/env python3 # -*- coding: utf-8 -*- # ============================================================================== # Copyright and license info is available in the LICENSE file included with # the Server Deployment Package (SDP), and also available online: # https://swarm.workshop.perforce.com/projects/perforce-software-sdp/view/main/LICENSE # ------------------------------------------------------------------------------ """ NAME: ValidateContentFormat.py DESCRIPTION: This trigger is intended for file content validation as part of change-content trigger Initially works for YAML. To install, add a line to your Perforce triggers table like the following: validate-yaml change-content //....yaml "python /p4/common/bin/triggers/ValidateContentFormat.py -p %serverport% -u perforce --yaml %change% " or (if server is standard SDP and has appropriate environment defaults for P4PORT and P4USER): validate-yaml change-content //....yaml "python /p4/common/bin/triggers/ValidateContentFormat.py --yaml %change% " You may need to provide the full path to python executable, or edit the path to the trigger. Also, don't forget to make the file executable. """ # Python 2.7/3.3 compatibility. from __future__ import print_function import sys import re import os import P4Triggers import P4 import yaml import json import tempfile # Regex extensions to search for in filenames file_extensions = {"yaml": ["\.yaml$", "\.yml$"], "json:": ["\.json$"]} class ValidateContentFormat(P4Triggers.P4Trigger): """See module doc string for details""" def __init__(self, *args, **kwargs): P4Triggers.P4Trigger.__init__(self, **kwargs) self.parse_args(__doc__, args) def add_parse_args(self, parser): """Specific args for this trigger - also calls super class to add common trigger args""" parser.add_argument('--yaml', default=False, action='store_true', help="Trigger validates yaml files") parser.add_argument('--json', default=False, action='store_true', help="Trigger validates json files") parser.add_argument('change', help="Change to process - %%change%% argument from triggers entry.") super(ValidateContentFormat, self).add_parse_args(parser) def yaml_load_errors(self, fname): try: with open(fname, 'r') as f: content = yaml.load(f) return "" except Exception as e: return str(e) def run(self): """Runs trigger""" exit_code = 0 try: self.logger.debug("ValidateContent trigger firing") self.setupP4() self.p4.connect() change = self.getChange(self.options.change) for df in change.files: exts = "" if self.options.yaml: exts = file_extensions["yaml"] valid_ext = False for ext in exts: if re.search(ext, df.depotFile): valid_ext = True if not valid_ext: continue name_parts = df.depotFile.split("/") tfile = os.path.join(tempfile.gettempdir(), name_parts[-1]) self.logger.debug("Validating %s as local: %s" % (df.depotFile, tfile)) self.p4.run_print("-o", tfile, "%s@=%s" % (df.depotFile, self.options.change)) result = self.yaml_load_errors(tfile) if result: exit_code += 1 print(result) print("Invalid format for %s" % df.depotFile) if exit_code: print("%d files failed" % exit_code) return exit_code except Exception: return self.reportException() if __name__ == '__main__': """ Main Program""" trigger = ValidateContentFormat(*sys.argv[1:]) sys.exit(trigger.run())