# 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 $