hipflag 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: b18769b4735bce8450b1d48e4815d7f5f7987f7492a32b40fd93953cd6b5860a
4
+ data.tar.gz: ecc90db5da2ed8d47ea65174668312a49befdeefd4fb033db07358250f0da8f1
5
+ SHA512:
6
+ metadata.gz: e5b902e6afbd6c385d157499b21d427243127c468ef44661943bfcce87ef63abe5bfda594fd907df4c986cd8018349489059c0f6a1e4cebe2e2f1849802c1677
7
+ data.tar.gz: caa46f5249e3aacf285d3c56929e517556dca4c22380f46948572608847a551556f3f39f1d8b015e60346714f67231b48ec7ce6a03dd321849801d1a3b278a0f
@@ -0,0 +1,11 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /_yardoc/
4
+ /coverage/
5
+ /doc/
6
+ /pkg/
7
+ /spec/reports/
8
+ /tmp/
9
+ .rspec_status
10
+ .byebug_history
11
+ Gemfile.lock
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --format documentation
2
+ --color
3
+ --require spec_helper
@@ -0,0 +1,5 @@
1
+ sudo: false
2
+ language: ruby
3
+ rvm:
4
+ - 2.6.3
5
+ before_install: gem install bundler -v 1.16.2
data/Gemfile ADDED
@@ -0,0 +1,13 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
4
+
5
+ group :development, :test do
6
+ gem 'byebug', '~> 11.0'
7
+ gem 'pry', '~> 0.12'
8
+ end
9
+
10
+ group :test do
11
+ gem 'rspec', '~> 3.8'
12
+ gem 'webmock', '~> 3.5.1'
13
+ end
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2019 Hipflag
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
@@ -0,0 +1,168 @@
1
+ # hipflag
2
+
3
+ [![Build Status](https://travis-ci.org/hipflag/hipflag_ruby.svg?branch=master)](https://travis-ci.org/hipflag/hipflag_ruby)
4
+
5
+ <img src="https://static.hipflag.com/images/logo.png" width="272" alt="Hipflag logo">
6
+
7
+ This gem is a Ruby client for interacting with [Hipflag API](https://www.hipflag.com/docs).
8
+
9
+ [Hipflag](https://www.hipflag.com) is a tool that allows to control and roll out new product features with flags. It offers a simple UI to enable/disable feature flags. It also let users to enable flags for a given percentage of users
10
+
11
+ ## Installation
12
+
13
+ Add this line to your application's Gemfile:
14
+
15
+ ```ruby
16
+ gem 'hipflag'
17
+ ```
18
+
19
+ or install it yourself as:
20
+
21
+ $ gem install hipflag
22
+
23
+ ## Usage
24
+
25
+ ### Initializing a client
26
+
27
+ The client can be configured globally:
28
+
29
+ ```ruby
30
+ Hipflag.configure do |config|
31
+ config.public_key = '**************'
32
+ config.secret_key = '**************'
33
+ end
34
+
35
+ Hipflag::Client.new
36
+ ```
37
+
38
+ or by instance:
39
+
40
+ ```ruby
41
+ Hipflag::Client.new(public_key: '*******', secret_key: '*******')
42
+ ```
43
+
44
+ ### Client methods
45
+
46
+ Clients methods returns a `Hipflag::Response` object. This kind of objects contain methods to get the status of the request (ie: `#ok?`, `#created?`, ...) and a method called `#json` which returns a JSON representation of the response.
47
+
48
+ #### Flag
49
+ ##### #flag(flag_id)
50
+
51
+ It returns relevant information about a specific flag
52
+
53
+ ```ruby
54
+ client.flag('new-header').json
55
+ ```
56
+
57
+ Response
58
+ ```ruby
59
+ {
60
+ 'flag' => {
61
+ 'active' => true,
62
+ 'name' => 'new-header'
63
+ }
64
+ }
65
+ ```
66
+
67
+ It is possible to pass a `user_id` to check if the flag is enabled for that given user:
68
+
69
+ ```ruby
70
+ client.flag('new-header', user_id: 123).json
71
+ ```
72
+
73
+ If a flag is not found, the client raises a `Hipflag::Client:NotFound` exception. Example:
74
+
75
+ ```ruby
76
+ client.flag('unknown-flag')
77
+ ```
78
+
79
+ Exception raised:
80
+ ```
81
+ Hipflag::Client::NotFound: Resource not found
82
+ ```
83
+
84
+ ##### #update_flag(flag_id, params)
85
+
86
+ This method updates a specific flag
87
+
88
+ ```ruby
89
+ client.update_flag('new-header', rollout: 75).json
90
+ ```
91
+
92
+ Response
93
+ ```ruby
94
+ {
95
+ 'flag' => {
96
+ 'enabled' => true,
97
+ 'rollout' => 75,
98
+ 'name' => 'new-header'
99
+ }
100
+ }
101
+ ```
102
+
103
+ ```ruby
104
+ client.update_flag('new-header', enabled: false).json
105
+ ```
106
+
107
+ Response
108
+ ```ruby
109
+ {
110
+ 'flag' => {
111
+ 'enabled' => false,
112
+ 'rollout' => 75,
113
+ 'name' => 'new-header'
114
+ }
115
+ }
116
+ ```
117
+
118
+ If Hipflag cannot update a flag because a param is not valid, the client raises an exception including the error message. For example:
119
+
120
+ ```ruby
121
+ client.update_flag('new-header', rollout: 500).json
122
+ ```
123
+
124
+ Exception raised
125
+ ```
126
+ Hipflag::Client::UnprocessableEntity: {"message"=>{"rollout"=>["must be less than or equal to 100"]}}
127
+ ```
128
+
129
+ You can get the list of editable attributes in the [documentation](https://www.hipflag.com/docs).
130
+
131
+ ### Client errors
132
+
133
+ `Hipflag::Client` methods can raise several exceptions when performing requests:
134
+
135
+ * `Hipflag::Client::Unauthorized`: Request is not properly authenticated
136
+ * `Hipflag::Client::ServerError`: Hipflag API is not responding
137
+ * `Hipflag::Client::NotFound`: Resource is not found (`404`)
138
+ * `Hipflag::Client::UnprocessableEntity`: Request could not be processed
139
+
140
+ ### How to retrieve the authentication keys
141
+
142
+ You can get your personal `Public`and `Secret` keys at https://www.hipflag.com/users/me
143
+
144
+ ### How to using in Rails
145
+
146
+ The best way to use the client in a Rails application is adding a initializer: `config/initializers/hipflag.rb`:
147
+
148
+ ```ruby
149
+ Hipflag.configure do |config|
150
+ config.public_key = '**************'
151
+ config.secret_key = '**************'
152
+ end
153
+ ```
154
+
155
+ Then you can instantiate the client already containing the configuration:
156
+
157
+ ```ruby
158
+ Hipflag::Client.new
159
+ => #<Hipflag::Client:0x00007faa173be430 @public_key="**********", @secret_key="**********">
160
+ ```
161
+
162
+ ## Contributing
163
+
164
+ Bug reports and pull requests are welcome on GitHub at https://github.com/hipflag/hipflag_ruby. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
165
+
166
+ ## License
167
+
168
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT)
@@ -0,0 +1,6 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'rspec/core/rake_task'
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task default: :spec
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $stdout.sync = true
4
+
5
+ require 'bundler/setup'
6
+ require 'hipflag'
7
+ require 'pry'
8
+
9
+ ARGV.clear
10
+ Pry.start
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
@@ -0,0 +1,28 @@
1
+ lib = File.expand_path('../lib', __FILE__)
2
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
+ require 'hipflag/version'
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = 'hipflag'
7
+ spec.version = Hipflag::VERSION
8
+ spec.authors = ['Hipflag']
9
+ spec.email = ['info@hipflag.com']
10
+
11
+ spec.summary = %q{Ruby client for interacting with Hipflag API}
12
+ spec.description = %q{This gem is a Ruby client for interacting with Hipflag API. Hipflag is a tool that allows to control and roll out new product features with flags}
13
+ spec.homepage = 'https://github.com/hipflag/hipflag_ruby'
14
+ spec.license = 'MIT'
15
+
16
+ spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
17
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(spec)/}) }
18
+ end
19
+ spec.bindir = 'bin'
20
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
21
+ spec.require_paths = ['lib']
22
+
23
+ spec.add_dependency 'patron', '~> 0.13.1'
24
+ spec.add_dependency 'oj', '~> 3.7.12'
25
+ spec.add_dependency 'zeitwerk', '~> 2.1.6'
26
+ spec.add_development_dependency 'bundler', '~> 1.17'
27
+ spec.add_development_dependency 'rake', '~> 12.3'
28
+ end
@@ -0,0 +1,11 @@
1
+ require 'zeitwerk'
2
+ loader = Zeitwerk::Loader.for_gem
3
+ loader.enable_reloading
4
+ loader.setup
5
+ loader.reload
6
+
7
+ module Hipflag
8
+ class << self
9
+ include Hipflag::Configurable
10
+ end
11
+ end
@@ -0,0 +1,58 @@
1
+ require 'patron'
2
+
3
+ module Hipflag
4
+ class Client
5
+ include Client::Flag
6
+
7
+ NotFound = Class.new(RuntimeError)
8
+ ServerError = Class.new(RuntimeError)
9
+ Unauthorized = Class.new(RuntimeError)
10
+ UnprocessableEntity = Class.new(RuntimeError)
11
+
12
+ BASE_URL = 'https://api.hipflag.com/v1/'
13
+ TIMEOUT = 10
14
+
15
+ attr_reader(*Configurable::OPTIONS)
16
+
17
+ def initialize(options = {})
18
+ Configurable::OPTIONS.each do |key|
19
+ instance_variable_set(:"@#{key}", options[key] || Hipflag.send(key))
20
+ end
21
+
22
+ http_client.base_url = BASE_URL
23
+ end
24
+
25
+ private
26
+
27
+ def http_client
28
+ @http_client ||= Patron::Session.new do |config|
29
+ config.timeout = TIMEOUT
30
+ config.headers = {
31
+ 'Content-Type' => 'application/json',
32
+ 'X-Auth-Public' => @public_key,
33
+ 'X-Auth-Secret' => @secret_key
34
+ }
35
+ end
36
+ end
37
+
38
+ def perform_request(method, url, params = {})
39
+ handle_errors do
40
+ Response.new(http_client.request(method, url, {}, params))
41
+ end
42
+ end
43
+
44
+ def handle_errors
45
+ yield.tap do |response|
46
+ if response.unauthorized?
47
+ raise Unauthorized, 'Unauthorized'
48
+ elsif response.unprocessable?
49
+ raise UnprocessableEntity, response.json
50
+ elsif response.server_error?
51
+ raise ServerError, 'Server is not available'
52
+ elsif response.not_found?
53
+ raise NotFound, 'Resource not found'
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,21 @@
1
+ module Hipflag
2
+ class Client
3
+ module Flag
4
+ def flag(flag_id, user_id: nil)
5
+ perform_request(:get, "flags/#{flag_id}?#{flag_params(user_id)}")
6
+ end
7
+
8
+ def update_flag(flag_id, params)
9
+ perform_request(:put, "flags/#{flag_id}", data: { flag: params }.to_json)
10
+ end
11
+
12
+ private
13
+
14
+ def flag_params(user_id)
15
+ return if user_id.nil?
16
+
17
+ URI.encode_www_form(user_id: user_id)
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,11 @@
1
+ module Hipflag
2
+ module Configurable
3
+ OPTIONS = %i[public_key secret_key].freeze
4
+
5
+ attr_accessor(*OPTIONS)
6
+
7
+ def configure
8
+ yield self
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,40 @@
1
+ require 'delegate'
2
+ require 'oj'
3
+
4
+ module Hipflag
5
+ class Response < SimpleDelegator
6
+ alias_method :object, :__getobj__
7
+
8
+ def json
9
+ Oj.load(object.body)
10
+ end
11
+
12
+ def ok?
13
+ object.status == 200
14
+ end
15
+
16
+ def created?
17
+ object.status == 201
18
+ end
19
+
20
+ def no_content?
21
+ object.status == 204
22
+ end
23
+
24
+ def unauthorized?
25
+ object.status == 401
26
+ end
27
+
28
+ def not_found?
29
+ object.status == 404
30
+ end
31
+
32
+ def unprocessable?
33
+ object.status == 422
34
+ end
35
+
36
+ def server_error?
37
+ object.status >= 500
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,3 @@
1
+ module Hipflag
2
+ VERSION = '1.0.0'
3
+ end
metadata ADDED
@@ -0,0 +1,132 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: hipflag
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Hipflag
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2019-05-08 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: patron
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 0.13.1
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 0.13.1
27
+ - !ruby/object:Gem::Dependency
28
+ name: oj
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: 3.7.12
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: 3.7.12
41
+ - !ruby/object:Gem::Dependency
42
+ name: zeitwerk
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: 2.1.6
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: 2.1.6
55
+ - !ruby/object:Gem::Dependency
56
+ name: bundler
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '1.17'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '1.17'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rake
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '12.3'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '12.3'
83
+ description: This gem is a Ruby client for interacting with Hipflag API. Hipflag is
84
+ a tool that allows to control and roll out new product features with flags
85
+ email:
86
+ - info@hipflag.com
87
+ executables:
88
+ - console
89
+ - setup
90
+ extensions: []
91
+ extra_rdoc_files: []
92
+ files:
93
+ - ".gitignore"
94
+ - ".rspec"
95
+ - ".travis.yml"
96
+ - Gemfile
97
+ - LICENSE.txt
98
+ - README.md
99
+ - Rakefile
100
+ - bin/console
101
+ - bin/setup
102
+ - hipflag.gemspec
103
+ - lib/hipflag.rb
104
+ - lib/hipflag/client.rb
105
+ - lib/hipflag/client/flag.rb
106
+ - lib/hipflag/configurable.rb
107
+ - lib/hipflag/response.rb
108
+ - lib/hipflag/version.rb
109
+ homepage: https://github.com/hipflag/hipflag_ruby
110
+ licenses:
111
+ - MIT
112
+ metadata: {}
113
+ post_install_message:
114
+ rdoc_options: []
115
+ require_paths:
116
+ - lib
117
+ required_ruby_version: !ruby/object:Gem::Requirement
118
+ requirements:
119
+ - - ">="
120
+ - !ruby/object:Gem::Version
121
+ version: '0'
122
+ required_rubygems_version: !ruby/object:Gem::Requirement
123
+ requirements:
124
+ - - ">="
125
+ - !ruby/object:Gem::Version
126
+ version: '0'
127
+ requirements: []
128
+ rubygems_version: 3.0.1
129
+ signing_key:
130
+ specification_version: 4
131
+ summary: Ruby client for interacting with Hipflag API
132
+ test_files: []