trip 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 +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
|
+
[](https://travis-ci.org/rpag/trip)
|
4
|
+
[](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:
|