fluentd 0.14.12 → 0.14.13
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/CONTRIBUTING.md +2 -0
- data/ChangeLog +33 -0
- data/bin/fluent-plugin-config-format +5 -0
- data/bin/fluent-plugin-generate +5 -0
- data/lib/fluent/command/plugin_config_formatter.rb +258 -0
- data/lib/fluent/command/plugin_generator.rb +301 -0
- data/lib/fluent/compat/detach_process_mixin.rb +25 -0
- data/lib/fluent/compat/filter.rb +1 -1
- data/lib/fluent/compat/input.rb +1 -0
- data/lib/fluent/compat/output.rb +8 -5
- data/lib/fluent/config/configure_proxy.rb +31 -8
- data/lib/fluent/configurable.rb +2 -2
- data/lib/fluent/output.rb +3 -0
- data/lib/fluent/plugin/buffer/file_chunk.rb +52 -11
- data/lib/fluent/plugin/filter.rb +1 -1
- data/lib/fluent/plugin/filter_record_transformer.rb +5 -1
- data/lib/fluent/plugin/in_tail.rb +13 -6
- data/lib/fluent/plugin/input.rb +1 -1
- data/lib/fluent/plugin/output.rb +26 -6
- data/lib/fluent/plugin/parser_apache.rb +1 -1
- data/lib/fluent/plugin/parser_apache_error.rb +1 -1
- data/lib/fluent/plugin/parser_multiline.rb +1 -0
- data/lib/fluent/plugin/parser_nginx.rb +1 -1
- data/lib/fluent/plugin/parser_regexp.rb +18 -0
- data/lib/fluent/plugin_helper.rb +19 -1
- data/lib/fluent/plugin_helper/retry_state.rb +40 -16
- data/lib/fluent/process.rb +22 -0
- data/lib/fluent/supervisor.rb +2 -21
- data/lib/fluent/test/helpers.rb +14 -0
- data/lib/fluent/version.rb +1 -1
- data/templates/new_gem/Gemfile +3 -0
- data/templates/new_gem/README.md.erb +43 -0
- data/templates/new_gem/Rakefile +13 -0
- data/templates/new_gem/fluent-plugin.gemspec.erb +27 -0
- data/templates/new_gem/lib/fluent/plugin/filter.rb.erb +14 -0
- data/templates/new_gem/lib/fluent/plugin/formatter.rb.erb +14 -0
- data/templates/new_gem/lib/fluent/plugin/input.rb.erb +11 -0
- data/templates/new_gem/lib/fluent/plugin/output.rb.erb +11 -0
- data/templates/new_gem/lib/fluent/plugin/parser.rb.erb +15 -0
- data/templates/new_gem/test/helper.rb.erb +8 -0
- data/templates/new_gem/test/plugin/test_filter.rb.erb +18 -0
- data/templates/new_gem/test/plugin/test_formatter.rb.erb +18 -0
- data/templates/new_gem/test/plugin/test_input.rb.erb +18 -0
- data/templates/new_gem/test/plugin/test_output.rb.erb +18 -0
- data/templates/new_gem/test/plugin/test_parser.rb.erb +18 -0
- data/templates/plugin_config_formatter/param.md-compact.erb +25 -0
- data/templates/plugin_config_formatter/param.md.erb +34 -0
- data/templates/plugin_config_formatter/section.md.erb +12 -0
- data/test/command/test_binlog_reader.rb +0 -9
- data/test/command/test_plugin_config_formatter.rb +275 -0
- data/test/command/test_plugin_generator.rb +66 -0
- data/test/config/test_configure_proxy.rb +89 -45
- data/test/plugin/data/log/foo/bar2 +0 -0
- data/test/plugin/test_in_tail.rb +97 -8
- data/test/plugin/test_output.rb +18 -0
- data/test/plugin/test_output_as_buffered.rb +35 -0
- data/test/plugin_helper/test_compat_parameters.rb +2 -0
- data/test/plugin_helper/test_retry_state.rb +23 -0
- data/test/test_output.rb +5 -0
- data/test/test_process.rb +14 -0
- metadata +37 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 158d62963384d98d44438e5f3a8e31c97f3124e4
|
4
|
+
data.tar.gz: 59a98cfbf508e67e462849f8ada07a509255f8bf
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: bf8ab978620b5472988d8483828a9b6e5004e5028b86165b31628810c93d15f591b07fd24e0f6f9929b9390bd8de7ccb1035eeb6d389c8b862638a1325f8fc6a
|
7
|
+
data.tar.gz: 52257e481b34bddce80b2c7f7442328f704f0b11ee1c3495fa895dea4902040ff3eec6ad65c62a261dcb659c5f48bd3cd0455abe045c860259dad420d1b2f9e5
|
data/CONTRIBUTING.md
CHANGED
@@ -16,6 +16,8 @@ Don't use Github issue for asking questions. Here are examples:
|
|
16
16
|
We may close such questions to keep clear repository for developers and users.
|
17
17
|
Github issue is mainly for submitting a bug report or feature request. See below.
|
18
18
|
|
19
|
+
If you can't judge your case is a bug or not, use mailing list or slack first.
|
20
|
+
|
19
21
|
## Found a bug?
|
20
22
|
|
21
23
|
If you find a bug of Fluentd or a mistake in the documentation, you can help us by
|
data/ChangeLog
CHANGED
@@ -1,5 +1,38 @@
|
|
1
1
|
# v0.14
|
2
2
|
|
3
|
+
## Release v0.14.13 - 2017/02/17
|
4
|
+
|
5
|
+
### New features / Enhancements
|
6
|
+
|
7
|
+
* in_tail: Add 'limit_recently_modified' to limit watch files.
|
8
|
+
https://github.com/fluent/fluentd/pull/1474
|
9
|
+
* configuration: Improve 'flush_interval' handling for better message and backward compatibility
|
10
|
+
https://github.com/fluent/fluentd/pull/1442
|
11
|
+
* command: Add 'fluent-plugin-generate' command
|
12
|
+
https://github.com/fluent/fluentd/pull/1427
|
13
|
+
* output: Skip record when 'Output#format' returns nil
|
14
|
+
https://github.com/fluent/fluentd/pull/1469
|
15
|
+
|
16
|
+
### Bug fixes
|
17
|
+
|
18
|
+
* output: Secondary calculation should consider 'retry_max_times'
|
19
|
+
https://github.com/fluent/fluentd/pull/1452
|
20
|
+
* Fix regression of deprecatd 'process' module
|
21
|
+
https://github.com/fluent/fluentd/pull/1443
|
22
|
+
* Fix missing parser_regex require
|
23
|
+
https://github.com/fluent/fluentd/issues/1458
|
24
|
+
https://github.com/fluent/fluentd/pull/1453
|
25
|
+
* Keep 'Fluent::BufferQueueLimitError' for exsting plugins
|
26
|
+
https://github.com/fluent/fluentd/pull/1456
|
27
|
+
* in_tail: Untracked files should be removed from watching list to avoid memory bloat
|
28
|
+
https://github.com/fluent/fluentd/pull/1467
|
29
|
+
* in_tail: directories should be skipped when the ** pattern is used
|
30
|
+
https://github.com/fluent/fluentd/pull/1464
|
31
|
+
* record_transformer: Revert "Use BasicObject for cleanroom" for `enable_ruby` regression.
|
32
|
+
https://github.com/fluent/fluentd/pull/1461
|
33
|
+
* buf_file: handle "Too many open files" error to keep buffer and metadata pair
|
34
|
+
https://github.com/fluent/fluentd/pull/1468
|
35
|
+
|
3
36
|
## Release v0.14.12 - 2017/01/30
|
4
37
|
|
5
38
|
### New features / Enhancements
|
@@ -0,0 +1,258 @@
|
|
1
|
+
#
|
2
|
+
# Fluentd
|
3
|
+
#
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
# you may not use this file except in compliance with the License.
|
6
|
+
# You may obtain a copy of the License at
|
7
|
+
#
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
#
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
# See the License for the specific language governing permissions and
|
14
|
+
# limitations under the License.
|
15
|
+
#
|
16
|
+
|
17
|
+
require "erb"
|
18
|
+
require "optparse"
|
19
|
+
require "pathname"
|
20
|
+
require "fluent/plugin"
|
21
|
+
require "fluent/env"
|
22
|
+
require "fluent/engine"
|
23
|
+
require "fluent/system_config"
|
24
|
+
require "fluent/config/element"
|
25
|
+
|
26
|
+
class FluentPluginConfigFormatter
|
27
|
+
|
28
|
+
AVAILABLE_FORMATS = [:markdown, :txt, :json]
|
29
|
+
SUPPORTED_TYPES = [
|
30
|
+
"input", "output", "filter",
|
31
|
+
"buffer", "parser", "formatter", "storage"
|
32
|
+
]
|
33
|
+
|
34
|
+
def initialize(argv = ARGV)
|
35
|
+
@argv = argv
|
36
|
+
|
37
|
+
@compact = false
|
38
|
+
@format = :markdown
|
39
|
+
@verbose = false
|
40
|
+
@libs = []
|
41
|
+
@plugin_dirs = []
|
42
|
+
@options = {}
|
43
|
+
|
44
|
+
prepare_option_parser
|
45
|
+
end
|
46
|
+
|
47
|
+
def call
|
48
|
+
parse_options!
|
49
|
+
init_libraries
|
50
|
+
@plugin = Fluent::Plugin.__send__("new_#{@plugin_type}", @plugin_name)
|
51
|
+
dumped_config = {}
|
52
|
+
if @plugin.class.respond_to?(:plugin_helpers)
|
53
|
+
dumped_config[:plugin_helpers] = @plugin.class.plugin_helpers
|
54
|
+
end
|
55
|
+
@plugin.class.ancestors.reverse_each do |plugin_class|
|
56
|
+
next unless plugin_class.respond_to?(:dump_config_definition)
|
57
|
+
unless @verbose
|
58
|
+
next if plugin_class.name =~ /::PluginHelper::/
|
59
|
+
end
|
60
|
+
dumped_config_definition = plugin_class.dump_config_definition
|
61
|
+
dumped_config[plugin_class.name] = dumped_config_definition unless dumped_config_definition.empty?
|
62
|
+
end
|
63
|
+
case @format
|
64
|
+
when :txt
|
65
|
+
puts dump_txt(dumped_config)
|
66
|
+
when :markdown
|
67
|
+
puts dump_markdown(dumped_config)
|
68
|
+
when :json
|
69
|
+
puts dump_json(dumped_config)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
private
|
74
|
+
|
75
|
+
def dump_txt(dumped_config)
|
76
|
+
dumped = ""
|
77
|
+
plugin_helpers = dumped_config.delete(:plugin_helpers)
|
78
|
+
if plugin_helpers && !plugin_helpers.empty?
|
79
|
+
dumped << "helpers: #{plugin_helpers.join(',')}\n"
|
80
|
+
end
|
81
|
+
if @verbose
|
82
|
+
dumped_config.each do |name, config|
|
83
|
+
dumped << "#{name}\n"
|
84
|
+
dumped << dump_section_txt(config)
|
85
|
+
end
|
86
|
+
else
|
87
|
+
configs = dumped_config.values
|
88
|
+
root_section = configs.shift
|
89
|
+
configs.each do |config|
|
90
|
+
root_section.update(config)
|
91
|
+
end
|
92
|
+
dumped << dump_section_txt(root_section)
|
93
|
+
end
|
94
|
+
dumped
|
95
|
+
end
|
96
|
+
|
97
|
+
def dump_section_txt(base_section, level = 0)
|
98
|
+
dumped = ""
|
99
|
+
indent = " " * level
|
100
|
+
if base_section[:section]
|
101
|
+
sections = []
|
102
|
+
params = base_section
|
103
|
+
else
|
104
|
+
sections, params = base_section.partition {|_name, value| value[:section] }
|
105
|
+
end
|
106
|
+
params.each do |name, config|
|
107
|
+
next if name == :section
|
108
|
+
dumped << "#{indent}#{name}: #{config[:type]}: (#{config[:default].inspect})"
|
109
|
+
dumped << " # #{config[:description]}" if config.key?(:description)
|
110
|
+
dumped << "\n"
|
111
|
+
end
|
112
|
+
sections.each do |section_name, sub_section|
|
113
|
+
required = sub_section.delete(:required)
|
114
|
+
multi = sub_section.delete(:multi)
|
115
|
+
alias_name = sub_section.delete(:alias)
|
116
|
+
required_label = required ? "required" : "optional"
|
117
|
+
multi_label = multi ? "multiple" : "single"
|
118
|
+
alias_label = "alias: #{alias_name}"
|
119
|
+
dumped << "#{indent}<#{section_name}>: #{required_label}, #{multi_label}"
|
120
|
+
if alias_name
|
121
|
+
dumped << ", #{alias_label}\n"
|
122
|
+
else
|
123
|
+
dumped << "\n"
|
124
|
+
end
|
125
|
+
sub_section.delete(:section)
|
126
|
+
dumped << dump_section_txt(sub_section, level + 1)
|
127
|
+
end
|
128
|
+
dumped
|
129
|
+
end
|
130
|
+
|
131
|
+
def dump_markdown(dumped_config)
|
132
|
+
dumped = ""
|
133
|
+
plugin_helpers = dumped_config.delete(:plugin_helpers)
|
134
|
+
if plugin_helpers && !plugin_helpers.empty?
|
135
|
+
dumped = "## Plugin helpers\n\n"
|
136
|
+
plugin_helpers.each do |plugin_helper|
|
137
|
+
dumped << "* #{plugin_helper}\n"
|
138
|
+
end
|
139
|
+
dumped << "\n"
|
140
|
+
end
|
141
|
+
dumped_config.each do |name, config|
|
142
|
+
if name == @plugin.class.name
|
143
|
+
dumped << "## #{name}\n\n"
|
144
|
+
dumped << dump_section_markdown(config)
|
145
|
+
else
|
146
|
+
dumped << "* See also: #{name}\n\n"
|
147
|
+
end
|
148
|
+
end
|
149
|
+
dumped
|
150
|
+
end
|
151
|
+
|
152
|
+
def dump_section_markdown(base_section, level = 0)
|
153
|
+
dumped = ""
|
154
|
+
if base_section[:section]
|
155
|
+
sections = []
|
156
|
+
params = base_section
|
157
|
+
else
|
158
|
+
sections, params = base_section.partition {|_name, value| value[:section] }
|
159
|
+
end
|
160
|
+
params.each do |name, config|
|
161
|
+
next if name == :section
|
162
|
+
template_name = @compact ? "param.md-compact.erb" : "param.md.erb"
|
163
|
+
dumped << ERB.new(template_path(template_name).read, nil, "-").result(binding)
|
164
|
+
end
|
165
|
+
dumped << "\n"
|
166
|
+
sections.each do |section_name, sub_section|
|
167
|
+
required = sub_section.delete(:required)
|
168
|
+
multi = sub_section.delete(:multi)
|
169
|
+
alias_name = sub_section.delete(:alias)
|
170
|
+
$log.trace(name: section_name, required: required, multi: multi, alias_name: alias_name)
|
171
|
+
sub_section.delete(:section)
|
172
|
+
dumped << ERB.new(template_path("section.md.erb").read, nil, "-").result(binding)
|
173
|
+
end
|
174
|
+
dumped
|
175
|
+
end
|
176
|
+
|
177
|
+
def dump_json(dumped_config)
|
178
|
+
if @compact
|
179
|
+
JSON.generate(dumped_config)
|
180
|
+
else
|
181
|
+
JSON.pretty_generate(dumped_config)
|
182
|
+
end
|
183
|
+
end
|
184
|
+
|
185
|
+
def usage(message = nil)
|
186
|
+
puts @parser.to_s
|
187
|
+
puts
|
188
|
+
puts "Error: #{message}" if message
|
189
|
+
exit(false)
|
190
|
+
end
|
191
|
+
|
192
|
+
def prepare_option_parser
|
193
|
+
@parser = OptionParser.new
|
194
|
+
@parser.banner = <<BANNER
|
195
|
+
Usage: #{$0} [options] <type> <name>
|
196
|
+
|
197
|
+
Output plugin config definitions
|
198
|
+
|
199
|
+
Arguments:
|
200
|
+
\ttype: #{SUPPORTED_TYPES.join(",")}
|
201
|
+
\tname: registered plugin name
|
202
|
+
|
203
|
+
Options:
|
204
|
+
BANNER
|
205
|
+
@parser.on("--verbose", "Be verbose") do
|
206
|
+
@verbose = true
|
207
|
+
end
|
208
|
+
@parser.on("-c", "--compact", "Compact output") do
|
209
|
+
@compact = true
|
210
|
+
end
|
211
|
+
@parser.on("-f", "--format=FORMAT", "Specify format. (#{AVAILABLE_FORMATS.join(',')})") do |s|
|
212
|
+
format = s.to_sym
|
213
|
+
usage("Unsupported format: #{s}") unless AVAILABLE_FORMATS.include?(format)
|
214
|
+
@format = format
|
215
|
+
end
|
216
|
+
@parser.on("-I PATH", "Add PATH to $LOAD_PATH") do |s|
|
217
|
+
$LOAD_PATH.unshift(s)
|
218
|
+
end
|
219
|
+
@parser.on("-r NAME", "Load library") do |s|
|
220
|
+
@libs << s
|
221
|
+
end
|
222
|
+
@parser.on("-p", "--plugin=DIR", "Add plugin directory") do |s|
|
223
|
+
@plugin_dirs << s
|
224
|
+
end
|
225
|
+
end
|
226
|
+
|
227
|
+
def parse_options!
|
228
|
+
@parser.parse!(@argv)
|
229
|
+
|
230
|
+
raise "Must specify plugin type and name" unless @argv.size == 2
|
231
|
+
|
232
|
+
@plugin_type, @plugin_name = @argv
|
233
|
+
@options = {
|
234
|
+
compact: @compact,
|
235
|
+
format: @format,
|
236
|
+
verbose: @verbose,
|
237
|
+
}
|
238
|
+
rescue => e
|
239
|
+
usage(e)
|
240
|
+
end
|
241
|
+
|
242
|
+
def init_libraries
|
243
|
+
@libs.each do |lib|
|
244
|
+
require lib
|
245
|
+
end
|
246
|
+
|
247
|
+
@plugin_dirs.each do |dir|
|
248
|
+
if Dir.exist?(dir)
|
249
|
+
dir = File.expand_path(dir)
|
250
|
+
Fluent::Plugin.add_plugin_dir(dir)
|
251
|
+
end
|
252
|
+
end
|
253
|
+
end
|
254
|
+
|
255
|
+
def template_path(name)
|
256
|
+
(Pathname(__dir__) + "../../../templates/plugin_config_formatter/#{name}").realpath
|
257
|
+
end
|
258
|
+
end
|
@@ -0,0 +1,301 @@
|
|
1
|
+
#
|
2
|
+
# Fluentd
|
3
|
+
#
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
# you may not use this file except in compliance with the License.
|
6
|
+
# You may obtain a copy of the License at
|
7
|
+
#
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
#
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
# See the License for the specific language governing permissions and
|
14
|
+
# limitations under the License.
|
15
|
+
#
|
16
|
+
|
17
|
+
require "optparse"
|
18
|
+
require "pathname"
|
19
|
+
require "fileutils"
|
20
|
+
require "erb"
|
21
|
+
require "open-uri"
|
22
|
+
|
23
|
+
require "fluent/registry"
|
24
|
+
|
25
|
+
class FluentPluginGenerator
|
26
|
+
attr_reader :type, :name
|
27
|
+
attr_reader :license_name
|
28
|
+
|
29
|
+
SUPPORTED_TYPES = ["input", "output", "filter", "parser", "formatter"]
|
30
|
+
|
31
|
+
def initialize(argv = ARGV)
|
32
|
+
@argv = argv
|
33
|
+
@parser = prepare_parser
|
34
|
+
|
35
|
+
@license_name = "Apache-2.0"
|
36
|
+
@overwrite_all = false
|
37
|
+
end
|
38
|
+
|
39
|
+
def call
|
40
|
+
parse_options!
|
41
|
+
FileUtils.mkdir_p(gem_name)
|
42
|
+
Dir.chdir(gem_name) do
|
43
|
+
copy_license
|
44
|
+
template_directory.find do |path|
|
45
|
+
next if path.directory?
|
46
|
+
dest_dir = path.dirname.sub(/\A#{Regexp.quote(template_directory.to_s)}\/?/, "")
|
47
|
+
dest_file = dest_filename(path)
|
48
|
+
if path.extname == ".erb"
|
49
|
+
if path.fnmatch?("*/plugin/*")
|
50
|
+
next unless path.basename.fnmatch?("*#{type}*")
|
51
|
+
end
|
52
|
+
template(path, dest_dir + dest_file)
|
53
|
+
else
|
54
|
+
file(path, dest_dir + dest_file)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
pid = spawn("git", "init", ".")
|
58
|
+
Process.wait(pid)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
private
|
63
|
+
|
64
|
+
def template_directory
|
65
|
+
(Pathname(__dir__) + "../../../templates/new_gem").realpath
|
66
|
+
end
|
67
|
+
|
68
|
+
def template_file(filename)
|
69
|
+
template_directory + filename
|
70
|
+
end
|
71
|
+
|
72
|
+
def template(source, dest)
|
73
|
+
dest.dirname.mkpath
|
74
|
+
contents = ERB.new(source.read, nil, "-").result(binding)
|
75
|
+
label = create_label(dest, contents)
|
76
|
+
puts "\t#{label} #{dest}"
|
77
|
+
if label == "conflict"
|
78
|
+
return unless overwrite?(dest)
|
79
|
+
end
|
80
|
+
File.write(dest, contents)
|
81
|
+
end
|
82
|
+
|
83
|
+
def file(source, dest)
|
84
|
+
label = create_label(dest, source.read)
|
85
|
+
puts "\t#{label} #{dest}"
|
86
|
+
if label == "conflict"
|
87
|
+
return unless overwrite?(dest)
|
88
|
+
end
|
89
|
+
FileUtils.cp(source, dest)
|
90
|
+
end
|
91
|
+
|
92
|
+
def prepare_parser
|
93
|
+
@parser = OptionParser.new
|
94
|
+
@parser.banner = <<BANNER
|
95
|
+
Usage: fluent-plugin-generate [options] <type> <name>
|
96
|
+
|
97
|
+
Generate a project skeleton for creating a Fluentd plugin
|
98
|
+
|
99
|
+
Arguments:
|
100
|
+
\ttype: #{SUPPORTED_TYPES.join(",")}
|
101
|
+
\tname: Your plugin name
|
102
|
+
|
103
|
+
Options:
|
104
|
+
BANNER
|
105
|
+
|
106
|
+
@parser.on("--[no-]license=NAME", "Specify license name (default: Apache-2.0)") do |v|
|
107
|
+
@license_name = v || "no-license"
|
108
|
+
end
|
109
|
+
@parser
|
110
|
+
end
|
111
|
+
|
112
|
+
def parse_options!
|
113
|
+
@parser.parse!(@argv)
|
114
|
+
unless @argv.size == 2
|
115
|
+
raise ArgumentError, "Missing arguments"
|
116
|
+
end
|
117
|
+
@type, @name = @argv
|
118
|
+
rescue => e
|
119
|
+
usage("#{e.class}:#{e.message}")
|
120
|
+
end
|
121
|
+
|
122
|
+
def usage(message = "")
|
123
|
+
puts message
|
124
|
+
puts
|
125
|
+
puts @parser.help
|
126
|
+
exit(false)
|
127
|
+
end
|
128
|
+
|
129
|
+
def user_name
|
130
|
+
v = `git config --get user.name`.chomp
|
131
|
+
v.empty? ? "TODO: Write your name" : v
|
132
|
+
end
|
133
|
+
|
134
|
+
def user_email
|
135
|
+
v = `git config --get user.email`.chomp
|
136
|
+
v.empty? ? "TODO: Write your email" : v
|
137
|
+
end
|
138
|
+
|
139
|
+
def gem_name
|
140
|
+
"fluent-plugin-#{name}"
|
141
|
+
end
|
142
|
+
|
143
|
+
def class_name
|
144
|
+
"#{name.capitalize}#{type.capitalize}"
|
145
|
+
end
|
146
|
+
|
147
|
+
def plugin_filename
|
148
|
+
case type
|
149
|
+
when "input"
|
150
|
+
"in_#{name}.rb"
|
151
|
+
when "output"
|
152
|
+
"out_#{name}.rb"
|
153
|
+
else
|
154
|
+
"#{type}_#{name}.rb"
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
def test_filename
|
159
|
+
case type
|
160
|
+
when "input"
|
161
|
+
"test_in_#{name}.rb"
|
162
|
+
when "output"
|
163
|
+
"test_out_#{name}.rb"
|
164
|
+
else
|
165
|
+
"test_#{type}_#{name}.rb"
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
def dest_filename(path)
|
170
|
+
case path.to_s
|
171
|
+
when %r!\.gemspec!
|
172
|
+
"#{gem_name}.gemspec"
|
173
|
+
when %r!lib/fluent/plugin!
|
174
|
+
plugin_filename
|
175
|
+
when %r!test/plugin!
|
176
|
+
test_filename
|
177
|
+
else
|
178
|
+
path.basename.sub_ext("")
|
179
|
+
end
|
180
|
+
end
|
181
|
+
|
182
|
+
def preamble
|
183
|
+
@license.preamble(user_name)
|
184
|
+
end
|
185
|
+
|
186
|
+
def copy_license
|
187
|
+
# in gem_name directory
|
188
|
+
return unless license_name
|
189
|
+
puts "License: #{license_name}"
|
190
|
+
license_class = self.class.lookup_license(license_name)
|
191
|
+
@license = license_class.new
|
192
|
+
Pathname("LICENSE").write(@license.text) unless @license.text.empty?
|
193
|
+
rescue Fluent::ConfigError
|
194
|
+
usage("Unknown license: #{license_name}")
|
195
|
+
rescue => ex
|
196
|
+
usage("#{ex.class}: #{ex.message}")
|
197
|
+
end
|
198
|
+
|
199
|
+
def create_label(dest, contents)
|
200
|
+
if dest.exist?
|
201
|
+
if dest.read == contents
|
202
|
+
"identical"
|
203
|
+
else
|
204
|
+
"conflict"
|
205
|
+
end
|
206
|
+
else
|
207
|
+
"create"
|
208
|
+
end
|
209
|
+
end
|
210
|
+
|
211
|
+
def overwrite?(dest)
|
212
|
+
return true if @overwrite_all
|
213
|
+
loop do
|
214
|
+
print "Overwrite #{dest}? (enter \"h\" for help) [Ynaqh]"
|
215
|
+
answer = $stdin.gets.chomp
|
216
|
+
return true if /\Ay\z/i =~ answer || answer.empty?
|
217
|
+
case answer
|
218
|
+
when "n"
|
219
|
+
return false
|
220
|
+
when "a"
|
221
|
+
@overwrite_all = true
|
222
|
+
return true
|
223
|
+
when "q"
|
224
|
+
exit
|
225
|
+
when "h"
|
226
|
+
puts <<HELP
|
227
|
+
\tY - yes, overwrite
|
228
|
+
\tn - no, do not overwrite
|
229
|
+
\ta - all, overwrite this and all others
|
230
|
+
\tq - quite, abort
|
231
|
+
\th - help, show this help
|
232
|
+
HELP
|
233
|
+
end
|
234
|
+
puts "Retrying..."
|
235
|
+
end
|
236
|
+
end
|
237
|
+
|
238
|
+
class NoLicense
|
239
|
+
attr_reader :name, :full_name, :text
|
240
|
+
|
241
|
+
def initialize
|
242
|
+
@name = ""
|
243
|
+
@full_name = ""
|
244
|
+
@text = ""
|
245
|
+
end
|
246
|
+
|
247
|
+
def preamble(usename)
|
248
|
+
""
|
249
|
+
end
|
250
|
+
end
|
251
|
+
|
252
|
+
class ApacheLicense
|
253
|
+
LICENSE_URL = "http://www.apache.org/licenses/LICENSE-2.0.txt"
|
254
|
+
|
255
|
+
attr_reader :text
|
256
|
+
|
257
|
+
def initialize
|
258
|
+
@text = ""
|
259
|
+
@preamble_source = ""
|
260
|
+
@preamble = nil
|
261
|
+
open(LICENSE_URL) do |io|
|
262
|
+
@text = io.read
|
263
|
+
end
|
264
|
+
@preamble_source = @text[/^(\s*Copyright.+)/m, 1]
|
265
|
+
end
|
266
|
+
|
267
|
+
def name
|
268
|
+
"Apache-2.0"
|
269
|
+
end
|
270
|
+
|
271
|
+
def full_name
|
272
|
+
"Apache License, Version 2.0"
|
273
|
+
end
|
274
|
+
|
275
|
+
def preamble(user_name)
|
276
|
+
@preamble ||= @preamble_source.dup.tap do |source|
|
277
|
+
source.gsub!(/\[yyyy\]/, "#{Date.today.year}-")
|
278
|
+
source.gsub!(/\[name of copyright owner\]/, user_name)
|
279
|
+
source.gsub!(/^ {2}|^$/, "#")
|
280
|
+
source.chomp!
|
281
|
+
end
|
282
|
+
end
|
283
|
+
end
|
284
|
+
|
285
|
+
LICENSE_REGISTRY = Fluent::Registry.new(:license, "")
|
286
|
+
|
287
|
+
def self.register_license(license, klass)
|
288
|
+
LICENSE_REGISTRY.register(license, klass)
|
289
|
+
end
|
290
|
+
|
291
|
+
def self.lookup_license(license)
|
292
|
+
LICENSE_REGISTRY.lookup(license)
|
293
|
+
end
|
294
|
+
|
295
|
+
{
|
296
|
+
"no-license" => NoLicense,
|
297
|
+
"Apache-2.0" => ApacheLicense
|
298
|
+
}.each do |license, klass|
|
299
|
+
register_license(license, klass)
|
300
|
+
end
|
301
|
+
end
|