<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> <head> <title>Class: CaseTrigger</title> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" /> <link rel=StyleSheet href=".././rdoc-style.css" type="text/css" media="screen" /> <script type="text/javascript" language="JavaScript"> <!-- function popCode(url) { window.open(url, "Code", "resizable=yes,scrollbars=yes,toolbar=no,status=no,height=150,width=400") } //--> </script> </head> <body bgcolor="white"> <table summary="Information on class" width="100%" border="0" cellspacing="0"> <tr class="title-row"> <td class="big-title-font"> <sup><font color="aqua">Class</font></sup> CaseTrigger </td> <td align="right"> <table summary="layout" cellspacing="0" cellpadding="2"> <tr valign="top"> <td class="small-title-font">In:</td> <td class="small-title-font"> <a href="../files/checkcase_rb.html" class="aqua"> checkcase.rb </a> <br /> </td> </tr> <tr> <td class="small-title-font">Parent:</td> <td class="small-title-font"> <a href="P4Trigger.html" class="aqua"> P4Trigger </a> </td> </tr> </table> </td> </tr> </table> <!-- banner header --> <div class="description"><p> The trigger class itself. The main method in here is validate() which is invoked from the super-class’ <a href="P4Trigger.html#M000021">parse_change</a>() method. </p> </div> <table summary="Methods" cellpadding="5" width="100%"> <tr><td class="tablesubtitle">Methods</td></tr> </table> <div class="name-list"> <a href="#M000017">mismatch_depot</a> <a href="#M000018">mismatch_dirs</a> <a href="#M000016">mismatch_exists</a> <a href="#M000014">new</a> <a href="#M000019">report</a> <a href="#M000015">validate</a> </div> <table summary="Method list" cellpadding="5" width="100%"> <tr><td class="tablesubtitle">Public Class methods</td></tr> </table> <table summary="method" width="100%" cellspacing="0" cellpadding="5" border="0"> <tr><td class="methodtitle"> <a name="M000014"></a> <b>new</b>( max_errors ) </td></tr> </table> <div class="description"> <p> Constructor. In this trigger we want to limit the number of errors we might report to the user because on a large changelist that could be a real pain. Simply pass the maximum number you want your users to deal with at one time. </p> </div> <pre class="source"> <span class="cmt"># File checkcase.rb, line 54</span> <span class="kw">def</span> initialize( max_errors ) @max_errors = max_errors <span class="kw">super</span>() <span class="kw">end</span> </pre> <table summary="Method list" cellpadding="5" width="100%"> <tr><td class="tablesubtitle">Public Instance methods</td></tr> </table> <table summary="method" width="100%" cellspacing="0" cellpadding="5" border="0"> <tr><td class="methodtitle"> <a name="M000015"></a> <b>validate</b>() </td></tr> </table> <div class="description"> <p> Enforce case checking. the basic algorithm is that we split the depot path of each file up into its components and use "p4 depots", "p4 dirs" (depending on what level we’re at to locate existing depots/dirs with the same names in different case. If we find any we reject submission. Note that we are only interested in new files being added/branched since existing files are assumed to be OK. </p> </div> <pre class="source"> <span class="cmt"># File checkcase.rb, line 79</span> <span class="kw">def</span> validate() badlist = Hash.new change.each_file <span class="kw">do</span> |file| <span class="cmt"># Ignore files not open for add or branch</span> action = file.revisions[ 0 ].action <span class="kw">next</span> <span class="kw">unless</span> ( action == <span class="str">"add"</span> || action == <span class="str">"branch"</span> ) <span class="kw">if</span> ( mismatch_exists( file.depot_file ) ) <span class="cmt"># @mismatch set by mismatch_exists() et. al.</span> badlist[ file.depot_file ] = @mismatch <span class="kw">end</span> <span class="kw">end</span> <span class="cmt"># Now report any problems to the user</span> report( badlist ) <span class="kw">if</span> ( ! badlist.empty? ) <span class="kw">return</span> badlist.empty? <span class="kw">end</span> </pre> <table summary="method" width="100%" cellspacing="0" cellpadding="5" border="0"> <tr><td class="methodtitle"> <a name="M000016"></a> <b>mismatch_exists</b>( path ) </td></tr> </table> <div class="description"> <p> This method does the work to check whether or not the components of a path already exist in different case. We do it by breaking the depot path up into components where the first part is the depot name, the last part is the filename and everything in between is a directory name. We then start at the depot and then iteratively check the directories one by one. </p> </div> <pre class="source"> <span class="cmt"># File checkcase.rb, line 104</span> <span class="kw">def</span> mismatch_exists( path ) path = path[ 2..-1 ] <span class="cmt"># Strip off leading //</span> dirs = path.split( <span class="str">"/"</span> ) depot = dirs.shift file = dirs.pop <span class="cmt"># Now look for mis-matching depots</span> <span class="kw">return</span> <span class="kw">true</span> <span class="kw">if</span> mismatch_depot( depot ) <span class="cmt"># Now look for mis-matching directories</span> <span class="kw">return</span> <span class="kw">true</span> <span class="kw">if</span> mismatch_dirs( depot, dirs ) <span class="kw">return</span> <span class="kw">false</span> <span class="kw">end</span> </pre> <table summary="method" width="100%" cellspacing="0" cellpadding="5" border="0"> <tr><td class="methodtitle"> <a name="M000017"></a> <b>mismatch_depot</b>( depot ) </td></tr> </table> <div class="description"> <p> Method to see whether a depot with a name matching the argument already exists. </p> </div> <pre class="source"> <span class="cmt"># File checkcase.rb, line 121</span> <span class="kw">def</span> mismatch_depot( depot ) match = <span class="kw">false</span> lcdepot = depot.downcase p4.run_depots.each <span class="kw">do</span> |line| dname = line.split()[ 1 ] lcdname = dname.downcase <span class="kw">if</span> ( lcdname == lcdepot && dname != depot ) match = <span class="kw">true</span> @mismatch = <span class="str">"//"</span> + dname <span class="kw">break</span> <span class="kw">end</span> <span class="kw">end</span> match <span class="kw">end</span> </pre> <table summary="method" width="100%" cellspacing="0" cellpadding="5" border="0"> <tr><td class="methodtitle"> <a name="M000018"></a> <b>mismatch_dirs</b>( depot, dirs ) </td></tr> </table> <div class="description"> <p> Method to descend the tree looking for mismatched directory names. If we find a mismatch at any level we break off and just return true. If there are no mismatches, returns false. </p> </div> <pre class="source"> <span class="cmt"># File checkcase.rb, line 140</span> <span class="kw">def</span> mismatch_dirs( depot, dirs ) match = <span class="kw">false</span> path = <span class="str">"//"</span> + depot dirs.each <span class="kw">do</span> |dir| lcpath = path.downcase p4.run_dirs( path + <span class="str">"/*"</span> ).each <span class="kw">do</span> |d| d = d[ <span class="str">"dir"</span> ] <span class="cmt"># We're in tagged mode</span> dname = d.sub( path + <span class="str">"/"</span>, <span class="str">""</span> ) <span class="kw">if</span> ( dir.downcase == dname.downcase ) <span class="cmt"># We found a match</span> <span class="kw">if</span> ( dir != dname ) match = <span class="kw">true</span> @mismatch = d <span class="kw">end</span> <span class="kw">break</span> <span class="kw">end</span> <span class="kw">end</span> <span class="cmt"># If we found a mismatch, we can break out now</span> <span class="kw">break</span> <span class="kw">if</span> ( match ) <span class="cmt"># This level is now OK, we need to descend to the</span> <span class="cmt"># next level in the tree</span> path << <span class="str">"/"</span> << dir <span class="kw">end</span> match <span class="kw">end</span> </pre> <table summary="method" width="100%" cellspacing="0" cellpadding="5" border="0"> <tr><td class="methodtitle"> <a name="M000019"></a> <b>report</b>( badfiles ) </td></tr> </table> <div class="description"> <p> Method to report the error to the user. Just formats the error message and sends it. We only report the first @max_errors bad files. On a large changelist they’ll be grateful for that. </p> </div> <pre class="source"> <span class="cmt"># File checkcase.rb, line 174</span> <span class="kw">def</span> report( badfiles ) errors = 0 msg = @@USER_MESSAGE badfiles.each <span class="kw">do</span> |file,mismatch| msg += sprintf( @@BADFILE_FORMAT, file, mismatch ) errors += 1 <span class="kw">break</span> <span class="kw">if</span> ( errors >= @max_errors ) <span class="kw">end</span> message( msg ) <span class="kw">end</span> </pre> </body> </html>
# | Change | User | Description | Committed | |
---|---|---|---|---|---|
#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. |