openfeature-sdk 0.6.4 → 0.6.6

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 (67) hide show
  1. checksums.yaml +4 -4
  2. data/.release-please-manifest.json +1 -1
  3. data/.ruby-version +1 -1
  4. data/.tool-versions +1 -1
  5. data/.yardopts +5 -0
  6. data/CHANGELOG.md +20 -0
  7. data/CLAUDE.md +4 -1
  8. data/CONTRIBUTING.md +15 -1
  9. data/Gemfile +17 -2
  10. data/Gemfile.lock +98 -67
  11. data/README.md +24 -8
  12. data/Rakefile +14 -0
  13. data/SECURITY.md +10 -0
  14. data/Steepfile +7 -0
  15. data/examples/basic_usage.rb +22 -0
  16. data/examples/custom_provider.rb +56 -0
  17. data/examples/rails_integration.rb +60 -0
  18. data/lib/open_feature/sdk/api.rb +1 -0
  19. data/lib/open_feature/sdk/client.rb +2 -3
  20. data/lib/open_feature/sdk/configuration.rb +26 -13
  21. data/lib/open_feature/sdk/evaluation_error.rb +28 -0
  22. data/lib/open_feature/sdk/hooks/hook_executor.rb +5 -5
  23. data/lib/open_feature/sdk/hooks/logging_hook.rb +1 -2
  24. data/lib/open_feature/sdk/provider/in_memory_provider.rb +24 -0
  25. data/lib/open_feature/sdk/provider_event.rb +5 -1
  26. data/lib/open_feature/sdk/provider_state_registry.rb +2 -2
  27. data/lib/open_feature/sdk/version.rb +1 -1
  28. data/openfeature-sdk.gemspec +34 -0
  29. data/rbs_collection.lock.yaml +292 -0
  30. data/rbs_collection.yaml +14 -0
  31. data/renovate.json +1 -1
  32. data/sig/open_feature/sdk/api.rbs +35 -0
  33. data/sig/open_feature/sdk/client.rbs +49 -0
  34. data/sig/open_feature/sdk/client_metadata.rbs +11 -0
  35. data/sig/open_feature/sdk/configuration.rbs +44 -0
  36. data/sig/open_feature/sdk/evaluation_context.rbs +19 -0
  37. data/sig/open_feature/sdk/evaluation_context_builder.rbs +7 -0
  38. data/sig/open_feature/sdk/evaluation_details.rbs +19 -0
  39. data/sig/open_feature/sdk/evaluation_error.rbs +11 -0
  40. data/sig/open_feature/sdk/event_dispatcher.rbs +24 -0
  41. data/sig/open_feature/sdk/hooks/hints.rbs +30 -0
  42. data/sig/open_feature/sdk/hooks/hook.rbs +19 -0
  43. data/sig/open_feature/sdk/hooks/hook_context.rbs +18 -0
  44. data/sig/open_feature/sdk/hooks/hook_executor.rbs +20 -0
  45. data/sig/open_feature/sdk/hooks/logging_hook.rbs +25 -0
  46. data/sig/open_feature/sdk/provider/error_code.rbs +16 -0
  47. data/sig/open_feature/sdk/provider/event_emitter.rbs +16 -0
  48. data/sig/open_feature/sdk/provider/in_memory_provider.rbs +46 -0
  49. data/sig/open_feature/sdk/provider/no_op_provider.rbs +25 -0
  50. data/sig/open_feature/sdk/provider/provider_metadata.rbs +11 -0
  51. data/sig/open_feature/sdk/provider/reason.rbs +17 -0
  52. data/sig/open_feature/sdk/provider/resolution_details.rbs +19 -0
  53. data/sig/open_feature/sdk/provider.rbs +24 -0
  54. data/sig/open_feature/sdk/provider_event.rbs +14 -0
  55. data/sig/open_feature/sdk/provider_initialization_error.rbs +11 -0
  56. data/sig/open_feature/sdk/provider_state.rbs +13 -0
  57. data/sig/open_feature/sdk/provider_state_registry.rbs +22 -0
  58. data/sig/open_feature/sdk/telemetry.rbs +29 -0
  59. data/sig/open_feature/sdk/thread_local_transaction_context_propagator.rbs +12 -0
  60. data/sig/open_feature/sdk/tracking_event_details.rbs +10 -0
  61. data/sig/open_feature/sdk/transaction_context_propagator.rbs +11 -0
  62. data/sig/open_feature/sdk/version.rbs +5 -0
  63. data/sig/open_feature/sdk.rbs +22 -0
  64. metadata +54 -140
  65. data/.simplecov +0 -12
  66. data/docs/plans/2026-03-07-telemetry-utility-design.md +0 -98
  67. data/docs/plans/2026-03-07-telemetry-utility-plan.md +0 -578
@@ -0,0 +1,60 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Example: OpenFeature integration with Ruby on Rails
4
+ #
5
+ # This file demonstrates how you might integrate OpenFeature into a Rails app.
6
+ # It is not runnable standalone — it shows patterns for use in a Rails context.
7
+
8
+ # config/initializers/openfeature.rb
9
+ #
10
+ # OpenFeature::SDK.configure do |config|
11
+ # config.set_provider(YourProvider.new)
12
+ #
13
+ # # Set global context with server-level info
14
+ # config.evaluation_context = OpenFeature::SDK::EvaluationContext.new(
15
+ # "environment" => Rails.env,
16
+ # "service" => "my-rails-app"
17
+ # )
18
+ #
19
+ # # Use thread-local transaction context for per-request data
20
+ # config.set_transaction_context_propagator(
21
+ # OpenFeature::SDK::ThreadLocalTransactionContextPropagator.new
22
+ # )
23
+ # end
24
+
25
+ # app/middleware/openfeature_context_middleware.rb
26
+ #
27
+ # class OpenFeatureContextMiddleware
28
+ # def initialize(app)
29
+ # @app = app
30
+ # end
31
+ #
32
+ # def call(env)
33
+ # request = ActionDispatch::Request.new(env)
34
+ # OpenFeature::SDK.set_transaction_context(
35
+ # OpenFeature::SDK::EvaluationContext.new(
36
+ # targeting_key: request.session[:user_id]&.to_s,
37
+ # "ip" => request.remote_ip,
38
+ # "user_agent" => request.user_agent
39
+ # )
40
+ # )
41
+ # @app.call(env)
42
+ # ensure
43
+ # # Clear context to prevent leakage in threaded servers (e.g. Puma)
44
+ # OpenFeature::SDK.set_transaction_context(nil)
45
+ # end
46
+ # end
47
+
48
+ # app/controllers/application_controller.rb
49
+ #
50
+ # class ApplicationController < ActionController::Base
51
+ # private
52
+ #
53
+ # def feature_client
54
+ # @feature_client ||= OpenFeature::SDK.build_client(domain: "web")
55
+ # end
56
+ #
57
+ # def feature_enabled?(flag_key)
58
+ # feature_client.fetch_boolean_value(flag_key: flag_key, default_value: false)
59
+ # end
60
+ # end
@@ -7,6 +7,7 @@ require_relative "configuration"
7
7
  require_relative "evaluation_context"
8
8
  require_relative "evaluation_context_builder"
9
9
  require_relative "evaluation_details"
10
+ require_relative "evaluation_error"
10
11
  require_relative "client_metadata"
11
12
  require_relative "hooks"
12
13
  require_relative "client"
@@ -80,7 +80,7 @@ module OpenFeature
80
80
  provider_hooks = @provider.respond_to?(:hooks) ? Array(@provider.hooks) : []
81
81
  ordered_hooks = [*OpenFeature::SDK.hooks, *@hooks, *invocation_hooks, *provider_hooks]
82
82
 
83
- # Check for short-circuit conditions (spec 1.7.6 + 1.7.7)
83
+ # Short-circuit NOT_READY/FATAL providers (required by evaluation_v2.feature)
84
84
  short_circuit_code = nil
85
85
  if OpenFeature::SDK.configuration.provider_tracked?(@provider)
86
86
  short_circuit_code = short_circuit_error_code(provider_status)
@@ -102,7 +102,7 @@ module OpenFeature
102
102
  rescue => e
103
103
  resolution = Provider::ResolutionDetails.new(
104
104
  value: default_value,
105
- error_code: Provider::ErrorCode::GENERAL,
105
+ error_code: EvaluationError.code_for(e),
106
106
  reason: Provider::Reason::ERROR,
107
107
  error_message: e.message
108
108
  )
@@ -130,7 +130,6 @@ module OpenFeature
130
130
  executor = Hooks::HookExecutor.new(logger: OpenFeature::SDK.configuration.logger)
131
131
 
132
132
  if short_circuit_code
133
- # Spec 1.7.6 + 1.7.7: short-circuit must still run error hooks and finally hooks
134
133
  resolution = Provider::ResolutionDetails.new(
135
134
  value: default_value,
136
135
  error_code: short_circuit_code,
@@ -1,8 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "timeout"
4
3
  require_relative "api"
5
4
  require_relative "provider_initialization_error"
5
+ require_relative "evaluation_error"
6
6
  require_relative "event_dispatcher"
7
7
  require_relative "provider_event"
8
8
  require_relative "provider_state_registry"
@@ -89,11 +89,17 @@ module OpenFeature
89
89
  end
90
90
 
91
91
  def shutdown
92
- providers_to_shutdown = @provider_mutex.synchronize { @providers.values.uniq(&:object_id) }
92
+ # Unbind before shutting down so events that arrive mid-shutdown are dropped
93
+ providers_to_shutdown = @provider_mutex.synchronize do
94
+ bound = @providers.values.uniq(&:object_id)
95
+ @providers = {}
96
+ bound
97
+ end
93
98
 
94
99
  providers_to_shutdown.each do |prov|
95
- # Spec 1.7.9: Set provider state to NOT_READY before shutdown
100
+ # Spec 1.7.6: Set provider state to NOT_READY before shutdown
96
101
  @provider_state_registry.set_initial_state(prov, ProviderState::NOT_READY)
102
+ prov.send(:detach) if prov.is_a?(Provider::EventEmitter)
97
103
  prov.shutdown if prov.respond_to?(:shutdown)
98
104
  rescue => e
99
105
  @logger&.warn("Error shutting down provider #{prov&.class&.name || "unknown"}: #{e.message}")
@@ -145,9 +151,11 @@ module OpenFeature
145
151
 
146
152
  # Spec 1.1.2.3: Only shutdown old provider if it's no longer bound to any domain
147
153
  if old_provider && !old_provider.equal?(provider)
148
- still_bound = @providers.any? { |_, p| p.equal?(old_provider) }
149
- needs_shutdown = !still_bound
150
- @provider_state_registry.remove_provider(old_provider) unless still_bound
154
+ needs_shutdown = !provider_bound?(old_provider)
155
+ if needs_shutdown
156
+ @provider_state_registry.remove_provider(old_provider)
157
+ old_provider.send(:detach) if old_provider.is_a?(Provider::EventEmitter)
158
+ end
151
159
  end
152
160
  end
153
161
 
@@ -187,12 +195,8 @@ module OpenFeature
187
195
 
188
196
  dispatch_provider_event(provider, ProviderEvent::PROVIDER_READY)
189
197
  rescue => e
190
- # Spec 1.7.8: Propagate error code from provider if available
191
- error_code = if e.respond_to?(:error_code) && e.error_code
192
- e.error_code
193
- else
194
- Provider::ErrorCode::GENERAL
195
- end
198
+ # Spec 1.7.5: PROVIDER_FATAL from init makes the provider FATAL
199
+ error_code = EvaluationError.code_for(e)
196
200
 
197
201
  dispatch_provider_event(provider, ProviderEvent::PROVIDER_ERROR,
198
202
  error_code: error_code,
@@ -209,7 +213,12 @@ module OpenFeature
209
213
  end
210
214
 
211
215
  def dispatch_provider_event(provider, event_type, details = {})
212
- @provider_state_registry.update_state_from_event(provider, event_type, details)
216
+ # Under the replacement lock, so a late event can't re-track a replaced or shut-down provider
217
+ @provider_mutex.synchronize do
218
+ return unless provider_bound?(provider)
219
+
220
+ @provider_state_registry.update_state_from_event(provider, event_type, details)
221
+ end
213
222
 
214
223
  provider_name = extract_provider_name(provider)
215
224
 
@@ -222,6 +231,10 @@ module OpenFeature
222
231
 
223
232
  private
224
233
 
234
+ def provider_bound?(provider)
235
+ @providers.each_value.any? { |p| p.equal?(provider) }
236
+ end
237
+
225
238
  def extract_provider_name(provider)
226
239
  provider.respond_to?(:metadata) ? provider.metadata.name : provider.class.name
227
240
  end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "provider/error_code"
4
+
5
+ module OpenFeature
6
+ module SDK
7
+ # Raised by a provider to signal an evaluation error with an OpenFeature
8
+ # error code (spec 2.2.7). Any exception responding to +error_code+ is
9
+ # honored the same way.
10
+ class EvaluationError < StandardError
11
+ # @return [String] the OpenFeature error code
12
+ attr_reader :error_code
13
+
14
+ def initialize(message = nil, error_code: Provider::ErrorCode::GENERAL)
15
+ super(message || error_code)
16
+ @error_code = error_code
17
+ end
18
+
19
+ # The error code carried by +exception+, or GENERAL when it has none.
20
+ # Rescues a failing reader so callers inside a rescue block never raise (spec 1.4.10).
21
+ def self.code_for(exception)
22
+ (exception.respond_to?(:error_code) && exception.error_code) || Provider::ErrorCode::GENERAL
23
+ rescue
24
+ Provider::ErrorCode::GENERAL
25
+ end
26
+ end
27
+ end
28
+ end
@@ -18,15 +18,15 @@ module OpenFeature
18
18
  @logger = logger
19
19
  end
20
20
 
21
- # Runs error hooks and finally hooks for a short-circuit evaluation
22
- # (spec 1.7.6 + 1.7.7). Before hooks and after hooks are NOT run.
21
+ # Runs error hooks and finally hooks for a short-circuit evaluation.
22
+ # Before hooks and after hooks are NOT run.
23
23
  #
24
24
  # @param ordered_hooks [Array] hooks in before-order
25
25
  # @param hook_context [HookContext] the hook context
26
26
  # @param hints [Hints] hook hints
27
27
  # @param evaluation_details [EvaluationDetails] the short-circuit result
28
28
  def run_short_circuit(ordered_hooks:, hook_context:, hints:, evaluation_details:)
29
- error = StandardError.new(evaluation_details.error_code)
29
+ error = EvaluationError.new(evaluation_details.error_message, error_code: evaluation_details.error_code)
30
30
  run_error_hooks(ordered_hooks, hook_context, error, hints)
31
31
  ensure
32
32
  run_finally_hooks(ordered_hooks, hook_context, evaluation_details, hints)
@@ -49,7 +49,7 @@ module OpenFeature
49
49
  # Spec 4.3.6: If evaluation resulted in an error (e.g. FLAG_NOT_FOUND,
50
50
  # TYPE_MISMATCH), run error hooks instead of after hooks.
51
51
  if evaluation_details.error_code
52
- error = StandardError.new(evaluation_details.error_message || evaluation_details.error_code)
52
+ error = EvaluationError.new(evaluation_details.error_message, error_code: evaluation_details.error_code)
53
53
  run_error_hooks(ordered_hooks, hook_context, error, hints)
54
54
  else
55
55
  run_after_hooks(ordered_hooks, hook_context, evaluation_details, hints)
@@ -61,7 +61,7 @@ module OpenFeature
61
61
  flag_key: hook_context.flag_key,
62
62
  resolution_details: Provider::ResolutionDetails.new(
63
63
  value: hook_context.default_value,
64
- error_code: Provider::ErrorCode::GENERAL,
64
+ error_code: EvaluationError.code_for(e),
65
65
  reason: Provider::Reason::ERROR,
66
66
  error_message: e.message
67
67
  )
@@ -49,8 +49,7 @@ module OpenFeature
49
49
 
50
50
  def build_error_message(hook_context, exception)
51
51
  parts = base_parts("error", hook_context)
52
- error_code = exception.respond_to?(:error_code) ? exception.error_code : Provider::ErrorCode::GENERAL
53
- parts << "error_code=#{sanitize(error_code)}"
52
+ parts << "error_code=#{sanitize(EvaluationError.code_for(exception))}"
54
53
  parts << "error_message=#{sanitize(exception.message)}"
55
54
  parts << "evaluation_context=#{format_context(hook_context.evaluation_context)}" if @include_evaluation_context
56
55
  parts.join(" ")
@@ -8,6 +8,10 @@ module OpenFeature
8
8
 
9
9
  NAME = "In-memory Provider"
10
10
 
11
+ # A flag with named variants. +context_evaluator+ receives the evaluation
12
+ # context and returns a variant key; anything else falls back to +default_variant+.
13
+ Flag = Struct.new(:variants, :default_variant, :context_evaluator, :flag_metadata, :disabled, keyword_init: true)
14
+
11
15
  attr_reader :metadata
12
16
 
13
17
  def initialize(flags = {})
@@ -70,6 +74,8 @@ module OpenFeature
70
74
  return ResolutionDetails.new(value: default_value, error_code: ErrorCode::FLAG_NOT_FOUND, reason: Reason::ERROR)
71
75
  end
72
76
 
77
+ return resolve_variant_flag(raw_value, default_value, evaluation_context) if raw_value.is_a?(Flag)
78
+
73
79
  if raw_value.respond_to?(:call)
74
80
  value = raw_value.call(evaluation_context)
75
81
  ResolutionDetails.new(value: value, reason: Reason::TARGETING_MATCH)
@@ -78,6 +84,24 @@ module OpenFeature
78
84
  end
79
85
  end
80
86
 
87
+ def resolve_variant_flag(flag, default_value, evaluation_context)
88
+ flag_metadata = flag.flag_metadata
89
+ return ResolutionDetails.new(value: default_value, reason: Reason::DISABLED, flag_metadata:) if flag.disabled
90
+
91
+ variants = flag.variants.to_h
92
+ unless variants.key?(flag.default_variant)
93
+ return ResolutionDetails.new(value: default_value, error_code: ErrorCode::PARSE_ERROR, reason: Reason::ERROR, flag_metadata:)
94
+ end
95
+
96
+ matched = flag.context_evaluator&.call(evaluation_context)
97
+ if variants.key?(matched)
98
+ return ResolutionDetails.new(value: variants[matched], variant: matched, reason: Reason::TARGETING_MATCH, flag_metadata:)
99
+ end
100
+
101
+ reason = flag.context_evaluator ? Reason::DEFAULT : Reason::STATIC
102
+ ResolutionDetails.new(value: variants[flag.default_variant], variant: flag.default_variant, reason:, flag_metadata:)
103
+ end
104
+
81
105
  def emit_provider_changed(flag_keys)
82
106
  return unless configuration_attached?
83
107
 
@@ -13,12 +13,16 @@ module OpenFeature
13
13
  PROVIDER_ERROR = "PROVIDER_ERROR"
14
14
  PROVIDER_CONFIGURATION_CHANGED = "PROVIDER_CONFIGURATION_CHANGED"
15
15
  PROVIDER_STALE = "PROVIDER_STALE"
16
+ PROVIDER_RECONCILING = "PROVIDER_RECONCILING"
17
+ PROVIDER_CONTEXT_CHANGED = "PROVIDER_CONTEXT_CHANGED"
16
18
 
17
19
  ALL_EVENTS = [
18
20
  PROVIDER_READY,
19
21
  PROVIDER_ERROR,
20
22
  PROVIDER_CONFIGURATION_CHANGED,
21
- PROVIDER_STALE
23
+ PROVIDER_STALE,
24
+ PROVIDER_RECONCILING,
25
+ PROVIDER_CONTEXT_CHANGED
22
26
  ].freeze
23
27
  end
24
28
  end
@@ -91,7 +91,7 @@ module OpenFeature
91
91
 
92
92
  def state_from_event(event_type, event_details = nil)
93
93
  case event_type
94
- when ProviderEvent::PROVIDER_READY
94
+ when ProviderEvent::PROVIDER_READY, ProviderEvent::PROVIDER_CONTEXT_CHANGED
95
95
  ProviderState::READY
96
96
  when ProviderEvent::PROVIDER_STALE
97
97
  ProviderState::STALE
@@ -100,7 +100,7 @@ module OpenFeature
100
100
  when ProviderEvent::PROVIDER_CONFIGURATION_CHANGED
101
101
  nil # No state change per OpenFeature spec Requirement 5.3.5
102
102
  else
103
- nil # No state change for unknown events - conservative default
103
+ nil # PROVIDER_RECONCILING (RECONCILING status is static-context only, spec 1.7.2.1) and unknown events
104
104
  end
105
105
  end
106
106
 
@@ -2,6 +2,6 @@
2
2
 
3
3
  module OpenFeature
4
4
  module SDK
5
- VERSION = "0.6.4"
5
+ VERSION = "0.6.6"
6
6
  end
7
7
  end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "lib/open_feature/sdk/version"
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = "openfeature-sdk"
7
+ spec.version = OpenFeature::SDK::VERSION
8
+ spec.authors = ["OpenFeature Authors"]
9
+ spec.email = ["cncf-openfeature-contributors@lists.cncf.io"]
10
+
11
+ spec.summary = "OpenFeature SDK for Ruby"
12
+ spec.description = "Ruby SDK for the OpenFeature specification, an open standard for feature flag management"
13
+ spec.homepage = "https://github.com/open-feature/ruby-sdk"
14
+ spec.license = "Apache-2.0"
15
+ spec.required_ruby_version = ">= 3.4"
16
+
17
+ spec.metadata["homepage_uri"] = spec.homepage
18
+ spec.metadata["source_code_uri"] = "https://github.com/open-feature/ruby-sdk"
19
+ spec.metadata["changelog_uri"] = "https://github.com/open-feature/ruby-sdk/blob/main/CHANGELOG.md"
20
+ spec.metadata["bug_tracker_uri"] = "https://github.com/open-feature/ruby-sdk/issues"
21
+ spec.metadata["documentation_uri"] = "https://github.com/open-feature/ruby-sdk#readme"
22
+ spec.metadata["rubygems_mfa_required"] = "true"
23
+
24
+ # Specify which files should be added to the gem when it is released.
25
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
26
+ spec.files = Dir.chdir(__dir__) do
27
+ `git ls-files -z`.split("\x0").reject do |f|
28
+ (f == __FILE__) || f.match(%r{\A(?:(?:bin|test|spec|features)/|\.(?:git|travis|circleci)|appveyor)})
29
+ end
30
+ end
31
+ spec.bindir = "exe"
32
+ spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
33
+ spec.require_paths = ["lib"]
34
+ end
@@ -0,0 +1,292 @@
1
+ ---
2
+ path: ".gem_rbs_collection"
3
+ gems:
4
+ - name: activesupport
5
+ version: '7.0'
6
+ source:
7
+ type: git
8
+ name: ruby/gem_rbs_collection
9
+ revision: 9bf2eebb1c54b5d6f23f2acb65d4c36f195b4783
10
+ remote: https://github.com/ruby/gem_rbs_collection.git
11
+ repo_dir: gems
12
+ - name: ast
13
+ version: '2.4'
14
+ source:
15
+ type: git
16
+ name: ruby/gem_rbs_collection
17
+ revision: 9bf2eebb1c54b5d6f23f2acb65d4c36f195b4783
18
+ remote: https://github.com/ruby/gem_rbs_collection.git
19
+ repo_dir: gems
20
+ - name: base64
21
+ version: 0.3.0
22
+ source:
23
+ type: rubygems
24
+ - name: bigdecimal
25
+ version: '4.0'
26
+ source:
27
+ type: git
28
+ name: ruby/gem_rbs_collection
29
+ revision: 9bf2eebb1c54b5d6f23f2acb65d4c36f195b4783
30
+ remote: https://github.com/ruby/gem_rbs_collection.git
31
+ repo_dir: gems
32
+ - name: concurrent-ruby
33
+ version: '1.1'
34
+ source:
35
+ type: git
36
+ name: ruby/gem_rbs_collection
37
+ revision: 9bf2eebb1c54b5d6f23f2acb65d4c36f195b4783
38
+ remote: https://github.com/ruby/gem_rbs_collection.git
39
+ repo_dir: gems
40
+ - name: connection_pool
41
+ version: '2.4'
42
+ source:
43
+ type: git
44
+ name: ruby/gem_rbs_collection
45
+ revision: 9bf2eebb1c54b5d6f23f2acb65d4c36f195b4783
46
+ remote: https://github.com/ruby/gem_rbs_collection.git
47
+ repo_dir: gems
48
+ - name: csv
49
+ version: '3.3'
50
+ source:
51
+ type: git
52
+ name: ruby/gem_rbs_collection
53
+ revision: 9bf2eebb1c54b5d6f23f2acb65d4c36f195b4783
54
+ remote: https://github.com/ruby/gem_rbs_collection.git
55
+ repo_dir: gems
56
+ - name: date
57
+ version: '0'
58
+ source:
59
+ type: stdlib
60
+ - name: dbm
61
+ version: '0'
62
+ source:
63
+ type: stdlib
64
+ - name: delegate
65
+ version: '0'
66
+ source:
67
+ type: stdlib
68
+ - name: diff-lcs
69
+ version: '1.5'
70
+ source:
71
+ type: git
72
+ name: ruby/gem_rbs_collection
73
+ revision: 9bf2eebb1c54b5d6f23f2acb65d4c36f195b4783
74
+ remote: https://github.com/ruby/gem_rbs_collection.git
75
+ repo_dir: gems
76
+ - name: digest
77
+ version: '0'
78
+ source:
79
+ type: stdlib
80
+ - name: erb
81
+ version: '0'
82
+ source:
83
+ type: stdlib
84
+ - name: ffi
85
+ version: 1.17.3
86
+ source:
87
+ type: rubygems
88
+ - name: fileutils
89
+ version: '0'
90
+ source:
91
+ type: stdlib
92
+ - name: forwardable
93
+ version: '0'
94
+ source:
95
+ type: stdlib
96
+ - name: i18n
97
+ version: '1.10'
98
+ source:
99
+ type: git
100
+ name: ruby/gem_rbs_collection
101
+ revision: 9bf2eebb1c54b5d6f23f2acb65d4c36f195b4783
102
+ remote: https://github.com/ruby/gem_rbs_collection.git
103
+ repo_dir: gems
104
+ - name: io-console
105
+ version: '0'
106
+ source:
107
+ type: stdlib
108
+ - name: json
109
+ version: '0'
110
+ source:
111
+ type: stdlib
112
+ - name: listen
113
+ version: '3.9'
114
+ source:
115
+ type: git
116
+ name: ruby/gem_rbs_collection
117
+ revision: 9bf2eebb1c54b5d6f23f2acb65d4c36f195b4783
118
+ remote: https://github.com/ruby/gem_rbs_collection.git
119
+ repo_dir: gems
120
+ - name: logger
121
+ version: '0'
122
+ source:
123
+ type: stdlib
124
+ - name: mini_mime
125
+ version: '0.1'
126
+ source:
127
+ type: git
128
+ name: ruby/gem_rbs_collection
129
+ revision: 9bf2eebb1c54b5d6f23f2acb65d4c36f195b4783
130
+ remote: https://github.com/ruby/gem_rbs_collection.git
131
+ repo_dir: gems
132
+ - name: minitest
133
+ version: '5.25'
134
+ source:
135
+ type: git
136
+ name: ruby/gem_rbs_collection
137
+ revision: 9bf2eebb1c54b5d6f23f2acb65d4c36f195b4783
138
+ remote: https://github.com/ruby/gem_rbs_collection.git
139
+ repo_dir: gems
140
+ - name: monitor
141
+ version: '0'
142
+ source:
143
+ type: stdlib
144
+ - name: mutex_m
145
+ version: 0.3.0
146
+ source:
147
+ type: rubygems
148
+ - name: openssl
149
+ version: '0'
150
+ source:
151
+ type: stdlib
152
+ - name: optparse
153
+ version: '0'
154
+ source:
155
+ type: stdlib
156
+ - name: parallel
157
+ version: '1.20'
158
+ source:
159
+ type: git
160
+ name: ruby/gem_rbs_collection
161
+ revision: 9bf2eebb1c54b5d6f23f2acb65d4c36f195b4783
162
+ remote: https://github.com/ruby/gem_rbs_collection.git
163
+ repo_dir: gems
164
+ - name: parser
165
+ version: '3.2'
166
+ source:
167
+ type: git
168
+ name: ruby/gem_rbs_collection
169
+ revision: 9bf2eebb1c54b5d6f23f2acb65d4c36f195b4783
170
+ remote: https://github.com/ruby/gem_rbs_collection.git
171
+ repo_dir: gems
172
+ - name: pp
173
+ version: '0'
174
+ source:
175
+ type: stdlib
176
+ - name: prettyprint
177
+ version: '0'
178
+ source:
179
+ type: stdlib
180
+ - name: prism
181
+ version: 1.9.0
182
+ source:
183
+ type: rubygems
184
+ - name: pstore
185
+ version: '0'
186
+ source:
187
+ type: stdlib
188
+ - name: psych
189
+ version: '0'
190
+ source:
191
+ type: stdlib
192
+ - name: rainbow
193
+ version: '3.0'
194
+ source:
195
+ type: git
196
+ name: ruby/gem_rbs_collection
197
+ revision: 9bf2eebb1c54b5d6f23f2acb65d4c36f195b4783
198
+ remote: https://github.com/ruby/gem_rbs_collection.git
199
+ repo_dir: gems
200
+ - name: rake
201
+ version: '13.0'
202
+ source:
203
+ type: git
204
+ name: ruby/gem_rbs_collection
205
+ revision: 9bf2eebb1c54b5d6f23f2acb65d4c36f195b4783
206
+ remote: https://github.com/ruby/gem_rbs_collection.git
207
+ repo_dir: gems
208
+ - name: rbs
209
+ version: 3.10.3
210
+ source:
211
+ type: rubygems
212
+ - name: rdoc
213
+ version: '0'
214
+ source:
215
+ type: stdlib
216
+ - name: regexp_parser
217
+ version: '2.8'
218
+ source:
219
+ type: git
220
+ name: ruby/gem_rbs_collection
221
+ revision: 9bf2eebb1c54b5d6f23f2acb65d4c36f195b4783
222
+ remote: https://github.com/ruby/gem_rbs_collection.git
223
+ repo_dir: gems
224
+ - name: rubocop
225
+ version: '1.57'
226
+ source:
227
+ type: git
228
+ name: ruby/gem_rbs_collection
229
+ revision: 9bf2eebb1c54b5d6f23f2acb65d4c36f195b4783
230
+ remote: https://github.com/ruby/gem_rbs_collection.git
231
+ repo_dir: gems
232
+ - name: rubocop-ast
233
+ version: '1.46'
234
+ source:
235
+ type: git
236
+ name: ruby/gem_rbs_collection
237
+ revision: 9bf2eebb1c54b5d6f23f2acb65d4c36f195b4783
238
+ remote: https://github.com/ruby/gem_rbs_collection.git
239
+ repo_dir: gems
240
+ - name: securerandom
241
+ version: '0'
242
+ source:
243
+ type: stdlib
244
+ - name: simplecov
245
+ version: '0.22'
246
+ source:
247
+ type: git
248
+ name: ruby/gem_rbs_collection
249
+ revision: 9bf2eebb1c54b5d6f23f2acb65d4c36f195b4783
250
+ remote: https://github.com/ruby/gem_rbs_collection.git
251
+ repo_dir: gems
252
+ - name: singleton
253
+ version: '0'
254
+ source:
255
+ type: stdlib
256
+ - name: socket
257
+ version: '0'
258
+ source:
259
+ type: stdlib
260
+ - name: stringio
261
+ version: '0'
262
+ source:
263
+ type: stdlib
264
+ - name: strscan
265
+ version: '0'
266
+ source:
267
+ type: stdlib
268
+ - name: time
269
+ version: '0'
270
+ source:
271
+ type: stdlib
272
+ - name: timeout
273
+ version: '0'
274
+ source:
275
+ type: stdlib
276
+ - name: tsort
277
+ version: '0'
278
+ source:
279
+ type: stdlib
280
+ - name: tzinfo
281
+ version: '2.0'
282
+ source:
283
+ type: git
284
+ name: ruby/gem_rbs_collection
285
+ revision: 9bf2eebb1c54b5d6f23f2acb65d4c36f195b4783
286
+ remote: https://github.com/ruby/gem_rbs_collection.git
287
+ repo_dir: gems
288
+ - name: uri
289
+ version: '0'
290
+ source:
291
+ type: stdlib
292
+ gemfile_lock_path: Gemfile.lock
@@ -0,0 +1,14 @@
1
+ sources:
2
+ - type: git
3
+ name: ruby/gem_rbs_collection
4
+ remote: https://github.com/ruby/gem_rbs_collection.git
5
+ revision: main
6
+ repo_dir: gems
7
+
8
+ path: .gem_rbs_collection
9
+
10
+ gems:
11
+ - name: singleton
12
+ - name: forwardable
13
+ - name: delegate
14
+ - name: timeout