# Perforce Defect Tracking Integration Project # # # EXAMPLE_TRIGGER.PY -- AN EXAMPLE PERFORCE TRIGGER FOR ENFORCING WORKFLOW # # Richard Brooksby, Ravenbrook Limited, 2000-12-06 # # # 1. INTRODUCTION # # This is an example Perforce trigger script for preventing changes # to areas of the Perforce repository without certain defect tracker # conditions being met [Requirements, 57]. # # This document is intended for administrators of the Perforce Defect # Tracking Integration (P4DTI). # # This document is not confidential. # # # 2. USING THE TRIGGER # # First, read section 5.2.2, "Installing Perforce triggers to enforce # workflow" of the "Perforce Defect Tracking Integration Administrator's # Guide" [RB 2000-08-10, 5.2.2]. # # To use this trigger, first adapt the code to make it test the # condition that you want to enforce. # # This example script insists that submissions fix to status "closed" at # least one issue which has a priority of "critical". This almost # certainly isn't quite what you want, so you'll need to do some # programming. # # You will also need to configure the P4DTI to replicate the fields that # you want to check. Most likely you'll want to check that the # "priority" or "severity" or something similar is above a certain # level, or that the "approval" field has been set by a manager, or # something like that. You need to make sure the relevant fields are # replicated. See section 5.1, "P4DTI configuration" of the "Perforce # Defect Tracking Integration Administrator's Guide" [RB 2000-08-10, # 5.1]. # # Be sure to read the "Triggers" section in chapter 6 of the "Perforce # System Administrator's Guide" [Perforce 2000-10-11]. Then use the "p4 # triggers" command to insert a line like: # # enforce-critical //depot/release/master/... "/usr/local/bin/python /whatever-path-to/your-trigger.py %serverport% root %client% %changelist%" # # Where "root" is a user which has access to Perforce without a # password. (Or you could edit this script to include the password.) # # See "Perforce Defect Tracking Integration Administrator's Guide" for # more information about this and other aspects of configuring the P4DTI # [RB 2000-08-10]. import sys import os import marshal def p4(command): stream = os.popen("p4 -G " + command, "r") results = [] try: while 1: results.append(marshal.load(stream)) except EOFError: pass if (len(results) == 1 and results[0].has_key('code') and results[0]["code"] == "error"): raise "Perforce Error", results[0]["data"] return results def check_fix(): usage = "python %s serverport user client changelist" % sys.argv[0] if len(sys.argv) != 5: sys.exit(usage) serverport, user, client, change = sys.argv[1:5] os.environ["P4PORT"] = serverport os.environ["P4USER"] = user os.environ["P4CLIENT"] = client fixes = p4("fixes -c %s" % change) # Fixes look like this: # [{'Change': '1', # 'Client': 'newton-lime', # 'Date': '976102677', # 'User': 'newton', # 'code': 'stat', # 'Job': '00003', # 'Status': 'closed'}, # ...] # Enforce the rule that every submission must close at least one # job with critical severity. It might affect other jobs as well, # but we don't care. for fix in fixes: assert fix.has_key("Change") and fix["Change"] == change assert fix.has_key("Status") job = p4("job -o %s" % fix["Job"])[0] if (fix["Status"] == "closed" and job.has_key("Severity") and job["Severity"] == "critical"): sys.exit(0) # No job was found that passed the test, so print a message to tell # the submittor why we're refusing to accept the change. print("Submissions to this codeline must fix at least one " "critical issue.") sys.exit(1) if __name__ == '__main__': check_fix() # A. REFERENCES # # [Perforce 2000-10-11] "Perforce 2000.1 System Administrator's Guide"; # Perforce Software; 2000-10-11; # . # # [RB 2000-08-10] "Perforce Defect Tracking Integration Administrator's # Guide"; Richard Brooksby; Ravenbrook Limited; 2000-08-10; # . # # [Requirements] "Perforce Defect Tracking Integration Project # Requirements"; Gareth Rees; Ravenbrook Limited; 2000-05-24; # . # # # B. DOCUMENT HISTORY # # 2000-12-06 RB Created to solve Ravenbrook job job000043. # # 2000-12-15 RB Fixed usage message to take script name from argv. # Detabbed to four spaces for consistency with the rest of our Python # source. # # 2001-03-02 RB Transferred copyright to Perforce under their license. # # 2001-04-29 GDR Formatted as a document. Added reference to # requirements. # # 2002-02-25 GDR Execute only when main. # # # C. COPYRIGHT AND LICENSE # # This file is copyright (c) 2001 Perforce Software, Inc. All rights # reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # 1. Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # 2. 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 # HOLDERS AND 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. # # # $Id: //info.ravenbrook.com/project/p4dti/version/2.1/code/replicator/example_trigger.py#2 $