/
apps.rb
220 lines (190 loc) · 6.49 KB
/
apps.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
require "heroku/command/base"
# manage apps (create, destroy)
#
class Heroku::Command::Apps < Heroku::Command::Base
# apps
#
# list your apps
#
def index
style_header("#{heroku.user} Apps")
list = heroku.list
if list.size > 0
owned, shared = list.partition {|app, owner| owner == heroku.user}
style_info("Owned by Me")
style_object(owned.map {|app, owner| app})
style_info("Shared with Me")
style_object(shared.map {|app, owner| app})
else
hputs("You have no apps.")
end
end
alias_command "list", "apps"
# apps:info
#
# show detailed app information
#
# -r, --raw # output info as raw key/value pairs
#
def info
unless options[:raw]
style_header("#{app} Info")
end
attrs = heroku.info(app)
if options[:raw]
attrs.keys.sort_by { |a| a.to_s }.each do |key|
case key
when :addons then
hputs("addons=#{attrs[:addons].map { |a| a["name"] }.sort.join(",")}")
when :collaborators then
hputs("collaborators=#{attrs[:collaborators].map { |c| c[:email] }.sort.join(",")}")
else
hputs("#{key}=#{attrs[key]}")
end
end
else
data = {
'Addons' => !attrs[:addons].empty? && attrs[:addons].map {|addon| addon['description']},
'Create Status' => (attrs[:create_status] != 'complete') && attrs[:create_status],
'Cron Finished At' => attrs[:cron_finished_at] && format_date(attrs[:cron_finished_at]),
'Cron Next Run' => attrs[:cron_next_run] && format_date(attrs[:cron_next_run]),
'Database Size' => attrs[:database_size] && format_bytes(attrs[:database_size]),
'Domain Name' => attrs[:domain_name],
'Dynos' => (attrs[:stack] != 'cedar') && attrs[:dynos],
'Git URL' => attrs[:git_url],
'Owner' => attrs[:owner],
'Repo Size' => attrs[:repo_size] && format_bytes(attrs[:repo_size]),
'Slug Size' => attrs[:slug_size] && format_bytes(attrs[:slug_size]),
'Stack' => attrs[:stack],
'Web URL' => attrs[:web_url],
'Workers' => (attrs[:stack] != 'cedar') && attrs[:workers],
}
data.reject! {|key,value| !value}
collaborators = attrs[:collaborators].delete_if { |c| c[:email] == attrs[:owner] }
unless collaborators.empty?
attrs[:collaborators].reject! {|collaborator| collaborator[:email] == attrs[:owner]}
data['Collaborators'] = attrs[:collaborators].map {|collaborator| collaborator[:email]}
end
if attrs[:database_tables]
data['Database Size'].gsub!('(empty)', '0K') + " in #{quantify("table", attrs[:database_tables])}"
end
if attrs[:dyno_hours].is_a?(Hash)
data['Dyno Hours'] = attrs[:dyno_hours].keys.map do |type|
" = %s: %0.2f dyno-hours" % [ type.to_s.capitalize, attrs[:dyno_hours][type] ]
end
end
style_object(data)
end
end
alias_command "info", "apps:info"
# apps:create [NAME]
#
# create a new app
#
# --addons ADDONS # a comma-delimited list of addons to install
# -b, --buildpack BUILDPACK # a buildpack url to use for this app
# -r, --remote REMOTE # the git remote to create, default "heroku"
# -s, --stack STACK # the stack on which to create the app
#
def create
remote = extract_option('--remote', 'heroku')
stack = extract_option('--stack', 'aspen-mri-1.8.6')
timeout = extract_option('--timeout', 30).to_i
name = args.shift.downcase.strip rescue nil
style_action("creating #{name}")
info = heroku.create_app(name, {:stack => stack})
name = info["name"]
begin
if info["create_status"] == "creating"
Timeout::timeout(timeout) do
loop do
break if heroku.create_complete?(name)
hprint(".")
sleep 1
end
end
end
hputs("done, stack is #{info["stack"]}")
(options[:addons] || "").split(",").each do |addon|
addon.strip!
style_action("adding #{addon} to #{name}")
heroku.install_addon(name, addon)
hputs("done")
end
if buildpack = options[:buildpack]
heroku.add_config_vars(name, "BUILDPACK_URL" => buildpack)
end
style_object({
:git_url => info["git_url"],
:web_url => info["web_url"]
})
rescue Timeout::Error
error("Timed Out! Check heroku status for known issues.")
end
create_git_remote(remote || "heroku", info["git_url"])
end
alias_command "create", "apps:create"
# apps:rename NEWNAME
#
# rename the app
#
def rename
newname = args.shift.downcase.strip rescue ''
raise(Heroku::Command::CommandFailed, "Must specify a new name.") if newname == ''
style_action("renaming #{app} to #{newname}")
heroku.update(app, :name => newname)
hputs("done")
info = heroku.info(newname)
style_object({
:git_url => info["git_url"],
:web_url => info["web_url"]
})
if remotes = git_remotes(Dir.pwd)
remotes.each do |remote_name, remote_app|
next if remote_app != app
git "remote rm #{remote_name}"
git "remote add #{remote_name} #{info[:git_url]}"
hputs("Git remote #{remote_name} updated")
end
else
hputs("Don't forget to update your Git remotes on any local checkouts.")
end
end
alias_command "rename", "apps:rename"
# apps:open
#
# open the app in a web browser
#
def open
info = heroku.info(app)
url = info[:web_url]
style_action("opening #{url}")
Launchy.open url
end
alias_command "open", "apps:open"
# apps:destroy
#
# permanently destroy an app
#
def destroy
@app = args.first || options[:app] || options[:confirm]
unless @app
raise Heroku::Command::CommandFailed.new("Usage: heroku apps:destroy --app APP")
end
action("destroying #{app} (including all add-ons)")
heroku.info(app) # fail fast if no access or doesn't exist
message = "WARNING: Potentially Destructive Action\nThis command will destroy #{app} (including all add-ons)."
if confirm_command(app, message)
heroku.destroy(app)
if remotes = git_remotes(Dir.pwd)
remotes.each do |remote_name, remote_app|
next if app != remote_app
git "remote rm #{remote_name}"
end
end
hputs("done")
end
end
alias_command "destroy", "apps:destroy"
alias_command "apps:delete", "apps:destroy"
end