#!/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())