flagsmith 3.1.1 → 3.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 540a1b7662a35e22fd9acd04ff632ff0ac3178653aa1b154406d0b5f27420f70
4
- data.tar.gz: 47a63fc9e165518bc8e7b0f946e3ebea50676771e4165ac9e383104950a54ce6
3
+ metadata.gz: 55ba6a7589045f62c03387dfb9fba16bdcf0eec278ee14b3db7549c6d16d0bcc
4
+ data.tar.gz: 1a91d635ec437cfe284492e11e57b2aa06edd13013dd562db0550cc5245a85a6
5
5
  SHA512:
6
- metadata.gz: 4f328cea0c2c2b56d0fda76244aab72a0314d590308f2ed2fbd458ebb2ba215c1feb57b02b1ac06034d6cebd19a2cecc236d496b8b929caf4083cb949e912b97
7
- data.tar.gz: 5325e0fd19633dd3f91665635ebb10e0a3c88d447df1a5db8bcef3c0d492f392fa477a22ac2ad04a7b918c2493c3f80e56e69634628c5df9ae16876a1ba11103
6
+ metadata.gz: 1e8bc92bbd6382240c16e9a3a48c5f3509ce4d68518d7152594c43095c722dfe3503216d9e77fa1ff740013c5164c998555ec1a95f98ec6c9b4eed35c037fa8b
7
+ data.tar.gz: 6b3c87dd50db25cc67bb9cca968f9b21ac1a9ed3f935978b6589479cc9ce76689cc9ae7eae9f05cfeb70fd4a8dc090dcd4d3dea6614121d30c08b2b9c9be22eb
data/.rubocop.yml CHANGED
@@ -9,3 +9,4 @@ AllCops:
9
9
  Exclude:
10
10
  - 'spec/**/*'
11
11
  - 'example/**/*'
12
+ - 'vendor/**/*'
data/.rubocop_todo.yml CHANGED
@@ -1,29 +1,22 @@
1
1
  # This configuration was generated by
2
- # `rubocop --auto-gen-config --auto-gen-only-exclude`
3
- # on 2020-12-30 22:56:14 UTC using RuboCop version 1.7.0.
2
+ # `rubocop --auto-gen-config`
3
+ # on 2023-07-20 10:26:52 UTC using RuboCop version 1.54.2.
4
4
  # The point is for the user to remove these configuration records
5
5
  # one by one as the offenses are removed from the code base.
6
6
  # Note that changes in the inspected code, or installation of new
7
7
  # versions of RuboCop, may require this file to be generated again.
8
8
 
9
- # Offense count: 1
10
- # Configuration parameters: CountComments, Max, CountAsOne, ExcludedMethods, IgnoredMethods.
11
- # IgnoredMethods: refine
12
- Metrics/BlockLength:
9
+ # Offense count: 6
10
+ # Configuration parameters: EnforcedStyle, AllowedGems, Include.
11
+ # SupportedStyles: Gemfile, gems.rb, gemspec
12
+ # Include: **/*.gemspec, **/Gemfile, **/gems.rb
13
+ Gemspec/DevelopmentDependencies:
13
14
  Exclude:
14
- - '**/*.gemspec'
15
-
16
- # Offense count: 1
17
- # Configuration parameters: AllowedMethods.
18
- # AllowedMethods: respond_to_missing?
19
- Style/OptionalBooleanParameter:
20
- Exclude:
21
- - 'lib/flagsmith.rb'
15
+ - 'flagsmith.gemspec'
22
16
 
23
- # Offense count: 1
24
- # Cop supports --auto-correct.
25
- # Configuration parameters: AutoCorrect, Max, AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, IgnoredPatterns.
17
+ # Offense count: 4
18
+ # This cop supports safe autocorrection (--autocorrect).
19
+ # Configuration parameters: AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, AllowedPatterns.
26
20
  # URISchemes: http, https
27
21
  Layout/LineLength:
28
- Exclude:
29
- - 'flagsmith.gemspec'
22
+ Max: 183
data/.ruby-version CHANGED
@@ -1 +1 @@
1
- 2.4.0
1
+ 3.1.4
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- flagsmith (3.1.1)
4
+ flagsmith (3.2.0)
5
5
  faraday
6
6
  faraday-retry
7
7
  faraday_middleware
@@ -10,10 +10,10 @@ PATH
10
10
  GEM
11
11
  remote: https://rubygems.org/
12
12
  specs:
13
- ast (2.4.1)
13
+ ast (2.4.2)
14
14
  coderay (1.1.3)
15
15
  diff-lcs (1.4.4)
16
- faraday (1.10.0)
16
+ faraday (1.10.3)
17
17
  faraday-em_http (~> 1.0)
18
18
  faraday-em_synchrony (~> 1.0)
19
19
  faraday-excon (~> 1.1)
@@ -39,17 +39,21 @@ GEM
39
39
  faraday_middleware (1.2.0)
40
40
  faraday (~> 1.0)
41
41
  gem-release (2.2.0)
42
+ json (2.6.3)
43
+ language_server-protocol (3.17.0.3)
42
44
  method_source (1.0.0)
43
- multipart-post (2.2.3)
44
- parallel (1.20.1)
45
- parser (3.0.0.0)
45
+ multipart-post (2.3.0)
46
+ parallel (1.23.0)
47
+ parser (3.2.2.3)
46
48
  ast (~> 2.4.1)
49
+ racc
47
50
  pry (0.14.1)
48
51
  coderay (~> 1.1)
49
52
  method_source (~> 1.0)
50
- rainbow (3.0.0)
53
+ racc (1.7.1)
54
+ rainbow (3.1.1)
51
55
  rake (13.0.3)
52
- regexp_parser (2.0.3)
56
+ regexp_parser (2.8.1)
53
57
  rexml (3.2.5)
54
58
  rspec (3.10.0)
55
59
  rspec-core (~> 3.10.0)
@@ -64,21 +68,23 @@ GEM
64
68
  diff-lcs (>= 1.2.0, < 2.0)
65
69
  rspec-support (~> 3.10.0)
66
70
  rspec-support (3.10.1)
67
- rubocop (1.7.0)
71
+ rubocop (1.54.2)
72
+ json (~> 2.3)
73
+ language_server-protocol (>= 3.17.0)
68
74
  parallel (~> 1.10)
69
- parser (>= 2.7.1.5)
75
+ parser (>= 3.2.2.3)
70
76
  rainbow (>= 2.2.2, < 4.0)
71
77
  regexp_parser (>= 1.8, < 3.0)
72
- rexml
73
- rubocop-ast (>= 1.2.0, < 2.0)
78
+ rexml (>= 3.2.5, < 4.0)
79
+ rubocop-ast (>= 1.28.0, < 2.0)
74
80
  ruby-progressbar (~> 1.7)
75
- unicode-display_width (>= 1.4.0, < 2.0)
76
- rubocop-ast (1.3.0)
77
- parser (>= 2.7.1.5)
78
- ruby-progressbar (1.10.1)
81
+ unicode-display_width (>= 2.4.0, < 3.0)
82
+ rubocop-ast (1.29.0)
83
+ parser (>= 3.2.1.0)
84
+ ruby-progressbar (1.13.0)
79
85
  ruby2_keywords (0.0.5)
80
86
  semantic (1.6.1)
81
- unicode-display_width (1.7.0)
87
+ unicode-display_width (2.4.2)
82
88
 
83
89
  PLATFORMS
84
90
  ruby
data/example/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: ..
3
3
  specs:
4
- flagsmith (3.0.0)
4
+ flagsmith (3.1.1)
5
5
  faraday
6
6
  faraday-retry
7
7
  faraday_middleware
@@ -10,8 +10,8 @@ PATH
10
10
  GEM
11
11
  remote: https://rubygems.org/
12
12
  specs:
13
- addressable (2.8.0)
14
- public_suffix (>= 2.0.2, < 5.0)
13
+ addressable (2.8.4)
14
+ public_suffix (>= 2.0.2, < 6.0)
15
15
  ast (2.4.2)
16
16
  better_errors (2.9.1)
17
17
  coderay (>= 1.0.0)
@@ -20,13 +20,14 @@ GEM
20
20
  bigdecimal (1.4.4)
21
21
  binding_of_caller (0.8.0)
22
22
  debug_inspector (>= 0.0.1)
23
- capybara (3.32.2)
23
+ capybara (3.39.0)
24
24
  addressable
25
+ matrix
25
26
  mini_mime (>= 0.1.3)
26
27
  nokogiri (~> 1.8)
27
28
  rack (>= 1.6.0)
28
29
  rack-test (>= 0.6.3)
29
- regexp_parser (~> 1.5)
30
+ regexp_parser (>= 1.5, < 3.0)
30
31
  xpath (~> 3.2)
31
32
  coderay (1.1.3)
32
33
  concurrent-ruby (1.1.10)
@@ -71,7 +72,7 @@ GEM
71
72
  dry-logic (~> 0.4, >= 0.4.0)
72
73
  dry-types (~> 0.11.0)
73
74
  erubi (1.10.0)
74
- faraday (1.10.0)
75
+ faraday (1.10.3)
75
76
  faraday-em_http (~> 1.0)
76
77
  faraday-em_synchrony (~> 1.0)
77
78
  faraday-excon (~> 1.1)
@@ -87,8 +88,8 @@ GEM
87
88
  faraday-em_synchrony (1.0.0)
88
89
  faraday-excon (1.1.0)
89
90
  faraday-httpclient (1.0.1)
90
- faraday-multipart (1.0.3)
91
- multipart-post (>= 1.2, < 3)
91
+ faraday-multipart (1.0.4)
92
+ multipart-post (~> 2)
92
93
  faraday-net_http (1.0.1)
93
94
  faraday-net_http_persistent (1.2.0)
94
95
  faraday-patron (1.0.0)
@@ -156,28 +157,31 @@ GEM
156
157
  inflecto (0.0.2)
157
158
  mail (2.7.1)
158
159
  mini_mime (>= 0.1.1)
160
+ matrix (0.4.2)
159
161
  method_source (1.0.0)
160
162
  mini_mime (1.1.2)
161
- mini_portile2 (2.4.0)
162
- multipart-post (2.1.1)
163
+ multipart-post (2.3.0)
163
164
  nio4r (2.5.8)
164
- nokogiri (1.10.10)
165
- mini_portile2 (~> 2.4.0)
165
+ nokogiri (1.14.3-arm64-darwin)
166
+ racc (~> 1.4)
167
+ nokogiri (1.14.3-x86_64-linux)
168
+ racc (~> 1.4)
166
169
  parallel (1.20.1)
167
170
  parser (3.1.2.0)
168
171
  ast (~> 2.4.1)
169
172
  pry (0.14.1)
170
173
  coderay (~> 1.1)
171
174
  method_source (~> 1.0)
172
- public_suffix (4.0.7)
175
+ public_suffix (5.0.1)
173
176
  puma (5.6.4)
174
177
  nio4r (~> 2.0)
175
- rack (2.2.3.1)
176
- rack-test (1.1.0)
177
- rack (>= 1.0, < 3)
178
+ racc (1.6.2)
179
+ rack (2.2.7)
180
+ rack-test (2.1.0)
181
+ rack (>= 1.3)
178
182
  rainbow (3.1.1)
179
183
  rake (13.0.6)
180
- regexp_parser (1.8.2)
184
+ regexp_parser (2.8.0)
181
185
  rexml (3.2.5)
182
186
  rom (3.3.3)
183
187
  concurrent-ruby (~> 1.0)
@@ -245,6 +249,7 @@ GEM
245
249
  nokogiri (~> 1.8)
246
250
 
247
251
  PLATFORMS
252
+ arm64-darwin-21
248
253
  x86_64-linux
249
254
 
250
255
  DEPENDENCIES
data/flagsmith.gemspec CHANGED
@@ -35,4 +35,5 @@ Gem::Specification.new do |spec|
35
35
  spec.add_dependency 'faraday_middleware'
36
36
  spec.add_dependency 'faraday-retry'
37
37
  spec.add_dependency 'semantic'
38
+ spec.metadata['rubygems_mfa_required'] = 'true'
38
39
  end
@@ -40,9 +40,7 @@ module Flagsmith
40
40
  multivariate_feature_state_values.sort.each do |multi_fs_value|
41
41
  limit = multi_fs_value.percentage_allocation + start_percentage
42
42
 
43
- if start_percentage <= percentage_value && percentage_value < limit
44
- return multi_fs_value.multivariate_feature_option.value
45
- end
43
+ return multi_fs_value.multivariate_feature_option.value if start_percentage <= percentage_value && percentage_value < limit
46
44
 
47
45
  start_percentage = limit
48
46
  end
@@ -165,7 +163,7 @@ module Flagsmith
165
163
  attr_reader :priority
166
164
 
167
165
  def initialize(params = {})
168
- @priority = params[:priority].nil? ? nil : params[:priority].to_i
166
+ @priority = params[:priority]&.to_i
169
167
  end
170
168
  end
171
169
  end
@@ -25,6 +25,7 @@ module Flagsmith
25
25
  IS_SET = 'IS_SET'
26
26
  IS_NOT_SET = 'IS_NOT_SET'
27
27
  MODULO = 'MODULO'
28
+ IN = 'IN'
28
29
 
29
30
  CONDITION_OPERATORS = [
30
31
  EQUAL,
@@ -37,7 +38,8 @@ module Flagsmith
37
38
  NOT_EQUAL,
38
39
  REGEX,
39
40
  PERCENTAGE_SPLIT,
40
- MODULO
41
+ MODULO,
42
+ IN
41
43
  ].freeze
42
44
  end
43
45
  end
@@ -36,6 +36,7 @@ module Flagsmith
36
36
  end
37
37
  end
38
38
 
39
+ # rubocop:disable Metrics/MethodLength
39
40
  def traits_match_segment_rule(identity_traits, rule, segment_id, identity_id)
40
41
  matching_block = lambda { |condition|
41
42
  traits_match_segment_condition(identity_traits, condition, segment_id, identity_id)
@@ -44,23 +45,25 @@ module Flagsmith
44
45
  matches_conditions =
45
46
  if rule.conditions&.length&.positive?
46
47
  rule.conditions.send(rule.matching_function, &matching_block)
47
- else true
48
+ else
49
+ true
48
50
  end
49
51
 
50
52
  matches_conditions &&
51
53
  rule.rules.all? { |r| traits_match_segment_rule(identity_traits, r, segment_id, identity_id) }
52
54
  end
55
+ # rubocop:enable Metrics/MethodLength
53
56
 
54
57
  def traits_match_segment_condition(identity_traits, condition, segment_id, identity_id)
55
58
  if condition.operator == PERCENTAGE_SPLIT
56
- return hashed_percentage_for_object_ids([segment_id, identity_id]) <= condition.value.to_f
59
+ return hashed_percentage_for_object_ids([segment_id,
60
+ identity_id]) <= condition.value.to_f
57
61
  end
58
62
 
59
63
  trait = identity_traits.find { |t| t.key.to_s == condition.property }
60
64
 
61
- if [IS_SET, IS_NOT_SET].include?(condition.operator)
62
- return handle_trait_existence_conditions(trait, condition.operator)
63
- end
65
+ return handle_trait_existence_conditions(trait, condition.operator) if [IS_SET,
66
+ IS_NOT_SET].include?(condition.operator)
64
67
 
65
68
  return condition.match_trait_value?(trait.trait_value) if trait
66
69
 
@@ -56,10 +56,9 @@ module Flagsmith
56
56
 
57
57
  def match_trait_value?(trait_value)
58
58
  # handle some exceptions
59
- if @value.is_a?(String) && @value.match?(/:semver$/)
60
- trait_value = Semantic::Version.new(trait_value.gsub(/:semver$/, ''))
61
- end
59
+ trait_value = Semantic::Version.new(trait_value.gsub(/:semver$/, '')) if @value.is_a?(String) && @value.match?(/:semver$/)
62
60
 
61
+ return match_in_value(trait_value) if @operator == IN
63
62
  return match_modulo_value(trait_value) if @operator == MODULO
64
63
 
65
64
  type_as_trait_value = format_to_type_of(trait_value)
@@ -73,8 +72,8 @@ module Flagsmith
73
72
  {
74
73
  'String' => ->(v) { v.to_s },
75
74
  'Semantic::Version' => ->(v) { Semantic::Version.new(v.to_s.gsub(/:semver$/, '')) },
76
- 'TrueClass' => ->(v) { ['True', 'true', 'TRUE', true, 1, '1'].include?(v) ? true : false },
77
- 'FalseClass' => ->(v) { ['False', 'false', 'FALSE', false, 0, '0'].include?(v) ? false : true },
75
+ 'TrueClass' => ->(v) { ['True', 'true', 'TRUE', true, 1, '1'].include?(v) },
76
+ 'FalseClass' => ->(v) { !['False', 'false', 'FALSE', false, 0, '0'].include?(v) },
78
77
  'Integer' => ->(v) { v.to_i },
79
78
  'Float' => ->(v) { v.to_f }
80
79
  }[input.class.to_s]
@@ -83,11 +82,17 @@ module Flagsmith
83
82
 
84
83
  def match_modulo_value(trait_value)
85
84
  divisor, remainder = @value.split('|')
86
- trait_value.is_a?(Numeric) && trait_value % divisor.to_f == remainder.to_f
85
+ trait_value.is_a?(Numeric) && trait_value % divisor.to_f == remainder.to_f # rubocop:disable Lint/FloatComparison
87
86
  rescue StandardError
88
87
  false
89
88
  end
90
89
 
90
+ def match_in_value(trait_value)
91
+ return @value.split(',').include?(trait_value.to_s) if trait_value.is_a?(String) || trait_value.is_a?(Integer)
92
+
93
+ false
94
+ end
95
+
91
96
  class << self
92
97
  def build(json)
93
98
  new(**json.slice(:operator, :value).merge(property: json[:property_]))
@@ -84,7 +84,7 @@ module Flagsmith
84
84
 
85
85
  class << self
86
86
  def environment_key
87
- ENV['FLAGSMITH_ENVIRONMENT_KEY']
87
+ ENV.fetch('FLAGSMITH_ENVIRONMENT_KEY', nil)
88
88
  end
89
89
  end
90
90
  end
@@ -4,32 +4,34 @@ module Flagsmith
4
4
  module Flags
5
5
  class NotFound < StandardError; end
6
6
 
7
+ # Base data class for the flag entity
7
8
  class BaseFlag
8
9
  include Comparable
9
10
 
10
11
  attr_reader :enabled, :value, :default
11
-
12
+
12
13
  def initialize(enabled:, value:, default:)
13
14
  @enabled = enabled
14
15
  @value = value
15
16
  @default = default
16
17
  end
17
-
18
+
18
19
  def enabled?
19
20
  enabled
20
21
  end
21
-
22
+
22
23
  alias is_default default
23
24
  end
24
25
 
26
+ # Flag class to be used by default handler logic
25
27
  class DefaultFlag < BaseFlag
26
28
  def initialize(enabled:, value:)
27
29
  super(enabled: enabled, value: value, default: true)
28
30
  end
29
31
  end
30
32
 
33
+ # 'live' Flag class as returned by API or local evaluation
31
34
  class Flag < BaseFlag
32
-
33
35
  attr_reader :feature_name, :feature_id
34
36
 
35
37
  def initialize(feature_name:, enabled:, value:, feature_id:)
@@ -77,6 +79,8 @@ module Flagsmith
77
79
  end
78
80
  end
79
81
 
82
+ # Implementation of a class to hold a collection of flags.
83
+ # Implements methods for working with the list to avoid requesting flags for each feature evaluation.
80
84
  class Collection
81
85
  include Enumerable
82
86
 
@@ -159,7 +163,7 @@ module Flagsmith
159
163
  def from_feature_state_models(feature_states, identity_id: nil, **args)
160
164
  to_flag_object = lambda { |feature_state, acc|
161
165
  acc[normalize_key(feature_state.feature.name)] =
162
- Flagsmith::Flags::Flag.from_feature_state_model(feature_state, identity_id)
166
+ Flagsmith::Flags::Flag.from_feature_state_model(feature_state, identity_id)
163
167
  }
164
168
 
165
169
  new(
@@ -2,9 +2,10 @@
2
2
 
3
3
  module Flagsmith
4
4
  module Segments
5
+ # Data class to hold segment information.
5
6
  class Segment
6
7
  attr_reader :id, :name
7
-
8
+
8
9
  def initialize(id:, name:)
9
10
  @id = id
10
11
  @name = name
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Flagsmith
4
- VERSION = '3.1.1'
4
+ VERSION = '3.2.0'
5
5
  end
data/lib/flagsmith.rb CHANGED
@@ -22,7 +22,7 @@ require 'flagsmith/engine/core'
22
22
  # no-doc
23
23
  module Flagsmith
24
24
  # Ruby client for flagsmith.com
25
- class Client
25
+ class Client # rubocop:disable Metrics/ClassLength
26
26
  extend Forwardable
27
27
  # A Flagsmith client.
28
28
  #
@@ -153,13 +153,13 @@ module Flagsmith
153
153
 
154
154
  def get_identity_segments(identifier, traits = {})
155
155
  unless environment
156
- raise Flagsmith::ClientError,
157
- 'Local evaluation required to obtain identity segments.'
156
+ raise Flagsmith::ClientError,
157
+ 'Local evaluation required to obtain identity segments.'
158
158
  end
159
159
 
160
160
  identity_model = build_identity_model(identifier, traits)
161
161
  segment_models = engine.get_identity_segments(environment, identity_model)
162
- return segment_models.map { |sm| Flagsmith::Segments::Segment.new(id: sm.id, name: sm.name) }.compact
162
+ segment_models.map { |sm| Flagsmith::Segments::Segment.new(id: sm.id, name: sm.name) }.compact
163
163
  end
164
164
 
165
165
  private
metadata CHANGED
@@ -1,15 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: flagsmith
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.1.1
4
+ version: 3.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tom Stuart
8
8
  - Brian Moelk
9
- autorequire:
9
+ autorequire:
10
10
  bindir: exe
11
11
  cert_chain: []
12
- date: 2023-02-22 00:00:00.000000000 Z
12
+ date: 2023-07-25 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: bundler
@@ -228,8 +228,9 @@ files:
228
228
  - lib/flagsmith/version.rb
229
229
  homepage: https://flagsmith.com
230
230
  licenses: []
231
- metadata: {}
232
- post_install_message:
231
+ metadata:
232
+ rubygems_mfa_required: 'true'
233
+ post_install_message:
233
234
  rdoc_options: []
234
235
  require_paths:
235
236
  - lib
@@ -244,8 +245,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
244
245
  - !ruby/object:Gem::Version
245
246
  version: '0'
246
247
  requirements: []
247
- rubygems_version: 3.3.7
248
- signing_key:
248
+ rubygems_version: 3.3.26
249
+ signing_key:
249
250
  specification_version: 4
250
251
  summary: Flagsmith - Ship features with confidence
251
252
  test_files: []