wtf-tools 1.0.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 +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
|