CaseTrigger (Class)

In: checkcase.rb
Parent: P4Trigger

The trigger class itself. The main method in here is validate() which is invoked from the super-class’ parse_change() method.

Public Class methods

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.

[Source]

    # File checkcase.rb, line 54
54:     def initialize( max_errors )
55:         @max_errors = max_errors
56:         super()
57:     end

Public Instance methods

Method to see whether a depot with a name matching the argument already exists.

[Source]

     # File checkcase.rb, line 121
121:     def mismatch_depot( depot )
122:         match = false
123:         lcdepot = depot.downcase
124:         p4.run_depots.each do
125:             |line|
126:             dname = line.split()[ 1 ]
127:             lcdname = dname.downcase
128:             if ( lcdname == lcdepot && dname != depot )
129:                 match = true
130:                 @mismatch = "//" + dname
131:                 break
132:             end
133:         end
134:         match
135:     end

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.

[Source]

     # File checkcase.rb, line 140
140:     def mismatch_dirs( depot, dirs )
141:         match = false
142:         path = "//" + depot
143:         dirs.each do
144:             |dir|
145:             lcpath = path.downcase
146:             p4.run_dirs( path + "/*" ).each do
147:                 |d|
148:                 d = d[ "dir" ] # We're in tagged mode
149:                 dname = d.sub( path + "/", "" )
150: 
151:                 if ( dir.downcase == dname.downcase )
152:                     # We found a match
153:                     if ( dir != dname )
154:                         match = true
155:                         @mismatch = d
156:                     end
157:                     break
158:                 end
159:             end
160: 
161:             # If we found a mismatch, we can break out now
162:             break if ( match )
163: 
164:             # This level is now OK, we need to descend to the
165:             # next level in the tree
166:             path << "/" << dir
167:         end
168:         match
169:     end

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.

[Source]

     # File checkcase.rb, line 104
104:     def mismatch_exists( path )
105:         path = path[ 2..-1 ]   # Strip off leading //
106:         dirs = path.split( "/" )
107:         depot = dirs.shift
108:         file  = dirs.pop
109: 
110:         # Now look for mis-matching depots
111:         return true if mismatch_depot( depot )
112: 
113:         # Now look for mis-matching directories
114:         return true if mismatch_dirs( depot, dirs )
115: 
116:         return false
117:     end

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.

[Source]

     # File checkcase.rb, line 174
174:     def report( badfiles )
175:         errors = 0
176:         msg = @@USER_MESSAGE
177:         badfiles.each do
178:             |file,mismatch|
179:             msg += sprintf( @@BADFILE_FORMAT, file, mismatch )
180:             errors += 1
181:             break if ( errors >= @max_errors )
182: 
183:         end
184:         message( msg )
185:     end

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.

[Source]

    # File checkcase.rb, line 79
79:     def validate()
80:         badlist = Hash.new
81:         change.each_file do
82:             |file|
83:             # Ignore files not open for add or branch
84:             action = file.revisions[ 0 ].action
85:             next unless ( action == "add" || action == "branch" )
86: 
87:             if ( mismatch_exists( file.depot_file ) )
88:                 # @mismatch set by mismatch_exists() et. al.
89:                 badlist[ file.depot_file ] = @mismatch
90:             end
91:         end
92: 
93:         # Now report any problems to the user
94:         report( badlist ) if ( ! badlist.empty? )
95:         return badlist.empty?
96:     end

[Validate]