class RailsPwnerer::App::Perforce

Public Instance Methods

checkout(remote_path, app_name, instance_name) click to toggle source
    # File lib/rails_pwnerer/app/vcs/perforce.rb
 87   def checkout(remote_path, app_name, instance_name)
 88     app_path = RailsPwnerer::Config[app_name, instance_name][:app_path]
 89     
 90     # paths look like p4://user@depot:port/path/to/application
 91     path_regexp = /^p4\:\/\/([^\@\/]*\@)?([^\:\/]*)(:[1-9]+)?\/(.*)$/
 92     path_match = path_regexp.match remote_path
 93     return :next unless path_match
 94     
 95     # extract path components
 96     p4_user = path_match[1] ? path_match[1][0...-1] : current_user
 97     p4_user, p4_password = *p4_user.split(':', 2)
 98     p4_server = path_match[2]
 99     p4_port = path_match[3] ? path_match[3][1..-1].to_i : 1666
100     p4_path = path_match[4]
101     p4_client = "rpwn-#{p4_user}-#{app_name}-#{instance_name}"
102     
103     # create settings file
104     p4_config_file = 
105     File.open(File.join(app_path, perforce_config_file), 'w') do |f|
106       f.write <<END_SETTINGS
107 P4PORT=#{p4_server}:#{p4_port}
108 P4USER=#{p4_user}
109 P4CLIENT=#{p4_client}
110 END_SETTINGS
111       f.write "P4PASSWD=#{p4_password}\n" if p4_password
112     end
113     
114     # create client spec
115     File.open(File.join(app_path, '.p4clientspec'), 'w') do |f|
116       f.write <<END_SETTINGS
117 Client:         #{p4_client}
118 Owner:          #{p4_user}
119 Description:    Deployment client for #{app_name} instance #{instance_name} created by rails_pwnerer
120 Root:           #{app_path}
121 Options:        noallwrite clobber unlocked nomodtime rmdir
122 SubmitOptions:  revertunchanged
123 LineEnd:        share
124 View:
125                 //depot/#{p4_path}/... //#{p4_client}/...
126 END_SETTINGS
127     end
128 
129     print "Creating Perforce client...\n"
130     Dir.chdir RailsPwnerer::Config[app_name, instance_name][:app_path] do    
131       success = Kernel.system "p4 client -i < .p4clientspec"
132       if !success
133         Kernel.system "p4 client -i < .p4clientspec" if try_prompting_for_perforce_password
134       end
135       
136       print "Doing Perforce sync...\n"
137       Kernel.system 'p4 sync -f'
138     end
139 
140     # check that we really checked out a Rails app
141     return check_rails_root(app_path) ? :ok : false
142   end
cleanup_app_caches(app_name, instance_name, app_name_is_dir = false) click to toggle source

clean up the application directory by removing caches

   # File lib/rails_pwnerer/app/vcs/perforce.rb
42 def cleanup_app_caches(app_name, instance_name, app_name_is_dir = false)
43   # TODO: this is almost-duplicated in git.rb -- pull up somewhere
44   app_path = app_name_is_dir ? app_name : RailsPwnerer::Config[app_name, instance_name][:app_path]
45   return unless File.exists?(File.join(app_path, '.p4clientspec'))
46   
47   # TODO: learn how Rails caches work and kill those too
48   ['app', 'lib', 'public/images',
49   'public/javascripts', 'public/stylesheets', 'script',
50   'test', 'tmp', 'vendor'
51   ].each { |dir| cleanup_app_dir app_name, instance_name, dir, app_name_is_dir }
52 end
cleanup_app_dir(app_name, instance_name, target_dir, app_name_is_dir = false) click to toggle source

remove any files not in client workspace

   # File lib/rails_pwnerer/app/vcs/perforce.rb
14 def cleanup_app_dir(app_name, instance_name, target_dir, app_name_is_dir = false)
15   path_base = app_name_is_dir ? app_name : RailsPwnerer::Config[app_name, instance_name][:app_path]
16   path_base = File.join path_base, target_dir
17   path_base = path_base[0...-1] if path_base[-1] == '/'
18   Dir.chdir path_base do
19     # get a listing of the files in that directory under version control
20     p4_output = `p4 have ...`
21     
22     # if p4 have failed, we don't have a reliable list, so we must give up
23     break if $CHILD_STATUS.exitstatus != 0
24     
25     client_files = Set.new
26     p4_output.each_line do |output_line|
27       next unless i = output_line.index(path_base)
28       client_files << output_line[(i + path_base.length + 1)..-1].strip
29     end
30    
31     local_files = Dir.glob('**/*')
32     local_files.each do |file|
33       next if client_files.include? file
34       next unless File.file? file
35       
36       FileUtils.rm_r file
37     end
38   end
39 end
perforce_config_file() click to toggle source
   # File lib/rails_pwnerer/app/vcs/perforce.rb
54 def perforce_config_file
55   ENV['P4CONFIG'] = '.p4config' unless ENV['P4CONFIG']
56   return ENV['P4CONFIG']
57 end
perforce_update(app_name, instance_name) click to toggle source
   # File lib/rails_pwnerer/app/vcs/perforce.rb
75 def perforce_update(app_name, instance_name)    
76   Dir.chdir RailsPwnerer::Config[app_name, instance_name][:app_path] do
77     perforce_config_file
78     
79     print "Doing Perforce sync...\n"
80     success = Kernel.system 'p4 sync'
81     if !success
82       Kernel.system 'p4 sync' if try_prompting_for_perforce_password
83     end
84   end
85 end
remove(app_name, instance_name) click to toggle source
    # File lib/rails_pwnerer/app/vcs/perforce.rb
161 def remove(app_name, instance_name)
162   app_path = RailsPwnerer::Config[app_name, instance_name][:app_path]
163   return unless File.exists?(File.join(app_path, '.p4clientspec'))
164   
165   
166   print "Deleting Perforce client...\n"
167   Dir.chdir RailsPwnerer::Config[app_name, instance_name][:app_path] do    
168     p4_config = File.read perforce_config_file
169     client_match = /^P4CLIENT=(.*)$/.match p4_config
170     p4_client = client_match[1]
171     
172     success = Kernel.system "p4 client -d #{p4_client}"
173     if !success
174       Kernel.system "p4 client -d #{p4_client}" if try_prompting_for_perforce_password
175     end
176   end
177 end
try_prompting_for_perforce_password() click to toggle source

Asks the user for their passwords and sets it, if that’s worth it. Assumes the current directory is the application’s directory.

   # File lib/rails_pwnerer/app/vcs/perforce.rb
61 def try_prompting_for_perforce_password
62   return false if ENV["P4PASSWD"]
63   
64   p4_config = File.read perforce_config_file
65   return false if p4_config.index "P4PASSWD="
66   
67   p4_password = prompt_user_for_password(
68       'Please enter your Perforce password:',
69       'Cannot securely obtain your Perforce password')
70   return false unless p4_password
71   ENV['P4PASSWD'] = p4_password
72   return true
73 end
update(app_name, instance_name) click to toggle source
    # File lib/rails_pwnerer/app/vcs/perforce.rb
144 def update(app_name, instance_name)
145   app_path = RailsPwnerer::Config[app_name, instance_name][:app_path]
146   return unless File.exists?(File.join(app_path, '.p4clientspec'))
147   
148   # TODO: maybe backup old version before issuing the p4 sync?
149   
150   perforce_update app_name, instance_name
151   cleanup_app_caches app_name, instance_name
152 end
update_prefetch(app_name, instance_name) click to toggle source
    # File lib/rails_pwnerer/app/vcs/perforce.rb
154 def update_prefetch(app_name, instance_name)
155   app_path = RailsPwnerer::Config[app_name, instance_name][:app_path]
156   return unless File.exists?(File.join(app_path, '.p4clientspec'))
157   
158   # TODO: maybe figure out a way to prefetch Perforce, if it's ever worth it
159 end