skylight 4.3.2 → 5.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (118) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +399 -336
  3. data/CLA.md +1 -1
  4. data/CONTRIBUTING.md +2 -8
  5. data/LICENSE.md +7 -17
  6. data/README.md +1 -1
  7. data/ext/extconf.rb +45 -56
  8. data/ext/libskylight.yml +10 -6
  9. data/ext/skylight_native.c +22 -99
  10. data/lib/skylight.rb +201 -14
  11. data/lib/skylight/api.rb +32 -21
  12. data/lib/skylight/cli.rb +48 -46
  13. data/lib/skylight/cli/doctor.rb +62 -63
  14. data/lib/skylight/cli/helpers.rb +19 -19
  15. data/lib/skylight/cli/merger.rb +142 -138
  16. data/lib/skylight/config.rb +634 -199
  17. data/lib/skylight/deprecation.rb +17 -0
  18. data/lib/skylight/errors.rb +23 -9
  19. data/lib/skylight/extensions.rb +95 -0
  20. data/lib/skylight/extensions/source_location.rb +291 -0
  21. data/lib/skylight/formatters/http.rb +18 -0
  22. data/lib/skylight/gc.rb +99 -0
  23. data/lib/skylight/helpers.rb +81 -36
  24. data/lib/skylight/instrumenter.rb +336 -18
  25. data/lib/skylight/middleware.rb +134 -1
  26. data/lib/skylight/native.rb +60 -12
  27. data/lib/skylight/native_ext_fetcher.rb +13 -14
  28. data/lib/skylight/normalizers.rb +157 -0
  29. data/lib/skylight/normalizers/action_controller/process_action.rb +68 -0
  30. data/lib/skylight/normalizers/action_controller/send_file.rb +51 -0
  31. data/lib/skylight/normalizers/action_dispatch/process_middleware.rb +22 -0
  32. data/lib/skylight/normalizers/action_dispatch/route_set.rb +27 -0
  33. data/lib/skylight/normalizers/action_view/render_collection.rb +24 -0
  34. data/lib/skylight/normalizers/action_view/render_layout.rb +25 -0
  35. data/lib/skylight/normalizers/action_view/render_partial.rb +23 -0
  36. data/lib/skylight/normalizers/action_view/render_template.rb +23 -0
  37. data/lib/skylight/normalizers/active_job/perform.rb +90 -0
  38. data/lib/skylight/normalizers/active_model_serializers/render.rb +32 -0
  39. data/lib/skylight/normalizers/active_record/instantiation.rb +16 -0
  40. data/lib/skylight/normalizers/active_record/sql.rb +12 -0
  41. data/lib/skylight/normalizers/active_storage.rb +28 -0
  42. data/lib/skylight/normalizers/active_support/cache.rb +11 -0
  43. data/lib/skylight/normalizers/active_support/cache_clear.rb +16 -0
  44. data/lib/skylight/normalizers/active_support/cache_decrement.rb +16 -0
  45. data/lib/skylight/normalizers/active_support/cache_delete.rb +16 -0
  46. data/lib/skylight/normalizers/active_support/cache_exist.rb +16 -0
  47. data/lib/skylight/normalizers/active_support/cache_fetch_hit.rb +16 -0
  48. data/lib/skylight/normalizers/active_support/cache_generate.rb +16 -0
  49. data/lib/skylight/normalizers/active_support/cache_increment.rb +16 -0
  50. data/lib/skylight/normalizers/active_support/cache_read.rb +16 -0
  51. data/lib/skylight/normalizers/active_support/cache_read_multi.rb +16 -0
  52. data/lib/skylight/normalizers/active_support/cache_write.rb +16 -0
  53. data/lib/skylight/normalizers/coach/handler_finish.rb +44 -0
  54. data/lib/skylight/normalizers/coach/middleware_finish.rb +33 -0
  55. data/lib/skylight/normalizers/couch_potato/query.rb +20 -0
  56. data/lib/skylight/normalizers/data_mapper/sql.rb +12 -0
  57. data/lib/skylight/normalizers/default.rb +24 -0
  58. data/lib/skylight/normalizers/elasticsearch/request.rb +20 -0
  59. data/lib/skylight/normalizers/faraday/request.rb +38 -0
  60. data/lib/skylight/normalizers/grape/endpoint.rb +28 -0
  61. data/lib/skylight/normalizers/grape/endpoint_render.rb +25 -0
  62. data/lib/skylight/normalizers/grape/endpoint_run.rb +39 -0
  63. data/lib/skylight/normalizers/grape/endpoint_run_filters.rb +20 -0
  64. data/lib/skylight/normalizers/grape/format_response.rb +20 -0
  65. data/lib/skylight/normalizers/graphiti/render.rb +22 -0
  66. data/lib/skylight/normalizers/graphiti/resolve.rb +31 -0
  67. data/lib/skylight/normalizers/graphql/base.rb +127 -0
  68. data/lib/skylight/normalizers/render.rb +79 -0
  69. data/lib/skylight/normalizers/sequel/sql.rb +12 -0
  70. data/lib/skylight/normalizers/shrine.rb +32 -0
  71. data/lib/skylight/normalizers/sql.rb +45 -0
  72. data/lib/skylight/probes.rb +173 -0
  73. data/lib/skylight/probes/action_controller.rb +52 -0
  74. data/lib/skylight/probes/action_dispatch.rb +2 -0
  75. data/lib/skylight/probes/action_dispatch/request_id.rb +33 -0
  76. data/lib/skylight/probes/action_dispatch/routing/route_set.rb +30 -0
  77. data/lib/skylight/probes/action_view.rb +42 -0
  78. data/lib/skylight/probes/active_job.rb +27 -0
  79. data/lib/skylight/probes/active_job_enqueue.rb +35 -0
  80. data/lib/skylight/probes/active_model_serializers.rb +50 -0
  81. data/lib/skylight/probes/delayed_job.rb +144 -0
  82. data/lib/skylight/probes/elasticsearch.rb +36 -0
  83. data/lib/skylight/probes/excon.rb +25 -0
  84. data/lib/skylight/probes/excon/middleware.rb +65 -0
  85. data/lib/skylight/probes/faraday.rb +23 -0
  86. data/lib/skylight/probes/graphql.rb +38 -0
  87. data/lib/skylight/probes/httpclient.rb +44 -0
  88. data/lib/skylight/probes/middleware.rb +135 -0
  89. data/lib/skylight/probes/mongo.rb +156 -0
  90. data/lib/skylight/probes/mongoid.rb +13 -0
  91. data/lib/skylight/probes/net_http.rb +54 -0
  92. data/lib/skylight/probes/redis.rb +51 -0
  93. data/lib/skylight/probes/sequel.rb +29 -0
  94. data/lib/skylight/probes/sinatra.rb +66 -0
  95. data/lib/skylight/probes/sinatra_add_middleware.rb +10 -10
  96. data/lib/skylight/probes/tilt.rb +25 -0
  97. data/lib/skylight/railtie.rb +157 -27
  98. data/lib/skylight/sidekiq.rb +47 -0
  99. data/lib/skylight/subscriber.rb +108 -0
  100. data/lib/skylight/test.rb +151 -0
  101. data/lib/skylight/trace.rb +325 -22
  102. data/lib/skylight/user_config.rb +58 -0
  103. data/lib/skylight/util.rb +12 -0
  104. data/lib/skylight/util/allocation_free.rb +26 -0
  105. data/lib/skylight/util/clock.rb +57 -0
  106. data/lib/skylight/util/component.rb +22 -22
  107. data/lib/skylight/util/deploy.rb +16 -21
  108. data/lib/skylight/util/gzip.rb +20 -0
  109. data/lib/skylight/util/http.rb +106 -113
  110. data/lib/skylight/util/instrumenter_method.rb +26 -0
  111. data/lib/skylight/util/logging.rb +136 -0
  112. data/lib/skylight/util/lru_cache.rb +36 -0
  113. data/lib/skylight/util/platform.rb +1 -5
  114. data/lib/skylight/util/ssl.rb +1 -25
  115. data/lib/skylight/vendor/cli/thor/rake_compat.rb +1 -1
  116. data/lib/skylight/version.rb +5 -1
  117. data/lib/skylight/vm/gc.rb +60 -0
  118. metadata +126 -13
@@ -24,7 +24,9 @@ module Skylight
24
24
  say "Please update your certificates with RVM by running `rvm osx-ssl-certs update all`.", :yellow
25
25
  say "Alternatively, try setting `SKYLIGHT_FORCE_OWN_CERTS=1` in your environment.", :yellow
26
26
  else
27
- say "Please update your local certificates or try setting `SKYLIGHT_FORCE_OWN_CERTS=1` in your environment.", :yellow
27
+ say "Please update your local certificates or try setting `SKYLIGHT_FORCE_OWN_CERTS=1` in your " \
28
+ "environment.",
29
+ :yellow
28
30
  end
29
31
  end
30
32
  else
@@ -65,9 +67,7 @@ module Skylight
65
67
  indent do
66
68
  install_log = File.expand_path("../../ext/install.log", __dir__)
67
69
  if File.exist?(install_log)
68
- File.readlines(install_log).each do |line|
69
- say line, :red
70
- end
70
+ File.readlines(install_log).each { |line| say line, :red }
71
71
  else
72
72
  say "Reason unknown", :red
73
73
  end
@@ -84,20 +84,18 @@ module Skylight
84
84
  say "Checking for valid configuration"
85
85
 
86
86
  indent do
87
- begin
88
- config.validate!
89
- say "Configuration is valid", :green
90
- rescue Core::ConfigError => e
91
- encountered_error!
92
-
93
- say "Configuration is invalid", :red
94
- indent do
95
- say e.message, :red
96
- say "This may occur if you are configuring with ENV variables and didn't set them in this shell."
97
- end
98
-
99
- done!
87
+ config.validate!
88
+ say "Configuration is valid", :green
89
+ rescue ConfigError => e
90
+ encountered_error!
91
+
92
+ say "Configuration is invalid", :red
93
+ indent do
94
+ say e.message, :red
95
+ say "This may occur if you are configuring with ENV variables and didn't set them in this shell."
100
96
  end
97
+
98
+ done!
101
99
  end
102
100
 
103
101
  puts "\n"
@@ -109,13 +107,16 @@ module Skylight
109
107
  indent do
110
108
  # Set this after we validate. It will give us more detailed information on start.
111
109
  logger = Logger.new("/dev/null") # Rely on `say` in the formatter instead
110
+
112
111
  # Log everything
113
112
  logger.level = Logger::DEBUG
113
+
114
114
  # Remove excess formatting
115
- logger.formatter = proc { |severity, _datetime, _progname, msg|
116
- msg = msg.sub("[SKYLIGHT] [#{Skylight::VERSION}] ", "")
117
- say "#{severity} - #{msg}" # Definitely non-standard
118
- }
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
119
120
  config.logger = logger
120
121
 
121
122
  config.set(:'daemon.lazy_start', false)
@@ -166,57 +167,55 @@ module Skylight
166
167
 
167
168
  private
168
169
 
169
- # Overwrite the default helper method to load from Rails
170
- def config
171
- return @config if @config
170
+ # Overwrite the default helper method to load from Rails
171
+ def config
172
+ return @config if @config
172
173
 
173
- # MEGAHAX
174
- if rails?
175
- # Normally auto-loaded, but we haven't loaded Rails by the time Skylight is loaded
176
- require "skylight/railtie"
177
- require rails_rb
178
-
179
- railtie = Skylight::Railtie.send(:new)
180
- @config = railtie.send(:load_skylight_config, Rails.application)
181
- else
182
- super
183
- end
184
- end
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
185
179
 
186
- def mac?
187
- Util::Platform::OS == "darwin"
180
+ railtie = Skylight::Railtie.send(:new)
181
+ @config = railtie.send(:load_skylight_config, Rails.application)
182
+ else
183
+ super
188
184
  end
185
+ end
189
186
 
190
- # NOTE: This check won't work correctly on Windows
191
- def rvm_present?
192
- if @has_rvm.nil?
193
- @has_rvm = system("which rvm > /dev/null")
194
- end
195
- @has_rvm
196
- end
187
+ def mac?
188
+ Util::Platform::OS == "darwin"
189
+ end
197
190
 
198
- def encountered_error!
199
- @has_errors = true
200
- 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
201
196
 
202
- def has_errors?
203
- @has_errors
204
- end
197
+ def encountered_error!
198
+ @has_errors = true
199
+ end
205
200
 
206
- def done!
207
- shell.padding = 0
208
- say "\n\n"
201
+ def has_errors?
202
+ @has_errors
203
+ end
209
204
 
210
- if has_errors?
211
- say "Skylight Doctor found some errors. Please review the output above.", :red
212
- say "If you have any further questions, please contact support@skylight.io.", :yellow
213
- exit 1
214
- else
215
- say "All checks passed!", :green
216
- say "If you're still having trouble, please contact support@skylight.io.", :yellow
217
- exit 0
218
- 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
219
217
  end
218
+ end
220
219
  end
221
220
  end
222
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
@@ -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,134 +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
255
- Skylight::Util::Component.new(env, component_name) && true
256
- rescue ArgumentError
257
- false
258
- end
260
+ def valid_component?(component_name, env)
261
+ return false unless env
259
262
 
260
- def parent_component_fingerprints
261
- @parent_app.components.map { |x| x.values_at("name", "environment") }
262
- end
263
+ Util::Component.new(env, component_name) && true
264
+ rescue ArgumentError
265
+ false
266
+ end
267
+
268
+ def parent_component_fingerprints
269
+ @parent_app.components.map { |x| x.values_at("name", "environment") }
270
+ end
263
271
 
264
- def children
265
- ret = Enumerator.new do |yielder|
272
+ def children
273
+ ret =
274
+ Enumerator.new do |yielder|
266
275
  @parents.each do |_, app|
267
276
  next if app == @parent_app
268
- app.components.each do |component|
269
- yielder << OpenStruct.new({ app_name: app.name }.merge(component))
270
- end
277
+
278
+ app.components.each { |component| yielder << OpenStruct.new({ app_name: app.name }.merge(component)) }
271
279
  end
272
280
 
273
281
  yielder << OpenStruct.new(app_name: STRINGS[:unlisted], unlisted: true)
274
282
  end
275
283
 
276
- ret = ret.each_with_object({}).with_index do |(c, r), i|
277
- r[i + 1] = c
278
- end
284
+ ret = ret.each_with_object({}).with_index { |(c, r), i| r[i + 1] = c }
279
285
 
280
- ret.tap do |result|
281
- if result.values.all?(&:unlisted)
282
- done!(
283
- success: false,
284
- message: "Sorry, you do not have any apps that can be merged into `#{@parent_app.name}`"
285
- )
286
- 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
+ )
287
292
  end
288
293
  end
294
+ end
289
295
 
290
- def specify_child_env
291
- validate_mergeability(
292
- @child_app,
293
- ask("Please enter your environment name (only lowercase letters, numbers, or hyphens): ", :green).chomp
294
- ) do
295
- specify_child_env
296
- end
297
- 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
298
302
  end
299
303
  end
300
304
  end