pogo 2.32.14 → 2.39.2
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +0 -2
- data/lib/heroku/auth.rb +3 -1
- data/lib/heroku/client.rb +8 -5
- data/lib/heroku/client/cisaurus.rb +25 -0
- data/lib/heroku/client/heroku_postgresql.rb +0 -3
- data/lib/heroku/client/rendezvous.rb +2 -1
- data/lib/heroku/command.rb +1 -1
- data/lib/heroku/command/addons.rb +11 -2
- data/lib/heroku/command/apps.rb +105 -20
- data/lib/heroku/command/base.rb +1 -1
- data/lib/heroku/command/certs.rb +95 -34
- data/lib/heroku/command/config.rb +5 -5
- data/lib/heroku/command/domains.rb +4 -4
- data/lib/heroku/command/fork.rb +160 -0
- data/lib/heroku/command/git.rb +19 -20
- data/lib/heroku/command/help.rb +18 -2
- data/lib/heroku/command/keys.rb +1 -1
- data/lib/heroku/command/labs.rb +1 -1
- data/lib/heroku/command/logs.rb +3 -56
- data/lib/heroku/command/maintenance.rb +2 -2
- data/lib/heroku/command/pg.rb +7 -16
- data/lib/heroku/command/pgbackups.rb +37 -17
- data/lib/heroku/command/ps.rb +82 -35
- data/lib/heroku/command/regions.rb +23 -0
- data/lib/heroku/command/releases.rb +3 -3
- data/lib/heroku/command/run.rb +40 -27
- data/lib/heroku/command/sharing.rb +4 -4
- data/lib/heroku/command/ssl.rb +7 -25
- data/lib/heroku/command/stack.rb +1 -1
- data/lib/heroku/helpers/heroku_postgresql.rb +13 -17
- data/lib/heroku/helpers/log_displayer.rb +70 -0
- data/lib/heroku/plugin.rb +3 -0
- data/lib/heroku/updater.rb +11 -2
- data/lib/heroku/version.rb +1 -1
- data/spec/heroku/auth_spec.rb +10 -0
- data/spec/heroku/client/ssl_endpoint_spec.rb +12 -12
- data/spec/heroku/client_spec.rb +100 -100
- data/spec/heroku/command/addons_spec.rb +63 -59
- data/spec/heroku/command/apps_spec.rb +68 -65
- data/spec/heroku/command/base_spec.rb +21 -21
- data/spec/heroku/command/certs_spec.rb +31 -31
- data/spec/heroku/command/config_spec.rb +18 -18
- data/spec/heroku/command/db_spec.rb +3 -3
- data/spec/heroku/command/domains_spec.rb +13 -13
- data/spec/heroku/command/drains_spec.rb +3 -3
- data/spec/heroku/command/fork_spec.rb +56 -0
- data/spec/heroku/command/git_spec.rb +57 -29
- data/spec/heroku/command/labs_spec.rb +8 -8
- data/spec/heroku/command/logs_spec.rb +3 -3
- data/spec/heroku/command/maintenance_spec.rb +5 -5
- data/spec/heroku/command/pg_spec.rb +11 -25
- data/spec/heroku/command/pgbackups_spec.rb +13 -8
- data/spec/heroku/command/ps_spec.rb +23 -23
- data/spec/heroku/command/releases_spec.rb +22 -24
- data/spec/heroku/command/run_spec.rb +12 -15
- data/spec/heroku/command/sharing_spec.rb +9 -9
- data/spec/heroku/command/stack_spec.rb +4 -4
- data/spec/heroku/command_spec.rb +12 -12
- data/spec/heroku/helpers/heroku_postgresql_spec.rb +35 -14
- data/spec/spec_helper.rb +17 -2
- data/spec/support/openssl_mock_helper.rb +1 -1
- metadata +11 -6
- data/spec/heroku/command/ssl_spec.rb +0 -32
@@ -46,11 +46,11 @@ class Heroku::Command::Config < Heroku::Command::Base
|
|
46
46
|
#Example:
|
47
47
|
#
|
48
48
|
# $ heroku config:set A=one
|
49
|
-
# Setting config vars and restarting
|
49
|
+
# Setting config vars and restarting example... done, v123
|
50
50
|
# A: one
|
51
51
|
#
|
52
52
|
# $ heroku config:set A=one B=two
|
53
|
-
# Setting config vars and restarting
|
53
|
+
# Setting config vars and restarting example... done, v123
|
54
54
|
# A: one
|
55
55
|
# B: two
|
56
56
|
#
|
@@ -107,11 +107,11 @@ class Heroku::Command::Config < Heroku::Command::Base
|
|
107
107
|
# unset one or more config vars
|
108
108
|
#
|
109
109
|
# $ heroku config:unset A
|
110
|
-
# Unsetting A and restarting
|
110
|
+
# Unsetting A and restarting example... done, v123
|
111
111
|
#
|
112
112
|
# $ heroku config:unset A B
|
113
|
-
# Unsetting A and restarting
|
114
|
-
# Unsetting B and restarting
|
113
|
+
# Unsetting A and restarting example... done, v123
|
114
|
+
# Unsetting B and restarting example... done, v124
|
115
115
|
#
|
116
116
|
def unset
|
117
117
|
if args.empty?
|
@@ -13,7 +13,7 @@ module Heroku::Command
|
|
13
13
|
#Examples:
|
14
14
|
#
|
15
15
|
# $ heroku domains
|
16
|
-
# === Domain names for
|
16
|
+
# === Domain names for example
|
17
17
|
# example.com
|
18
18
|
#
|
19
19
|
def index
|
@@ -34,7 +34,7 @@ module Heroku::Command
|
|
34
34
|
#Examples:
|
35
35
|
#
|
36
36
|
# $ heroku domains:add example.com
|
37
|
-
# Adding example.com to
|
37
|
+
# Adding example.com to example... done
|
38
38
|
#
|
39
39
|
def add
|
40
40
|
unless domain = shift_argument
|
@@ -53,7 +53,7 @@ module Heroku::Command
|
|
53
53
|
#Examples:
|
54
54
|
#
|
55
55
|
# $ heroku domains:remove example.com
|
56
|
-
# Removing example.com from
|
56
|
+
# Removing example.com from example... done
|
57
57
|
#
|
58
58
|
def remove
|
59
59
|
unless domain = shift_argument
|
@@ -72,7 +72,7 @@ module Heroku::Command
|
|
72
72
|
#Examples:
|
73
73
|
#
|
74
74
|
# $ heroku domains:clear
|
75
|
-
# Removing all domain names for
|
75
|
+
# Removing all domain names for example... done
|
76
76
|
#
|
77
77
|
def clear
|
78
78
|
validate_arguments!
|
@@ -0,0 +1,160 @@
|
|
1
|
+
require "heroku/client/cisaurus"
|
2
|
+
require "heroku/command/base"
|
3
|
+
|
4
|
+
module Heroku::Command
|
5
|
+
|
6
|
+
# clone an existing app
|
7
|
+
#
|
8
|
+
class Fork < Base
|
9
|
+
|
10
|
+
# fork [NEWNAME]
|
11
|
+
#
|
12
|
+
# Fork an existing app -- copy config vars and Heroku Postgres data, and re-provision add-ons to a new app.
|
13
|
+
# New app name should not be an existing app. The new app will be created as part of the forking process.
|
14
|
+
#
|
15
|
+
# -s, --stack STACK # specify a stack for the new app
|
16
|
+
# --region REGION # specify a region
|
17
|
+
#
|
18
|
+
def index
|
19
|
+
|
20
|
+
from = app
|
21
|
+
to = shift_argument || "#{from}-#{(rand*1000).to_i}"
|
22
|
+
|
23
|
+
from_info = api.get_app(from).body
|
24
|
+
|
25
|
+
to_info = action("Creating fork #{to}") do
|
26
|
+
api.post_app({
|
27
|
+
:name => to,
|
28
|
+
:region => options[:region] || from_info["region"],
|
29
|
+
:stack => options[:stack] || from_info["stack"],
|
30
|
+
:tier => from_info["tier"] == "legacy" ? "production" : from_info["tier"]
|
31
|
+
}).body
|
32
|
+
end
|
33
|
+
|
34
|
+
action("Copying slug") do
|
35
|
+
job_location = cisaurus_client.copy_slug(from, to)
|
36
|
+
loop do
|
37
|
+
break if cisaurus_client.job_done?(job_location)
|
38
|
+
sleep 1
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
from_config = api.get_config_vars(from).body
|
43
|
+
from_addons = api.get_addons(from).body
|
44
|
+
|
45
|
+
from_addons.each do |addon|
|
46
|
+
print "Adding #{addon["name"]}... "
|
47
|
+
begin
|
48
|
+
to_addon = api.post_addon(to, addon["name"]).body
|
49
|
+
puts "done"
|
50
|
+
rescue Heroku::API::Errors::RequestFailed => ex
|
51
|
+
puts "skipped (%s)" % json_decode(ex.response.body)["error"]
|
52
|
+
rescue Heroku::API::Errors::NotFound
|
53
|
+
puts "skipped (not found)"
|
54
|
+
end
|
55
|
+
if addon["name"] =~ /^heroku-postgresql:/
|
56
|
+
from_var_name = "#{addon["attachment_name"]}_URL"
|
57
|
+
from_attachment = to_addon["message"].match(/Attached as (\w+)_URL\n/)[1]
|
58
|
+
if from_config[from_var_name] == from_config["DATABASE_URL"]
|
59
|
+
from_config["DATABASE_URL"] = api.get_config_vars(to).body["#{from_attachment}_URL"]
|
60
|
+
end
|
61
|
+
from_config.delete(from_var_name)
|
62
|
+
|
63
|
+
plan = addon["name"].split(":").last
|
64
|
+
unless %w(dev basic).include? plan
|
65
|
+
wait_for_db to, to_addon
|
66
|
+
end
|
67
|
+
|
68
|
+
check_for_pgbackups! from
|
69
|
+
check_for_pgbackups! to
|
70
|
+
migrate_db addon, from, to_addon, to
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
to_config = api.get_config_vars(to).body
|
75
|
+
|
76
|
+
action("Copying config vars") do
|
77
|
+
diff = from_config.inject({}) do |ax, (key, val)|
|
78
|
+
ax[key] = val unless to_config[key]
|
79
|
+
ax
|
80
|
+
end
|
81
|
+
api.put_config_vars to, diff
|
82
|
+
end
|
83
|
+
|
84
|
+
puts "Fork complete, view it at #{to_info['web_url']}"
|
85
|
+
end
|
86
|
+
|
87
|
+
private
|
88
|
+
|
89
|
+
def cisaurus_client
|
90
|
+
cisaurus_url = ENV["CISAURUS_HOST"] || "https://cisaurus.herokuapp.com"
|
91
|
+
@cisaurus_client ||= Heroku::Client::Cisaurus.new(cisaurus_url)
|
92
|
+
end
|
93
|
+
|
94
|
+
def check_for_pgbackups!(app)
|
95
|
+
unless api.get_addons(app).body.detect { |addon| addon["name"] =~ /^pgbackups:/ }
|
96
|
+
action("Adding pgbackups:plus to #{app}") do
|
97
|
+
api.post_addon app, "pgbackups:plus"
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
def migrate_db(from_addon, from, to_addon, to)
|
103
|
+
transfer = nil
|
104
|
+
|
105
|
+
action("Creating database backup from #{from} (this can take some time)") do
|
106
|
+
from_config = api.get_config_vars(from).body
|
107
|
+
from_attachment = from_addon["attachment_name"]
|
108
|
+
pgb = Heroku::Client::Pgbackups.new(from_config["PGBACKUPS_URL"])
|
109
|
+
transfer = pgb.create_transfer(from_config["#{from_attachment}_URL"], from_attachment, nil, "BACKUP", :expire => "true")
|
110
|
+
error transfer["errors"].values.flatten.join("\n") if transfer["errors"]
|
111
|
+
loop do
|
112
|
+
transfer = pgb.get_transfer(transfer["id"])
|
113
|
+
error transfer["errors"].values.flatten.join("\n") if transfer["errors"]
|
114
|
+
break if transfer["finished_at"]
|
115
|
+
sleep 1
|
116
|
+
end
|
117
|
+
print " "
|
118
|
+
end
|
119
|
+
|
120
|
+
action("Restoring database backup to #{to} (this can take some time)") do
|
121
|
+
to_config = api.get_config_vars(to).body
|
122
|
+
to_attachment = to_addon["message"].match(/Attached as (\w+)_URL\n/)[1]
|
123
|
+
pgb = Heroku::Client::Pgbackups.new(to_config["PGBACKUPS_URL"])
|
124
|
+
transfer = pgb.create_transfer(transfer["public_url"], "EXTERNAL_BACKUP", to_config["#{to_attachment}_URL"], to_attachment)
|
125
|
+
error transfer["errors"].values.flatten.join("\n") if transfer["errors"]
|
126
|
+
loop do
|
127
|
+
transfer = pgb.get_transfer(transfer["id"])
|
128
|
+
error transfer["errors"].values.flatten.join("\n") if transfer["errors"]
|
129
|
+
break if transfer["finished_at"]
|
130
|
+
sleep 1
|
131
|
+
end
|
132
|
+
print " "
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
def pg_api(starter=false)
|
137
|
+
host = starter ? "postgres-starter-api.heroku.com" : "postgres-api.heroku.com"
|
138
|
+
RestClient::Resource.new "https://#{host}/client/v11/databases", Heroku::Auth.user, Heroku::Auth.password
|
139
|
+
end
|
140
|
+
|
141
|
+
def wait_for_db(app, attachment)
|
142
|
+
attachments = api.get_attachments(app).body.inject({}) { |ax,att| ax.update(att["name"] => att["resource"]["name"]) }
|
143
|
+
attachment_name = attachment["message"].match(/Attached as (\w+)_URL\n/)[1]
|
144
|
+
action("Waiting for database to be ready (this can take some time)") do
|
145
|
+
loop do
|
146
|
+
begin
|
147
|
+
waiting = json_decode(pg_api["#{attachments[attachment_name]}/wait_status"].get.to_s)["waiting?"]
|
148
|
+
break unless waiting
|
149
|
+
sleep 5
|
150
|
+
rescue RestClient::ResourceNotFound
|
151
|
+
rescue Interrupt
|
152
|
+
exit 0
|
153
|
+
end
|
154
|
+
end
|
155
|
+
print " "
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
end
|
160
|
+
end
|
data/lib/heroku/command/git.rb
CHANGED
@@ -4,36 +4,35 @@ require "heroku/command/base"
|
|
4
4
|
#
|
5
5
|
class Heroku::Command::Git < Heroku::Command::Base
|
6
6
|
|
7
|
-
# git:clone [
|
7
|
+
# git:clone APP [DIRECTORY]
|
8
8
|
#
|
9
|
-
# clones
|
9
|
+
# clones a heroku app to your local machine at DIRECTORY (defaults to app name)
|
10
10
|
#
|
11
|
-
#
|
12
|
-
#
|
13
|
-
# -n, --no-remote # don't create a git remote
|
14
|
-
# -r, --remote REMOTE # the git remote to create, default "heroku"
|
11
|
+
# -r, --remote REMOTE # the git remote to create, default "heroku"
|
15
12
|
#
|
16
13
|
#Examples:
|
17
14
|
#
|
18
|
-
# $ heroku git:clone
|
19
|
-
# Cloning
|
20
|
-
#
|
15
|
+
# $ heroku git:clone example
|
16
|
+
# Cloning from app 'example'...
|
17
|
+
# Cloning into 'example'...
|
18
|
+
# remote: Counting objects: 42, done.
|
19
|
+
# ...
|
21
20
|
#
|
22
21
|
def clone
|
23
|
-
|
24
|
-
remote = options[:remote] || 'heroku'
|
22
|
+
remote = options[:remote] || "heroku"
|
25
23
|
|
26
|
-
|
24
|
+
name = options[:app] || shift_argument || error("Usage: heroku git:clone APP [DIRECTORY]")
|
25
|
+
directory = shift_argument
|
26
|
+
validate_arguments!
|
27
27
|
|
28
|
-
|
28
|
+
git_url = api.get_app(name).body["git_url"]
|
29
29
|
|
30
|
-
|
31
|
-
|
32
|
-
create_git_remote(remote, app_data['git_url'])
|
33
|
-
end
|
34
|
-
end
|
30
|
+
puts "Cloning from app '#{name}'..."
|
31
|
+
system "git clone -o #{remote} #{git_url} #{directory}".strip
|
35
32
|
end
|
36
33
|
|
34
|
+
alias_command "clone", "git:clone"
|
35
|
+
|
37
36
|
# git:remote [OPTIONS]
|
38
37
|
#
|
39
38
|
# adds a git remote to an app repo
|
@@ -44,10 +43,10 @@ class Heroku::Command::Git < Heroku::Command::Base
|
|
44
43
|
#
|
45
44
|
#Examples:
|
46
45
|
#
|
47
|
-
# $ heroku git:remote -a
|
46
|
+
# $ heroku git:remote -a example
|
48
47
|
# Git remote heroku added
|
49
48
|
#
|
50
|
-
# $ heroku git:remote -a
|
49
|
+
# $ heroku git:remote -a example
|
51
50
|
# ! Git remote heroku already exists
|
52
51
|
#
|
53
52
|
def remote
|
data/lib/heroku/command/help.rb
CHANGED
@@ -87,6 +87,18 @@ private
|
|
87
87
|
nil
|
88
88
|
end
|
89
89
|
|
90
|
+
def skip_namespace?(ns)
|
91
|
+
return true if ns[:description] =~ /DEPRECATED:/
|
92
|
+
return true if ns[:description] =~ /HIDDEN:/
|
93
|
+
false
|
94
|
+
end
|
95
|
+
|
96
|
+
def skip_command?(command)
|
97
|
+
return true if command[:help] =~ /DEPRECATED:/
|
98
|
+
return true if command[:help] =~ /^ HIDDEN:/
|
99
|
+
false
|
100
|
+
end
|
101
|
+
|
90
102
|
def primary_namespaces
|
91
103
|
PRIMARY_NAMESPACES.map { |name| namespaces[name] }.compact
|
92
104
|
end
|
@@ -98,6 +110,7 @@ private
|
|
98
110
|
def summary_for_namespaces(namespaces)
|
99
111
|
size = longest(namespaces.map { |n| n[:name] })
|
100
112
|
namespaces.sort_by {|namespace| namespace[:name]}.each do |namespace|
|
113
|
+
next if skip_namespace?(namespace)
|
101
114
|
name = namespace[:name]
|
102
115
|
namespace[:description] ||= legacy_help_for_namespace(name)
|
103
116
|
puts " %-#{size}s # %s" % [ name, namespace[:description] ]
|
@@ -123,7 +136,7 @@ private
|
|
123
136
|
unless namespace_commands.empty?
|
124
137
|
size = longest(namespace_commands.map { |c| c[:banner] })
|
125
138
|
namespace_commands.sort_by { |c| c[:banner].to_s }.each do |command|
|
126
|
-
next if command
|
139
|
+
next if skip_command?(command)
|
127
140
|
command[:summary] ||= legacy_help_for_command(command[:command])
|
128
141
|
puts " %-#{size}s # %s" % [ command[:banner], command[:summary] ]
|
129
142
|
end
|
@@ -139,7 +152,10 @@ private
|
|
139
152
|
puts "Usage: heroku #{command[:banner]}"
|
140
153
|
|
141
154
|
if command[:help].strip.length > 0
|
142
|
-
|
155
|
+
help = command[:help].split("\n").reject do |line|
|
156
|
+
line =~ /HIDDEN/
|
157
|
+
end
|
158
|
+
puts help[1..-1].join("\n")
|
143
159
|
else
|
144
160
|
puts
|
145
161
|
puts " " + legacy_help_for_command(name).to_s
|
data/lib/heroku/command/keys.rb
CHANGED
data/lib/heroku/command/labs.rb
CHANGED
@@ -15,7 +15,7 @@ class Heroku::Command::Labs < Heroku::Command::Base
|
|
15
15
|
#
|
16
16
|
# === App Features (glacial-retreat-5913)
|
17
17
|
# [ ] preboot Provide seamless web dyno deploys
|
18
|
-
# [ ] user-env-compile Add user config vars to the environment during slug compilation # $ heroku labs -a
|
18
|
+
# [ ] user-env-compile Add user config vars to the environment during slug compilation # $ heroku labs -a example
|
19
19
|
#
|
20
20
|
def index
|
21
21
|
validate_arguments!
|
data/lib/heroku/command/logs.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require "heroku/command/base"
|
2
|
+
require "heroku/helpers/log_displayer"
|
2
3
|
|
3
4
|
# display logs for an app
|
4
5
|
#
|
@@ -28,25 +29,8 @@ class Heroku::Command::Logs < Heroku::Command::Base
|
|
28
29
|
opts << "ps=#{URI.encode(options[:ps])}" if options[:ps]
|
29
30
|
opts << "source=#{URI.encode(options[:source])}" if options[:source]
|
30
31
|
|
31
|
-
|
32
|
-
|
33
|
-
@token = nil
|
34
|
-
|
35
|
-
heroku.read_logs(app, opts) do |chunk|
|
36
|
-
unless chunk.empty?
|
37
|
-
if STDOUT.isatty && ENV.has_key?("TERM")
|
38
|
-
display(colorize(chunk))
|
39
|
-
else
|
40
|
-
display(chunk)
|
41
|
-
end
|
42
|
-
end
|
43
|
-
end
|
44
|
-
rescue Errno::EPIPE
|
45
|
-
rescue Interrupt => interrupt
|
46
|
-
if STDOUT.isatty && ENV.has_key?("TERM")
|
47
|
-
display("\e[0m")
|
48
|
-
end
|
49
|
-
raise(interrupt)
|
32
|
+
log_displayer = ::Heroku::Helpers::LogDisplayer.new(heroku, app, opts)
|
33
|
+
log_displayer.display_logs
|
50
34
|
end
|
51
35
|
|
52
36
|
# logs:drains
|
@@ -58,41 +42,4 @@ class Heroku::Command::Logs < Heroku::Command::Base
|
|
58
42
|
display("~ `heroku logs:drains` has been deprecated and replaced with `heroku drains`")
|
59
43
|
Heroku::Command::Drains.new.index
|
60
44
|
end
|
61
|
-
|
62
|
-
protected
|
63
|
-
|
64
|
-
COLORS = %w( cyan yellow green magenta red )
|
65
|
-
COLOR_CODES = {
|
66
|
-
"red" => 31,
|
67
|
-
"green" => 32,
|
68
|
-
"yellow" => 33,
|
69
|
-
"magenta" => 35,
|
70
|
-
"cyan" => 36,
|
71
|
-
}
|
72
|
-
|
73
|
-
def colorize(chunk)
|
74
|
-
lines = []
|
75
|
-
chunk.split("\n").map do |line|
|
76
|
-
if parsed_line = parse_log(line)
|
77
|
-
header, identifier, body = parsed_line
|
78
|
-
@assigned_colors[identifier] ||= COLORS[@assigned_colors.size % COLORS.size]
|
79
|
-
lines << [
|
80
|
-
"\e[#{COLOR_CODES[@assigned_colors[identifier]]}m",
|
81
|
-
header,
|
82
|
-
"\e[0m",
|
83
|
-
body,
|
84
|
-
].join("")
|
85
|
-
elsif not line.empty?
|
86
|
-
lines << line
|
87
|
-
end
|
88
|
-
end
|
89
|
-
lines.join("\n")
|
90
|
-
end
|
91
|
-
|
92
|
-
def parse_log(log)
|
93
|
-
return unless parsed = log.match(/^(.*\[(\w+)([\d\.]+)?\]:)(.*)?$/)
|
94
|
-
[1, 2, 4].map { |i| parsed[i] }
|
95
|
-
end
|
96
|
-
|
97
45
|
end
|
98
|
-
|
@@ -31,7 +31,7 @@ class Heroku::Command::Maintenance < Heroku::Command::Base
|
|
31
31
|
#Example:
|
32
32
|
#
|
33
33
|
# $ heroku maintenance:on
|
34
|
-
# Enabling maintenance mode for
|
34
|
+
# Enabling maintenance mode for example
|
35
35
|
#
|
36
36
|
def on
|
37
37
|
validate_arguments!
|
@@ -48,7 +48,7 @@ class Heroku::Command::Maintenance < Heroku::Command::Base
|
|
48
48
|
#Example:
|
49
49
|
#
|
50
50
|
# $ heroku maintenance:off
|
51
|
-
# Disabling maintenance mode for
|
51
|
+
# Disabling maintenance mode for example
|
52
52
|
#
|
53
53
|
def off
|
54
54
|
validate_arguments!
|