# Task: determine which files need to be "p4 add'ed." # # num of calls to 'p4': 2 # status: tested on Darwin Mac OS X using "p4 -R" # # Copyright 2004 Perforce Corporation, Inc. All rights reserved. require "readp4marshal" require 'getoptlong' require "find" verboseOption = false defaultPort = nil defaultUser = nil defaultClient = nil options = GetoptLong.new( [ '--verbose', '-v', GetoptLong::OPTIONAL_ARGUMENT], [ '--user', '-u', GetoptLong::REQUIRED_ARGUMENT], [ '--port', '-p', GetoptLong::REQUIRED_ARGUMENT], [ '--client', '-c', GetoptLong::REQUIRED_ARGUMENT], [ '--help', '-h', GetoptLong::REQUIRED_ARGUMENT], [ '--quiet', '-q', GetoptLong::REQUIRED_ARGUMENT] ) options.each do |opt, arg| case opt when "--verbose" verboseOption = true when "--user" defaultUser = arg when "--client" defaultClient = arg when "--port" defaultPort = arg when "--quiet" puts "'--quiet' not implemented yet." when "--help" puts options.Usage end end p4 = P4Marshal.new("p4port" => defaultPort, "p4user" => defaultUser, "p4client" => defaultClient) #----------------------------------------------------------- # first call to P4: 'p4 client -o' #----------------------------------------------------------- puts "Step 1: Get the client name." cl_spec = p4.run("client", "-o")[0] cl_name = cl_spec['Client'] cl_root = cl_spec['Root'] puts "Ran user-client, output was \"client=#{cl_name}\"" #----------------------------------------------------------- # second call to P4: 'p4 fstat //myclient/...' #----------------------------------------------------------- puts "Step 2: Get the list of Perforce-known files." ret = p4.run("fstat", "//#{cl_name}/...").delete_if { |r| r['headAction'] == 'delete' } # # at this point, we create two arrays to hold # the filenames: # allFilesPerforce - from "p4 fstat //myclient/..." # allFilesPresent - from "Find.find(cl_root)" # we can use set operations for the tricky stuff, and # it's a great advert for Ruby. # # (note that we map the path-separator to be '/', regardless # of platform. Ruby's polite about using '/' everywhere; the # output of "p4 fstat" uses '\' for Windows.) # allFilesPerforce = ret.collect { |r| r['clientFile'].tr('\\', '/') } puts "Step 3: Get the list of files on the local disk." allFilesPresent = [] Find.find(cl_root) do |f| Find.prune if f == "." || f == ".." allFilesPresent << f if File.stat(f).file? end puts "List of files present in workspace, but unknown to Perforce:" puts (allFilesPresent - allFilesPerforce) puts "List of files known to Perforce, but not (yet) synced to workspace:" puts (allFilesPerforce - allFilesPresent)
# | 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. |