<?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: CaseTrigger</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>CaseTrigger <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/checkcase_rb.html"> checkcase.rb </a> <br /> </td> </tr> <tr class="top-aligned-row"> <td><strong>Parent:</strong></td> <td> <a href="P4Trigger.html"> P4Trigger </a> </td> </tr> </table> </div> <!-- banner header --> <div id="bodyContent"> <div id="contextContent"> <div id="description"> <p> The trigger class itself. The main method in here is validate() which is invoked from the super-class’ parse_change() method. </p> </div> <div id="method-list"> <h2 class="section-bar">Methods</h2> <div class="name-list"> <a href="#M000026">mismatch_depot</a> <a href="#M000027">mismatch_dirs</a> <a href="#M000025">mismatch_exists</a> <a href="#M000023">new</a> <a href="#M000028">report</a> <a href="#M000024">validate</a> </div> </div> </div> <!-- if includes --> <!-- if method_list --> <div id="methods"> <h2 class="section-bar">Public Class methods</h2> <div id="method-M000023" class="method-detail"> <a name="M000023"></a> <div class="method-heading"> <a href="#M000023" class="method-signature"> <span class="method-name">new</span><span class="method-args">( max_errors )</span> </a> </div> <div class="method-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> <p><a class="source-toggle" href="#" onclick="toggleCode('M000023-source');return false;">[Source]</a></p> <div class="method-source-code" id="M000023-source"> <pre> <span class="ruby-comment cmt"># File checkcase.rb, line 54</span> 54: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">initialize</span>( <span class="ruby-identifier">max_errors</span> ) 55: <span class="ruby-ivar">@max_errors</span> = <span class="ruby-identifier">max_errors</span> 56: <span class="ruby-keyword kw">super</span>() 57: <span class="ruby-keyword kw">end</span> </pre> </div> </div> </div> <h2 class="section-bar">Public Instance methods</h2> <div id="method-M000026" class="method-detail"> <a name="M000026"></a> <div class="method-heading"> <a href="#M000026" class="method-signature"> <span class="method-name">mismatch_depot</span><span class="method-args">( depot )</span> </a> </div> <div class="method-description"> <p> Method to see whether a depot with a name matching the argument already exists. </p> <p><a class="source-toggle" href="#" onclick="toggleCode('M000026-source');return false;">[Source]</a></p> <div class="method-source-code" id="M000026-source"> <pre> <span class="ruby-comment cmt"># File checkcase.rb, line 121</span> 121: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">mismatch_depot</span>( <span class="ruby-identifier">depot</span> ) 122: <span class="ruby-identifier">match</span> = <span class="ruby-keyword kw">false</span> 123: <span class="ruby-identifier">lcdepot</span> = <span class="ruby-identifier">depot</span>.<span class="ruby-identifier">downcase</span> 124: <span class="ruby-identifier">p4</span>.<span class="ruby-identifier">run_depots</span>.<span class="ruby-identifier">each</span> <span class="ruby-keyword kw">do</span> 125: <span class="ruby-operator">|</span><span class="ruby-identifier">line</span><span class="ruby-operator">|</span> 126: <span class="ruby-identifier">dname</span> = <span class="ruby-identifier">line</span>.<span class="ruby-identifier">split</span>()[ <span class="ruby-value">1</span> ] 127: <span class="ruby-identifier">lcdname</span> = <span class="ruby-identifier">dname</span>.<span class="ruby-identifier">downcase</span> 128: <span class="ruby-keyword kw">if</span> ( <span class="ruby-identifier">lcdname</span> <span class="ruby-operator">==</span> <span class="ruby-identifier">lcdepot</span> <span class="ruby-operator">&&</span> <span class="ruby-identifier">dname</span> <span class="ruby-operator">!=</span> <span class="ruby-identifier">depot</span> ) 129: <span class="ruby-identifier">match</span> = <span class="ruby-keyword kw">true</span> 130: <span class="ruby-ivar">@mismatch</span> = <span class="ruby-value str">"//"</span> <span class="ruby-operator">+</span> <span class="ruby-identifier">dname</span> 131: <span class="ruby-keyword kw">break</span> 132: <span class="ruby-keyword kw">end</span> 133: <span class="ruby-keyword kw">end</span> 134: <span class="ruby-identifier">match</span> 135: <span class="ruby-keyword kw">end</span> </pre> </div> </div> </div> <div id="method-M000027" class="method-detail"> <a name="M000027"></a> <div class="method-heading"> <a href="#M000027" class="method-signature"> <span class="method-name">mismatch_dirs</span><span class="method-args">( depot, dirs )</span> </a> </div> <div class="method-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> <p><a class="source-toggle" href="#" onclick="toggleCode('M000027-source');return false;">[Source]</a></p> <div class="method-source-code" id="M000027-source"> <pre> <span class="ruby-comment cmt"># File checkcase.rb, line 140</span> 140: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">mismatch_dirs</span>( <span class="ruby-identifier">depot</span>, <span class="ruby-identifier">dirs</span> ) 141: <span class="ruby-identifier">match</span> = <span class="ruby-keyword kw">false</span> 142: <span class="ruby-identifier">path</span> = <span class="ruby-value str">"//"</span> <span class="ruby-operator">+</span> <span class="ruby-identifier">depot</span> 143: <span class="ruby-identifier">dirs</span>.<span class="ruby-identifier">each</span> <span class="ruby-keyword kw">do</span> 144: <span class="ruby-operator">|</span><span class="ruby-identifier">dir</span><span class="ruby-operator">|</span> 145: <span class="ruby-identifier">lcpath</span> = <span class="ruby-identifier">path</span>.<span class="ruby-identifier">downcase</span> 146: <span class="ruby-identifier">p4</span>.<span class="ruby-identifier">run_dirs</span>( <span class="ruby-identifier">path</span> <span class="ruby-operator">+</span> <span class="ruby-value str">"/*"</span> ).<span class="ruby-identifier">each</span> <span class="ruby-keyword kw">do</span> 147: <span class="ruby-operator">|</span><span class="ruby-identifier">d</span><span class="ruby-operator">|</span> 148: <span class="ruby-identifier">d</span> = <span class="ruby-identifier">d</span>[ <span class="ruby-value str">"dir"</span> ] <span class="ruby-comment cmt"># We're in tagged mode</span> 149: <span class="ruby-identifier">dname</span> = <span class="ruby-identifier">d</span>.<span class="ruby-identifier">sub</span>( <span class="ruby-identifier">path</span> <span class="ruby-operator">+</span> <span class="ruby-value str">"/"</span>, <span class="ruby-value str">""</span> ) 150: 151: <span class="ruby-keyword kw">if</span> ( <span class="ruby-identifier">dir</span>.<span class="ruby-identifier">downcase</span> <span class="ruby-operator">==</span> <span class="ruby-identifier">dname</span>.<span class="ruby-identifier">downcase</span> ) 152: <span class="ruby-comment cmt"># We found a match</span> 153: <span class="ruby-keyword kw">if</span> ( <span class="ruby-identifier">dir</span> <span class="ruby-operator">!=</span> <span class="ruby-identifier">dname</span> ) 154: <span class="ruby-identifier">match</span> = <span class="ruby-keyword kw">true</span> 155: <span class="ruby-ivar">@mismatch</span> = <span class="ruby-identifier">d</span> 156: <span class="ruby-keyword kw">end</span> 157: <span class="ruby-keyword kw">break</span> 158: <span class="ruby-keyword kw">end</span> 159: <span class="ruby-keyword kw">end</span> 160: 161: <span class="ruby-comment cmt"># If we found a mismatch, we can break out now</span> 162: <span class="ruby-keyword kw">break</span> <span class="ruby-keyword kw">if</span> ( <span class="ruby-identifier">match</span> ) 163: 164: <span class="ruby-comment cmt"># This level is now OK, we need to descend to the</span> 165: <span class="ruby-comment cmt"># next level in the tree</span> 166: <span class="ruby-identifier">path</span> <span class="ruby-operator"><<</span> <span class="ruby-value str">"/"</span> <span class="ruby-operator"><<</span> <span class="ruby-identifier">dir</span> 167: <span class="ruby-keyword kw">end</span> 168: <span class="ruby-identifier">match</span> 169: <span class="ruby-keyword kw">end</span> </pre> </div> </div> </div> <div id="method-M000025" class="method-detail"> <a name="M000025"></a> <div class="method-heading"> <a href="#M000025" class="method-signature"> <span class="method-name">mismatch_exists</span><span class="method-args">( path )</span> </a> </div> <div class="method-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> <p><a class="source-toggle" href="#" onclick="toggleCode('M000025-source');return false;">[Source]</a></p> <div class="method-source-code" id="M000025-source"> <pre> <span class="ruby-comment cmt"># File checkcase.rb, line 104</span> 104: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">mismatch_exists</span>( <span class="ruby-identifier">path</span> ) 105: <span class="ruby-identifier">path</span> = <span class="ruby-identifier">path</span>[ <span class="ruby-value">2</span><span class="ruby-operator">..</span><span class="ruby-value">-1</span> ] <span class="ruby-comment cmt"># Strip off leading //</span> 106: <span class="ruby-identifier">dirs</span> = <span class="ruby-identifier">path</span>.<span class="ruby-identifier">split</span>( <span class="ruby-value str">"/"</span> ) 107: <span class="ruby-identifier">depot</span> = <span class="ruby-identifier">dirs</span>.<span class="ruby-identifier">shift</span> 108: <span class="ruby-identifier">file</span> = <span class="ruby-identifier">dirs</span>.<span class="ruby-identifier">pop</span> 109: 110: <span class="ruby-comment cmt"># Now look for mis-matching depots</span> 111: <span class="ruby-keyword kw">return</span> <span class="ruby-keyword kw">true</span> <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">mismatch_depot</span>( <span class="ruby-identifier">depot</span> ) 112: 113: <span class="ruby-comment cmt"># Now look for mis-matching directories</span> 114: <span class="ruby-keyword kw">return</span> <span class="ruby-keyword kw">true</span> <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">mismatch_dirs</span>( <span class="ruby-identifier">depot</span>, <span class="ruby-identifier">dirs</span> ) 115: 116: <span class="ruby-keyword kw">return</span> <span class="ruby-keyword kw">false</span> 117: <span class="ruby-keyword kw">end</span> </pre> </div> </div> </div> <div id="method-M000028" class="method-detail"> <a name="M000028"></a> <div class="method-heading"> <a href="#M000028" class="method-signature"> <span class="method-name">report</span><span class="method-args">( badfiles )</span> </a> </div> <div class="method-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> <p><a class="source-toggle" href="#" onclick="toggleCode('M000028-source');return false;">[Source]</a></p> <div class="method-source-code" id="M000028-source"> <pre> <span class="ruby-comment cmt"># File checkcase.rb, line 174</span> 174: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">report</span>( <span class="ruby-identifier">badfiles</span> ) 175: <span class="ruby-identifier">errors</span> = <span class="ruby-value">0</span> 176: <span class="ruby-identifier">msg</span> = @<span class="ruby-ivar">@USER_MESSAGE</span> 177: <span class="ruby-identifier">badfiles</span>.<span class="ruby-identifier">each</span> <span class="ruby-keyword kw">do</span> 178: <span class="ruby-operator">|</span><span class="ruby-identifier">file</span>,<span class="ruby-identifier">mismatch</span><span class="ruby-operator">|</span> 179: <span class="ruby-identifier">msg</span> <span class="ruby-operator">+=</span> <span class="ruby-identifier">sprintf</span>( @<span class="ruby-ivar">@BADFILE_FORMAT</span>, <span class="ruby-identifier">file</span>, <span class="ruby-identifier">mismatch</span> ) 180: <span class="ruby-identifier">errors</span> <span class="ruby-operator">+=</span> <span class="ruby-value">1</span> 181: <span class="ruby-keyword kw">break</span> <span class="ruby-keyword kw">if</span> ( <span class="ruby-identifier">errors</span> <span class="ruby-operator">>=</span> <span class="ruby-ivar">@max_errors</span> ) 182: 183: <span class="ruby-keyword kw">end</span> 184: <span class="ruby-identifier">message</span>( <span class="ruby-identifier">msg</span> ) 185: <span class="ruby-keyword kw">end</span> </pre> </div> </div> </div> <div id="method-M000024" class="method-detail"> <a name="M000024"></a> <div class="method-heading"> <a href="#M000024" class="method-signature"> <span class="method-name">validate</span><span class="method-args">()</span> </a> </div> <div class="method-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> <p><a class="source-toggle" href="#" onclick="toggleCode('M000024-source');return false;">[Source]</a></p> <div class="method-source-code" id="M000024-source"> <pre> <span class="ruby-comment cmt"># File checkcase.rb, line 79</span> 79: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">validate</span>() 80: <span class="ruby-identifier">badlist</span> = <span class="ruby-constant">Hash</span>.<span class="ruby-identifier">new</span> 81: <span class="ruby-identifier">change</span>.<span class="ruby-identifier">each_file</span> <span class="ruby-keyword kw">do</span> 82: <span class="ruby-operator">|</span><span class="ruby-identifier">file</span><span class="ruby-operator">|</span> 83: <span class="ruby-comment cmt"># Ignore files not open for add or branch</span> 84: <span class="ruby-identifier">action</span> = <span class="ruby-identifier">file</span>.<span class="ruby-identifier">revisions</span>[ <span class="ruby-value">0</span> ].<span class="ruby-identifier">action</span> 85: <span class="ruby-keyword kw">next</span> <span class="ruby-keyword kw">unless</span> ( <span class="ruby-identifier">action</span> <span class="ruby-operator">==</span> <span class="ruby-value str">"add"</span> <span class="ruby-operator">||</span> <span class="ruby-identifier">action</span> <span class="ruby-operator">==</span> <span class="ruby-value str">"branch"</span> ) 86: 87: <span class="ruby-keyword kw">if</span> ( <span class="ruby-identifier">mismatch_exists</span>( <span class="ruby-identifier">file</span>.<span class="ruby-identifier">depot_file</span> ) ) 88: <span class="ruby-comment cmt"># @mismatch set by mismatch_exists() et. al.</span> 89: <span class="ruby-identifier">badlist</span>[ <span class="ruby-identifier">file</span>.<span class="ruby-identifier">depot_file</span> ] = <span class="ruby-ivar">@mismatch</span> 90: <span class="ruby-keyword kw">end</span> 91: <span class="ruby-keyword kw">end</span> 92: 93: <span class="ruby-comment cmt"># Now report any problems to the user</span> 94: <span class="ruby-identifier">report</span>( <span class="ruby-identifier">badlist</span> ) <span class="ruby-keyword kw">if</span> ( <span class="ruby-operator">!</span> <span class="ruby-identifier">badlist</span>.<span class="ruby-identifier">empty?</span> ) 95: <span class="ruby-keyword kw">return</span> <span class="ruby-identifier">badlist</span>.<span class="ruby-identifier">empty?</span> 96: <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/CaseTrigger.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. |