[p4ruby] diff output

Jeff J. jeffperforce at gmail.com
Thu Mar 13 14:28:14 PDT 2008


>
>  We have an array of hashes.  Each hash already contains the parsed
>  version of the raw perforce output.  Each hash contains the
>  information for a specific file.  One file, one hash.
>
>  Except this is not the case.  Some elements in the array are strings
>  which pertain to the previous hash.  Remember, the perforce output has
>  already been parsed.  Those strings should not be floating around
>  aimlessly.  They are tied to a specific file.  They should be included
>  in the hash which describes the file to which they belong.

In my opinion, the P4#run behavior described above is unreasonable; it
should behave like P4#gathered_run (below).  Until then, I guess I'll
always use gathered_run instead.

class P4
   #
   # Call P4#run, gathering the non-hash elements of the result array
   # into the previously appearing hash in the array.
   #
   # For an element _elem_ in the returned array,
   # <code>elem.output</code> gives the non-hash elements appearing
   # immediately after _elem_ in the original result array.
   #
   # Example: Create a diff compatible with the "patch" program:
   #
   #     p4.gathered_run("diff", "-du", *ARGV).each { |elem|
   #        if elem["type"] =~ %r!text! and not elem.output.empty?
   #           %w(- +).each { |sig|
   #              puts("#{sig*3} #{elem['clientFile']}")
   #           }
   #           puts(elem.output)
   #        end
   #     }
   #
   def gathered_run(*args)
      result = run(args)
      last_hash = nil
      gathered_output = []
      index = 0
      while index < result.size + 1
         elem = result[index]
         if elem.is_a?(Hash) or index == result.size
            # hash element or past the end of the array
            if last_hash
               lambda {
                  # bind here
                  output = gathered_output

                  class << last_hash
                     self
                  end.class_eval {
                     define_method(:output) {
                        output
                     }
                  }
               }.call
            end
            last_hash = elem
            gathered_output = Array.new
            index += 1
         elsif last_hash.nil?
            raise(P4Exception,
                  "gathered_run: non-hash elements found before hash elements")
         else
            gathered_output << result.slice!(index)
         end
      end
      result
   end
end



More information about the p4ruby mailing list