openfeature-sdk 0.5.1 → 0.6.0

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 36540a362c2f482ce84d2aa8ba3a6efd9b5d68fe7881ed4037f1422ad85f5525
4
- data.tar.gz: 4f7e6a764074d50467949e056b0d50be794df0a67323bb80c5e34a724236314b
3
+ metadata.gz: af657f35506e7f76184269c57877bbe87cb75f03a2e697e228e9b48f0b2bb17c
4
+ data.tar.gz: 57944d4c3a74838e73a1f55b4f06e9b82ec4b5186c76ad000577504b30d72d88
5
5
  SHA512:
6
- metadata.gz: b77f6731c17b537069bbf72cf4760e88293bc59c9ae147079ff3b24ac6ac7f1b18b42b49e29fd1a04a85a6054d0a43834289561c06d6b342ba579ec23d510ef8
7
- data.tar.gz: 077d8a3f20c396c82413dad70b9a93cff0cd27a76ff8034f67c50bfa0d08235e3424755a4cd33b81c39fed962d7a62e40d1f257d3bbc4e87bac787d0e315b3fb
6
+ metadata.gz: 8dc359e5bb318d79e2fcb48bc0c393c055578cf0a331b02bc61f82910b3da973eaf487457db80d9cd73f12303b15a77cbef9062481933c3d7b4c305de0ed1cc2
7
+ data.tar.gz: c733ce2f12dbd64ad9fd4e42a5c6cd17c805aa0ab746408c222aee42e6af5ba385ff92baf6cffbf79e4e949dbd7e6b5b2c67937694717ef5b41396353b9f9391
@@ -1,3 +1,3 @@
1
1
  {
2
- ".": "0.5.1"
2
+ ".": "0.6.0"
3
3
  }
data/.ruby-version CHANGED
@@ -1 +1 @@
1
- 3.4.8
1
+ 4.0.1
data/.tool-versions CHANGED
@@ -1 +1 @@
1
- ruby 3.4.8
1
+ ruby 4.0.1
data/CHANGELOG.md CHANGED
@@ -1,5 +1,16 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.6.0](https://github.com/open-feature/ruby-sdk/compare/v0.5.1...v0.6.0) (2026-03-05)
4
+
5
+
6
+ ### ⚠ BREAKING CHANGES
7
+
8
+ * add Ruby 4.0 support, require minimum Ruby 3.4 ([#217](https://github.com/open-feature/ruby-sdk/issues/217))
9
+
10
+ ### Features
11
+
12
+ * add Ruby 4.0 support, require minimum Ruby 3.4 ([#217](https://github.com/open-feature/ruby-sdk/issues/217)) ([f38ba40](https://github.com/open-feature/ruby-sdk/commit/f38ba40b31beb650ba475c631947fc7969e476fa))
13
+
3
14
  ## [0.5.1](https://github.com/open-feature/ruby-sdk/compare/v0.5.0...v0.5.1) (2026-03-04)
4
15
 
5
16
 
data/CLAUDE.md CHANGED
@@ -2,71 +2,50 @@
2
2
 
3
3
  This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4
4
 
5
- ## Project Overview
5
+ ## Overview
6
6
 
7
- OpenFeature Ruby SDK implements the [OpenFeature specification](https://openfeature.dev) (v0.8.0) for vendor-agnostic feature flag management. Published as the `openfeature-sdk` gem. Pure Ruby, no runtime dependencies. Requires Ruby >= 3.1.
7
+ This is the official OpenFeature SDK for Ruby — an implementation of the [OpenFeature specification](https://openfeature.dev) providing a vendor-agnostic API for feature flag evaluation. Published as the `openfeature-sdk` gem. Requires Ruby >= 3.1.
8
8
 
9
9
  ## Commands
10
10
 
11
- ```bash
12
- # Install dependencies
13
- bundle install
11
+ - **Run all tests:** `bundle exec rspec`
12
+ - **Run a single test file:** `bundle exec rspec spec/open_feature/sdk/client_spec.rb`
13
+ - **Run a specific test by line:** `bundle exec rspec spec/open_feature/sdk/client_spec.rb:43`
14
+ - **Lint:** `bundle exec standardrb`
15
+ - **Lint with autofix:** `bundle exec standardrb --fix`
16
+ - **Default rake (tests + lint):** `bundle exec rake`
14
17
 
15
- # Run full test suite + linting (default rake task)
16
- bundle exec rake
18
+ Note: Linting uses [Standard Ruby](https://github.com/standardrb/standard) (configured via the `standard` gem), which enforces double-quoted strings and its own opinionated style. There is no `.rubocop.yml` — Standard manages RuboCop configuration internally. Do not use `bundle exec rubocop` directly as a stale RuboCop server may apply different rules; always use `bundle exec standardrb`.
17
19
 
18
- # Run tests only
19
- bundle exec rspec
20
-
21
- # Run a single test file
22
- bundle exec rspec spec/open_feature/sdk/client_spec.rb
23
-
24
- # Run a specific test by line number
25
- bundle exec rspec spec/open_feature/sdk/client_spec.rb:40
26
-
27
- # Lint (StandardRB with performance plugin)
28
- bundle exec rake standard
20
+ ## Architecture
29
21
 
30
- # Auto-fix lint issues
31
- bundle exec standardrb --fix
32
- ```
22
+ ### Entry point and API singleton
33
23
 
34
- ## Architecture
24
+ `OpenFeature::SDK` (in `lib/open_feature/sdk.rb`) delegates all method calls to `API.instance` via `method_missing`. `API` is a Singleton that holds a `Configuration` object and builds `Client` instances.
35
25
 
36
- Entry point: `require 'open_feature/sdk'` — the `OpenFeature::SDK` module delegates all method calls to `API.instance` (Singleton) via `method_missing`.
26
+ ### Provider duck type
37
27
 
38
- ### Core Components
28
+ Providers are not subclasses — they follow a duck type interface. Any object implementing `fetch_boolean_value`, `fetch_string_value`, `fetch_number_value`, `fetch_integer_value`, `fetch_float_value`, and `fetch_object_value` (all accepting `flag_key:`, `default_value:`, `evaluation_context:`) works as a provider. Each method must return a `ResolutionDetails` struct. Two built-in providers exist: `NoOpProvider` (default) and `InMemoryProvider` (for testing). Providers may optionally implement `init(evaluation_context)`, `shutdown`, and `metadata`.
39
29
 
40
- - **API** (`lib/open_feature/sdk/api.rb`) Singleton orchestrator. Manages providers (global or domain-scoped), builds clients, stores API-level evaluation context, and registers event handlers.
41
- - **Configuration** (`lib/open_feature/sdk/configuration.rb`) — Thread-safe provider storage. Handles provider lifecycle (init/shutdown), domain-scoped provider mapping, and event dispatching. Uses Mutex for all shared state.
42
- - **Client** (`lib/open_feature/sdk/client.rb`) — Flag evaluation interface. Uses `class_eval` metaprogramming to generate 12 typed methods: `fetch_{boolean,string,number,integer,float,object}_value` and `fetch_*_details` variants. Merges evaluation contexts (API + client + invocation).
43
- - **EvaluationContext** (`lib/open_feature/sdk/evaluation_context.rb`) — Key-value targeting data with a special `targeting_key`. Supports merging with precedence: invocation > client > API.
30
+ ### Client dynamic method generation
44
31
 
45
- ### Provider System
32
+ `Client` uses `class_eval` to metaprogram `fetch_<type>_value` and `fetch_<type>_details` methods from `RESULT_TYPE` and `SUFFIXES` arrays. This generates 12 public methods (6 types × 2 suffixes).
46
33
 
47
- - **Provider interface** — Must implement 6 `fetch_*_value` methods, optional `init(evaluation_context)` and `shutdown`. Returns `ResolutionDetails`.
48
- - **EventEmitter** (`lib/open_feature/sdk/provider/event_emitter.rb`) — Mixin that providers include to emit lifecycle events.
49
- - **Built-in providers**: `NoOpProvider` (default), `InMemoryProvider` (testing/examples).
50
- - **Provider states**: `NOT_READY → READY`, with `ERROR`, `FATAL`, `STALE` transitions. Tracked per-instance via `ProviderStateRegistry` using `object_id`.
51
- - **Initialization modes**: `set_provider` (async, background thread) or `set_provider_and_wait` (sync, raises `ProviderInitializationError` on failure).
34
+ ### Evaluation context merging
52
35
 
53
- ### Event System
36
+ `EvaluationContextBuilder` merges three layers of context with this precedence: invocation > client > API (global). Context is a hash-like object with a special `targeting_key` field.
54
37
 
55
- - **EventDispatcher** (`lib/open_feature/sdk/event_dispatcher.rb`) — Thread-safe pub-sub. Handlers called outside mutex to prevent deadlocks. Supports API-level and client-level handlers.
56
- - **ProviderEvent** constants: `PROVIDER_READY`, `PROVIDER_ERROR`, `PROVIDER_STALE`, `PROVIDER_CONFIGURATION_CHANGED`.
38
+ ### Provider eventing
57
39
 
58
- ## Test Structure
40
+ `Configuration` manages provider lifecycle events (READY, ERROR, STALE, CONFIGURATION_CHANGED). Providers can emit spontaneous events by including `Provider::EventEmitter`. Event handlers can be registered at API level (global) or client level (domain-scoped). `ProviderStateRegistry` tracks provider states; `EventDispatcher` manages handler registration and invocation.
59
41
 
60
- Tests in `spec/` split into two categories:
61
- - `spec/specification/` — OpenFeature spec compliance tests, organized by requirement number (e.g., "Requirement 1.1.1")
62
- - `spec/open_feature/` — Unit tests for individual components
42
+ ### Domain-based provider binding
63
43
 
64
- Uses Timecop for time-sensitive tests (auto-reset after each test), SimpleCov for coverage.
44
+ Providers can be registered for specific domains. `Configuration#provider(domain:)` resolves domain-specific providers, falling back to the default (nil-domain) provider. Clients are built with an optional `domain:` that binds them to a specific provider.
65
45
 
66
46
  ## Conventions
67
47
 
68
- - **Linter**: StandardRB (Ruby Standard Style) with `standard-performance` plugin, targeting Ruby 3.1
69
- - **Commits**: Conventional Commits required for PR titles (enforced by CI)
70
- - **Releases**: Automated via release-please; changelog auto-generated
71
- - **Threading**: All shared mutable state must be Mutex-protected. Provider storage uses immutable reassignment (`@providers = @providers.dup.merge(...)`)
72
- - **Structs for DTOs**: `EvaluationDetails`, `ResolutionDetails`, `ClientMetadata`, `ProviderMetadata` are `Struct`-based
48
+ - All `.rb` files must have `# frozen_string_literal: true` as the first line.
49
+ - Tests live under `spec/` and mirror the `lib/` structure. `spec/specification/` contains tests mapped to OpenFeature spec requirements.
50
+ - Always sign git commits using the `-S` flag.
51
+ - Always include DCO sign-off in commits using the `-s` flag (i.e., `git commit -s -S`). This adds a `Signed-off-by` trailer required by the project's CI.
data/Gemfile.lock CHANGED
@@ -1,41 +1,51 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- openfeature-sdk (0.5.1)
4
+ openfeature-sdk (0.6.0)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
8
8
  specs:
9
- ast (2.4.2)
10
- debug (1.9.2)
9
+ ast (2.4.3)
10
+ date (3.5.1)
11
+ debug (1.11.1)
11
12
  irb (~> 1.10)
12
13
  reline (>= 0.3.8)
13
- diff-lcs (1.5.1)
14
- docile (1.4.0)
15
- io-console (0.7.2)
16
- irb (1.12.0)
17
- rdoc
14
+ diff-lcs (1.6.2)
15
+ docile (1.4.1)
16
+ erb (6.0.2)
17
+ io-console (0.8.2)
18
+ irb (1.17.0)
19
+ pp (>= 0.6.0)
20
+ prism (>= 1.3.0)
21
+ rdoc (>= 4.0.0)
18
22
  reline (>= 0.4.2)
19
- json (2.7.1)
20
- language_server-protocol (3.17.0.3)
23
+ json (2.18.1)
24
+ language_server-protocol (3.17.0.5)
21
25
  lint_roller (1.1.0)
22
- markly (0.10.0)
23
- parallel (1.24.0)
24
- parser (3.3.0.5)
26
+ markly (0.15.2)
27
+ parallel (1.27.0)
28
+ parser (3.3.10.2)
25
29
  ast (~> 2.4.1)
26
30
  racc
27
- psych (5.1.2)
31
+ pp (0.6.3)
32
+ prettyprint
33
+ prettyprint (0.2.0)
34
+ prism (1.9.0)
35
+ psych (5.3.1)
36
+ date
28
37
  stringio
29
- racc (1.7.3)
38
+ racc (1.8.1)
30
39
  rainbow (3.1.1)
31
- rake (13.1.0)
32
- rdoc (6.6.3.1)
40
+ rake (13.3.1)
41
+ rdoc (7.2.0)
42
+ erb
33
43
  psych (>= 4.0.0)
34
- regexp_parser (2.9.0)
35
- reline (0.5.0)
44
+ tsort
45
+ regexp_parser (2.11.3)
46
+ reline (0.6.3)
36
47
  io-console (~> 0.5)
37
- rexml (3.3.6)
38
- strscan
48
+ rexml (3.4.4)
39
49
  rspec (3.12.0)
40
50
  rspec-core (~> 3.12.0)
41
51
  rspec-expectations (~> 3.12.0)
@@ -49,54 +59,59 @@ GEM
49
59
  diff-lcs (>= 1.2.0, < 2.0)
50
60
  rspec-support (~> 3.12.0)
51
61
  rspec-support (3.12.2)
52
- rubocop (1.62.1)
62
+ rubocop (1.84.2)
53
63
  json (~> 2.3)
54
- language_server-protocol (>= 3.17.0)
64
+ language_server-protocol (~> 3.17.0.2)
65
+ lint_roller (~> 1.1.0)
55
66
  parallel (~> 1.10)
56
67
  parser (>= 3.3.0.2)
57
68
  rainbow (>= 2.2.2, < 4.0)
58
- regexp_parser (>= 1.8, < 3.0)
59
- rexml (>= 3.2.5, < 4.0)
60
- rubocop-ast (>= 1.31.1, < 2.0)
69
+ regexp_parser (>= 2.9.3, < 3.0)
70
+ rubocop-ast (>= 1.49.0, < 2.0)
61
71
  ruby-progressbar (~> 1.7)
62
- unicode-display_width (>= 2.4.0, < 3.0)
63
- rubocop-ast (1.31.2)
64
- parser (>= 3.3.0.4)
65
- rubocop-performance (1.20.2)
66
- rubocop (>= 1.48.1, < 2.0)
67
- rubocop-ast (>= 1.30.0, < 2.0)
72
+ unicode-display_width (>= 2.4.0, < 4.0)
73
+ rubocop-ast (1.49.0)
74
+ parser (>= 3.3.7.2)
75
+ prism (~> 1.7)
76
+ rubocop-performance (1.26.1)
77
+ lint_roller (~> 1.1)
78
+ rubocop (>= 1.75.0, < 2.0)
79
+ rubocop-ast (>= 1.47.1, < 2.0)
68
80
  ruby-progressbar (1.13.0)
69
81
  simplecov (0.22.0)
70
82
  docile (~> 1.1)
71
83
  simplecov-html (~> 0.11)
72
84
  simplecov_json_formatter (~> 0.1)
73
- simplecov-cobertura (2.1.0)
85
+ simplecov-cobertura (3.1.0)
74
86
  rexml
75
87
  simplecov (~> 0.19)
76
- simplecov-html (0.12.3)
88
+ simplecov-html (0.13.2)
77
89
  simplecov_json_formatter (0.1.4)
78
- standard (1.35.1)
90
+ standard (1.54.0)
79
91
  language_server-protocol (~> 3.17.0.2)
80
92
  lint_roller (~> 1.0)
81
- rubocop (~> 1.62.0)
93
+ rubocop (~> 1.84.0)
82
94
  standard-custom (~> 1.0.0)
83
- standard-performance (~> 1.3)
95
+ standard-performance (~> 1.8)
84
96
  standard-custom (1.0.2)
85
97
  lint_roller (~> 1.0)
86
98
  rubocop (~> 1.50)
87
- standard-performance (1.3.1)
99
+ standard-performance (1.9.0)
88
100
  lint_roller (~> 1.1)
89
- rubocop-performance (~> 1.20.2)
90
- stringio (3.1.0)
91
- strscan (3.1.0)
101
+ rubocop-performance (~> 1.26.0)
102
+ stringio (3.2.0)
92
103
  timecop (0.9.10)
93
- unicode-display_width (2.5.0)
104
+ tsort (0.2.0)
105
+ unicode-display_width (3.2.0)
106
+ unicode-emoji (~> 4.1)
107
+ unicode-emoji (4.2.0)
94
108
 
95
109
  PLATFORMS
96
110
  arm64-darwin-21
97
111
  arm64-darwin-22
98
112
  arm64-darwin-23
99
113
  arm64-darwin-24
114
+ arm64-darwin-25
100
115
  x64-mingw-ucrt
101
116
  x64-mingw32
102
117
  x86_64-darwin-19
@@ -111,7 +126,7 @@ DEPENDENCIES
111
126
  rake (~> 13.0)
112
127
  rspec (~> 3.12.0)
113
128
  simplecov (~> 0.22.0)
114
- simplecov-cobertura (~> 2.1.0)
129
+ simplecov-cobertura (~> 3.0)
115
130
  standard
116
131
  standard-performance
117
132
  timecop (~> 0.9.10)
data/README.md CHANGED
@@ -17,8 +17,8 @@
17
17
  </a>
18
18
  <!-- x-release-please-start-version -->
19
19
 
20
- <a href="https://github.com/open-feature/ruby-sdk/releases/tag/v0.5.1">
21
- <img alt="Release" src="https://img.shields.io/static/v1?label=release&message=v0.5.1&color=blue&style=for-the-badge" />
20
+ <a href="https://github.com/open-feature/ruby-sdk/releases/tag/v0.6.0">
21
+ <img alt="Release" src="https://img.shields.io/static/v1?label=release&message=v0.6.0&color=blue&style=for-the-badge" />
22
22
  </a>
23
23
 
24
24
  <!-- x-release-please-end -->
@@ -38,9 +38,8 @@
38
38
 
39
39
  | Supported Ruby Version | OS |
40
40
  | ------------ | --------------------- |
41
- | Ruby 3.1.4 | Windows, MacOS, Linux |
42
- | Ruby 3.2.3 | Windows, MacOS, Linux |
43
- | Ruby 3.3.0 | Windows, MacOS, Linux |
41
+ | Ruby 3.4.x | Windows, MacOS, Linux |
42
+ | Ruby 4.0.x | Windows, MacOS, Linux |
44
43
 
45
44
  ### Install
46
45
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module OpenFeature
2
4
  module SDK
3
5
  ClientMetadata = Struct.new(:domain, keyword_init: true)
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module OpenFeature
2
4
  module SDK
3
5
  class EvaluationContext
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module OpenFeature
2
4
  module SDK
3
5
  # Used to combine evaluation contexts from different sources
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module OpenFeature
2
4
  module SDK
3
5
  EvaluationDetails = Struct.new(:flag_key, :resolution_details, keyword_init: true) do
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module OpenFeature
2
4
  module SDK
3
5
  module Provider
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module OpenFeature
2
4
  module SDK
3
5
  module Provider
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module OpenFeature
2
4
  module SDK
3
5
  module Provider
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module OpenFeature
2
4
  module SDK
3
5
  module Provider
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module OpenFeature
2
4
  module SDK
3
5
  module Provider
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require_relative "provider/error_code"
2
4
  require_relative "provider/reason"
3
5
  require_relative "provider/resolution_details"
@@ -2,6 +2,6 @@
2
2
 
3
3
  module OpenFeature
4
4
  module SDK
5
- VERSION = "0.5.1"
5
+ VERSION = "0.6.0"
6
6
  end
7
7
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: openfeature-sdk
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.1
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - OpenFeature Authors
@@ -113,14 +113,14 @@ dependencies:
113
113
  requirements:
114
114
  - - "~>"
115
115
  - !ruby/object:Gem::Version
116
- version: 2.1.0
116
+ version: '3.0'
117
117
  type: :development
118
118
  prerelease: false
119
119
  version_requirements: !ruby/object:Gem::Requirement
120
120
  requirements:
121
121
  - - "~>"
122
122
  - !ruby/object:Gem::Version
123
- version: 2.1.0
123
+ version: '3.0'
124
124
  - !ruby/object:Gem::Dependency
125
125
  name: timecop
126
126
  requirement: !ruby/object:Gem::Requirement
@@ -204,14 +204,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
204
204
  requirements:
205
205
  - - ">="
206
206
  - !ruby/object:Gem::Version
207
- version: '3.1'
207
+ version: '3.4'
208
208
  required_rubygems_version: !ruby/object:Gem::Requirement
209
209
  requirements:
210
210
  - - ">="
211
211
  - !ruby/object:Gem::Version
212
212
  version: '0'
213
213
  requirements: []
214
- rubygems_version: 3.6.9
214
+ rubygems_version: 4.0.3
215
215
  specification_version: 4
216
216
  summary: OpenFeature SDK for Ruby
217
217
  test_files: []