featury 1.0.0.rc22 → 1.0.0.rc24

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: 978b872baf023c8de159d5ecfa2928e59d1d28d950fd26c9ec9ca3dc43d116b8
4
- data.tar.gz: 326784e9821c20af6dc91f765b069ae1574624b6035dabca6b76dc5331501492
3
+ metadata.gz: 0c1b72f8275c2ade5b4e3716b598937fa8c4f243dfa142c17c9cc675523b9f70
4
+ data.tar.gz: 6112766f0f732d53a04b807e6f5af30f5125077a41a5ca043f43c0145bbba708
5
5
  SHA512:
6
- metadata.gz: 18cd733daf8b0208364b6733d737b9720ca02f446cf899d486737d26fb2bee962cb748f642586bfbe06fbe9ed9d405c7453525493aced50a85da3f759200ecc2
7
- data.tar.gz: 5f5cde128bbc8a04706c72b5cc560f0f5c9b033d92e53298f601c0bf849938b79bd313a92d2419dc1111a85de5adde6541e5d545e03f40e66e859221635a8bba
6
+ metadata.gz: 4d3f21be19cfb9090f9c79ac9ce52d060eaea14ea014384ed2a3f1911f962058d58e87e796c36a28575b24841bf610dd0c2565d16f7a3c0a73a7343f6273b866
7
+ data.tar.gz: 38df69d5f0c94cef5213279b39966c79c006dc1ddff5ccb54f715e51b07c4e42bd2d84858659e3273fe3ddf48efcbd08d244afa40908b5fbefb8a0d1bfb3cd58
data/README.md CHANGED
@@ -56,7 +56,7 @@ class ApplicationFeature < Featury::Base
56
56
  features.all? { |feature| Flipper.disable(feature, *options.values) }
57
57
  end
58
58
 
59
- action :add do |features:, **options|
59
+ action :add, web: :regular do |features:, **options|
60
60
  features.all? { |feature| Flipper.add(feature, *options.values) }
61
61
  end
62
62
 
@@ -90,10 +90,10 @@ class User::OnboardingFeature < ApplicationFeature
90
90
 
91
91
  condition ->(resources:) { resources.user.onboarding_awaiting? }
92
92
 
93
- features :passage # => :user_onboarding_passage
93
+ feature :passage, description: "User onboarding passage feature" # => :user_onboarding_passage
94
94
 
95
- groups BillingFeature,
96
- PaymentSystemFeature
95
+ group BillingFeature, description: "Billing functionality group"
96
+ group PaymentSystemFeature, description: "Payment system functionality group"
97
97
  end
98
98
  ```
99
99
 
@@ -101,8 +101,8 @@ end
101
101
  class BillingFeature < ApplicationFeature
102
102
  prefix :billing
103
103
 
104
- features :api, # => :billing_api
105
- :webhooks # => :billing_webhooks
104
+ feature :api, description: "Billing API feature" # => :billing_api
105
+ feature :webhooks, description: "Billing webhooks feature" # => :billing_webhooks
106
106
  end
107
107
  ```
108
108
 
@@ -110,8 +110,8 @@ end
110
110
  class PaymentSystemFeature < ApplicationFeature
111
111
  prefix :payment_system
112
112
 
113
- features :api, # => :payment_system_api
114
- :webhooks # => :payment_system_webhooks
113
+ feature :api, description: "Payment system API feature" # => :payment_system_api
114
+ feature :webhooks, description: "Payment system webhooks feature" # => :payment_system_webhooks
115
115
  end
116
116
  ```
117
117
 
@@ -161,6 +161,20 @@ In the preceding example, there might be a scenario where the payment system is
161
161
  undergoing technical maintenance and therefore is temporarily shut down.
162
162
  Consequently, the onboarding process for new users will be halted until further notice.
163
163
 
164
+ #### Feature and Group descriptions
165
+
166
+ When defining features and groups, you can provide descriptions to add more context about what they do:
167
+
168
+ ```ruby
169
+ # Adding a feature with description
170
+ feature :api, description: "External API integration"
171
+
172
+ # Adding a group with description
173
+ group PaymentSystemFeature, description: "Payment processing functionality"
174
+ ```
175
+
176
+ These descriptions are preserved in the feature tree and can be accessed via the info method.
177
+
164
178
  #### Information about features
165
179
 
166
180
  ```ruby
@@ -168,11 +182,27 @@ info = User::OnboardingFeature.info
168
182
  ```
169
183
 
170
184
  ```ruby
171
- info.actions # Feature actions (all, web) of the current class.
172
- info.resources # Feature resources of the current class.
173
- info.features # Feature flags of the current class.
174
- info.groups # Feature flag groups of the current class.
175
- info.tree # Tree of feature flags from the current class.
185
+ # Feature actions information (all actions and web actions)
186
+ info.actions.all # All actions: [:enabled?, :disabled?, :enable, :disable, :add]
187
+ info.actions.web.all # Web actions: [:enabled?, :disabled?, :enable, :disable, :add]
188
+
189
+ # Access specific web actions by their web: option name
190
+ info.actions.web.enabled # Returns the method name (:enabled?) that was defined with `web: :enabled?`
191
+ info.actions.web.enable # Returns the method name (:enable) that was defined with `web: :enable`
192
+ info.actions.web.disable # Returns the method name (:disable) that was defined with `web: :disable`
193
+
194
+ # Feature resources information
195
+ info.resources # Feature resources of the current class.
196
+
197
+ # Feature flags information (with descriptions)
198
+ info.features # Feature flags of the current class with their names and descriptions.
199
+
200
+ # Feature groups information (with descriptions)
201
+ info.groups # Feature groups of the current class with their class references and descriptions.
202
+
203
+ # Complete feature tree (features and nested groups)
204
+ info.tree.features # Direct features of the current class.
205
+ info.tree.groups # Features from nested groups.
176
206
  ```
177
207
 
178
208
  ## Contributing
@@ -31,10 +31,25 @@ module Featury
31
31
 
32
32
  input :action, type: Featury::Actions::Action
33
33
 
34
- input :collection_of_resources, type: Featury::Resources::Collection
35
- input :collection_of_conditions, type: Featury::Conditions::Collection
36
- input :collection_of_features, type: Featury::Features::Collection
37
- input :collection_of_groups, type: Featury::Groups::Collection
34
+ input :collection_of_resources,
35
+ type: Featury::Resources::Collection,
36
+ required: false,
37
+ default: Featury::Resources::Collection.new
38
+
39
+ input :collection_of_conditions,
40
+ type: Featury::Conditions::Collection,
41
+ required: false,
42
+ default: Featury::Conditions::Collection.new
43
+
44
+ input :collection_of_features,
45
+ type: Featury::Features::Collection,
46
+ required: false,
47
+ default: Featury::Features::Collection.new
48
+
49
+ input :collection_of_groups,
50
+ type: Featury::Groups::Collection,
51
+ required: false,
52
+ default: Featury::Groups::Collection.new
38
53
 
39
54
  output :all_true, type: [TrueClass, FalseClass]
40
55
 
@@ -65,7 +80,7 @@ module Featury
65
80
  [resource.name, inputs.public_send(resource.name)]
66
81
  end
67
82
 
68
- inputs.action.block.call(features: inputs.collection_of_features.full_names, **options)
83
+ inputs.action.block.call(features: inputs.collection_of_features.names, **options)
69
84
  end
70
85
 
71
86
  def groups_are_true
@@ -74,7 +89,7 @@ module Featury
74
89
  end
75
90
 
76
91
  inputs.collection_of_groups.all? do |group|
77
- group.group.public_send(inputs.action.name, **arguments)
92
+ group.group_class.public_send(inputs.action.name, **arguments)
78
93
  end
79
94
  end
80
95
  end
@@ -9,7 +9,7 @@ module Featury
9
9
  Featury::Callbacks::Service.call!(
10
10
  action: action.name,
11
11
  callbacks: collection_of_callbacks.before,
12
- features: collection_of_features.full_names
12
+ features: collection_of_features.names
13
13
  )
14
14
 
15
15
  result = super
@@ -17,7 +17,7 @@ module Featury
17
17
  Featury::Callbacks::Service.call!(
18
18
  action: action.name,
19
19
  callbacks: collection_of_callbacks.after,
20
- features: collection_of_features.full_names
20
+ features: collection_of_features.names
21
21
  )
22
22
 
23
23
  result
@@ -4,14 +4,14 @@ module Featury
4
4
  module Features
5
5
  class Collection
6
6
  extend Forwardable
7
- def_delegators :@collection, :<<, :each, :map, :merge
7
+ def_delegators :@collection, :<<, :each, :map, :merge, :to_a, :empty?
8
8
 
9
9
  def initialize(collection = Set.new)
10
10
  @collection = collection
11
11
  end
12
12
 
13
- def full_names
14
- map(&:full_name)
13
+ def names
14
+ map(&:name)
15
15
  end
16
16
  end
17
17
  end
@@ -20,12 +20,22 @@ module Featury
20
20
  self.feature_prefix = prefix
21
21
  end
22
22
 
23
+ # DEPRECATED: Need to use the `feature` method instead of `features`.
23
24
  def features(*names)
25
+ Kernel.warn "DEPRECATION WARNING: " \
26
+ "Method `features` is deprecated; " \
27
+ "use `feature` instead. " \
28
+ "It will be removed in one of the next releases."
29
+
24
30
  names.each do |name|
25
- collection_of_features << Feature.new(feature_prefix, name)
31
+ collection_of_features << Feature.new(prefix: feature_prefix, name:, description: nil)
26
32
  end
27
33
  end
28
34
 
35
+ def feature(name, description: nil)
36
+ collection_of_features << Feature.new(prefix: feature_prefix, name:, description:)
37
+ end
38
+
29
39
  def feature_prefix=(value)
30
40
  @feature_prefix = value
31
41
  end
@@ -3,13 +3,12 @@
3
3
  module Featury
4
4
  module Features
5
5
  class Feature
6
- def initialize(prefix, name)
7
- @prefix = prefix
8
- @name = name
9
- end
6
+ attr_reader :name,
7
+ :description
10
8
 
11
- def full_name
12
- :"#{@prefix}_#{@name}"
9
+ def initialize(prefix:, name:, description:)
10
+ @name = :"#{prefix}_#{name}"
11
+ @description = description
13
12
  end
14
13
  end
15
14
  end
@@ -4,7 +4,7 @@ module Featury
4
4
  module Groups
5
5
  class Collection
6
6
  extend Forwardable
7
- def_delegators :@collection, :<<, :each, :map, :filter, :to_h, :merge, :all?
7
+ def_delegators :@collection, :<<, :each, :map, :flat_map, :filter, :to_h, :merge, :to_a, :all?, :empty?
8
8
 
9
9
  def initialize(collection = Set.new)
10
10
  @collection = collection
@@ -16,12 +16,22 @@ module Featury
16
16
 
17
17
  private
18
18
 
19
+ # DEPRECATED: Need to use the `group` method instead of `groups`.
19
20
  def groups(*groups)
21
+ Kernel.warn "DEPRECATION WARNING: " \
22
+ "Method `groups` is deprecated; " \
23
+ "use `group` instead. " \
24
+ "It will be removed in one of the next releases."
25
+
20
26
  groups.each do |group|
21
- collection_of_groups << Group.new(group)
27
+ collection_of_groups << Group.new(group:, description: nil)
22
28
  end
23
29
  end
24
30
 
31
+ def group(group, description: nil)
32
+ collection_of_groups << Group.new(group:, description:)
33
+ end
34
+
25
35
  def collection_of_groups
26
36
  @collection_of_groups ||= Collection.new
27
37
  end
@@ -3,10 +3,12 @@
3
3
  module Featury
4
4
  module Groups
5
5
  class Group
6
- attr_reader :group
6
+ attr_reader :group_class,
7
+ :description
7
8
 
8
- def initialize(group)
9
- @group = group
9
+ def initialize(group:, description:)
10
+ @group_class = group
11
+ @description = description
10
12
  end
11
13
  end
12
14
  end
@@ -8,17 +8,13 @@ module Featury
8
8
  end
9
9
 
10
10
  module ClassMethods
11
- def info # rubocop:disable Metrics/MethodLength, Metrics/AbcSize
11
+ def info
12
12
  Featury::Info::Result.new(
13
13
  actions: Featury::Info::Result::Actions.new(collection_of_actions),
14
- resources: collection_of_resources.names,
15
- features: collection_of_features.full_names,
16
- groups: collection_of_groups.map(&:group),
17
- tree: collection_of_features.full_names.concat(
18
- collection_of_groups.map do |group|
19
- group.group.info.tree
20
- end
21
- )
14
+ resources: Featury::Info::Result::Resources.new(collection_of_resources).all.names,
15
+ features: Featury::Info::Result::Features.new(collection_of_features).all,
16
+ groups: Featury::Info::Result::Groups.new(collection_of_groups).all,
17
+ tree: Featury::Info::Result::Tree.new(collection_of_features, collection_of_groups).all
22
18
  )
23
19
  end
24
20
 
@@ -27,6 +27,74 @@ module Featury
27
27
  end
28
28
  end
29
29
 
30
+ class Resources
31
+ attr_reader :all
32
+
33
+ def initialize(collection_of_resources)
34
+ @all = collection_of_resources
35
+ end
36
+ end
37
+
38
+ class Features
39
+ attr_reader :all
40
+
41
+ def initialize(collection_of_features)
42
+ @all = collection_of_features
43
+ end
44
+ end
45
+
46
+ class Groups
47
+ attr_reader :all
48
+
49
+ def initialize(collection_of_groups)
50
+ @all = collection_of_groups
51
+ end
52
+ end
53
+
54
+ class Tree
55
+ attr_reader :all
56
+
57
+ class Features
58
+ attr_reader :features,
59
+ :groups
60
+
61
+ def initialize(features, groups)
62
+ @features = features.map do |feature|
63
+ Feature.new(
64
+ name: feature.name,
65
+ description: feature.description
66
+ )
67
+ end
68
+
69
+ @groups = groups.flat_map do |group|
70
+ group.group_class.info.tree
71
+ end
72
+ end
73
+
74
+ class Feature
75
+ attr_reader :name,
76
+ :description
77
+
78
+ def initialize(name:, description:)
79
+ @name = name
80
+ @description = description
81
+ end
82
+ end
83
+ end
84
+
85
+ def initialize(features, groups)
86
+ @all = Features.new(features, groups)
87
+
88
+ # @groups = groups.flat_map do |group|
89
+ # group.group_class.info.tree
90
+ # end
91
+ end
92
+
93
+ # nested: @groups.flat_map do |group|
94
+ # group.group_class.info.tree
95
+ # end
96
+ end
97
+
30
98
  attr_reader :actions,
31
99
  :resources,
32
100
  :features,
@@ -5,7 +5,7 @@ module Featury
5
5
  MAJOR = 1
6
6
  MINOR = 0
7
7
  PATCH = 0
8
- PRE = "rc22"
8
+ PRE = "rc24"
9
9
 
10
10
  STRING = [MAJOR, MINOR, PATCH, PRE].compact.join(".")
11
11
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: featury
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0.rc22
4
+ version: 1.0.0.rc24
5
5
  platform: ruby
6
6
  authors:
7
7
  - Anton Sokolov