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
def initialize( max_errors )
@max_errors = max_errors
super()
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
def validate()
badlist = Hash.new
change.each_file do
|file|
# Ignore files not open for add or branch
action = file.revisions[ 0 ].action
next unless ( action == "add" || action == "branch" )
if ( mismatch_exists( file.depot_file ) )
# @mismatch set by mismatch_exists() et. al.
badlist[ file.depot_file ] = @mismatch
end
end
# Now report any problems to the user
report( badlist ) if ( ! badlist.empty? )
return badlist.empty?
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
def mismatch_exists( path )
path = path[ 2..-1 ] # Strip off leading //
dirs = path.split( "/" )
depot = dirs.shift
file = dirs.pop
# Now look for mis-matching depots
return true if mismatch_depot( depot )
# Now look for mis-matching directories
return true if mismatch_dirs( depot, dirs )
return false
end
Method to see whether a depot with a name matching the argument already
exists.
# File checkcase.rb, line 121
def mismatch_depot( depot )
match = false
lcdepot = depot.downcase
p4.run_depots.each do
|line|
dname = line.split()[ 1 ]
lcdname = dname.downcase
if ( lcdname == lcdepot && dname != depot )
match = true
@mismatch = "//" + dname
break
end
end
match
end
mismatch_dirs( depot, dirs )
|
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
def mismatch_dirs( depot, dirs )
match = false
path = "//" + depot
dirs.each do
|dir|
lcpath = path.downcase
p4.run_dirs( path + "/*" ).each do
|d|
d = d[ "dir" ] # We're in tagged mode
dname = d.sub( path + "/", "" )
if ( dir.downcase == dname.downcase )
# We found a match
if ( dir != dname )
match = true
@mismatch = d
end
break
end
end
# If we found a mismatch, we can break out now
break if ( match )
# This level is now OK, we need to descend to the
# next level in the tree
path << "/" << dir
end
match
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
def report( badfiles )
errors = 0
msg = @@USER_MESSAGE
badfiles.each do
|file,mismatch|
msg += sprintf( @@BADFILE_FORMAT, file, mismatch )
errors += 1
break if ( errors >= @max_errors )
end
message( msg )
end