class Heroku::Command::Apps
manage apps (create, destroy)
Public Instance Methods
create()
click to toggle source
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 "heroku" --space SPACE # HIDDEN: the space in which to create the app -s, --stack STACK # the stack on which to create the app --region REGION # specify region for this app to run in -l, --locked # lock the app --ssh-git # Use SSH git protocol -t, --tier TIER # HIDDEN: the tier for this app --http-git # HIDDEN: Use HTTP git protocol
Examples:
$ heroku apps:create Creating floating-dragon-42... done, stack is cedar http://floating-dragon-42.heroku.com/ | https://git.heroku.com/floating-dragon-42.git # specify a stack $ heroku create -s cedar Creating stormy-garden-5052... done, stack is cedar https://stormy-garden-5052.herokuapp.com/ | https://git.heroku.com/stormy-garden-5052.git # specify a name $ heroku apps:create example Creating example... done, stack is cedar http://example.heroku.com/ | https://git.heroku.com/example.git # create a staging app $ heroku apps:create example-staging --remote staging # create an app in the eu region $ heroku apps:create --region eu
# File lib/heroku/command/apps.rb, line 245 def create name = shift_argument || options[:app] || ENV['HEROKU_APP'] validate_arguments! options[:ignore_no_org] = true validate_space_xor_org! params = { "name" => name, "region" => options[:region], "space" => options[:space], "stack" => Heroku::Command::Stack::Codex.in(options[:stack]), "locked" => options[:locked] } info = if options[:space] api.post_organizations_app_v3_dogwood(params).body elsif org org_api.post_app(params, org).body else api.post_app(params).body end begin display_org = !!org if info['space'] space_name = info['space']['name'] display_org = false end action("Creating #{info['name']}", :space => space_name, :org => display_org) 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 options[:region] status("region is #{region_from_app(info)}") else stack = (info['stack'].is_a?(Hash) ? info['stack']["name"] : info['stack']) status("stack is #{Heroku::Command::Stack::Codex.out(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_app_buildpacks_v3(info['name'], {:updates => [{:buildpack => buildpack}]}) display "Buildpack set. Next release on #{info['name']} will use #{buildpack}." end hputs([ info["web_url"], git_url(info['name']) ].join(" | ")) rescue Timeout::Error hputs("Timed Out! Run `heroku status` to check for known platform issues.") end unless options[:no_remote].is_a? FalseClass create_git_remote(options[:remote] || "heroku", git_url(info['name'])) end end
destroy()
click to toggle source
apps:destroy --app APP permanently destroy an app
Example:
$ heroku apps:destroy -a example --confirm example Destroying example (including all add-ons)... done
# File lib/heroku/command/apps.rb, line 385 def destroy @app = shift_argument || options[:app] || options[:confirm] validate_arguments! unless @app error("Usage: heroku 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
downgrade()
click to toggle source
apps:downgrade TIER –app APP
HIDDEN: downgrade an app's pricing tier
# File lib/heroku/command/apps.rb, line 502 def downgrade tier = shift_argument error("Usage: heroku 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
index()
click to toggle source
apps list your apps -o, --org ORG # the org to list the apps for --space SPACE # HIDDEN: list apps in a given space -A, --all # list all apps in the org. Not just joined apps -p, --personal # list apps in personal account when a default org is set
Example:
$ heroku apps === My Apps example example2 === Collaborated Apps theirapp other@owner.name
# File lib/heroku/command/apps.rb, line 28 def index validate_arguments! options[:ignore_no_org] = true validate_space_xor_org! apps = if options[:space] api.get_apps.body.select do |app| app["space"] && [app["space"]["name"], app["space"]["id"]].include?(options[:space]) end elsif org org_api.get_apps(org).body else api.get_apps.body.select { |app| options[:all] ? true : !org?(app["owner_email"]) } end unless apps.empty? if options[:space] styled_header("Apps in space #{options[:space]}") styled_array(apps.map { |app| regionized_app_name(app) }) elsif org joined, unjoined = apps.partition { |app| app['joined'] == true } styled_header("Apps joined in organization #{org}") unless joined.empty? styled_array(joined.map {|app| regionized_app_name(app) + (app['locked'] ? ' (locked)' : '') }) else display("You haven't joined any apps.") display("Use --all to see unjoined apps.") unless options[:all] display end if options[:all] styled_header("Apps available to join in organization #{org}") unless unjoined.empty? styled_array(unjoined.map {|app| regionized_app_name(app) + (app['locked'] ? ' (locked)' : '') }) else display("There are no apps to join.") display end end else my_apps, collaborated_apps = apps.partition { |app| app["owner_email"] == Heroku::Auth.user } unless my_apps.empty? styled_header("My Apps") styled_array(my_apps.map { |app| regionized_app_name(app) }) end unless collaborated_apps.empty? styled_header("Collaborated Apps") styled_array(collaborated_apps.map { |app| [regionized_app_name(app), app_owner(app["owner_email"])] }) end end else if options[:space] display("There are no apps available in space #{options[:space]}.") elsif org display("There are no apps in organization #{org}.") else display("You have no apps.") end end end
info()
click to toggle source
apps:info show detailed app information -s, --shell # output more shell friendly key/value pairs
Examples:
$ heroku apps:info === example Git URL: https://git.heroku.com/example.git Repo Size: 5M ... $ heroku apps:info --shell git_url=https://git.heroku.com/example.git repo_size=5000000 ...
# File lib/heroku/command/apps.rb, line 113 def info validate_arguments! requires_preauth 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 rescue {} collaborators_data = api.get_collaborators(app).body.map {|collaborator| collaborator["email"]}.sort collaborators_data.reject! {|email| email == app_data["owner_email"]} if org? app_data['owner_email'] app_data['owner'] = app_owner(app_data['owner_email']) app_data.delete("owner_email") end if options[:shell] app_data['git_url'] = git_url(app_data['name']) 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 if app_data["archived_at"] data["Archived At"] = format_date(app_data["archived_at"]) 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"] = git_url(app_data['name']) 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["owner_email"] data["Owner"] = app_data["owner"] if app_data["owner"] data["Region"] = app_data["region"] if app_data["region"] data["Space"] = app_data["space"]["name"] if app_data["space"] && app_data["space"]["name"] data["Repo Size"] = format_bytes(app_data["repo_size"]) if app_data["repo_size"] data["Slug Size"] = format_bytes(app_data["slug_size"]) if app_data["slug_size"] data["Cache Size"] = format_bytes(app_data["cache_size"]) if app_data["cache_size"] data["Stack"] = Heroku::Command::Stack::Codex.out(app_data["stack"]) if data["Stack"] != "cedar-10" data.merge!("Dynos" => app_data["dynos"], "Workers" => app_data["workers"]) end data["Web URL"] = app_data["web_url"] styled_hash(data) end end
join()
click to toggle source
apps:join –app APP
add yourself to an organization app
-a, –app APP # the app
# File lib/heroku/command/apps.rb, line 417 def join begin action("Joining application #{app}") do org_api.join_app(app) end rescue Heroku::API::Errors::NotFound error("Application does not exist or does not belong to an org that you have access to.") end end
leave()
click to toggle source
apps:leave –app APP
remove yourself from an organization app
-a, –app APP # the app
# File lib/heroku/command/apps.rb, line 434 def leave begin action("Leaving application #{app}") do if org_from_app = extract_org_from_app org_api.leave_app(app) else api.delete_collaborator(app, Heroku::Auth.user) end end end end
lock()
click to toggle source
apps:lock –app APP
lock an organization app to restrict access
# File lib/heroku/command/apps.rb, line 452 def lock begin action("Locking #{app}") { org_api.lock_app(app) } display("Organization members must be invited this app.") rescue Excon::Errors::NotFound error("#{app} was not found") end end
open()
click to toggle source
apps:open --app APP open the app in a web browser
Example:
$ heroku apps:open Opening example... done
# File lib/heroku/command/apps.rb, line 364 def open path = shift_argument validate_arguments! app_data = api.get_app(app).body url = [app_data['web_url'], path].join launchy("Opening #{app}", url) end
rename()
click to toggle source
apps:rename NEWNAME --app APP rename the app --ssh-git # Use SSH git protocol --http-git # HIDDEN: Use HTTP git protocol
Example:
$ heroku apps:rename example-newname http://example-newname.herokuapp.com/ | https://git.heroku.com/example-newname.git Git remote heroku updated
# File lib/heroku/command/apps.rb, line 327 def rename newname = shift_argument if newname.nil? || newname.empty? error("Usage: heroku 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"], git_url(newname) ].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} #{git_url(newname)}" hputs("Git remote #{remote_name} updated") end else hputs("Don't forget to update your Git remotes on any local checkouts.") end end
unlock()
click to toggle source
apps:unlock –app APP
unlock an organization app so that any org member can join it
# File lib/heroku/command/apps.rb, line 469 def unlock begin action("Unlocking #{app}") { org_api.unlock_app(app) } display("All organization members can join this app.") rescue Excon::Errors::NotFound error("#{app} was not found") end end
upgrade()
click to toggle source
apps:upgrade TIER –app APP
HIDDEN: upgrade an app's pricing tier
# File lib/heroku/command/apps.rb, line 486 def upgrade tier = shift_argument error("Usage: heroku 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
Private Instance Methods
region_from_app(app)
click to toggle source
# File lib/heroku/command/apps.rb, line 527 def region_from_app app region = app["region"].is_a?(Hash) ? app["region"]["name"] : app["region"] end
regionized_app_name(app)
click to toggle source
# File lib/heroku/command/apps.rb, line 516 def regionized_app_name(app) region = region_from_app(app) # temporary, show region for non-us apps if app["region"] && region != 'us' "#{app["name"]} (#{region})" else app["name"] end end
validate_space_xor_org!()
click to toggle source
# File lib/heroku/command/apps.rb, line 531 def validate_space_xor_org! if options[:space] && options[:org] error "Specify option for space or org, but not both." end end