boilerman 0.0.4 → 0.1.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/app/assets/javascripts/boilerman/actions_controller.js +132 -0
- data/app/assets/stylesheets/boilerman/actions_controller.css +4 -0
- data/app/assets/stylesheets/boilerman/application.scss +4 -0
- data/app/controllers/boilerman/actions_controller.rb +34 -0
- data/app/controllers/boilerman/controllers_controller.rb +2 -2
- data/app/helpers/boilerman/actions_controller_helper.rb +4 -0
- data/app/views/boilerman/actions/_controller_filter.html.erb +30 -0
- data/app/views/boilerman/actions/_filters_filter.html.erb +54 -0
- data/app/views/boilerman/actions/index.html.erb +65 -0
- data/app/views/boilerman/controllers/_action_filter.html.erb +4 -4
- data/app/views/boilerman/controllers/_application_statistics_panel.html.erb +0 -5
- data/app/views/boilerman/controllers/index.html.erb +3 -3
- data/app/views/layouts/boilerman/application.html.erb +2 -1
- data/config/routes.rb +3 -3
- data/lib/boilerman.rb +1 -0
- data/lib/boilerman/actions.rb +272 -0
- data/lib/boilerman/engine.rb +9 -3
- data/lib/boilerman/version.rb +1 -1
- data/test/controllers/boilerman/actions_controller_controller_test.rb +13 -0
- metadata +12 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fed72c928bb0ed06e91813300d052c45431f5e99
|
4
|
+
data.tar.gz: e92359b7ff8f41937bdbb6c7db273c7121cba0dc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8d9f3d412f02dc5c1251f31cf76de74f7331fee01f5756f8c4f150e566a02ab0ead9cca3caae41afe6f427612b26211f2b54a4ec14416e32233f019f40557eea
|
7
|
+
data.tar.gz: a29a8dc2b797967740560e14a0862fae8badb089f74c4476ae29b3af71b19c5cbd8eb9407ad72cf8b12c7059dac9fc2cc462c2696318016ed86656209daed437
|
@@ -0,0 +1,132 @@
|
|
1
|
+
// Place all the behaviors and hooks related to the matching controller here.
|
2
|
+
// All this logic will automatically be available in application.js.
|
3
|
+
|
4
|
+
$( document ).ready(function() {
|
5
|
+
// Initialize global variables
|
6
|
+
window.controller_filters = [];
|
7
|
+
|
8
|
+
// When the enter key is pressed on the filter input boxes, trigger the
|
9
|
+
// onclick event for that text box
|
10
|
+
$("#controller_filter_input").keyup(function(event){
|
11
|
+
if(event.keyCode == 13){
|
12
|
+
$("#controller_filter_input_btn").click();
|
13
|
+
}
|
14
|
+
});
|
15
|
+
|
16
|
+
$("#with_filter_input").keyup(function(event){
|
17
|
+
if(event.keyCode == 13){
|
18
|
+
$("#action_with_filter_input_btn").click();
|
19
|
+
}
|
20
|
+
});
|
21
|
+
|
22
|
+
$("#without_filter_input").keyup(function(event){
|
23
|
+
if(event.keyCode == 13){
|
24
|
+
$("#action_without_filter_input_btn").click();
|
25
|
+
}
|
26
|
+
});
|
27
|
+
});
|
28
|
+
|
29
|
+
function send_with_filter() {
|
30
|
+
var filter_input = $("#with_filter_input")[0];
|
31
|
+
|
32
|
+
// we should only apply new query string if there is actual input
|
33
|
+
if (filter_input.value.length) {
|
34
|
+
// decide which seperator we want depending on if there is a current query string
|
35
|
+
var seperator = window.location.search ? "&" : "?";
|
36
|
+
|
37
|
+
// Get current URL
|
38
|
+
var href = window.location.href;
|
39
|
+
// append new query
|
40
|
+
new_link = href + seperator + "filters[with_filters][]=" + filter_input.value;
|
41
|
+
|
42
|
+
window.location = new_link;
|
43
|
+
} else {
|
44
|
+
alert("You did not specify a filter to apply");
|
45
|
+
}
|
46
|
+
}
|
47
|
+
|
48
|
+
|
49
|
+
function send_controller_filter() {
|
50
|
+
var filter_input = $("#controller_filter_input")[0];
|
51
|
+
|
52
|
+
// we should only apply new query string if there is actual input
|
53
|
+
if (filter_input.value.length) {
|
54
|
+
// decide which seperator we want depending on if there is a current query string
|
55
|
+
var seperator = window.location.search ? "&" : "?";
|
56
|
+
|
57
|
+
// Get current URL
|
58
|
+
var href = window.location.href;
|
59
|
+
// append new query
|
60
|
+
new_link = href + seperator + "filters[controller_filters][]=" + filter_input.value;
|
61
|
+
|
62
|
+
window.location = new_link;
|
63
|
+
} else {
|
64
|
+
alert("You did not specify a filter to apply");
|
65
|
+
}
|
66
|
+
}
|
67
|
+
|
68
|
+
|
69
|
+
function send_without_filter() {
|
70
|
+
var filter_input = $("#without_filter_input")[0];
|
71
|
+
|
72
|
+
// we should only apply new query string if there is actual input
|
73
|
+
if (filter_input.value.length) {
|
74
|
+
// decide which seperator we want depending on if there is a current query string
|
75
|
+
var seperator = window.location.search ? "&" : "?";
|
76
|
+
|
77
|
+
// Get current URL
|
78
|
+
var href = window.location.href;
|
79
|
+
// append new query
|
80
|
+
new_link = href + seperator + "filters[without_filters][]=" + filter_input.value;
|
81
|
+
|
82
|
+
window.location = new_link;
|
83
|
+
} else {
|
84
|
+
alert("You did not specify a filter to apply");
|
85
|
+
}
|
86
|
+
}
|
87
|
+
|
88
|
+
function remove_with_filter(list_item) {
|
89
|
+
var filter_text = list_item.text.trim();
|
90
|
+
var original_query = window.location.search;
|
91
|
+
|
92
|
+
console.log(filter_text);
|
93
|
+
var question_regex = new RegExp("\\?filters\\[with_filters\\]\\[\\]=" + filter_text + "&*");
|
94
|
+
var ampersand_regex = new RegExp("&filters\\[with_filters\\]\\[\\]=" + filter_text);
|
95
|
+
|
96
|
+
var query = "";
|
97
|
+
if (question_regex.test(original_query)) {
|
98
|
+
console.log("we've got a question mark");
|
99
|
+
query = original_query.replace(question_regex, '?');
|
100
|
+
|
101
|
+
} else if (ampersand_regex.test(original_query)) {
|
102
|
+
console.log("we've got an ampersand mark");
|
103
|
+
query = original_query.replace(ampersand_regex, '');
|
104
|
+
}
|
105
|
+
|
106
|
+
// reload page with new query string
|
107
|
+
window.location = window.location.href.split('?')[0] + query;
|
108
|
+
}
|
109
|
+
|
110
|
+
function remove_without_filter(list_item) {
|
111
|
+
console.log("remove_without_filter");
|
112
|
+
var filter_text = list_item.text.trim();
|
113
|
+
var original_query = window.location.search;
|
114
|
+
|
115
|
+
console.log(filter_text);
|
116
|
+
var question_regex = new RegExp("\\?filters\\[without_filters\\]\\[\\]=" + filter_text + "&*");
|
117
|
+
var ampersand_regex = new RegExp("&filters\\[without_filters\\]\\[\\]=" + filter_text);
|
118
|
+
|
119
|
+
var query = "";
|
120
|
+
if (question_regex.test(original_query)) {
|
121
|
+
console.log("we've got a question mark");
|
122
|
+
query = original_query.replace(question_regex, '?');
|
123
|
+
|
124
|
+
} else if (ampersand_regex.test(original_query)) {
|
125
|
+
console.log("we've got an ampersand mark");
|
126
|
+
query = original_query.replace(ampersand_regex, '');
|
127
|
+
}
|
128
|
+
|
129
|
+
console.log(query);
|
130
|
+
// reload page with new query string
|
131
|
+
window.location = window.location.href.split('?')[0] + query;
|
132
|
+
}
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require_dependency "boilerman/application_controller"
|
2
|
+
|
3
|
+
module Boilerman
|
4
|
+
class ActionsController < ApplicationController
|
5
|
+
def index
|
6
|
+
default_filters = { controller_filters: [], # XXX Implemented
|
7
|
+
with_actions: [],
|
8
|
+
without_actions: [],
|
9
|
+
with_filters: [], # XXX Implemented
|
10
|
+
without_filters: [], # XXX Implemented
|
11
|
+
ignore_filters: [], # XXX Implemented
|
12
|
+
ignore_actions: [] } # XXX Implemented
|
13
|
+
|
14
|
+
if params[:filters]
|
15
|
+
filters = params[:filters].reverse_merge(default_filters)
|
16
|
+
else
|
17
|
+
filters = default_filters
|
18
|
+
end
|
19
|
+
|
20
|
+
@controller_filters = filters[:controller_filters]
|
21
|
+
|
22
|
+
@with_actions = filters[:with_actions]
|
23
|
+
@without_actions = filters[:without_actions]
|
24
|
+
|
25
|
+
@with_filters = filters[:with_filters] || []
|
26
|
+
@without_filters = filters[:without_filters]
|
27
|
+
|
28
|
+
@ignore_filters = filters[:ignore_filters]
|
29
|
+
@ignore_actions = filters[:ignore_actions]
|
30
|
+
|
31
|
+
@action_filter_hash = Boilerman::Actions.get_action_hash(filters)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
<h4>Controllers</h4>
|
2
|
+
|
3
|
+
<div class="row">
|
4
|
+
<div class="col-lg-6">
|
5
|
+
<div class="input-group">
|
6
|
+
<span class="input-group-btn">
|
7
|
+
<button id="controller_filter_input_btn" onclick="send_controller_filter()" class="btn btn-success" type="button">
|
8
|
+
<span class="glyphicon glyphicon-plus" aria-hidden="true"></span>
|
9
|
+
Include
|
10
|
+
</button>
|
11
|
+
</span>
|
12
|
+
<input id="controller_filter_input" type="text" class="form-control" placeholder="Filters by controller name...">
|
13
|
+
</div><!-- /input-group -->
|
14
|
+
</div><!-- /.col-lg-6 -->
|
15
|
+
|
16
|
+
<div class="col-lg-6">
|
17
|
+
<ul class="list-group" id="include-controllers">
|
18
|
+
<% if @controller_filters.empty? %>
|
19
|
+
<li class="list-group-item">No controller filters currently set</li>
|
20
|
+
<% else %>
|
21
|
+
<% @controller_filters.each do |controller_filter| %>
|
22
|
+
<a href="#" onclick="removeController(this)" class="list-group-item">
|
23
|
+
<%= controller_filter %>
|
24
|
+
<span class="glyphicon glyphicon-remove pull-right list-group-span" aria-hidden="true"></span>
|
25
|
+
</a>
|
26
|
+
<% end %>
|
27
|
+
<% end %>
|
28
|
+
</ul>
|
29
|
+
</div><!-- /.col-lg-6 -->
|
30
|
+
</div><!-- /.row -->
|
@@ -0,0 +1,54 @@
|
|
1
|
+
<h4>Filters</h4>
|
2
|
+
|
3
|
+
<div class="row">
|
4
|
+
<div class="col-lg-6">
|
5
|
+
<div class="input-group">
|
6
|
+
<span class="input-group-btn">
|
7
|
+
<button id="with_filter_input_btn" class="btn btn-success" type="button" onclick="send_with_filter()">
|
8
|
+
<span class="glyphicon glyphicon-plus" aria-hidden="true"></span>
|
9
|
+
With
|
10
|
+
</button>
|
11
|
+
</span>
|
12
|
+
<input id="with_filter_input" type="text" class="form-control" placeholder="(e.g. require_admin)" >
|
13
|
+
</div><!-- /input-group -->
|
14
|
+
|
15
|
+
<ul class="list-group top-buffer" id="with-filters">
|
16
|
+
<% if @with_filters.empty? %>
|
17
|
+
<li class="list-group-item">No with filters currently set</li>
|
18
|
+
<% else %>
|
19
|
+
<% @with_filters.each do |with_filter| %>
|
20
|
+
<a href="#" onclick="remove_with_filter(this)" class="list-group-item">
|
21
|
+
<%= with_filter %>
|
22
|
+
<span class="glyphicon glyphicon-remove pull-right list-group-span" aria-hidden="true"></span>
|
23
|
+
</a>
|
24
|
+
<% end %>
|
25
|
+
<% end %>
|
26
|
+
</ul>
|
27
|
+
|
28
|
+
</div><!-- /.col-lg-6 -->
|
29
|
+
<div class="col-lg-6">
|
30
|
+
<div class="input-group">
|
31
|
+
<span class="input-group-btn">
|
32
|
+
<button id="without_filter_input_btn" class="btn btn-danger" type="button" onclick="send_without_filter()">
|
33
|
+
<span class="glyphicon glyphicon-minus" aria-hidden="true"></span>
|
34
|
+
Without
|
35
|
+
</button>
|
36
|
+
</span>
|
37
|
+
<input id="without_filter_input" type="text" class="form-control" placeholder="(e.g. verify_authenticity_token)">
|
38
|
+
</div><!-- /input-group -->
|
39
|
+
|
40
|
+
<ul class="list-group top-buffer" id="without-filters">
|
41
|
+
<% if @without_filters.empty? %>
|
42
|
+
<li class="list-group-item">No without filters currently set</li>
|
43
|
+
<% else %>
|
44
|
+
<% @without_filters.each do |without_filter| %>
|
45
|
+
<a href="#" onclick="remove_without_filter(this)" class="list-group-item">
|
46
|
+
<%= without_filter %>
|
47
|
+
<span class="glyphicon glyphicon-remove pull-right list-group-span" aria-hidden="true"></span>
|
48
|
+
</a>
|
49
|
+
<% end %>
|
50
|
+
<% end %>
|
51
|
+
</ul>
|
52
|
+
</div><!-- /.col-lg-6 -->
|
53
|
+
</div><!-- /.row -->
|
54
|
+
|
@@ -0,0 +1,65 @@
|
|
1
|
+
<div class="row">
|
2
|
+
<div class="panel panel-primary">
|
3
|
+
<div class="panel-heading" data-toggle="collapse" data-target="#filter_panel" aria-expanded="true" >
|
4
|
+
<h3 class="panel-title">Filter</h3>
|
5
|
+
</div>
|
6
|
+
<div class="panel-body" id="filter_panel">
|
7
|
+
|
8
|
+
<%= render "controller_filter" %>
|
9
|
+
<%= render "filters_filter" %>
|
10
|
+
|
11
|
+
<button onclick="clearLocalFilters()" class="btn btn-warning pull-right">Clear Filters</button>
|
12
|
+
</div>
|
13
|
+
</div>
|
14
|
+
|
15
|
+
</div>
|
16
|
+
|
17
|
+
|
18
|
+
<div class="row">
|
19
|
+
<table id="controller_action_table" class="table table-bordered table-condensed">
|
20
|
+
<thead>
|
21
|
+
<th>Controller</th>
|
22
|
+
<th>Actions</th>
|
23
|
+
<th>Filters</th>
|
24
|
+
</thead>
|
25
|
+
<tbody>
|
26
|
+
<% @action_filter_hash.each do |controller, actions| %>
|
27
|
+
<tr>
|
28
|
+
|
29
|
+
<% filter_count = actions.map{|_, filters| filters.empty? ? 1 : filters}.flatten.count %>
|
30
|
+
|
31
|
+
<td rowspan="<%= filter_count %>"><%= controller %></td>
|
32
|
+
<% actions.each_with_index do |(action, filters),index| %>
|
33
|
+
|
34
|
+
<% if index == 0 %>
|
35
|
+
<td rowspan="<%= filters.count %>"><%= action %></td>
|
36
|
+
<% filters.each_with_index do |filter, index| %>
|
37
|
+
<% if index == 0 %>
|
38
|
+
<td colspan="1"><%= filter %></td>
|
39
|
+
<% else %>
|
40
|
+
<tr>
|
41
|
+
<td colspan="1"><%= filter %></td>
|
42
|
+
</tr>
|
43
|
+
<% end %>
|
44
|
+
<% end %>
|
45
|
+
<% else %>
|
46
|
+
<tr colspan="2">
|
47
|
+
<td rowspan="<%= filters.count %>"><%= action %></td>
|
48
|
+
|
49
|
+
<% filters.each_with_index do |filter, index| %>
|
50
|
+
<% if index == 0 %>
|
51
|
+
<td colspan="1"><%= filter %></td>
|
52
|
+
<% else %>
|
53
|
+
<tr>
|
54
|
+
<td colspan="1"><%= filter %></td>
|
55
|
+
</tr>
|
56
|
+
<% end %>
|
57
|
+
<% end %>
|
58
|
+
</tr>
|
59
|
+
<% end %>
|
60
|
+
<% end %>
|
61
|
+
</tr>
|
62
|
+
<% end %>
|
63
|
+
</tbody>
|
64
|
+
</table>
|
65
|
+
</div>
|
@@ -13,10 +13,10 @@
|
|
13
13
|
</div><!-- /input-group -->
|
14
14
|
|
15
15
|
<ul class="list-group top-buffer" id="with-actions">
|
16
|
-
<% if @
|
16
|
+
<% if @with_actions.empty? %>
|
17
17
|
<li class="list-group-item">No action filters currently set</li>
|
18
18
|
<% else %>
|
19
|
-
<% @
|
19
|
+
<% @with_actions.each do |action_filter| %>
|
20
20
|
<a href="#" onclick="removeWithActionItem()" class="list-group-item">
|
21
21
|
<%= action_filter %>
|
22
22
|
<span class="glyphicon glyphicon-remove pull-right list-group-span" aria-hidden="true"></span>
|
@@ -38,10 +38,10 @@
|
|
38
38
|
</div><!-- /input-group -->
|
39
39
|
|
40
40
|
<ul class="list-group top-buffer" id="without-actions">
|
41
|
-
<% if @
|
41
|
+
<% if @without_actions.empty? %>
|
42
42
|
<li class="list-group-item">No action filters currently set</li>
|
43
43
|
<% else %>
|
44
|
-
<% @
|
44
|
+
<% @without_actions.each do |action_filter| %>
|
45
45
|
<a href="#" onclick="removeWithoutActionItem()" class="list-group-item">
|
46
46
|
<%= action_filter %>
|
47
47
|
<span class="glyphicon glyphicon-remove pull-right list-group-span" aria-hidden="true"></span>
|
@@ -1,9 +1,9 @@
|
|
1
1
|
<div class="row">
|
2
|
-
<div class="panel panel-primary">
|
3
|
-
<div class="panel-heading">
|
2
|
+
<div class="panel panel-primary" >
|
3
|
+
<div class="panel-heading" data-toggle="collapse" data-target="#filter_panel">
|
4
4
|
<h3 class="panel-title">Filter</h3>
|
5
5
|
</div>
|
6
|
-
<div class="panel-body">
|
6
|
+
<div class="panel-body" id="filter_panel">
|
7
7
|
|
8
8
|
<%= render "controller_filter" %>
|
9
9
|
<%= render "action_filter" %>
|
@@ -13,7 +13,8 @@
|
|
13
13
|
<%= link_to "Boilerman", '#', id: "logo" %>
|
14
14
|
<nav>
|
15
15
|
<ul class="nav navbar-nav navbar-right">
|
16
|
-
<li><%= link_to "
|
16
|
+
<li><%= link_to "Actions", actions_path %></li>
|
17
|
+
<li><%= link_to "Controllers", controllers_path %></li>
|
17
18
|
<li><%= link_to "Checks", '#' %></li>
|
18
19
|
</ul>
|
19
20
|
</nav>
|
data/config/routes.rb
CHANGED
data/lib/boilerman.rb
CHANGED
@@ -0,0 +1,272 @@
|
|
1
|
+
module Boilerman
|
2
|
+
module Actions
|
3
|
+
METADATA_KEYS = [:_non_existant_route,
|
4
|
+
:_method_conditionals,
|
5
|
+
:_proc_conditionals,
|
6
|
+
:_weird_controller]
|
7
|
+
|
8
|
+
|
9
|
+
def self.get_action_hash(filters={})
|
10
|
+
controller_filters = filters[:controller_filters] || []
|
11
|
+
|
12
|
+
with_actions = filters[:with_actions] || []
|
13
|
+
without_actions = filters[:without_actions] || []
|
14
|
+
|
15
|
+
with_filters = filters[:with_filters] || []
|
16
|
+
without_filters = filters[:without_filters] || []
|
17
|
+
|
18
|
+
ignore_filters = filters[:ignore_filters] || []
|
19
|
+
ignore_actions = filters[:ignore_actions] || []
|
20
|
+
|
21
|
+
# Biggie Smalls... Biggie Smalls... Biggie Smalls....
|
22
|
+
routes = Rails.application.routes.routes.routes.select do |route|
|
23
|
+
# Select routes that point to a specific controller and action. Also
|
24
|
+
# ignore routes that just redirect
|
25
|
+
route.defaults.key?(:controller) &&
|
26
|
+
!route.defaults.empty? &&
|
27
|
+
route.app.class != ActionDispatch::Routing::Redirect
|
28
|
+
end
|
29
|
+
|
30
|
+
# We only care about the defaults which will give us an array of
|
31
|
+
# controller/action hashes. We're also going to rearrange things a bit so
|
32
|
+
# that the controller is the key and the value is another hash that
|
33
|
+
# represent each action and it's corresponding filters. This will look
|
34
|
+
# like:
|
35
|
+
#
|
36
|
+
# {:controler_name1 => {"action1" => [filter1, filter2, ... , filterN]}}
|
37
|
+
controller_action_hash = build_controller_action_list(routes)
|
38
|
+
|
39
|
+
filter_list = build_filter_list(controller_action_hash)
|
40
|
+
|
41
|
+
# controller_filters
|
42
|
+
unless controller_filters.empty?
|
43
|
+
filter_list.select! do |controller, _|
|
44
|
+
METADATA_KEYS.include?(controller) || include_controller?(controller_filters, controller.to_s)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
# ignore_actions
|
49
|
+
unless ignore_actions.empty?
|
50
|
+
filter_list = filter_list.inject(Hash.new) do |new_results, (controller, actions)|
|
51
|
+
new_results[controller] = actions.reject{|action, filter| ignore_actions.include?(action) }
|
52
|
+
new_results
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
# ignore_filters
|
57
|
+
unless ignore_filters.empty?
|
58
|
+
filter_list = filter_list.inject(Hash.new) do |new_results, (controller, actions)|
|
59
|
+
# FIXME Is this idiomatic Ruby code? Feels a bit icky to me.
|
60
|
+
# Mapping over a hash turns it into a 2D array so we need to
|
61
|
+
# turn it back into a hash using the Hash[] syntax.
|
62
|
+
new_results[controller] = Hash[actions.map do |action, filters|
|
63
|
+
[action, filters.reject{|filter| ignore_filters.include?(filter.to_s)}]
|
64
|
+
end]
|
65
|
+
new_results
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
# without_filters
|
70
|
+
unless without_filters.empty?
|
71
|
+
filter_list = filter_list.inject(Hash.new) do |new_results, (controller, actions)|
|
72
|
+
new_results[controller] = actions.select{|action, filters| (without_filters & filters).empty? }
|
73
|
+
new_results
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
# with_filters
|
78
|
+
unless with_filters.empty?
|
79
|
+
filter_list = filter_list.inject(Hash.new) do |new_results, (controller, actions)|
|
80
|
+
new_results[controller] = actions.select{|action, filters| (with_filters - filters).empty? }
|
81
|
+
new_results
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
filter_list
|
86
|
+
|
87
|
+
#if !with_actions.empty? && !without_actions.empty?
|
88
|
+
## This means that both with_actions AND without_actions were specified
|
89
|
+
#next route_hash if without_actions.include?(defaults[:action])
|
90
|
+
#next route_hash if !with_actions.include?(defaults[:action])
|
91
|
+
#elsif with_actions.empty?
|
92
|
+
## This means that just without_actions filtering was specified
|
93
|
+
#next route_hash if without_actions.include?(defaults[:action])
|
94
|
+
#elsif without_actions.empty?
|
95
|
+
## This means that just with_action filtering was specified
|
96
|
+
#next route_hash if !with_actions.include?(defaults[:action])
|
97
|
+
#end
|
98
|
+
end
|
99
|
+
|
100
|
+
private
|
101
|
+
|
102
|
+
# Returns an array of strings as controller actions
|
103
|
+
def self.actions_from_conditional(conditionals)
|
104
|
+
unless conditionals.empty?
|
105
|
+
conditionals.map do |conditional|
|
106
|
+
conditional.scan(/'(.+?)'/).flatten
|
107
|
+
end.flatten
|
108
|
+
else
|
109
|
+
return
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
# Only skip and call next if the controller_filters list isn't empty
|
114
|
+
# AND the controller we're looking at is NOT in the filters.
|
115
|
+
def self.include_controller?(filters, controller)
|
116
|
+
return true if filters.empty?
|
117
|
+
|
118
|
+
filters.each do |filter|
|
119
|
+
# check if the provided filter is a substring of the controller
|
120
|
+
return true if controller.downcase.include?(filter.downcase)
|
121
|
+
end
|
122
|
+
|
123
|
+
return false
|
124
|
+
end
|
125
|
+
|
126
|
+
def self.build_controller_action_list(routes)
|
127
|
+
routes.inject(Hash.new) do |route_hash, route|
|
128
|
+
defaults = route.defaults
|
129
|
+
|
130
|
+
begin
|
131
|
+
# This is what Rails does to get from a String to an object we can
|
132
|
+
# call methods on. Note that a NameError will get thrown if the class
|
133
|
+
# doesn't exist in the app.
|
134
|
+
#
|
135
|
+
# See actionpack/lib/action_dispatch/routing/route_set.rb:67
|
136
|
+
#
|
137
|
+
# Progression goes something like this:
|
138
|
+
# bank_accounts => BankAccounts => BankAccountsController
|
139
|
+
controller = ActiveSupport::Dependencies.constantize("#{ defaults[:controller].camelize }Controller")
|
140
|
+
rescue NameError
|
141
|
+
# This error will get thrown if there is a route in config/routes.rb
|
142
|
+
# that points to a controller that doesn't actually exist.
|
143
|
+
|
144
|
+
route_hash[:_non_existant_route] ||= []
|
145
|
+
# Keep a record of this in the form of "BankAccountsController#index"
|
146
|
+
# so we can notify the user
|
147
|
+
route_hash[:_non_existant_route] << "#{ defaults[:controller].camelize }Controller##{ defaults[:action] }"
|
148
|
+
|
149
|
+
next route_hash # On to the next route since we don't have a controller to process
|
150
|
+
end
|
151
|
+
|
152
|
+
route_hash[controller] ||= []
|
153
|
+
|
154
|
+
|
155
|
+
# we don't want duplicate actions in our array (this happens for PUT/PATCH routes
|
156
|
+
route_hash[controller] << defaults[:action] unless route_hash[controller].include? defaults[:action]
|
157
|
+
route_hash
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
def self.build_filter_list(controller_action_hash)
|
162
|
+
|
163
|
+
controller_action_filter_hash = {}
|
164
|
+
|
165
|
+
# Initialize the return hash
|
166
|
+
controller_action_hash.each do |controller, actions|
|
167
|
+
controller_action_filter_hash[controller] = {}
|
168
|
+
|
169
|
+
# With our controller_action_filter_hash being a nested hash, we want
|
170
|
+
# to initialize each action hash with an empty array so we can use <<
|
171
|
+
# in the upcoming code.
|
172
|
+
actions.each do |action|
|
173
|
+
controller_action_filter_hash[controller][action] = []
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
177
|
+
# Initialize metadata keys.
|
178
|
+
#
|
179
|
+
# _proc_conditionals: keeps track of filters that call Procs to
|
180
|
+
# decide whether or not a filter will be applied to an action.
|
181
|
+
#
|
182
|
+
# _method_conditionals: keeps track of filters that call methods within
|
183
|
+
# the controller to decide whether or not a filter will be applied to an
|
184
|
+
# action.
|
185
|
+
controller_action_filter_hash[:_proc_conditionals] = {}
|
186
|
+
controller_action_filter_hash[:_method_conditionals] = {}
|
187
|
+
|
188
|
+
# All right, now we have a mapping of routable controllers and actions in
|
189
|
+
# the application. Let's collect the before_actions that get run on each
|
190
|
+
# controller action.
|
191
|
+
controller_action_hash.each do |controller, actions|
|
192
|
+
|
193
|
+
unless controller.respond_to?(:_process_action_callbacks)
|
194
|
+
#FIXME: change this metadata key name
|
195
|
+
controller_action_filter_hash[:_weird_controller] ||= []
|
196
|
+
controller_action_filter_hash[:_weird_controller] << controller
|
197
|
+
next
|
198
|
+
end
|
199
|
+
|
200
|
+
|
201
|
+
# We only care about before_actions
|
202
|
+
controller._process_action_callbacks.select{|c| c.kind == :before}.each do |callback|
|
203
|
+
# There is a slight disparity in the way conditional before_actions
|
204
|
+
# are handled between Rails 3.2 and 4.x so we need to take this into
|
205
|
+
# consideration here.
|
206
|
+
|
207
|
+
# RAILS 3.2
|
208
|
+
if callback.instance_variables.include?(:@options)
|
209
|
+
options = callback.instance_variable_get(:@options)
|
210
|
+
if_call, unless_call = options[:if], options[:unless]
|
211
|
+
else # RAILS 4.x
|
212
|
+
if_call, unless_call = callback.instance_variable_get(:@if), callback.instance_variable_get(:@unless)
|
213
|
+
end
|
214
|
+
|
215
|
+
# Keep track of before_actions that rely on Procs. Since we can't
|
216
|
+
# really handle this in our code, we keep it in a metadata key and
|
217
|
+
# present it to the user so they can check up on it themselves.
|
218
|
+
if if_call.first.is_a?(Proc) || unless_call.first.is_a?(Proc)
|
219
|
+
controller_action_filter_hash[:_proc_conditionals][controller] ||= []
|
220
|
+
controller_action_filter_hash[:_proc_conditionals][controller] << callback.filter.to_s
|
221
|
+
next
|
222
|
+
end
|
223
|
+
|
224
|
+
|
225
|
+
# Go through and process each condition
|
226
|
+
if if_call.empty? && unless_call.empty?
|
227
|
+
actions.each do |action|
|
228
|
+
controller_action_filter_hash[controller][action] << callback.filter.to_s
|
229
|
+
end
|
230
|
+
elsif !if_call.empty? # before_(filter|action) only: [:foo, :bar, :baz]
|
231
|
+
|
232
|
+
actions_to_filter = if_call.select{|call| call.is_a?(Symbol)}
|
233
|
+
actions_to_filter << actions_from_conditional(if_call.select{|call| call.is_a?(String)})
|
234
|
+
|
235
|
+
actions_to_filter.flatten! unless actions_to_filter.empty?
|
236
|
+
actions_to_filter.compact! unless actions_to_filter.empty?
|
237
|
+
|
238
|
+
actions_to_filter.each do |action|
|
239
|
+
next unless actions.include?(action)
|
240
|
+
controller_action_filter_hash[controller][action] << callback.filter.to_s
|
241
|
+
end
|
242
|
+
|
243
|
+
elsif !unless_call.empty? # before_(filter|action) unless: [:qux]
|
244
|
+
# Get all the symbols first
|
245
|
+
unless_actions = unless_call.select{|call| call.is_a?(Symbol)}
|
246
|
+
|
247
|
+
# Now process any Array based conditionas
|
248
|
+
unless_actions << actions_from_conditional(unless_call.select{|call| call.is_a?(String)})
|
249
|
+
|
250
|
+
unless_actions.flatten! unless unless_actions.empty?
|
251
|
+
unless_actions.compact! unless unless_actions.empty?
|
252
|
+
|
253
|
+
# If the unless conditional isn't an action we won't include it because
|
254
|
+
# similar to the proces this filter relies on the true/false output of a
|
255
|
+
# method
|
256
|
+
if (actions & unless_actions).empty?
|
257
|
+
controller_action_filter_hash[:_method_conditionals][controller] ||= []
|
258
|
+
controller_action_filter_hash[:_method_conditionals][controller] << {filter: callback.filter.to_s, conditional: unless_actions}
|
259
|
+
next
|
260
|
+
end
|
261
|
+
|
262
|
+
actions.reject{|a| unless_actions.include?(a)}.each do |action|
|
263
|
+
controller_action_filter_hash[controller][action] << callback.filter.to_s
|
264
|
+
end
|
265
|
+
end
|
266
|
+
end
|
267
|
+
end
|
268
|
+
controller_action_filter_hash
|
269
|
+
end
|
270
|
+
end
|
271
|
+
end
|
272
|
+
|
data/lib/boilerman/engine.rb
CHANGED
@@ -3,8 +3,14 @@ module Boilerman
|
|
3
3
|
isolate_namespace Boilerman
|
4
4
|
load_generators
|
5
5
|
|
6
|
-
|
7
|
-
|
8
|
-
|
6
|
+
begin
|
7
|
+
require 'bootstrap-sass'
|
8
|
+
require 'gon'
|
9
|
+
require 'jquery-rails'
|
10
|
+
rescue LoadError
|
11
|
+
puts "WARNING: You're probably side loading boilerman into a console.
|
12
|
+
Note that you will only have console access to Boilerman and will be
|
13
|
+
unable to access it via the /boilerman path"
|
14
|
+
end
|
9
15
|
end
|
10
16
|
end
|
data/lib/boilerman/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: boilerman
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tomek Rabczak
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-09-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -90,15 +90,22 @@ files:
|
|
90
90
|
- MIT-LICENSE
|
91
91
|
- Rakefile
|
92
92
|
- app/assets/javascripts/application.js
|
93
|
+
- app/assets/javascripts/boilerman/actions_controller.js
|
93
94
|
- app/assets/javascripts/boilerman/application.js
|
94
95
|
- app/assets/javascripts/boilerman/controllers.js
|
95
96
|
- app/assets/stylesheets/application.css
|
97
|
+
- app/assets/stylesheets/boilerman/actions_controller.css
|
96
98
|
- app/assets/stylesheets/boilerman/application.scss
|
97
99
|
- app/assets/stylesheets/boilerman/controllers.css
|
100
|
+
- app/controllers/boilerman/actions_controller.rb
|
98
101
|
- app/controllers/boilerman/application_controller.rb
|
99
102
|
- app/controllers/boilerman/controllers_controller.rb
|
103
|
+
- app/helpers/boilerman/actions_controller_helper.rb
|
100
104
|
- app/helpers/boilerman/application_helper.rb
|
101
105
|
- app/helpers/boilerman/controllers_helper.rb
|
106
|
+
- app/views/boilerman/actions/_controller_filter.html.erb
|
107
|
+
- app/views/boilerman/actions/_filters_filter.html.erb
|
108
|
+
- app/views/boilerman/actions/index.html.erb
|
102
109
|
- app/views/boilerman/controllers/_action_filter.html.erb
|
103
110
|
- app/views/boilerman/controllers/_application_statistics_panel.html.erb
|
104
111
|
- app/views/boilerman/controllers/_callback_breakdown_panel.html.erb
|
@@ -109,11 +116,13 @@ files:
|
|
109
116
|
- config/locales/en.bootstrap.yml
|
110
117
|
- config/routes.rb
|
111
118
|
- lib/boilerman.rb
|
119
|
+
- lib/boilerman/actions.rb
|
112
120
|
- lib/boilerman/engine.rb
|
113
121
|
- lib/boilerman/version.rb
|
114
122
|
- lib/generators/boilerman/install_generator.rb
|
115
123
|
- lib/tasks/boilerman_tasks.rake
|
116
124
|
- test/boilerman_test.rb
|
125
|
+
- test/controllers/boilerman/actions_controller_controller_test.rb
|
117
126
|
- test/controllers/boilerman/controllers_controller_test.rb
|
118
127
|
- test/dummy/README.rdoc
|
119
128
|
- test/dummy/Rakefile
|
@@ -177,6 +186,7 @@ specification_version: 4
|
|
177
186
|
summary: A Rails dynamic analysis tool
|
178
187
|
test_files:
|
179
188
|
- test/boilerman_test.rb
|
189
|
+
- test/controllers/boilerman/actions_controller_controller_test.rb
|
180
190
|
- test/controllers/boilerman/controllers_controller_test.rb
|
181
191
|
- test/dummy/app/assets/javascripts/application.js
|
182
192
|
- test/dummy/app/assets/stylesheets/application.css
|
@@ -214,4 +224,3 @@ test_files:
|
|
214
224
|
- test/helpers/boilerman/controllers_helper_test.rb
|
215
225
|
- test/integration/navigation_test.rb
|
216
226
|
- test/test_helper.rb
|
217
|
-
has_rdoc:
|