Class Heroku::CommandLine
In: lib/heroku/command_line.rb
Parent: Object

This wraps the Heroku::Client class with higher-level actions suitable for use from the command line.

Methods

Classes and Modules

Class Heroku::CommandLine::CommandFailed

Attributes

credentials  [RW] 

Public Instance methods

[Source]

     # File lib/heroku/command_line.rb, line 121
121:         def add_collaborator(name, email, access)
122:                 display heroku.add_collaborator(name, email, access)
123:         end

[Source]

     # File lib/heroku/command_line.rb, line 329
329:         def add_key(keyfile=nil)
330:                 keyfile ||= find_key
331:                 key = File.read(keyfile)
332: 
333:                 display "Uploading ssh public key #{keyfile}"
334:                 heroku.add_key(key)
335:         end

[Source]

     # File lib/heroku/command_line.rb, line 202
202:         def ask_for_credentials
203:                 puts "Enter your Heroku credentials."
204: 
205:                 print "Email: "
206:                 user = gets.strip
207: 
208:                 print "Password: "
209:                 password = running_on_windows? ? ask_for_password_on_windows : ask_for_password
210: 
211:                 [ user, password ]
212:         end

[Source]

     # File lib/heroku/command_line.rb, line 231
231:         def ask_for_password
232:                 echo_off
233:                 password = gets.strip
234:                 puts
235:                 echo_on
236:                 return password
237:         end

[Source]

     # File lib/heroku/command_line.rb, line 214
214:         def ask_for_password_on_windows
215:                 require "Win32API"
216:                 char = nil
217:                 password = ''
218: 
219:                 while char = Win32API.new("crtdll", "_getch", [ ], "L").Call do
220:                         break if char == 10 || char == 13 # received carriage return or newline
221:                         if char == 127 || char == 8 # backspace and delete
222:                                 password.slice!(-1, 1)
223:                         else
224:                                 password << char.chr
225:                         end
226:                 end
227:                 puts
228:                 return password
229:         end

[Source]

     # File lib/heroku/command_line.rb, line 377
377:         def authkey
378:                 return @ssh_key if @ssh_key
379:                 %w( rsa dsa ).each do |key_type|
380:                         key = authkey_type(key_type)
381:                         return key if key
382:                 end
383:                 raise "Your ssh public key was not found.  Make sure you have a rsa or dsa key in #{home_directory}/.ssh, or specify the full path to the keyfile."
384:         end

[Source]

     # File lib/heroku/command_line.rb, line 373
373:         def authkey_read(filename)
374:                 File.read(filename) if File.exists?(filename)
375:         end

[Source]

     # File lib/heroku/command_line.rb, line 369
369:         def authkey_type(key_type)
370:                 authkey_read("#{home_directory}/.ssh/id_#{key_type}.pub")
371:         end

[Source]

    # File lib/heroku/command_line.rb, line 76
76:         def clone(args)
77:                 name = args.shift.downcase.strip rescue ""
78:                 if name.length == 0 or name.slice(0, 1) == '-'
79:                         display "Usage: heroku clone <app>"
80:                         display "(this command is deprecated in favor of using the git repo url directly)"
81:                 else
82:                         cmd = "git clone #{git_repo_for(name)}"
83:                         display cmd
84:                         system cmd
85:                 end
86:         end

[Source]

     # File lib/heroku/command_line.rb, line 117
117:         def collaborators(args)
118:                 sharing(args)
119:         end

[Source]

    # File lib/heroku/command_line.rb, line 49
49:         def create(args)
50:                 name = args.shift.downcase.strip rescue nil
51:                 name = heroku.create(name, {})
52:                 display "Created http://#{name}.#{heroku.host}/ | git@#{heroku.host}:#{name}.git"
53:         end

[Source]

     # File lib/heroku/command_line.rb, line 175
175:         def credentials_file
176:                 "#{home_directory}/.heroku/credentials"
177:         end

[Source]

     # File lib/heroku/command_line.rb, line 276
276:         def delete_credentials
277:                 FileUtils.rm_f(credentials_file)
278:         end

[Source]

    # File lib/heroku/command_line.rb, line 88
88:         def destroy(args)
89:                 name = args.shift.strip.downcase rescue ""
90:                 if name.length == 0 or name.slice(0, 1) == '-'
91:                         display "Usage: heroku destroy <app>"
92:                 else
93:                         heroku.destroy(name)
94:                         display "Destroyed #{name}"
95:                 end
96:         end

^^^ Deprecated

[Source]

     # File lib/heroku/command_line.rb, line 387
387:         def display(msg)
388:                 puts msg
389:         end

[Source]

     # File lib/heroku/command_line.rb, line 194
194:         def echo_off
195:                 system "stty -echo"
196:         end

[Source]

     # File lib/heroku/command_line.rb, line 198
198:         def echo_on
199:                 system "stty echo"
200:         end

[Source]

    # File lib/heroku/command_line.rb, line 6
 6:         def execute(command, args)
 7:                 send(command, args)
 8:         rescue RestClient::Unauthorized
 9:                 display "Authentication failure"
10:         rescue RestClient::ResourceNotFound
11:                 display "Resource not found.  (Did you mistype the app name?)"
12:         rescue RestClient::RequestFailed => e
13:                 display extract_error(e.response)
14:         rescue Heroku::CommandLine::CommandFailed => e
15:                 display e.message
16:         end

[Source]

     # File lib/heroku/command_line.rb, line 395
395:         def extract_error(response)
396:                 return "Not found" if response.code.to_i == 404
397: 
398:                 msg = parse_error_xml(response.body) rescue ''
399:                 msg = 'Internal server error' if msg.empty?
400:                 msg
401:         end

[Source]

     # File lib/heroku/command_line.rb, line 363
363:         def extract_key!
364:                 return unless key_path = extract_option(ARGV, ['-k', '--key'])
365:                 raise "Please inform the full path for your ssh public key" if File.directory?(key_path)
366:                 raise "Could not read ssh public key in #{key_path}" unless @ssh_key = authkey_read(key_path)
367:         end

[Source]

     # File lib/heroku/command_line.rb, line 280
280:         def extract_option(args, options, valid_values=nil)
281:                 values = options.is_a?(Array) ? options : [options]
282:                 return unless opt_index = args.select { |a| values.include? a }.first
283:                 opt_value = args[args.index(opt_index) + 1] rescue nil
284: 
285:                 # remove option from args
286:                 args.delete(opt_index)
287:                 args.delete(opt_value)
288: 
289:                 if valid_values
290:                         opt_value = opt_value.downcase if opt_value
291:                         raise CommandFailed, "Invalid value '#{opt_value}' for option #{values.last}" unless valid_values.include?(opt_value)
292:                 end
293: 
294:                 block_given? ? yield(opt_value) : opt_value
295:         end

[Source]

     # File lib/heroku/command_line.rb, line 347
347:         def find_key
348:                 %w(rsa dsa).each do |key_type|
349:                         keyfile = "#{home_directory}/.ssh/id_#{key_type}.pub"
350:                         return keyfile if File.exists? keyfile
351:                 end
352:                 raise CommandFailed, "No ssh public key found in #{home_directory}/.ssh/id_[rd]sa.pub.  You may want to specify the full path to the keyfile."
353:         end

[Source]

     # File lib/heroku/command_line.rb, line 140
140:         def git_repo_for(name)
141:                 "git@#{heroku.host}:#{name}.git"
142:         end

[Source]

     # File lib/heroku/command_line.rb, line 391
391:         def home_directory
392:                 running_on_windows? ? ENV['USERPROFILE'] : ENV['HOME']
393:         end

[Source]

    # File lib/heroku/command_line.rb, line 27
27:         def info(args)
28:                 name = args.shift.downcase.strip rescue ""
29:                 if name.length == 0 or name.slice(0, 1) == '-'
30:                         display "Usage: heroku info <app>"
31:                 else
32:                         attrs = heroku.info(name)
33:                         display "=== #{attrs[:name]}"
34:                         display "Web URL:        http://#{attrs[:name]}.#{heroku.host}/"
35:                         display "Domain name:    http://#{attrs[:domain_name]}/" if attrs[:domain_name]
36:                         display "Git Repo:       git@#{heroku.host}:#{attrs[:name]}.git"
37:                         display "Mode:           #{ attrs[:production] == 'true' ? 'production' : 'development' }"
38:                         display "Public:         #{ attrs[:'share-public'] == 'true' ? 'true' : 'false' }"
39: 
40:                         first = true
41:                         lead = "Collaborators:"
42:                         attrs[:collaborators].each do |collaborator|
43:                                 display "#{first ? lead : ' ' * lead.length}  #{collaborator[:email]} (#{collaborator[:access]})"
44:                                 first = false
45:                         end
46:                 end
47:         end

[Source]

     # File lib/heroku/command_line.rb, line 297
297:         def keys(*args)
298:                 args = args.first  # something weird with ruby argument passing
299: 
300:                 if args.empty?
301:                         list_keys
302:                         return
303:                 end
304: 
305:                 extract_option(args, '--add') do |keyfile|
306:                         add_key(keyfile)
307:                         return
308:                 end
309:                 extract_option(args, '--remove') do |arg|
310:                         remove_key(arg)
311:                         return
312:                 end
313: 
314:                 display "Usage: heroku keys [--add or --remove]"
315:         end

[Source]

    # File lib/heroku/command_line.rb, line 18
18:         def list(args)
19:                 list = heroku.list
20:                 if list.size > 0
21:                         display list.join("\n")
22:                 else
23:                         display "You have no apps."
24:                 end
25:         end

[Source]

     # File lib/heroku/command_line.rb, line 135
135:         def list_collaborators(name)
136:                 list = heroku.list_collaborators(name)
137:                 display list.map { |c| "#{c[:email]} (#{c[:access]})" }.join("\n")
138:         end

[Source]

     # File lib/heroku/command_line.rb, line 317
317:         def list_keys
318:                 keys = heroku.keys
319:                 if keys.empty?
320:                         display "No keys for #{user}"
321:                 else
322:                         display "=== #{keys.size} key#{keys.size > 1 ? 's' : ''} for #{user}"
323:                         keys.each do |key|
324:                                 display key
325:                         end
326:                 end
327:         end

[Source]

     # File lib/heroku/command_line.rb, line 403
403:         def parse_error_xml(body)
404:                 xml_errors = REXML::Document.new(body).elements.to_a("//errors/error")
405:                 xml_errors.map { |a| a.text }.join(" / ")
406:         end

[Source]

     # File lib/heroku/command_line.rb, line 144
144:         def rake(args)
145:                 app_name = args.shift.strip.downcase rescue ""
146:                 cmd = args.join(' ')
147:                 if app_name.length == 0 or cmd.length == 0
148:                         display "Usage: heroku rake <app> <command>"
149:                 else
150:                         puts heroku.rake(app_name, cmd)
151:                 end
152:         end

[Source]

     # File lib/heroku/command_line.rb, line 188
188:         def read_credentials
189:                 if File.exists? credentials_file
190:                         return File.read(credentials_file).split("\n")
191:                 end
192:         end

[Source]

     # File lib/heroku/command_line.rb, line 130
130:         def remove_collaborator(name, email)
131:                 heroku.remove_collaborator(name, email)
132:                 display "Collaborator removed"
133:         end

[Source]

     # File lib/heroku/command_line.rb, line 337
337:         def remove_key(arg)
338:                 if arg == 'all'
339:                         heroku.remove_all_keys
340:                         display "All keys removed."
341:                 else
342:                         heroku.remove_key(arg)
343:                         display "Key #{arg} removed."
344:                 end
345:         end

[Source]

     # File lib/heroku/command_line.rb, line 257
257:         def retry_login?
258:                 @login_attempts ||= 0
259:                 @login_attempts += 1
260:                 @login_attempts < 3
261:         end

[Source]

     # File lib/heroku/command_line.rb, line 408
408:         def running_on_windows?
409:                 RUBY_PLATFORM =~ /mswin32/
410:         end

[Source]

     # File lib/heroku/command_line.rb, line 239
239:         def save_credentials
240:                 begin
241:                         write_credentials
242:                         add_key
243:                 rescue RestClient::Unauthorized => e
244:                         delete_credentials
245:                         raise e unless retry_login?
246: 
247:                         display "\nAuthentication failed"
248:                         @credentials = ask_for_credentials
249:                         @heroku = init_heroku
250:                         retry
251:                 rescue Exception => e
252:                         delete_credentials
253:                         raise e
254:                 end
255:         end

[Source]

     # File lib/heroku/command_line.rb, line 271
271:         def set_credentials_permissions
272:                 FileUtils.chmod 0700, File.dirname(credentials_file)
273:                 FileUtils.chmod 0600, credentials_file
274:         end

[Source]

     # File lib/heroku/command_line.rb, line 98
 98:         def sharing(args)
 99:                 name = args.shift.strip.downcase rescue ""
100:                 if name.length == 0 or name.slice(0, 1) == '-'
101:                         display "Usage: heroku sharing <app>"
102:                 else
103:                         access = extract_option(args, '--access', %w( edit view )) || 'view'
104:                         extract_option(args, '--add') do |email|
105:                                 return add_collaborator(name, email, access)
106:                         end
107:                         extract_option(args, '--update') do |email|
108:                                 return update_collaborator(name, email, access)
109:                         end
110:                         extract_option(args, '--remove') do |email|
111:                                 return remove_collaborator(name, email)
112:                         end
113:                         return list_collaborators(name)
114:                 end
115:         end

[Source]

    # File lib/heroku/command_line.rb, line 55
55:         def update(args)
56:                 name = args.shift.downcase.strip rescue ""
57:                 raise CommandFailed, "Invalid app name" if name.length == 0 or name.slice(0, 1) == '-'
58: 
59:                 attributes = {}
60:                 extract_option(args, '--name') do |new_name|
61:                         attributes[:name] = new_name
62:                 end
63:                 extract_option(args, '--public', %w( true false )) do |public|
64:                         attributes[:share_public] = (public == 'true')
65:                 end
66:                 extract_option(args, '--mode', %w( production development )) do |mode|
67:                         attributes[:production] = (mode == 'production')
68:                 end
69:                 raise CommandFailed, "Nothing to update" if attributes.empty?
70:                 heroku.update(name, attributes)
71: 
72:                 app_name = attributes[:name] || name
73:                 display "http://#{app_name}.#{heroku.host}/ updated"
74:         end

[Source]

     # File lib/heroku/command_line.rb, line 125
125:         def update_collaborator(name, email, access)
126:                 heroku.update_collaborator(name, email, access)
127:                 display "Collaborator updated"
128:         end

vvv Deprecated

[Source]

     # File lib/heroku/command_line.rb, line 356
356:         def upload_authkey(*args)
357:                 extract_key!
358:                 display "Uploading ssh public key"
359:                 display "(upload_authkey is deprecated, please use \"heroku keys --add\" instead)"
360:                 heroku.add_key(authkey)
361:         end

[Source]

     # File lib/heroku/command_line.rb, line 263
263:         def write_credentials
264:                 FileUtils.mkdir_p(File.dirname(credentials_file))
265:                 File.open(credentials_file, 'w') do |f|
266:                         f.puts self.credentials
267:                 end
268:                 set_credentials_permissions
269:         end

[Validate]