#!/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