switchlet 0.2.0 → 0.3.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 +45 -4
- data/app/controllers/switchlet/flags_controller.rb +18 -15
- data/app/views/switchlet/flags/index.html.erb +139 -94
- data/config/routes.rb +3 -7
- data/lib/switchlet/version.rb +1 -1
- data/lib/switchlet.rb +6 -3
- metadata +1 -7
- data/lib/generators/switchlet/add_description_generator.rb +0 -22
- data/lib/generators/switchlet/templates/add_description_to_switchlet_flags.rb +0 -7
- data/switchlet-0.1.1.gem +0 -0
- data/switchlet-0.1.2.gem +0 -0
- data/switchlet-0.1.3.gem +0 -0
- data/switchlet-0.1.4.gem +0 -0
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: f5df5ba1da7343518f0a7886f3e8cb26a7b125d217fddae79a43106e58a07ca3
|
|
4
|
+
data.tar.gz: e2005adb28bcd955ea762047e462f6befd04502d99df79fffdb69119d426addf
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 3ece132acb395196ea895f118a6899857ffafe3d07930eaaccee2fe0115573d7addb904f2236758b8e1cee91ff2ed51af771b27335061ef4ceee1e9f884b8570
|
|
7
|
+
data.tar.gz: 880b12eb1b49bcb90122be722b5ee9c8a0c359b558af95c961ee58471374fff013965513115fb246abd4eb751453202cbf6dd17c100dacebc60cd77b4c4a0aed
|
data/README.md
CHANGED
|
@@ -28,16 +28,18 @@ Switchlet.enabled?(:my_feature) # => false
|
|
|
28
28
|
Switchlet.enable!(:my_feature) # => true
|
|
29
29
|
|
|
30
30
|
# Enable a feature with description
|
|
31
|
-
Switchlet.enable!(:my_feature
|
|
31
|
+
Switchlet.enable!(:my_feature) # => true
|
|
32
32
|
|
|
33
33
|
# Disable a feature
|
|
34
34
|
Switchlet.disable!(:my_feature) # => false
|
|
35
35
|
|
|
36
36
|
# Disable with description
|
|
37
|
-
Switchlet.disable!(:my_feature
|
|
37
|
+
Switchlet.disable!(:my_feature) # => false
|
|
38
38
|
|
|
39
|
-
#
|
|
40
|
-
Switchlet.
|
|
39
|
+
# Update description or enabled status
|
|
40
|
+
Switchlet.update!(:my_feature, description: "Updated description") # => Flag object
|
|
41
|
+
Switchlet.update!(:my_feature, enabled: false) # => Flag object
|
|
42
|
+
Switchlet.update!(:my_feature, description: "New description", enabled: true) # => Flag object
|
|
41
43
|
|
|
42
44
|
# Delete a feature flag
|
|
43
45
|
Switchlet.delete!(:my_feature) # => nil
|
|
@@ -46,6 +48,45 @@ Switchlet.delete!(:my_feature) # => nil
|
|
|
46
48
|
Switchlet.list # => [{ name: "my_feature", enabled: true, description: "New payment system", updated_at: Time }]
|
|
47
49
|
```
|
|
48
50
|
|
|
51
|
+
### Common Usage Patterns
|
|
52
|
+
|
|
53
|
+
Feature flags are often combined with other conditions for more sophisticated control:
|
|
54
|
+
|
|
55
|
+
```ruby
|
|
56
|
+
# Time-based rollout: Enable feature after specific date
|
|
57
|
+
if Switchlet.enabled?(:my_feature) && Time.current >= Time.zone.parse("2025-06-01 00:00:00")
|
|
58
|
+
# New feature implementation
|
|
59
|
+
render :new_checkout_process
|
|
60
|
+
else
|
|
61
|
+
# Fallback to old implementation
|
|
62
|
+
render :old_checkout_process
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
# User-based gradual rollout: Enable for specific user segments
|
|
66
|
+
if Switchlet.enabled?(:my_feature) && current_user.id % 4 == 0
|
|
67
|
+
# Enable for 25% of users (user IDs divisible by 4)
|
|
68
|
+
show_new_dashboard_ui
|
|
69
|
+
else
|
|
70
|
+
show_classic_dashboard_ui
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
# Role-based access: Enable only for specific user roles
|
|
74
|
+
if Switchlet.enabled?(:my_feature) && current_user.admin?
|
|
75
|
+
# Admin-only feature
|
|
76
|
+
render_admin_analytics_panel
|
|
77
|
+
else
|
|
78
|
+
render_basic_stats
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
# Complex conditions: Combine multiple criteria
|
|
82
|
+
if Switchlet.enabled?(:beta_features) &&
|
|
83
|
+
current_user.beta_tester? &&
|
|
84
|
+
Time.current.hour.between?(9, 17)
|
|
85
|
+
# Beta feature available only during business hours for beta testers
|
|
86
|
+
enable_experimental_features
|
|
87
|
+
end
|
|
88
|
+
```
|
|
89
|
+
|
|
49
90
|
## Web UI
|
|
50
91
|
|
|
51
92
|
Switchlet includes a web interface for managing feature flags:
|
|
@@ -6,18 +6,6 @@ module Switchlet
|
|
|
6
6
|
@flags = Switchlet.list
|
|
7
7
|
end
|
|
8
8
|
|
|
9
|
-
def toggle
|
|
10
|
-
flag_name = params[:name]
|
|
11
|
-
current_state = Switchlet.enabled?(flag_name)
|
|
12
|
-
|
|
13
|
-
if current_state
|
|
14
|
-
Switchlet.disable!(flag_name)
|
|
15
|
-
else
|
|
16
|
-
Switchlet.enable!(flag_name)
|
|
17
|
-
end
|
|
18
|
-
|
|
19
|
-
redirect_to switchlet.flags_path, notice: "Flag '#{flag_name}' #{current_state ? 'disabled' : 'enabled'}"
|
|
20
|
-
end
|
|
21
9
|
|
|
22
10
|
def create
|
|
23
11
|
flag_name = params[:flag_name].strip
|
|
@@ -32,9 +20,24 @@ module Switchlet
|
|
|
32
20
|
|
|
33
21
|
def update
|
|
34
22
|
flag_name = params[:name]
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
23
|
+
|
|
24
|
+
# Handle toggle action
|
|
25
|
+
if params[:action_type] == 'toggle'
|
|
26
|
+
current_state = Switchlet.enabled?(flag_name)
|
|
27
|
+
|
|
28
|
+
if current_state
|
|
29
|
+
Switchlet.disable!(flag_name)
|
|
30
|
+
else
|
|
31
|
+
Switchlet.enable!(flag_name)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
redirect_to switchlet.flags_path, notice: "Flag '#{flag_name}' #{current_state ? 'disabled' : 'enabled'}"
|
|
35
|
+
# Handle description update
|
|
36
|
+
else
|
|
37
|
+
description = params[:description]
|
|
38
|
+
Switchlet.update!(flag_name, description: description)
|
|
39
|
+
redirect_to switchlet.flags_path, notice: "Description updated for '#{flag_name}'"
|
|
40
|
+
end
|
|
38
41
|
end
|
|
39
42
|
|
|
40
43
|
def destroy
|
|
@@ -6,163 +6,207 @@
|
|
|
6
6
|
<%= csrf_meta_tags %>
|
|
7
7
|
<style>
|
|
8
8
|
body {
|
|
9
|
-
font-family: -apple-system,
|
|
9
|
+
font-family: system-ui, -apple-system, sans-serif;
|
|
10
10
|
margin: 0;
|
|
11
|
-
padding:
|
|
12
|
-
background
|
|
11
|
+
padding: 16px;
|
|
12
|
+
background: #fff;
|
|
13
13
|
color: #333;
|
|
14
|
+
line-height: 1.4;
|
|
14
15
|
}
|
|
15
16
|
.container {
|
|
16
|
-
max-width:
|
|
17
|
+
max-width: 1000px;
|
|
17
18
|
margin: 0 auto;
|
|
18
|
-
background: white;
|
|
19
|
-
padding: 30px;
|
|
20
|
-
border-radius: 8px;
|
|
21
|
-
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
|
|
22
19
|
}
|
|
23
20
|
h1 {
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
21
|
+
font-size: 24px;
|
|
22
|
+
font-weight: 600;
|
|
23
|
+
margin: 0 0 24px 0;
|
|
24
|
+
color: #000;
|
|
28
25
|
}
|
|
29
26
|
.alert {
|
|
30
|
-
padding: 12px
|
|
31
|
-
|
|
32
|
-
|
|
27
|
+
padding: 8px 12px;
|
|
28
|
+
margin-bottom: 16px;
|
|
29
|
+
border-radius: 3px;
|
|
30
|
+
font-size: 14px;
|
|
33
31
|
}
|
|
34
32
|
.alert-success {
|
|
35
|
-
background
|
|
36
|
-
color: #
|
|
37
|
-
border: 1px solid #c3e6cb;
|
|
33
|
+
background: #d4f7d4;
|
|
34
|
+
color: #0d5016;
|
|
38
35
|
}
|
|
39
36
|
.alert-danger {
|
|
40
|
-
background
|
|
37
|
+
background: #ffd6d6;
|
|
41
38
|
color: #721c24;
|
|
42
|
-
border: 1px solid #f5c6cb;
|
|
43
39
|
}
|
|
44
40
|
.create-form {
|
|
45
|
-
|
|
46
|
-
padding:
|
|
47
|
-
border
|
|
48
|
-
|
|
41
|
+
margin-bottom: 24px;
|
|
42
|
+
padding: 16px;
|
|
43
|
+
border: 1px solid #ddd;
|
|
44
|
+
border-radius: 3px;
|
|
49
45
|
}
|
|
50
46
|
.create-form h2 {
|
|
51
|
-
|
|
52
|
-
|
|
47
|
+
font-size: 16px;
|
|
48
|
+
font-weight: 600;
|
|
49
|
+
margin: 0 0 12px 0;
|
|
53
50
|
}
|
|
54
51
|
.form-group {
|
|
55
52
|
display: flex;
|
|
56
53
|
flex-direction: column;
|
|
57
|
-
gap:
|
|
54
|
+
gap: 8px;
|
|
58
55
|
}
|
|
59
56
|
.form-row {
|
|
60
57
|
display: flex;
|
|
61
|
-
gap:
|
|
58
|
+
gap: 8px;
|
|
62
59
|
align-items: center;
|
|
63
60
|
}
|
|
64
|
-
input
|
|
61
|
+
.flag-name-input {
|
|
62
|
+
flex: 0 0 200px;
|
|
63
|
+
}
|
|
64
|
+
.description-input-inline {
|
|
65
65
|
flex: 1;
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
66
|
+
}
|
|
67
|
+
input, textarea {
|
|
68
|
+
padding: 8px;
|
|
69
|
+
border: 1px solid #ccc;
|
|
70
|
+
border-radius: 3px;
|
|
69
71
|
font-size: 14px;
|
|
70
|
-
font-family: inherit;
|
|
71
72
|
}
|
|
72
73
|
textarea {
|
|
73
74
|
resize: vertical;
|
|
74
|
-
min-height: 40px;
|
|
75
75
|
}
|
|
76
76
|
.btn {
|
|
77
|
-
padding: 8px
|
|
78
|
-
border:
|
|
79
|
-
border-radius:
|
|
77
|
+
padding: 8px 12px;
|
|
78
|
+
border: 1px solid #ccc;
|
|
79
|
+
border-radius: 3px;
|
|
80
|
+
background: #f8f8f8;
|
|
80
81
|
cursor: pointer;
|
|
81
|
-
text-decoration: none;
|
|
82
82
|
font-size: 14px;
|
|
83
|
+
text-decoration: none;
|
|
83
84
|
display: inline-block;
|
|
84
85
|
}
|
|
86
|
+
.btn:hover {
|
|
87
|
+
background: #e8e8e8;
|
|
88
|
+
}
|
|
85
89
|
.btn-primary {
|
|
86
|
-
background
|
|
87
|
-
color:
|
|
90
|
+
background: #0969da;
|
|
91
|
+
color: #fff;
|
|
92
|
+
border-color: #0969da;
|
|
88
93
|
}
|
|
89
94
|
.btn-primary:hover {
|
|
90
|
-
background
|
|
95
|
+
background: #0860ca;
|
|
91
96
|
}
|
|
92
97
|
.btn-success {
|
|
93
|
-
background
|
|
94
|
-
color:
|
|
98
|
+
background: #1a7f37;
|
|
99
|
+
color: #fff;
|
|
100
|
+
border-color: #1a7f37;
|
|
95
101
|
}
|
|
96
102
|
.btn-success:hover {
|
|
97
|
-
background
|
|
103
|
+
background: #116329;
|
|
98
104
|
}
|
|
99
105
|
.btn-danger {
|
|
100
|
-
background
|
|
101
|
-
color:
|
|
106
|
+
background: #d1242f;
|
|
107
|
+
color: #fff;
|
|
108
|
+
border-color: #d1242f;
|
|
102
109
|
}
|
|
103
110
|
.btn-danger:hover {
|
|
104
|
-
background
|
|
111
|
+
background: #a40e26;
|
|
105
112
|
}
|
|
106
|
-
.btn-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
}
|
|
110
|
-
.btn-secondary:hover {
|
|
111
|
-
background-color: #7f8c8d;
|
|
113
|
+
.btn-sm {
|
|
114
|
+
padding: 4px 8px;
|
|
115
|
+
font-size: 12px;
|
|
112
116
|
}
|
|
113
|
-
|
|
117
|
+
table {
|
|
114
118
|
width: 100%;
|
|
115
119
|
border-collapse: collapse;
|
|
116
|
-
|
|
120
|
+
border: 1px solid #ddd;
|
|
117
121
|
}
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
padding: 12px;
|
|
122
|
+
th, td {
|
|
123
|
+
padding: 8px 12px;
|
|
121
124
|
text-align: left;
|
|
122
125
|
border-bottom: 1px solid #ddd;
|
|
123
126
|
}
|
|
124
|
-
|
|
125
|
-
background
|
|
127
|
+
th {
|
|
128
|
+
background: #f6f8fa;
|
|
126
129
|
font-weight: 600;
|
|
127
|
-
|
|
130
|
+
font-size: 14px;
|
|
128
131
|
}
|
|
129
132
|
.status-enabled {
|
|
130
|
-
color: #
|
|
131
|
-
font-weight:
|
|
133
|
+
color: #1a7f37;
|
|
134
|
+
font-weight: 600;
|
|
132
135
|
}
|
|
133
136
|
.status-disabled {
|
|
134
|
-
color: #
|
|
135
|
-
font-weight:
|
|
137
|
+
color: #d1242f;
|
|
138
|
+
font-weight: 600;
|
|
136
139
|
}
|
|
137
140
|
.actions {
|
|
138
141
|
display: flex;
|
|
139
|
-
gap:
|
|
142
|
+
gap: 4px;
|
|
143
|
+
align-items: center;
|
|
140
144
|
}
|
|
141
145
|
.actions form {
|
|
142
146
|
margin: 0;
|
|
143
147
|
}
|
|
148
|
+
.toggle-form {
|
|
149
|
+
display: inline-block;
|
|
150
|
+
}
|
|
151
|
+
.toggle-switch {
|
|
152
|
+
position: relative;
|
|
153
|
+
display: inline-block;
|
|
154
|
+
width: 44px;
|
|
155
|
+
height: 24px;
|
|
156
|
+
margin-right: 8px;
|
|
157
|
+
}
|
|
158
|
+
.toggle-switch input {
|
|
159
|
+
opacity: 0;
|
|
160
|
+
width: 0;
|
|
161
|
+
height: 0;
|
|
162
|
+
}
|
|
163
|
+
.toggle-slider {
|
|
164
|
+
position: absolute;
|
|
165
|
+
cursor: pointer;
|
|
166
|
+
top: 0;
|
|
167
|
+
left: 0;
|
|
168
|
+
right: 0;
|
|
169
|
+
bottom: 0;
|
|
170
|
+
background-color: #ccc;
|
|
171
|
+
transition: .3s;
|
|
172
|
+
border-radius: 24px;
|
|
173
|
+
}
|
|
174
|
+
.toggle-slider:before {
|
|
175
|
+
position: absolute;
|
|
176
|
+
content: "";
|
|
177
|
+
height: 18px;
|
|
178
|
+
width: 18px;
|
|
179
|
+
left: 3px;
|
|
180
|
+
bottom: 3px;
|
|
181
|
+
background-color: white;
|
|
182
|
+
transition: .3s;
|
|
183
|
+
border-radius: 50%;
|
|
184
|
+
}
|
|
185
|
+
.toggle-switch input:checked + .toggle-slider {
|
|
186
|
+
background-color: #1a7f37;
|
|
187
|
+
}
|
|
188
|
+
.toggle-switch input:checked + .toggle-slider:before {
|
|
189
|
+
transform: translateX(20px);
|
|
190
|
+
}
|
|
191
|
+
.toggle-switch input:focus + .toggle-slider {
|
|
192
|
+
box-shadow: 0 0 0 2px rgba(26, 127, 55, 0.2);
|
|
193
|
+
}
|
|
144
194
|
.empty-state {
|
|
145
195
|
text-align: center;
|
|
146
|
-
padding:
|
|
147
|
-
color: #
|
|
196
|
+
padding: 48px 16px;
|
|
197
|
+
color: #656d76;
|
|
148
198
|
}
|
|
149
199
|
.text-muted {
|
|
150
|
-
color: #
|
|
151
|
-
font-style: italic;
|
|
152
|
-
}
|
|
153
|
-
.description-cell {
|
|
154
|
-
min-width: 200px;
|
|
200
|
+
color: #656d76;
|
|
155
201
|
}
|
|
156
202
|
.description-text {
|
|
157
203
|
cursor: pointer;
|
|
158
|
-
display: block;
|
|
159
|
-
min-height: 20px;
|
|
160
204
|
padding: 4px;
|
|
161
|
-
border-radius:
|
|
162
|
-
|
|
205
|
+
border-radius: 3px;
|
|
206
|
+
min-height: 16px;
|
|
163
207
|
}
|
|
164
208
|
.description-text:hover {
|
|
165
|
-
background
|
|
209
|
+
background: #f6f8fa;
|
|
166
210
|
}
|
|
167
211
|
.description-input {
|
|
168
212
|
width: 100%;
|
|
@@ -172,10 +216,6 @@
|
|
|
172
216
|
display: flex;
|
|
173
217
|
gap: 4px;
|
|
174
218
|
}
|
|
175
|
-
.btn-sm {
|
|
176
|
-
padding: 4px 8px;
|
|
177
|
-
font-size: 12px;
|
|
178
|
-
}
|
|
179
219
|
</style>
|
|
180
220
|
</head>
|
|
181
221
|
<body>
|
|
@@ -193,12 +233,10 @@
|
|
|
193
233
|
<div class="create-form">
|
|
194
234
|
<h2>Create New Flag</h2>
|
|
195
235
|
<%= form_with url: switchlet.flags_path, local: true do |form| %>
|
|
196
|
-
<div class="form-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
</div>
|
|
201
|
-
<%= form.text_area :description, placeholder: "Optional description...", rows: 2 %>
|
|
236
|
+
<div class="form-row">
|
|
237
|
+
<%= form.text_field :flag_name, placeholder: "Flag name", required: true, class: "flag-name-input" %>
|
|
238
|
+
<%= form.text_field :description, placeholder: "Optional description", class: "description-input-inline" %>
|
|
239
|
+
<%= form.submit "Create Flag", class: "btn btn-primary" %>
|
|
202
240
|
</div>
|
|
203
241
|
<% end %>
|
|
204
242
|
</div>
|
|
@@ -233,7 +271,9 @@
|
|
|
233
271
|
<% end %>
|
|
234
272
|
</span>
|
|
235
273
|
<div class="description-edit" style="display: none;">
|
|
236
|
-
<%= form_with url: switchlet.flag_path(flag[:name]),
|
|
274
|
+
<%= form_with url: switchlet.flag_path(flag[:name]), local: true, class: "description-form" do |form| %>
|
|
275
|
+
<%= hidden_field_tag :authenticity_token, form_authenticity_token %>
|
|
276
|
+
<%= hidden_field_tag :_method, 'patch' %>
|
|
237
277
|
<%= form.text_area :description, value: flag[:description], rows: 2,
|
|
238
278
|
class: "description-input",
|
|
239
279
|
placeholder: "Enter description..." %>
|
|
@@ -253,14 +293,19 @@
|
|
|
253
293
|
<td><%= flag[:updated_at].strftime("%Y-%m-%d %H:%M") %></td>
|
|
254
294
|
<td>
|
|
255
295
|
<div class="actions">
|
|
256
|
-
<%=
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
296
|
+
<%= form_with url: switchlet.flag_path(flag[:name]), method: :patch, local: true, class: "toggle-form" do |form| %>
|
|
297
|
+
<%= hidden_field_tag :authenticity_token, form_authenticity_token %>
|
|
298
|
+
<%= hidden_field_tag :action_type, 'toggle' %>
|
|
299
|
+
<label class="toggle-switch">
|
|
300
|
+
<%= check_box_tag "enabled", "1", flag[:enabled],
|
|
301
|
+
onchange: "this.form.submit()",
|
|
302
|
+
class: "toggle-input" %>
|
|
303
|
+
<span class="toggle-slider"></span>
|
|
304
|
+
</label>
|
|
260
305
|
<% end %>
|
|
261
306
|
<%= button_to switchlet.flag_path(flag[:name]),
|
|
262
307
|
method: :delete,
|
|
263
|
-
class: "btn btn-danger",
|
|
308
|
+
class: "btn btn-danger btn-sm",
|
|
264
309
|
confirm: "Are you sure you want to delete '#{flag[:name]}'?" do %>
|
|
265
310
|
Delete
|
|
266
311
|
<% end %>
|
data/config/routes.rb
CHANGED
|
@@ -2,10 +2,6 @@
|
|
|
2
2
|
|
|
3
3
|
Switchlet::Engine.routes.draw do
|
|
4
4
|
root "flags#index"
|
|
5
|
-
|
|
6
|
-
resources :flags, only: [:index, :create, :update, :destroy], param: :name
|
|
7
|
-
|
|
8
|
-
patch :toggle
|
|
9
|
-
end
|
|
10
|
-
end
|
|
11
|
-
end
|
|
5
|
+
|
|
6
|
+
resources :flags, only: [:index, :create, :update, :destroy], param: :name
|
|
7
|
+
end
|
data/lib/switchlet/version.rb
CHANGED
data/lib/switchlet.rb
CHANGED
|
@@ -53,9 +53,12 @@ module Switchlet
|
|
|
53
53
|
end
|
|
54
54
|
end
|
|
55
55
|
|
|
56
|
-
def self.
|
|
56
|
+
def self.update!(name, description: nil, enabled: nil)
|
|
57
57
|
flag = Flag.find_or_create_by(name: name.to_s)
|
|
58
|
-
|
|
59
|
-
|
|
58
|
+
attrs = {}
|
|
59
|
+
attrs[:description] = description unless description.nil?
|
|
60
|
+
attrs[:enabled] = enabled unless enabled.nil?
|
|
61
|
+
flag.update!(attrs) if attrs.any?
|
|
62
|
+
flag
|
|
60
63
|
end
|
|
61
64
|
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: switchlet
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.3.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- komagata
|
|
@@ -65,9 +65,7 @@ files:
|
|
|
65
65
|
- app/controllers/switchlet/flags_controller.rb
|
|
66
66
|
- app/views/switchlet/flags/index.html.erb
|
|
67
67
|
- config/routes.rb
|
|
68
|
-
- lib/generators/switchlet/add_description_generator.rb
|
|
69
68
|
- lib/generators/switchlet/install_generator.rb
|
|
70
|
-
- lib/generators/switchlet/templates/add_description_to_switchlet_flags.rb
|
|
71
69
|
- lib/generators/switchlet/templates/create_switchlet_flags.rb
|
|
72
70
|
- lib/generators/switchlet/templates/switchlet.rb
|
|
73
71
|
- lib/switchlet.rb
|
|
@@ -78,10 +76,6 @@ files:
|
|
|
78
76
|
- lib/switchlet/version.rb
|
|
79
77
|
- lib/tasks/switchlet.rake
|
|
80
78
|
- sig/switchlet.rbs
|
|
81
|
-
- switchlet-0.1.1.gem
|
|
82
|
-
- switchlet-0.1.2.gem
|
|
83
|
-
- switchlet-0.1.3.gem
|
|
84
|
-
- switchlet-0.1.4.gem
|
|
85
79
|
homepage: https://github.com/komagata/switchlet
|
|
86
80
|
licenses:
|
|
87
81
|
- MIT
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require "rails/generators"
|
|
4
|
-
require "rails/generators/migration"
|
|
5
|
-
|
|
6
|
-
module Switchlet
|
|
7
|
-
module Generators
|
|
8
|
-
class AddDescriptionGenerator < Rails::Generators::Base
|
|
9
|
-
include Rails::Generators::Migration
|
|
10
|
-
|
|
11
|
-
source_root File.expand_path("templates", __dir__)
|
|
12
|
-
|
|
13
|
-
def self.next_migration_number(path)
|
|
14
|
-
ActiveRecord::Generators::Base.next_migration_number(path)
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
def create_migration_file
|
|
18
|
-
migration_template "add_description_to_switchlet_flags.rb", "db/migrate/add_description_to_switchlet_flags.rb"
|
|
19
|
-
end
|
|
20
|
-
end
|
|
21
|
-
end
|
|
22
|
-
end
|
data/switchlet-0.1.1.gem
DELETED
|
Binary file
|
data/switchlet-0.1.2.gem
DELETED
|
Binary file
|
data/switchlet-0.1.3.gem
DELETED
|
Binary file
|
data/switchlet-0.1.4.gem
DELETED
|
Binary file
|