rails_flags 0.1.0 → 0.1.1
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 +53 -3
- data/app/controllers/rails_flags/admin_controller.rb +36 -0
- data/app/views/rails_flags/admin/index.html.erb +101 -0
- data/config/routes.rb +6 -0
- data/lib/rails_flags/configuration.rb +7 -1
- data/lib/rails_flags/version.rb +1 -1
- data/lib/rails_flags.rb +4 -0
- metadata +25 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fe7b819caaddc037424b3b33e788af96fa02da82f94c6ec2b60c7fe99431e886
|
4
|
+
data.tar.gz: d68835ff9af94c371e65bc0d4b35386d67f9e749cb61a7818dfc7e8abc0900d8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2b9893919d8d482e8c2b9b0ecebde2dbdd2c0c62fffc9597962e9aeb89ce9cb74eb6d1a988e98d7aa67cb8ff55446fa6987d4b48821a2c50116d3ebf4a9335f1
|
7
|
+
data.tar.gz: 30c12444f5b1d0464e8a4e479cb648e8ecc3910574faa68700bd47393de218ff4f3912cd44ad022e46e889187ed88609be4d08f05977decf0f1f272eafed9821
|
data/README.md
CHANGED
@@ -9,6 +9,7 @@ A simple and powerful feature flagging system for Ruby on Rails applications. Ra
|
|
9
9
|
- Thread-safe operations
|
10
10
|
- Configurable default states
|
11
11
|
- Support for flag metadata (descriptions, creation timestamps)
|
12
|
+
- Built-in admin interface for managing feature flags
|
12
13
|
|
13
14
|
## Installation
|
14
15
|
|
@@ -46,7 +47,28 @@ RailsFlags.configure do |config|
|
|
46
47
|
end
|
47
48
|
```
|
48
49
|
|
49
|
-
|
50
|
+
## Usage
|
51
|
+
|
52
|
+
### Mounting the Engine
|
53
|
+
Add this to your `config/routes.rb`:
|
54
|
+
```ruby
|
55
|
+
Rails.application.routes.draw do
|
56
|
+
mount RailsFlags::Engine => "/rails_flags"
|
57
|
+
end
|
58
|
+
```
|
59
|
+
|
60
|
+
### Admin Interface
|
61
|
+
Access the admin interface at `/rails_flags/admin` to:
|
62
|
+
- View all feature flags
|
63
|
+
- Create new feature flags
|
64
|
+
- Enable/disable flags
|
65
|
+
- Delete feature flags
|
66
|
+
|
67
|
+

|
68
|
+
|
69
|
+
### Programmatic Usage
|
70
|
+
|
71
|
+
#### Registering Flags
|
50
72
|
```ruby
|
51
73
|
# Register a new feature flag (disabled by default)
|
52
74
|
RailsFlags.register(
|
@@ -63,7 +85,7 @@ RailsFlags.register(
|
|
63
85
|
)
|
64
86
|
```
|
65
87
|
|
66
|
-
|
88
|
+
#### Checking Flags
|
67
89
|
```ruby
|
68
90
|
# Check if a flag is enabled
|
69
91
|
if RailsFlags.enabled?(:new_feature)
|
@@ -74,7 +96,7 @@ end
|
|
74
96
|
RailsFlags.registered?(:new_feature)
|
75
97
|
```
|
76
98
|
|
77
|
-
|
99
|
+
#### Managing Flags
|
78
100
|
```ruby
|
79
101
|
# Enable a flag
|
80
102
|
RailsFlags.enable(:new_feature)
|
@@ -82,10 +104,21 @@ RailsFlags.enable(:new_feature)
|
|
82
104
|
# Disable a flag
|
83
105
|
RailsFlags.disable(:new_feature)
|
84
106
|
|
107
|
+
# Delete a flag
|
108
|
+
RailsFlags.delete(:new_feature)
|
109
|
+
|
85
110
|
# Get all flags
|
86
111
|
all_flags = RailsFlags.all_flags
|
87
112
|
```
|
88
113
|
|
114
|
+
### In Views
|
115
|
+
You can use feature flags in your views:
|
116
|
+
```erb
|
117
|
+
<% if RailsFlags.enabled?(:new_feature) %>
|
118
|
+
<!-- New feature content -->
|
119
|
+
<% end %>
|
120
|
+
```
|
121
|
+
|
89
122
|
## Storage Adapters
|
90
123
|
|
91
124
|
### Memory Adapter
|
@@ -99,6 +132,23 @@ all_flags = RailsFlags.all_flags
|
|
99
132
|
- Provides atomic operations
|
100
133
|
- Requires Redis server
|
101
134
|
|
135
|
+
## Testing
|
136
|
+
|
137
|
+
This gem supports multiple Rails versions (6.x, 7.x, and 8.x). We use Appraisal to test against different Rails versions.
|
138
|
+
|
139
|
+
To run the tests for all supported Rails versions:
|
140
|
+
|
141
|
+
```bash
|
142
|
+
bundle exec appraisal rspec
|
143
|
+
```
|
144
|
+
|
145
|
+
To run tests for a specific Rails version:
|
146
|
+
|
147
|
+
```bash
|
148
|
+
bundle exec appraisal rails-6 rspec # For Rails 6
|
149
|
+
bundle exec appraisal rails-7 rspec # For Rails 7
|
150
|
+
bundle exec appraisal rails-8 rspec # For Rails 8
|
151
|
+
```
|
102
152
|
|
103
153
|
## Contributing
|
104
154
|
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module RailsFlags
|
2
|
+
class AdminController < ApplicationController
|
3
|
+
def index
|
4
|
+
@feature_flags = RailsFlags.all_flags
|
5
|
+
end
|
6
|
+
|
7
|
+
def create
|
8
|
+
RailsFlags.register(
|
9
|
+
params[:name],
|
10
|
+
enabled: params[:enabled] == "1",
|
11
|
+
description: params[:description]
|
12
|
+
)
|
13
|
+
redirect_to admin_path, notice: "Feature flag created successfully"
|
14
|
+
rescue StandardError => e
|
15
|
+
redirect_to admin_path, alert: e.message
|
16
|
+
end
|
17
|
+
|
18
|
+
def update
|
19
|
+
if params[:enabled] == "1"
|
20
|
+
RailsFlags.enable(params[:name])
|
21
|
+
else
|
22
|
+
RailsFlags.disable(params[:name])
|
23
|
+
end
|
24
|
+
redirect_to admin_path, notice: "Feature flag updated successfully"
|
25
|
+
rescue StandardError => e
|
26
|
+
redirect_to admin_path, alert: e.message
|
27
|
+
end
|
28
|
+
|
29
|
+
def destroy
|
30
|
+
RailsFlags.delete(params[:name])
|
31
|
+
redirect_to admin_path, notice: "Feature flag deleted successfully"
|
32
|
+
rescue StandardError => e
|
33
|
+
redirect_to admin_path, alert: e.message
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,101 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<title>Feature Flags Admin</title>
|
5
|
+
<meta name="viewport" content="width=device-width,initial-scale=1">
|
6
|
+
<%= csrf_meta_tags %>
|
7
|
+
<%= csp_meta_tag %>
|
8
|
+
|
9
|
+
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet">
|
10
|
+
</head>
|
11
|
+
<body>
|
12
|
+
<div class="container mt-4">
|
13
|
+
<h1>Feature Flags Admin</h1>
|
14
|
+
|
15
|
+
<% if notice %>
|
16
|
+
<div class="alert alert-success"><%= notice %></div>
|
17
|
+
<% end %>
|
18
|
+
|
19
|
+
<% if alert %>
|
20
|
+
<div class="alert alert-danger"><%= alert %></div>
|
21
|
+
<% end %>
|
22
|
+
|
23
|
+
<!-- New Feature Flag Form -->
|
24
|
+
<div class="card mb-4">
|
25
|
+
<div class="card-header">
|
26
|
+
<h5 class="mb-0">Create New Feature Flag</h5>
|
27
|
+
</div>
|
28
|
+
<div class="card-body">
|
29
|
+
<%= form_tag admin_create_path, method: :post, class: 'row g-3' do %>
|
30
|
+
<div class="col-md-4">
|
31
|
+
<label class="form-label">Name</label>
|
32
|
+
<%= text_field_tag :name, nil, class: 'form-control', required: true %>
|
33
|
+
</div>
|
34
|
+
<div class="col-md-6">
|
35
|
+
<label class="form-label">Description</label>
|
36
|
+
<%= text_field_tag :description, nil, class: 'form-control' %>
|
37
|
+
</div>
|
38
|
+
<div class="col-md-2">
|
39
|
+
<label class="form-label">Enabled</label>
|
40
|
+
<div>
|
41
|
+
<%= check_box_tag :enabled, "1", false, class: 'form-check-input' %>
|
42
|
+
</div>
|
43
|
+
</div>
|
44
|
+
<div class="col-12">
|
45
|
+
<%= submit_tag 'Create Feature Flag', class: 'btn btn-primary' %>
|
46
|
+
</div>
|
47
|
+
<% end %>
|
48
|
+
</div>
|
49
|
+
</div>
|
50
|
+
|
51
|
+
<!-- Feature Flags List -->
|
52
|
+
<div class="card">
|
53
|
+
<div class="card-header">
|
54
|
+
<h5 class="mb-0">Existing Feature Flags</h5>
|
55
|
+
</div>
|
56
|
+
<div class="card-body">
|
57
|
+
<div class="table-responsive">
|
58
|
+
<table class="table">
|
59
|
+
<thead>
|
60
|
+
<tr>
|
61
|
+
<th>Name</th>
|
62
|
+
<th>Description</th>
|
63
|
+
<th>Status</th>
|
64
|
+
<th>Created At</th>
|
65
|
+
<th>Actions</th>
|
66
|
+
</tr>
|
67
|
+
</thead>
|
68
|
+
<tbody>
|
69
|
+
<% @feature_flags.each do |name, data| %>
|
70
|
+
<tr>
|
71
|
+
<td><%= name %></td>
|
72
|
+
<td><%= data[:description] %></td>
|
73
|
+
<td>
|
74
|
+
<%= form_tag admin_update_path(name), method: :patch, class: 'd-inline' do %>
|
75
|
+
<div class="form-check form-switch">
|
76
|
+
<%= check_box_tag :enabled, "1", data[:enabled],
|
77
|
+
class: 'form-check-input',
|
78
|
+
onchange: 'this.form.submit()' %>
|
79
|
+
</div>
|
80
|
+
<% end %>
|
81
|
+
</td>
|
82
|
+
<td><%= data[:created_at]&.strftime("%Y-%m-%d %H:%M:%S") %></td>
|
83
|
+
<td>
|
84
|
+
<%= button_to "Delete",
|
85
|
+
admin_delete_path(name),
|
86
|
+
method: :delete,
|
87
|
+
class: "btn btn-danger btn-sm",
|
88
|
+
data: { confirm: "Are you sure?" } %>
|
89
|
+
</td>
|
90
|
+
</tr>
|
91
|
+
<% end %>
|
92
|
+
</tbody>
|
93
|
+
</table>
|
94
|
+
</div>
|
95
|
+
</div>
|
96
|
+
</div>
|
97
|
+
</div>
|
98
|
+
|
99
|
+
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js"></script>
|
100
|
+
</body>
|
101
|
+
</html>
|
data/config/routes.rb
CHANGED
@@ -1,2 +1,8 @@
|
|
1
1
|
RailsFlags::Engine.routes.draw do
|
2
|
+
get "/admin", to: "admin#index", as: :admin
|
3
|
+
post "/admin/create", to: "admin#create", as: :admin_create
|
4
|
+
patch "/admin/:name", to: "admin#update", as: :admin_update
|
5
|
+
delete "/admin/:name", to: "admin#destroy", as: :admin_delete
|
6
|
+
|
7
|
+
root to: "admin#index"
|
2
8
|
end
|
@@ -42,6 +42,11 @@ module RailsFlags
|
|
42
42
|
@adapter.write(flag.to_sym, data)
|
43
43
|
end
|
44
44
|
|
45
|
+
def delete(flag)
|
46
|
+
validate_flag_exists!(flag)
|
47
|
+
@adapter.delete(flag.to_sym)
|
48
|
+
end
|
49
|
+
|
45
50
|
def registered?(flag)
|
46
51
|
@adapter.read(flag.to_sym) ? true : false
|
47
52
|
end
|
@@ -53,7 +58,8 @@ module RailsFlags
|
|
53
58
|
private
|
54
59
|
|
55
60
|
def validate_flag_name!(name)
|
56
|
-
raise ArgumentError, "Flag name
|
61
|
+
raise ArgumentError, "Flag name cannot be nil" if name.nil?
|
62
|
+
raise ArgumentError, "Flag name must be a string or symbol" unless name.is_a?(String) || name.is_a?(Symbol)
|
57
63
|
raise ArgumentError, "Flag name cannot be empty" if name.to_s.strip.empty?
|
58
64
|
end
|
59
65
|
|
data/lib/rails_flags/version.rb
CHANGED
data/lib/rails_flags.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rails_flags
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Dhurba Baral
|
@@ -16,14 +16,20 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version:
|
19
|
+
version: '6.0'
|
20
|
+
- - "<"
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: '8.1'
|
20
23
|
type: :runtime
|
21
24
|
prerelease: false
|
22
25
|
version_requirements: !ruby/object:Gem::Requirement
|
23
26
|
requirements:
|
24
27
|
- - ">="
|
25
28
|
- !ruby/object:Gem::Version
|
26
|
-
version:
|
29
|
+
version: '6.0'
|
30
|
+
- - "<"
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '8.1'
|
27
33
|
- !ruby/object:Gem::Dependency
|
28
34
|
name: redis
|
29
35
|
requirement: !ruby/object:Gem::Requirement
|
@@ -52,6 +58,20 @@ dependencies:
|
|
52
58
|
- - ">="
|
53
59
|
- !ruby/object:Gem::Version
|
54
60
|
version: '0'
|
61
|
+
- !ruby/object:Gem::Dependency
|
62
|
+
name: appraisal
|
63
|
+
requirement: !ruby/object:Gem::Requirement
|
64
|
+
requirements:
|
65
|
+
- - ">="
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
version: '0'
|
68
|
+
type: :development
|
69
|
+
prerelease: false
|
70
|
+
version_requirements: !ruby/object:Gem::Requirement
|
71
|
+
requirements:
|
72
|
+
- - ">="
|
73
|
+
- !ruby/object:Gem::Version
|
74
|
+
version: '0'
|
55
75
|
description: A simple and powerful feature flagging system for Ruby on Rails applications.
|
56
76
|
RailsFlags provides an easy way to manage feature flags with support for multiple
|
57
77
|
storage backends.
|
@@ -65,12 +85,14 @@ files:
|
|
65
85
|
- README.md
|
66
86
|
- Rakefile
|
67
87
|
- app/assets/stylesheets/rails_flags/application.css
|
88
|
+
- app/controllers/rails_flags/admin_controller.rb
|
68
89
|
- app/controllers/rails_flags/application_controller.rb
|
69
90
|
- app/helpers/rails_flags/application_helper.rb
|
70
91
|
- app/jobs/rails_flags/application_job.rb
|
71
92
|
- app/mailers/rails_flags/application_mailer.rb
|
72
93
|
- app/models/rails_flags/application_record.rb
|
73
94
|
- app/views/layouts/rails_flags/application.html.erb
|
95
|
+
- app/views/rails_flags/admin/index.html.erb
|
74
96
|
- config/routes.rb
|
75
97
|
- lib/rails_flags.rb
|
76
98
|
- lib/rails_flags/adapters/base.rb
|