pogo 2.32.14 → 2.39.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (63) hide show
  1. data/README.md +0 -2
  2. data/lib/heroku/auth.rb +3 -1
  3. data/lib/heroku/client.rb +8 -5
  4. data/lib/heroku/client/cisaurus.rb +25 -0
  5. data/lib/heroku/client/heroku_postgresql.rb +0 -3
  6. data/lib/heroku/client/rendezvous.rb +2 -1
  7. data/lib/heroku/command.rb +1 -1
  8. data/lib/heroku/command/addons.rb +11 -2
  9. data/lib/heroku/command/apps.rb +105 -20
  10. data/lib/heroku/command/base.rb +1 -1
  11. data/lib/heroku/command/certs.rb +95 -34
  12. data/lib/heroku/command/config.rb +5 -5
  13. data/lib/heroku/command/domains.rb +4 -4
  14. data/lib/heroku/command/fork.rb +160 -0
  15. data/lib/heroku/command/git.rb +19 -20
  16. data/lib/heroku/command/help.rb +18 -2
  17. data/lib/heroku/command/keys.rb +1 -1
  18. data/lib/heroku/command/labs.rb +1 -1
  19. data/lib/heroku/command/logs.rb +3 -56
  20. data/lib/heroku/command/maintenance.rb +2 -2
  21. data/lib/heroku/command/pg.rb +7 -16
  22. data/lib/heroku/command/pgbackups.rb +37 -17
  23. data/lib/heroku/command/ps.rb +82 -35
  24. data/lib/heroku/command/regions.rb +23 -0
  25. data/lib/heroku/command/releases.rb +3 -3
  26. data/lib/heroku/command/run.rb +40 -27
  27. data/lib/heroku/command/sharing.rb +4 -4
  28. data/lib/heroku/command/ssl.rb +7 -25
  29. data/lib/heroku/command/stack.rb +1 -1
  30. data/lib/heroku/helpers/heroku_postgresql.rb +13 -17
  31. data/lib/heroku/helpers/log_displayer.rb +70 -0
  32. data/lib/heroku/plugin.rb +3 -0
  33. data/lib/heroku/updater.rb +11 -2
  34. data/lib/heroku/version.rb +1 -1
  35. data/spec/heroku/auth_spec.rb +10 -0
  36. data/spec/heroku/client/ssl_endpoint_spec.rb +12 -12
  37. data/spec/heroku/client_spec.rb +100 -100
  38. data/spec/heroku/command/addons_spec.rb +63 -59
  39. data/spec/heroku/command/apps_spec.rb +68 -65
  40. data/spec/heroku/command/base_spec.rb +21 -21
  41. data/spec/heroku/command/certs_spec.rb +31 -31
  42. data/spec/heroku/command/config_spec.rb +18 -18
  43. data/spec/heroku/command/db_spec.rb +3 -3
  44. data/spec/heroku/command/domains_spec.rb +13 -13
  45. data/spec/heroku/command/drains_spec.rb +3 -3
  46. data/spec/heroku/command/fork_spec.rb +56 -0
  47. data/spec/heroku/command/git_spec.rb +57 -29
  48. data/spec/heroku/command/labs_spec.rb +8 -8
  49. data/spec/heroku/command/logs_spec.rb +3 -3
  50. data/spec/heroku/command/maintenance_spec.rb +5 -5
  51. data/spec/heroku/command/pg_spec.rb +11 -25
  52. data/spec/heroku/command/pgbackups_spec.rb +13 -8
  53. data/spec/heroku/command/ps_spec.rb +23 -23
  54. data/spec/heroku/command/releases_spec.rb +22 -24
  55. data/spec/heroku/command/run_spec.rb +12 -15
  56. data/spec/heroku/command/sharing_spec.rb +9 -9
  57. data/spec/heroku/command/stack_spec.rb +4 -4
  58. data/spec/heroku/command_spec.rb +12 -12
  59. data/spec/heroku/helpers/heroku_postgresql_spec.rb +35 -14
  60. data/spec/spec_helper.rb +17 -2
  61. data/spec/support/openssl_mock_helper.rb +1 -1
  62. metadata +11 -6
  63. data/spec/heroku/command/ssl_spec.rb +0 -32
@@ -93,15 +93,11 @@ class Heroku::Command::Pg < Heroku::Command::Base
93
93
  end
94
94
  validate_arguments!
95
95
 
96
- attachment = hpg_resolve(db) unless db == "SHARED_DATABASE"
96
+ attachment = hpg_resolve(db)
97
97
  return unless confirm_command
98
98
 
99
- if db == "SHARED_DATABASE"
100
- action("Resetting SHARED_DATABASE") { heroku.database_reset(app) }
101
- else
102
- action("Resetting #{attachment.display_name}") do
103
- hpg_client(attachment).reset
104
- end
99
+ action("Resetting #{attachment.display_name}") do
100
+ hpg_client(attachment).reset
105
101
  end
106
102
  end
107
103
 
@@ -181,6 +177,9 @@ class Heroku::Command::Pg < Heroku::Command::Base
181
177
  uri = URI.parse( attachment.url )
182
178
  display "Connection info string:"
183
179
  display " \"dbname=#{uri.path[1..-1]} host=#{uri.host} port=#{uri.port || 5432} user=#{uri.user} password=#{uri.password} sslmode=require\""
180
+ display "Connection URL:"
181
+ display " " + attachment.url
182
+
184
183
  end
185
184
  end
186
185
 
@@ -218,15 +217,7 @@ private
218
217
  end
219
218
 
220
219
  def hpg_info(attachment, extended=false)
221
- if attachment.resource_name == "SHARED_DATABASE"
222
- data = api.get_app(app).body
223
- {:info => [{
224
- 'name' => 'Data Size',
225
- 'values' => [format_bytes(data['database_size'])]
226
- }]}
227
- else
228
- hpg_client(attachment).get_database(extended)
229
- end
220
+ hpg_client(attachment).get_database(extended)
230
221
  end
231
222
 
232
223
  def hpg_info_display(item)
@@ -20,10 +20,11 @@ module Heroku::Command
20
20
  pgbackup_client.get_transfers.each { |t|
21
21
  next unless backup_types.member?(t['to_name']) && !t['error_at'] && !t['destroyed_at']
22
22
  backups << {
23
- 'id' => backup_name(t['to_url']),
24
- 'created_at' => t['created_at'],
25
- 'size' => t['size'],
26
- 'database' => t['from_name']
23
+ 'id' => backup_name(t['to_url']),
24
+ 'created_at' => t['created_at'],
25
+ 'status' => transfer_status(t),
26
+ 'size' => t['size'],
27
+ 'database' => t['from_name']
27
28
  }
28
29
  }
29
30
 
@@ -32,8 +33,8 @@ module Heroku::Command
32
33
  else
33
34
  display_table(
34
35
  backups,
35
- %w{ id created_at size database },
36
- ["ID", "Backup Time", "Size", "Database"]
36
+ %w{ id created_at status size database },
37
+ ["ID", "Backup Time", "Status", "Size", "Database"]
37
38
  )
38
39
  end
39
40
  end
@@ -90,6 +91,7 @@ module Heroku::Command
90
91
 
91
92
  if backup["error_at"]
92
93
  message = "An error occurred and your backup did not finish."
94
+ message += "\nPlease run `heroku logs --ps pgbackups` for details."
93
95
  message += "\nThe database is not yet online. Please try again." if backup['log'] =~ /Name or service not known/
94
96
  message += "\nThe database credentials are incorrect." if backup['log'] =~ /psql: FATAL:/
95
97
  error(message)
@@ -157,7 +159,11 @@ module Heroku::Command
157
159
 
158
160
  if restore["error_at"]
159
161
  message = "An error occurred and your restore did not finish."
160
- message += "\nThe backup url is invalid. Use `pgbackups:url` to generate a new temporary URL." if restore['log'] =~ /Invalid dump format: .*: XML document text/
162
+ if restore['log'] =~ /Invalid dump format: .*: XML document text/
163
+ message += "\nThe backup url is invalid. Use `pgbackups:url` to generate a new temporary URL."
164
+ else
165
+ message += "\nPlease run `heroku logs --ps pgbackups` for details."
166
+ end
161
167
  error(message)
162
168
  end
163
169
  end
@@ -183,6 +189,17 @@ module Heroku::Command
183
189
 
184
190
  protected
185
191
 
192
+ def transfer_status(t)
193
+ if t['finished_at']
194
+ "Finished @ #{t["finished_at"]}"
195
+ elsif t['started_at']
196
+ step = t['progress'] && t['progress'].split[0]
197
+ step.nil? ? 'Unknown' : step_map[step]
198
+ else
199
+ "Unknown"
200
+ end
201
+ end
202
+
186
203
  def config_vars
187
204
  @config_vars ||= api.get_config_vars(app).body
188
205
  end
@@ -207,6 +224,7 @@ module Heroku::Command
207
224
  error <<-EOM
208
225
  Failed to query the PGBackups status API. Your backup may still be running.
209
226
  Verify the status of your backup with `heroku pgbackups -a #{app}`
227
+ You can also watch progress with `heroku logs --tail --ps pgbackups -a #{app}`
210
228
  EOM
211
229
  end
212
230
 
@@ -228,7 +246,7 @@ Verify the status of your backup with `heroku pgbackups -a #{app}`
228
246
  begin
229
247
  sleep(sleep_time)
230
248
  transfer = pgbackup_client.get_transfer(transfer["id"])
231
- rescue RestClient::ServiceUnavailable, RestClient::ServerBrokeConnection
249
+ rescue
232
250
  if sleep_time > 300
233
251
  poll_error(app)
234
252
  else
@@ -243,15 +261,8 @@ Verify the status of your backup with `heroku pgbackups -a #{app}`
243
261
  return transfer
244
262
  end
245
263
 
246
- def update_display(transfer)
247
- @ticks ||= 0
248
- @last_updated_at ||= 0
249
- @last_logs ||= []
250
- @last_progress ||= ["", 0]
251
-
252
- @ticks += 1
253
-
254
- step_map = {
264
+ def step_map
265
+ @step_map ||= {
255
266
  "dump" => "Capturing",
256
267
  "upload" => "Storing",
257
268
  "download" => "Retrieving",
@@ -259,6 +270,15 @@ Verify the status of your backup with `heroku pgbackups -a #{app}`
259
270
  "gunzip" => "Uncompressing",
260
271
  "load" => "Restoring",
261
272
  }
273
+ end
274
+
275
+ def update_display(transfer)
276
+ @ticks ||= 0
277
+ @last_updated_at ||= 0
278
+ @last_logs ||= []
279
+ @last_progress ||= ["", 0]
280
+
281
+ @ticks += 1
262
282
 
263
283
  if !transfer["log"]
264
284
  @last_progress = ['pending', nil]
@@ -1,6 +1,6 @@
1
1
  require "heroku/command/base"
2
2
 
3
- # manage processes (dynos, workers)
3
+ # manage dynos (dynos, workers)
4
4
  #
5
5
  class Heroku::Command::Ps < Heroku::Command::Base
6
6
 
@@ -80,12 +80,12 @@ class Heroku::Command::Ps < Heroku::Command::Base
80
80
 
81
81
  # ps
82
82
  #
83
- # list processes for an app
83
+ # list dynos for an app
84
84
  #
85
85
  #Example:
86
86
  #
87
87
  # $ heroku ps
88
- # === run: one-off processes
88
+ # === run: one-off dyno
89
89
  # run.1: up for 5m: `bash`
90
90
  #
91
91
  # === web: `bundle exec thin start -p $PORT`
@@ -99,21 +99,23 @@ class Heroku::Command::Ps < Heroku::Command::Base
99
99
  processes.each do |process|
100
100
  name = process["process"].split(".").first
101
101
  elapsed = time_ago(Time.now - process['elapsed'])
102
+ size = process.fetch("size", 1)
102
103
 
103
104
  if name == "run"
104
105
  key = "run: one-off processes"
105
- item = "%s: %s %s: `%s`" % [ process["process"], process["state"], elapsed, process["command"] ]
106
+ item = "%s (%sX): %s %s: `%s`" % [ process["process"], size, process["state"], elapsed, process["command"] ]
106
107
  else
107
- key = "#{name}: `#{process["command"]}`"
108
+ key = "#{name} (#{size}X): `#{process["command"]}`"
108
109
  item = "%s: %s %s" % [ process["process"], process["state"], elapsed ]
109
110
  end
110
111
 
111
112
  processes_by_command[key] << item
112
113
  end
113
114
 
115
+ extract_run_id = /\.(\d+).*:/
114
116
  processes_by_command.keys.each do |key|
115
117
  processes_by_command[key] = processes_by_command[key].sort do |x,y|
116
- x.match(/\.(\d+):/).captures.first.to_i <=> y.match(/\.(\d+):/).captures.first.to_i
118
+ x.match(extract_run_id).captures.first.to_i <=> y.match(extract_run_id).captures.first.to_i
117
119
  end
118
120
  end
119
121
 
@@ -123,36 +125,36 @@ class Heroku::Command::Ps < Heroku::Command::Base
123
125
  end
124
126
  end
125
127
 
126
- # ps:restart [PROCESS]
128
+ # ps:restart [DYNO]
127
129
  #
128
- # restart an app process
130
+ # restart an app dyno
129
131
  #
130
- # if PROCESS is not specified, restarts all processes on the app
132
+ # if DYNO is not specified, restarts all dynos on the app
131
133
  #
132
134
  #Examples:
133
135
  #
134
136
  # $ heroku ps:restart web.1
135
- # Restarting web.1 process... done
137
+ # Restarting web.1 dyno... done
136
138
  #
137
139
  # $ heroku ps:restart web
138
- # Restarting web processes... done
140
+ # Restarting web dyno... done
139
141
  #
140
142
  # $ heroku ps:restart
141
- # Restarting processes... done
143
+ # Restarting dynos... done
142
144
  #
143
145
  def restart
144
- process = shift_argument
146
+ dyno = shift_argument
145
147
  validate_arguments!
146
148
 
147
- message, options = case process
149
+ message, options = case dyno
148
150
  when NilClass
149
- ["Restarting processes", {}]
151
+ ["Restarting dynos", {}]
150
152
  when /.+\..+/
151
153
  ps = args.first
152
- ["Restarting #{ps} process", { :ps => ps }]
154
+ ["Restarting #{ps} dyno", { :ps => ps }]
153
155
  else
154
156
  type = args.first
155
- ["Restarting #{type} processes", { :type => type }]
157
+ ["Restarting #{type} dynos", { :type => type }]
156
158
  end
157
159
 
158
160
  action(message) do
@@ -162,15 +164,15 @@ class Heroku::Command::Ps < Heroku::Command::Base
162
164
 
163
165
  alias_command "restart", "ps:restart"
164
166
 
165
- # ps:scale PROCESS1=AMOUNT1 [PROCESS2=AMOUNT2 ...]
167
+ # ps:scale DYNO1=AMOUNT1 [DYNO2=AMOUNT2 ...]
166
168
  #
167
- # scale processes by the given amount
169
+ # scale dynos by the given amount
168
170
  #
169
171
  #Examples:
170
172
  #
171
173
  # $ heroku ps:scale web=3 worker+1
172
- # Scaling web processes... done, now running 3
173
- # Scaling worker processes... done, now running 1
174
+ # Scaling web dynos... done, now running 3
175
+ # Scaling worker dynos... done, now running 1
174
176
  #
175
177
  def scale
176
178
  changes = {}
@@ -181,14 +183,14 @@ class Heroku::Command::Ps < Heroku::Command::Base
181
183
  end
182
184
 
183
185
  if changes.empty?
184
- error("Usage: heroku ps:scale PROCESS1=AMOUNT1 [PROCESS2=AMOUNT2 ...]\nMust specify PROCESS and AMOUNT to scale.")
186
+ error("Usage: heroku ps:scale DYNO1=AMOUNT1 [DYNO2=AMOUNT2 ...]\nMust specify DYNO and AMOUNT to scale.")
185
187
  end
186
188
 
187
- changes.keys.sort.each do |process|
188
- amount = changes[process]
189
- action("Scaling #{process} processes") do
189
+ changes.keys.sort.each do |dyno|
190
+ amount = changes[dyno]
191
+ action("Scaling #{dyno} dynos") do
190
192
  amount.gsub!("=", "")
191
- new_qty = api.post_ps_scale(app, process, amount).body
193
+ new_qty = api.post_ps_scale(app, dyno, amount).body
192
194
  status("now running #{new_qty}")
193
195
  end
194
196
  end
@@ -196,31 +198,31 @@ class Heroku::Command::Ps < Heroku::Command::Base
196
198
 
197
199
  alias_command "scale", "ps:scale"
198
200
 
199
- # ps:stop PROCESS
201
+ # ps:stop DYNOS
200
202
  #
201
- # stop an app process
203
+ # stop an app dyno
202
204
  #
203
205
  # Examples:
204
206
  #
205
207
  # $ heroku stop run.3
206
- # Stopping run.3 process... done
208
+ # Stopping run.3 dyno... done
207
209
  #
208
210
  # $ heroku stop run
209
- # Stopping run processes... done
211
+ # Stopping run dynos... done
210
212
  #
211
213
  def stop
212
- process = shift_argument
214
+ dyno = shift_argument
213
215
  validate_arguments!
214
216
 
215
- message, options = case process
217
+ message, options = case dyno
216
218
  when NilClass
217
- error("Usage: heroku ps:stop PROCESS\nMust specify PROCESS to stop.")
219
+ error("Usage: heroku ps:stop DYNO\nMust specify DYNO to stop.")
218
220
  when /.+\..+/
219
221
  ps = args.first
220
- ["Stopping #{ps} process", { :ps => ps }]
222
+ ["Stopping #{ps} dyno", { :ps => ps }]
221
223
  else
222
224
  type = args.first
223
- ["Stopping #{type} processes", { :type => type }]
225
+ ["Stopping #{type} dynos", { :type => type }]
224
226
  end
225
227
 
226
228
  action(message) do
@@ -229,4 +231,49 @@ class Heroku::Command::Ps < Heroku::Command::Base
229
231
  end
230
232
 
231
233
  alias_command "stop", "ps:stop"
234
+
235
+ # ps:resize DYNO1=1X|2X [DYNO2=1X|2X ...]
236
+ #
237
+ # resize dynos to the given size
238
+ #
239
+ # Example:
240
+ #
241
+ # $ heroku ps:resize web=2X worker=1X
242
+ # Resizing and restarting the specified dynos... done
243
+ # web dynos now 2X ($0.10/dyno-hour)
244
+ # worker dynos now 1X ($0.05/dyno-hour)
245
+ #
246
+ def resize
247
+ app
248
+ changes = {}
249
+ args.each do |arg|
250
+ if arg =~ /^([a-zA-Z0-9_]+)=(\d+)([xX]?)$/
251
+ changes[$1] = { "size" => $2.to_i }
252
+ end
253
+ end
254
+
255
+ if changes.empty?
256
+ message = [
257
+ "Usage: heroku ps:resize DYNO1=1X|2X [DYNO2=1X|2X ...]",
258
+ "Must specify DYNO and SIZE to resize."
259
+ ]
260
+ error(message.join("\n"))
261
+ end
262
+
263
+ action("Resizing and restarting the specified dynos") do
264
+ api.request(
265
+ :expects => 200,
266
+ :method => :put,
267
+ :path => "/apps/#{app}/formation",
268
+ :body => json_encode(changes)
269
+ )
270
+ end
271
+ changes.each do |type, options|
272
+ size = options["size"]
273
+ price = sprintf("%.2f", 0.05 * size)
274
+ display "#{type} dynos now #{size}X ($#{price}/dyno-hour)"
275
+ end
276
+ end
277
+
278
+ alias_command "resize", "ps:resize"
232
279
  end
@@ -0,0 +1,23 @@
1
+ require "heroku/command/base"
2
+
3
+ # list available regions
4
+ #
5
+ class Heroku::Command::Regions < Heroku::Command::Base
6
+
7
+ # regions
8
+ #
9
+ # List available regions for deployment
10
+ #
11
+ #Example:
12
+ #
13
+ # $ heroku regions
14
+ # === Regions
15
+ # us
16
+ # eu
17
+ def index
18
+ regions = json_decode(heroku.get("/regions"))
19
+ styled_header("Regions")
20
+ styled_array(regions.map { |region| [region["slug"], region["name"]] })
21
+ end
22
+ end
23
+
@@ -11,7 +11,7 @@ class Heroku::Command::Releases < Heroku::Command::Base
11
11
  #Example:
12
12
  #
13
13
  # $ heroku releases
14
- # === myapp Releases
14
+ # === example Releases
15
15
  # v1 Config add FOO_BAR by email@example.com 0s ago
16
16
  # v2 Config add BAR_BAZ by email@example.com 0s ago
17
17
  # v3 Config add BAZ_QUX by email@example.com 0s ago
@@ -105,10 +105,10 @@ class Heroku::Command::Releases < Heroku::Command::Base
105
105
  #Example:
106
106
  #
107
107
  # $ heroku releases:rollback
108
- # Rolling back myapp... done, v122
108
+ # Rolling back example... done, v122
109
109
  #
110
110
  # $ heroku releases:rollback v42
111
- # Rolling back myapp to v42... done
111
+ # Rolling back example to v42... done
112
112
  #
113
113
  def rollback
114
114
  release = shift_argument
@@ -1,5 +1,6 @@
1
1
  require "readline"
2
2
  require "heroku/command/base"
3
+ require "heroku/helpers/log_displayer"
3
4
 
4
5
  # run one-off commands (console, rake)
5
6
  #
@@ -7,7 +8,9 @@ class Heroku::Command::Run < Heroku::Command::Base
7
8
 
8
9
  # run COMMAND
9
10
  #
10
- # run an attached process
11
+ # run an attached dyno
12
+ #
13
+ # -s, --size SIZE # specify dyno size
11
14
  #
12
15
  #Example:
13
16
  #
@@ -17,13 +20,16 @@ class Heroku::Command::Run < Heroku::Command::Base
17
20
  #
18
21
  def index
19
22
  command = args.join(" ")
20
- error("Usage: heroku run COMMAND")if command.empty?
23
+ error("Usage: heroku run COMMAND") if command.empty?
21
24
  run_attached(command)
22
25
  end
23
26
 
24
27
  # run:detached COMMAND
25
28
  #
26
- # run a detached process, where output is sent to your logs
29
+ # run a detached dyno, where output is sent to your logs
30
+ #
31
+ # -s, --size SIZE # specify dyno size
32
+ # -t, --tail # stream logs for the dyno
27
33
  #
28
34
  #Example:
29
35
  #
@@ -33,14 +39,25 @@ class Heroku::Command::Run < Heroku::Command::Base
33
39
  #
34
40
  def detached
35
41
  command = args.join(" ")
36
- error("Usage: heroku run COMMAND")if command.empty?
42
+ error("Usage: heroku run COMMAND") if command.empty?
37
43
  opts = { :attach => false, :command => command }
44
+ opts[:size] = get_size if options[:size]
45
+
46
+ app_name = app
38
47
  process_data = action("Running `#{command}` detached", :success => "up") do
39
- process_data = api.post_ps(app, command, { :attach => false }).body
48
+ process_data = api.post_ps(app_name, command, opts).body
40
49
  status(process_data['process'])
41
50
  process_data
42
51
  end
43
- display("Use `heroku logs -p #{process_data['process']}` to view the output.")
52
+ if options[:tail]
53
+ opts = []
54
+ opts << "tail=1"
55
+ opts << "ps=#{process_data['process']}"
56
+ log_displayer = ::Heroku::Helpers::LogDisplayer.new(heroku, app, opts)
57
+ log_displayer.display_logs
58
+ else
59
+ display("Use `heroku logs -p #{process_data['process']}` to view the output.")
60
+ end
44
61
  end
45
62
 
46
63
  # run:rake COMMAND
@@ -75,37 +92,27 @@ class Heroku::Command::Run < Heroku::Command::Base
75
92
  #Examples:
76
93
  #
77
94
  # $ heroku console
78
- # Ruby console for myapp.heroku.com
95
+ # Ruby console for example.heroku.com
79
96
  # >>
80
97
  #
81
98
  def console
82
- cmd = args.join(' ').strip
83
- if cmd.empty?
84
- console_session(app)
85
- else
86
- display(heroku.console(app, cmd))
87
- end
88
- rescue RestClient::RequestFailed => e
89
- if e.http_body =~ /For Cedar apps, use: `heroku run console`/
90
- deprecate("`heroku #{current_command}` has been deprecated for Cedar apps. Please use: `heroku run console` instead.")
91
- command = "console #{args.join(' ')}"
92
- run_attached(command)
93
- else
94
- raise(e)
95
- end
96
- rescue RestClient::RequestTimeout
97
- error("Timed out. Long running requests are not supported on the console.\nPlease consider creating a rake task instead.")
98
- rescue Heroku::Client::AppCrashed => e
99
- error(e.message)
99
+ puts "`heroku #{current_command}` has been removed. Please use: `heroku run` instead."
100
+ puts "For more information, please see:"
101
+ puts " * https://devcenter.heroku.com/articles/one-off-dynos"
102
+ puts " * https://devcenter.heroku.com/articles/rails3#console"
103
+ puts " * https://devcenter.heroku.com/articles/console-bamboo"
100
104
  end
101
-
102
105
  alias_command "console", "run:console"
103
106
 
104
107
  protected
105
108
 
106
109
  def run_attached(command)
110
+ app_name = app
111
+ opts = { :attach => true, :ps_env => get_terminal_environment }
112
+ opts[:size] = get_size if options[:size]
113
+
107
114
  process_data = action("Running `#{command}` attached to terminal", :success => "up") do
108
- process_data = api.post_ps(app, command, { :attach => true, :ps_env => get_terminal_environment }).body
115
+ process_data = api.post_ps(app_name, command, opts).body
109
116
  status(process_data["process"])
110
117
  process_data
111
118
  end
@@ -178,4 +185,10 @@ protected
178
185
  Readline::HISTORY.push(cmd)
179
186
  File.open(console_history_file(app), "a") { |f| f.puts cmd + "\n" }
180
187
  end
188
+
189
+ def get_size
190
+ size = options[:size].to_i
191
+ error("Must specify SIZE in format '1X' or '2X'.") if size <= 0
192
+ size
193
+ end
181
194
  end