# Task: compare two labels, create report giving # lists of # only in first label # only in second label, # in both, but the revision in the label isn't same. # # num of calls to 'p4': 2 calls to 'p4 files' # status: tested on Win/NT using P4Ruby API, # tested on Darwin Mac OS X using P4Ruby API # # Copyright 2004 Perforce Corporation, Inc. All rights reserved. require 'getoptlong' label1 = label2 = nil debugOption = false defaultPort = nil defaultUser = nil options = GetoptLong.new( [ '--debug', '-d', GetoptLong::OPTIONAL_ARGUMENT], [ '--user', '-u', GetoptLong::REQUIRED_ARGUMENT], [ '--label1', '-1', GetoptLong::REQUIRED_ARGUMENT], [ '--label2', '-2', GetoptLong::REQUIRED_ARGUMENT], [ '--port', '-p', GetoptLong::REQUIRED_ARGUMENT] ) options.each do |opt, arg| case opt when "--debug" debugOption = true when "--user" defaultUser = arg when "--port" defaultPort = arg when "--label1" label1 = arg when "--label2" label2 = arg end end raise RuntimeError, "--label1 XXXX must be given on command-line" if label1 == nil raise RuntimeError, "--label2 XXXX must be given on command-line" if label2 == nil require "P4" p4 = P4.new p4.port = defaultPort if defaultPort != nil p4.user = defaultUser if defaultUser != nil # p4.client = "dent.development" p4.tagged p4.parse_forms p4.connect begin puts "label1 = #{label1}" if debugOption puts "label2 = #{label2}" if debugOption # # strategy: # 1. We'll collect Perforce output in "label1list" # a.and in order to let Ruby "set operations" assist, # we'll make an Array of "label1filenames" that are # only the filenames;, # b.and for fast lookup of revisions, a "label1revbyfname" # 2. Afterwards, it's a set operation (subtract) to get # the list of filenames "in one label but not the other" # 3. And a set operation (intersection - that's "&") to # get the filenames in both places, which we can infer # are the ones we need to look at to see if there are # different revisions to report. (item 1b, above, # has the structures in place to do so.) #----------------------------------------------------------- # first call to P4: 'p4 files @label1' #----------------------------------------------------------- label1list = p4.run("files", "@#{label1}") label1revbyfname = {} label1list.each { |f| label1revbyfname[f['depotFile']] = f['rev'] } label1filenames = label1list.collect { |f| f['depotFile'] } puts label1filenames.inspect if debugOption #----------------------------------------------------------- # second call to P4: 'p4 files @label2' #----------------------------------------------------------- label2list = p4.run("files", "@#{label2}") label2filenames = label2list.collect { |f| f['depotFile'] } label2revbyfname = {} label2list.each { |f| label2revbyfname[f['depotFile']] = f['rev'] } puts label2filenames.inspect if debugOption # case 1: files in the first label but not the second filesOnlyInLabel1 = label1filenames - label2filenames filesOnlyInLabel1.each { |fname| puts "Only in #{label1}: #{fname}" } # case 2: files in the first label but not the second filesOnlyInLabel2 = label2filenames - label1filenames filesOnlyInLabel2.each { |fname| puts "Only in #{label2}: #{fname}" } # case 3: files in both labels, but different revisions filesInCommon = label2filenames & label1filenames puts "#{filesInCommon.length} files in common (but maybe different revs)" filesInCommon.each do |fname| rev1 = label1revbyfname[fname] rev2 = label2revbyfname[fname] puts "Comparing rev1=#{rev1} rev2=#{rev2} for #{fname}" if debugOption if rev1 != rev2 puts "#{fname} is rev #{rev1} in #{label1} but #{rev2} in #{label2}" end end rescue P4Exception p4.errors.each { |e| $stderr.puts( e ) } raise end p4.disconnect
# | Change | User | Description | Committed | |
---|---|---|---|---|---|
#1 | 4312 | Jeff Bowles |
Adding a number of example scripts that show how to get to Perforce data for a variety of scripting languages and variety of simple tasks. Note that Perl/Python/Ruby (and variants) are included, but shell/batch/DCL/applescript are not. (Am trying to stick with somewhat-portable approaches, to make comparisons easier.) Each program is written in the following languages/configurations: 1. Perl, calling "p4 -Ztag" for data 2. Perl, calling Tony Smith's "P4Perl" module 3. Python, calling "p4 -G" for data 4. Ruby, calling "p4 -R" for data 5. Ruby, calling Tony Smith's "P4Ruby" module The programs do the following: a. compare client specs to users (find old clients) b. compare two labels c. determine which client specs use compression. d. determine which files need to be "p4 add'ed." e. output list of 'opened' files, using local pathnames. |