trip 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.bundle/config +3 -0
- data/.gitignore +6 -0
- data/.travis.yml +10 -0
- data/Gemfile +6 -0
- data/MIT-LICENSE.txt +21 -0
- data/README.md +103 -0
- data/Rakefile +8 -0
- data/examples/concurrent.rb +41 -0
- data/examples/time.rb +15 -0
- data/lib/trip.rb +167 -0
- data/lib/trip/event.rb +31 -0
- data/lib/trip/version.rb +3 -0
- data/spec/setup.rb +3 -0
- data/spec/trip_spec.rb +157 -0
- data/trip.gemspec +11 -0
- metadata +58 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 2d170e305895c49de5afa27d65e21481a42b0647
|
4
|
+
data.tar.gz: d2245ff1028cbe489f101e53ac352c460db424d2
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 28639d5f905547c812c2696d6451984f2624b7327180e597b15f9891f972693204a179914fd6731caf346a97549a9f9088c0d76f79e4fad11e3722377406fe0c
|
7
|
+
data.tar.gz: c4ae55b130f2bf502a7c3626178065ab97128e44da94a9d16685b410451af9501938236a0500dc1dc3e352d1173e1b2ef0acf07255671c0bbdaed8cfa4a45acf
|
data/.bundle/config
ADDED
data/.gitignore
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/MIT-LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2014 rpag
|
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
|
13
|
+
all 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
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,103 @@
|
|
1
|
+
__trip__
|
2
|
+
|
3
|
+
[![Build Status](https://travis-ci.org/rpag/trip.svg?branch=master)](https://travis-ci.org/rpag/trip)
|
4
|
+
[![Code Climate](https://codeclimate.com/github/rpag/trip/badges/gpa.svg)](https://codeclimate.com/github/rpag/trip)
|
5
|
+
|
6
|
+
trip is a concurrent tracer for the ruby programming language. It yields control
|
7
|
+
between two threads, most likely the main thread and a thread that trip creates.
|
8
|
+
It is implemented in pure ruby(no C) and with the help of "Thread#set_trace_func".
|
9
|
+
It can be useful when building developer tools like a debugger or if you want to
|
10
|
+
step through code progmatically at runtime.
|
11
|
+
|
12
|
+
|
13
|
+
__Limitations__
|
14
|
+
|
15
|
+
trip is implemented with "Thread#set_trace_func". It can be a bottleneck,
|
16
|
+
especially when there are a large number of events being created. I have seen
|
17
|
+
ruby grind to a halt when the codepath being traced is busy. It wouldn't be a good
|
18
|
+
library to use with something like a production rails application, but it can be
|
19
|
+
useful when building developer tools.
|
20
|
+
|
21
|
+
"Thread#set_trace_func" isn't well supported on any ruby implementation but the
|
22
|
+
official MRI/CRuby implementations, so jruby+rubinius aren't supported.
|
23
|
+
|
24
|
+
__Examples__
|
25
|
+
|
26
|
+
__1.__
|
27
|
+
|
28
|
+
The code being traced is paused on method call and method return events
|
29
|
+
by default.
|
30
|
+
|
31
|
+
```ruby
|
32
|
+
def add(x,y)
|
33
|
+
x + y
|
34
|
+
end
|
35
|
+
|
36
|
+
trip = Trip.new { add(20,50) }
|
37
|
+
e1 = trip.start # Trip::Event (for the method call of "#add")
|
38
|
+
e2 = trip.resume # Trip::Event (for the method return of "#add")
|
39
|
+
e3 = trip.resume # returns nil (thread exits)
|
40
|
+
```
|
41
|
+
|
42
|
+
__2.__
|
43
|
+
|
44
|
+
A predicate Proc can be implemented as a custom value. It receives
|
45
|
+
an instance of `Trip::Event` that can support the Proc when it is
|
46
|
+
making a decision on whether or not it should pause the tracer by
|
47
|
+
returning false, or to continue by returning true.
|
48
|
+
|
49
|
+
```ruby
|
50
|
+
class Planet
|
51
|
+
def initialize(name)
|
52
|
+
@name = name
|
53
|
+
end
|
54
|
+
|
55
|
+
def echo
|
56
|
+
'ping'
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
trip = Trip.new { Planet.new('earth').echo }
|
61
|
+
trip.pause? { |e| # pause on a method call
|
62
|
+
e.name == 'call'
|
63
|
+
}
|
64
|
+
e1 = trip.start # Trip::Event (for the method call of `Planet#initialize`)
|
65
|
+
e2 = trip.resume # Trip::Event (for the method call of `Planet#echo`)
|
66
|
+
e3 = trip.resume # returns nil (thread exits)
|
67
|
+
```
|
68
|
+
|
69
|
+
__3.__
|
70
|
+
|
71
|
+
Trip::Event#binding can be used to evaluate ruby while the trip
|
72
|
+
thread is sleeping. The example returns the value of the local
|
73
|
+
variable "x" after the add method has been called.
|
74
|
+
|
75
|
+
```ruby
|
76
|
+
def add(x,y)
|
77
|
+
x + y
|
78
|
+
end
|
79
|
+
|
80
|
+
trip = Trip.new { add(2,3) }
|
81
|
+
e1 = trip.start # Trip::Event (for the method call of add)
|
82
|
+
x = e1.binding.eval('x') # returns 2 (x is equal to 2)
|
83
|
+
trip.stop # thread exits
|
84
|
+
|
85
|
+
puts "x is equal to #{x}"
|
86
|
+
```
|
87
|
+
|
88
|
+
__Install__
|
89
|
+
|
90
|
+
rubygems:
|
91
|
+
|
92
|
+
gem install trip
|
93
|
+
|
94
|
+
git:
|
95
|
+
|
96
|
+
git clone https://github.com/rpag/trip.git
|
97
|
+
cd trip
|
98
|
+
gem build trip.gemspec
|
99
|
+
gem install *.gem
|
100
|
+
|
101
|
+
__License__
|
102
|
+
|
103
|
+
See MIT-LICENSE.txt file.
|
data/Rakefile
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
$LOAD_PATH.unshift 'lib'
|
2
|
+
require 'trip'
|
3
|
+
|
4
|
+
#
|
5
|
+
# an example method.
|
6
|
+
# it assigns a local variable and returns control to the caller.
|
7
|
+
#
|
8
|
+
def example
|
9
|
+
x = 1
|
10
|
+
end
|
11
|
+
|
12
|
+
#
|
13
|
+
# initialize Trip with a block that calls the example() method.
|
14
|
+
# the trace doesn't start yet.
|
15
|
+
#
|
16
|
+
trip = Trip.new do
|
17
|
+
example()
|
18
|
+
end
|
19
|
+
|
20
|
+
#
|
21
|
+
# the tracer can be paused on certain events.
|
22
|
+
#
|
23
|
+
trip.pause? do |event|
|
24
|
+
event.name == 'call' or event.name == 'return'
|
25
|
+
end
|
26
|
+
|
27
|
+
#
|
28
|
+
# start trip.
|
29
|
+
# e1 and e2 reference Trip::Event objects. e3 ends up referencing nil.
|
30
|
+
# nil is returned when trip has finished.
|
31
|
+
#
|
32
|
+
e1 = trip.start # before assignment of 'x'
|
33
|
+
e2 = trip.resume # after assignment of 'x'
|
34
|
+
e3 = trip.resume # finished
|
35
|
+
|
36
|
+
#
|
37
|
+
# print the value of 'x'.
|
38
|
+
# the local variable 'x' belongs to the binding closed over by e2(method return).
|
39
|
+
#
|
40
|
+
print 'x is equal to "%s".' % e2.binding.eval('x')
|
41
|
+
|
data/examples/time.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
$LOAD_PATH.unshift 'lib'
|
2
|
+
require 'trip'
|
3
|
+
|
4
|
+
class Phone
|
5
|
+
def self.call
|
6
|
+
sleep(2)
|
7
|
+
'ring ring'
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
trip = Trip.new { Phone.call }
|
12
|
+
trip.pause? { |e| e.name == 'call' or e.name == 'return' }
|
13
|
+
t1 = trip.start.created_at
|
14
|
+
t2 = trip.resume.created_at
|
15
|
+
puts "it took around #{t2 - t1} seconds"
|
data/lib/trip.rb
ADDED
@@ -0,0 +1,167 @@
|
|
1
|
+
class Trip
|
2
|
+
require 'thread'
|
3
|
+
require_relative 'trip/event'
|
4
|
+
require_relative 'trip/version'
|
5
|
+
|
6
|
+
NotStartedError = Class.new(RuntimeError)
|
7
|
+
NotFinishedError = Class.new(RuntimeError)
|
8
|
+
|
9
|
+
RUN_STATE = 'run'
|
10
|
+
SLEEP_STATE = 'sleep'
|
11
|
+
END_STATE = [nil, false]
|
12
|
+
CALL_E = ['call', 'c-call']
|
13
|
+
RETURN_E = ['return', 'c-return']
|
14
|
+
PAUSE_P = Proc.new { |event|
|
15
|
+
CALL_E.include?(event.name) or RETURN_E.include?(event.name)
|
16
|
+
}
|
17
|
+
|
18
|
+
#
|
19
|
+
# @param [Proc] &block
|
20
|
+
# a block of code
|
21
|
+
#
|
22
|
+
# @return [Trip]
|
23
|
+
# returns an instance of Trip
|
24
|
+
#
|
25
|
+
def initialize(&block)
|
26
|
+
if block.equal?(nil)
|
27
|
+
raise ArgumentError, 'expected to receive a block but none given'
|
28
|
+
end
|
29
|
+
@thread = nil
|
30
|
+
@block = block
|
31
|
+
@queue = nil
|
32
|
+
@pause = PAUSE_P
|
33
|
+
end
|
34
|
+
|
35
|
+
#
|
36
|
+
# @raise [ArgumentError]
|
37
|
+
# when no arguments are received
|
38
|
+
#
|
39
|
+
# @param [Proc] callable
|
40
|
+
# accepts a Proc or a block
|
41
|
+
#
|
42
|
+
# @return [Proc]
|
43
|
+
# returns a Proc
|
44
|
+
#
|
45
|
+
def pause?(callable = nil, &block)
|
46
|
+
pause = callable || block
|
47
|
+
if pause.equal?(nil)
|
48
|
+
raise ArgumentError, 'expected to receive a block but none given'
|
49
|
+
end
|
50
|
+
@pause = pause
|
51
|
+
end
|
52
|
+
|
53
|
+
#
|
54
|
+
# @return [Boolean]
|
55
|
+
# returns true when a trace has started
|
56
|
+
#
|
57
|
+
def started?
|
58
|
+
@thread != nil
|
59
|
+
end
|
60
|
+
|
61
|
+
#
|
62
|
+
# @return [Boolean]
|
63
|
+
# returns true when a tracer thread is running
|
64
|
+
#
|
65
|
+
def running?
|
66
|
+
@thread and @thread.status == RUN_STATE
|
67
|
+
end
|
68
|
+
|
69
|
+
#
|
70
|
+
# @return [Boolean]
|
71
|
+
# returns true when a tracer thread has finished
|
72
|
+
#
|
73
|
+
def finished?
|
74
|
+
@thread and END_STATE.include?(@thread.status)
|
75
|
+
end
|
76
|
+
|
77
|
+
#
|
78
|
+
# @return [Boolean]
|
79
|
+
# returns true when a tracer thread is sleeping
|
80
|
+
#
|
81
|
+
def sleeping?
|
82
|
+
@thread and @thread.status == SLEEP_STATE
|
83
|
+
end
|
84
|
+
|
85
|
+
#
|
86
|
+
# resume the tracer
|
87
|
+
#
|
88
|
+
# @raise [Trip::NotStartedError]
|
89
|
+
# when the start method has not been called yet
|
90
|
+
#
|
91
|
+
# @return [Trip::Event, nil]
|
92
|
+
# returns an event or nil
|
93
|
+
#
|
94
|
+
def resume
|
95
|
+
unless started?
|
96
|
+
raise NotStartedError, 'the tracer has not been started'
|
97
|
+
end
|
98
|
+
if sleeping?
|
99
|
+
@thread.wakeup
|
100
|
+
@queue.deq
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
#
|
105
|
+
# start the tracer
|
106
|
+
#
|
107
|
+
# @raise [Trip::NotFinishedError]
|
108
|
+
# when a trace is already in progress
|
109
|
+
#
|
110
|
+
# @return [Trip::Event, nil]
|
111
|
+
# returns an event, or nil
|
112
|
+
#
|
113
|
+
def start
|
114
|
+
if started? and !finished?
|
115
|
+
raise NotFinishedError, 'a trace is still in progress'
|
116
|
+
end
|
117
|
+
@queue = Queue.new
|
118
|
+
@thread = Thread.new do
|
119
|
+
Thread.current.set_trace_func method(:on_event).to_proc
|
120
|
+
@block.call
|
121
|
+
Thread.current.set_trace_func(nil)
|
122
|
+
@queue.enq(nil)
|
123
|
+
end
|
124
|
+
@queue.deq
|
125
|
+
end
|
126
|
+
|
127
|
+
#
|
128
|
+
# stop the tracer
|
129
|
+
#
|
130
|
+
# @return [nil]
|
131
|
+
# returns nil
|
132
|
+
#
|
133
|
+
def stop
|
134
|
+
if @thread
|
135
|
+
@thread.set_trace_func(nil)
|
136
|
+
@thread.exit
|
137
|
+
@thread.join
|
138
|
+
nil
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
private
|
143
|
+
def on_event(name, file, lineno, method, binding, classname)
|
144
|
+
event = Event.new name, {
|
145
|
+
file: file,
|
146
|
+
lineno: lineno,
|
147
|
+
module: classname,
|
148
|
+
method: method,
|
149
|
+
binding: binding
|
150
|
+
}
|
151
|
+
if event.file != __FILE__ and @pause.call(event)
|
152
|
+
@queue.enq(event)
|
153
|
+
Thread.stop
|
154
|
+
end
|
155
|
+
rescue Exception => e
|
156
|
+
warn <<-CRASH.each_line.map(&:lstrip)
|
157
|
+
(trip) the tracer has crashed! :(
|
158
|
+
|
159
|
+
#{e.class}:
|
160
|
+
#{e.message}
|
161
|
+
|
162
|
+
BACKTRACE
|
163
|
+
#{e.backtrace.join("\n")}
|
164
|
+
CRASH
|
165
|
+
Thread.current.set_trace_func(nil)
|
166
|
+
end
|
167
|
+
end
|
data/lib/trip/event.rb
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
class Trip::Event < BasicObject
|
2
|
+
Kernel = ::Kernel
|
3
|
+
Time = ::Time
|
4
|
+
CALLS = %w(call c-call)
|
5
|
+
RETURNS = %w(return c-return)
|
6
|
+
|
7
|
+
attr_reader :name, :created_at
|
8
|
+
|
9
|
+
def initialize(name, event)
|
10
|
+
@name = name
|
11
|
+
@event = event
|
12
|
+
@created_at = Time.now
|
13
|
+
end
|
14
|
+
|
15
|
+
[:file, :lineno, :module, :method, :binding].each do |name|
|
16
|
+
define_method(name) { @event[name] }
|
17
|
+
end
|
18
|
+
|
19
|
+
#
|
20
|
+
# @return [Binding]
|
21
|
+
# returns a binding for an instance of {Trip::Event}
|
22
|
+
#
|
23
|
+
def __binding__
|
24
|
+
Kernel.binding
|
25
|
+
end
|
26
|
+
|
27
|
+
def inspect
|
28
|
+
inspect_m = Kernel.instance_method(:inspect).bind(self)
|
29
|
+
inspect_m.call
|
30
|
+
end
|
31
|
+
end
|
data/lib/trip/version.rb
ADDED
data/spec/setup.rb
ADDED
data/spec/trip_spec.rb
ADDED
@@ -0,0 +1,157 @@
|
|
1
|
+
require_relative 'setup'
|
2
|
+
describe Trip do
|
3
|
+
class Planet
|
4
|
+
def echo(message)
|
5
|
+
return message
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
before do
|
10
|
+
@planet = Planet.new
|
11
|
+
@trip = Trip.new { @planet.echo('ping') }
|
12
|
+
end
|
13
|
+
|
14
|
+
after do
|
15
|
+
unless @trip.finished?
|
16
|
+
@trip.stop
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
describe '#initialize' do
|
21
|
+
it 'raises an ArgumentError without a block' do
|
22
|
+
assert_raises(ArgumentError) { Trip.new }
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
describe '#start' do
|
27
|
+
it 'returns an instance of Trip::Event' do
|
28
|
+
assert Trip::Event === @trip.start
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'returns nil with a false pause predicate' do
|
32
|
+
@trip.pause? { false }
|
33
|
+
assert_equal nil, @trip.start
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'raises Trip::NotFinishedError' do
|
37
|
+
@trip.start
|
38
|
+
assert_raises(Trip::NotFinishedError) { @trip.start }
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
describe '#sleeping?' do
|
43
|
+
it 'returns true' do
|
44
|
+
@trip.start
|
45
|
+
assert_equal true, @trip.sleeping?
|
46
|
+
end
|
47
|
+
|
48
|
+
it 'returns false' do
|
49
|
+
@trip.start
|
50
|
+
@trip.resume while @trip.resume
|
51
|
+
assert_equal false, @trip.sleeping?
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
describe '#started?' do
|
56
|
+
it 'returns true' do
|
57
|
+
@trip.start
|
58
|
+
assert_equal true, @trip.started?
|
59
|
+
end
|
60
|
+
|
61
|
+
it 'returns false' do
|
62
|
+
assert_equal false, @trip.started?
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
describe '#resume' do
|
67
|
+
it 'raises Trip::NotStartedError' do
|
68
|
+
assert_raises(Trip::NotStartedError) { @trip.resume }
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
describe '#pause?' do
|
73
|
+
it 'raises an ArgumentError' do
|
74
|
+
assert_raises(ArgumentError) { @trip.pause? }
|
75
|
+
end
|
76
|
+
|
77
|
+
it 'accepts a Proc' do
|
78
|
+
obj = Proc.new {}
|
79
|
+
assert_equal obj, @trip.pause?(obj)
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
describe '#finished?' do
|
84
|
+
it 'returns true' do
|
85
|
+
@trip.start
|
86
|
+
@trip.resume while @trip.resume
|
87
|
+
assert_equal true, @trip.finished?
|
88
|
+
end
|
89
|
+
|
90
|
+
it 'returns false' do
|
91
|
+
@trip.start
|
92
|
+
assert_equal false, @trip.finished?
|
93
|
+
end
|
94
|
+
|
95
|
+
it 'returns nil' do
|
96
|
+
assert_equal nil, @trip.finished?
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
describe '#running?' do
|
101
|
+
it 'returns false' do
|
102
|
+
@trip.start
|
103
|
+
@trip.resume while @trip.resume
|
104
|
+
assert_equal false, @trip.running?
|
105
|
+
end
|
106
|
+
|
107
|
+
it 'returns nil' do
|
108
|
+
assert_equal nil, @trip.running?
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
describe Trip::Event do
|
113
|
+
describe '#module' do
|
114
|
+
it 'returns a Module' do
|
115
|
+
e1 = @trip.start
|
116
|
+
assert_equal Planet, e1.module
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
describe '#method' do
|
121
|
+
it 'returns a method name' do
|
122
|
+
e1 = @trip.start
|
123
|
+
assert_equal :echo, e1.method
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
describe '#file' do
|
128
|
+
it 'returns a path' do
|
129
|
+
e1 = @trip.start
|
130
|
+
assert_equal __FILE__, e1.file
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
describe '#lineno' do
|
135
|
+
it 'returns an Integer' do
|
136
|
+
e1 = @trip.start
|
137
|
+
assert_kind_of Integer, e1.lineno
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
describe '#binding' do
|
142
|
+
it 'returns a Binding with access to the local variable "message"' do
|
143
|
+
@trip.pause? { |e| e.name == 'call' or e.name == 'return' }
|
144
|
+
e1 = @trip.start
|
145
|
+
e2 = @trip.resume
|
146
|
+
assert_equal 'ping', e2.binding.eval('message')
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
describe '#__binding__' do
|
151
|
+
it 'returns a Binding for an instance of Trip::Event' do
|
152
|
+
e1 = @trip.start
|
153
|
+
assert Trip::Event === e1.__binding__.eval('self')
|
154
|
+
end
|
155
|
+
end
|
156
|
+
end
|
157
|
+
end
|
data/trip.gemspec
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
$LOAD_PATH << 'lib'
|
2
|
+
require 'trip'
|
3
|
+
Gem::Specification.new do |g|
|
4
|
+
g.name = 'trip'
|
5
|
+
g.author = 'rpag'
|
6
|
+
g.email = 'rpag@singletonclass.com'
|
7
|
+
g.version = Trip::VERSION
|
8
|
+
g.summary = 'concurrent ruby tracer'
|
9
|
+
g.description = 'concurrent ruby tracer built with Thread#set_trace_func'
|
10
|
+
g.files = `git ls-files`.split($/)
|
11
|
+
end
|
metadata
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: trip
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- rpag
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-10-03 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description: concurrent ruby tracer built with Thread#set_trace_func
|
14
|
+
email: rpag@singletonclass.com
|
15
|
+
executables: []
|
16
|
+
extensions: []
|
17
|
+
extra_rdoc_files: []
|
18
|
+
files:
|
19
|
+
- ".bundle/config"
|
20
|
+
- ".gitignore"
|
21
|
+
- ".travis.yml"
|
22
|
+
- Gemfile
|
23
|
+
- MIT-LICENSE.txt
|
24
|
+
- README.md
|
25
|
+
- Rakefile
|
26
|
+
- examples/concurrent.rb
|
27
|
+
- examples/time.rb
|
28
|
+
- lib/trip.rb
|
29
|
+
- lib/trip/event.rb
|
30
|
+
- lib/trip/version.rb
|
31
|
+
- spec/setup.rb
|
32
|
+
- spec/trip_spec.rb
|
33
|
+
- trip.gemspec
|
34
|
+
homepage:
|
35
|
+
licenses: []
|
36
|
+
metadata: {}
|
37
|
+
post_install_message:
|
38
|
+
rdoc_options: []
|
39
|
+
require_paths:
|
40
|
+
- lib
|
41
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
42
|
+
requirements:
|
43
|
+
- - ">="
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
46
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
47
|
+
requirements:
|
48
|
+
- - ">="
|
49
|
+
- !ruby/object:Gem::Version
|
50
|
+
version: '0'
|
51
|
+
requirements: []
|
52
|
+
rubyforge_project:
|
53
|
+
rubygems_version: 2.2.2
|
54
|
+
signing_key:
|
55
|
+
specification_version: 4
|
56
|
+
summary: concurrent ruby tracer
|
57
|
+
test_files: []
|
58
|
+
has_rdoc:
|