fluentd 0.10.46 → 0.10.47
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of fluentd might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/.travis.yml +5 -2
- data/ChangeLog +9 -0
- data/lib/fluent/command/fluentd.rb +2 -15
- data/lib/fluent/config/basic_parser.rb +4 -0
- data/lib/fluent/config/types.rb +2 -0
- data/lib/fluent/config/v1_parser.rb +8 -4
- data/lib/fluent/log.rb +3 -1
- data/lib/fluent/plugin/in_forward.rb +36 -5
- data/lib/fluent/plugin/in_monitor_agent.rb +45 -0
- data/lib/fluent/plugin/in_tail.rb +1 -1
- data/lib/fluent/supervisor.rb +30 -1
- data/lib/fluent/test.rb +0 -2
- data/lib/fluent/test/base.rb +41 -0
- data/lib/fluent/version.rb +1 -1
- data/spec/config/config_parser_spec.rb +7 -0
- data/test/helper.rb +2 -1
- data/test/plugin/test_in_forward.rb +87 -0
- metadata +2 -3
- data/.rvmrc +0 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2fe2bff2ce1a5aecb6cee52438d601388c2aa896
|
4
|
+
data.tar.gz: f8aed6a81a228824681acde0c7f38656c4ea17b8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 59337e23670288e3d11cbbf954d2601cd79d6f32b9cb008ffd94c3b59f5e1a5272774be6640d0a7c2af2fef26cca690e88422752d35f9b64beae2383627eb297
|
7
|
+
data.tar.gz: 1ed344c08218d378a029dc575083fd1217b1c227a38030e9907eca5b8d445e534bc04e7e068c0a79c8cb4324cc015568174e761ef3dcc3b347db1e91a239cf1b
|
data/.travis.yml
CHANGED
data/ChangeLog
CHANGED
@@ -1,3 +1,12 @@
|
|
1
|
+
Release 0.10.47 - 2014/05/15
|
2
|
+
|
3
|
+
* in_tail: Fix typo in flush_buffer
|
4
|
+
* in_forward: Add chunk_size_warn_limit and chunk_size_limit for large chunks
|
5
|
+
* in_monitor_agent: Add /api/config APIs to expose Fluentd configurations
|
6
|
+
* supervisor: Add Supervisor.default_options to return default Fluentd options
|
7
|
+
* test: Add DummyLogDevise and improve log handling in tests
|
8
|
+
* config: Allow empty string value like `tag_mapped` in v1 configuration
|
9
|
+
|
1
10
|
Release 0.10.46 - 2014/04/21
|
2
11
|
|
3
12
|
* in_tail: Fix typo in rescue for dumping backtrace
|
@@ -19,26 +19,13 @@
|
|
19
19
|
require 'optparse'
|
20
20
|
require 'fluent/log'
|
21
21
|
require 'fluent/env'
|
22
|
+
require 'fluent/supervisor'
|
22
23
|
require 'fluent/version'
|
23
24
|
|
24
25
|
op = OptionParser.new
|
25
26
|
op.version = Fluent::VERSION
|
26
27
|
|
27
|
-
|
28
|
-
opts = {
|
29
|
-
:config_path => Fluent::DEFAULT_CONFIG_PATH,
|
30
|
-
:plugin_dirs => [Fluent::DEFAULT_PLUGIN_DIR],
|
31
|
-
:log_level => Fluent::Log::LEVEL_INFO,
|
32
|
-
:log_path => nil,
|
33
|
-
:daemonize => false,
|
34
|
-
:libs => [],
|
35
|
-
:setup_path => nil,
|
36
|
-
:chuser => nil,
|
37
|
-
:chgroup => nil,
|
38
|
-
:suppress_interval => 0,
|
39
|
-
:suppress_repeated_stacktrace => false,
|
40
|
-
:use_v1_config => false,
|
41
|
-
}
|
28
|
+
opts = Fluent::Supervisor.default_options
|
42
29
|
|
43
30
|
op.on('-s', "--setup [DIR=#{File.dirname(Fluent::DEFAULT_CONFIG_PATH)}]", "install sample configuration file to the directory") {|s|
|
44
31
|
opts[:setup_path] = s || File.dirname(Fluent::DEFAULT_CONFIG_PATH)
|
data/lib/fluent/config/types.rb
CHANGED
@@ -102,11 +102,15 @@ module Fluent
|
|
102
102
|
else
|
103
103
|
k = scan_string(SPACING)
|
104
104
|
spacing
|
105
|
-
|
106
|
-
|
107
|
-
|
105
|
+
if prev_match.include?("\n") # support 'tag_mapped' like "without value" configuration
|
106
|
+
attrs[k] = ""
|
107
|
+
else
|
108
|
+
v = parse_literal
|
109
|
+
unless line_end
|
110
|
+
parse_error! "expected end of line"
|
111
|
+
end
|
112
|
+
attrs[k] = v
|
108
113
|
end
|
109
|
-
attrs[k] = v
|
110
114
|
end
|
111
115
|
end
|
112
116
|
|
data/lib/fluent/log.rb
CHANGED
@@ -34,6 +34,9 @@ module Fluent
|
|
34
34
|
# This option is for Cool.io's loop wait timeout to avoid loop stuck at shutdown. Almost users don't need to change this value.
|
35
35
|
config_param :blocking_timeout, :time, :default => 0.5
|
36
36
|
|
37
|
+
config_param :chunk_size_warn_limit, :size, :default => nil
|
38
|
+
config_param :chunk_size_limit, :size, :default => nil
|
39
|
+
|
37
40
|
def configure(conf)
|
38
41
|
super
|
39
42
|
end
|
@@ -122,7 +125,7 @@ module Fluent
|
|
122
125
|
# 2: long? time
|
123
126
|
# 3: object record
|
124
127
|
# }
|
125
|
-
def on_message(msg)
|
128
|
+
def on_message(msg, chunk_size, source)
|
126
129
|
if msg.nil?
|
127
130
|
# for future TCP heartbeat_request
|
128
131
|
return
|
@@ -132,6 +135,13 @@ module Fluent
|
|
132
135
|
tag = msg[0].to_s
|
133
136
|
entries = msg[1]
|
134
137
|
|
138
|
+
if @chunk_size_limit && (chunk_size > @chunk_size_limit)
|
139
|
+
log.warn "Input chunk size is larger than 'chunk_size_limit', dropped:", tag: tag, source: source, limit: @chunk_size_limit, size: chunk_size
|
140
|
+
return
|
141
|
+
elsif @chunk_size_warn_limit && (chunk_size > @chunk_size_warn_limit)
|
142
|
+
log.warn "Input chunk size is larger than 'chunk_size_warn_limit':", tag: tag, source: source, limit: @chunk_size_warn_limit, size: chunk_size
|
143
|
+
end
|
144
|
+
|
135
145
|
if entries.class == String
|
136
146
|
# PackedForward
|
137
147
|
es = MessagePackEventStream.new(entries, @cached_unpacker)
|
@@ -160,16 +170,29 @@ module Fluent
|
|
160
170
|
end
|
161
171
|
|
162
172
|
class Handler < Coolio::Socket
|
173
|
+
PEERADDR_FAILED = ["?", "?", "name resolusion failed", "?"]
|
174
|
+
|
163
175
|
def initialize(io, linger_timeout, log, on_message)
|
164
176
|
super(io)
|
165
|
-
|
177
|
+
|
178
|
+
if io.is_a?(TCPSocket) # for unix domain socket support in the future
|
179
|
+
proto, port, host, addr = ( io.peeraddr rescue PEERADDR_FAILED )
|
180
|
+
@source = "host: #{host}, addr: #{addr}, port: #{port}"
|
181
|
+
|
166
182
|
opt = [1, linger_timeout].pack('I!I!') # { int l_onoff; int l_linger; }
|
167
183
|
io.setsockopt(Socket::SOL_SOCKET, Socket::SO_LINGER, opt)
|
168
184
|
end
|
185
|
+
|
186
|
+
@chunk_counter = 0
|
169
187
|
@on_message = on_message
|
170
188
|
@log = log
|
171
189
|
@log.trace {
|
172
|
-
|
190
|
+
begin
|
191
|
+
remote_port, remote_addr = *Socket.unpack_sockaddr_in(@_io.getpeername)
|
192
|
+
rescue => e
|
193
|
+
remote_port = nil
|
194
|
+
remote_addr = nil
|
195
|
+
end
|
173
196
|
"accepted fluent socket from '#{remote_addr}:#{remote_port}': object_id=#{self.object_id}"
|
174
197
|
}
|
175
198
|
end
|
@@ -182,7 +205,10 @@ module Fluent
|
|
182
205
|
if first == '{' || first == '['
|
183
206
|
m = method(:on_read_json)
|
184
207
|
@y = Yajl::Parser.new
|
185
|
-
@y.on_parse_complete =
|
208
|
+
@y.on_parse_complete = lambda { |obj|
|
209
|
+
@on_message.call(obj, @chunk_counter, @source)
|
210
|
+
@chunk_counter = 0
|
211
|
+
}
|
186
212
|
else
|
187
213
|
m = method(:on_read_msgpack)
|
188
214
|
@u = MessagePack::Unpacker.new
|
@@ -195,6 +221,7 @@ module Fluent
|
|
195
221
|
end
|
196
222
|
|
197
223
|
def on_read_json(data)
|
224
|
+
@chunk_counter += data.bytesize
|
198
225
|
@y << data
|
199
226
|
rescue => e
|
200
227
|
@log.error "forward error", :error => e, :error_class => e.class
|
@@ -203,7 +230,11 @@ module Fluent
|
|
203
230
|
end
|
204
231
|
|
205
232
|
def on_read_msgpack(data)
|
206
|
-
@
|
233
|
+
@chunk_counter += data.bytesize
|
234
|
+
@u.feed_each(data) do |obj|
|
235
|
+
@on_message.call(obj, @chunk_counter, @source)
|
236
|
+
@chunk_counter = 0
|
237
|
+
end
|
207
238
|
rescue => e
|
208
239
|
@log.error "forward error", :error => e, :error_class => e.class
|
209
240
|
@log.error_backtrace
|
@@ -153,6 +153,36 @@ module Fluent
|
|
153
153
|
end
|
154
154
|
end
|
155
155
|
|
156
|
+
class ConfigMonitorServlet < MonitorServlet
|
157
|
+
def build_object(req, res)
|
158
|
+
{
|
159
|
+
'pid' => Process.pid,
|
160
|
+
'ppid' => Process.ppid
|
161
|
+
}.merge(@agent.fluentd_opts)
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
class LTSVConfigMonitorServlet < ConfigMonitorServlet
|
166
|
+
def process(req, res)
|
167
|
+
result = build_object(req, res)
|
168
|
+
|
169
|
+
row = []
|
170
|
+
JSON.parse(result.to_json).each_pair { |k, v|
|
171
|
+
row << "#{k}:#{v}"
|
172
|
+
}
|
173
|
+
text = row.join("\t")
|
174
|
+
|
175
|
+
[200, {'Content-Type'=>'text/plain'}, text]
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
179
|
+
class JSONConfigMonitorServlet < ConfigMonitorServlet
|
180
|
+
def process(req, res)
|
181
|
+
result = build_object(req, res)
|
182
|
+
render_json(result)
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
156
186
|
def start
|
157
187
|
log.debug "listening monitoring http server on http://#{@bind}:#{@port}/api/plugins"
|
158
188
|
@srv = WEBrick::HTTPServer.new({
|
@@ -163,6 +193,8 @@ module Fluent
|
|
163
193
|
})
|
164
194
|
@srv.mount('/api/plugins', LTSVMonitorServlet, self)
|
165
195
|
@srv.mount('/api/plugins.json', JSONMonitorServlet, self)
|
196
|
+
@srv.mount('/api/config', LTSVConfigMonitorServlet, self)
|
197
|
+
@srv.mount('/api/config.json', JSONConfigMonitorServlet, self)
|
166
198
|
@thread = Thread.new {
|
167
199
|
@srv.start
|
168
200
|
}
|
@@ -282,5 +314,18 @@ module Fluent
|
|
282
314
|
|
283
315
|
obj
|
284
316
|
end
|
317
|
+
|
318
|
+
def fluentd_opts
|
319
|
+
@fluentd_opts ||= get_fluentd_opts
|
320
|
+
end
|
321
|
+
|
322
|
+
def get_fluentd_opts
|
323
|
+
opts = {}
|
324
|
+
ObjectSpace.each_object(Fluent::Supervisor) { |obj|
|
325
|
+
opts.merge!(obj.options)
|
326
|
+
break
|
327
|
+
}
|
328
|
+
opts
|
329
|
+
end
|
285
330
|
end
|
286
331
|
end
|
data/lib/fluent/supervisor.rb
CHANGED
@@ -15,6 +15,10 @@
|
|
15
15
|
# See the License for the specific language governing permissions and
|
16
16
|
# limitations under the License.
|
17
17
|
#
|
18
|
+
|
19
|
+
require 'fluent/env'
|
20
|
+
require 'fluent/log'
|
21
|
+
|
18
22
|
module Fluent
|
19
23
|
class Supervisor
|
20
24
|
class LoggerInitializer
|
@@ -56,6 +60,23 @@ module Fluent
|
|
56
60
|
end
|
57
61
|
end
|
58
62
|
|
63
|
+
def self.default_options
|
64
|
+
{
|
65
|
+
:config_path => Fluent::DEFAULT_CONFIG_PATH,
|
66
|
+
:plugin_dirs => [Fluent::DEFAULT_PLUGIN_DIR],
|
67
|
+
:log_level => Fluent::Log::LEVEL_INFO,
|
68
|
+
:log_path => nil,
|
69
|
+
:daemonize => nil,
|
70
|
+
:libs => [],
|
71
|
+
:setup_path => nil,
|
72
|
+
:chuser => nil,
|
73
|
+
:chgroup => nil,
|
74
|
+
:suppress_interval => 0,
|
75
|
+
:suppress_repeated_stacktrace => false,
|
76
|
+
:use_v1_config => false,
|
77
|
+
}
|
78
|
+
end
|
79
|
+
|
59
80
|
def initialize(opt)
|
60
81
|
@config_path = opt[:config_path]
|
61
82
|
@log_path = opt[:log_path]
|
@@ -99,6 +120,15 @@ module Fluent
|
|
99
120
|
end
|
100
121
|
end
|
101
122
|
|
123
|
+
def options
|
124
|
+
{
|
125
|
+
'config_path' => @config_path,
|
126
|
+
'pid_file' => @daemonize,
|
127
|
+
'plugin_dirs' => @plugin_dirs,
|
128
|
+
'log_path' => @log_path
|
129
|
+
}
|
130
|
+
end
|
131
|
+
|
102
132
|
private
|
103
133
|
|
104
134
|
def dry_run
|
@@ -388,4 +418,3 @@ module Fluent
|
|
388
418
|
end
|
389
419
|
end
|
390
420
|
end
|
391
|
-
|
data/lib/fluent/test.rb
CHANGED
data/lib/fluent/test/base.rb
CHANGED
@@ -32,6 +32,8 @@ module Fluent
|
|
32
32
|
else
|
33
33
|
@instance = klass
|
34
34
|
end
|
35
|
+
@instance.log = TestLogger.new
|
36
|
+
|
35
37
|
@config = Config.new
|
36
38
|
end
|
37
39
|
|
@@ -58,5 +60,44 @@ module Fluent
|
|
58
60
|
end
|
59
61
|
end
|
60
62
|
end
|
63
|
+
|
64
|
+
class DummyLogDevice
|
65
|
+
attr_reader :logs
|
66
|
+
|
67
|
+
def initialize
|
68
|
+
@logs = []
|
69
|
+
end
|
70
|
+
|
71
|
+
def tty?
|
72
|
+
false
|
73
|
+
end
|
74
|
+
|
75
|
+
def puts(*args)
|
76
|
+
args.each{ |arg| write(arg + "\n") }
|
77
|
+
end
|
78
|
+
|
79
|
+
def write(message)
|
80
|
+
@logs.push message
|
81
|
+
end
|
82
|
+
|
83
|
+
def flush
|
84
|
+
true
|
85
|
+
end
|
86
|
+
|
87
|
+
def close
|
88
|
+
true
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
class TestLogger < Fluent::PluginLogger
|
93
|
+
def initialize
|
94
|
+
@logdev = DummyLogDevice.new
|
95
|
+
super(Fluent::Log.new(@logdev))
|
96
|
+
end
|
97
|
+
|
98
|
+
def logs
|
99
|
+
@logdev.logs
|
100
|
+
end
|
101
|
+
end
|
61
102
|
end
|
62
103
|
end
|
data/lib/fluent/version.rb
CHANGED
@@ -34,6 +34,13 @@ describe Fluent::Config::V1Parser do
|
|
34
34
|
].should be_parsed_as("k1"=>"v1", "k2"=>"v2")
|
35
35
|
end
|
36
36
|
|
37
|
+
it "allows attribute without value" do
|
38
|
+
%[
|
39
|
+
k1
|
40
|
+
k2 v2
|
41
|
+
].should be_parsed_as("k1"=>"", "k2"=>"v2")
|
42
|
+
end
|
43
|
+
|
37
44
|
it "parses attribute key always string" do
|
38
45
|
"1 1".should be_parsed_as("1" => "1")
|
39
46
|
end
|
data/test/helper.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
require 'test/unit'
|
2
2
|
require 'fileutils'
|
3
3
|
require 'fluent/log'
|
4
|
+
require 'fluent/test'
|
4
5
|
require 'rr'
|
5
6
|
|
6
7
|
unless defined?(Test::Unit::AssertionFailedError)
|
@@ -26,4 +27,4 @@ def ipv6_enabled?
|
|
26
27
|
end
|
27
28
|
end
|
28
29
|
|
29
|
-
$log = Fluent::Log.new(
|
30
|
+
$log = Fluent::Log.new(Fluent::Test::DummyLogDevice.new, Fluent::Log::LEVEL_WARN)
|
@@ -116,6 +116,93 @@ class ForwardInputTest < Test::Unit::TestCase
|
|
116
116
|
end
|
117
117
|
end
|
118
118
|
|
119
|
+
def test_send_large_chunk_warning
|
120
|
+
d = create_driver(CONFIG + %[
|
121
|
+
chunk_size_warn_limit 16M
|
122
|
+
chunk_size_limit 32M
|
123
|
+
])
|
124
|
+
|
125
|
+
time = Time.parse("2014-04-25 13:14:15 UTC").to_i
|
126
|
+
|
127
|
+
# generate over 16M chunk
|
128
|
+
str = "X" * 1024 * 1024
|
129
|
+
chunk = [ "test.tag", (0...16).map{|i| [time + i, {"data" => str}] } ].to_msgpack
|
130
|
+
assert chunk.size > (16 * 1024 * 1024)
|
131
|
+
assert chunk.size < (32 * 1024 * 1024)
|
132
|
+
|
133
|
+
d.run do
|
134
|
+
MessagePack::Unpacker.new.feed_each(chunk) do |obj|
|
135
|
+
d.instance.send(:on_message, obj, chunk.size, "host: 127.0.0.1, addr: 127.0.0.1, port: 0000")
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
# check emitted data
|
140
|
+
emits = d.emits
|
141
|
+
assert_equal 16, emits.size
|
142
|
+
assert emits.map(&:first).all?{|t| t == "test.tag" }
|
143
|
+
assert_equal (0...16).to_a, emits.map{|tag, t, record| t - time }
|
144
|
+
|
145
|
+
# check log
|
146
|
+
assert d.instance.log.logs.select{|line|
|
147
|
+
line =~ / \[warn\]: Input chunk size is larger than 'chunk_size_warn_limit':/ &&
|
148
|
+
line =~ / tag="test.tag" source="host: 127.0.0.1, addr: 127.0.0.1, port: \d+" limit=16777216 size=16777501/
|
149
|
+
}.size == 1, "large chunk warning is not logged"
|
150
|
+
end
|
151
|
+
|
152
|
+
def test_send_large_chunk_only_warning
|
153
|
+
d = create_driver(CONFIG + %[
|
154
|
+
chunk_size_warn_limit 16M
|
155
|
+
])
|
156
|
+
time = Time.parse("2014-04-25 13:14:15 UTC").to_i
|
157
|
+
|
158
|
+
# generate over 16M chunk
|
159
|
+
str = "X" * 1024 * 1024
|
160
|
+
chunk = [ "test.tag", (0...16).map{|i| [time + i, {"data" => str}] } ].to_msgpack
|
161
|
+
|
162
|
+
d.run do
|
163
|
+
MessagePack::Unpacker.new.feed_each(chunk) do |obj|
|
164
|
+
d.instance.send(:on_message, obj, chunk.size, "host: 127.0.0.1, addr: 127.0.0.1, port: 0000")
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
# check log
|
169
|
+
assert d.instance.log.logs.select{ |line|
|
170
|
+
line =~ / \[warn\]: Input chunk size is larger than 'chunk_size_warn_limit':/ &&
|
171
|
+
line =~ / tag="test.tag" source="host: 127.0.0.1, addr: 127.0.0.1, port: \d+" limit=16777216 size=16777501/
|
172
|
+
}.size == 1, "large chunk warning is not logged"
|
173
|
+
end
|
174
|
+
|
175
|
+
def test_send_large_chunk_limit
|
176
|
+
d = create_driver(CONFIG + %[
|
177
|
+
chunk_size_warn_limit 16M
|
178
|
+
chunk_size_limit 32M
|
179
|
+
])
|
180
|
+
|
181
|
+
time = Time.parse("2014-04-25 13:14:15 UTC").to_i
|
182
|
+
|
183
|
+
# generate over 32M chunk
|
184
|
+
str = "X" * 1024 * 1024
|
185
|
+
chunk = [ "test.tag", (0...32).map{|i| [time + i, {"data" => str}] } ].to_msgpack
|
186
|
+
assert chunk.size > (32 * 1024 * 1024)
|
187
|
+
|
188
|
+
# d.run => send_data
|
189
|
+
d.run do
|
190
|
+
MessagePack::Unpacker.new.feed_each(chunk) do |obj|
|
191
|
+
d.instance.send(:on_message, obj, chunk.size, "host: 127.0.0.1, addr: 127.0.0.1, port: 0000")
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
195
|
+
# check emitted data
|
196
|
+
emits = d.emits
|
197
|
+
assert_equal 0, emits.size
|
198
|
+
|
199
|
+
# check log
|
200
|
+
assert d.instance.log.logs.select{|line|
|
201
|
+
line =~ / \[warn\]: Input chunk size is larger than 'chunk_size_limit', dropped:/ &&
|
202
|
+
line =~ / tag="test.tag" source="host: 127.0.0.1, addr: 127.0.0.1, port: \d+" limit=33554432 size=33554989/
|
203
|
+
}.size == 1, "large chunk warning is not logged"
|
204
|
+
end
|
205
|
+
|
119
206
|
def send_data(data)
|
120
207
|
io = connect
|
121
208
|
begin
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fluentd
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.10.
|
4
|
+
version: 0.10.47
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sadayuki Furuhashi
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-05-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: msgpack
|
@@ -253,7 +253,6 @@ extensions: []
|
|
253
253
|
extra_rdoc_files: []
|
254
254
|
files:
|
255
255
|
- ".gitignore"
|
256
|
-
- ".rvmrc"
|
257
256
|
- ".travis.yml"
|
258
257
|
- AUTHORS
|
259
258
|
- COPYING
|
data/.rvmrc
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
rvm 1.9.3
|