engineyard 1.3.1 → 1.3.2
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/engineyard.rb +1 -0
- data/lib/engineyard/api.rb +4 -12
- data/lib/engineyard/cli.rb +29 -23
- data/lib/engineyard/cli/recipes.rb +9 -3
- data/lib/engineyard/cli/ui.rb +1 -1
- data/lib/engineyard/cli/web.rb +6 -4
- data/lib/engineyard/collection/abstract.rb +8 -2
- data/lib/engineyard/error.rb +15 -17
- data/lib/engineyard/model.rb +6 -5
- data/lib/engineyard/model/account.rb +8 -0
- data/lib/engineyard/model/app.rb +2 -1
- data/lib/engineyard/model/environment.rb +2 -1
- data/lib/engineyard/repo.rb +5 -1
- data/lib/engineyard/resolver.rb +122 -0
- data/lib/engineyard/thor.rb +16 -20
- data/lib/engineyard/version.rb +1 -1
- data/spec/engineyard/api_spec.rb +0 -30
- data/spec/engineyard/resolver_spec.rb +116 -0
- data/spec/ey/deploy_spec.rb +10 -9
- data/spec/ey/list_environments_spec.rb +1 -0
- data/spec/ey/logs_spec.rb +4 -3
- data/spec/ey/rebuild_spec.rb +3 -2
- data/spec/ey/recipes/apply_spec.rb +3 -2
- data/spec/ey/recipes/download_spec.rb +11 -3
- data/spec/ey/recipes/upload_spec.rb +3 -2
- data/spec/ey/rollback_spec.rb +3 -3
- data/spec/ey/ssh_spec.rb +10 -8
- data/spec/ey/web/disable_spec.rb +3 -3
- data/spec/ey/web/enable_spec.rb +3 -3
- data/spec/spec_helper.rb +4 -1
- data/spec/support/fake_awsm.ru +47 -3
- data/spec/support/git_repo.rb +27 -14
- data/spec/support/helpers.rb +5 -0
- data/spec/support/shared_behavior.rb +92 -12
- metadata +18 -28
data/lib/engineyard.rb
CHANGED
data/lib/engineyard/api.rb
CHANGED
@@ -30,20 +30,12 @@ module EY
|
|
30
30
|
@apps ||= EY::Model::App.from_array(request('/apps')["apps"], :api => self)
|
31
31
|
end
|
32
32
|
|
33
|
-
def
|
34
|
-
|
33
|
+
def resolver
|
34
|
+
@resolver ||= Resolver.new(self)
|
35
35
|
end
|
36
36
|
|
37
|
-
def
|
38
|
-
|
39
|
-
if candidates.size > 1
|
40
|
-
raise EY::AmbiguousGitUriError.new(repo.urls, candidates.map{|x| x.name})
|
41
|
-
end
|
42
|
-
candidates.first
|
43
|
-
end
|
44
|
-
|
45
|
-
def app_for_repo!(repo)
|
46
|
-
app_for_repo(repo) || raise(NoAppError.new(repo))
|
37
|
+
def apps_for_repo(repo)
|
38
|
+
apps.find_all {|a| repo.urls.include?(a.repository_uri) }
|
47
39
|
end
|
48
40
|
|
49
41
|
class InvalidCredentials < EY::Error; end
|
data/lib/engineyard/cli.rb
CHANGED
@@ -44,13 +44,14 @@ module EY
|
|
44
44
|
:desc => "Git ref to deploy. May be a branch, a tag, or a SHA."
|
45
45
|
method_option :app, :type => :string, :aliases => %w(-a),
|
46
46
|
:desc => "Name of the application to deploy"
|
47
|
+
method_option :account, :type => :string, :aliases => %w(-c),
|
48
|
+
:desc => "Name of the account you want to deploy in"
|
47
49
|
method_option :verbose, :type => :boolean, :aliases => %w(-v),
|
48
50
|
:desc => "Be verbose"
|
49
51
|
method_option :extra_deploy_hook_options, :type => :hash, :default => {},
|
50
52
|
:desc => "Additional options to be made available in deploy hooks (in the 'config' hash)"
|
51
53
|
def deploy
|
52
|
-
app
|
53
|
-
environment = fetch_environment(options[:environment], app)
|
54
|
+
app, environment = fetch_app_and_environment(options[:app], options[:environment], options[:account])
|
54
55
|
environment.ignore_bad_master = options[:ignore_bad_master]
|
55
56
|
deploy_ref = if options[:app]
|
56
57
|
environment.resolve_branch(options[:ref], options[:ignore_default_branch]) ||
|
@@ -90,8 +91,8 @@ module EY
|
|
90
91
|
def environments
|
91
92
|
if options[:all] && options[:simple]
|
92
93
|
# just put each env
|
93
|
-
api.environments.each do |
|
94
|
-
puts
|
94
|
+
api.environments.each do |environment|
|
95
|
+
puts environment.name
|
95
96
|
end
|
96
97
|
else
|
97
98
|
apps = get_apps(options[:all])
|
@@ -120,10 +121,12 @@ module EY
|
|
120
121
|
|
121
122
|
method_option :environment, :type => :string, :aliases => %w(-e),
|
122
123
|
:desc => "Environment to rebuild"
|
124
|
+
method_option :account, :type => :string, :aliases => %w(-c),
|
125
|
+
:desc => "Name of the account you want to rebuild in"
|
123
126
|
def rebuild
|
124
|
-
|
125
|
-
EY.ui.debug("Rebuilding #{
|
126
|
-
|
127
|
+
environment = fetch_environment(options[:environment], options[:account])
|
128
|
+
EY.ui.debug("Rebuilding #{environment.name}")
|
129
|
+
environment.rebuild
|
127
130
|
end
|
128
131
|
|
129
132
|
desc "rollback [--environment ENVIRONMENT]", "Rollback to the previous deploy."
|
@@ -136,18 +139,17 @@ module EY
|
|
136
139
|
:desc => "Environment in which to roll back the application"
|
137
140
|
method_option :app, :type => :string, :aliases => %w(-a),
|
138
141
|
:desc => "Name of the application to roll back"
|
142
|
+
method_option :account, :type => :string, :aliases => %w(-c),
|
143
|
+
:desc => "Name of the account you want to roll back in"
|
139
144
|
method_option :verbose, :type => :boolean, :aliases => %w(-v),
|
140
145
|
:desc => "Be verbose"
|
141
146
|
method_option :extra_deploy_hook_options, :type => :hash, :default => {},
|
142
147
|
:desc => "Additional options to be made available in deploy hooks (in the 'config' hash)"
|
143
148
|
def rollback
|
144
|
-
app =
|
145
|
-
env = fetch_environment(options[:environment], app)
|
149
|
+
app, environment = fetch_app_and_environment(options[:app], options[:environment], options[:account])
|
146
150
|
|
147
|
-
EY.ui.info("Rolling back '#{app.name}' in '#{
|
148
|
-
if
|
149
|
-
options[:extra_deploy_hook_options],
|
150
|
-
options[:verbose])
|
151
|
+
EY.ui.info("Rolling back '#{app.name}' in '#{environment.name}'")
|
152
|
+
if environment.rollback(app, options[:extra_deploy_hook_options], options[:verbose])
|
151
153
|
EY.ui.info "Rollback complete"
|
152
154
|
else
|
153
155
|
raise EY::Error, "Rollback failed"
|
@@ -167,6 +169,8 @@ module EY
|
|
167
169
|
DESC
|
168
170
|
method_option :environment, :type => :string, :aliases => %w(-e),
|
169
171
|
:desc => "Environment to ssh into"
|
172
|
+
method_option :account, :type => :string, :aliases => %w(-c),
|
173
|
+
:desc => "Name of the account you want to deploy in"
|
170
174
|
method_option :all, :type => :boolean, :aliases => %(-a),
|
171
175
|
:desc => "Run command on all servers"
|
172
176
|
method_option :app_servers, :type => :boolean,
|
@@ -181,13 +185,13 @@ module EY
|
|
181
185
|
:desc => "Run command on the utility servers with the given names. If no names are given, run on all utility servers."
|
182
186
|
|
183
187
|
def ssh(cmd=nil)
|
184
|
-
|
185
|
-
hosts = ssh_hosts(options,
|
188
|
+
environment = fetch_environment(options[:environment], options[:account])
|
189
|
+
hosts = ssh_hosts(options, environment)
|
186
190
|
|
187
191
|
raise NoCommandError.new if cmd.nil? and hosts.count != 1
|
188
192
|
|
189
193
|
hosts.each do |host|
|
190
|
-
system "ssh #{
|
194
|
+
system "ssh #{environment.username}@#{host} #{cmd}"
|
191
195
|
end
|
192
196
|
end
|
193
197
|
|
@@ -203,7 +207,7 @@ module EY
|
|
203
207
|
return lambda {|instance| %w(solo app_master ).include?(instance.role) }
|
204
208
|
end
|
205
209
|
|
206
|
-
def ssh_hosts(opts,
|
210
|
+
def ssh_hosts(opts, environment)
|
207
211
|
if opts[:utilities] and not opts[:utilities].respond_to?(:include?)
|
208
212
|
includes_everything = []
|
209
213
|
class << includes_everything
|
@@ -214,8 +218,8 @@ module EY
|
|
214
218
|
filter = ssh_host_filter(opts)
|
215
219
|
end
|
216
220
|
|
217
|
-
instances =
|
218
|
-
raise NoInstancesError.new(
|
221
|
+
instances = environment.instances.select {|instance| filter[instance] }
|
222
|
+
raise NoInstancesError.new(environment.name) if instances.empty?
|
219
223
|
return instances.map { |instance| instance.public_hostname }
|
220
224
|
end
|
221
225
|
end
|
@@ -228,18 +232,20 @@ module EY
|
|
228
232
|
DESC
|
229
233
|
method_option :environment, :type => :string, :aliases => %w(-e),
|
230
234
|
:desc => "Environment with the interesting logs"
|
235
|
+
method_option :account, :type => :string, :aliases => %w(-c),
|
236
|
+
:desc => "Name of the account you want to deploy in"
|
231
237
|
def logs
|
232
|
-
|
233
|
-
|
238
|
+
environment = fetch_environment(options[:environment], options[:account])
|
239
|
+
environment.logs.each do |log|
|
234
240
|
EY.ui.info log.instance_name
|
235
241
|
|
236
242
|
if log.main
|
237
|
-
EY.ui.info "Main logs for #{
|
243
|
+
EY.ui.info "Main logs for #{environment.name}:"
|
238
244
|
EY.ui.say log.main
|
239
245
|
end
|
240
246
|
|
241
247
|
if log.custom
|
242
|
-
EY.ui.info "Custom logs for #{
|
248
|
+
EY.ui.info "Custom logs for #{environment.name}:"
|
243
249
|
EY.ui.say log.custom
|
244
250
|
end
|
245
251
|
end
|
@@ -10,8 +10,10 @@ module EY
|
|
10
10
|
|
11
11
|
method_option :environment, :type => :string, :aliases => %w(-e),
|
12
12
|
:desc => "Environment in which to apply recipes"
|
13
|
+
method_option :account, :type => :string, :aliases => %w(-c),
|
14
|
+
:desc => "Name of the account you want to deploy in"
|
13
15
|
def apply
|
14
|
-
environment =
|
16
|
+
environment = fetch_environment(options[:environment], options[:account])
|
15
17
|
environment.run_custom_recipes
|
16
18
|
EY.ui.say "Uploaded recipes started for #{environment.name}"
|
17
19
|
end
|
@@ -25,8 +27,10 @@ module EY
|
|
25
27
|
|
26
28
|
method_option :environment, :type => :string, :aliases => %w(-e),
|
27
29
|
:desc => "Environment that will receive the recipes"
|
30
|
+
method_option :account, :type => :string, :aliases => %w(-c),
|
31
|
+
:desc => "Name of the account you want to deploy in"
|
28
32
|
def upload
|
29
|
-
environment =
|
33
|
+
environment = fetch_environment(options[:environment], options[:account])
|
30
34
|
environment.upload_recipes
|
31
35
|
EY.ui.say "Recipes uploaded successfully for #{environment.name}"
|
32
36
|
end
|
@@ -41,8 +45,10 @@ module EY
|
|
41
45
|
DESC
|
42
46
|
method_option :environment, :type => :string, :aliases => %w(-e),
|
43
47
|
:desc => "Environment for which to download the recipes"
|
48
|
+
method_option :account, :type => :string, :aliases => %w(-c),
|
49
|
+
:desc => "Name of the account you want to deploy in"
|
44
50
|
def download
|
45
|
-
environment =
|
51
|
+
environment = fetch_environment(options[:environment], options[:account])
|
46
52
|
environment.download_recipes
|
47
53
|
EY.ui.say "Recipes downloaded successfully for #{environment.name}"
|
48
54
|
end
|
data/lib/engineyard/cli/ui.rb
CHANGED
data/lib/engineyard/cli/web.rb
CHANGED
@@ -9,9 +9,10 @@ module EY
|
|
9
9
|
:desc => "Name of the application whose maintenance page will be removed"
|
10
10
|
method_option :verbose, :type => :boolean, :aliases => %w(-v),
|
11
11
|
:desc => "Be verbose"
|
12
|
+
method_option :account, :type => :string, :aliases => %w(-c),
|
13
|
+
:desc => "Name of the account you want to deploy in"
|
12
14
|
def enable
|
13
|
-
app
|
14
|
-
environment = fetch_environment(options[:environment], app)
|
15
|
+
app, environment = fetch_app_and_environment(options[:app], options[:environment], options[:account])
|
15
16
|
EY.ui.info "Taking down maintenance page for '#{app.name}' in '#{environment.name}'"
|
16
17
|
environment.take_down_maintenance_page(app, options[:verbose])
|
17
18
|
end
|
@@ -35,9 +36,10 @@ module EY
|
|
35
36
|
:desc => "Name of the application whose maintenance page will be put up"
|
36
37
|
method_option :verbose, :type => :boolean, :aliases => %w(-v),
|
37
38
|
:desc => "Be verbose"
|
39
|
+
method_option :account, :type => :string, :aliases => %w(-c),
|
40
|
+
:desc => "Name of the account you want to deploy in"
|
38
41
|
def disable
|
39
|
-
app
|
40
|
-
environment = fetch_environment(options[:environment], app)
|
42
|
+
app, environment = fetch_app_and_environment(options[:app], options[:environment], options[:account])
|
41
43
|
EY.ui.info "Putting up maintenance page for '#{app.name}' in '#{environment.name}'"
|
42
44
|
environment.put_up_maintenance_page(app, options[:verbose])
|
43
45
|
end
|
@@ -8,8 +8,14 @@ module EY
|
|
8
8
|
We are working on letting you specify the account name to resolve this ambiguity.
|
9
9
|
MSG
|
10
10
|
|
11
|
-
def named(name)
|
12
|
-
candidates = find_all
|
11
|
+
def named(name, account_name=nil)
|
12
|
+
candidates = find_all do |x|
|
13
|
+
if account_name
|
14
|
+
x.name == name && x.account.name == account_name
|
15
|
+
else
|
16
|
+
x.name == name
|
17
|
+
end
|
18
|
+
end
|
13
19
|
if candidates.size > 1
|
14
20
|
raise ambiguous_error(name, candidates.map {|e| e.name}, COLLAB_MESSAGE )
|
15
21
|
end
|
data/lib/engineyard/error.rb
CHANGED
@@ -7,6 +7,10 @@ module EY
|
|
7
7
|
end
|
8
8
|
end
|
9
9
|
|
10
|
+
class ResolveError < EY::Error; end
|
11
|
+
class NoMatchesError < ResolveError; end
|
12
|
+
class MultipleMatchesError < ResolveError; end
|
13
|
+
|
10
14
|
class NoCommandError < EY::Error
|
11
15
|
def initialize
|
12
16
|
super "Must specify a command to run via ssh"
|
@@ -41,18 +45,6 @@ module EY
|
|
41
45
|
end
|
42
46
|
end
|
43
47
|
|
44
|
-
class AmbiguousGitUriError < EY::Error
|
45
|
-
def initialize(uris, matches)
|
46
|
-
message = "The following Git Remote urls match multiple Applications in AppCloud\n"
|
47
|
-
uris.each { |uri| message << "\t#{uri}\n" }
|
48
|
-
|
49
|
-
message << "Please use -a <appname> to specify one of the following applications:\n"
|
50
|
-
matches.each { |app| message << "\t#{app}\n" }
|
51
|
-
|
52
|
-
super message
|
53
|
-
end
|
54
|
-
end
|
55
|
-
|
56
48
|
class NoAppMasterError < EY::Error
|
57
49
|
def initialize(env_name)
|
58
50
|
super "The environment '#{env_name}' does not have a master instance."
|
@@ -84,7 +76,13 @@ module EY
|
|
84
76
|
def initialize(environments)
|
85
77
|
message = "The repository url in this directory is ambiguous.\n"
|
86
78
|
message << "Please use -e <envname> to specify one of the following environments:\n"
|
87
|
-
environments.
|
79
|
+
environments.sort do |a, b|
|
80
|
+
if a.account == b.account
|
81
|
+
a.name <=> b.name
|
82
|
+
else
|
83
|
+
a.account.name <=> b.account.name
|
84
|
+
end
|
85
|
+
end.each { |env| message << "\t#{env.name} (#{env.account.name})\n" }
|
88
86
|
super message
|
89
87
|
end
|
90
88
|
end
|
@@ -110,15 +108,15 @@ module EY
|
|
110
108
|
|
111
109
|
class BranchMismatchError < EY::Error
|
112
110
|
def initialize(default_branch, branch)
|
113
|
-
super
|
114
|
-
%|If you want to deploy branch "#{branch}", use --ignore-default_branch.|
|
111
|
+
super(%|Your deploy branch is set to "#{default_branch}".\n| +
|
112
|
+
%|If you want to deploy branch "#{branch}", use --ignore-default_branch.|)
|
115
113
|
end
|
116
114
|
end
|
117
115
|
|
118
116
|
class DeployArgumentError < EY::Error
|
119
117
|
def initialize
|
120
|
-
super
|
121
|
-
%|You can set default environments and branches in ey.yml|
|
118
|
+
super(%("deploy" was called incorrectly. Call as "deploy [--environment <env>] [--ref <branch|tag|ref>]"\n) +
|
119
|
+
%|You can set default environments and branches in ey.yml|)
|
122
120
|
end
|
123
121
|
end
|
124
122
|
end
|
data/lib/engineyard/model.rb
CHANGED
@@ -1,9 +1,10 @@
|
|
1
1
|
module EY
|
2
2
|
module Model
|
3
|
-
autoload :ApiStruct,
|
4
|
-
autoload :
|
5
|
-
autoload :
|
6
|
-
autoload :
|
7
|
-
autoload :
|
3
|
+
autoload :ApiStruct, 'engineyard/model/api_struct'
|
4
|
+
autoload :Account, 'engineyard/model/account'
|
5
|
+
autoload :App, 'engineyard/model/app'
|
6
|
+
autoload :Environment, 'engineyard/model/environment'
|
7
|
+
autoload :Log, 'engineyard/model/log'
|
8
|
+
autoload :Instance, 'engineyard/model/instance'
|
8
9
|
end
|
9
10
|
end
|
data/lib/engineyard/model/app.rb
CHANGED
@@ -1,10 +1,11 @@
|
|
1
1
|
module EY
|
2
2
|
module Model
|
3
|
-
class App < ApiStruct.new(:name, :repository_uri, :environments, :api)
|
3
|
+
class App < ApiStruct.new(:id, :account, :name, :repository_uri, :environments, :api)
|
4
4
|
|
5
5
|
def self.from_hash(hash)
|
6
6
|
super.tap do |app|
|
7
7
|
app.environments = Environment.from_array(app.environments, :api => app.api)
|
8
|
+
app.account = Account.from_hash(app.account)
|
8
9
|
end
|
9
10
|
end
|
10
11
|
|
@@ -1,6 +1,6 @@
|
|
1
1
|
module EY
|
2
2
|
module Model
|
3
|
-
class Environment < ApiStruct.new(:id, :name, :framework_env, :instances, :instances_count, :apps, :app_master, :username, :stack_name, :api)
|
3
|
+
class Environment < ApiStruct.new(:id, :account, :name, :framework_env, :instances, :instances_count, :apps, :app_master, :username, :stack_name, :api)
|
4
4
|
|
5
5
|
attr_accessor :ignore_bad_master
|
6
6
|
|
@@ -8,6 +8,7 @@ module EY
|
|
8
8
|
super.tap do |env|
|
9
9
|
env.username = hash['ssh_username']
|
10
10
|
env.apps = App.from_array(env.apps, :api => env.api)
|
11
|
+
env.account = Account.from_hash(env.account)
|
11
12
|
env.instances = Instance.from_array(hash['instances'], :environment => env)
|
12
13
|
env.app_master = Instance.from_hash(env.app_master.merge(:environment => env)) if env.app_master
|
13
14
|
end
|
data/lib/engineyard/repo.rb
CHANGED
@@ -7,8 +7,12 @@ module EY
|
|
7
7
|
@path = path
|
8
8
|
end
|
9
9
|
|
10
|
+
def exists?
|
11
|
+
File.directory?(File.join(@path, ".git"))
|
12
|
+
end
|
13
|
+
|
10
14
|
def current_branch
|
11
|
-
if
|
15
|
+
if exists?
|
12
16
|
head = File.read(File.join(@path, ".git/HEAD")).chomp
|
13
17
|
if head.gsub!("ref: refs/heads/", "")
|
14
18
|
head
|
@@ -0,0 +1,122 @@
|
|
1
|
+
module EY
|
2
|
+
class Resolver
|
3
|
+
attr_reader :api
|
4
|
+
|
5
|
+
def initialize(api)
|
6
|
+
@api = api
|
7
|
+
end
|
8
|
+
|
9
|
+
def environment(options)
|
10
|
+
raise ArgumentError if options[:app_name]
|
11
|
+
candidates, account_candidates, app_candidates, environment_candidates = filter_candidates(options)
|
12
|
+
|
13
|
+
environments = candidates.map{ |c| [c[:account_name], c[:environment_name]] }.uniq.map do |account_name, environment_name|
|
14
|
+
api.environments.named(environment_name, account_name)
|
15
|
+
end
|
16
|
+
|
17
|
+
if environments.empty?
|
18
|
+
if options[:environment_name]
|
19
|
+
raise EY::NoEnvironmentError.new(options[:environment_name])
|
20
|
+
else
|
21
|
+
raise EY::NoAppError.new(options[:repo])
|
22
|
+
end
|
23
|
+
elsif environments.size > 1
|
24
|
+
if options[:environment_name]
|
25
|
+
message = "Multiple environments possible, please be more specific:\n\n"
|
26
|
+
candidates.map{|e| [e[:account_name], e[:environment_name]]}.uniq.each do |account_name, environment_name|
|
27
|
+
message << "\t#{environment_name} # ey <command> --environment='#{environment_name}' --account='#{account_name}'\n"
|
28
|
+
end
|
29
|
+
raise MultipleMatchesError.new(message)
|
30
|
+
else
|
31
|
+
raise EY::AmbiguousEnvironmentGitUriError.new(environments)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
environments.first
|
35
|
+
end
|
36
|
+
|
37
|
+
def app_and_environment(options)
|
38
|
+
candidates, account_candidates, app_candidates, environment_candidates = filter_candidates(options)
|
39
|
+
|
40
|
+
if candidates.empty?
|
41
|
+
if account_candidates.empty? && options[:account_name]
|
42
|
+
raise NoMatchesError.new("There were no accounts that matched #{options[:account_name]}")
|
43
|
+
elsif app_candidates.empty?
|
44
|
+
if options[:app_name]
|
45
|
+
raise InvalidAppError.new(options[:app_name])
|
46
|
+
else
|
47
|
+
raise NoAppError.new(options[:repo])
|
48
|
+
end
|
49
|
+
elsif environment_candidates.empty?
|
50
|
+
raise NoEnvironmentError.new(options[:environment_name])
|
51
|
+
else
|
52
|
+
message = "The matched apps & environments do not correspond with each other.\n"
|
53
|
+
message << "Applications:\n"
|
54
|
+
app_candidates.map{|ad| [ad[:account_name], ad[:app_name]]}.uniq.each do |account_name, app_name|
|
55
|
+
app = api.apps.named(app_name, account_name)
|
56
|
+
message << "\t#{app.name}\n"
|
57
|
+
app.environments.each do |env|
|
58
|
+
message << "\t\t#{env.name} # ey <command> -e #{env.name} -a #{app.name}\n"
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
raise NoMatchesError.new(message)
|
63
|
+
elsif candidates.size > 1
|
64
|
+
message = "Multiple app deployments possible, please be more specific:\n\n"
|
65
|
+
candidates.map{|c| [c[:account_name], c[:app_name]]}.uniq.each do |account_name, app_name|
|
66
|
+
message << "#{app_name}\n"
|
67
|
+
candidates.select {|x| x[:app_name] == app_name && x[:account_name] == account_name}.map{|x| x[:environment_name]}.uniq.each do |env_name|
|
68
|
+
message << "\t#{env_name} # ey <command> --environment='#{env_name}' --app='#{app_name}' --account='#{account_name}'\n"
|
69
|
+
end
|
70
|
+
end
|
71
|
+
raise MultipleMatchesError.new(message)
|
72
|
+
end
|
73
|
+
result = candidates.first
|
74
|
+
[api.apps.named(result[:app_name], result[:account_name]), api.environments.named(result[:environment_name], result[:account_name])]
|
75
|
+
end
|
76
|
+
|
77
|
+
private
|
78
|
+
|
79
|
+
def app_deployments
|
80
|
+
@app_deployments ||= api.apps.map do |app|
|
81
|
+
app.environments.map do |environment|
|
82
|
+
{
|
83
|
+
:app_name => app.name,
|
84
|
+
:repository_uri => app.repository_uri,
|
85
|
+
:environment_name => environment.name,
|
86
|
+
:account_name => app.account.name,
|
87
|
+
}
|
88
|
+
end
|
89
|
+
end.flatten
|
90
|
+
end
|
91
|
+
|
92
|
+
def filter_candidates(options)
|
93
|
+
raise ArgumentError if options.empty?
|
94
|
+
|
95
|
+
candidates = app_deployments
|
96
|
+
|
97
|
+
account_candidates = filter_candidates_by(:account_name, options, candidates)
|
98
|
+
|
99
|
+
app_candidates = if options[:app_name]
|
100
|
+
filter_candidates_by(:app_name, options, candidates)
|
101
|
+
elsif options[:repo]
|
102
|
+
candidates.select {|c| options[:repo].urls.include?(c[:repository_uri]) }
|
103
|
+
else
|
104
|
+
candidates
|
105
|
+
end
|
106
|
+
|
107
|
+
environment_candidates = filter_candidates_by(:environment_name, options, candidates)
|
108
|
+
candidates = app_candidates & environment_candidates & account_candidates
|
109
|
+
[candidates, account_candidates, app_candidates, environment_candidates]
|
110
|
+
end
|
111
|
+
|
112
|
+
def filter_candidates_by(type, options, candidates)
|
113
|
+
if options[type] && candidates.any?{|c| c[type] == options[type] }
|
114
|
+
candidates.select {|c| c[type] == options[type] }
|
115
|
+
elsif options[type]
|
116
|
+
candidates.select {|c| c[type][options[type]] }
|
117
|
+
else
|
118
|
+
candidates
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|