ffe 0.2.0 → 1.0.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/README.md +40 -3
- data/app/controllers/ffe/feature_flags_controller.rb +10 -5
- data/app/views/ffe/feature_flags/_form.html.erb +5 -0
- data/app/views/ffe/feature_flags/index.html.erb +4 -3
- data/app/views/ffe/feature_flags/show.html.erb +5 -0
- data/config/routes.rb +3 -1
- data/lib/ffe/version.rb +1 -1
- data/lib/generators/ffe/install/install_generator.rb +1 -0
- data/lib/generators/ffe/templates/feature_flags.json.tt +9 -0
- data/lib/generators/ffe/templates/ffe_initializer.rb.tt +16 -0
- metadata +2 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 8714db1c7883a34c1d3d855f04531060fe1dfe11b568bee0508570f4e4c1942a
|
|
4
|
+
data.tar.gz: e781c9895aeeb7ccc047b684805216d81ee4e3adc1eece5e7ee3fe9078f4a715
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 5ca29b54bfe343aa8dd8fee221a0921bf8ce349b177e759d65efecdabe69d8c824a439d507b687d7bfd42bf72ab0492ed38365cad0febc90ef0c4f7239908002
|
|
7
|
+
data.tar.gz: 792f322fe595ec922daf165dee955ee7550a02ab6ef0354ef007fdb60ac44248f48b1c878ee0d324161a43b1b5d43c3a6e7dd42eabbefd45322be00734158f9b
|
data/README.md
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
A minimalistic Feature Flag engine, cause i was bored of unleash and other overloaded ones.
|
|
4
4
|
|
|
5
5
|
## Installation
|
|
6
|
+
|
|
6
7
|
Add this line to your application's Gemfile:
|
|
7
8
|
|
|
8
9
|
```ruby
|
|
@@ -28,6 +29,9 @@ config.env_variable = 'RAILS_ENV'
|
|
|
28
29
|
config.queue_adapter = :solid_queue
|
|
29
30
|
```
|
|
30
31
|
|
|
32
|
+
It also adds a loader for `feature_flags.json`, so you can easily load feature flags from a file.
|
|
33
|
+
But to this later under `Scenarios`.
|
|
34
|
+
|
|
31
35
|
Install the migration with:
|
|
32
36
|
```bash
|
|
33
37
|
$ bin/rails ffe:install:migrations
|
|
@@ -52,17 +56,50 @@ Run your app and go to [http://localhost:3000/ffe/feature_flags](http://localhos
|
|
|
52
56
|
|
|
53
57
|
1. general usage, respecting only the environment
|
|
54
58
|
```rb
|
|
55
|
-
FeatureFlag.enabled?(:flag)
|
|
59
|
+
Ffe::FeatureFlag.enabled?(:flag)
|
|
56
60
|
# or
|
|
57
|
-
FeatureFlag.disabled?(:flag)
|
|
61
|
+
Ffe::FeatureFlag.disabled?(:flag)
|
|
58
62
|
```
|
|
59
63
|
|
|
60
64
|
|
|
61
65
|
2. check if a user is allowed
|
|
62
66
|
```rb
|
|
63
|
-
FeatureFlag.enabled_for?(:flag, user: current_user)
|
|
67
|
+
Ffe::FeatureFlag.enabled_for?(:flag, user: current_user)
|
|
64
68
|
```
|
|
65
69
|
|
|
70
|
+
## Usage Scenarios
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
**Use Case**: Cleaning-Up -- The functionality is available to everyone.
|
|
74
|
+
|
|
75
|
+
> Please don't forget to remove feature flags after its use isn't needed anymore.
|
|
76
|
+
|
|
77
|
+
> Every unused feature flag, makes the code noisy and uncomfortable to read and understand.
|
|
78
|
+
|
|
79
|
+
1. Clean up the code after the feature flag has been disabled, or doesn't changed over a long time!
|
|
80
|
+
|
|
81
|
+
**Use Case**: A new functionality is to be developed that is accessible to specific users and/or environments via a feature flag.
|
|
82
|
+
|
|
83
|
+
1. Create a feature flag in production
|
|
84
|
+
2. Dump the flags, then replace the `config/feature_flags.json` file locally and commit it.
|
|
85
|
+
3. Continue developing against the feature as before.
|
|
86
|
+
|
|
87
|
+
**Use Case**: Functionality is available to only a small number of users.
|
|
88
|
+
|
|
89
|
+
1. Create a feature flag in production, and add allowed users.
|
|
90
|
+
2. Dump the flags, then replace the `config/feature_flags.json` file locally and commit it.
|
|
91
|
+
3. Edit the flag locally and specify a corresponding user.
|
|
92
|
+
4. Continue developing against the feature as before.
|
|
93
|
+
|
|
94
|
+
**Use Case**: Set a feature flag for an announcement, or something similar, for a specific period of time.
|
|
95
|
+
|
|
96
|
+
> This requires the use of ActiveJob; currently, only `SolidQueue` and `Sidekiq` are supported. But feel free to add more.
|
|
97
|
+
|
|
98
|
+
1. Create a feature flag in production, but without setting the expires date.
|
|
99
|
+
2. Dump the flags, then replace the `config/feature_flags.json` file locally and commit it.
|
|
100
|
+
3. Continue developing against the feature as before.
|
|
101
|
+
4. After deployment to production, set the expiration date on the flag -- the flag will be automatically disabled after the expiration date.
|
|
102
|
+
|
|
66
103
|
|
|
67
104
|
## Contributing
|
|
68
105
|
|
|
@@ -5,19 +5,19 @@ module Ffe
|
|
|
5
5
|
before_action :set_ffe, only: %i[show edit update destroy]
|
|
6
6
|
|
|
7
7
|
def index
|
|
8
|
-
@feature_flags =
|
|
8
|
+
@feature_flags = Ffe::FeatureFlag.order(created_at: :desc)
|
|
9
9
|
end
|
|
10
10
|
|
|
11
11
|
def show; end
|
|
12
12
|
|
|
13
13
|
def new
|
|
14
|
-
@feature_flag =
|
|
14
|
+
@feature_flag = Ffe::FeatureFlag.new
|
|
15
15
|
end
|
|
16
16
|
|
|
17
17
|
def edit; end
|
|
18
18
|
|
|
19
19
|
def create
|
|
20
|
-
@feature_flag =
|
|
20
|
+
@feature_flag = Ffe::FeatureFlag.new(feature_flag_params.except(:milieus, :clear_expires_at))
|
|
21
21
|
|
|
22
22
|
if @feature_flag.save
|
|
23
23
|
redirect_to feature_flag_path(@feature_flag), notice: 'FFE wurde erstellt.'
|
|
@@ -39,18 +39,23 @@ module Ffe
|
|
|
39
39
|
redirect_to feature_flags_path, notice: 'FFE wurde gelöscht.'
|
|
40
40
|
end
|
|
41
41
|
|
|
42
|
+
def dump
|
|
43
|
+
render json: Ffe::FeatureFlag.order(:name).map { |ff| ff.attributes.slice('name', 'description', 'enabled', 'milieu', 'expires_at', 'percentage') }
|
|
44
|
+
end
|
|
45
|
+
|
|
42
46
|
private
|
|
43
47
|
|
|
44
48
|
def set_ffe
|
|
45
|
-
@feature_flag =
|
|
49
|
+
@feature_flag = Ffe::FeatureFlag.find(params.expect(:id))
|
|
46
50
|
end
|
|
47
51
|
|
|
48
52
|
def feature_flag_params
|
|
49
53
|
params.expect(
|
|
50
|
-
feature_flag: [:name, :description, :enabled, :expires_at, :clear_expires_at, { milieus: {} }]
|
|
54
|
+
feature_flag: [:name, :description, :enabled, :expires_at, :clear_expires_at, { user_ids: [], milieus: {} }]
|
|
51
55
|
).tap do |params|
|
|
52
56
|
params[:milieu] = params[:milieus].values.join.ljust(Ffe.config.bitlength, '0') if params[:milieus].present?
|
|
53
57
|
params[:expires_at] = nil if params[:clear_expires_at] == '1'
|
|
58
|
+
params[:user_ids]&.delete_if(&:blank?)
|
|
54
59
|
end
|
|
55
60
|
end
|
|
56
61
|
end
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
<h1>Feature Flags</h1>
|
|
2
2
|
|
|
3
|
-
<
|
|
3
|
+
<div><%= link_to 'Neues Feature Flag anlegen', new_feature_flag_path %></div>
|
|
4
|
+
<div><%= link_to 'dump', dump_feature_flags_path, download: 'feature_flags.json' %></div>
|
|
4
5
|
|
|
5
6
|
<table>
|
|
6
7
|
<thead>
|
|
@@ -22,8 +23,8 @@
|
|
|
22
23
|
<td><%= feature_flag.expires_at&.strftime('%Y-%m-%dT%H:%M') %></td>
|
|
23
24
|
<td><%= feature_flag.readable_milieus %></td>
|
|
24
25
|
<td>
|
|
25
|
-
<%= link_to
|
|
26
|
-
<%= button_to
|
|
26
|
+
<%= link_to 'Bearbeiten', edit_feature_flag_path(feature_flag) %>
|
|
27
|
+
<%= button_to 'Löschen', feature_flag_path(feature_flag), method: :delete %>
|
|
27
28
|
</td>
|
|
28
29
|
</tr>
|
|
29
30
|
<% end %>
|
|
@@ -17,5 +17,10 @@
|
|
|
17
17
|
<%= @feature_flag.readable_milieus %>
|
|
18
18
|
</div>
|
|
19
19
|
|
|
20
|
+
<div>
|
|
21
|
+
<strong>User IDs:</strong>
|
|
22
|
+
<%= @feature_flag.user_ids %>
|
|
23
|
+
</div>
|
|
24
|
+
|
|
20
25
|
<p><%= link_to "Bearbeiten", edit_feature_flag_path(@feature_flag) %></p>
|
|
21
26
|
<p><%= link_to "Zurück", feature_flags_path %></p>
|
data/config/routes.rb
CHANGED
data/lib/ffe/version.rb
CHANGED
|
@@ -29,3 +29,19 @@ Ffe.configure do |config|
|
|
|
29
29
|
# actual supported: :solid_queue, :sidekiq
|
|
30
30
|
config.queue_adapter = ActiveJob::Base.queue_adapter_name.to_sym
|
|
31
31
|
end
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
Rails.configuration.after_initialize do
|
|
35
|
+
if ActiveRecord::Base.connection.table_exists?(:feature_flags)
|
|
36
|
+
path = Rails.root.join('config/feature_flags.json')
|
|
37
|
+
next unless File.exist?(path)
|
|
38
|
+
|
|
39
|
+
data = JSON.load_file(path)
|
|
40
|
+
data.each do |flag|
|
|
41
|
+
name = flag.delete('name')
|
|
42
|
+
next if Ffe::FeatureFlag.exists?(name: name)
|
|
43
|
+
|
|
44
|
+
Ffe::FeatureFlag.create_with(flag).find_or_create_by(name: name)
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: ffe
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 1.0.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- LeFnord
|
|
@@ -59,6 +59,7 @@ files:
|
|
|
59
59
|
- lib/ffe/engine.rb
|
|
60
60
|
- lib/ffe/version.rb
|
|
61
61
|
- lib/generators/ffe/install/install_generator.rb
|
|
62
|
+
- lib/generators/ffe/templates/feature_flags.json.tt
|
|
62
63
|
- lib/generators/ffe/templates/ffe_initializer.rb.tt
|
|
63
64
|
- lib/tasks/ffe_tasks.rake
|
|
64
65
|
homepage: https://github.com/LeFnord/ffe
|