lhc 10.1.2 → 10.1.3

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.
Files changed (142) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +1 -1
  3. data/Gemfile +2 -0
  4. data/README.md +1 -1
  5. data/lhc.gemspec +2 -0
  6. data/lib/lhc.rb +2 -0
  7. data/lib/lhc/concerns/lhc/basic_methods_concern.rb +2 -0
  8. data/lib/lhc/concerns/lhc/configuration_concern.rb +2 -0
  9. data/lib/lhc/concerns/lhc/formats_concern.rb +2 -0
  10. data/lib/lhc/concerns/lhc/request/user_agent_concern.rb +2 -0
  11. data/lib/lhc/config.rb +2 -0
  12. data/lib/lhc/endpoint.rb +2 -0
  13. data/lib/lhc/error.rb +3 -1
  14. data/lib/lhc/errors/client_error.rb +2 -0
  15. data/lib/lhc/errors/parser_error.rb +2 -0
  16. data/lib/lhc/errors/server_error.rb +2 -0
  17. data/lib/lhc/errors/timeout.rb +2 -0
  18. data/lib/lhc/errors/unknown_error.rb +2 -0
  19. data/lib/lhc/format.rb +2 -0
  20. data/lib/lhc/formats.rb +2 -0
  21. data/lib/lhc/formats/json.rb +2 -0
  22. data/lib/lhc/formats/multipart.rb +2 -0
  23. data/lib/lhc/formats/plain.rb +2 -0
  24. data/lib/lhc/interceptor.rb +2 -0
  25. data/lib/lhc/interceptors.rb +2 -0
  26. data/lib/lhc/interceptors/auth.rb +2 -0
  27. data/lib/lhc/interceptors/caching.rb +2 -0
  28. data/lib/lhc/interceptors/default_timeout.rb +2 -0
  29. data/lib/lhc/interceptors/logging.rb +2 -0
  30. data/lib/lhc/interceptors/monitoring.rb +2 -0
  31. data/lib/lhc/interceptors/prometheus.rb +2 -0
  32. data/lib/lhc/interceptors/retry.rb +2 -0
  33. data/lib/lhc/interceptors/rollbar.rb +2 -0
  34. data/lib/lhc/interceptors/zipkin.rb +8 -6
  35. data/lib/lhc/railtie.rb +2 -0
  36. data/lib/lhc/request.rb +2 -0
  37. data/lib/lhc/response.rb +2 -0
  38. data/lib/lhc/response/data.rb +2 -0
  39. data/lib/lhc/response/data/base.rb +2 -0
  40. data/lib/lhc/response/data/collection.rb +2 -0
  41. data/lib/lhc/response/data/item.rb +2 -0
  42. data/lib/lhc/test/cache_helper.rb +2 -0
  43. data/lib/lhc/version.rb +3 -1
  44. data/spec/basic_methods/delete_spec.rb +2 -0
  45. data/spec/basic_methods/get_spec.rb +2 -0
  46. data/spec/basic_methods/post_spec.rb +2 -0
  47. data/spec/basic_methods/put_spec.rb +2 -0
  48. data/spec/basic_methods/request_spec.rb +2 -0
  49. data/spec/basic_methods/request_without_rails_spec.rb +2 -0
  50. data/spec/config/endpoints_spec.rb +2 -0
  51. data/spec/config/placeholders_spec.rb +2 -0
  52. data/spec/dummy/Rakefile +2 -0
  53. data/spec/dummy/app/controllers/application_controller.rb +2 -0
  54. data/spec/dummy/app/helpers/application_helper.rb +2 -0
  55. data/spec/dummy/bin/bundle +2 -0
  56. data/spec/dummy/bin/rails +2 -0
  57. data/spec/dummy/bin/rake +2 -0
  58. data/spec/dummy/config.ru +2 -0
  59. data/spec/dummy/config/application.rb +2 -0
  60. data/spec/dummy/config/boot.rb +2 -0
  61. data/spec/dummy/config/environment.rb +2 -0
  62. data/spec/dummy/config/environments/development.rb +2 -0
  63. data/spec/dummy/config/environments/production.rb +2 -0
  64. data/spec/dummy/config/environments/test.rb +2 -0
  65. data/spec/dummy/config/initializers/assets.rb +2 -0
  66. data/spec/dummy/config/initializers/backtrace_silencers.rb +2 -0
  67. data/spec/dummy/config/initializers/cookies_serializer.rb +2 -0
  68. data/spec/dummy/config/initializers/filter_parameter_logging.rb +2 -0
  69. data/spec/dummy/config/initializers/inflections.rb +2 -0
  70. data/spec/dummy/config/initializers/mime_types.rb +2 -0
  71. data/spec/dummy/config/initializers/session_store.rb +2 -0
  72. data/spec/dummy/config/initializers/wrap_parameters.rb +2 -0
  73. data/spec/dummy/config/routes.rb +2 -0
  74. data/spec/endpoint/compile_spec.rb +2 -0
  75. data/spec/endpoint/match_spec.rb +2 -0
  76. data/spec/endpoint/placeholders_spec.rb +2 -0
  77. data/spec/endpoint/remove_interpolated_params_spec.rb +2 -0
  78. data/spec/endpoint/values_as_params_spec.rb +2 -0
  79. data/spec/error/dup_spec.rb +2 -0
  80. data/spec/error/find_spec.rb +2 -0
  81. data/spec/error/response_spec.rb +2 -0
  82. data/spec/error/timeout_spec.rb +2 -0
  83. data/spec/error/to_s_spec.rb +4 -2
  84. data/spec/formats/json_spec.rb +2 -0
  85. data/spec/formats/multipart_spec.rb +5 -8
  86. data/spec/formats/plain_spec.rb +6 -9
  87. data/spec/interceptors/after_request_spec.rb +2 -0
  88. data/spec/interceptors/after_response_spec.rb +2 -0
  89. data/spec/interceptors/auth/basic_auth_spec.rb +2 -0
  90. data/spec/interceptors/auth/bearer_spec.rb +2 -0
  91. data/spec/interceptors/auth/reauthentication_configuration_spec.rb +2 -0
  92. data/spec/interceptors/auth/reauthentication_spec.rb +2 -0
  93. data/spec/interceptors/before_request_spec.rb +2 -0
  94. data/spec/interceptors/before_response_spec.rb +2 -0
  95. data/spec/interceptors/caching/hydra_spec.rb +2 -0
  96. data/spec/interceptors/caching/main_spec.rb +2 -0
  97. data/spec/interceptors/caching/methods_spec.rb +2 -0
  98. data/spec/interceptors/caching/options_spec.rb +2 -0
  99. data/spec/interceptors/caching/parameters_spec.rb +2 -0
  100. data/spec/interceptors/caching/response_status_spec.rb +2 -0
  101. data/spec/interceptors/caching/to_cache_spec.rb +2 -0
  102. data/spec/interceptors/default_interceptors_spec.rb +2 -0
  103. data/spec/interceptors/default_timeout/main_spec.rb +2 -0
  104. data/spec/interceptors/define_spec.rb +2 -0
  105. data/spec/interceptors/dup_spec.rb +2 -0
  106. data/spec/interceptors/logging/main_spec.rb +2 -0
  107. data/spec/interceptors/monitoring/main_spec.rb +2 -0
  108. data/spec/interceptors/prometheus_spec.rb +2 -0
  109. data/spec/interceptors/response_competition_spec.rb +2 -0
  110. data/spec/interceptors/retry/main_spec.rb +2 -0
  111. data/spec/interceptors/return_response_spec.rb +2 -0
  112. data/spec/interceptors/rollbar/main_spec.rb +2 -0
  113. data/spec/interceptors/zipkin/distributed_tracing_spec.rb +2 -0
  114. data/spec/rails_helper.rb +2 -0
  115. data/spec/request/body_spec.rb +2 -0
  116. data/spec/request/encoding_spec.rb +2 -0
  117. data/spec/request/error_handling_spec.rb +2 -0
  118. data/spec/request/headers_spec.rb +2 -0
  119. data/spec/request/ignore_errors_spec.rb +2 -0
  120. data/spec/request/option_dup_spec.rb +2 -0
  121. data/spec/request/parallel_requests_spec.rb +2 -0
  122. data/spec/request/params_encoding_spec.rb +2 -0
  123. data/spec/request/request_without_rails_spec.rb +2 -0
  124. data/spec/request/url_patterns_spec.rb +2 -0
  125. data/spec/request/user_agent_spec.rb +2 -0
  126. data/spec/request/user_agent_without_rails_spec.rb +2 -0
  127. data/spec/response/body_spec.rb +2 -0
  128. data/spec/response/code_spec.rb +2 -0
  129. data/spec/response/data_accessor_spec.rb +2 -0
  130. data/spec/response/data_spec.rb +2 -0
  131. data/spec/response/effective_url_spec.rb +2 -0
  132. data/spec/response/headers_spec.rb +2 -0
  133. data/spec/response/options_spec.rb +2 -0
  134. data/spec/response/success_spec.rb +2 -0
  135. data/spec/response/time_spec.rb +2 -0
  136. data/spec/spec_helper.rb +2 -0
  137. data/spec/support/load_json.rb +2 -0
  138. data/spec/support/reset_config.rb +2 -0
  139. data/spec/support/zipkin_mock.rb +10 -8
  140. data/spec/timeouts/no_signal_spec.rb +2 -0
  141. data/spec/timeouts/timings_spec.rb +2 -0
  142. metadata +2 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b67c504475f965371d8573ca0e93bcb4d8ed985bf60b7f606470ca68b1cf381d
4
- data.tar.gz: 1905c89d14fa0db90fcd79d15d843b7565847814d3cfa725fb7e33cb723cd16e
3
+ metadata.gz: 517b130b228cba24e702fdb021efdd774e5a882f8df0373c2588ada562a6ef53
4
+ data.tar.gz: ffa8c5c05477ae88f9225b386714259b35e4be4c6b8c6b39c13693adacdd0016
5
5
  SHA512:
6
- metadata.gz: 3466bf3c2e8bba1286cc27606d44a1c3566fecc984da5204d8669c9b35081a869bcf3097ea06c55bd116706a8e9ba79c85ff943606d7c1297ae50ec90894a9f9
7
- data.tar.gz: 3bc96a32797cc08bb2edf4d32945bc1efc30444f3733472641bf8ed941da927821569bf8c07d9846a76fba7d1cb45029dc0318c94c70e9d5bbb5739e362a99b2
6
+ metadata.gz: a0901b96573c03cd67b0f59cb123538adcf4a0cafcb7b47d2480f578553a60e368f5a92614050c525d8b984021fbe5216f24a04a909ebe0da6f8fdf3c19c66b8
7
+ data.tar.gz: c2671a92b13d0fd6e8ecc74c347b11a31117ba3b5a77fb7cc4452fa43e521ff41095a1f0dca1bb045b4dd06267c7c88252053760a73eebd507bb796ab60f05b0
@@ -43,7 +43,7 @@ RSpec/InstanceVariable:
43
43
  Enabled: false
44
44
 
45
45
  Style/FrozenStringLiteralComment:
46
- Enabled: false
46
+ Enabled: true
47
47
 
48
48
  Naming/MemoizedInstanceVariableName:
49
49
  Enabled: false
data/Gemfile CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  source 'https://rubygems.org'
2
4
 
3
5
  # Declare your gem's dependencies in lhc.gemspec.
data/README.md CHANGED
@@ -410,7 +410,7 @@ If a error handler is provided nothing is raised.
410
410
  If your error handler returns anything else but `nil` it replaces the response body.
411
411
 
412
412
  ```ruby
413
- handler = ->(response){ do_something_with_repsonse; return {name: 'unknown'} }
413
+ handler = ->(response){ do_something_with_response; return {name: 'unknown'} }
414
414
  response = LHC.get('http://something', error_handler: handler)
415
415
  response.data.name # 'unknown'
416
416
  ```
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  $LOAD_PATH.push File.expand_path("../lib", __FILE__)
2
4
 
3
5
  # Maintain your gem's version:
data/lib/lhc.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'typhoeus'
2
4
  require 'active_support/core_ext/object/blank'
3
5
  require 'active_support/core_ext/hash/keys'
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'active_support'
2
4
 
3
5
  module LHC
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'active_support'
2
4
 
3
5
  module LHC
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module LHC
2
4
  module FormatsConcern
3
5
  extend ActiveSupport::Concern
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'active_support'
2
4
  require 'lhc/version'
3
5
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'singleton'
2
4
 
3
5
  class LHC::Config
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'addressable/template'
2
4
 
3
5
  # An endpoint is an url that leads to a backend resource.
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class LHC::Error < StandardError
2
4
  attr_accessor :response, :_message
3
5
 
@@ -63,7 +65,7 @@ class LHC::Error < StandardError
63
65
  debug << "Options: #{request.options}"
64
66
  debug << "Headers: #{request.headers}"
65
67
  debug << "Response Code: #{response.code} (#{response.options[:return_code]})"
66
- debug << "Repsonse Options: #{response.options}"
68
+ debug << "Response Options: #{response.options}"
67
69
  debug << response.body
68
70
  debug << _message
69
71
  debug.map { |str| fix_invalid_encoding(str) }.join("\n")
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class LHC::ClientError < LHC::Error
2
4
  end
3
5
 
@@ -1,2 +1,4 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class LHC::ParserError < LHC::Error
2
4
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class LHC::ServerError < LHC::Error
2
4
  end
3
5
 
@@ -1,2 +1,4 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class LHC::Timeout < LHC::Error
2
4
  end
@@ -1,2 +1,4 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class LHC::UnknownError < LHC::Error
2
4
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class LHC::Format
2
4
 
3
5
  private
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module LHC::Formats
2
4
  autoload :JSON, 'lhc/formats/json'
3
5
  autoload :Multipart, 'lhc/formats/multipart'
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module LHC::Formats
2
4
  class JSON < LHC::Format
3
5
  include LHC::BasicMethodsConcern
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module LHC::Formats
2
4
  class Multipart < LHC::Format
3
5
  include LHC::BasicMethodsConcern
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module LHC::Formats
2
4
  class Plain < LHC::Format
3
5
  include LHC::BasicMethodsConcern
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class LHC::Interceptor
2
4
 
3
5
  attr_reader :request
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Handles interceptions during the lifecycle of a request
2
4
  # Represents all active interceptors for a request/response.
3
5
  class LHC::Interceptors
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class LHC::Auth < LHC::Interceptor
2
4
  include ActiveSupport::Configurable
3
5
  config_accessor :refresh_client_token
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class LHC::Caching < LHC::Interceptor
2
4
  include ActiveSupport::Configurable
3
5
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class LHC::DefaultTimeout < LHC::Interceptor
2
4
  include ActiveSupport::Configurable
3
5
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class LHC::Logging < LHC::Interceptor
2
4
 
3
5
  include ActiveSupport::Configurable
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class LHC::Monitoring < LHC::Interceptor
2
4
 
3
5
  # Options forwarded to the monitoring
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class LHC::Prometheus < LHC::Interceptor
2
4
  include ActiveSupport::Configurable
3
5
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class LHC::Retry < LHC::Interceptor
2
4
  attr_accessor :retries, :current_retry
3
5
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class LHC::Rollbar < LHC::Interceptor
2
4
  include ActiveSupport::Configurable
3
5
 
@@ -1,12 +1,14 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class LHC::Zipkin < LHC::Interceptor
2
4
  B3_HEADERS = {
3
- trace_id: 'X-B3-TraceId'.freeze,
4
- parent_id: 'X-B3-ParentSpanId'.freeze,
5
- span_id: 'X-B3-SpanId'.freeze,
6
- sampled: 'X-B3-Sampled'.freeze,
7
- flags: 'X-B3-Flags'.freeze
5
+ trace_id: 'X-B3-TraceId',
6
+ parent_id: 'X-B3-ParentSpanId',
7
+ span_id: 'X-B3-SpanId',
8
+ sampled: 'X-B3-Sampled',
9
+ flags: 'X-B3-Flags'
8
10
  }.freeze
9
- TRUE = '1'.freeze # true in binary annotation
11
+ TRUE = '1' # true in binary annotation
10
12
 
11
13
  def before_request
12
14
  return unless dependencies?
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module LHC
2
4
  class Railtie < Rails::Railtie
3
5
  initializer "lhc.configure_rails_initialization" do
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'uri'
2
4
  require 'active_support/core_ext/object/deep_dup'
3
5
  require 'lhc/concerns/lhc/request/user_agent_concern'
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'active_support/core_ext/module'
2
4
 
3
5
  # The response contains the raw response (typhoeus)
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class LHC::Response::Data
2
4
  autoload :Base, 'lhc/response/data/base'
3
5
  autoload :Item, 'lhc/response/data/item'
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Response data is data provided through the response body
2
4
  # but made accssible in the ruby world
3
5
  module LHC::Response::Data::Base
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class LHC::Response::Data::Collection < Array
2
4
  include LHC::Response::Data::Base
3
5
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class LHC::Response::Data::Item < OpenStruct
2
4
  include LHC::Response::Data::Base
3
5
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  RSpec.configure do |config|
2
4
  LHC::Caching.cache = ActiveSupport::Cache::MemoryStore.new
3
5
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module LHC
2
- VERSION ||= '10.1.2'
4
+ VERSION ||= '10.1.3'
3
5
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'rails_helper'
2
4
 
3
5
  describe LHC do
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'rails_helper'
2
4
 
3
5
  describe LHC do
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'rails_helper'
2
4
 
3
5
  describe LHC do
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'rails_helper'
2
4
 
3
5
  describe LHC do
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'rails_helper'
2
4
 
3
5
  describe LHC do
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'spec_helper'
2
4
 
3
5
  describe LHC do
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'rails_helper'
2
4
 
3
5
  describe LHC do
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'rails_helper'
2
4
 
3
5
  describe LHC do
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Add your own tasks in files placed in lib/tasks ending in .rake,
2
4
  # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
3
5
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class ApplicationController < ActionController::Base
2
4
  # Prevent CSRF attacks by raising an exception.
3
5
  # For APIs, you may want to use :null_session instead.
@@ -1,2 +1,4 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ApplicationHelper
2
4
  end
@@ -1,3 +1,5 @@
1
1
  #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
2
4
  ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__)
3
5
  load Gem.bin_path('bundler', 'bundle')
@@ -1,4 +1,6 @@
1
1
  #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
2
4
  APP_PATH = File.expand_path('../../config/application', __FILE__)
3
5
  require_relative '../config/boot'
4
6
  require 'rails/commands'
@@ -1,4 +1,6 @@
1
1
  #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
2
4
  require_relative '../config/boot'
3
5
  require 'rake'
4
6
  Rake.application.run
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # This file is used by Rack-based servers to start the application.
2
4
 
3
5
  require ::File.expand_path('../config/environment', __FILE__)
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require File.expand_path('../boot', __FILE__)
2
4
 
3
5
  require "action_controller/railtie"
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Set up gems listed in the Gemfile.
2
4
  ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../../../Gemfile', __FILE__)
3
5