#!/usr/local/bin/ruby
#
# Copyright 2005 Perforce Software. All rights reserved.
#
require "P4Data.rb"
require "P4Form.rb"
require "P4Valid.rb"
#
# Syntactially corrects the defined fields to be in set format
# with unique values
#
def cleanup_sets(values, sets, fields)
fields.each do |field|
if sets.keys.include?(field) then
value = extract_set(values[field])
#
# Uncomment the following to also sort the sets
#
#value.sort!
if sets[field] == "1" then
values[field] = value.join(" ")
else
values[field] = value.join("\n\t")
end
end
end
end
#
# Returns zero to 2 lines of text listing the changes made to a
# set of values. If no changes were made, then returns the empty string
# Using embedded tabs and newlines for proper inclusion in job
#
def set_delta(oldsetstring, newsetstring)
oldset = extract_set(oldsetstring)
newset = extract_set(newsetstring)
deleted = oldset - newset
added = newset - oldset
line = ""
if deleted.length > 0 then
if added.length > 0 then
line = sprintf("\n\t Adding: %s\n\t Deleting: %s",
added.join(", "), deleted.join(", "))
else
line = sprintf("\n\t Deleting: %s", deleted.join(", "))
end
elsif added.length > 0 then
line = sprintf("\n\t Adding: %s", added.join(", "))
end
return line
end
#
# Returns a formated history line(s) for the specified change
#
def add_history(type, t_form, a_form, field, newhistory)
line = ""
case type
when /moved/
case P4HISTORY[field]
when /select/
line = sprintf("\t %s moved to base job, was %s",
field, t_form.fields[field])
when /word/
line = sprintf("\t %s moved to base job, was %s",
field, t_form.fields[field])
when /set1/
line = sprintf("\t %s moved to base job, was %s",
field, t_form.fields[field])
when /setN/
value = extract_set(t_form.fields[field])
line = sprintf("\t %s moved to base job, was:\n\t %s",
field, value.join("\n\t "))
else
line = sprintf("\t %s moved to base job",
field)
end
when /changed/
case P4HISTORY[field]
when /select/
if a_form.fields[field].strip != t_form.fields[field].strip then
line = sprintf("\t %s changed from %s to %s",
field, a_form.fields[field], t_form.fields[field])
end
when /word/
if a_form.fields[field].strip != t_form.fields[field].strip then
line = sprintf("\t %s changed from %s to %s",
field, a_form.fields[field], t_form.fields[field])
end
when /set[N1]/
changes = set_delta(a_form.fields[field], t_form.fields[field])
if changes != "" then
line = sprintf("\t %s changed by:%s",
field, changes)
end # o/w just placement changes
else
line = sprintf("\t %s changed",
field)
end
when /added/
case P4HISTORY[field]
when /select/
line = sprintf("\t %s added as %s",
field, t_form.fields[field])
when /word/
line = sprintf("\t %s added as %s",
field, t_form.fields[field])
when /set[N1]/
additions = set_delta(nil, t_form.fields[field])
if additions != "" then
line = sprintf("\t %s added by:%s",
field, additions)
end
else
line = sprintf("\t %s added",
field)
end
when /deleted/
case P4HISTORY[field]
when /select/
line = sprintf("\t %s deleted, was %s",
field, a_form.fields[field])
when /word/
line = sprintf("\t %s deleted, was %s",
field, a_form.fields[field])
when /set[N1]/
deletions = set_delta(a_form.fields[field], nil)
if deletions != "" then
line = sprintf("\t %s deleted by:%s",
field, deletions)
end
else
line = sprintf("\t %s deleted",
field)
end
else
line = sprintf("\t unknown action to %s",
field)
end
if line != "" then
newhistory << line
end
end
#
# Goes throught the fields which probably have changed and adds
# a line to the history for each one stating the change appropriately
#
def append_history(ts, u, logfile, t_form, a_form, changed, added, deleted, moved)
newhistory = []
changed.each do |field|
if !P4IGNORE.include?(field) then
add_history("changed", t_form, a_form, field, newhistory)
end
end
added.each do |field|
if !P4IGNORE.include?(field) then
add_history("added", t_form, a_form, field, newhistory)
end
end
deleted.each do |field|
if !P4IGNORE.include?(field) then
add_history("deleted", t_form, a_form, field, newhistory)
end
end
moved.each do |field|
if !P4IGNORE.include?(field) then
add_history("moved", t_form, a_form, field, newhistory)
end
end
if newhistory.length > 0 then
newhistory.sort!
fullhistory = []
fullhistory << sprintf("\t%s, user %s:", ts, u)
fullhistory << newhistory
if t_form.fields[P4HISTORYFIELD] != nil then
fullhistory << t_form.fields[P4HISTORYFIELD].split(/\n/)
end
t_form.fields[P4HISTORYFIELD] = fullhistory.join("\n")
end
end
#
# Look up the default interested parties based on product
#
# search order
# a.b.c
# a.b
# a
# *
def product_watchers(watchlist, product)
if product == nil || product == "" then
return []
end
key = product.split(/[.]/)
done = false
list = nil
while !done && key.length > 0 do
list = watchlist[key.join(".")]
if list != nil then
done = true
else
key[-1..-1] = nil # drop the last item in array
end
end
if key.length == 0 then
list = watchlist["*"]
end
return extract_set(list)
end
#
# Looks up the new owner based on the Status and Product values
# Returns either a possible UserID or "". The function does not
# test to see of the return value is a valid UserID
#
# search order
# a.b.c:z
# a.b.c:*
# a.b:z
# a.b:*
# a:z
# a:*
# *:z
# *:*
def state_owner(flow, fields, status_field, product_field)
seen = [] # Prevents endless loops
state = fields[status_field]
base_state = state
product = fields[product_field].split(/[.]/)
owner = ""
done = false
key = sprintf("%s:%s", product.join("."), state)
while !done && !seen.include?(key) do
owner = flow[key]
seen << key
if owner != nil then
if owner[0..0] == '$' then
#
# Use the value of specified field
#
owner = fields[owner[1..-1]]
done = true
elsif owner[0..0] == '%' then
if owner[1..-1] != base_state then
#
# Restart search using alternative state as the basis
#
state = owner[1..-1]
base_state = state
product = fields[product_field].split(/[.]/)
seen.delete_if { |tag| tag =~ /[^*]:[*]/ } # Purge the blah:* states
owner = ""
elsif state == "*" then
if product.length > 0 then
product[-1..-1] = nil # drop the last item in array
state = base_state # Toggle the state
else
done = true
end
else
state = "*" # Toggle the state
end
else
done = true
end
elsif state == "*" then
if product.length > 0 then
product[-1..-1] = nil # drop the last item in array
state = base_state # Toggle the state
else
done = true
end
else
state = "*" # Toggle the state
end
# Build next search key
if product.length > 0 then
key = sprintf("%s:%s", product.join("."), state)
else
key = sprintf("*:%s", state)
end
end
# Sanitize owner
if owner == nil then
owner = ""
end
return owner
end