Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add fluent-plugin-generate command #1427

Merged
merged 89 commits into from
Feb 16, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
89 commits
Select commit Hold shift + click to select a range
da3664e
Add fluent-plugin-generate
okkez Jan 20, 2017
11526c7
Copy license first
okkez Jan 20, 2017
52559a8
Display using license
okkez Jan 20, 2017
27d2cd7
Be silent
okkez Jan 20, 2017
6b0abce
Add create_label and overwrite?
okkez Jan 20, 2017
2cc7f7c
Overwrite generated files when destination exists
okkez Jan 20, 2017
8dcb7f9
Fix a typo
okkez Jan 20, 2017
6d99ffd
Align
okkez Jan 20, 2017
44d4a1b
Organize spec.files, spec.test_files
okkez Jan 20, 2017
79a412c
Add missing spec.version
okkez Jan 20, 2017
2d5175f
Support all, quit and help in FluentPluginGenerator#overwrite?
okkez Jan 20, 2017
62fadcd
Chmod 0755 bin/fluent-plugin-generate
okkez Jan 20, 2017
2e723a7
Support --no-license option
okkez Jan 20, 2017
fc26431
Use `#file` instead of `FileUtils#cp`
okkez Jan 20, 2017
dd2581f
Parse @argv properly
okkez Jan 20, 2017
bbab5e4
Move capture_stdout to use other test
okkez Jan 20, 2017
031e171
Handle unknown license
okkez Jan 20, 2017
d962784
Wait pid
okkez Jan 20, 2017
3300253
Add test for fluent-plugin-generate
okkez Jan 20, 2017
02b2679
Add `Fuent::Plugin::Base.plugin_helpers`
okkez Jan 19, 2017
4dde4c7
Move templates for new gem under new_gem directory
okkez Jan 20, 2017
545d1aa
Add fluent-plugin-config-format command
okkez Jan 23, 2017
cba9edc
Fluent::Plugin::Base#plugin_helpers returns plugin helper name
okkez Jan 23, 2017
5bdec2d
Stop displaying plugin helper's params
okkez Jan 23, 2017
41d1ea5
Display plugin class name if verbose
okkez Jan 23, 2017
e4d29df
Add missing new line after plugin helpers
okkez Jan 23, 2017
e5cb82d
Stop displaying sections that have no params
okkez Jan 23, 2017
39f717e
Add missing new line before sub proxy
okkez Jan 23, 2017
8a01688
Skip Fluent::Plugin::Base
okkez Jan 23, 2017
30c4dd2
Fix section markup
okkez Jan 23, 2017
6a7be2f
Remove unused `--all` option
okkez Jan 23, 2017
ad89aa4
Display root section
okkez Jan 23, 2017
444ca3f
Organize header level
okkez Jan 23, 2017
6d63b2d
Display info about section
okkez Jan 23, 2017
3f85071
Support compact template
okkez Jan 23, 2017
42af799
Support JSON
okkez Jan 23, 2017
7740b8c
Move formatter implementations to lib/fluent/command/plugin_config_fo…
okkez Jan 25, 2017
024e6a0
Use `fluent-plugin-config-format` instead of `fluentd --show-plugin-c…
okkez Jan 25, 2017
b8a9493
Fix a typo
okkez Jan 25, 2017
d8a4f16
Output compact style JSON when --compact is specified
okkez Jan 25, 2017
a92142b
Set description properly
okkez Jan 25, 2017
d588635
Fix test to follow previous changes
okkez Jan 25, 2017
a5d4b22
Add test for fluent-plugin-config-format
okkez Jan 25, 2017
cfeab97
Remove trailing white spaces in preamble
okkez Jan 25, 2017
aaeabdc
Fix method definitions
okkez Jan 25, 2017
99672a4
Fix typos
okkez Jan 25, 2017
4c1ccfb
Set required properly
okkez Jan 27, 2017
f358972
Remove debug print
okkez Jan 27, 2017
8947e06
Rename Fluent::ConfigureProxy#dump to Fluent::ConfigureProxy#dump_con…
okkez Jan 27, 2017
e3fede2
Follow previous commit
okkez Jan 27, 2017
32297b1
Stop using Fluent::Engine in FluentPluginConfigFormatter
okkez Jan 27, 2017
b1a6f14
Stop displaying plugin helpers if plugin helpers are empty
okkez Jan 27, 2017
dc5eb66
Use static method invocation instead of dynamic method invocation
okkez Jan 27, 2017
64fe217
Validate specified format
okkez Jan 27, 2017
83b1df3
Add `Fluent::PluginHelper#helpers_internal`
okkez Jan 27, 2017
8dec555
Move plugin_helpers implementation to Fluent::PluginHelper module
okkez Jan 27, 2017
e549700
Ignore empty dumped config definition
okkez Jan 27, 2017
540054c
Symplify
okkez Jan 27, 2017
459f2c6
Remove redundant code
okkez Jan 27, 2017
b138781
Move templates
okkez Jan 27, 2017
88a2dbd
Fix template directory to follow previous commit
okkez Jan 27, 2017
e04784c
Remove license related files
okkez Jan 27, 2017
371d898
Add usage method
okkez Jan 27, 2017
79f146a
Download license from web site
okkez Jan 27, 2017
08eb596
Use Fluent::Registry to manage licenses
okkez Jan 27, 2017
c76e088
Rename ApacheLicense#license to ApacheLicense#text
okkez Jan 27, 2017
5e224b1
Support no license properly
okkez Jan 27, 2017
834abae
Use preamble in license object
okkez Jan 27, 2017
2ffd60b
Add installation section
okkez Jan 27, 2017
e87628a
Enhance fluent-plugin-generate help
okkez Jan 27, 2017
d1a54d4
Enhance fluent-plugin-config-format help
okkez Jan 27, 2017
33c6f0a
Add -I option to fluent-plugin-config-format
okkez Jan 27, 2017
caaf557
Move capture_stdout under Fluetn::Test::Helpers
okkez Jan 28, 2017
56d67df
Use `test "name" do ...` style
okkez Jan 28, 2017
a5fe470
Extend Test::Unit::TestCase to use `config_element`
okkez Jan 28, 2017
75dd130
Specify version spec to generated gemspec
okkez Jan 30, 2017
43af372
Define Fluent::Test::Helpers#capture_stdout properly
okkez Jan 30, 2017
3e7ec76
Fix typos
okkez Jan 30, 2017
ea79554
Stop displaying plugin helpers when owned plugins
okkez Jan 30, 2017
2b60e8d
Dump nested section properly
okkez Jan 30, 2017
0bf8c2c
Simplify markdown output
okkez Jan 30, 2017
2dac957
Add test for fluent-plugin-config-format
okkez Jan 30, 2017
0043507
Initialize @_plugin_helpers_list to suppress warnings
okkez Jan 30, 2017
78e987c
Add trace log to suppress warnings
okkez Jan 30, 2017
261796c
Be sure to initialize @_plugin_helpers_list
okkez Jan 30, 2017
8e4b749
Define NoLicense#preamble same as ApacheLicense#preamble
okkez Jan 30, 2017
654a5a5
Stop generating LICENSE file when no license
okkez Jan 30, 2017
67d73e0
Assert timekey_zone dynamically
okkez Jan 30, 2017
ecf5fa5
Rescue SystemExit by assert_raise
okkez Feb 10, 2017
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions bin/fluent-plugin-config-format
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#!/usr/bin/env ruby
$LOAD_PATH.unshift(File.join(__dir__, 'lib'))
require 'fluent/command/plugin_config_formatter'

FluentPluginConfigFormatter.new.call
5 changes: 5 additions & 0 deletions bin/fluent-plugin-generate
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#!/usr/bin/env ruby
$LOAD_PATH << File.expand_path(File.join(__dir__, '..', 'lib'))
require 'fluent/command/plugin_generator'

FluentPluginGenerator.new.call
258 changes: 258 additions & 0 deletions lib/fluent/command/plugin_config_formatter.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,258 @@
#
# Fluentd
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#

require "erb"
require "optparse"
require "pathname"
require "fluent/plugin"
require "fluent/env"
require "fluent/engine"
require "fluent/system_config"
require "fluent/config/element"

class FluentPluginConfigFormatter

AVAILABLE_FORMATS = [:markdown, :txt, :json]
SUPPORTED_TYPES = [
"input", "output", "filter",
"buffer", "parser", "formatter", "storage"
]

def initialize(argv = ARGV)
@argv = argv

@compact = false
@format = :markdown
@verbose = false
@libs = []
@plugin_dirs = []
@options = {}

prepare_option_parser
end

def call
parse_options!
init_libraries
@plugin = Fluent::Plugin.__send__("new_#{@plugin_type}", @plugin_name)
dumped_config = {}
if @plugin.class.respond_to?(:plugin_helpers)
dumped_config[:plugin_helpers] = @plugin.class.plugin_helpers
end
@plugin.class.ancestors.reverse_each do |plugin_class|
next unless plugin_class.respond_to?(:dump_config_definition)
unless @verbose
next if plugin_class.name =~ /::PluginHelper::/
end
dumped_config_definition = plugin_class.dump_config_definition
dumped_config[plugin_class.name] = dumped_config_definition unless dumped_config_definition.empty?
end
case @format
when :txt
puts dump_txt(dumped_config)
when :markdown
puts dump_markdown(dumped_config)
when :json
puts dump_json(dumped_config)
end
end

private

def dump_txt(dumped_config)
dumped = ""
plugin_helpers = dumped_config.delete(:plugin_helpers)
if plugin_helpers && !plugin_helpers.empty?
dumped << "helpers: #{plugin_helpers.join(',')}\n"
end
if @verbose
dumped_config.each do |name, config|
dumped << "#{name}\n"
dumped << dump_section_txt(config)
end
else
configs = dumped_config.values
root_section = configs.shift
configs.each do |config|
root_section.update(config)
end
dumped << dump_section_txt(root_section)
end
dumped
end

def dump_section_txt(base_section, level = 0)
dumped = ""
indent = " " * level
if base_section[:section]
sections = []
params = base_section
else
sections, params = base_section.partition {|_name, value| value[:section] }
end
params.each do |name, config|
next if name == :section
dumped << "#{indent}#{name}: #{config[:type]}: (#{config[:default].inspect})"
dumped << " # #{config[:description]}" if config.key?(:description)
dumped << "\n"
end
sections.each do |section_name, sub_section|
required = sub_section.delete(:required)
multi = sub_section.delete(:multi)
alias_name = sub_section.delete(:alias)
required_label = required ? "required" : "optional"
multi_label = multi ? "multiple" : "single"
alias_label = "alias: #{alias_name}"
dumped << "#{indent}<#{section_name}>: #{required_label}, #{multi_label}"
if alias_name
dumped << ", #{alias_label}\n"
else
dumped << "\n"
end
sub_section.delete(:section)
dumped << dump_section_txt(sub_section, level + 1)
end
dumped
end

def dump_markdown(dumped_config)
dumped = ""
plugin_helpers = dumped_config.delete(:plugin_helpers)
if plugin_helpers && !plugin_helpers.empty?
dumped = "## Plugin helpers\n\n"
plugin_helpers.each do |plugin_helper|
dumped << "* #{plugin_helper}\n"
end
dumped << "\n"
end
dumped_config.each do |name, config|
if name == @plugin.class.name
dumped << "## #{name}\n\n"
dumped << dump_section_markdown(config)
else
dumped << "* See also: #{name}\n\n"
end
end
dumped
end

def dump_section_markdown(base_section, level = 0)
dumped = ""
if base_section[:section]
sections = []
params = base_section
else
sections, params = base_section.partition {|_name, value| value[:section] }
end
params.each do |name, config|
next if name == :section
template_name = @compact ? "param.md-compact.erb" : "param.md.erb"
dumped << ERB.new(template_path(template_name).read, nil, "-").result(binding)
end
dumped << "\n"
sections.each do |section_name, sub_section|
required = sub_section.delete(:required)
multi = sub_section.delete(:multi)
alias_name = sub_section.delete(:alias)
$log.trace(name: section_name, required: required, multi: multi, alias_name: alias_name)
sub_section.delete(:section)
dumped << ERB.new(template_path("section.md.erb").read, nil, "-").result(binding)
end
dumped
end

def dump_json(dumped_config)
if @compact
JSON.generate(dumped_config)
else
JSON.pretty_generate(dumped_config)
end
end

def usage(message = nil)
puts @parser.to_s
puts
puts "Error: #{message}" if message
exit(false)
end

def prepare_option_parser
@parser = OptionParser.new
@parser.banner = <<BANNER
Usage: #{$0} [options] <type> <name>

Output plugin config definitions

Arguments:
\ttype: #{SUPPORTED_TYPES.join(",")}
\tname: registered plugin name

Options:
BANNER
@parser.on("--verbose", "Be verbose") do
@verbose = true
end
@parser.on("-c", "--compact", "Compact output") do
@compact = true
end
@parser.on("-f", "--format=FORMAT", "Specify format. (#{AVAILABLE_FORMATS.join(',')})") do |s|
format = s.to_sym
usage("Unsupported format: #{s}") unless AVAILABLE_FORMATS.include?(format)
@format = format
end
@parser.on("-I PATH", "Add PATH to $LOAD_PATH") do |s|
$LOAD_PATH.unshift(s)
end
@parser.on("-r NAME", "Load library") do |s|
@libs << s
end
@parser.on("-p", "--plugin=DIR", "Add plugin directory") do |s|
@plugin_dirs << s
end
end

def parse_options!
@parser.parse!(@argv)

raise "Must specify plugin type and name" unless @argv.size == 2

@plugin_type, @plugin_name = @argv
@options = {
compact: @compact,
format: @format,
verbose: @verbose,
}
rescue => e
usage(e)
end

def init_libraries
@libs.each do |lib|
require lib
end

@plugin_dirs.each do |dir|
if Dir.exist?(dir)
dir = File.expand_path(dir)
Fluent::Plugin.add_plugin_dir(dir)
end
end
end

def template_path(name)
(Pathname(__dir__) + "../../../templates/plugin_config_formatter/#{name}").realpath
end
end
Loading