Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Add flagd provider #2

Merged
merged 11 commits into from
Jan 5, 2023
6 changes: 6 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
[submodule "providers/openfeature-flagd-provider/schemas"]
josecolella marked this conversation as resolved.
Show resolved Hide resolved
path = providers/openfeature-flagd-provider/schemas
url = https://github.com/open-feature/schemas
[submodule "providers/openfeature-flagd-provider/providers/openfeature-flagd-provider/schemas"]
path = providers/openfeature-flagd-provider/providers/openfeature-flagd-provider/schemas
url = https://github.com/open-feature/schemas
josecolella marked this conversation as resolved.
Show resolved Hide resolved
21 changes: 19 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,19 @@
# ruby-sdk-contrib
Community contributions for hooks and reference providers in Ruby
# OpenFeature Ruby Contributions

![Experimental](https://img.shields.io/badge/experimental-breaking%20changes%20allowed-yellow)
![Alpha](https://img.shields.io/badge/alpha-release-red)
josecolella marked this conversation as resolved.
Show resolved Hide resolved

This repository is intended for OpenFeature contributions which are not included in the [OpenFeature SDK](https://github.com/open-feature/ruby-sdk).

The project includes:

- [Providers](./providers)
- [Hooks](./hooks)

## Releases

This repo uses _Release Please_ to release packages. Release Please sets up a running PR that tracks all changes for the library components, and maintains the versions according to [conventional commits](https://www.conventionalcommits.org/en/v1.0.0/), generated when [PRs are merged](https://github.com/amannn/action-semantic-pull-request). When Release Please's running PR is merged, any changed artifacts are published.

## License

Apache 2.0 - See [LICENSE](./LICENSE) for more information.
11 changes: 11 additions & 0 deletions providers/openfeature-flagd-provider/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
/.bundle/
/.yardoc
/_yardoc/
/coverage/
/doc/
/pkg/
/spec/reports/
/tmp/

# rspec failure tracking
.rspec_status
4 changes: 4 additions & 0 deletions providers/openfeature-flagd-provider/.rspec
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
-I lib
--format documentation
--color
--require spec_helper
50 changes: 50 additions & 0 deletions providers/openfeature-flagd-provider/.rubocop.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
AllCops:
TargetRubyVersion: 3.1
NewCops: enable

Style/StringLiterals:
Enabled: true
EnforcedStyle: double_quotes

Style/StringLiteralsInInterpolation:
Enabled: true
EnforcedStyle: double_quotes

Layout/LineLength:
Max: 120
Exclude:
- 'spec/**/*.rb'
- 'lib/openfeature/flagd/provider/schema/v1/**'

Lint/EmptyBlock:
Exclude:
- 'lib/openfeature/flagd/provider/schema/v1/**'

Metrics/BlockLength:
Exclude:
- 'spec/**/*_spec.rb'
- 'openfeature-flagd-provider.gemspec'
- 'lib/openfeature/flagd/provider/schema/v1/**'

Gemspec/RequireMFA:
Enabled: false

Style/FrozenStringLiteralComment:
Exclude:
- 'lib/openfeature/flagd/provider/schema/v1/**'

DocumentDynamicEvalDefinition:
Exclude:
- lib/openfeature/flagd/provider/client.rb

Metrics/AbcSize:
Exclude:
- lib/openfeature/flagd/provider/**/*.rb

Metrics/MethodLength:
Exclude:
- lib/openfeature/flagd/provider/**/*.rb

Metrics/CyclomaticComplexity:
Exclude:
- lib/openfeature/flagd/provider/**/*.rb
1 change: 1 addition & 0 deletions providers/openfeature-flagd-provider/.ruby-version
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
3.1.2
6 changes: 6 additions & 0 deletions providers/openfeature-flagd-provider/Gemfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# frozen_string_literal: true

source "https://rubygems.org"

# Specify your gem's dependencies in openfeature-flagd-provider.gemspec
gemspec
64 changes: 64 additions & 0 deletions providers/openfeature-flagd-provider/Gemfile.lock
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
PATH
remote: .
specs:
openfeature-flagd-provider (0.0.1)
grpc (~> 1.50)

GEM
remote: https://rubygems.org/
specs:
ast (2.4.2)
diff-lcs (1.5.0)
google-protobuf (3.21.12)
googleapis-common-protos-types (1.4.0)
google-protobuf (~> 3.14)
grpc (1.50.0)
google-protobuf (~> 3.21)
googleapis-common-protos-types (~> 1.0)
json (2.6.2)
parallel (1.22.1)
parser (3.1.3.0)
ast (~> 2.4.1)
rainbow (3.1.1)
rake (13.0.6)
regexp_parser (2.6.1)
rexml (3.2.5)
rspec (3.12.0)
rspec-core (~> 3.12.0)
rspec-expectations (~> 3.12.0)
rspec-mocks (~> 3.12.0)
rspec-core (3.12.0)
rspec-support (~> 3.12.0)
rspec-expectations (3.12.0)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.12.0)
rspec-mocks (3.12.0)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.12.0)
rspec-support (3.12.0)
rubocop (1.37.1)
json (~> 2.3)
parallel (~> 1.10)
parser (>= 3.1.2.1)
rainbow (>= 2.2.2, < 4.0)
regexp_parser (>= 1.8, < 3.0)
rexml (>= 3.2.5, < 4.0)
rubocop-ast (>= 1.23.0, < 2.0)
ruby-progressbar (~> 1.7)
unicode-display_width (>= 1.4.0, < 3.0)
rubocop-ast (1.23.0)
parser (>= 3.1.1.0)
ruby-progressbar (1.11.0)
unicode-display_width (2.3.0)

PLATFORMS
arm64-darwin-21

DEPENDENCIES
openfeature-flagd-provider!
rake (~> 13.0)
rspec (~> 3.12.0)
rubocop (~> 1.37.1)

BUNDLED WITH
2.3.25
51 changes: 51 additions & 0 deletions providers/openfeature-flagd-provider/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# OpenFeature FlagD Provider for Ruby

This is the Ruby [provider](https://docs.openfeature.dev/docs/specification/sections/providers) implementation of the [FlagD](https://github.com/open-feature/flagd)
## Installation

Add this line to your application's Gemfile:

```ruby
gem 'openfeature-flagd-provider'
```

And then execute:

$ bundle install
josecolella marked this conversation as resolved.
Show resolved Hide resolved

Or install it yourself as:

$ gem install openfeature-flagd-provider
josecolella marked this conversation as resolved.
Show resolved Hide resolved

## Usage

The provider allows for configuration of host, port, socket_path, and tls connection.

```ruby
OpenFeature::FlagD::Provider.configure do |config|
config.host = "localhost"
config.port = 8013
config.tls = false
end
```

If no configurations are provided, the provider will be initialized with the following environment variables:

> FLAGD_HOST
> FLAGD_PORT
> FLAGD_TLS
> FLAGD_SOCKET_PATH

If no environment variables are set the [default configuration](./lib/openfeature/flagd/provider/configuration.rb) is set

## Resolving flag values

```ruby
OpenFeature::FlagD::Provider.resolve_boolean_value(flag_key: 'boolean-flag', default_value: false)
josecolella marked this conversation as resolved.
Show resolved Hide resolved


```

## Contributing

https://github.com/open-feature/ruby-sdk-contrib
josecolella marked this conversation as resolved.
Show resolved Hide resolved
8 changes: 8 additions & 0 deletions providers/openfeature-flagd-provider/Rakefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# frozen_string_literal: true

require "bundler/gem_tasks"
require "rspec/core/rake_task"

RSpec::Core::RakeTask.new(:spec)

task default: :spec
15 changes: 15 additions & 0 deletions providers/openfeature-flagd-provider/bin/console
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#!/usr/bin/env ruby
# frozen_string_literal: true

require "bundler/setup"
require "openfeature/flagd/provider"

# You can add fixtures and/or initialization code here to make experimenting
# with your gem easier. You can also use a different console, if you like.

# (If you use this, don't forget to add pry to your Gemfile!)
# require "pry"
# Pry.start

require "irb"
IRB.start(__FILE__)
8 changes: 8 additions & 0 deletions providers/openfeature-flagd-provider/bin/setup
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#!/usr/bin/env bash
set -euo pipefail
IFS=$'\n\t'
set -vx

bundle install

# Do any other automated setup that you need to do here
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
# frozen_string_literal: true

require_relative "provider/configuration"
require_relative "provider/client"

module OpenFeature
module FlagD
# Provider represents the entry point for interacting with the FlagD provider
# values. The implementation follows the details specified in https://docs.openfeature.dev/docs/specification/sections/providers
#
# Provider contains functionality to configure the GRPC connection via
#
# OpenFeature::FlagD::Provider.configure do |config|
# config.host = 'localhost'
# config.port = 8379
# config.tls = false
# end
# The Provider providers the following methods and attributes:
#
# * <tt>metadata</tt> - Returns the associated provider metadata with the name
#
# * <tt>resolve_boolean_value(flag_key:, default_value:, context: nil)</tt>
# manner; <tt>client.resolve_boolean(flag_key: 'boolean-flag', default_value: false)</tt>
#
# * <tt>resolve_integer_value(flag_key:, default_value:, context: nil)</tt>
# manner; <tt>client.resolve_integer_value(flag_key: 'integer-flag', default_value: 2)</tt>
#
# * <tt>resolve_float_value(flag_key:, default_value:, context: nil)</tt>
# manner; <tt>client.resolve_float_value(flag_key: 'float-flag', default_value: 2.0)</tt>
#
# * <tt>resolve_string_value(flag_key:, default_value:, context: nil)</tt>
# manner; <tt>client.resolve_string_value(flag_key: 'string-flag', default_value: 'some-defau;t-value')</tt>
#
# * <tt>resolve_object_value(flag_key:, default_value:, context: nil)</tt>
# manner; <tt>client.resolve_object_value(flag_key: 'object-flag', default_value: { default_value: 'value'})</tt>
module Provider
class << self
def method_missing(method_name, *args, **kwargs, &)
if client.respond_to?(method_name)
client.send(method_name, *args, **kwargs, &)
else
super
end
end

def respond_to_missing?(method_name, include_private = false)
client.respond_to?(method_name, include_private) || super
end

def configuration
@configuration ||= explicit_configuration
.merge(Configuration.environment_variables_config)
.merge(Configuration.default_config)
end

def configure(&block)
return unless block_given?

block.call(explicit_configuration)
end

private

def explicit_configuration
@explicit_configuration ||= Configuration.new
end

def client
@client ||= Client.new(configuration:)
end
end
end
end
end
Loading