Class: Azuki::Command::Apps

Inherits:
Base
  • Object
show all
Defined in:
lib/azuki/command/apps.rb

Overview

manage apps (create, destroy)

Instance Attribute Summary

Attributes inherited from Base

#args, #options

Instance Method Summary collapse

Methods inherited from Base

#api, #app, #azuki, #initialize, namespace

Methods included from Helpers

#action, #ask, #confirm, #confirm_billing, #confirm_command, #create_git_remote, #deprecate, #display, #display_header, #display_object, #display_row, #display_table, #error, error_with_failure, error_with_failure=, extended, extended_into, #fail, #format_bytes, #format_date, #format_error, #format_with_bang, #get_terminal_environment, #git, #has_git?, #home_directory, #hprint, #hputs, included, included_into, #json_decode, #json_encode, #launchy, #line_formatter, #longest, #output_with_bang, #quantify, #redisplay, #retry_on_exception, #run_command, #running_on_a_mac?, #running_on_windows?, #set_buffer, #shell, #spinner, #status, #string_distance, #styled_array, #styled_error, #styled_hash, #styled_header, #suggestion, #time_ago, #truncate, #with_tty

Constructor Details

This class inherits a constructor from Azuki::Command::Base

Instance Method Details

#createObject

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 -n, –no-remote # don’t create a git remote -r, –remote REMOTE # the git remote to create, default “azuki” -s, –stack STACK # the stack on which to create the app

--region REGION        # HIDDEN: specify region for this app to run on

-t, –tier TIER # HIDDEN: the tier for this app

Examples:

$ azuki apps:create Creating floating-dragon-42… done, stack is cedar floating-dragon-42.azukiapp.com/ | [email protected]:floating-dragon-42.git

$ azuki apps:create -s bamboo Creating floating-dragon-42… done, stack is bamboo-mri-1.9.2 floating-dragon-42.azukiapp.com/ | [email protected]:floating-dragon-42.git

# specify a name $ azuki apps:create example Creating example… done, stack is cedar example.azukiapp.com/ | [email protected]:example.git

# create a staging app $ azuki apps:create example-staging –remote staging



207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
# File 'lib/azuki/command/apps.rb', line 207

def create
  name    = shift_argument || options[:app] || ENV['AZUKI_APP']
  validate_arguments!

  info    = api.post_app({
    "name" => name,
    "region" => options[:region],
    "stack" => options[:stack],
    "tier" => options[:tier]
  }).body
  begin
    action("Creating #{info['name']}") do
      if info['create_status'] == 'creating'
        Timeout::timeout(options[:timeout].to_i) do
          loop do
            break if api.get_app(info['name']).body['create_status'] == 'complete'
            sleep 1
          end
        end
      end
      if info['region']
        status("region is #{info['region']}")
      else
        status("stack is #{info['stack']}")
      end
    end

    (options[:addons] || "").split(",").each do |addon|
      addon.strip!
      action("Adding #{addon} to #{info["name"]}") do
        api.post_addon(info["name"], addon)
      end
    end

    if buildpack = options[:buildpack]
      api.put_config_vars(info["name"], "BUILDPACK_URL" => buildpack)
      display("BUILDPACK_URL=#{buildpack}")
    end

    hputs([ info["web_url"], info["git_url"] ].join(" | "))
  rescue Timeout::Error
    hputs("Timed Out! Run `azuki status` to check for known platform issues.")
  end

  unless options[:no_remote].is_a? FalseClass
    create_git_remote(options[:remote] || "azuki", info["git_url"])
  end
end

#destroyObject

apps:destroy

permanently destroy an app

Example:

$ azuki apps:destroy -a example –confirm example Destroying example (including all add-ons)… done



323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
# File 'lib/azuki/command/apps.rb', line 323

def destroy
  @app = shift_argument || options[:app] || options[:confirm]
  validate_arguments!

  unless @app
    error("Usage: azuki apps:destroy --app APP\nMust specify APP to destroy.")
  end

  api.get_app(@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)
    action("Destroying #{@app} (including all add-ons)") do
      api.delete_app(@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
    end
  end
end

#downgradeObject

apps:downgrade TIER

HIDDEN: downgrade an app’s pricing tier



370
371
372
373
374
375
376
377
378
# File 'lib/azuki/command/apps.rb', line 370

def downgrade
  tier = shift_argument
  error("Usage: azuki apps:downgrade TIER\nMust specify TIER to downgrade.") if tier.nil? || tier.empty?
  validate_arguments!

  action("Upgrading #{app} to #{tier}") do
    api.put_app(app, "tier" => tier)
  end
end

#indexObject

apps

list your apps

Example:

$ azuki apps

My Apps

example example2

Collaborated Apps

theirapp [email protected]



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
# File 'lib/azuki/command/apps.rb', line 21

def index
  validate_arguments!
  apps = api.get_apps.body
  unless apps.empty?
    my_apps, collaborated_apps = apps.partition do |app|
      app["owner_email"] == Azuki::Auth.user
    end

    unless my_apps.empty?
      non_legacy_apps = my_apps.select do |app|
        app["tier"] != "legacy"
      end

      unless non_legacy_apps.empty?
        production_basic_apps, dev_legacy_apps = my_apps.partition do |app|
          ["production", "basic"].include?(app["tier"])
        end

        unless production_basic_apps.empty?
          styled_header("Basic & Production Apps")
          styled_array(production_basic_apps.map { |app| regionized_app_name(app) })
        end

        unless dev_legacy_apps.empty?
          styled_header("Dev & Legacy Apps")
          styled_array(dev_legacy_apps.map { |app| regionized_app_name(app) })
        end
      else
        styled_header("My Apps")
        styled_array(my_apps.map { |app| regionized_app_name(app) })
      end
    end

    unless collaborated_apps.empty?
      styled_header("Collaborated Apps")
      styled_array(collaborated_apps.map { |app| [regionized_app_name(app), app["owner_email"]] })
    end
  else
    display("You have no apps.")
  end
end

#infoObject

apps:info

show detailed app information

-s, –shell # output more shell friendly key/value pairs

Examples:

$ azuki apps:info

example

Git URL: [email protected]:example.git Repo Size: 5M …

$ azuki apps:info –shell [email protected]:example.git repo_size=5000000 …



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
# File 'lib/azuki/command/apps.rb', line 84

def info
  validate_arguments!
  app_data = api.get_app(app).body

  unless options[:shell]
    styled_header(app_data["name"])
  end

  addons_data = api.get_addons(app).body.map {|addon| addon['name']}.sort
  collaborators_data = api.get_collaborators(app).body.map {|collaborator| collaborator["email"]}.sort
  collaborators_data.reject! {|email| email == app_data["owner_email"]}

  if options[:shell]
    if app_data['domain_name']
      app_data['domain_name'] = app_data['domain_name']['domain']
    end
    unless addons_data.empty?
      app_data['addons'] = addons_data.join(',')
    end
    unless collaborators_data.empty?
      app_data['collaborators'] = collaborators_data.join(',')
    end
    app_data.keys.sort_by { |a| a.to_s }.each do |key|
      hputs("#{key}=#{app_data[key]}")
    end
  else
    data = {}

    unless addons_data.empty?
      data["Addons"] = addons_data
    end

    data["Collaborators"] = collaborators_data

    if app_data["create_status"] && app_data["create_status"] != "complete"
      data["Create Status"] = app_data["create_status"]
    end

    if app_data["cron_finished_at"]
      data["Cron Finished At"] = format_date(app_data["cron_finished_at"])
    end

    if app_data["cron_next_run"]
      data["Cron Next Run"] = format_date(app_data["cron_next_run"])
    end

    if app_data["database_size"]
      data["Database Size"] = format_bytes(app_data["database_size"])
    end

    data["Git URL"] = app_data["git_url"]

    if app_data["database_tables"]
      data["Database Size"].gsub!('(empty)', '0K') + " in #{quantify("table", app_data["database_tables"])}"
    end

    if app_data["dyno_hours"].is_a?(Hash)
      data["Dyno Hours"] = app_data["dyno_hours"].keys.map do |type|
        "%s - %0.2f dyno-hours" % [ type.to_s.capitalize, app_data["dyno_hours"][type] ]
      end
    end

    data["Owner Email"] = app_data["owner_email"]

    if app_data["region"]
      data["Region"] = app_data["region"]
    end

    if app_data["repo_size"]
      data["Repo Size"] = format_bytes(app_data["repo_size"])
    end

    if app_data["slug_size"]
      data["Slug Size"] = format_bytes(app_data["slug_size"])
    end

    data["Stack"] = app_data["stack"]
    if data["Stack"] != "cedar"
      data.merge!("Dynos" => app_data["dynos"], "Workers" => app_data["workers"])
    end

    data["Web URL"] = app_data["web_url"]

    if app_data["tier"]
      data["Tier"] = app_data["tier"].capitalize
    end

    styled_hash(data)
  end
end

#openObject

apps:open

open the app in a web browser

Example:

$ azuki apps:open Opening example… done



305
306
307
308
309
310
# File 'lib/azuki/command/apps.rb', line 305

def open
  validate_arguments!

  app_data = api.get_app(app).body
  launchy("Opening #{app}", app_data['web_url'])
end

#renameObject

apps:rename NEWNAME

rename the app

Example:

$ azuki apps:rename example-newname example-newname.azukiapp.com/ | [email protected]:example-newname.git Git remote azuki updated



268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
# File 'lib/azuki/command/apps.rb', line 268

def rename
  newname = shift_argument
  if newname.nil? || newname.empty?
    error("Usage: azuki apps:rename NEWNAME\nMust specify NEWNAME to rename.")
  end
  validate_arguments!

  action("Renaming #{app} to #{newname}") do
    api.put_app(app, "name" => newname)
  end

  app_data = api.get_app(newname).body
  hputs([ app_data["web_url"], app_data["git_url"] ].join(" | "))

  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} #{app_data["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

#upgradeObject

apps:upgrade TIER

HIDDEN: upgrade an app’s pricing tier



354
355
356
357
358
359
360
361
362
# File 'lib/azuki/command/apps.rb', line 354

def upgrade
  tier = shift_argument
  error("Usage: azuki apps:upgrade TIER\nMust specify TIER to upgrade.") if tier.nil? || tier.empty?
  validate_arguments!

  action("Upgrading #{app} to #{tier}") do
    api.put_app(app, "tier" => tier)
  end
end