<?xml version="1.0" encoding="iso-8859-1"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> <head> <title>Class: P4Trigger</title> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" /> <meta http-equiv="Content-Script-Type" content="text/javascript" /> <link rel="stylesheet" href=".././rdoc-style.css" type="text/css" media="screen" /> <script type="text/javascript"> // <![CDATA[ function popupCode( url ) { window.open(url, "Code", "resizable=yes,scrollbars=yes,toolbar=no,status=no,height=150,width=400") } function toggleCode( id ) { if ( document.getElementById ) elem = document.getElementById( id ); else if ( document.all ) elem = eval( "document.all." + id ); else return false; elemStyle = elem.style; if ( elemStyle.display != "block" ) { elemStyle.display = "block" } else { elemStyle.display = "none" } return true; } // Make codeblocks hidden by default document.writeln( "<style type=\"text/css\">div.method-source-code { display: none }</style>" ) // ]]> </script> </head> <body> <div id="classHeader"> <h1>P4Trigger <sup class="type-note">(Class)</sup></h1> <table class="header-table"> <tr class="top-aligned-row"> <td><strong>In:</strong></td> <td> <a href="../files/P4Triggers_rb.html"> P4Triggers.rb </a> <br /> </td> </tr> <tr class="top-aligned-row"> <td><strong>Parent:</strong></td> <td> Object </td> </tr> </table> </div> <!-- banner header --> <div id="bodyContent"> <div id="contextContent"> <div id="description"> <p> A class providing a generic framework for all triggers. It provides rudimentary error handling so all errors get logged to stderr, and we also have a method for reporting a more friendly message to the user. It is intended that all trigger scripts will derive their own subclass of <a href="P4Trigger.html">P4Trigger</a> and override/expand it as necessary. </p> <p> You must override the validate() method if you want your trigger to work. The default implementation accepts <b>everything</b> so make sure you provide a method to reject bad changes or you will have accomplished nothing. </p> </div> <div id="method-list"> <h2 class="section-bar">Methods</h2> <div class="name-list"> <a href="#M000034">error_message</a> <a href="#M000031">get_change</a> <a href="#M000033">message</a> <a href="#M000029">new</a> <a href="#M000030">parse_change</a> <a href="#M000032">validate</a> </div> </div> <div id="attribute-list"> <h2 class="section-bar">Attributes</h2> <div class="name-list"> <table> <tr class="top-aligned-row context-row"> <td class="context-item-name">change</td> <td class="context-item-value"> [R] </td> <td class="context-item-desc"> Direct access to the changelist in question. Returns a <a href="P4Change.html">P4Change</a> object </td> </tr> <tr class="top-aligned-row context-row"> <td class="context-item-name">p4</td> <td class="context-item-value"> [R] </td> <td class="context-item-desc"> Direct access to the <a href="P4.html">P4</a> object. You can use this for interrogating the Perforce server. It’s in parse_forms() mode and has an exception_level of 1 so exceptions will only be raised on errors, not warnings. </td> </tr> </table> </div> </div> </div> <!-- if includes --> <!-- if method_list --> <div id="methods"> <h2 class="section-bar">Public Class methods</h2> <div id="method-M000029" class="method-detail"> <a name="M000029"></a> <div class="method-heading"> <a href="#M000029" class="method-signature"> <span class="method-name">new</span><span class="method-args">()</span> </a> </div> <div class="method-description"> <p> Constructor. </p> <p><a class="source-toggle" href="#" onclick="toggleCode('M000029-source');return false;">[Source]</a></p> <div class="method-source-code" id="M000029-source"> <pre> <span class="ruby-comment cmt"># File P4Triggers.rb, line 159</span> 159: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">initialize</span> 160: <span class="ruby-ivar">@change</span> = <span class="ruby-keyword kw">nil</span> 161: <span class="ruby-ivar">@p4</span> = <span class="ruby-constant">P4</span>.<span class="ruby-identifier">new</span> 162: <span class="ruby-ivar">@p4</span>.<span class="ruby-identifier">parse_forms</span> 163: <span class="ruby-keyword kw">begin</span> 164: <span class="ruby-ivar">@p4</span>.<span class="ruby-identifier">connect</span> 165: <span class="ruby-keyword kw">rescue</span> <span class="ruby-constant">P4Exception</span> 166: <span class="ruby-identifier">error_message</span>() 167: <span class="ruby-identifier">raise</span> 168: <span class="ruby-keyword kw">end</span> 169: <span class="ruby-keyword kw">end</span> </pre> </div> </div> </div> <h2 class="section-bar">Public Instance methods</h2> <div id="method-M000034" class="method-detail"> <a name="M000034"></a> <div class="method-heading"> <a href="#M000034" class="method-signature"> <span class="method-name">error_message</span><span class="method-args">()</span> </a> </div> <div class="method-description"> <p> Default message for when things go wrong </p> <p><a class="source-toggle" href="#" onclick="toggleCode('M000034-source');return false;">[Source]</a></p> <div class="method-source-code" id="M000034-source"> <pre> <span class="ruby-comment cmt"># File P4Triggers.rb, line 257</span> 257: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">error_message</span>() 258: <span class="ruby-value str">"\n"</span> <span class="ruby-operator">+</span> 259: <span class="ruby-value str">"An error was encountered during trigger execution. Please\n"</span> <span class="ruby-operator">+</span> 260: <span class="ruby-value str">"contact your Perforce administrator and ask them to\n"</span> <span class="ruby-operator">+</span> 261: <span class="ruby-value str">"investigate the cause of this error\n\n"</span> 262: <span class="ruby-keyword kw">end</span> </pre> </div> </div> </div> <div id="method-M000031" class="method-detail"> <a name="M000031"></a> <div class="method-heading"> <a href="#M000031" class="method-signature"> <span class="method-name">get_change</span><span class="method-args">( change_no )</span> </a> </div> <div class="method-description"> <p> The default implementation of <a href="P4Trigger.html#M000031">get_change</a>. Returns a hash describing the change based on an execution of "p4 describe -s". The hash is also saved in the @change member which subclasses may access in their validate() method. For most triggers this will be sufficient. </p> <p><a class="source-toggle" href="#" onclick="toggleCode('M000031-source');return false;">[Source]</a></p> <div class="method-source-code" id="M000031-source"> <pre> <span class="ruby-comment cmt"># File P4Triggers.rb, line 236</span> 236: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">get_change</span>( <span class="ruby-identifier">change_no</span> ) 237: <span class="ruby-ivar">@change</span> = <span class="ruby-identifier">p4</span>.<span class="ruby-identifier">run_describe</span>( <span class="ruby-value str">"-s"</span>, <span class="ruby-identifier">change_no</span> ) 238: <span class="ruby-keyword kw">end</span> </pre> </div> </div> </div> <div id="method-M000033" class="method-detail"> <a name="M000033"></a> <div class="method-heading"> <a href="#M000033" class="method-signature"> <span class="method-name">message</span><span class="method-args">( string )</span> </a> </div> <div class="method-description"> <p> Method to send a message to the user. Just writes to stdout, but it’s nice to encapsulate that here. </p> <p><a class="source-toggle" href="#" onclick="toggleCode('M000033-source');return false;">[Source]</a></p> <div class="method-source-code" id="M000033-source"> <pre> <span class="ruby-comment cmt"># File P4Triggers.rb, line 252</span> 252: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">message</span>( <span class="ruby-identifier">string</span> ) 253: <span class="ruby-identifier">$stdout</span>.<span class="ruby-identifier">print</span>( <span class="ruby-identifier">string</span> ) 254: <span class="ruby-keyword kw">end</span> </pre> </div> </div> </div> <div id="method-M000030" class="method-detail"> <a name="M000030"></a> <div class="method-heading"> <a href="#M000030" class="method-signature"> <span class="method-name">parse_change</span><span class="method-args">( change_no )</span> </a> </div> <div class="method-description"> <p> The main execution phase of the trigger. We assume since this is a pre-submit trigger that there will be a changelist involved. The steps for most triggers are common: </p> <ol> <li>Find out about the changelist </li> <li>Enforce the rules </li> </ol> <p> We try to generalise this process so this class calls <a href="P4Trigger.html#M000031">get_change</a>() for step 1, and validate() for step 2. Subclasses may override these methods to tailor the trigger’s behaviour </p> <p> <a href="P4Trigger.html#M000030">parse_change</a>() returns the correct exit status for the trigger so you would normally use it like this: </p> <pre> exit( trig.parse_change( change_no ) ) </pre> <p><a class="source-toggle" href="#" onclick="toggleCode('M000030-source');return false;">[Source]</a></p> <div class="method-source-code" id="M000030-source"> <pre> <span class="ruby-comment cmt"># File P4Triggers.rb, line 196</span> 196: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">parse_change</span>( <span class="ruby-identifier">change_no</span> ) 197: <span class="ruby-keyword kw">begin</span> 198: <span class="ruby-keyword kw">if</span> ( <span class="ruby-operator">!</span> <span class="ruby-identifier">change_no</span> ) 199: <span class="ruby-identifier">raise</span>( <span class="ruby-value str">"No changelist number supplied to trigger script.\n"</span> <span class="ruby-operator">+</span> 200: <span class="ruby-value str">"Please check your trigger configuration."</span> 201: ) 202: <span class="ruby-keyword kw">end</span> 203: <span class="ruby-identifier">get_change</span>( <span class="ruby-identifier">change_no</span> ) 204: <span class="ruby-keyword kw">return</span> ( <span class="ruby-identifier">validate</span>() <span class="ruby-operator">?</span> <span class="ruby-value">0</span> <span class="ruby-operator">:</span> <span class="ruby-value">1</span> ) 205: <span class="ruby-keyword kw">rescue</span> 206: <span class="ruby-comment cmt"># Full error report to stderr, so they go into the Perforce server's</span> 207: <span class="ruby-comment cmt"># logfile </span> 208: <span class="ruby-identifier">$stderr</span>.<span class="ruby-identifier">puts</span>( <span class="ruby-value str">"\nError during trigger execution:\n\n"</span> ) 209: <span class="ruby-keyword kw">if</span> ( <span class="ruby-identifier">$!</span>.<span class="ruby-identifier">kind_of?</span>( <span class="ruby-constant">P4Exception</span> ) ) 210: <span class="ruby-identifier">p4</span>.<span class="ruby-identifier">warnings</span>.<span class="ruby-identifier">each</span> { <span class="ruby-operator">|</span><span class="ruby-identifier">w</span><span class="ruby-operator">|</span> <span class="ruby-identifier">$stderr</span>.<span class="ruby-identifier">puts</span>( <span class="ruby-value str">"WARNING: "</span> <span class="ruby-operator">+</span> <span class="ruby-identifier">w</span> ) } 211: <span class="ruby-identifier">p4</span>.<span class="ruby-identifier">errors</span>.<span class="ruby-identifier">each</span> { <span class="ruby-operator">|</span><span class="ruby-identifier">e</span><span class="ruby-operator">|</span> <span class="ruby-identifier">$stderr</span>.<span class="ruby-identifier">puts</span>( <span class="ruby-value str">"ERROR: "</span> <span class="ruby-operator">+</span> <span class="ruby-identifier">e</span> ) } 212: <span class="ruby-keyword kw">else</span> 213: <span class="ruby-identifier">$stderr</span>.<span class="ruby-identifier">puts</span>( <span class="ruby-identifier">$!</span>.<span class="ruby-identifier">to_s</span> ) 214: <span class="ruby-keyword kw">end</span> 215: <span class="ruby-identifier">$stderr</span>.<span class="ruby-identifier">puts</span>( <span class="ruby-value str">"\nStack Trace:\n"</span> ) 216: <span class="ruby-identifier">$stderr</span>.<span class="ruby-identifier">puts</span>( <span class="ruby-identifier">$!</span>.<span class="ruby-identifier">backtrace</span> ) 217: 218: <span class="ruby-comment cmt">#</span> 219: <span class="ruby-comment cmt"># Simpler error report (sans-stack backtrace) to stdout.</span> 220: <span class="ruby-comment cmt">#</span> 221: <span class="ruby-identifier">$stdout</span>.<span class="ruby-identifier">puts</span>( <span class="ruby-identifier">error_message</span>() ) 222: <span class="ruby-identifier">p4</span>.<span class="ruby-identifier">warnings</span>.<span class="ruby-identifier">each</span> { <span class="ruby-operator">|</span><span class="ruby-identifier">w</span><span class="ruby-operator">|</span> <span class="ruby-identifier">$stdout</span>.<span class="ruby-identifier">puts</span>( <span class="ruby-value str">"WARNING: "</span> <span class="ruby-operator">+</span> <span class="ruby-identifier">w</span> ) } 223: <span class="ruby-identifier">p4</span>.<span class="ruby-identifier">errors</span>.<span class="ruby-identifier">each</span> { <span class="ruby-operator">|</span><span class="ruby-identifier">e</span><span class="ruby-operator">|</span> <span class="ruby-identifier">$stdeoutrr</span>.<span class="ruby-identifier">puts</span>( <span class="ruby-value str">"ERROR: "</span> <span class="ruby-operator">+</span> <span class="ruby-identifier">e</span> ) } 224: 225: 226: <span class="ruby-comment cmt"># Now we return false to the caller so they can return with </span> 227: <span class="ruby-comment cmt"># the correct exit status</span> 228: <span class="ruby-keyword kw">return</span> <span class="ruby-value">1</span> 229: <span class="ruby-keyword kw">end</span> 230: <span class="ruby-keyword kw">end</span> </pre> </div> </div> </div> <div id="method-M000032" class="method-detail"> <a name="M000032"></a> <div class="method-heading"> <a href="#M000032" class="method-signature"> <span class="method-name">validate</span><span class="method-args">()</span> </a> </div> <div class="method-description"> <p> The default implementation of validate(). Very simple, it accepts everything. You are expected to override this method with one of your own. When you do so, you can use the @change member to get at the details of the change you’re validating. </p> <p><a class="source-toggle" href="#" onclick="toggleCode('M000032-source');return false;">[Source]</a></p> <div class="method-source-code" id="M000032-source"> <pre> <span class="ruby-comment cmt"># File P4Triggers.rb, line 244</span> 244: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">validate</span>() 245: <span class="ruby-keyword kw">true</span> 246: <span class="ruby-keyword kw">end</span> </pre> </div> </div> </div> </div> </div> <div id="validator-badges"> <p><small><a href="http://validator.w3.org/check/referer">[Validate]</a></small></p> </div> </body> </html>
# | Change | User | Description | Committed | |
---|---|---|---|---|---|
#1 | 6014 | Robert Cowham | Bring in Tony's latest trigger changes | ||
//guest/tony_smith/perforce/P4Rubylib/triggers/doc/classes/P4Trigger.html | |||||
#3 | 4654 | Tony Smith |
Add an example spec trigger to show how you might restrict the default view for all new clients to a pre-defined set of mappings. |
||
#2 | 4640 | Tony Smith |
Add a sample post-commit trigger that can be used to keep a master and slave branch in sync. |
||
#1 | 3637 | Tony Smith | Add RDoc documentation to the sample triggers. |