cool.io 1.2.0-x86-mingw32

Sign up to get free protection for your applications and to get access to all the features.
Files changed (79) hide show
  1. data/.gitignore +26 -0
  2. data/.rspec +3 -0
  3. data/.travis.yml +4 -0
  4. data/CHANGES.md +176 -0
  5. data/Gemfile +4 -0
  6. data/LICENSE +20 -0
  7. data/README.md +172 -0
  8. data/Rakefile +81 -0
  9. data/cool.io.gemspec +28 -0
  10. data/examples/dslified_echo_client.rb +34 -0
  11. data/examples/dslified_echo_server.rb +24 -0
  12. data/examples/echo_client.rb +38 -0
  13. data/examples/echo_server.rb +27 -0
  14. data/examples/google.rb +9 -0
  15. data/examples/httpclient.rb +38 -0
  16. data/ext/cool.io/.gitignore +5 -0
  17. data/ext/cool.io/cool.io.h +58 -0
  18. data/ext/cool.io/cool.io_ext.c +25 -0
  19. data/ext/cool.io/ev_wrap.h +8 -0
  20. data/ext/cool.io/extconf.rb +73 -0
  21. data/ext/cool.io/iowatcher.c +189 -0
  22. data/ext/cool.io/libev.c +8 -0
  23. data/ext/cool.io/loop.c +301 -0
  24. data/ext/cool.io/stat_watcher.c +269 -0
  25. data/ext/cool.io/timer_watcher.c +219 -0
  26. data/ext/cool.io/utils.c +122 -0
  27. data/ext/cool.io/watcher.c +264 -0
  28. data/ext/cool.io/watcher.h +71 -0
  29. data/ext/http11_client/.gitignore +5 -0
  30. data/ext/http11_client/LICENSE +31 -0
  31. data/ext/http11_client/ext_help.h +14 -0
  32. data/ext/http11_client/extconf.rb +6 -0
  33. data/ext/http11_client/http11_client.c +300 -0
  34. data/ext/http11_client/http11_parser.c +403 -0
  35. data/ext/http11_client/http11_parser.h +48 -0
  36. data/ext/http11_client/http11_parser.rl +173 -0
  37. data/ext/iobuffer/extconf.rb +9 -0
  38. data/ext/iobuffer/iobuffer.c +765 -0
  39. data/ext/libev/Changes +388 -0
  40. data/ext/libev/LICENSE +36 -0
  41. data/ext/libev/README +58 -0
  42. data/ext/libev/README.embed +3 -0
  43. data/ext/libev/ev.c +4803 -0
  44. data/ext/libev/ev.h +845 -0
  45. data/ext/libev/ev_epoll.c +279 -0
  46. data/ext/libev/ev_kqueue.c +214 -0
  47. data/ext/libev/ev_poll.c +148 -0
  48. data/ext/libev/ev_port.c +185 -0
  49. data/ext/libev/ev_select.c +314 -0
  50. data/ext/libev/ev_vars.h +203 -0
  51. data/ext/libev/ev_win32.c +163 -0
  52. data/ext/libev/ev_wrap.h +200 -0
  53. data/ext/libev/test_libev_win32.c +123 -0
  54. data/lib/.gitignore +2 -0
  55. data/lib/cool.io.rb +32 -0
  56. data/lib/cool.io/async_watcher.rb +43 -0
  57. data/lib/cool.io/custom_require.rb +9 -0
  58. data/lib/cool.io/dns_resolver.rb +225 -0
  59. data/lib/cool.io/dsl.rb +135 -0
  60. data/lib/cool.io/eventmachine.rb +234 -0
  61. data/lib/cool.io/http_client.rb +427 -0
  62. data/lib/cool.io/io.rb +174 -0
  63. data/lib/cool.io/iowatcher.rb +17 -0
  64. data/lib/cool.io/listener.rb +93 -0
  65. data/lib/cool.io/loop.rb +130 -0
  66. data/lib/cool.io/meta.rb +49 -0
  67. data/lib/cool.io/server.rb +74 -0
  68. data/lib/cool.io/socket.rb +230 -0
  69. data/lib/cool.io/timer_watcher.rb +17 -0
  70. data/lib/cool.io/version.rb +5 -0
  71. data/lib/coolio.rb +2 -0
  72. data/spec/async_watcher_spec.rb +57 -0
  73. data/spec/dns_spec.rb +39 -0
  74. data/spec/spec_helper.rb +12 -0
  75. data/spec/stat_watcher_spec.rb +77 -0
  76. data/spec/timer_watcher_spec.rb +55 -0
  77. data/spec/unix_listener_spec.rb +25 -0
  78. data/spec/unix_server_spec.rb +25 -0
  79. metadata +200 -0
@@ -0,0 +1,26 @@
1
+ ## MAC OS
2
+ .DS_Store
3
+
4
+ ## TEXTMATE
5
+ *.tmproj
6
+ tmtags
7
+
8
+ ## EMACS
9
+ *~
10
+ \#*
11
+ .\#*
12
+
13
+ ## VIM
14
+ *.swp
15
+
16
+ ## PROJECT::GENERAL
17
+ coverage
18
+ rdoc
19
+ pkg
20
+ tmp
21
+
22
+ ## RUBINIUS
23
+ *.rbc
24
+
25
+ ## PROJECT::SPECIFIC
26
+ conftest.dSYM
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --color
2
+ --format documentation
3
+ --backtrace
@@ -0,0 +1,4 @@
1
+ rvm:
2
+ - 1.8.7
3
+ - 1.9.2
4
+ - rbx
@@ -0,0 +1,176 @@
1
+ 1.2.0
2
+ -----
3
+
4
+ * Support Windows environment via cross compilation
5
+ * Include iobuffer library
6
+ * Update to libev 4.15
7
+
8
+ 1.1.0
9
+ -----
10
+
11
+ * Switch from Jeweler to Bundler for the gem boilerplate
12
+ * Fix firing of Coolio::HttpClient#on_request_complete (#15)
13
+ * Fix failure to resolve Init_cool symbol on win32 mingw (#14)
14
+ * Fix closing /etc/hosts in the DNS resolver (#12)
15
+ * Refactor StatWatcher to pass pervious and current path state ala Node.js
16
+ * spec:valgrind Rake task to run specs under valgrind
17
+ * Use rake-compiler to build cool.io
18
+ * Upgrade to libev 4.04
19
+
20
+ 1.0.0
21
+ -----
22
+
23
+ * Fancy new DSL
24
+
25
+ 0.9.0
26
+ -----
27
+
28
+ * Rename the project to cool.io
29
+ * Bump the version all the way to 0.9! Hell yeah! 1.0 soon!
30
+ * Rename the main module from Rev to Coolio, with deprecation warnings for Rev
31
+ * Use Jeweler to manage the gem
32
+ * Update to RSpec 2.0
33
+ * Update to libev 4.01
34
+ * Initial Rubinius support
35
+
36
+ 0.3.2
37
+ -----
38
+
39
+ * Perform a blocking system call if we're the only thread running (1.8 only)
40
+ * Run in non-blocking mode if we're the only thread in the process (1.8 only)
41
+ * Make Rev::Loop#run_nonblock signal-safe
42
+ * Fix spurious firing of Rev::AsyncWatchers
43
+
44
+ 0.3.1
45
+ -----
46
+
47
+ * Configurable intervals for Rev::StatWatcher
48
+ * Fix broken version number :(
49
+ * Removed warning about spuriously readable sockets from Rev::Listener
50
+ * Rev::Listener ignores ECONNABORTED from accept_nonblock
51
+ * Document rationale for EAGAIN/ECONNABORTED handling in Rev::Listener
52
+
53
+ 0.3.0
54
+ -----
55
+
56
+ * Add Rev::StatWatcher to monitor filesystem changes
57
+ * Add Rev::Listener#fileno for accessing the underlying file descriptor
58
+ * Support for creating Rev::Listeners from existing TCPServers/UNIXServers
59
+ * Upgrade to libev 3.8
60
+ * Simplified code loading
61
+ * Pull in iobuffer gem and change outstanding uses of Rev::Buffer to IO::Buffer
62
+ * Fix memory leaks resulting from strange semantics of Ruby's xrealloc
63
+ * Rev::UNIXServer: use path instead of the first argument
64
+ * Rev::Server-based classes can build off ::*Server objects
65
+
66
+ 0.2.4
67
+ -----
68
+
69
+ * Ugh, botched my first release from the git repo. Oh well. Try, try again.
70
+
71
+ 0.2.3
72
+ -----
73
+
74
+ * Initial Windows support
75
+ * Initial Ruby 1.8.7 and 1.9.1 support
76
+ * Upgrade to libev 3.52
77
+ * Add checks for sys/resource.h and don't allow getting/setting maxfds if it
78
+ isn't present
79
+
80
+ 0.2.2
81
+ -----
82
+
83
+ * Correct a pointer arithmetic error in the buffering code that could result
84
+ in data corruption.
85
+ * Upgrade to libev 3.41
86
+ * Relax HTTP/1.1 reponse parser to allow the "reason" portion of the response
87
+ header to be omitted
88
+
89
+ 0.2.1
90
+ -----
91
+
92
+ * Upgrade to libev 3.31
93
+ * Rev::Loop#run_once and Rev::Loop#run_nonblock now return the number of events
94
+ received when they were running
95
+ * Remove inheritence relationship between Rev::IO and Rev::IOWatcher
96
+ * Loosen HTTP/1.1 response parser to accept a common malformation in HTTP/1.1
97
+ chunk headers
98
+ * Add underscore prefix to instance variables to avoid conflicts in subclasses
99
+ * Remove Rev::SSLServer until it can be made more useful
100
+
101
+ 0.2.0
102
+ -----
103
+
104
+ * Initial Ruby 1.8.6 support
105
+ * Omit Rev::LIBEV_VERSION constant
106
+ * Catch Errno::ECONNRESET when writing to sockets
107
+ * SSL support via Rev::SSL, with a small C extension subclassing Ruby's
108
+ OpenSSL::SSL::SSLSocket allowing for non-blocking SSL handshakes
109
+ * Initial Rev::Utils implementation with #ncpus and methods to query and
110
+ change the maximum number of file descriptors for the current process.
111
+ * Initial Rev::AsyncWatcher implementation for cross-thread signaling
112
+ * Handle unspecified Content-Length when encoding is identity in HttpClient
113
+ * Fix bug in HttpClient processing zero Content-Length
114
+ * Get rid of method_missing stuff in Rev::HttpClient
115
+ * Have Rev::HttpClient close the connection on error
116
+ * Allow Rev::TCPSocket#on_connect to be private when accepting connections
117
+ from a Rev::TCPServer
118
+
119
+ 0.1.4
120
+ -----
121
+
122
+ * Calibrate Rev::TimerWatchers against ev_time() and ev_now() when the watcher
123
+ is attached to the loop to ensure that the timeout interval is correct.
124
+ * Add check to ensure that a Rev::Loop cannot be run from within a callback
125
+ * Store Rev::Loop.default in a Thread-specific instance variable
126
+ * Upgrade libev to 0.3.0
127
+ * Rename BufferedIO to IO
128
+ * Fixed bug in BufferedIO#write_output_buffer causing it to spin endlessly on
129
+ an empty buffer.
130
+ * Added has_active_watchers? to Rev::Loop to check for active watchers
131
+
132
+ 0.1.3
133
+ -----
134
+
135
+ * Fixed bug in Rev::Buffer read_from and write_to: now rb_sys_fail on failed
136
+ reads/writes.
137
+ * Change Rev::Buffer memory pools to purge on a periodic interval, rather than
138
+ whenever the GC marks the object.
139
+ * Fix bug in tracking the active watcher count. Factor shared watcher behavior
140
+ from rev_watcher.h to rev_watcher.c.
141
+
142
+ 0.1.2
143
+ -----
144
+
145
+ * Commit initial specs
146
+ * Improve RDoc for the library
147
+ * Eliminate "zero copy" writes as they bypass the event loop
148
+ * Added Rev::Buffer C extension to provide high speed buffered writes
149
+ * Implement Rev::TCPSocket#peeraddr to improve compatibility with Ruby sockets
150
+ * Added Rev::Listener.close for clean shutdown of a listener
151
+ * Rev::Loop.default used to call ev_loop_default() (in C). However, this
152
+ registers signal handlers which conflict with Ruby's own. Now the behavior
153
+ has been changed to return a thread-local singleton of Rev::Loop.
154
+ * Creating a new Rev::TCPListener will disable reverse lookups in BasicSocket
155
+ * Made backlog for Rev::TCPListener user-definable
156
+ * Rev::TCPSocket now implements an on_resolve_failed callback for failed DNS
157
+ resolution. By default it's aliased to on_connect_failed.
158
+ * Changed event_callbacks to use instance_exec rather than passing the
159
+ watcher object as an argument. Documented use of defining an event
160
+ callback as a block
161
+ * Subsecond precision for Rev::TimerWatchers
162
+
163
+ 0.1.1
164
+ -----
165
+
166
+ * Added Rev::HttpClient, an asynchronous HTTP/1.1 client written on top of
167
+ the Rev::TCPSocket class
168
+ * Imported HTTP response parser from the RFuzz project
169
+ * Added exception handling for Errno::ECONNRESET and Errno::EAGAIN
170
+ * Fixed bugs in buffered writer which resulted in exceptions if all data
171
+ couldn't be written with a nonblocking write.
172
+
173
+ 0.1.0
174
+ -----
175
+
176
+ * Initial public release
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in cool.io.gemspec
4
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2007-10 Tony Arcieri
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,172 @@
1
+ Cool.io
2
+ =======
3
+
4
+ ### NOTE: cool.io is in maintenance mode only and is not being actively developed
5
+ ### Please check out [Celluloid::IO](http://github.com/celluloid/celluloid-io) instead!
6
+
7
+ Cool.io is an event library for Ruby, built on the libev event library which
8
+ provides a cross-platform interface to high performance system calls . This
9
+ includes the epoll system call for Linux, the kqueue system call for BSDs and
10
+ OS X, and the completion ports interface for Solaris.
11
+
12
+ Cool.io also binds asynchronous wrappers to Ruby's core socket classes so you can
13
+ use them in conjunction with Cool.io to build asynchronous event-driven
14
+ applications.
15
+
16
+ You can include Cool.io in your programs with:
17
+
18
+ require 'rubygems'
19
+ require 'cool.io'
20
+
21
+ Questions? Sign up for the mailing list by emailing: [cool.io@librelist.com](mailto:cool.io@librelist.com)
22
+
23
+ Anatomy
24
+ -------
25
+
26
+ Cool.io builds on two core classes which bind to the libev API:
27
+
28
+ * Cool.io::Loop - This class represents an event loop which uses underlying high
29
+ performance system calls to wait for events.
30
+
31
+ * Cool.io::Watcher - This is the base class for event observers. Once you attach
32
+ an event observer to a loop and start running it, you will begin receiving
33
+ callbacks to particlar methods when events occur.
34
+
35
+ Watchers
36
+ --------
37
+
38
+ There are presently four types of watchers:
39
+
40
+ * Cool.io::IOWatcher - This class waits for an IO object to become readable,
41
+ writable, or both.
42
+
43
+ * Cool.io::TimerWatcher - This class waits for a specified duration then fires
44
+ an event. You can also configure it to fire an event at specified intervals.
45
+
46
+ * Cool.io::StatWatcher - Monitors files or directories for changes
47
+
48
+ * Cool.io::AsyncWatcher - Can be used to wake up a Cool.io::Loop running in a
49
+ different thread. This allows each thread to run a separate Cool.io::Loop and
50
+ for the different event loops to be able to signal each other.
51
+
52
+ Using Watchers
53
+ --------------
54
+
55
+ Watchers have five important methods:
56
+
57
+ * attach(loop) - This binds a watcher to the specified event loop. If the
58
+ watcher is already bound to a loop it will be detached first, then attached
59
+ to the new one.
60
+
61
+ * detach - This completely unbinds a watcher from an event loop.
62
+
63
+ * disable - This stops the watcher from receiving events but does not unbind
64
+ it from the loop. If you are trying to toggle a watcher on and off, it's
65
+ best to use this method (and enable) as it performs better than completely
66
+ removing the watcher from the event loop.
67
+
68
+ * enable - This re-enables a watcher which has been disabled in the past.
69
+ The watcher must still be bound to an event loop.
70
+
71
+ * evloop - This returns the Cool.io::Loop object which the watcher is currently
72
+ bound to.
73
+
74
+ Asynchronous Wrappers
75
+ ---------------------
76
+
77
+ Several classes which provide asynchronous event-driven wrappers for Ruby's
78
+ core socket classes are also provided. Among these are:
79
+
80
+ * Cool.io::TCPSocket - A buffered wrapper to core Ruby's Socket class for use with
81
+ TCP sockets. You can asynchronously create outgoing TCP connections using
82
+ its Cool.io::TCPSocket.connect method. Cool.io::TCPSocket provides write buffering
83
+ to ensure that writing never blocks, and has asynchronous callbacks for
84
+ several events, including when the connection is opened (or failed), when
85
+ data is received, when the write buffer has been written out completely,
86
+ and when the connection closes.
87
+
88
+ * Cool.io::TCPServer - A wrapper for TCPServer which creates new instances of
89
+ Cool.io::TCPSocket (or any subclass you wish to provide) whenever an incoming
90
+ connection is received.
91
+
92
+ * Cool.io::HttpClient - An HTTP/1.1 client with support for chunked encoding
93
+ and streaming response processing through asynchronous callbacks.
94
+
95
+ Example Program
96
+ ---------------
97
+
98
+ Cool.io provides a Sinatra-like DSL for authoring event-driven programs:
99
+
100
+ require 'rubygems'
101
+ require 'cool.io'
102
+
103
+ ADDR = '127.0.0.1'
104
+ PORT = 4321
105
+
106
+ cool.io.connection :echo_server_connection do
107
+ on_connect do
108
+ puts "#{remote_addr}:#{remote_port} connected"
109
+ end
110
+
111
+ on_close do
112
+ puts "#{remote_addr}:#{remote_port} disconnected"
113
+ end
114
+
115
+ on_read do |data|
116
+ write data
117
+ end
118
+ end
119
+
120
+ puts "Echo server listening on #{ADDR}:#{PORT}"
121
+ cool.io.server ADDR, PORT, :echo_server_connection
122
+ cool.io.run
123
+
124
+ This creates a new connection class called :echo_server_connection and defines
125
+ a set of callbacks for when various events occur.
126
+
127
+ We then create a new server on the given address and port. When this server
128
+ receives new connections, it will create new instances of the given connection
129
+ class for each connection.
130
+
131
+ Finally, we kick everything off with cool.io.run. Calling cool.io.run will
132
+ block, listening for events on our server.
133
+
134
+ Using Cool.io subclasses directly
135
+ ---------------------------------
136
+
137
+ Below is an example of how to write an echo server using a subclass instead of
138
+ the DSL:
139
+
140
+ require 'cool.io'
141
+ HOST = 'localhost'
142
+ PORT = 4321
143
+
144
+ class EchoServerConnection < Cool.io::TCPSocket
145
+ def on_connect
146
+ puts "#{remote_addr}:#{remote_port} connected"
147
+ end
148
+
149
+ def on_close
150
+ puts "#{remote_addr}:#{remote_port} disconnected"
151
+ end
152
+
153
+ def on_read(data)
154
+ write data
155
+ end
156
+ end
157
+
158
+ server = Cool.io::TCPServer.new(HOST, PORT, EchoServerConnection)
159
+ server.attach(Cool.io::Loop.default)
160
+
161
+ puts "Echo server listening on #{HOST}:#{PORT}"
162
+ Cool.io::Loop.default.run
163
+
164
+ Here a new observer type (EchoServerConnection) is made by subclassing an
165
+ existing one and adding new implementations to existing event handlers.
166
+
167
+ A new event loop is created, and a new Cool.io::TCPServer (whose base class is
168
+ Cool.io::Watcher) is created and attached to the event loop.
169
+
170
+ Once this is done, the event loop is started with event_loop.run. This method
171
+ will block until there are no active watchers for the loop or the loop is
172
+ stopped explicitly with event_loop.stop.
@@ -0,0 +1,81 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'rake/clean'
3
+
4
+ require 'rspec/core/rake_task'
5
+ RSpec::Core::RakeTask.new
6
+
7
+ RSpec::Core::RakeTask.new(:rcov) do |task|
8
+ task.rcov = true
9
+ end
10
+
11
+ task :default => %w(compile spec)
12
+
13
+ require 'rdoc/task'
14
+ Rake::RDocTask.new do |rdoc|
15
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
16
+
17
+ rdoc.rdoc_dir = 'rdoc'
18
+ rdoc.title = "cool.io #{version}"
19
+ rdoc.rdoc_files.include('README*')
20
+ rdoc.rdoc_files.include('lib/**/*.rb')
21
+ end
22
+
23
+ require 'rake/extensiontask'
24
+
25
+ spec = eval(File.read("cool.io.gemspec"))
26
+
27
+ def configure_cross_compilation(ext)
28
+ unless RUBY_PLATFORM =~ /mswin|mingw/
29
+ ext.cross_compile = true
30
+ ext.cross_platform = 'i386-mingw32'#['i386-mswin32-60', 'i386-mingw32']
31
+ end
32
+ end
33
+
34
+ Rake::ExtensionTask.new('iobuffer_ext', spec) do |ext|
35
+ ext.ext_dir = 'ext/iobuffer'
36
+ configure_cross_compilation(ext)
37
+ end
38
+
39
+ Rake::ExtensionTask.new('http11_client', spec) do |ext|
40
+ ext.ext_dir = 'ext/http11_client'
41
+ configure_cross_compilation(ext)
42
+ end
43
+
44
+ Rake::ExtensionTask.new('cool.io_ext', spec) do |ext|
45
+ ext.ext_dir = 'ext/cool.io'
46
+ configure_cross_compilation(ext)
47
+ end
48
+
49
+ # Rebuild parser Ragel
50
+ task :http11_parser do
51
+ Dir.chdir "ext/http11_client" do
52
+ target = "http11_parser.c"
53
+ File.unlink target if File.exist? target
54
+ sh "ragel http11_parser.rl | rlgen-cd -G2 -o #{target}"
55
+ raise "Failed to build C source" unless File.exist? target
56
+ end
57
+ end
58
+
59
+ # adapted from http://flavoriffic.blogspot.com/2009/06/easily-valgrind-gdb-your-ruby-c.html
60
+ def specs_command
61
+ require "find"
62
+ files = []
63
+ Find.find("spec") do |f|
64
+ files << f if File.basename(f) =~ /.*spec.*\.rb$/
65
+ end
66
+ cmdline = "#{RUBY} -I.:lib:ext:spec \
67
+ -e '%w[#{files.join(' ')}].each { |f| require f }'"
68
+ end
69
+
70
+ namespace :spec do
71
+ desc "run specs with valgrind"
72
+ task :valgrind => :compile do
73
+ system "valgrind --num-callers=15 \
74
+ --partial-loads-ok=yes --undef-value-errors=no \
75
+ --tool=memcheck --leak-check=yes --track-fds=yes \
76
+ --show-reachable=yes #{specs_command}"
77
+ end
78
+ end
79
+
80
+ CLEAN.include "**/*.rbc", "**/*.o", "**/*.so", "**/*.bundle"
81
+ CLEAN.exclude "vendor/**/*.rbc", "vendor/**/*.o", "vendor/**/*.so", "vendor/**/*.bundle"