# Task: determine which files need to be "p4 add'ed." # # num of calls to 'p4': 2 # status: tested on Darwin Mac OS X using P4Ruby API # # Copyright 2004 Perforce Corporation, Inc. All rights reserved. require "P4" 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 = P4.new p4.port = defaultPort if defaultPort != nil p4.user = defaultUser if defaultUser != nil p4.client = defaultClient if defaultClient != nil p4.tagged p4.parse_forms p4.connect begin #----------------------------------------------------------- # first call to P4: 'p4 client -o' #----------------------------------------------------------- cl_spec = p4.fetch_client cl_name = cl_spec['Client'] cl_root = cl_spec['Root'] #----------------------------------------------------------- # second call to P4: 'p4 fstat //myclient/...' #----------------------------------------------------------- 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('\\', '/') } 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) rescue P4Exception p4.errors.each { |e| $stderr.puts( e ) } raise end p4.disconnect