skylight 5.0.0.beta4 → 5.1.0.beta2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (80) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +399 -362
  3. data/CLA.md +1 -1
  4. data/CONTRIBUTING.md +1 -1
  5. data/LICENSE.md +7 -17
  6. data/README.md +1 -1
  7. data/ext/extconf.rb +42 -54
  8. data/ext/libskylight.yml +10 -5
  9. data/lib/skylight.rb +20 -30
  10. data/lib/skylight/api.rb +22 -18
  11. data/lib/skylight/cli.rb +47 -46
  12. data/lib/skylight/cli/doctor.rb +50 -50
  13. data/lib/skylight/cli/helpers.rb +19 -19
  14. data/lib/skylight/cli/merger.rb +141 -139
  15. data/lib/skylight/config.rb +267 -310
  16. data/lib/skylight/deprecation.rb +4 -4
  17. data/lib/skylight/errors.rb +3 -4
  18. data/lib/skylight/extensions.rb +17 -29
  19. data/lib/skylight/extensions/source_location.rb +128 -128
  20. data/lib/skylight/formatters/http.rb +1 -3
  21. data/lib/skylight/gc.rb +30 -40
  22. data/lib/skylight/helpers.rb +57 -30
  23. data/lib/skylight/instrumenter.rb +25 -18
  24. data/lib/skylight/middleware.rb +31 -35
  25. data/lib/skylight/native.rb +8 -10
  26. data/lib/skylight/native_ext_fetcher.rb +10 -12
  27. data/lib/skylight/normalizers.rb +43 -38
  28. data/lib/skylight/normalizers/action_controller/process_action.rb +24 -25
  29. data/lib/skylight/normalizers/action_controller/send_file.rb +7 -6
  30. data/lib/skylight/normalizers/action_dispatch/route_set.rb +7 -7
  31. data/lib/skylight/normalizers/active_job/perform.rb +48 -44
  32. data/lib/skylight/normalizers/active_model_serializers/render.rb +7 -3
  33. data/lib/skylight/normalizers/active_storage.rb +11 -13
  34. data/lib/skylight/normalizers/active_support/cache.rb +1 -12
  35. data/lib/skylight/normalizers/coach/handler_finish.rb +1 -3
  36. data/lib/skylight/normalizers/default.rb +1 -9
  37. data/lib/skylight/normalizers/faraday/request.rb +1 -3
  38. data/lib/skylight/normalizers/grape/endpoint.rb +13 -19
  39. data/lib/skylight/normalizers/grape/endpoint_run.rb +16 -18
  40. data/lib/skylight/normalizers/grape/endpoint_run_filters.rb +1 -3
  41. data/lib/skylight/normalizers/graphql/base.rb +23 -28
  42. data/lib/skylight/normalizers/render.rb +19 -21
  43. data/lib/skylight/normalizers/shrine.rb +32 -0
  44. data/lib/skylight/normalizers/sql.rb +4 -4
  45. data/lib/skylight/probes.rb +38 -46
  46. data/lib/skylight/probes/action_controller.rb +32 -28
  47. data/lib/skylight/probes/action_dispatch/request_id.rb +9 -5
  48. data/lib/skylight/probes/action_dispatch/routing/route_set.rb +7 -5
  49. data/lib/skylight/probes/action_view.rb +9 -10
  50. data/lib/skylight/probes/active_job_enqueue.rb +3 -9
  51. data/lib/skylight/probes/active_model_serializers.rb +8 -8
  52. data/lib/skylight/probes/delayed_job.rb +37 -42
  53. data/lib/skylight/probes/elasticsearch.rb +4 -6
  54. data/lib/skylight/probes/excon.rb +1 -1
  55. data/lib/skylight/probes/excon/middleware.rb +22 -23
  56. data/lib/skylight/probes/graphql.rb +2 -7
  57. data/lib/skylight/probes/middleware.rb +14 -5
  58. data/lib/skylight/probes/mongo.rb +83 -91
  59. data/lib/skylight/probes/net_http.rb +1 -1
  60. data/lib/skylight/probes/redis.rb +5 -17
  61. data/lib/skylight/probes/sequel.rb +7 -11
  62. data/lib/skylight/probes/sinatra.rb +8 -5
  63. data/lib/skylight/probes/tilt.rb +2 -4
  64. data/lib/skylight/railtie.rb +121 -135
  65. data/lib/skylight/sidekiq.rb +4 -5
  66. data/lib/skylight/subscriber.rb +31 -33
  67. data/lib/skylight/test.rb +89 -84
  68. data/lib/skylight/trace.rb +121 -115
  69. data/lib/skylight/user_config.rb +14 -17
  70. data/lib/skylight/util/clock.rb +1 -0
  71. data/lib/skylight/util/component.rb +18 -21
  72. data/lib/skylight/util/deploy.rb +11 -13
  73. data/lib/skylight/util/http.rb +104 -105
  74. data/lib/skylight/util/logging.rb +4 -6
  75. data/lib/skylight/util/lru_cache.rb +2 -6
  76. data/lib/skylight/util/platform.rb +2 -6
  77. data/lib/skylight/util/ssl.rb +1 -25
  78. data/lib/skylight/version.rb +1 -1
  79. data/lib/skylight/vm/gc.rb +1 -9
  80. metadata +20 -5
@@ -25,7 +25,8 @@ module Skylight
25
25
  say "Alternatively, try setting `SKYLIGHT_FORCE_OWN_CERTS=1` in your environment.", :yellow
26
26
  else
27
27
  say "Please update your local certificates or try setting `SKYLIGHT_FORCE_OWN_CERTS=1` in your " \
28
- "environment.", :yellow
28
+ "environment.",
29
+ :yellow
29
30
  end
30
31
  end
31
32
  else
@@ -66,9 +67,7 @@ module Skylight
66
67
  indent do
67
68
  install_log = File.expand_path("../../ext/install.log", __dir__)
68
69
  if File.exist?(install_log)
69
- File.readlines(install_log).each do |line|
70
- say line, :red
71
- end
70
+ File.readlines(install_log).each { |line| say line, :red }
72
71
  else
73
72
  say "Reason unknown", :red
74
73
  end
@@ -108,13 +107,16 @@ module Skylight
108
107
  indent do
109
108
  # Set this after we validate. It will give us more detailed information on start.
110
109
  logger = Logger.new("/dev/null") # Rely on `say` in the formatter instead
110
+
111
111
  # Log everything
112
112
  logger.level = Logger::DEBUG
113
+
113
114
  # Remove excess formatting
114
- logger.formatter = proc { |severity, _datetime, _progname, msg|
115
- msg = msg.sub("[SKYLIGHT] [#{Skylight::VERSION}] ", "")
116
- say "#{severity} - #{msg}" # Definitely non-standard
117
- }
115
+ logger.formatter =
116
+ proc do |severity, _datetime, _progname, msg|
117
+ msg = msg.sub("[SKYLIGHT] [#{Skylight::VERSION}] ", "")
118
+ say "#{severity} - #{msg}" # Definitely non-standard
119
+ end
118
120
  config.logger = logger
119
121
 
120
122
  config.set(:'daemon.lazy_start', false)
@@ -165,57 +167,55 @@ module Skylight
165
167
 
166
168
  private
167
169
 
168
- # Overwrite the default helper method to load from Rails
169
- def config
170
- return @config if @config
170
+ # Overwrite the default helper method to load from Rails
171
+ def config
172
+ return @config if @config
171
173
 
172
- # MEGAHAX
173
- if rails?
174
- # Normally auto-loaded, but we haven't loaded Rails by the time Skylight is loaded
175
- require "skylight/railtie"
176
- require rails_rb
174
+ # MEGAHAX
175
+ if rails?
176
+ # Normally auto-loaded, but we haven't loaded Rails by the time Skylight is loaded
177
+ require "skylight/railtie"
178
+ require rails_rb
177
179
 
178
- railtie = Skylight::Railtie.send(:new)
179
- @config = railtie.send(:load_skylight_config, Rails.application)
180
- else
181
- super
182
- end
183
- end
184
-
185
- def mac?
186
- Util::Platform::OS == "darwin"
180
+ railtie = Skylight::Railtie.send(:new)
181
+ @config = railtie.send(:load_skylight_config, Rails.application)
182
+ else
183
+ super
187
184
  end
185
+ end
188
186
 
189
- # NOTE: This check won't work correctly on Windows
190
- def rvm_present?
191
- if @has_rvm.nil?
192
- @has_rvm = system("which rvm > /dev/null")
193
- end
194
- @has_rvm
195
- end
187
+ def mac?
188
+ Util::Platform::OS == "darwin"
189
+ end
196
190
 
197
- def encountered_error!
198
- @has_errors = true
199
- end
191
+ # NOTE: This check won't work correctly on Windows
192
+ def rvm_present?
193
+ @has_rvm = system("which rvm > /dev/null") if @has_rvm.nil?
194
+ @has_rvm
195
+ end
200
196
 
201
- def has_errors?
202
- @has_errors
203
- end
197
+ def encountered_error!
198
+ @has_errors = true
199
+ end
204
200
 
205
- def done!
206
- shell.padding = 0
207
- say "\n\n"
201
+ def has_errors?
202
+ @has_errors
203
+ end
208
204
 
209
- if has_errors?
210
- say "Skylight Doctor found some errors. Please review the output above.", :red
211
- say "If you have any further questions, please contact support@skylight.io.", :yellow
212
- exit 1
213
- else
214
- say "All checks passed!", :green
215
- say "If you're still having trouble, please contact support@skylight.io.", :yellow
216
- exit 0
217
- end
205
+ def done!
206
+ shell.padding = 0
207
+ say "\n\n"
208
+
209
+ if has_errors?
210
+ say "Skylight Doctor found some errors. Please review the output above.", :red
211
+ say "If you have any further questions, please contact support@skylight.io.", :yellow
212
+ exit 1
213
+ else
214
+ say "All checks passed!", :green
215
+ say "If you're still having trouble, please contact support@skylight.io.", :yellow
216
+ exit 0
218
217
  end
218
+ end
219
219
  end
220
220
  end
221
221
  end
@@ -3,28 +3,28 @@ module Skylight
3
3
  module Helpers
4
4
  private
5
5
 
6
- # Duplicated below
7
- def rails_rb
8
- File.expand_path("config/application.rb")
9
- end
6
+ # Duplicated below
7
+ def rails_rb
8
+ File.expand_path("config/application.rb")
9
+ end
10
10
 
11
- def rails?
12
- File.exist?(rails_rb)
13
- end
11
+ def rails?
12
+ File.exist?(rails_rb)
13
+ end
14
14
 
15
- def config
16
- # Calling .load checks ENV variables
17
- @config ||= Config.load
18
- end
15
+ def config
16
+ # Calling .load checks ENV variables
17
+ @config ||= Config.load
18
+ end
19
19
 
20
- # Sets the output padding while executing a block and resets it.
21
- #
22
- def indent(count = 1)
23
- orig_padding = shell.padding
24
- shell.padding += count
25
- yield
26
- shell.padding = orig_padding
27
- end
20
+ # Sets the output padding while executing a block and resets it.
21
+ #
22
+ def indent(count = 1)
23
+ orig_padding = shell.padding
24
+ shell.padding += count
25
+ yield
26
+ shell.padding = orig_padding
27
+ end
28
28
  end
29
29
  end
30
30
  end
@@ -14,7 +14,7 @@ module Skylight
14
14
 
15
15
  STRINGS = {
16
16
  get_token: "get your merge token from `https://www.skylight.io/merging`",
17
- unlisted: "My app isn't listed here :("
17
+ unlisted: "My app isn't listed here :("
18
18
  }.freeze
19
19
 
20
20
  argument :merge_token, type: :string, desc: STRINGS[:get_token]
@@ -23,8 +23,8 @@ module Skylight
23
23
  say "\nHello! Welcome to the `skylight merge` CLI!\n", :green
24
24
 
25
25
  say "This CLI is for Skylight users who already have Skylight Environments set up\n" \
26
- "using the legacy method of creating a separate Skylight app per environment.\n" \
27
- "Use this CLI to merge legacy environment apps into their parent apps as Environments."
26
+ "using the legacy method of creating a separate Skylight app per environment.\n" \
27
+ "Use this CLI to merge legacy environment apps into their parent apps as Environments."
28
28
  end
29
29
 
30
30
  def fetch_apps
@@ -40,23 +40,24 @@ module Skylight
40
40
  rescue Skylight::Api::Unauthorized
41
41
  done!(
42
42
  success: false,
43
- message: "Provided merge token is invalid.\n" \
44
- "Please #{STRINGS[:get_token]}" \
45
- "and run `skylight merge <merge token>` again."
43
+ message:
44
+ "Provided merge token is invalid.\n" \
45
+ "Please #{STRINGS[:get_token]}" \
46
+ "and run `skylight merge <merge token>` again."
46
47
  )
47
48
  end
48
49
 
49
50
  def ask_for_parent_app
50
- @parents ||= begin
51
- a = (@apps + [{ name: STRINGS[:unlisted], components: [], unlisted: true }])
52
- a.each_with_object({}).with_index do |(app, h), i|
53
- h[i + 1] = OpenStruct.new(app)
51
+ @parents ||=
52
+ begin
53
+ a = (@apps + [{ name: STRINGS[:unlisted], components: [], unlisted: true }])
54
+ a.each_with_object({}).with_index { |(app, h), i| h[i + 1] = OpenStruct.new(app) }
54
55
  end
55
- end
56
56
 
57
57
  say "\nLet's begin!\n\n" \
58
- "Please specify the \"parent\" app.\n" \
59
- "In most cases, this will be the production app handling web requests.", :green
58
+ "Please specify the \"parent\" app.\n" \
59
+ "In most cases, this will be the production app handling web requests.",
60
+ :green
60
61
 
61
62
  @parent_app = ask_for_app(@parents)
62
63
  end
@@ -76,8 +77,9 @@ module Skylight
76
77
 
77
78
  def ask_for_child_env
78
79
  say "\nWhat environment is the child app?\n" \
79
- "In many cases, this will be equivalent to the Rails " \
80
- "environment, i.e., `development`.", :green
80
+ "In many cases, this will be equivalent to the Rails " \
81
+ "environment, i.e., `development`.",
82
+ :green
81
83
 
82
84
  say "1. development"
83
85
  say "2. staging"
@@ -85,15 +87,18 @@ module Skylight
85
87
 
86
88
  i = ask("\nWhich number?").chomp.to_i
87
89
 
88
- @child_env = case i
89
- when 1 then "development"
90
- when 2 then "staging"
91
- when 3
92
- specify_child_env
93
- else
94
- say("\nEh? Please enter 1, 2, or 3.", :red)
95
- ask_for_child_env
96
- end
90
+ @child_env =
91
+ case i
92
+ when 1
93
+ "development"
94
+ when 2
95
+ "staging"
96
+ when 3
97
+ specify_child_env
98
+ else
99
+ say("\nEh? Please enter 1, 2, or 3.", :red)
100
+ ask_for_child_env
101
+ end
97
102
  end
98
103
 
99
104
  def confirm_child_env
@@ -102,7 +107,7 @@ module Skylight
102
107
 
103
108
  def confirm_everything
104
109
  say "\nOk! Now we're going to merge `#{set_color(format_component(@child_app), :yellow)}` " \
105
- "into `#{set_color(@parent_app.name, :green)}` as `#{set_color(@child_env, :yellow)}`."
110
+ "into `#{set_color(@parent_app.name, :green)}` as `#{set_color(@child_env, :yellow)}`."
106
111
  end
107
112
 
108
113
  def do_confirm
@@ -112,10 +117,7 @@ module Skylight
112
117
  when "Y", ""
113
118
  do_merge
114
119
  when "N"
115
- done!(
116
- success: true,
117
- message: "Ok, come back any time."
118
- )
120
+ done!(success: true, message: "Ok, come back any time.")
119
121
  else
120
122
  say("Please respond 'Y' to merge or 'n' to cancel.", :red)
121
123
  do_confirm
@@ -128,37 +130,43 @@ module Skylight
128
130
  say "=======================================================\n", :yellow
129
131
 
130
132
  say "IMPORTANT!\n" \
131
- "If you use a config/skylight.yml file to configure Skylight:\n", :yellow
133
+ "If you use a config/skylight.yml file to configure Skylight:\n",
134
+ :yellow
132
135
 
133
136
  say "The #{@child_env} environment for the #{@parent_app.name} app\n" \
134
- "will now connect using the default authentication token for the app.\n" \
135
- "Remove any environment-specific `authentication` configs from the\n" \
136
- "#{@parent_app.name} #{@child_env} environment.\n", :yellow
137
+ "will now connect using the default authentication token for the app.\n" \
138
+ "Remove any environment-specific `authentication` configs from the\n" \
139
+ "#{@parent_app.name} #{@child_env} environment.\n",
140
+ :yellow
137
141
 
138
142
  say "If you're running in Rails and your Rails environment exactly matches `#{@child_env}`,\n" \
139
- "we will automatically detect and report that environment when your agent connects.\n" \
140
- "Otherwise, you should set `env: '#{@child_env}'` as environment-specific configuration for\n" \
141
- "#{@child_env}'s Rails environment. For example:\n" \
142
- "```yml\n" \
143
- "staging:\n" \
144
- " env: staging-42\n" \
145
- "```\n", :yellow
143
+ "we will automatically detect and report that environment when your agent connects.\n" \
144
+ "Otherwise, you should set `env: '#{@child_env}'` as environment-specific configuration for\n" \
145
+ "#{@child_env}'s Rails environment. For example:\n" \
146
+ "```yml\n" \
147
+ "staging:\n" \
148
+ " env: staging-42\n" \
149
+ "```\n",
150
+ :yellow
146
151
 
147
152
  say "=======================================================\n", :yellow
148
153
 
149
154
  say "IMPORTANT!\n" \
150
- "If you configure Skylight using environment variables:\n", :yellow
155
+ "If you configure Skylight using environment variables:\n",
156
+ :yellow
151
157
 
152
158
  say "Deploy the latest agent before updating your environment variables.\n", :yellow
153
159
 
154
160
  say "The #{@child_env} environment for the #{@parent_app.name} app\n" \
155
- "will now connect using the default authentication token for the app.\n" \
156
- "Set `SKYLIGHT_AUTHENTICATION` in the #{@child_env} environment to the\n" \
157
- "#{@parent_app.name} app's authentication token.\n", :yellow
161
+ "will now connect using the default authentication token for the app.\n" \
162
+ "Set `SKYLIGHT_AUTHENTICATION` in the #{@child_env} environment to the\n" \
163
+ "#{@parent_app.name} app's authentication token.\n",
164
+ :yellow
158
165
 
159
166
  say "If you're running in Rails and your Rails environment exactly matches `#{@child_env}`,\n" \
160
- "we will automatically detect and report that environment when your agent connects.\n" \
161
- "Otherwise, you should set `SKYLIGHT_ENV=#{@child_env}` when running in this environment.\n", :yellow
167
+ "we will automatically detect and report that environment when your agent connects.\n" \
168
+ "Otherwise, you should set `SKYLIGHT_ENV=#{@child_env}` when running in this environment.\n",
169
+ :yellow
162
170
 
163
171
  say "=======================================================", :yellow
164
172
 
@@ -167,136 +175,130 @@ module Skylight
167
175
 
168
176
  private
169
177
 
170
- def do_merge
171
- say "Merging..."
178
+ def do_merge
179
+ say "Merging..."
172
180
 
173
- api.merge_apps!(@merge_token,
174
- app_guid: @parent_app.guid,
175
- component_guid: @child_app.guid,
176
- environment: @child_env)
177
- rescue => e
178
- say("Something went wrong. Please contact support@skylight.io for more information.", :red)
179
- done!(message: e.message, success: false)
180
- end
181
+ api.merge_apps!(
182
+ @merge_token,
183
+ app_guid: @parent_app.guid,
184
+ component_guid: @child_app.guid,
185
+ environment: @child_env
186
+ )
187
+ rescue StandardError => e
188
+ say("Something went wrong. Please contact support@skylight.io for more information.", :red)
189
+ done!(message: e.message, success: false)
190
+ end
181
191
 
182
- def done!(message: nil, success: true)
183
- shell.padding = 0
184
- say "\n"
192
+ def done!(message: nil, success: true)
193
+ shell.padding = 0
194
+ say "\n"
185
195
 
186
- if success
187
- say(message, :green) if message
188
- say "If you have any questions, please contact support@skylight.io.", :green
189
- exit 0
190
- else
191
- say message || "Skylight wasn't able to merge your apps.", :red
192
- say "If you have any questions, please contact support@skylight.io.", :yellow
193
- exit 1
194
- end
196
+ if success
197
+ say(message, :green) if message
198
+ say "If you have any questions, please contact support@skylight.io.", :green
199
+ exit 0
200
+ else
201
+ say message || "Skylight wasn't able to merge your apps.", :red
202
+ say "If you have any questions, please contact support@skylight.io.", :yellow
203
+ exit 1
195
204
  end
205
+ end
196
206
 
197
- def ask_for_app(app_list, &formatter)
198
- formatter ||= :name.to_proc
199
- app_list.each do |index, app|
200
- say("\t#{index}. #{formatter.call(app)}")
201
- end
207
+ def ask_for_app(app_list, &formatter)
208
+ formatter ||= :name.to_proc
209
+ app_list.each { |index, app| say("\t#{index}. #{formatter.call(app)}") }
202
210
 
203
- n = ask("\nWhich number?").chomp.to_i
211
+ n = ask("\nWhich number?").chomp.to_i
204
212
 
205
- if !app_list.key?(n)
206
- say "\nHmm?"
207
- ask_for_app(app_list, &formatter)
208
- elsif app_list[n].unlisted
209
- done!(
210
- success: false,
211
- message: "Sorry, `skylight merge` is only able to merge apps that you own."
212
- )
213
- else
214
- app_list[n]
215
- end
213
+ if !app_list.key?(n)
214
+ say "\nHmm?"
215
+ ask_for_app(app_list, &formatter)
216
+ elsif app_list[n].unlisted
217
+ done!(success: false, message: "Sorry, `skylight merge` is only able to merge apps that you own.")
218
+ else
219
+ app_list[n]
216
220
  end
221
+ end
217
222
 
218
- def api
219
- @api ||= Skylight::Api.new(config)
220
- end
223
+ def api
224
+ @api ||= Skylight::Api.new(config)
225
+ end
221
226
 
222
- def format_component(component)
223
- parts = [].tap do |ary|
227
+ def format_component(component)
228
+ parts =
229
+ [].tap do |ary|
224
230
  ary << component.name unless component.name == "web"
225
231
  ary << component.environment unless component.environment == "production"
226
232
  end
227
233
 
228
- str = ""
229
- str << component.app_name
230
- str << Thor::Shell::Color.new.set_color(" (#{parts.join(':')})", :yellow) if parts.any?
231
- str
232
- end
234
+ str = ""
235
+ str << component.app_name
236
+ str << Thor::Shell::Color.new.set_color(" (#{parts.join(":")})", :yellow) if parts.any?
237
+ str
238
+ end
233
239
 
234
- def validate_mergeability(child_app, child_env)
235
- errors = []
240
+ def validate_mergeability(child_app, child_env)
241
+ errors = []
236
242
 
237
- unless valid_component?(child_app.name, child_env)
238
- errors << "Environment can only contain letters, numbers, and hyphens."
239
- end
243
+ unless valid_component?(child_app.name, child_env)
244
+ errors << "Environment can only contain letters, numbers, and hyphens."
245
+ end
240
246
 
241
- if @parent_app && parent_component_fingerprints.include?([child_app.name, child_env])
242
- errors << "Sorry, `#{@parent_app.name}` already has a `#{child_env}` " \
247
+ if @parent_app && parent_component_fingerprints.include?([child_app.name, child_env])
248
+ errors <<
249
+ "Sorry, `#{@parent_app.name}` already has a `#{child_env}` " \
243
250
  "component that conflicts with this merge request. Please choose a new environment."
244
- end
251
+ end
245
252
 
246
- return child_env unless errors.any?
253
+ return child_env unless errors.any?
247
254
 
248
- say errors.join("\n"), :red
255
+ say errors.join("\n"), :red
249
256
 
250
- yield
251
- end
257
+ yield
258
+ end
252
259
 
253
- def valid_component?(component_name, env)
254
- return false unless env
260
+ def valid_component?(component_name, env)
261
+ return false unless env
255
262
 
256
- Util::Component.new(env, component_name) && true
257
- rescue ArgumentError
258
- false
259
- end
263
+ Util::Component.new(env, component_name) && true
264
+ rescue ArgumentError
265
+ false
266
+ end
260
267
 
261
- def parent_component_fingerprints
262
- @parent_app.components.map { |x| x.values_at("name", "environment") }
263
- end
268
+ def parent_component_fingerprints
269
+ @parent_app.components.map { |x| x.values_at("name", "environment") }
270
+ end
264
271
 
265
- def children
266
- ret = Enumerator.new do |yielder|
272
+ def children
273
+ ret =
274
+ Enumerator.new do |yielder|
267
275
  @parents.each do |_, app|
268
276
  next if app == @parent_app
269
277
 
270
- app.components.each do |component|
271
- yielder << OpenStruct.new({ app_name: app.name }.merge(component))
272
- end
278
+ app.components.each { |component| yielder << OpenStruct.new({ app_name: app.name }.merge(component)) }
273
279
  end
274
280
 
275
281
  yielder << OpenStruct.new(app_name: STRINGS[:unlisted], unlisted: true)
276
282
  end
277
283
 
278
- ret = ret.each_with_object({}).with_index do |(c, r), i|
279
- r[i + 1] = c
280
- end
284
+ ret = ret.each_with_object({}).with_index { |(c, r), i| r[i + 1] = c }
281
285
 
282
- ret.tap do |result|
283
- if result.values.all?(&:unlisted)
284
- done!(
285
- success: false,
286
- message: "Sorry, you do not have any apps that can be merged into `#{@parent_app.name}`"
287
- )
288
- end
286
+ ret.tap do |result|
287
+ if result.values.all?(&:unlisted)
288
+ done!(
289
+ success: false,
290
+ message: "Sorry, you do not have any apps that can be merged into `#{@parent_app.name}`"
291
+ )
289
292
  end
290
293
  end
294
+ end
291
295
 
292
- def specify_child_env
293
- validate_mergeability(
294
- @child_app,
295
- ask("Please enter your environment name (only lowercase letters, numbers, or hyphens): ", :green).chomp
296
- ) do
297
- specify_child_env
298
- end
299
- end
296
+ def specify_child_env
297
+ validate_mergeability(
298
+ @child_app,
299
+ ask("Please enter your environment name (only lowercase letters, numbers, or hyphens): ", :green).chomp
300
+ ) { specify_child_env }
301
+ end
300
302
  end
301
303
  end
302
304
  end