tuttle 0.0.1 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +17 -0
- data/README.md +0 -4
- data/app/controllers/tuttle/rails_controller.rb +15 -0
- data/app/controllers/tuttle/ruby_controller.rb +2 -0
- data/app/views/layouts/tuttle/application.html.erb +2 -0
- data/app/views/tuttle/home/index.html.erb +1 -1
- data/app/views/tuttle/rails/cache.html.erb +81 -0
- data/app/views/tuttle/rails/inflectors.html.erb +50 -0
- data/app/views/tuttle/ruby/index.html.erb +1 -1
- data/config/routes.rb +1 -1
- data/lib/tuttle.rb +8 -0
- data/lib/tuttle/engine.rb +15 -5
- data/lib/tuttle/version.rb +1 -1
- data/test/controllers/tuttle/rails_controller_test.rb +15 -0
- data/test/dummy/config/initializers/tuttle.rb +3 -0
- data/test/dummy/config/routes.rb +0 -1
- metadata +16 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 73376a729eaa050431d5429bc44cbaf0ae395102
|
4
|
+
data.tar.gz: 28f8cbd544f44c4313aab862c4851c73a1db19b2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d1adf98bdb6bee5241729f1d3f63fe837b7c8827940e149915a2b26c65d05e594d00a642039d5e4c2335efe3561db24db2bc43375f42d3a866b8c9519079f6f5
|
7
|
+
data.tar.gz: cbc6476294b3e90d88ba033798f9e6854f5784ecb3b3c15ff78714eb1bdc4b628a2233efa472c93a3ab41d61b6a7f4b61234ce36bf1d5d4f82ddd46ef851d525
|
data/CHANGELOG.md
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
### 0.0.2
|
2
|
+
|
3
|
+
* features
|
4
|
+
* Tuttle::Engine will now auto-mount routes
|
5
|
+
* Engine configurable via initializer
|
6
|
+
* ActiveSupport cache configuration inspection
|
7
|
+
* ActiveSupport inflectors inspection and simple testing
|
8
|
+
|
9
|
+
### 0.0.1
|
10
|
+
|
11
|
+
* features
|
12
|
+
* Initial engine implementation with instrumentation monitoring
|
13
|
+
* Rails inspection for general configuration, controllers, models, assets, helpers
|
14
|
+
* Ruby VM inspection
|
15
|
+
* Devise configuration inspection
|
16
|
+
* CanCanCan configuration inspection and simple rule testing
|
17
|
+
|
data/README.md
CHANGED
@@ -48,5 +48,20 @@ module Tuttle
|
|
48
48
|
@event_counts = Tuttle::Engine.event_counts
|
49
49
|
end
|
50
50
|
|
51
|
+
def inflectors
|
52
|
+
@test_word = params[:test_word] || ''
|
53
|
+
|
54
|
+
@plurals = ActiveSupport::Inflector.inflections.plurals
|
55
|
+
@singulars = ActiveSupport::Inflector.inflections.singulars
|
56
|
+
@uncountables = ActiveSupport::Inflector.inflections.uncountables
|
57
|
+
@humans = ActiveSupport::Inflector.inflections.humans
|
58
|
+
@acronyms = ActiveSupport::Inflector.inflections.acronyms
|
59
|
+
end
|
60
|
+
|
61
|
+
def cache
|
62
|
+
@cache = Rails.cache
|
63
|
+
@cache_events = Tuttle::Engine.events.select {|e| /cache_(read|write)\.active_support/ =~ e.name }
|
64
|
+
end
|
65
|
+
|
51
66
|
end
|
52
67
|
end
|
@@ -4,6 +4,8 @@ module Tuttle
|
|
4
4
|
class RubyController < ApplicationController
|
5
5
|
|
6
6
|
def index
|
7
|
+
# TODO: need better filter for sensitive values. this covers DB-style URLs with passwords, passwords, and keys
|
8
|
+
@filtered_env = ENV.to_hash.tap{ |h| h.each{ |k,_v| h[k] = '--FILTERED--' if /.*_(URL|PASSWORD|KEY|KEY_BASE)$/ =~ k } }
|
7
9
|
end
|
8
10
|
|
9
11
|
end
|
@@ -38,6 +38,8 @@
|
|
38
38
|
<li><%= link_to 'Routes', rails_routes_path %></li>
|
39
39
|
<li><%= link_to 'Database', rails_database_path %></li>
|
40
40
|
<li><%= link_to 'Instrumentation', rails_instrumentation_path %></li>
|
41
|
+
<li><%= link_to 'Inflectors', rails_inflectors_path %></li>
|
42
|
+
<li><%= link_to 'Caching', rails_cache_path %></li>
|
41
43
|
</ul>
|
42
44
|
</li>
|
43
45
|
<li class="dropdown">
|
@@ -0,0 +1,81 @@
|
|
1
|
+
<h1>Cache</h1>
|
2
|
+
|
3
|
+
<h2>Configuration</h2>
|
4
|
+
|
5
|
+
<pre>
|
6
|
+
|
7
|
+
Rails.application.config.action_controller.perform_caching = <%= Rails.application.config.action_controller.perform_caching %>
|
8
|
+
|
9
|
+
Page caching available? <%= !!defined?(ActionController::Caching::Pages) %>
|
10
|
+
Action caching available? <%= !!defined?(ActionController::Caching::Actions) %>
|
11
|
+
|
12
|
+
Rails.cache class = <%= @cache.class %>
|
13
|
+
Rails.cache options = <%= @cache.options %>
|
14
|
+
|
15
|
+
Rails.cache standard options
|
16
|
+
<%- ActiveSupport::Cache::UNIVERSAL_OPTIONS.each do |option| %>
|
17
|
+
:<%= option.to_s %> = <%= @cache.options[option] %>
|
18
|
+
<%- end %>
|
19
|
+
|
20
|
+
<%- if @cache.is_a?(ActiveSupport::Cache::MemoryStore) %>
|
21
|
+
Rails MemoryStore options
|
22
|
+
:size = <%= @cache.instance_variable_get(:@max_size) %>
|
23
|
+
:max_prune_time = <%= @cache.instance_variable_get(:@max_prune_time) %>
|
24
|
+
<%- elsif @cache.is_a?(ActiveSupport::Cache::FileStore) %>
|
25
|
+
Rails FileStore options
|
26
|
+
:cache_path = <%= @cache.instance_variable_get(:@cache_path) %>
|
27
|
+
<%- elsif defined?(Dalli) && @cache.is_a?(ActiveSupport::Cache::MemCacheStore) %>
|
28
|
+
Rails MemCacheStore options
|
29
|
+
TBD - can take an array of addresses
|
30
|
+
<%- elsif defined?(Dalli) && defined?(ActiveSupport::Cache::DalliStore) && @cache.is_a?(ActiveSupport::Cache::DalliStore) %>
|
31
|
+
DalliStore options
|
32
|
+
TBD - can take an array of addresses, can use connection_pool gem
|
33
|
+
<%- end %>
|
34
|
+
</pre>
|
35
|
+
|
36
|
+
<%- if defined?(Dalli) && @cache.respond_to?(:stats) %>
|
37
|
+
<h3>MemCache Stats</h3>
|
38
|
+
<pre>
|
39
|
+
<%= @cache.stats %>
|
40
|
+
</pre>
|
41
|
+
<%- end %>
|
42
|
+
|
43
|
+
<%-
|
44
|
+
#TODO: Controls
|
45
|
+
#Add options here for MemoryStore(clear, cleanup, and prune), FileStore(clear, cleanup), and MemCacheStore(clear).
|
46
|
+
#For MemoryStore, provide method to dump keys and Entry attributes for very granular testing
|
47
|
+
#For testing/inspection, provide a form to manipulate (add,remove,incr,decr) entries
|
48
|
+
|
49
|
+
-%>
|
50
|
+
|
51
|
+
<h2>Monitoring/Instrumentation</h2>
|
52
|
+
|
53
|
+
<h3>Recent cache interactions</h3>
|
54
|
+
|
55
|
+
<table class="table">
|
56
|
+
<tr>
|
57
|
+
<th>Action</th>
|
58
|
+
<th>Key</th>
|
59
|
+
<th>Hit?</th>
|
60
|
+
<th>Options</th>
|
61
|
+
<th>Time</th>
|
62
|
+
<th>Duration</th>
|
63
|
+
<th>TransactionID</th>
|
64
|
+
</tr>
|
65
|
+
<% @cache_events.reverse.each do |event| -%>
|
66
|
+
<tr >
|
67
|
+
<td><%= event.name=='cache_read.active_support' ? 'read':'write' %></td>
|
68
|
+
<td><%= event.payload[:key] %></td>
|
69
|
+
<td><%= event.payload[:hit] %></td>
|
70
|
+
<td><%= event.payload.reject {|k,_v| k==:key || k==:hit} %></td>
|
71
|
+
<td><%= event.time.to_s(:db) %></td>
|
72
|
+
<td><%= number_with_precision(event.duration) %></td>
|
73
|
+
<td><%= event.transaction_id %></td>
|
74
|
+
</tr>
|
75
|
+
<% end -%>
|
76
|
+
</table>
|
77
|
+
|
78
|
+
<%-
|
79
|
+
# TODO: Track calls and record keys broken down by namespace
|
80
|
+
# TODO: Possibly track calls with backtrace to identify calling location
|
81
|
+
-%>
|
@@ -0,0 +1,50 @@
|
|
1
|
+
<h1>ActiveSupport::Inflection</h1>
|
2
|
+
|
3
|
+
<h2>Example</h2>
|
4
|
+
<form class="form-horizontal" role="form" metho="get">
|
5
|
+
<div class="form-group">
|
6
|
+
<label for="test_word" class="col-sm-2 control-label">Test Word</label>
|
7
|
+
<div class="col-sm-10">
|
8
|
+
<input type="text" class="form-control" name="test_word" id="test_word" value="<%= @test_word %>">
|
9
|
+
</div>
|
10
|
+
</div>
|
11
|
+
<div class="form-group">
|
12
|
+
<div class="col-sm-offset-2 col-sm-10">
|
13
|
+
<button type="submit" class="btn btn-default">Test</button>
|
14
|
+
</div>
|
15
|
+
</div>
|
16
|
+
</form>
|
17
|
+
|
18
|
+
<%- unless @test_word.blank? %>
|
19
|
+
<table class="table table-striped table-condensed">
|
20
|
+
<tr><th width="120">Variation</th><th>Value</th></tr>
|
21
|
+
<tr><td>pluralize</td><td><%= @test_word.pluralize %></td></tr>
|
22
|
+
<tr><td>singularize</td><td><%= @test_word.singularize %></td></tr>
|
23
|
+
<tr><td>humanize</td><td><%= @test_word.humanize %></td></tr>
|
24
|
+
<tr><td>titleize</td><td><%= @test_word.titleize %></td></tr>
|
25
|
+
|
26
|
+
<tr><td>camelize</td><td><%= @test_word.camelize %></td></tr>
|
27
|
+
<tr><td>classify</td><td><%= @test_word.classify %></td></tr>
|
28
|
+
<tr><td>dasherize</td><td><%= @test_word.dasherize %></td></tr>
|
29
|
+
<tr><td>deconstantize</td><td><%= @test_word.deconstantize %></td></tr>
|
30
|
+
<tr><td>demodulize</td><td><%= @test_word.demodulize %></td></tr>
|
31
|
+
<tr><td>foreign_key</td><td><%= @test_word.foreign_key %></td></tr>
|
32
|
+
<tr><td>parameterize</td><td><%= @test_word.parameterize %></td></tr>
|
33
|
+
<tr><td>tableize</td><td><%= @test_word.tableize %></td></tr>
|
34
|
+
<tr><td>underscore</td><td><%= @test_word.underscore %></td></tr>
|
35
|
+
</table>
|
36
|
+
<%- end %>
|
37
|
+
|
38
|
+
<h2>Inflector Rules</h2>
|
39
|
+
|
40
|
+
<pre>
|
41
|
+
@plurals = <%= @plurals.inspect %>
|
42
|
+
|
43
|
+
@singulars = <%= @singulars.inspect %>
|
44
|
+
|
45
|
+
@uncountables = <%= @uncountables.inspect %>
|
46
|
+
|
47
|
+
@humans = <%= @humans.inspect %>
|
48
|
+
|
49
|
+
@acronyms = <%= @acronyms.inspect %>
|
50
|
+
</pre>
|
data/config/routes.rb
CHANGED
@@ -4,7 +4,7 @@ Tuttle::Engine.routes.draw do
|
|
4
4
|
|
5
5
|
namespace :rails do
|
6
6
|
get '', :action => :index
|
7
|
-
get :controllers, :models, :database, :helpers, :assets, :routes, :instrumentation
|
7
|
+
get :controllers, :models, :database, :helpers, :assets, :routes, :instrumentation, :inflectors, :cache
|
8
8
|
end
|
9
9
|
|
10
10
|
get '/ruby' => 'ruby#index'
|
data/lib/tuttle.rb
CHANGED
data/lib/tuttle/engine.rb
CHANGED
@@ -27,13 +27,23 @@ module Tuttle
|
|
27
27
|
Tuttle::Engine.event_counts = Hash.new(0)
|
28
28
|
|
29
29
|
# For now, only instrument non-production mode
|
30
|
-
|
30
|
+
unless Rails.env.production?
|
31
|
+
ActiveSupport::Notifications.subscribe(/.*/) do |*args|
|
32
|
+
event = ActiveSupport::Notifications::Event.new(*args)
|
33
|
+
Tuttle::Engine.events << event
|
34
|
+
Tuttle::Engine.event_counts[event.name] += 1
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
31
39
|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
40
|
+
initializer :tuttle_automounter do
|
41
|
+
if Tuttle.automount_engine
|
42
|
+
Rails.application.routes.append do
|
43
|
+
mount Tuttle::Engine, at: "tuttle"
|
44
|
+
end
|
36
45
|
end
|
37
46
|
end
|
47
|
+
|
38
48
|
end
|
39
49
|
end
|
data/lib/tuttle/version.rb
CHANGED
@@ -51,6 +51,21 @@ module Tuttle
|
|
51
51
|
assert_not_nil assigns(:events)
|
52
52
|
assert_not_nil assigns(:event_counts)
|
53
53
|
end
|
54
|
+
|
55
|
+
test 'should get inflectors' do
|
56
|
+
get :inflectors
|
57
|
+
assert_response :success
|
58
|
+
assert_not_nil assigns(:test_word)
|
59
|
+
assert_not_nil assigns(:plurals)
|
60
|
+
end
|
61
|
+
|
62
|
+
test 'should get cache' do
|
63
|
+
get :cache
|
64
|
+
assert_response :success
|
65
|
+
assert_not_nil assigns(:cache)
|
66
|
+
assert_not_nil assigns(:cache_events)
|
67
|
+
end
|
68
|
+
|
54
69
|
end
|
55
70
|
|
56
71
|
end
|
data/test/dummy/config/routes.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: tuttle
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Dave Gynn
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-01-
|
11
|
+
date: 2015-01-14 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -16,14 +16,20 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 4.1.
|
19
|
+
version: 4.1.4
|
20
|
+
- - "<"
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: 5.0.0
|
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: 4.1.
|
29
|
+
version: 4.1.4
|
30
|
+
- - "<"
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: 5.0.0
|
27
33
|
- !ruby/object:Gem::Dependency
|
28
34
|
name: rake
|
29
35
|
requirement: !ruby/object:Gem::Requirement
|
@@ -59,6 +65,7 @@ executables: []
|
|
59
65
|
extensions: []
|
60
66
|
extra_rdoc_files: []
|
61
67
|
files:
|
68
|
+
- CHANGELOG.md
|
62
69
|
- MIT-LICENSE
|
63
70
|
- README.md
|
64
71
|
- Rakefile
|
@@ -79,10 +86,12 @@ files:
|
|
79
86
|
- app/views/tuttle/devise/index.html.erb
|
80
87
|
- app/views/tuttle/home/index.html.erb
|
81
88
|
- app/views/tuttle/rails/assets.html.erb
|
89
|
+
- app/views/tuttle/rails/cache.html.erb
|
82
90
|
- app/views/tuttle/rails/controllers.html.erb
|
83
91
|
- app/views/tuttle/rails/database.html.erb
|
84
92
|
- app/views/tuttle/rails/helpers.html.erb
|
85
93
|
- app/views/tuttle/rails/index.html.erb
|
94
|
+
- app/views/tuttle/rails/inflectors.html.erb
|
86
95
|
- app/views/tuttle/rails/instrumentation.html.erb
|
87
96
|
- app/views/tuttle/rails/models.html.erb
|
88
97
|
- app/views/tuttle/rails/routes.html.erb
|
@@ -120,6 +129,7 @@ files:
|
|
120
129
|
- test/dummy/config/initializers/mime_types.rb
|
121
130
|
- test/dummy/config/initializers/secret_token.rb
|
122
131
|
- test/dummy/config/initializers/session_store.rb
|
132
|
+
- test/dummy/config/initializers/tuttle.rb
|
123
133
|
- test/dummy/config/initializers/wrap_parameters.rb
|
124
134
|
- test/dummy/config/locales/en.yml
|
125
135
|
- test/dummy/config/routes.rb
|
@@ -154,7 +164,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
154
164
|
requirements:
|
155
165
|
- - ">="
|
156
166
|
- !ruby/object:Gem::Version
|
157
|
-
version:
|
167
|
+
version: 1.9.3
|
158
168
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
159
169
|
requirements:
|
160
170
|
- - ">="
|
@@ -191,6 +201,7 @@ test_files:
|
|
191
201
|
- test/dummy/config/initializers/mime_types.rb
|
192
202
|
- test/dummy/config/initializers/secret_token.rb
|
193
203
|
- test/dummy/config/initializers/session_store.rb
|
204
|
+
- test/dummy/config/initializers/tuttle.rb
|
194
205
|
- test/dummy/config/initializers/wrap_parameters.rb
|
195
206
|
- test/dummy/config/locales/en.yml
|
196
207
|
- test/dummy/config/routes.rb
|