6 # This is a script I wrote while I was using the perforce revision control
7 # system. I later switched to mostly using git. This script might still be
8 # useful to someone still using perforce, though.
10 # Given a perforce tree, this script:
11 # 1. Verifies that none of the files in it have been
12 # made writable without being checked out.
13 # 2. Finds "phantom files" that exist in the filesystem but not in perforce
24 ##################### CLASSES #####################
30 parser = OptionParser.new do |myparser|
31 myparser.banner = "Usage: p4_check [opts]"
32 myparser.separator "Specific options:"
33 #myparser.on("-i PATH", "--input-dir PATH",
34 #"The input directory") do |a|
44 class NotOpened < RuntimeError
47 ##################### FUNCTIONS #####################
50 # If we allow non-arrays to be passed to this function, they will be subject
51 # to yucky shell expansion.
52 if (! cmd.kind_of?(Array)) then
53 $stderr.puts "FATAL: sorry, you must pass an array to this function."
56 # p4 has the following calling convention:
57 # 1) exit code is always 0
58 # 2) errors are on stdout, output is on stderr
59 stdin, stdout, stderr = Open3.popen3(*cmd)
60 err = stderr.readlines
61 ret = stdout.readlines
63 # Take a look at the errors generated by p4.
64 # Some are always fatal; for others, we throw an exception
65 if (! err.empty?()) then
66 if (err[0] =~ /Perforce password (P4PASSWD) invalid or unset./) then
67 $stderr.puts "FATAL: #{err[0]}"
69 elsif (err[0] =~ /Client \'.*\' unknown - use \'client\' \
70 command to create it./) then
71 $stderr.puts "FATAL: #{err[0]}"
82 lines = p4_call(["p4"])
84 if (line =~ /Perforce -- the Fast Software Configuration \
85 Management System/) then
89 throw "validate_p4: failed to validate p4 program: #{lines.join}"
92 ##################### CODE #####################
93 opts = MyOptionParse.parse(ARGV)
99 # Look at all files in the tree
100 Find.find( Dir.pwd ) do |fname|
101 #puts "fname = #{fname}"
102 if (File.file?(fname)) then
103 if (File.writable?(fname)) then
105 p4_call(["p4", "opened", fname])
107 puts "unknown writable: #{fname}"