wtf-tools 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/LICENSE +22 -0
- data/README.md +142 -0
- data/Rakefile +8 -0
- data/example/dump.rb +26 -0
- data/example/timing.rb +18 -0
- data/example/tracking.rb +32 -0
- data/lib/wtf-tools.rb +56 -0
- data/lib/wtf/dumper.rb +87 -0
- data/lib/wtf/method_tracker.rb +89 -0
- data/lib/wtf/query_tracker.rb +33 -0
- data/test/test_dumper.rb +8 -0
- data/test/test_method_tracker.rb +8 -0
- data/test/test_timing.rb +8 -0
- data/wtf-tools.gemspec +24 -0
- metadata +76 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 39cd4bdb18179b654c8c89627596eba83ef1bb93
|
4
|
+
data.tar.gz: b55d4b4ddb008660477c7c54a3124299b50f8380
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 3fe5a3c452e36a089d9f54f94f2e082e3453bf9f2164ea91d28a58c3b725d24b7c18c8935e914890ab830374305cca3cb6d73add38cdbad12bc86191b6485b13
|
7
|
+
data.tar.gz: b3301c939c79f6dcf23ad3060908e0555255bd517e3f71a129bc26f57a26ec4c3cdde88643f2828bf607ff49c18038420667dcc8782937cfb61af39bbe5bdce2
|
data/LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2014 Remigijus Jodelis
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
+
SOFTWARE.
|
22
|
+
|
data/README.md
ADDED
@@ -0,0 +1,142 @@
|
|
1
|
+
wtf-tools
|
2
|
+
=========
|
3
|
+
|
4
|
+
Some tools for debugging and profiling Ruby on Rails projects. Included:
|
5
|
+
|
6
|
+
* data dumper
|
7
|
+
* code timing tool
|
8
|
+
* method tracker - a kind of middle ground between simple timing and full profiling
|
9
|
+
* SQL tracker - detect where exactly given SQL query originated from
|
10
|
+
|
11
|
+
User is responsible for requiring gems necessary for rendering output.
|
12
|
+
For example, when :yaml option is used with `WTF?`, we expect that `YAML` is already loaded.
|
13
|
+
Library requirements for specific options are documented below.
|
14
|
+
|
15
|
+
Usage examples
|
16
|
+
--------------
|
17
|
+
|
18
|
+
### Data dumping
|
19
|
+
|
20
|
+
```ruby
|
21
|
+
WTF? my_var # basic
|
22
|
+
WTF? my_var, other_var, { some: data }, :pp # more data, option: pretty-print
|
23
|
+
WTF? :label, records, :bare, :time # multiple options given
|
24
|
+
```
|
25
|
+
|
26
|
+
Supported options
|
27
|
+
|
28
|
+
```
|
29
|
+
Prefix
|
30
|
+
(default) WTF (my_file_name/method_name:227):
|
31
|
+
:time with timestamp: [2014-10-28 12:33:11 +0200]
|
32
|
+
:nl new line before the record
|
33
|
+
:no no prefix at all
|
34
|
+
|
35
|
+
Formatting
|
36
|
+
(default) simple Ruby inspect
|
37
|
+
:pp pretty-print, require 'pp'
|
38
|
+
:yaml YAML format, require 'yaml'
|
39
|
+
:json JSON format, require 'json'
|
40
|
+
:csv CSV format, require 'csv'
|
41
|
+
:text simple Ruby to_s
|
42
|
+
:line modifier, each object in separate line
|
43
|
+
:bare modifier, ActiveRecord with just id attributs: #<MyClass id: 1234>
|
44
|
+
|
45
|
+
Output control
|
46
|
+
(default) to the chosen logger (see configuration)
|
47
|
+
:log to Rails default logger
|
48
|
+
:file to a separate file in configured location
|
49
|
+
:page to a thread variable Thread.current[:wtf]
|
50
|
+
:redis to a Redis list on key 'wtf', expiring in 30min
|
51
|
+
:raise raise the string containing data as exception
|
52
|
+
```
|
53
|
+
|
54
|
+
---
|
55
|
+
|
56
|
+
### Code timing
|
57
|
+
|
58
|
+
```ruby
|
59
|
+
class MyClass
|
60
|
+
def run_something
|
61
|
+
WTF.time {
|
62
|
+
# your code
|
63
|
+
}
|
64
|
+
end
|
65
|
+
end
|
66
|
+
```
|
67
|
+
|
68
|
+
---
|
69
|
+
|
70
|
+
### Method tracking
|
71
|
+
|
72
|
+
```ruby
|
73
|
+
class MyClass
|
74
|
+
def run_something
|
75
|
+
WTF.track(self, OtherClass)
|
76
|
+
# lots of code
|
77
|
+
WTF.track_finish
|
78
|
+
end
|
79
|
+
end
|
80
|
+
```
|
81
|
+
|
82
|
+
This will create a CSV file in configured location, containing profiling info.
|
83
|
+
Profiling happens only in the methods of the calling class, and other given class.
|
84
|
+
|
85
|
+
How it works: every method in `MyClass` and `OtherClass` is overridden, adding resource timing code.
|
86
|
+
All calls to those methods from the code between `track` and `track_finish` are measured (time and memory),
|
87
|
+
and sum amounts are output at the end, sorted by total time used.
|
88
|
+
|
89
|
+
Example output:
|
90
|
+
|
91
|
+
```csv
|
92
|
+
class,method,count,time,heap_mb
|
93
|
+
,top,0,0.948,0.0
|
94
|
+
Overview,some_helper,16408,0.351,0.0
|
95
|
+
Overview,my_records,28,0.172,0.0
|
96
|
+
Overview,load_data,1,0.166,0.0
|
97
|
+
...
|
98
|
+
```
|
99
|
+
|
100
|
+
Requirements: Ruby 2.0, because the technique used involves module `prepend`-ing, which is not available in Ruby 1.9.
|
101
|
+
Warning: tracking method calls adds time overhead (somewhere from 10% to 3x, depending on number of times the methods were called).
|
102
|
+
|
103
|
+
---
|
104
|
+
|
105
|
+
### SQL tracking
|
106
|
+
|
107
|
+
```ruby
|
108
|
+
class MyClass
|
109
|
+
def run_something
|
110
|
+
WTF.sql %q{SELECT * FROM `my_records` WHERE `attribute`='value' AND `etc`}
|
111
|
+
WTF.sql %q{UPDATE `my_records` SET `some_values`=NULL}
|
112
|
+
# lots of code
|
113
|
+
end
|
114
|
+
end
|
115
|
+
```
|
116
|
+
|
117
|
+
This will add a `WTF?`-style dump in the default location, containing stacktrace where given SQL statement was generated. SQL must match exactly as strings.
|
118
|
+
|
119
|
+
---
|
120
|
+
|
121
|
+
|
122
|
+
Configuration
|
123
|
+
-------------
|
124
|
+
|
125
|
+
Configure WTF before using the above-mentioned facilities. Rails initializer dir is a good place for it.
|
126
|
+
|
127
|
+
```ruby
|
128
|
+
WTF.options = {
|
129
|
+
default: Rails.logger,
|
130
|
+
files: "#{Rails.root}/log/wtf",
|
131
|
+
redis: Redis.new,
|
132
|
+
}
|
133
|
+
|
134
|
+
require 'yaml' # to use :yaml option, etc
|
135
|
+
```
|
136
|
+
|
137
|
+
---
|
138
|
+
|
139
|
+
License
|
140
|
+
-------
|
141
|
+
|
142
|
+
This is released under the [MIT License](http://www.opensource.org/licenses/MIT).
|
data/Rakefile
ADDED
data/example/dump.rb
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'wtf-tools'
|
3
|
+
require 'pp'
|
4
|
+
require 'json'
|
5
|
+
require 'yaml'
|
6
|
+
require 'active_support/logger'
|
7
|
+
require 'fileutils'
|
8
|
+
|
9
|
+
WTF.options = {
|
10
|
+
:default => ActiveSupport::Logger.new('./example.log'),
|
11
|
+
:files => './wtf',
|
12
|
+
}
|
13
|
+
|
14
|
+
data = { 'some' => { 'nested' => { 'data' => 17 } }, :question => %w(life universe and everything), :answer => 42 }
|
15
|
+
|
16
|
+
WTF? Time.now
|
17
|
+
|
18
|
+
WTF? :label, "string", 17, 2.0001, :time, :nl
|
19
|
+
|
20
|
+
WTF? 'label', "string", 17, 2.0001, :time, :line, :nl
|
21
|
+
|
22
|
+
WTF? data, :pp, :nl
|
23
|
+
|
24
|
+
WTF? data, :json, :nl
|
25
|
+
|
26
|
+
WTF? data, :yaml, :no, :file
|
data/example/timing.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'wtf-tools'
|
3
|
+
require 'active_support/logger'
|
4
|
+
|
5
|
+
# default: puts
|
6
|
+
WTF.time {
|
7
|
+
sleep 1.01
|
8
|
+
}
|
9
|
+
|
10
|
+
# logging time with specified precision and options
|
11
|
+
WTF.options = {
|
12
|
+
:default => ActiveSupport::Logger.new('./example.log'),
|
13
|
+
}
|
14
|
+
result = WTF.time(4, :nl) {
|
15
|
+
sleep 3.12346
|
16
|
+
17
|
17
|
+
}
|
18
|
+
p result # => 17
|
data/example/tracking.rb
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'wtf-tools'
|
3
|
+
require 'fileutils'
|
4
|
+
require 'csv'
|
5
|
+
|
6
|
+
WTF.options = {
|
7
|
+
:files => './wtf',
|
8
|
+
}
|
9
|
+
|
10
|
+
class Sample
|
11
|
+
def run
|
12
|
+
WTF.track(self)
|
13
|
+
action1
|
14
|
+
action2
|
15
|
+
action3
|
16
|
+
WTF.track_finish
|
17
|
+
end
|
18
|
+
|
19
|
+
def action1
|
20
|
+
sleep 1
|
21
|
+
end
|
22
|
+
|
23
|
+
def action2
|
24
|
+
sleep 2
|
25
|
+
end
|
26
|
+
|
27
|
+
def action3
|
28
|
+
sleep 3
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
Sample.new.run
|
data/lib/wtf-tools.rb
ADDED
@@ -0,0 +1,56 @@
|
|
1
|
+
require 'wtf/dumper'
|
2
|
+
require 'wtf/method_tracker'
|
3
|
+
require 'wtf/query_tracker'
|
4
|
+
|
5
|
+
module WTF
|
6
|
+
class << self
|
7
|
+
def options=(value)
|
8
|
+
@options = value
|
9
|
+
end
|
10
|
+
|
11
|
+
def options
|
12
|
+
@options ||= {}
|
13
|
+
end
|
14
|
+
|
15
|
+
def files_path
|
16
|
+
dirs = FileUtils.mkdir_p(options[:files])
|
17
|
+
dirs.first
|
18
|
+
end
|
19
|
+
|
20
|
+
# TODO: separately track ActiveRecord finders usage in the related methods
|
21
|
+
def track(*objects)
|
22
|
+
WTF::MethodTracker.start_tracking(*objects)
|
23
|
+
if block_given?
|
24
|
+
yield
|
25
|
+
track_finish
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def track_finish
|
30
|
+
WTF::MethodTracker.finish
|
31
|
+
end
|
32
|
+
|
33
|
+
def sql(sql)
|
34
|
+
WTF::QueryTracker.start_tracking(sql)
|
35
|
+
end
|
36
|
+
|
37
|
+
def time(*args)
|
38
|
+
require 'absolute_time'
|
39
|
+
|
40
|
+
precision = args.shift if args.first.is_a?(Fixnum)
|
41
|
+
precision ||= 3
|
42
|
+
before = AbsoluteTime.now
|
43
|
+
result = yield
|
44
|
+
duration = AbsoluteTime.now - before
|
45
|
+
WTF::Dumper.new(duration.round(precision), *args)
|
46
|
+
result
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
Object.class_eval do
|
52
|
+
def WTF?(*args)
|
53
|
+
WTF::Dumper.new(*args)
|
54
|
+
nil
|
55
|
+
end
|
56
|
+
end
|
data/lib/wtf/dumper.rb
ADDED
@@ -0,0 +1,87 @@
|
|
1
|
+
module WTF
|
2
|
+
class Dumper
|
3
|
+
OPTIONS = [
|
4
|
+
:time, :nl, :no, # prefix
|
5
|
+
:pp, :yaml, :json, :text, :line, :csv, # format
|
6
|
+
:bare, # modify
|
7
|
+
:page, :file, :raise, :redis, :log, # output
|
8
|
+
].freeze
|
9
|
+
|
10
|
+
attr_reader :options
|
11
|
+
|
12
|
+
def initialize(*args)
|
13
|
+
@options = {}
|
14
|
+
while OPTIONS.include?(args.last)
|
15
|
+
@options[args.pop] = true
|
16
|
+
end
|
17
|
+
|
18
|
+
data = prefix(args) << format(args)
|
19
|
+
output(data)
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def prefix(args)
|
25
|
+
data = ''
|
26
|
+
return data if options[:no]
|
27
|
+
data << "\n" if options[:nl]
|
28
|
+
data << "[%s] " % Time.now if options[:time]
|
29
|
+
data << if args[0].is_a?(Symbol)
|
30
|
+
args.shift.to_s.upcase
|
31
|
+
else
|
32
|
+
pattern = %r{([^/]+?)(?:\.rb)?:(\d+):in `(.*)'$} # '
|
33
|
+
"WTF (%s/%s:%s)" % caller[3].match(pattern).values_at(1,3,2)
|
34
|
+
end
|
35
|
+
data << ': '
|
36
|
+
end
|
37
|
+
|
38
|
+
def format(args)
|
39
|
+
case
|
40
|
+
when options[:pp]
|
41
|
+
cleanup(args.pretty_inspect, options[:bare])
|
42
|
+
when options[:yaml]
|
43
|
+
YAML.dump(args)
|
44
|
+
when options[:json]
|
45
|
+
JSON::pretty_generate(args)
|
46
|
+
when options[:text]
|
47
|
+
args.map(&:to_s).join("\n")
|
48
|
+
when options[:line]
|
49
|
+
args.map(&:inspect).join("\n ")
|
50
|
+
when options[:csv]
|
51
|
+
args[0].map(&:to_csv).join
|
52
|
+
else
|
53
|
+
cleanup(args.inspect, options[:bare])
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def output(data)
|
58
|
+
case
|
59
|
+
when options[:page]
|
60
|
+
(Thread.current[:wtf] ||= []) << data
|
61
|
+
when options[:file]
|
62
|
+
time = Time.now.strftime('%m%d_%H%M%S')
|
63
|
+
file = "#{WTF.files_path}/wtf_#{time}_#{rand(10000)}.txt"
|
64
|
+
File.write(file, data)
|
65
|
+
when options[:raise]
|
66
|
+
raise StandardError, data
|
67
|
+
when options[:redis]
|
68
|
+
WTF.options[:redis].rpush('wtf', data)
|
69
|
+
WTF.options[:redis].expire('wtf', 30*60)
|
70
|
+
when options[:log]
|
71
|
+
Rails.logger.info(data)
|
72
|
+
when WTF.options[:default]
|
73
|
+
WTF.options[:default].info(data)
|
74
|
+
else
|
75
|
+
puts data
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def cleanup(str, bare = false)
|
80
|
+
# remove array parentheses
|
81
|
+
str.gsub!(/^\[|\]$/,'')
|
82
|
+
# ActiveRecord no attributes
|
83
|
+
str.gsub!(/#<[A-Z]\w+ id: \d+\K.*?>/, '>') if bare
|
84
|
+
str
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
@@ -0,0 +1,89 @@
|
|
1
|
+
module WTF
|
2
|
+
module MethodTracker
|
3
|
+
class << self
|
4
|
+
def start_tracking(*objects)
|
5
|
+
require 'absolute_time'
|
6
|
+
|
7
|
+
objects.each do |object|
|
8
|
+
klass = object.is_a?(Module) ? object : object.class
|
9
|
+
prepare(klass)
|
10
|
+
end
|
11
|
+
reset_state
|
12
|
+
end
|
13
|
+
|
14
|
+
def prepare(base)
|
15
|
+
methods = base.instance_methods(false) + base.private_instance_methods(false)
|
16
|
+
compiled = methods.map do |name|
|
17
|
+
override_method(base, name)
|
18
|
+
end
|
19
|
+
base.module_eval %{
|
20
|
+
module Tracking
|
21
|
+
#{compiled.join}
|
22
|
+
end
|
23
|
+
prepend Tracking
|
24
|
+
}
|
25
|
+
end
|
26
|
+
|
27
|
+
def override_method(base, name)
|
28
|
+
%{
|
29
|
+
def #{name}(*args)
|
30
|
+
WTF::MethodTracker.on_start(#{base}, :#{name})
|
31
|
+
return_value = super
|
32
|
+
WTF::MethodTracker.on_end
|
33
|
+
return_value
|
34
|
+
end
|
35
|
+
}
|
36
|
+
end
|
37
|
+
|
38
|
+
attr_accessor :stats, :stack, :last_time, :last_heap
|
39
|
+
|
40
|
+
def reset_state
|
41
|
+
self.stats = Hash.new { |h,k| h[k] = { :freq => 0, :time => 0.0, :heap => 0 } }
|
42
|
+
self.stack = [[nil, :top]]
|
43
|
+
self.last_time = AbsoluteTime.now
|
44
|
+
self.last_heap = GC.stat[:heap_length]
|
45
|
+
end
|
46
|
+
|
47
|
+
def on_start(*full_name)
|
48
|
+
add_stats(full_name)
|
49
|
+
stack.push(full_name)
|
50
|
+
end
|
51
|
+
|
52
|
+
def on_end
|
53
|
+
add_stats
|
54
|
+
stack.pop
|
55
|
+
end
|
56
|
+
|
57
|
+
def finish
|
58
|
+
add_stats
|
59
|
+
dump_stats
|
60
|
+
reset_state
|
61
|
+
end
|
62
|
+
|
63
|
+
def add_stats(at_start = nil)
|
64
|
+
stat = stats[stack.last]
|
65
|
+
|
66
|
+
this_time = AbsoluteTime.now
|
67
|
+
stat[:time] += this_time - last_time
|
68
|
+
self.last_time = this_time
|
69
|
+
|
70
|
+
this_heap = GC.stat[:heap_length]
|
71
|
+
stat[:heap] += this_heap - last_heap
|
72
|
+
self.last_heap = this_heap
|
73
|
+
|
74
|
+
stats[at_start][:freq] += 1 if at_start
|
75
|
+
end
|
76
|
+
|
77
|
+
def dump_stats
|
78
|
+
data = stats.map do |key, val|
|
79
|
+
[*key, val[:freq].to_i, val[:time].to_f.round(3), (val[:heap].to_f / 64).round(3)]
|
80
|
+
end
|
81
|
+
data = data.sort_by {|it| it[3] }.reverse
|
82
|
+
data.unshift(%w(class method count time heap_mb))
|
83
|
+
|
84
|
+
time = Time.now.strftime('%m%d_%H%M%S')
|
85
|
+
File.write("#{WTF.files_path}/track_#{time}_#{rand(10000)}.csv", data.map(&:to_csv).join)
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module WTF
|
2
|
+
module QueryTracker
|
3
|
+
class << self
|
4
|
+
attr_reader :trackable
|
5
|
+
|
6
|
+
def start_tracking(sql)
|
7
|
+
if @trackable.nil?
|
8
|
+
prepare_hook
|
9
|
+
@trackable = {}
|
10
|
+
end
|
11
|
+
@trackable[sql] = true
|
12
|
+
end
|
13
|
+
|
14
|
+
def prepare_hook
|
15
|
+
ActiveRecord::ConnectionAdapters::AbstractAdapter.module_eval %{
|
16
|
+
module TrackingSQL
|
17
|
+
def log(sql, *args, &block)
|
18
|
+
WTF::QueryTracker.on_sql(sql)
|
19
|
+
super(sql, *args, &block)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
prepend TrackingSQL
|
23
|
+
}
|
24
|
+
end
|
25
|
+
|
26
|
+
def on_sql(sql)
|
27
|
+
if trackable[sql]
|
28
|
+
WTF::Dumper.new(:sql, sql, *caller.take(30), :line)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
data/test/test_dumper.rb
ADDED
data/test/test_timing.rb
ADDED
data/wtf-tools.gemspec
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
Gem::Specification.new do |s|
|
2
|
+
s.name = 'wtf-tools'
|
3
|
+
s.version = '1.0.0'
|
4
|
+
s.date = '2014-10-14'
|
5
|
+
s.platform = Gem::Platform::RUBY
|
6
|
+
s.required_ruby_version = Gem::Requirement.new(">= 2.0.0")
|
7
|
+
s.summary = 'tools for debugging and profiling Ruby on Rails projects'
|
8
|
+
s.license = 'MIT'
|
9
|
+
|
10
|
+
s.description = <<-EOF
|
11
|
+
WTF-tools offers some flexible options for your puts-style Ruby debugging needs,
|
12
|
+
and method-level profiling for Ruby on Rails projects.
|
13
|
+
EOF
|
14
|
+
|
15
|
+
s.files = Dir['{lib/**/*,example/*,test/*}'] + %w(LICENSE Rakefile README.md wtf-tools.gemspec)
|
16
|
+
s.require_path = 'lib'
|
17
|
+
s.test_files = Dir['test/*.rb']
|
18
|
+
|
19
|
+
s.author = 'Remigijus Jodelis'
|
20
|
+
s.email = 'remigijus.jodelis@gmail.com'
|
21
|
+
s.homepage = 'http://github.com/remigijusj/wtf-tools'
|
22
|
+
|
23
|
+
s.add_runtime_dependency 'absolute_time', '~> 1.0'
|
24
|
+
end
|
metadata
ADDED
@@ -0,0 +1,76 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: wtf-tools
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Remigijus Jodelis
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-10-14 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: absolute_time
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.0'
|
27
|
+
description: |
|
28
|
+
WTF-tools offers some flexible options for your puts-style Ruby debugging needs,
|
29
|
+
and method-level profiling for Ruby on Rails projects.
|
30
|
+
email: remigijus.jodelis@gmail.com
|
31
|
+
executables: []
|
32
|
+
extensions: []
|
33
|
+
extra_rdoc_files: []
|
34
|
+
files:
|
35
|
+
- LICENSE
|
36
|
+
- README.md
|
37
|
+
- Rakefile
|
38
|
+
- example/dump.rb
|
39
|
+
- example/timing.rb
|
40
|
+
- example/tracking.rb
|
41
|
+
- lib/wtf-tools.rb
|
42
|
+
- lib/wtf/dumper.rb
|
43
|
+
- lib/wtf/method_tracker.rb
|
44
|
+
- lib/wtf/query_tracker.rb
|
45
|
+
- test/test_dumper.rb
|
46
|
+
- test/test_method_tracker.rb
|
47
|
+
- test/test_timing.rb
|
48
|
+
- wtf-tools.gemspec
|
49
|
+
homepage: http://github.com/remigijusj/wtf-tools
|
50
|
+
licenses:
|
51
|
+
- MIT
|
52
|
+
metadata: {}
|
53
|
+
post_install_message:
|
54
|
+
rdoc_options: []
|
55
|
+
require_paths:
|
56
|
+
- lib
|
57
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 2.0.0
|
62
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
63
|
+
requirements:
|
64
|
+
- - ">="
|
65
|
+
- !ruby/object:Gem::Version
|
66
|
+
version: '0'
|
67
|
+
requirements: []
|
68
|
+
rubyforge_project:
|
69
|
+
rubygems_version: 2.2.2
|
70
|
+
signing_key:
|
71
|
+
specification_version: 4
|
72
|
+
summary: tools for debugging and profiling Ruby on Rails projects
|
73
|
+
test_files:
|
74
|
+
- test/test_dumper.rb
|
75
|
+
- test/test_method_tracker.rb
|
76
|
+
- test/test_timing.rb
|