rollout_ui2 0.2.0 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Rakefile +0 -5
- data/example_rack/.ruby-version +1 -0
- data/example_rack/Gemfile +2 -0
- data/example_rack/Gemfile.lock +21 -1
- data/example_rack/config.ru +50 -2
- data/lib/rollout_ui2/version.rb +1 -1
- data/lib/rollout_ui2.rb +56 -2
- data/lib/views/index.erb +40 -30
- data/lib/views/layout.erb +120 -19
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 64002c1fb49d0e15c4fec912f5960dd86b9af94d
|
4
|
+
data.tar.gz: 797c8dfcea7849943abd07c1ea72532ebfe7c94c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5c7249d7ad063ad68fc1ebda86a74eec6a5ea2c1ebf69f3043332ec131c82c31377f92d154450852da9acd22612f8d458dd7b2e8b02047eacefc0c92ec7693f0
|
7
|
+
data.tar.gz: da1213298d6d5d02ec7fd69e00092a44d4700053f15e025fd8d1fcec7bbe060ba1fe2a51bbb8e88296d4d73b685843dc16cb3bef71f06a1b4f9a84cc0c148a27
|
data/Rakefile
CHANGED
@@ -0,0 +1 @@
|
|
1
|
+
2.3.0
|
data/example_rack/Gemfile
CHANGED
data/example_rack/Gemfile.lock
CHANGED
@@ -1,28 +1,48 @@
|
|
1
1
|
PATH
|
2
2
|
remote: ..
|
3
3
|
specs:
|
4
|
-
rollout_ui2 (0.
|
4
|
+
rollout_ui2 (0.2.0)
|
5
5
|
sinatra (~> 1.4, >= 1.4.7)
|
6
6
|
|
7
7
|
GEM
|
8
8
|
remote: https://rubygems.org/
|
9
9
|
specs:
|
10
|
+
coderay (1.1.1)
|
11
|
+
ffi (1.9.14)
|
12
|
+
listen (3.1.5)
|
13
|
+
rb-fsevent (~> 0.9, >= 0.9.4)
|
14
|
+
rb-inotify (~> 0.9, >= 0.9.7)
|
15
|
+
ruby_dep (~> 1.2)
|
16
|
+
method_source (0.8.2)
|
17
|
+
pry (0.10.4)
|
18
|
+
coderay (~> 1.1.0)
|
19
|
+
method_source (~> 0.8.1)
|
20
|
+
slop (~> 3.4)
|
10
21
|
rack (1.6.5)
|
11
22
|
rack-protection (1.5.3)
|
12
23
|
rack
|
24
|
+
rb-fsevent (0.9.8)
|
25
|
+
rb-inotify (0.9.7)
|
26
|
+
ffi (>= 0.5.0)
|
13
27
|
redis (3.3.2)
|
28
|
+
rerun (0.11.0)
|
29
|
+
listen (~> 3.0)
|
14
30
|
rollout (2.4.0)
|
31
|
+
ruby_dep (1.5.0)
|
15
32
|
sinatra (1.4.7)
|
16
33
|
rack (~> 1.5)
|
17
34
|
rack-protection (~> 1.4)
|
18
35
|
tilt (>= 1.3, < 3)
|
36
|
+
slop (3.6.0)
|
19
37
|
tilt (2.0.5)
|
20
38
|
|
21
39
|
PLATFORMS
|
22
40
|
ruby
|
23
41
|
|
24
42
|
DEPENDENCIES
|
43
|
+
pry
|
25
44
|
redis
|
45
|
+
rerun
|
26
46
|
rollout (>= 2.0.0)
|
27
47
|
rollout_ui2!
|
28
48
|
|
data/example_rack/config.ru
CHANGED
@@ -1,7 +1,55 @@
|
|
1
|
+
require 'rollout'
|
1
2
|
require 'rollout_ui2'
|
2
|
-
|
3
3
|
require 'redis'
|
4
|
-
|
4
|
+
|
5
|
+
USERS = [ { id: 1,
|
6
|
+
text: "jimi.lepisto@example.com",
|
7
|
+
picture: "https://randomuser.me/api/portraits/thumb/men/21.jpg" },
|
8
|
+
{ id: 2,
|
9
|
+
text: "emilia.koskinen@example.com",
|
10
|
+
picture: "https://randomuser.me/api/portraits/thumb/women/61.jpg" },
|
11
|
+
{ id: 3,
|
12
|
+
text: "ron.perez@example.com",
|
13
|
+
picture: "https://randomuser.me/api/portraits/thumb/men/96.jpg" },
|
14
|
+
{ id: 4,
|
15
|
+
text: "tim.carpenter@example.com",
|
16
|
+
picture: "https://randomuser.me/api/portraits/thumb/men/79.jpg" },
|
17
|
+
{ id: 5,
|
18
|
+
text: "aatu.marttila@example.com",
|
19
|
+
picture: "https://randomuser.me/api/portraits/thumb/men/36.jpg" },
|
20
|
+
{ id: 6,
|
21
|
+
text: "طاها.نكونظر@example.com",
|
22
|
+
picture: "https://randomuser.me/api/portraits/thumb/men/86.jpg" },
|
23
|
+
{ id: 7,
|
24
|
+
text: "gabrielle.chu@example.com",
|
25
|
+
picture: "https://randomuser.me/api/portraits/thumb/women/40.jpg" },
|
26
|
+
{ id: 8,
|
27
|
+
text: "hans.philipp@example.com",
|
28
|
+
picture: "https://randomuser.me/api/portraits/thumb/men/49.jpg" },
|
29
|
+
{ id: 9,
|
30
|
+
text: "isabella.harris@example.com",
|
31
|
+
picture: "https://randomuser.me/api/portraits/thumb/women/32.jpg" },
|
32
|
+
{ id: 10,
|
33
|
+
text: "stacey.olson@example.com",
|
34
|
+
picture: "https://randomuser.me/api/portraits/thumb/women/3.jpg" } ]
|
35
|
+
|
36
|
+
class User
|
37
|
+
def self.find_by_id(ids)
|
38
|
+
USERS.select { |it| ids.include?(it[:id].to_s) }
|
39
|
+
end
|
40
|
+
|
41
|
+
def self.search(query, page)
|
42
|
+
result = USERS.select { |it| %r{#{query}} =~ it[:text] }
|
43
|
+
per_page = 3
|
44
|
+
{
|
45
|
+
results: result[(page-1) * per_page...page * per_page],
|
46
|
+
per_page: per_page,
|
47
|
+
total_count: result.count
|
48
|
+
}
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
RolloutUi2.wrap(Rollout.new(Redis.new)).with_finder(User)
|
5
53
|
|
6
54
|
RolloutUi2::Server.use Rack::Auth::Basic do |user, pass|
|
7
55
|
user == pass
|
data/lib/rollout_ui2/version.rb
CHANGED
data/lib/rollout_ui2.rb
CHANGED
@@ -4,8 +4,18 @@ require 'yaml'
|
|
4
4
|
|
5
5
|
module RolloutUi2
|
6
6
|
class << self
|
7
|
+
def with_finder(finder)
|
8
|
+
@finder = finder
|
9
|
+
self
|
10
|
+
end
|
11
|
+
|
12
|
+
def finder
|
13
|
+
@finder
|
14
|
+
end
|
15
|
+
|
7
16
|
def wrap(rollout)
|
8
17
|
@rollout = rollout
|
18
|
+
self
|
9
19
|
end
|
10
20
|
|
11
21
|
def store
|
@@ -39,6 +49,10 @@ module RolloutUi2
|
|
39
49
|
rollout.deactivate(feature.name)
|
40
50
|
end
|
41
51
|
|
52
|
+
def groups
|
53
|
+
|
54
|
+
end
|
55
|
+
|
42
56
|
private
|
43
57
|
|
44
58
|
def multi(keys)
|
@@ -73,8 +87,27 @@ module RolloutUi2
|
|
73
87
|
|
74
88
|
class Server < Sinatra::Base
|
75
89
|
helpers do
|
90
|
+
def active_for(feature, key, user)
|
91
|
+
return unless user && user != ""
|
92
|
+
case key
|
93
|
+
when :any
|
94
|
+
feature.active?(RolloutUi2.rollout, user)
|
95
|
+
when :percentage
|
96
|
+
feature.feature.send(:user_in_percentage?, user) rescue nil
|
97
|
+
when :user
|
98
|
+
feature.feature.send(:user_in_active_users?, user) rescue nil
|
99
|
+
when :group
|
100
|
+
feature.feature.send(:user_in_active_group?, user, RolloutUi2.rollout) rescue nil
|
101
|
+
end && yield || nil
|
102
|
+
end
|
103
|
+
|
104
|
+
def user
|
105
|
+
params[:user]
|
106
|
+
end
|
107
|
+
|
76
108
|
def all_groups(features)
|
77
|
-
|
109
|
+
defined_groups = RolloutUi2.rollout.instance_eval("@groups").keys rescue []
|
110
|
+
defined_groups | features.reduce([]) { |a, e| a | e.groups }
|
78
111
|
end
|
79
112
|
|
80
113
|
def as_array(param)
|
@@ -103,6 +136,27 @@ module RolloutUi2
|
|
103
136
|
return "eye-open" if public?(feature)
|
104
137
|
"filter"
|
105
138
|
end
|
139
|
+
|
140
|
+
def users_2_select2(users)
|
141
|
+
return users unless users_provided?
|
142
|
+
RolloutUi2
|
143
|
+
.finder
|
144
|
+
.find_by_id(Array(users))
|
145
|
+
.map { |it| it.merge!(selected: true, placeholder: it[:text]) }
|
146
|
+
.to_json
|
147
|
+
end
|
148
|
+
|
149
|
+
def users_provided?
|
150
|
+
!RolloutUi2.finder.nil?
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
get '/users' do
|
155
|
+
return status 404 unless users_provided?
|
156
|
+
RolloutUi2
|
157
|
+
.finder
|
158
|
+
.search(params["q"], (params["page"] || 1).to_i)
|
159
|
+
.to_json
|
106
160
|
end
|
107
161
|
|
108
162
|
get '/' do
|
@@ -127,7 +181,7 @@ module RolloutUi2
|
|
127
181
|
RolloutUi2.save(feature)
|
128
182
|
end
|
129
183
|
|
130
|
-
redirect to(
|
184
|
+
redirect to("#{request.path_info}?#{request.query_string}")
|
131
185
|
end
|
132
186
|
end
|
133
187
|
end
|
data/lib/views/index.erb
CHANGED
@@ -1,24 +1,22 @@
|
|
1
|
-
<div class="
|
2
|
-
<
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
</form>
|
11
|
-
</div>
|
1
|
+
<div class="jumbotron">
|
2
|
+
<label for="newfeature">New feature</label>
|
3
|
+
<form class="form-inline" method="post" action="<%= request.fullpath %>">
|
4
|
+
<div class="form-group form-group-sm">
|
5
|
+
<input type="hidden" name="action" value="new" >
|
6
|
+
<input type="text" name="name" placeholder="feature name" class="form-control" id="newfeature">
|
7
|
+
</div>
|
8
|
+
<button type="submit" class="btn btn-default btn-sm">Create</button>
|
9
|
+
</form>
|
12
10
|
</div>
|
13
11
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
12
|
+
<% @features.each_with_index do |feature, index| %>
|
13
|
+
<div class="row">
|
14
|
+
<div id="feature-<%= feature.name.to_s %>"
|
15
|
+
class="panel panel-default <%= active_for(feature, :any, user) { "panel-success" } %> <%= 'panel-success' if public?(feature) %>"
|
16
|
+
style="<%= 'opacity:0.5' if hidden?(feature) %>">
|
19
17
|
<div class="panel-heading">
|
20
18
|
<div >
|
21
|
-
<form class="form-inline pull-right" data-require-confirm="true" method="post">
|
19
|
+
<form class="form-inline pull-right" data-require-confirm="true" method="post" action="<%= request.fullpath %>">
|
22
20
|
<input type="hidden" name="action" value="delete" >
|
23
21
|
<input type="hidden" name="name" value="<%= feature.name.to_s %>" >
|
24
22
|
<button type="submit" class="glyphicon glyphicon-trash" style="background:none;border:none"><span class="sr-only">Delete</span></button>
|
@@ -33,10 +31,10 @@
|
|
33
31
|
<div class="panel-body" style="position:relative">
|
34
32
|
<div style="background:#F8F8F8;position:absolute;left:0;bottom:0px;height:8px;width:100%"></div>
|
35
33
|
<div style="background:#EEEEEE;position:absolute;left:0;bottom:0px;height:8px;width:<%= feature.percentage %>%"></div>
|
36
|
-
<form class="form-horizontal" method="post">
|
34
|
+
<form class="form-horizontal" method="post" action="<%= request.fullpath %>">
|
37
35
|
<input type="hidden" name="action" value="update" >
|
38
36
|
<input type="hidden" name="name" value="<%= feature.name.to_s %>" >
|
39
|
-
<div class="form-group form-group-sm">
|
37
|
+
<div class="form-group form-group-sm <%= active_for(feature, :percentage, user) { "has-success" } %>">
|
40
38
|
<label class="col-sm-2 control-label" for="percentage">Pecentage</label>
|
41
39
|
<div class="col-sm-2">
|
42
40
|
<div class="input-group">
|
@@ -46,10 +44,11 @@
|
|
46
44
|
</div>
|
47
45
|
</div>
|
48
46
|
|
49
|
-
<div class="form-group form-group-sm">
|
47
|
+
<div class="form-group form-group-sm <%= active_for(feature, :group, user) { "has-success" } %>">
|
50
48
|
<label class="col-sm-2 control-label" for="groups">Groups</label>
|
51
|
-
|
52
|
-
|
49
|
+
|
50
|
+
<div class="col-sm-10">
|
51
|
+
<select data-tags="true" style="height:5ex" class="form-control" data-role="select2" multiple="multiple" id="groups" name="groups[]">
|
53
52
|
<% (@groups - feature.groups).each do |f| %><option><%= f %></option><% end %>
|
54
53
|
<% feature.groups.each do |f| %><option selected=true><%= f %></option><% end %>
|
55
54
|
</select>
|
@@ -57,18 +56,29 @@
|
|
57
56
|
</div>
|
58
57
|
</div>
|
59
58
|
|
60
|
-
<div class="form-group form-group-sm">
|
59
|
+
<div class="form-group form-group-sm <%= active_for(feature, :user, user) { "has-success" } %>">
|
61
60
|
<label class="col-sm-2 control-label" for="users">Users</label>
|
62
|
-
<div class="col-sm-
|
63
|
-
|
64
|
-
|
65
|
-
|
61
|
+
<div class="col-sm-10">
|
62
|
+
<% if users_provided? %>
|
63
|
+
<select
|
64
|
+
data-tags="true"
|
65
|
+
class="form-control user-api"
|
66
|
+
multiple="multiple"
|
67
|
+
id="users"
|
68
|
+
name="users[]"
|
69
|
+
data-data='<%= users_2_select2(feature.users) %>'>
|
70
|
+
</select>
|
71
|
+
<% else %>
|
72
|
+
<select class="form-control" data-role="select2" multiple="multiple" id="users" name="users[]">
|
73
|
+
<% feature.users.each do |f| %><option selected=true><%= f %></option><% end %>
|
74
|
+
</select>
|
75
|
+
<% end %>
|
66
76
|
</div>
|
67
77
|
</div>
|
68
78
|
|
69
79
|
<% if feature.data? %>
|
70
80
|
<div class="form-group form-group-sm">
|
71
|
-
<div class="col-sm-offset-2 col-sm-
|
81
|
+
<div class="col-sm-offset-2 col-sm-10">
|
72
82
|
<pre><%= feature.data %></pre>
|
73
83
|
</div>
|
74
84
|
</div>
|
@@ -81,6 +91,6 @@
|
|
81
91
|
</div>
|
82
92
|
</form>
|
83
93
|
</div>
|
84
|
-
|
85
|
-
<% end %>
|
94
|
+
</div>
|
86
95
|
</div>
|
96
|
+
<% end %>
|
data/lib/views/layout.erb
CHANGED
@@ -7,43 +7,144 @@
|
|
7
7
|
<link href="<%= u "vendor/bootstrap/css/bootstrap.min.css" %>" rel="stylesheet">
|
8
8
|
<link href="<%= u "vendor/select2/css/select2.min.css" %>" rel="stylesheet">
|
9
9
|
<link href="<%= u "vendor/bootstrap/css/bootstrap-theme.css" %>" rel="stylesheet">
|
10
|
+
<link href="https://fk.github.io/select2-bootstrap-css/css/select2-bootstrap.css" rel="stylesheet">
|
11
|
+
<style>
|
12
|
+
.main {
|
13
|
+
margin: auto;
|
14
|
+
max-width: 980px;
|
15
|
+
max-width: 750px;
|
16
|
+
}
|
17
|
+
/* pull-right on all except xs devices */
|
18
|
+
@media (min-width: 768px) {
|
19
|
+
.pull-right-sm {
|
20
|
+
float: right;
|
21
|
+
}
|
22
|
+
}
|
23
|
+
|
24
|
+
/*Make select2 responsive*/
|
25
|
+
[class*="col-"] .select2-container, .select2-container{
|
26
|
+
width:100%!important;
|
27
|
+
}
|
28
|
+
[class*="col-"] .select2-container .select2-search input[type="text"],
|
29
|
+
{
|
30
|
+
padding:2px 4%!important;
|
31
|
+
width:90%!important;
|
32
|
+
margin:5px 2%;
|
33
|
+
}
|
34
|
+
[class*="col-"] .select2-container .select2-drop {
|
35
|
+
width: 100%!important;
|
36
|
+
}
|
37
|
+
|
38
|
+
.has-success .select2-selection__choice,
|
39
|
+
.has-success .select2-selection__choice__remove {
|
40
|
+
color: #3c763d !important;
|
41
|
+
background-color: #dff0d8 !important;
|
42
|
+
border-color: #3c763d !important;
|
43
|
+
}
|
44
|
+
|
45
|
+
.select2-selection__rendered img {
|
46
|
+
width: 2.5ex !important;
|
47
|
+
}
|
48
|
+
|
49
|
+
.select2-selection--single, .select2-selection__arrow {
|
50
|
+
height: 34px !important;
|
51
|
+
padding: 2px;
|
52
|
+
}
|
53
|
+
|
54
|
+
.select2-selection__clear {
|
55
|
+
position: absolute;
|
56
|
+
z-index: 200
|
57
|
+
}
|
58
|
+
|
59
|
+
</style>
|
10
60
|
</head>
|
11
61
|
<body>
|
12
|
-
<
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
<
|
62
|
+
<nav class="navbar navbar-default">
|
63
|
+
<div class="container">
|
64
|
+
<div class="row">
|
65
|
+
<div class="navbar-header"><a class="navbar-brand" href="/">RolloutUi2</a></div>
|
66
|
+
<form method="get">
|
67
|
+
<div class="col-sm-6 col-sm-offset-4" style="top:7px">
|
68
|
+
<div class="form-group">
|
69
|
+
<div class="input-group select2-bootstrap-append">
|
70
|
+
<% if users_provided? %>
|
71
|
+
<select
|
72
|
+
data-tags="true"
|
73
|
+
class="form-control user-api"
|
74
|
+
id="user"
|
75
|
+
name="user"
|
76
|
+
data-allow-clear="true"
|
77
|
+
data-placeholder="Select a user"
|
78
|
+
data-data='<%= users_2_select2(params["user"]) %>'>
|
79
|
+
<option></option>
|
80
|
+
</select>
|
81
|
+
<% else %>
|
82
|
+
<input type="text" class="form-control" name="user" value="<%= params[:user] %>" placeholder="Select a user">
|
83
|
+
<% end %>
|
84
|
+
<span class="input-group-btn">
|
85
|
+
<button class="btn btn-default" type="submit" data-select2-open="multi-append">
|
86
|
+
<span class="glyphicon glyphicon-user"></span>
|
87
|
+
</button>
|
88
|
+
</span>
|
89
|
+
</div>
|
90
|
+
</div>
|
91
|
+
</div>
|
92
|
+
</form>
|
17
93
|
</div>
|
18
|
-
</
|
19
|
-
|
94
|
+
</div><!-- /.container-fluid -->
|
95
|
+
</nav>
|
96
|
+
<main class="container main">
|
20
97
|
<div>
|
21
|
-
<%if @error then %>
|
22
|
-
<div class="alert alert-error"><%=@error%></div>
|
23
|
-
<% end %>
|
98
|
+
<%if @error then %><div class="alert alert-error"><%=@error%></div><% end %>
|
24
99
|
<%= yield %>
|
25
100
|
</div>
|
26
|
-
|
101
|
+
</main>
|
27
102
|
<script src="<%= u "vendor/jquery-1.9.1.min.js" %>"></script>
|
28
103
|
<script src="<%= u "vendor/bootstrap/js/bootstrap.min.js" %>"></script>
|
29
|
-
<script src="<%= u "vendor/select2/js/select2.
|
104
|
+
<script src="<%= u "vendor/select2/js/select2.js" %>"></script>
|
30
105
|
<script src="<%= u "vendor/jq-debounce.min.js" %>"></script>
|
31
106
|
<script type="text/javascript">
|
107
|
+
$('[data-role="select2"]').select2({tokenSeparators: [',', ' ']})
|
32
108
|
|
109
|
+
function template(item) {
|
110
|
+
if (!item.text) return null;
|
111
|
+
if (!item.picture) return '' + item.text;
|
112
|
+
return "<span><img src=\"" + item.picture + "\"> " + item.text + "</span>";
|
113
|
+
}
|
33
114
|
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
115
|
+
$("select.user-api").select2({
|
116
|
+
ajax: {
|
117
|
+
url: "<%= u 'users' %>",
|
118
|
+
dataType: 'json',
|
119
|
+
delay: 250,
|
120
|
+
data: function (params) {
|
121
|
+
return { q: params.term, page: params.page };
|
122
|
+
},
|
123
|
+
processResults: function (data, params) {
|
124
|
+
params.page = params.page || 1;
|
125
|
+
return {
|
126
|
+
results: data.results,
|
127
|
+
pagination: { more: (params.page * data.per_page) < data.total_count }
|
128
|
+
};
|
129
|
+
},
|
130
|
+
cache: true
|
131
|
+
},
|
132
|
+
escapeMarkup: function (markup) { return markup; },
|
133
|
+
minimumInputLength: 1,
|
134
|
+
templateResult: template,
|
135
|
+
templateSelection: template
|
136
|
+
});
|
39
137
|
|
40
138
|
$('[data-require-confirm="true"]').submit(function() {
|
41
139
|
return confirm("Are you sure?");
|
42
140
|
});
|
43
141
|
|
44
|
-
|
45
|
-
|
142
|
+
|
143
|
+
$(".js-example-placeholder-single").select2({
|
144
|
+
placeholder: "Select a state",
|
145
|
+
allowClear: true
|
46
146
|
});
|
147
|
+
|
47
148
|
</script>
|
48
149
|
|
49
150
|
</body>
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rollout_ui2
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Manuel
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-12-
|
11
|
+
date: 2016-12-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -103,6 +103,7 @@ files:
|
|
103
103
|
- bin/console
|
104
104
|
- bin/setup
|
105
105
|
- example_rack/.bundle/config
|
106
|
+
- example_rack/.ruby-version
|
106
107
|
- example_rack/Gemfile
|
107
108
|
- example_rack/Gemfile.lock
|
108
109
|
- example_rack/config.ru
|
@@ -160,3 +161,4 @@ signing_key:
|
|
160
161
|
specification_version: 4
|
161
162
|
summary: WebUI for rollout 2
|
162
163
|
test_files: []
|
164
|
+
has_rdoc:
|