<?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. |