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.
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.
# File checkcase.rb, line 54 54: def initialize( max_errors ) 55: @max_errors = max_errors 56: super() 57: end
Method to see whether a depot with a name matching the argument already exists.
# 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.
# 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.
# 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.
# 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.
# 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