# Task: determine which files need to be "p4 add'ed." # # num of calls to 'p4': 2 (will be higher for '-a' option) # status: tested on Darwin Mac OS X using P4Ruby API # R Cowham - converted to work fine on Windows # # Copyright 2004 Perforce Corporation, Inc. All rights reserved. require "P4" require 'getoptlong' require "find" def convert_paths(arr) if RUBY_PLATFORM.match("win32") arr.collect! {|e| e.tr('/', '\\')} else arr.collect! {|e| e.tr('\\', '/')} end end verboseOption = false defaultPort = nil defaultUser = nil defaultClient = nil addToP4 = false options = GetoptLong.new( [ '--verbose', '-v', GetoptLong::OPTIONAL_ARGUMENT], [ '--add', '-a', 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 "--add" addToP4 = 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.exception_level = 1 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. # allFilesPerforce = ret.collect { |r| r['clientFile'] } allFilesPresent = [] Find.find(cl_root) do |f| Find.prune if f == "." || f == ".." allFilesPresent << f if File.stat(f).file? end convert_paths(allFilesPresent) convert_paths(allFilesPerforce) puts "List of files present in workspace, but unknown to Perforce:" newFiles = (allFilesPresent - allFilesPerforce) puts newFiles puts "Total files: #{newFiles.size}" if addToP4 ret = p4.run_add(newFiles) end # 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