engineyard 1.3.1 → 1.3.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|