pogo 2.31.2
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +73 -0
- data/bin/pogo +22 -0
- data/data/cacert.pem +3988 -0
- data/lib/heroku.rb +22 -0
- data/lib/heroku/auth.rb +320 -0
- data/lib/heroku/cli.rb +38 -0
- data/lib/heroku/client.rb +764 -0
- data/lib/heroku/client/heroku_postgresql.rb +111 -0
- data/lib/heroku/client/pgbackups.rb +113 -0
- data/lib/heroku/client/rendezvous.rb +105 -0
- data/lib/heroku/client/ssl_endpoint.rb +25 -0
- data/lib/heroku/command.rb +273 -0
- data/lib/heroku/command/account.rb +23 -0
- data/lib/heroku/command/accounts.rb +34 -0
- data/lib/heroku/command/addons.rb +305 -0
- data/lib/heroku/command/apps.rb +311 -0
- data/lib/heroku/command/auth.rb +86 -0
- data/lib/heroku/command/base.rb +230 -0
- data/lib/heroku/command/certs.rb +148 -0
- data/lib/heroku/command/config.rb +137 -0
- data/lib/heroku/command/db.rb +218 -0
- data/lib/heroku/command/domains.rb +85 -0
- data/lib/heroku/command/drains.rb +46 -0
- data/lib/heroku/command/git.rb +65 -0
- data/lib/heroku/command/help.rb +163 -0
- data/lib/heroku/command/keys.rb +115 -0
- data/lib/heroku/command/labs.rb +161 -0
- data/lib/heroku/command/logs.rb +98 -0
- data/lib/heroku/command/maintenance.rb +61 -0
- data/lib/heroku/command/pg.rb +277 -0
- data/lib/heroku/command/pgbackups.rb +289 -0
- data/lib/heroku/command/plugins.rb +110 -0
- data/lib/heroku/command/ps.rb +232 -0
- data/lib/heroku/command/releases.rb +124 -0
- data/lib/heroku/command/run.rb +179 -0
- data/lib/heroku/command/sharing.rb +89 -0
- data/lib/heroku/command/ssl.rb +61 -0
- data/lib/heroku/command/stack.rb +62 -0
- data/lib/heroku/command/status.rb +51 -0
- data/lib/heroku/command/update.rb +47 -0
- data/lib/heroku/command/version.rb +23 -0
- data/lib/heroku/deprecated.rb +5 -0
- data/lib/heroku/deprecated/help.rb +38 -0
- data/lib/heroku/distribution.rb +9 -0
- data/lib/heroku/helpers.rb +517 -0
- data/lib/heroku/helpers/heroku_postgresql.rb +104 -0
- data/lib/heroku/plugin.rb +161 -0
- data/lib/heroku/updater.rb +158 -0
- data/lib/heroku/version.rb +3 -0
- data/lib/vendor/heroku/okjson.rb +598 -0
- data/spec/helper/legacy_help.rb +16 -0
- data/spec/heroku/auth_spec.rb +246 -0
- data/spec/heroku/client/heroku_postgresql_spec.rb +34 -0
- data/spec/heroku/client/pgbackups_spec.rb +43 -0
- data/spec/heroku/client/rendezvous_spec.rb +62 -0
- data/spec/heroku/client/ssl_endpoint_spec.rb +48 -0
- data/spec/heroku/client_spec.rb +564 -0
- data/spec/heroku/command/addons_spec.rb +585 -0
- data/spec/heroku/command/apps_spec.rb +351 -0
- data/spec/heroku/command/auth_spec.rb +38 -0
- data/spec/heroku/command/base_spec.rb +109 -0
- data/spec/heroku/command/certs_spec.rb +178 -0
- data/spec/heroku/command/config_spec.rb +144 -0
- data/spec/heroku/command/db_spec.rb +110 -0
- data/spec/heroku/command/domains_spec.rb +87 -0
- data/spec/heroku/command/drains_spec.rb +34 -0
- data/spec/heroku/command/git_spec.rb +116 -0
- data/spec/heroku/command/help_spec.rb +93 -0
- data/spec/heroku/command/keys_spec.rb +120 -0
- data/spec/heroku/command/labs_spec.rb +99 -0
- data/spec/heroku/command/logs_spec.rb +60 -0
- data/spec/heroku/command/maintenance_spec.rb +51 -0
- data/spec/heroku/command/pg_spec.rb +223 -0
- data/spec/heroku/command/pgbackups_spec.rb +280 -0
- data/spec/heroku/command/plugins_spec.rb +104 -0
- data/spec/heroku/command/ps_spec.rb +195 -0
- data/spec/heroku/command/releases_spec.rb +130 -0
- data/spec/heroku/command/run_spec.rb +86 -0
- data/spec/heroku/command/sharing_spec.rb +59 -0
- data/spec/heroku/command/ssl_spec.rb +32 -0
- data/spec/heroku/command/stack_spec.rb +46 -0
- data/spec/heroku/command/status_spec.rb +48 -0
- data/spec/heroku/command/version_spec.rb +16 -0
- data/spec/heroku/command_spec.rb +211 -0
- data/spec/heroku/helpers/heroku_postgresql_spec.rb +109 -0
- data/spec/heroku/helpers_spec.rb +48 -0
- data/spec/heroku/plugin_spec.rb +172 -0
- data/spec/heroku/updater_spec.rb +44 -0
- data/spec/spec.opts +1 -0
- data/spec/spec_helper.rb +209 -0
- data/spec/support/display_message_matcher.rb +49 -0
- data/spec/support/openssl_mock_helper.rb +8 -0
- metadata +220 -0
@@ -0,0 +1,65 @@
|
|
1
|
+
require "heroku/command/base"
|
2
|
+
|
3
|
+
# manage git for apps
|
4
|
+
#
|
5
|
+
class Heroku::Command::Git < Heroku::Command::Base
|
6
|
+
|
7
|
+
# git:clone [OPTIONS]
|
8
|
+
#
|
9
|
+
# clones an app repo
|
10
|
+
#
|
11
|
+
# if OPTIONS are specified they will be passed to git clone
|
12
|
+
#
|
13
|
+
# -n, --no-remote # don't create a git remote
|
14
|
+
# -r, --remote REMOTE # the git remote to create, default "heroku"
|
15
|
+
#
|
16
|
+
#Examples:
|
17
|
+
#
|
18
|
+
# $ heroku git:clone -a myapp
|
19
|
+
# Cloning into 'myapp'...
|
20
|
+
# Git remote heroku added
|
21
|
+
#
|
22
|
+
def clone
|
23
|
+
git_options = args.join(" ")
|
24
|
+
remote = options[:remote] || 'heroku'
|
25
|
+
|
26
|
+
app_data = api.get_app(app).body
|
27
|
+
|
28
|
+
display git("clone #{app_data['git_url']} #{git_options}")
|
29
|
+
|
30
|
+
unless $?.exitstatus > 0 || options[:no_remote].is_a?(FalseClass)
|
31
|
+
FileUtils.chdir(app_data['name']) do
|
32
|
+
create_git_remote(remote, app_data['git_url'])
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
# git:remote [OPTIONS]
|
38
|
+
#
|
39
|
+
# adds a git remote to an app repo
|
40
|
+
#
|
41
|
+
# if OPTIONS are specified they will be passed to git remote add
|
42
|
+
#
|
43
|
+
# -r, --remote REMOTE # the git remote to create, default "heroku"
|
44
|
+
#
|
45
|
+
#Examples:
|
46
|
+
#
|
47
|
+
# $ heroku git:remote -a myapp
|
48
|
+
# Git remote heroku added
|
49
|
+
#
|
50
|
+
# $ heroku git:remote -a myapp
|
51
|
+
# ! Git remote heroku already exists
|
52
|
+
#
|
53
|
+
def remote
|
54
|
+
git_options = args.join(" ")
|
55
|
+
remote = options[:remote] || 'heroku'
|
56
|
+
|
57
|
+
if git('remote').split("\n").include?(remote)
|
58
|
+
error("Git remote #{remote} already exists")
|
59
|
+
else
|
60
|
+
app_data = api.get_app(app).body
|
61
|
+
create_git_remote(remote, app_data['git_url'])
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
@@ -0,0 +1,163 @@
|
|
1
|
+
require "heroku/command/base"
|
2
|
+
require "heroku/deprecated/help"
|
3
|
+
|
4
|
+
# list commands and display help
|
5
|
+
#
|
6
|
+
class Heroku::Command::Help < Heroku::Command::Base
|
7
|
+
|
8
|
+
PRIMARY_NAMESPACES = %w( auth apps ps run addons config releases domains logs sharing )
|
9
|
+
|
10
|
+
include Heroku::Deprecated::Help
|
11
|
+
|
12
|
+
# help [COMMAND]
|
13
|
+
#
|
14
|
+
# list available commands or display help for a specific command
|
15
|
+
#
|
16
|
+
#Examples:
|
17
|
+
#
|
18
|
+
# $ heroku help
|
19
|
+
# Usage: heroku COMMAND [--app APP] [command-specific-options]
|
20
|
+
#
|
21
|
+
# Primary help topics, type "heroku help TOPIC" for more details:
|
22
|
+
#
|
23
|
+
# addons # manage addon resources
|
24
|
+
# apps # manage apps (create, destroy)
|
25
|
+
# ...
|
26
|
+
#
|
27
|
+
# Additional topics:
|
28
|
+
#
|
29
|
+
# account # manage heroku account options
|
30
|
+
# accounts # manage multiple heroku accounts
|
31
|
+
# ...
|
32
|
+
#
|
33
|
+
# $ heroku help apps:create
|
34
|
+
# Usage: heroku apps:create [NAME]
|
35
|
+
#
|
36
|
+
# create a new app
|
37
|
+
#
|
38
|
+
# --addons ADDONS # a comma-delimited list of addons to install
|
39
|
+
# -b, --buildpack BUILDPACK # a buildpack url to use for this app
|
40
|
+
# -r, --remote REMOTE # the git remote to create, default "heroku"
|
41
|
+
# -s, --stack STACK # the stack on which to create the app
|
42
|
+
#
|
43
|
+
def index
|
44
|
+
if command = args.shift
|
45
|
+
help_for_command(command)
|
46
|
+
else
|
47
|
+
help_for_root
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
alias_command "-h", "help"
|
52
|
+
alias_command "--help", "help"
|
53
|
+
|
54
|
+
private
|
55
|
+
|
56
|
+
def commands_for_namespace(name)
|
57
|
+
Heroku::Command.commands.values.select do |command|
|
58
|
+
command[:namespace] == name && command[:command] != name
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def namespaces
|
63
|
+
namespaces = Heroku::Command.namespaces
|
64
|
+
namespaces.delete("app")
|
65
|
+
namespaces
|
66
|
+
end
|
67
|
+
|
68
|
+
def commands
|
69
|
+
Heroku::Command.commands
|
70
|
+
end
|
71
|
+
|
72
|
+
def legacy_help_for_namespace(namespace)
|
73
|
+
instance = Heroku::Command::Help.groups.map do |group|
|
74
|
+
[ group.title, group.select { |c| c.first =~ /^#{namespace}/ }.length ]
|
75
|
+
end.sort_by { |l| l.last }.last
|
76
|
+
return nil unless instance
|
77
|
+
return nil if instance.last.zero?
|
78
|
+
instance.first
|
79
|
+
end
|
80
|
+
|
81
|
+
def legacy_help_for_command(command)
|
82
|
+
Heroku::Command::Help.groups.each do |group|
|
83
|
+
group.each do |cmd, description|
|
84
|
+
return description if cmd.split(" ").first == command
|
85
|
+
end
|
86
|
+
end
|
87
|
+
nil
|
88
|
+
end
|
89
|
+
|
90
|
+
def primary_namespaces
|
91
|
+
PRIMARY_NAMESPACES.map { |name| namespaces[name] }.compact
|
92
|
+
end
|
93
|
+
|
94
|
+
def additional_namespaces
|
95
|
+
(namespaces.values - primary_namespaces)
|
96
|
+
end
|
97
|
+
|
98
|
+
def summary_for_namespaces(namespaces)
|
99
|
+
size = longest(namespaces.map { |n| n[:name] })
|
100
|
+
namespaces.sort_by {|namespace| namespace[:name]}.each do |namespace|
|
101
|
+
name = namespace[:name]
|
102
|
+
namespace[:description] ||= legacy_help_for_namespace(name)
|
103
|
+
puts " %-#{size}s # %s" % [ name, namespace[:description] ]
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
def help_for_root
|
108
|
+
puts "Usage: heroku COMMAND [--app APP] [command-specific-options]"
|
109
|
+
puts
|
110
|
+
puts "Primary help topics, type \"heroku help TOPIC\" for more details:"
|
111
|
+
puts
|
112
|
+
summary_for_namespaces(primary_namespaces)
|
113
|
+
puts
|
114
|
+
puts "Additional topics:"
|
115
|
+
puts
|
116
|
+
summary_for_namespaces(additional_namespaces)
|
117
|
+
puts
|
118
|
+
end
|
119
|
+
|
120
|
+
def help_for_namespace(name)
|
121
|
+
namespace_commands = commands_for_namespace(name)
|
122
|
+
|
123
|
+
unless namespace_commands.empty?
|
124
|
+
size = longest(namespace_commands.map { |c| c[:banner] })
|
125
|
+
namespace_commands.sort_by { |c| c[:banner].to_s }.each do |command|
|
126
|
+
next if command[:help] =~ /DEPRECATED/
|
127
|
+
command[:summary] ||= legacy_help_for_command(command[:command])
|
128
|
+
puts " %-#{size}s # %s" % [ command[:banner], command[:summary] ]
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
def help_for_command(name)
|
134
|
+
if command_alias = Heroku::Command.command_aliases[name]
|
135
|
+
display("Alias: #{name} redirects to #{command_alias}")
|
136
|
+
name = command_alias
|
137
|
+
end
|
138
|
+
if command = commands[name]
|
139
|
+
puts "Usage: heroku #{command[:banner]}"
|
140
|
+
|
141
|
+
if command[:help].strip.length > 0
|
142
|
+
puts command[:help].split("\n")[1..-1].join("\n")
|
143
|
+
else
|
144
|
+
puts
|
145
|
+
puts " " + legacy_help_for_command(name).to_s
|
146
|
+
end
|
147
|
+
puts
|
148
|
+
end
|
149
|
+
|
150
|
+
namespace_commands = commands_for_namespace(name).reject do |command|
|
151
|
+
command[:help] =~ /DEPRECATED/
|
152
|
+
end
|
153
|
+
|
154
|
+
if !namespace_commands.empty?
|
155
|
+
puts "Additional commands, type \"heroku help COMMAND\" for more details:"
|
156
|
+
puts
|
157
|
+
help_for_namespace(name)
|
158
|
+
puts
|
159
|
+
elsif command.nil?
|
160
|
+
error "#{name} is not a heroku command. See `heroku help`."
|
161
|
+
end
|
162
|
+
end
|
163
|
+
end
|
@@ -0,0 +1,115 @@
|
|
1
|
+
require "heroku/command/base"
|
2
|
+
|
3
|
+
module Heroku::Command
|
4
|
+
|
5
|
+
# manage authentication keys
|
6
|
+
#
|
7
|
+
class Keys < Base
|
8
|
+
|
9
|
+
# keys
|
10
|
+
#
|
11
|
+
# display keys for the current user
|
12
|
+
#
|
13
|
+
# -l, --long # display extended information for each key
|
14
|
+
#
|
15
|
+
#Examples:
|
16
|
+
#
|
17
|
+
# $ heroku keys
|
18
|
+
# === email@example.com Keys
|
19
|
+
# ssh-rsa ABCDEFGHIJK...OPQRSTUV== email@example.com
|
20
|
+
#
|
21
|
+
# $ heroku keys --long
|
22
|
+
# === email@example.com Keys
|
23
|
+
# ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAp9AJD5QABmOcrkHm6SINuQkDefaR0MUrfgZ1Pxir3a4fM1fwa00dsUwbUaRuR7FEFD8n1E9WwDf8SwQTHtyZsJg09G9myNqUzkYXCmydN7oGr5IdVhRyv5ixcdiE0hj7dRnOJg2poSQ3Qi+Ka8SVJzF7nIw1YhuicHPSbNIFKi5s0D5a+nZb/E6MNGvhxoFCQX2IcNxaJMqhzy1ESwlixz45aT72mXYq0LIxTTpoTqma1HuKdRY8HxoREiivjmMQulYP+CxXFcMyV9kxTKIUZ/FXqlC6G5vSm3J4YScSatPOj9ID5HowpdlIx8F6y4p1/28r2tTl4CY40FFyoke4MQ== email@example.com
|
24
|
+
#
|
25
|
+
def index
|
26
|
+
validate_arguments!
|
27
|
+
keys = api.get_keys.body
|
28
|
+
if keys.length > 0
|
29
|
+
styled_header("#{Heroku::Auth.user} Keys")
|
30
|
+
keys = if options[:long]
|
31
|
+
keys.map {|key| key["contents"].strip}
|
32
|
+
else
|
33
|
+
keys.map {|key| format_key_for_display(key["contents"])}
|
34
|
+
end
|
35
|
+
styled_array(keys)
|
36
|
+
else
|
37
|
+
display("You have no keys.")
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
# keys:add [KEY]
|
42
|
+
#
|
43
|
+
# add a key for the current user
|
44
|
+
#
|
45
|
+
# if no KEY is specified, will try to find ~/.ssh/id_[rd]sa.pub
|
46
|
+
#
|
47
|
+
#Examples:
|
48
|
+
#
|
49
|
+
# $ heroku keys:add
|
50
|
+
# Could not find an existing public key.
|
51
|
+
# Would you like to generate one? [Yn] y
|
52
|
+
# Generating new SSH public key.
|
53
|
+
# Uploading SSH public key /.ssh/id_rsa.pub... done
|
54
|
+
#
|
55
|
+
# $ heroku keys:add /my/key.pub
|
56
|
+
# Uploading SSH public key /my/key.pub... done
|
57
|
+
#
|
58
|
+
def add
|
59
|
+
keyfile = shift_argument
|
60
|
+
validate_arguments!
|
61
|
+
|
62
|
+
if keyfile
|
63
|
+
Heroku::Auth.associate_key(keyfile)
|
64
|
+
else
|
65
|
+
# make sure we have credentials
|
66
|
+
Heroku::Auth.get_credentials
|
67
|
+
Heroku::Auth.associate_or_generate_ssh_key
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
# keys:remove KEY
|
72
|
+
#
|
73
|
+
# remove a key from the current user
|
74
|
+
#
|
75
|
+
#Examples:
|
76
|
+
#
|
77
|
+
# $ heroku keys:remove email@example.com
|
78
|
+
# Removing email@example.com SSH key... done
|
79
|
+
#
|
80
|
+
def remove
|
81
|
+
key = shift_argument
|
82
|
+
if key.nil? || key.empty?
|
83
|
+
error("Usage: heroku keys:remove KEY\nMust specify KEY to remove.")
|
84
|
+
end
|
85
|
+
validate_arguments!
|
86
|
+
|
87
|
+
action("Removing #{key} SSH key") do
|
88
|
+
api.delete_key(key)
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
# keys:clear
|
93
|
+
#
|
94
|
+
# remove all authentication keys from the current user
|
95
|
+
#
|
96
|
+
#Examples:
|
97
|
+
#
|
98
|
+
# $ heroku keys:cleare
|
99
|
+
# Removing all SSH keys... done
|
100
|
+
#
|
101
|
+
def clear
|
102
|
+
validate_arguments!
|
103
|
+
|
104
|
+
action("Removing all SSH keys") do
|
105
|
+
api.delete_keys
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
protected
|
110
|
+
def format_key_for_display(key)
|
111
|
+
type, hex, local = key.strip.split(/\s/)
|
112
|
+
[type, hex[0,10] + '...' + hex[-10,10], local].join(' ')
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
@@ -0,0 +1,161 @@
|
|
1
|
+
require "heroku/command/base"
|
2
|
+
|
3
|
+
# manage optional features
|
4
|
+
#
|
5
|
+
class Heroku::Command::Labs < Heroku::Command::Base
|
6
|
+
|
7
|
+
# labs [APP]
|
8
|
+
#
|
9
|
+
# lists enabled features for an app
|
10
|
+
#
|
11
|
+
#Example:
|
12
|
+
#
|
13
|
+
# $ heroku labs -a myapp
|
14
|
+
# === myapp Enabled Features
|
15
|
+
# sigterm-all: When stopping a dyno, send SIGTERM to all processes rather than only to the root process.
|
16
|
+
#
|
17
|
+
# === email@example.com Enabled Features
|
18
|
+
# sumo-rankings: Heroku Sumo ranks and visualizes the scale of your app, and suggests the optimum combination of dynos and add-ons to take it to the next level.
|
19
|
+
#
|
20
|
+
def index
|
21
|
+
validate_arguments!
|
22
|
+
|
23
|
+
if app
|
24
|
+
display_features(app, 'enabled', { 'enabled' => true, 'kind' => 'app' })
|
25
|
+
end
|
26
|
+
|
27
|
+
display_features(Heroku::Auth.user, 'enabled', { 'enabled' => true, 'kind' => 'user' })
|
28
|
+
end
|
29
|
+
|
30
|
+
# labs:info FEATURE
|
31
|
+
#
|
32
|
+
# displays additional information about FEATURE
|
33
|
+
#
|
34
|
+
#Example:
|
35
|
+
#
|
36
|
+
# $ heroku labs:info user_env_compile
|
37
|
+
# === user_env_compile
|
38
|
+
# Docs: http://devcenter.heroku.com/articles/labs-user-env-compile
|
39
|
+
# Summary: Add user config vars to the environment during slug compilation
|
40
|
+
#
|
41
|
+
def info
|
42
|
+
unless feature_name = shift_argument
|
43
|
+
error("Usage: heroku labs:info FEATURE\nMust specify FEATURE for info.")
|
44
|
+
end
|
45
|
+
validate_arguments!
|
46
|
+
|
47
|
+
feature_data = api.get_feature(feature_name, app).body
|
48
|
+
styled_header(feature_data['name'])
|
49
|
+
styled_hash({
|
50
|
+
'Summary' => feature_data['summary'],
|
51
|
+
'Docs' => feature_data['docs']
|
52
|
+
})
|
53
|
+
end
|
54
|
+
|
55
|
+
# labs:disable FEATURE
|
56
|
+
#
|
57
|
+
# disables FEATURE on an app
|
58
|
+
#
|
59
|
+
#Example:
|
60
|
+
#
|
61
|
+
# $ heroku labs:disable user_env_compile
|
62
|
+
# Disabling user_env_compile for myapp... done
|
63
|
+
#
|
64
|
+
def disable
|
65
|
+
unless feature_name = shift_argument
|
66
|
+
error("Usage: heroku labs:disable FEATURE\nMust specify FEATURE to disable.")
|
67
|
+
end
|
68
|
+
validate_arguments!
|
69
|
+
|
70
|
+
message = "Disabling #{feature_name}"
|
71
|
+
message += " for #{app}" if app
|
72
|
+
action(message) do
|
73
|
+
api.delete_feature(feature_name, app)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
# labs:enable FEATURE
|
78
|
+
#
|
79
|
+
# enables FEATURE on an app
|
80
|
+
#
|
81
|
+
#Example:
|
82
|
+
#
|
83
|
+
# $ heroku labs:enable user_env_compile
|
84
|
+
# Enabling user_env_compile for myapp... done
|
85
|
+
# For more information see: http://devcenter.heroku.com/articles/labs-user-env-compile
|
86
|
+
#
|
87
|
+
def enable
|
88
|
+
unless feature_name = shift_argument
|
89
|
+
error("Usage: heroku labs:enable FEATURE\nMust specify FEATURE to enable.")
|
90
|
+
end
|
91
|
+
validate_arguments!
|
92
|
+
|
93
|
+
message = "Enabling #{feature_name}"
|
94
|
+
message += " for #{app}" if app
|
95
|
+
feature_data = nil
|
96
|
+
action(message) do
|
97
|
+
feature_data = api.post_feature(feature_name, app).body
|
98
|
+
end
|
99
|
+
display("WARNING: This feature is experimental and may change or be removed without notice.")
|
100
|
+
display("For more information see: #{feature_data['docs']}")
|
101
|
+
end
|
102
|
+
|
103
|
+
# labs:list
|
104
|
+
#
|
105
|
+
# lists available features
|
106
|
+
#
|
107
|
+
#Example:
|
108
|
+
#
|
109
|
+
# $ heroku labs:list
|
110
|
+
# === App Available Features
|
111
|
+
# dot-profile: Source .profile during dyno startup
|
112
|
+
# preboot: Provide seamless deploys by booting web dynos with new code before killing existing web dynos.
|
113
|
+
# user_env_compile: Add user config vars to the environment during slug compilation
|
114
|
+
#
|
115
|
+
# === User Available Features
|
116
|
+
# default-heroku-postgresql-dev: Use the new heroku-postgresql:dev add-on as the default database for Cedar apps.
|
117
|
+
#
|
118
|
+
def list
|
119
|
+
validate_arguments!
|
120
|
+
|
121
|
+
display_features('App', 'available', { 'kind' => 'app' })
|
122
|
+
display_features('User', 'available', { 'kind' => 'user' })
|
123
|
+
end
|
124
|
+
|
125
|
+
private
|
126
|
+
|
127
|
+
def app
|
128
|
+
# app is not required for these commands, so rescue if there is none
|
129
|
+
super
|
130
|
+
rescue Heroku::Command::CommandFailed
|
131
|
+
nil
|
132
|
+
end
|
133
|
+
|
134
|
+
def display_features(type, status, attributes)
|
135
|
+
@features ||= api.get_features(app).body
|
136
|
+
|
137
|
+
selected_features = @features.dup
|
138
|
+
attributes.each do |key, value|
|
139
|
+
selected_features = selected_features.select {|feature| feature[key] == value}
|
140
|
+
end
|
141
|
+
|
142
|
+
feature_hash = {}
|
143
|
+
selected_features.each do |feature|
|
144
|
+
feature_hash[feature['name']] = feature['summary']
|
145
|
+
end
|
146
|
+
|
147
|
+
if feature_hash.empty?
|
148
|
+
case status
|
149
|
+
when 'available'
|
150
|
+
display("There are no #{type} features available.")
|
151
|
+
when 'enabled'
|
152
|
+
display("#{type} has no enabled features.")
|
153
|
+
end
|
154
|
+
else
|
155
|
+
styled_header("#{type} #{status.capitalize} Features")
|
156
|
+
styled_hash(feature_hash)
|
157
|
+
display
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
end
|