openfeature-sdk 0.1.0 → 0.2.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 +4 -4
- data/.release-please-manifest.json +1 -1
- data/.ruby-version +1 -1
- data/.simplecov +12 -0
- data/.standard.yml +5 -0
- data/.tool-versions +1 -0
- data/CHANGELOG.md +29 -0
- data/CODEOWNERS +6 -0
- data/Gemfile.lock +73 -20
- data/README.md +38 -7
- data/Rakefile +2 -7
- data/lib/{openfeature → open_feature}/sdk/api.rb +6 -7
- data/lib/{openfeature → open_feature}/sdk/client.rb +3 -2
- data/lib/open_feature/sdk/configuration.rb +42 -0
- data/lib/open_feature/sdk/evaluation_details.rb +9 -0
- data/lib/open_feature/sdk/provider/error_code.rb +15 -0
- data/lib/open_feature/sdk/provider/in_memory_provider.rb +62 -0
- data/lib/{openfeature → open_feature}/sdk/provider/no_op_provider.rb +1 -3
- data/lib/open_feature/sdk/provider/reason.rb +17 -0
- data/lib/open_feature/sdk/provider/resolution_details.rb +7 -0
- data/lib/open_feature/sdk/provider.rb +12 -0
- data/lib/{openfeature → open_feature}/sdk/version.rb +1 -1
- data/lib/{openfeature → open_feature}/sdk.rb +2 -2
- data/release-please-config.json +1 -1
- data/renovate.json +11 -0
- metadata +94 -16
- data/.rubocop.yml +0 -28
- data/lib/openfeature/sdk/configuration.rb +0 -25
- data/sig/openfeature/sdk.rbs +0 -6
- /data/lib/{openfeature → open_feature}/sdk/metadata.rb +0 -0
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: ef370095e429959ee1d1c0089e9a9e321cc3e4a2345f059aae26b8d965adf1b3
|
|
4
|
+
data.tar.gz: c00d676c31455f90592bd1ff604816f468750576e5a181d3b9f02d81c27dd878
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 7d7d24acecc2f9de37b64d037316f17c58138ab78b4ef71923ec8e403fabb94d739b9bc66611a31e50012774f88792b8b9823049202a519da6b13f188a2ec389
|
|
7
|
+
data.tar.gz: d9830c29d198b3a4b7f0aef3da391d08ac4a30042eb0bbc47e9b30602ee806e5bb76794243dfa2ea1ed235ab0a8d17ea9b64184a6de6d900a4d7d1b82f0c06b1
|
data/.ruby-version
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
3.
|
|
1
|
+
3.3.0
|
data/.simplecov
ADDED
data/.standard.yml
ADDED
data/.tool-versions
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
ruby 3.3.0
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,34 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.2.0](https://github.com/open-feature/ruby-sdk/compare/v0.1.1...v0.2.0) (2024-03-09)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### ⚠ BREAKING CHANGES
|
|
7
|
+
|
|
8
|
+
* Implement Requirement 1.1.3 ([#80](https://github.com/open-feature/ruby-sdk/issues/80))
|
|
9
|
+
* rename top-level lib folder to `open_feature` ([#90](https://github.com/open-feature/ruby-sdk/issues/90))
|
|
10
|
+
* Drop Ruby 2.7 and 3.0, add Ruby 3.3 ([#91](https://github.com/open-feature/ruby-sdk/issues/91))
|
|
11
|
+
|
|
12
|
+
### Features
|
|
13
|
+
|
|
14
|
+
* adds `InMemoryProvider` ([#102](https://github.com/open-feature/ruby-sdk/issues/102)) ([25680a4](https://github.com/open-feature/ruby-sdk/commit/25680a40b0955ee66da256f23f7078655754a4b6))
|
|
15
|
+
* Implement Requirement 1.1.2 ([#78](https://github.com/open-feature/ruby-sdk/issues/78)) ([8cea7d0](https://github.com/open-feature/ruby-sdk/commit/8cea7d0cefc31ddeb2095ac60c40db3b038b02c5))
|
|
16
|
+
* Implement Requirement 1.1.3 ([#80](https://github.com/open-feature/ruby-sdk/issues/80)) ([bc65e7a](https://github.com/open-feature/ruby-sdk/commit/bc65e7a2754d736e858a856fd39118940c63ee41))
|
|
17
|
+
* Updates to `Provider` module in preparation for `InMemoryProvider` ([#99](https://github.com/open-feature/ruby-sdk/issues/99)) ([2d89570](https://github.com/open-feature/ruby-sdk/commit/2d89570b2ebace61bcb261cfcb54b2724a4a75f7))
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
### Miscellaneous Chores
|
|
21
|
+
|
|
22
|
+
* Drop Ruby 2.7 and 3.0, add Ruby 3.3 ([#91](https://github.com/open-feature/ruby-sdk/issues/91)) ([51cd3a1](https://github.com/open-feature/ruby-sdk/commit/51cd3a1801e589f9049bffd7349d56bb6d32d05e))
|
|
23
|
+
* rename top-level lib folder to `open_feature` ([#90](https://github.com/open-feature/ruby-sdk/issues/90)) ([e1a9a01](https://github.com/open-feature/ruby-sdk/commit/e1a9a018e18cb62acedd1b5cd5a00ad3ecb4321a))
|
|
24
|
+
|
|
25
|
+
## [0.1.1](https://github.com/open-feature/ruby-sdk/compare/v0.1.0...v0.1.1) (2023-09-13)
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
### Bug Fixes
|
|
29
|
+
|
|
30
|
+
* OpenFeature::SDK::Configuration uses concurrent-ruby gem even though it doesn't depend on it ([#61](https://github.com/open-feature/ruby-sdk/issues/61)) ([c3c1222](https://github.com/open-feature/ruby-sdk/commit/c3c12226a21e43d62358562f4008a4a44a10e72b))
|
|
31
|
+
|
|
3
32
|
## [0.1.0](https://github.com/open-feature/ruby-sdk/compare/v0.0.3...v0.1.0) (2022-12-15)
|
|
4
33
|
|
|
5
34
|
|
data/CODEOWNERS
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
# These owners will be the default owners for everything in
|
|
2
|
+
# the repo. Unless a later match takes precedence
|
|
3
|
+
#
|
|
4
|
+
# Managed by Peribolos: https://github.com/open-feature/community/blob/main/config/open-feature/sdk-ruby/workgroup.yaml
|
|
5
|
+
#
|
|
6
|
+
* @open-feature/sdk-ruby-maintainers
|
data/Gemfile.lock
CHANGED
|
@@ -1,53 +1,101 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
openfeature-sdk (0.
|
|
4
|
+
openfeature-sdk (0.2.0)
|
|
5
5
|
|
|
6
6
|
GEM
|
|
7
7
|
remote: https://rubygems.org/
|
|
8
8
|
specs:
|
|
9
9
|
ast (2.4.2)
|
|
10
|
-
|
|
10
|
+
base64 (0.1.1)
|
|
11
|
+
concurrent-ruby (1.2.3)
|
|
12
|
+
debug (1.9.1)
|
|
13
|
+
irb (~> 1.10)
|
|
14
|
+
reline (>= 0.3.8)
|
|
11
15
|
diff-lcs (1.5.0)
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
16
|
+
docile (1.4.0)
|
|
17
|
+
io-console (0.7.2)
|
|
18
|
+
irb (1.11.2)
|
|
19
|
+
rdoc
|
|
20
|
+
reline (>= 0.4.2)
|
|
21
|
+
json (2.6.3)
|
|
22
|
+
language_server-protocol (3.17.0.3)
|
|
23
|
+
lint_roller (1.1.0)
|
|
24
|
+
markly (0.10.0)
|
|
25
|
+
parallel (1.23.0)
|
|
26
|
+
parser (3.2.2.3)
|
|
15
27
|
ast (~> 2.4.1)
|
|
28
|
+
racc
|
|
29
|
+
psych (5.1.2)
|
|
30
|
+
stringio
|
|
31
|
+
racc (1.7.1)
|
|
16
32
|
rainbow (3.1.1)
|
|
17
33
|
rake (13.0.6)
|
|
18
|
-
|
|
19
|
-
|
|
34
|
+
rdoc (6.6.2)
|
|
35
|
+
psych (>= 4.0.0)
|
|
36
|
+
regexp_parser (2.8.1)
|
|
37
|
+
reline (0.4.3)
|
|
38
|
+
io-console (~> 0.5)
|
|
39
|
+
rexml (3.2.6)
|
|
20
40
|
rspec (3.12.0)
|
|
21
41
|
rspec-core (~> 3.12.0)
|
|
22
42
|
rspec-expectations (~> 3.12.0)
|
|
23
43
|
rspec-mocks (~> 3.12.0)
|
|
24
|
-
rspec-core (3.12.
|
|
44
|
+
rspec-core (3.12.2)
|
|
25
45
|
rspec-support (~> 3.12.0)
|
|
26
|
-
rspec-expectations (3.12.
|
|
46
|
+
rspec-expectations (3.12.3)
|
|
27
47
|
diff-lcs (>= 1.2.0, < 2.0)
|
|
28
48
|
rspec-support (~> 3.12.0)
|
|
29
|
-
rspec-mocks (3.12.
|
|
49
|
+
rspec-mocks (3.12.6)
|
|
30
50
|
diff-lcs (>= 1.2.0, < 2.0)
|
|
31
51
|
rspec-support (~> 3.12.0)
|
|
32
|
-
rspec-support (3.12.
|
|
33
|
-
rubocop (1.
|
|
52
|
+
rspec-support (3.12.1)
|
|
53
|
+
rubocop (1.56.3)
|
|
54
|
+
base64 (~> 0.1.1)
|
|
34
55
|
json (~> 2.3)
|
|
56
|
+
language_server-protocol (>= 3.17.0)
|
|
35
57
|
parallel (~> 1.10)
|
|
36
|
-
parser (>= 3.
|
|
58
|
+
parser (>= 3.2.2.3)
|
|
37
59
|
rainbow (>= 2.2.2, < 4.0)
|
|
38
60
|
regexp_parser (>= 1.8, < 3.0)
|
|
39
61
|
rexml (>= 3.2.5, < 4.0)
|
|
40
|
-
rubocop-ast (>= 1.
|
|
62
|
+
rubocop-ast (>= 1.28.1, < 2.0)
|
|
41
63
|
ruby-progressbar (~> 1.7)
|
|
42
|
-
unicode-display_width (>=
|
|
43
|
-
rubocop-ast (1.
|
|
44
|
-
parser (>= 3.
|
|
45
|
-
|
|
46
|
-
|
|
64
|
+
unicode-display_width (>= 2.4.0, < 3.0)
|
|
65
|
+
rubocop-ast (1.29.0)
|
|
66
|
+
parser (>= 3.2.1.0)
|
|
67
|
+
rubocop-performance (1.19.0)
|
|
68
|
+
rubocop (>= 1.7.0, < 2.0)
|
|
69
|
+
rubocop-ast (>= 0.4.0)
|
|
70
|
+
ruby-progressbar (1.13.0)
|
|
71
|
+
simplecov (0.22.0)
|
|
72
|
+
docile (~> 1.1)
|
|
73
|
+
simplecov-html (~> 0.11)
|
|
74
|
+
simplecov_json_formatter (~> 0.1)
|
|
75
|
+
simplecov-cobertura (2.1.0)
|
|
76
|
+
rexml
|
|
77
|
+
simplecov (~> 0.19)
|
|
78
|
+
simplecov-html (0.12.3)
|
|
79
|
+
simplecov_json_formatter (0.1.4)
|
|
80
|
+
standard (1.31.1)
|
|
81
|
+
language_server-protocol (~> 3.17.0.2)
|
|
82
|
+
lint_roller (~> 1.0)
|
|
83
|
+
rubocop (~> 1.56.2)
|
|
84
|
+
standard-custom (~> 1.0.0)
|
|
85
|
+
standard-performance (~> 1.2)
|
|
86
|
+
standard-custom (1.0.2)
|
|
87
|
+
lint_roller (~> 1.0)
|
|
88
|
+
rubocop (~> 1.50)
|
|
89
|
+
standard-performance (1.2.0)
|
|
90
|
+
lint_roller (~> 1.1)
|
|
91
|
+
rubocop-performance (~> 1.19.0)
|
|
92
|
+
stringio (3.1.0)
|
|
93
|
+
unicode-display_width (2.4.2)
|
|
47
94
|
|
|
48
95
|
PLATFORMS
|
|
49
96
|
arm64-darwin-21
|
|
50
97
|
arm64-darwin-22
|
|
98
|
+
arm64-darwin-23
|
|
51
99
|
x64-mingw-ucrt
|
|
52
100
|
x64-mingw32
|
|
53
101
|
x86_64-darwin-19
|
|
@@ -57,10 +105,15 @@ PLATFORMS
|
|
|
57
105
|
|
|
58
106
|
DEPENDENCIES
|
|
59
107
|
concurrent-ruby
|
|
108
|
+
debug
|
|
109
|
+
markly
|
|
60
110
|
openfeature-sdk!
|
|
61
111
|
rake (~> 13.0)
|
|
62
112
|
rspec (~> 3.12.0)
|
|
63
|
-
|
|
113
|
+
simplecov (~> 0.22.0)
|
|
114
|
+
simplecov-cobertura (~> 2.1.0)
|
|
115
|
+
standard
|
|
116
|
+
standard-performance
|
|
64
117
|
|
|
65
118
|
BUNDLED WITH
|
|
66
119
|
2.3.25
|
data/README.md
CHANGED
|
@@ -14,9 +14,9 @@ We support multiple data types for flags (numbers, strings, booleans, objects) a
|
|
|
14
14
|
|
|
15
15
|
| Ruby Version | OS |
|
|
16
16
|
| ----------- | ----------- |
|
|
17
|
-
| Ruby
|
|
18
|
-
| Ruby 3.
|
|
19
|
-
| Ruby 3.
|
|
17
|
+
| Ruby 3.1.4 | Windows, MacOS, Linux |
|
|
18
|
+
| Ruby 3.2.3 | Windows, MacOS, Linux |
|
|
19
|
+
| Ruby 3.3.0 | Windows, MacOS, Linux |
|
|
20
20
|
|
|
21
21
|
|
|
22
22
|
## Installation
|
|
@@ -36,14 +36,21 @@ gem install openfeature-sdk
|
|
|
36
36
|
## Usage
|
|
37
37
|
|
|
38
38
|
```ruby
|
|
39
|
-
require '
|
|
39
|
+
require 'open_feature/sdk'
|
|
40
40
|
require 'json' # For JSON.dump
|
|
41
41
|
|
|
42
42
|
# API Initialization and configuration
|
|
43
43
|
|
|
44
44
|
OpenFeature::SDK.configure do |config|
|
|
45
|
-
|
|
46
|
-
|
|
45
|
+
# your provider of choice, which will be used as the default provider
|
|
46
|
+
config.set_provider(OpenFeature::SDK::Provider::InMemoryProvider.new(
|
|
47
|
+
{
|
|
48
|
+
"flag1" => true,
|
|
49
|
+
"flag2" => 1
|
|
50
|
+
}
|
|
51
|
+
))
|
|
52
|
+
# alternatively, you can bind multiple providers to different domains
|
|
53
|
+
config.set_provider(OpenFeature::SDK::Provider::NoOpProvider.new, domain: "legacy_flags")
|
|
47
54
|
end
|
|
48
55
|
|
|
49
56
|
# Create a client
|
|
@@ -63,7 +70,31 @@ integer_value = client.fetch_number_value(flag_key: 'number_value', default_valu
|
|
|
63
70
|
object = client.fetch_object_value(flag_key: 'object_value', default_value: JSON.dump({ name: 'object'}))
|
|
64
71
|
```
|
|
65
72
|
|
|
66
|
-
For complete documentation, visit: https://
|
|
73
|
+
For complete documentation, visit: https://openfeature.dev/docs/category/concepts
|
|
74
|
+
|
|
75
|
+
### Providers
|
|
76
|
+
|
|
77
|
+
Providers are the abstraction layer between OpenFeature and different flag management systems.
|
|
78
|
+
|
|
79
|
+
The `NoOpProvider` is an example of a minimalist provider. The `InMemoryProvider` is a provider that can be initialized with flags and used to store flags in process. For complete documentation on the Provider interface, visit: https://openfeature.dev/specification/sections/providers.
|
|
80
|
+
|
|
81
|
+
In addition to the `fetch_*` methods, providers can optionally implement lifecycle methods that are invoked when the underlying provider is switched out. For example:
|
|
82
|
+
|
|
83
|
+
```ruby
|
|
84
|
+
class MyProvider
|
|
85
|
+
def init
|
|
86
|
+
# Perform any initialization steps with flag management system here
|
|
87
|
+
# Return value is ignored
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
def shutdown
|
|
91
|
+
# Perform any shutdown/reclamation steps with flag management system here
|
|
92
|
+
# Return value is ignored
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
**Note** The OpenFeature spec defines a lifecycle method called `initialize` to be called when a new provider is set. To avoid conflicting with the Ruby `initialize` method, this method should be named `init` when creating a provider.
|
|
67
98
|
|
|
68
99
|
## Contributing
|
|
69
100
|
|
data/Rakefile
CHANGED
|
@@ -5,11 +5,6 @@ require "rspec/core/rake_task"
|
|
|
5
5
|
|
|
6
6
|
RSpec::Core::RakeTask.new(:spec)
|
|
7
7
|
|
|
8
|
-
require "
|
|
8
|
+
require "standard/rake"
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
task.options = ["--parallel"]
|
|
12
|
-
task.options << "--color" if ENV["CI"] == "true"
|
|
13
|
-
end
|
|
14
|
-
|
|
15
|
-
task default: %i[spec rubocop]
|
|
10
|
+
task default: %i[spec standard]
|
|
@@ -4,9 +4,10 @@ require "forwardable"
|
|
|
4
4
|
require "singleton"
|
|
5
5
|
|
|
6
6
|
require_relative "configuration"
|
|
7
|
+
require_relative "evaluation_details"
|
|
7
8
|
require_relative "client"
|
|
8
9
|
require_relative "metadata"
|
|
9
|
-
require_relative "provider
|
|
10
|
+
require_relative "provider"
|
|
10
11
|
|
|
11
12
|
module OpenFeature
|
|
12
13
|
module SDK
|
|
@@ -18,7 +19,7 @@ module OpenFeature
|
|
|
18
19
|
# To use the SDK, you can optionally configure a <tt>Provider</tt>, with <tt>Hook</tt>
|
|
19
20
|
#
|
|
20
21
|
# OpenFeature::SDK::API.instance.configure do |config|
|
|
21
|
-
# config.
|
|
22
|
+
# config.set_provider NoOpProvider.new
|
|
22
23
|
# end
|
|
23
24
|
#
|
|
24
25
|
# If no provider is specified, the <tt>NoOpProvider</tt> is set as the default <tt>Provider</tt>.
|
|
@@ -26,19 +27,17 @@ module OpenFeature
|
|
|
26
27
|
#
|
|
27
28
|
# client = OpenFeature::SDK::API.instance.build_client(name: 'my-open-feature-client')
|
|
28
29
|
class API
|
|
29
|
-
include Singleton
|
|
30
|
+
include Singleton # Satisfies Flag Evaluation API Requirement 1.1.1
|
|
30
31
|
extend Forwardable
|
|
31
32
|
|
|
32
|
-
|
|
33
|
-
def_delegator :@configuration, :hooks
|
|
34
|
-
def_delegator :@configuration, :context
|
|
33
|
+
def_delegators :configuration, :provider, :set_provider, :hooks, :context
|
|
35
34
|
|
|
36
35
|
def configuration
|
|
37
36
|
@configuration ||= Configuration.new
|
|
38
37
|
end
|
|
39
38
|
|
|
40
39
|
def configure(&block)
|
|
41
|
-
return unless
|
|
40
|
+
return unless block
|
|
42
41
|
|
|
43
42
|
block.call(configuration)
|
|
44
43
|
end
|
|
@@ -26,8 +26,9 @@ module OpenFeature
|
|
|
26
26
|
# result = @provider.fetch_boolean_value(flag_key: flag_key, default_value: default_value, evaluation_context: evaluation_context)
|
|
27
27
|
# end
|
|
28
28
|
def fetch_#{result_type}_#{suffix}(flag_key:, default_value:, evaluation_context: nil)
|
|
29
|
-
|
|
30
|
-
|
|
29
|
+
resolution_details = @provider.fetch_#{result_type}_value(flag_key:, default_value:, evaluation_context:)
|
|
30
|
+
evaluation_details = EvaluationDetails.new(flag_key:, resolution_details:)
|
|
31
|
+
#{"evaluation_details.value" if suffix == :value}
|
|
31
32
|
end
|
|
32
33
|
RUBY
|
|
33
34
|
end
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "concurrent"
|
|
4
|
+
|
|
5
|
+
require_relative "api"
|
|
6
|
+
|
|
7
|
+
module OpenFeature
|
|
8
|
+
module SDK
|
|
9
|
+
# Represents the configuration object for the global API where <tt>Provider</tt>, <tt>Hook</tt>,
|
|
10
|
+
# and <tt>Context</tt> are configured.
|
|
11
|
+
# This class is not meant to be interacted with directly but instead through the <tt>OpenFeature::SDK.configure</tt>
|
|
12
|
+
# method
|
|
13
|
+
class Configuration
|
|
14
|
+
extend Forwardable
|
|
15
|
+
|
|
16
|
+
attr_accessor :context, :hooks
|
|
17
|
+
|
|
18
|
+
def_delegator :provider, :metadata
|
|
19
|
+
|
|
20
|
+
def initialize
|
|
21
|
+
@hooks = []
|
|
22
|
+
@providers = {}
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def provider(domain: nil)
|
|
26
|
+
@providers[domain]
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# When switching providers, there are a few lifecycle methods that need to be taken care of.
|
|
30
|
+
# 1. If a provider is already set, we need to call `shutdown` on it.
|
|
31
|
+
# 2. On the new provider, call `init`.
|
|
32
|
+
# 3. Finally, set the internal provider to the new provider
|
|
33
|
+
def set_provider(provider, domain: nil)
|
|
34
|
+
@providers[domain].shutdown if @providers[domain].respond_to?(:shutdown)
|
|
35
|
+
|
|
36
|
+
provider.init if provider.respond_to?(:init)
|
|
37
|
+
|
|
38
|
+
@providers[domain] = provider
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
module OpenFeature
|
|
2
|
+
module SDK
|
|
3
|
+
EvaluationDetails = Struct.new(:flag_key, :resolution_details, keyword_init: true) do
|
|
4
|
+
extend Forwardable
|
|
5
|
+
|
|
6
|
+
def_delegators :resolution_details, :value, :reason, :variant, :error_code, :error_message, :flag_metadata
|
|
7
|
+
end
|
|
8
|
+
end
|
|
9
|
+
end
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
module OpenFeature
|
|
2
|
+
module SDK
|
|
3
|
+
module Provider
|
|
4
|
+
module ErrorCode
|
|
5
|
+
PROVIDER_NOT_READY = "Provider Not Ready"
|
|
6
|
+
FLAG_NOT_FOUND = "Flag Not Found"
|
|
7
|
+
PARSE_ERROR = "Parse Error"
|
|
8
|
+
TYPE_MISMATCH = "Type Mismatch"
|
|
9
|
+
TARGETING_KEY_MISSING = "Targeting Key Missing"
|
|
10
|
+
INVALID_CONTEXT = "Invalid Context"
|
|
11
|
+
GENERAL = "General"
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
module OpenFeature
|
|
2
|
+
module SDK
|
|
3
|
+
module Provider
|
|
4
|
+
# TODO: Add evaluation context support
|
|
5
|
+
class InMemoryProvider
|
|
6
|
+
NAME = "In-memory Provider"
|
|
7
|
+
|
|
8
|
+
def initialize(flags = {})
|
|
9
|
+
@metadata = Metadata.new(name: NAME).freeze
|
|
10
|
+
@flags = flags
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def init
|
|
14
|
+
# Intentional no-op, used for testing
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def shutdown
|
|
18
|
+
# Intentional no-op, used for testing
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def add_flag(flag_key:, value:)
|
|
22
|
+
flags[flag_key] = value
|
|
23
|
+
# TODO: Emit PROVIDER_CONFIGURATION_CHANGED event once events are implemented
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def fetch_boolean_value(flag_key:, default_value:, evaluation_context: nil)
|
|
27
|
+
fetch_value(allowed_classes: [TrueClass, FalseClass], flag_key:, default_value:, evaluation_context:)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def fetch_string_value(flag_key:, default_value:, evaluation_context: nil)
|
|
31
|
+
fetch_value(allowed_classes: [String], flag_key:, default_value:, evaluation_context:)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def fetch_number_value(flag_key:, default_value:, evaluation_context: nil)
|
|
35
|
+
fetch_value(allowed_classes: [Integer, Float], flag_key:, default_value:, evaluation_context:)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def fetch_object_value(flag_key:, default_value:, evaluation_context: nil)
|
|
39
|
+
fetch_value(allowed_classes: [Array, Hash], flag_key:, default_value:, evaluation_context:)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
private
|
|
43
|
+
|
|
44
|
+
attr_reader :flags
|
|
45
|
+
|
|
46
|
+
def fetch_value(allowed_classes:, flag_key:, default_value:, evaluation_context:)
|
|
47
|
+
value = flags[flag_key]
|
|
48
|
+
|
|
49
|
+
if value.nil?
|
|
50
|
+
return ResolutionDetails.new(value: default_value, error_code: ErrorCode::FLAG_NOT_FOUND, reason: Reason::ERROR)
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
if allowed_classes.include?(value.class)
|
|
54
|
+
ResolutionDetails.new(value:, reason: Reason::STATIC)
|
|
55
|
+
else
|
|
56
|
+
ResolutionDetails.new(value: default_value, error_code: ErrorCode::TYPE_MISMATCH, reason: Reason::ERROR)
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
@@ -11,7 +11,7 @@ module OpenFeature
|
|
|
11
11
|
# To use <tt>NoOpProvider</tt>, it can be set during the configuration of the SDK
|
|
12
12
|
#
|
|
13
13
|
# OpenFeature::SDK.configure do |config|
|
|
14
|
-
# config.
|
|
14
|
+
# config.set_provider NoOpProvider.new
|
|
15
15
|
# end
|
|
16
16
|
#
|
|
17
17
|
# Within the <tt>NoOpProvider</tt>, the following methods exist
|
|
@@ -30,8 +30,6 @@ module OpenFeature
|
|
|
30
30
|
|
|
31
31
|
attr_reader :metadata
|
|
32
32
|
|
|
33
|
-
ResolutionDetails = Struct.new(:value, :reason, :variant, :error_code, :error_message)
|
|
34
|
-
|
|
35
33
|
def initialize
|
|
36
34
|
@metadata = Metadata.new(name: NAME).freeze
|
|
37
35
|
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
module OpenFeature
|
|
2
|
+
module SDK
|
|
3
|
+
module Provider
|
|
4
|
+
module Reason
|
|
5
|
+
STATIC = "Static"
|
|
6
|
+
DEFAULT = "Default"
|
|
7
|
+
TARGETING_MATCH = "Targeting Match"
|
|
8
|
+
SPLIT = "Split"
|
|
9
|
+
CACHED = "Cached"
|
|
10
|
+
DISABLED = "Disabled"
|
|
11
|
+
UNKNOWN = "Unknown"
|
|
12
|
+
STALE = "Stale"
|
|
13
|
+
ERROR = "Error"
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
require_relative "provider/error_code"
|
|
2
|
+
require_relative "provider/reason"
|
|
3
|
+
require_relative "provider/resolution_details"
|
|
4
|
+
require_relative "provider/no_op_provider"
|
|
5
|
+
require_relative "provider/in_memory_provider"
|
|
6
|
+
|
|
7
|
+
module OpenFeature
|
|
8
|
+
module SDK
|
|
9
|
+
module Provider
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
end
|
|
@@ -8,9 +8,9 @@ module OpenFeature
|
|
|
8
8
|
#
|
|
9
9
|
module SDK
|
|
10
10
|
class << self
|
|
11
|
-
def method_missing(method_name,
|
|
11
|
+
def method_missing(method_name, ...)
|
|
12
12
|
if API.instance.respond_to?(method_name)
|
|
13
|
-
API.instance.send(method_name,
|
|
13
|
+
API.instance.send(method_name, ...)
|
|
14
14
|
else
|
|
15
15
|
super
|
|
16
16
|
end
|
data/release-please-config.json
CHANGED
data/renovate.json
CHANGED
|
@@ -2,5 +2,16 @@
|
|
|
2
2
|
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
|
|
3
3
|
"extends": [
|
|
4
4
|
"config:base"
|
|
5
|
+
],
|
|
6
|
+
"packageRules": [
|
|
7
|
+
{
|
|
8
|
+
"matchUpdateTypes": ["minor", "patch"],
|
|
9
|
+
"matchCurrentVersion": "!/^0/",
|
|
10
|
+
"automerge": true
|
|
11
|
+
},
|
|
12
|
+
{
|
|
13
|
+
"matchManagers": ["github-actions"],
|
|
14
|
+
"automerge": true
|
|
15
|
+
}
|
|
5
16
|
]
|
|
6
17
|
}
|
metadata
CHANGED
|
@@ -1,15 +1,43 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: openfeature-sdk
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.2.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- OpenFeature Authors
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2024-03-11 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
|
+
- !ruby/object:Gem::Dependency
|
|
14
|
+
name: debug
|
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
|
16
|
+
requirements:
|
|
17
|
+
- - ">="
|
|
18
|
+
- !ruby/object:Gem::Version
|
|
19
|
+
version: '0'
|
|
20
|
+
type: :development
|
|
21
|
+
prerelease: false
|
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
23
|
+
requirements:
|
|
24
|
+
- - ">="
|
|
25
|
+
- !ruby/object:Gem::Version
|
|
26
|
+
version: '0'
|
|
27
|
+
- !ruby/object:Gem::Dependency
|
|
28
|
+
name: markly
|
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
|
30
|
+
requirements:
|
|
31
|
+
- - ">="
|
|
32
|
+
- !ruby/object:Gem::Version
|
|
33
|
+
version: '0'
|
|
34
|
+
type: :development
|
|
35
|
+
prerelease: false
|
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
37
|
+
requirements:
|
|
38
|
+
- - ">="
|
|
39
|
+
- !ruby/object:Gem::Version
|
|
40
|
+
version: '0'
|
|
13
41
|
- !ruby/object:Gem::Dependency
|
|
14
42
|
name: rake
|
|
15
43
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -39,19 +67,61 @@ dependencies:
|
|
|
39
67
|
- !ruby/object:Gem::Version
|
|
40
68
|
version: 3.12.0
|
|
41
69
|
- !ruby/object:Gem::Dependency
|
|
42
|
-
name:
|
|
70
|
+
name: standard
|
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
|
72
|
+
requirements:
|
|
73
|
+
- - ">="
|
|
74
|
+
- !ruby/object:Gem::Version
|
|
75
|
+
version: '0'
|
|
76
|
+
type: :development
|
|
77
|
+
prerelease: false
|
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
79
|
+
requirements:
|
|
80
|
+
- - ">="
|
|
81
|
+
- !ruby/object:Gem::Version
|
|
82
|
+
version: '0'
|
|
83
|
+
- !ruby/object:Gem::Dependency
|
|
84
|
+
name: standard-performance
|
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
|
86
|
+
requirements:
|
|
87
|
+
- - ">="
|
|
88
|
+
- !ruby/object:Gem::Version
|
|
89
|
+
version: '0'
|
|
90
|
+
type: :development
|
|
91
|
+
prerelease: false
|
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
93
|
+
requirements:
|
|
94
|
+
- - ">="
|
|
95
|
+
- !ruby/object:Gem::Version
|
|
96
|
+
version: '0'
|
|
97
|
+
- !ruby/object:Gem::Dependency
|
|
98
|
+
name: simplecov
|
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
|
100
|
+
requirements:
|
|
101
|
+
- - "~>"
|
|
102
|
+
- !ruby/object:Gem::Version
|
|
103
|
+
version: 0.22.0
|
|
104
|
+
type: :development
|
|
105
|
+
prerelease: false
|
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
107
|
+
requirements:
|
|
108
|
+
- - "~>"
|
|
109
|
+
- !ruby/object:Gem::Version
|
|
110
|
+
version: 0.22.0
|
|
111
|
+
- !ruby/object:Gem::Dependency
|
|
112
|
+
name: simplecov-cobertura
|
|
43
113
|
requirement: !ruby/object:Gem::Requirement
|
|
44
114
|
requirements:
|
|
45
115
|
- - "~>"
|
|
46
116
|
- !ruby/object:Gem::Version
|
|
47
|
-
version: 1.
|
|
117
|
+
version: 2.1.0
|
|
48
118
|
type: :development
|
|
49
119
|
prerelease: false
|
|
50
120
|
version_requirements: !ruby/object:Gem::Requirement
|
|
51
121
|
requirements:
|
|
52
122
|
- - "~>"
|
|
53
123
|
- !ruby/object:Gem::Version
|
|
54
|
-
version: 1.
|
|
124
|
+
version: 2.1.0
|
|
55
125
|
description: Ruby SDK for an the specifications for the open standard of feature flag
|
|
56
126
|
management
|
|
57
127
|
email:
|
|
@@ -62,25 +132,33 @@ extra_rdoc_files: []
|
|
|
62
132
|
files:
|
|
63
133
|
- ".release-please-manifest.json"
|
|
64
134
|
- ".rspec"
|
|
65
|
-
- ".rubocop.yml"
|
|
66
135
|
- ".ruby-version"
|
|
136
|
+
- ".simplecov"
|
|
137
|
+
- ".standard.yml"
|
|
138
|
+
- ".tool-versions"
|
|
67
139
|
- CHANGELOG.md
|
|
140
|
+
- CODEOWNERS
|
|
68
141
|
- CODE_OF_CONDUCT.md
|
|
69
142
|
- Gemfile
|
|
70
143
|
- Gemfile.lock
|
|
71
144
|
- LICENSE
|
|
72
145
|
- README.md
|
|
73
146
|
- Rakefile
|
|
74
|
-
- lib/
|
|
75
|
-
- lib/
|
|
76
|
-
- lib/
|
|
77
|
-
- lib/
|
|
78
|
-
- lib/
|
|
79
|
-
- lib/
|
|
80
|
-
- lib/
|
|
147
|
+
- lib/open_feature/sdk.rb
|
|
148
|
+
- lib/open_feature/sdk/api.rb
|
|
149
|
+
- lib/open_feature/sdk/client.rb
|
|
150
|
+
- lib/open_feature/sdk/configuration.rb
|
|
151
|
+
- lib/open_feature/sdk/evaluation_details.rb
|
|
152
|
+
- lib/open_feature/sdk/metadata.rb
|
|
153
|
+
- lib/open_feature/sdk/provider.rb
|
|
154
|
+
- lib/open_feature/sdk/provider/error_code.rb
|
|
155
|
+
- lib/open_feature/sdk/provider/in_memory_provider.rb
|
|
156
|
+
- lib/open_feature/sdk/provider/no_op_provider.rb
|
|
157
|
+
- lib/open_feature/sdk/provider/reason.rb
|
|
158
|
+
- lib/open_feature/sdk/provider/resolution_details.rb
|
|
159
|
+
- lib/open_feature/sdk/version.rb
|
|
81
160
|
- release-please-config.json
|
|
82
161
|
- renovate.json
|
|
83
|
-
- sig/openfeature/sdk.rbs
|
|
84
162
|
homepage: https://github.com/open-feature/openfeature-ruby
|
|
85
163
|
licenses:
|
|
86
164
|
- Apache-2.0'
|
|
@@ -98,14 +176,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
98
176
|
requirements:
|
|
99
177
|
- - ">="
|
|
100
178
|
- !ruby/object:Gem::Version
|
|
101
|
-
version:
|
|
179
|
+
version: '3.1'
|
|
102
180
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
103
181
|
requirements:
|
|
104
182
|
- - ">="
|
|
105
183
|
- !ruby/object:Gem::Version
|
|
106
184
|
version: '0'
|
|
107
185
|
requirements: []
|
|
108
|
-
rubygems_version: 3.3
|
|
186
|
+
rubygems_version: 3.5.3
|
|
109
187
|
signing_key:
|
|
110
188
|
specification_version: 4
|
|
111
189
|
summary: OpenFeature SDK for Ruby
|
data/.rubocop.yml
DELETED
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
AllCops:
|
|
2
|
-
TargetRubyVersion: 2.7
|
|
3
|
-
NewCops: enable
|
|
4
|
-
|
|
5
|
-
Style/StringLiterals:
|
|
6
|
-
Enabled: true
|
|
7
|
-
EnforcedStyle: double_quotes
|
|
8
|
-
|
|
9
|
-
Style/StringLiteralsInInterpolation:
|
|
10
|
-
Enabled: true
|
|
11
|
-
EnforcedStyle: double_quotes
|
|
12
|
-
|
|
13
|
-
Layout/LineLength:
|
|
14
|
-
Max: 120
|
|
15
|
-
Exclude:
|
|
16
|
-
- 'spec/**/*.rb'
|
|
17
|
-
|
|
18
|
-
Metrics/BlockLength:
|
|
19
|
-
Exclude:
|
|
20
|
-
- 'spec/**/*.rb'
|
|
21
|
-
- 'openfeature-sdk.gemspec'
|
|
22
|
-
|
|
23
|
-
Gemspec/RequireMFA:
|
|
24
|
-
Enabled: false
|
|
25
|
-
|
|
26
|
-
Style/DocumentDynamicEvalDefinition:
|
|
27
|
-
# TODO re-enable after figuring out what it actually wants
|
|
28
|
-
Enabled: false
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require "concurrent"
|
|
4
|
-
|
|
5
|
-
require_relative "api"
|
|
6
|
-
|
|
7
|
-
module OpenFeature
|
|
8
|
-
module SDK
|
|
9
|
-
# Represents the configuration object for the global API where <tt>Provider</tt>, <tt>Hook</tt>,
|
|
10
|
-
# and <tt>Context</tt> are configured.
|
|
11
|
-
# This class is not meant to be interacted with directly but instead through the <tt>OpenFeature::SDK.configure</tt>
|
|
12
|
-
# method
|
|
13
|
-
class Configuration
|
|
14
|
-
extend Forwardable
|
|
15
|
-
|
|
16
|
-
attr_accessor :context, :provider, :hooks
|
|
17
|
-
|
|
18
|
-
def_delegator :@provider, :metadata
|
|
19
|
-
|
|
20
|
-
def initialize
|
|
21
|
-
@hooks = Concurrent::Array.new([])
|
|
22
|
-
end
|
|
23
|
-
end
|
|
24
|
-
end
|
|
25
|
-
end
|
data/sig/openfeature/sdk.rbs
DELETED
|
File without changes
|