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

Conversation

okkez
Copy link
Contributor

@okkez okkez commented Jan 20, 2017

See #1376

@okkez
Copy link
Contributor Author

okkez commented Jan 20, 2017

This is workin progress.
I will add one more feature #1376 (comment)

@tagomoris tagomoris added feature request *Deprecated Label* Use enhancement label in general v0.14 work-in-progress labels Jan 20, 2017
@okkez okkez changed the title WIP: Add fluent-plugin-generate command Add fluent-plugin-generate command Jan 25, 2017
@okkez
Copy link
Contributor Author

okkez commented Jan 25, 2017

Done my work.
Could you check this PR @tagomoris @repeatedly ?

Copy link
Member

@tagomoris tagomoris left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have 2 general points.

Can you move templates from lib/fluent/command/templates to templates? It's bad practice to have non-ruby script files under lib.

Could you add some tests for dumped configuration definitions? Especially for markdown and text. I want to see the actual output example of that feature.

end
dumped_config[plugin_class.name] = plugin_class.dump
end
puts __send__("dump_#{@format}", dumped_config)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's better to call methods via case when clause. Using __send__("dump_#{@format}") makes code unreadable and hard to know the exact list of supported formats.

@@ -166,8 +166,8 @@ def merged_configure_proxy
configurables.map{ |a| a.configure_proxy(a.name || a.object_id.to_s) }.reduce(:merge)
end

def dump(level = 0)
configure_proxy_map[self.to_s].dump(level)
def dump
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you change the method name from dump to dump_config_definition or something like that?
PluginClass.dump looks awful for that purpose.

@@ -28,6 +28,17 @@ class Base

attr_accessor :under_plugin_development

def self.plugin_helpers
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are no need to show all plugin helpers enabled in plugins. For example, all input plugins enable event_emitter plugin helper, but it makes no sense for users. There are same things about thread, event_loop and some others.

So, how about to do this?:

  • store the list of plugin helpers enabled by helpers into class variable
  • return the list of plugin helpers enabled by helpers (concatenated list of ancestors)
  • add another method Fluent::PluginHelper.helpers_internal to bypass storing helper names for internal use about event_emitter, thread, retry_state and some others in plugin base classes.
module Fluent
  module PluginHelper
    module Mixin
      # ...
    end
    def helpers_internal(*snake_case_symbols) # it's actually rename of current #helpers
      # ...
    end
    def helpers(*sname_case_symbols)
      @_plugin_helpers_list ||= []
      @_plugin_helpers_list << sname_case_symbols
      helpers_internal(*sname_case_symbols)
    end
  end
end

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds nice. I will change implementation.

def dump_txt(dumped_config)
dumped = ""
plugin_helpers = dumped_config.delete(:plugin_helpers)
dumped << "helpers: #{plugin_helpers.join(',')}\n" if plugin_helpers
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PluginClass.plugin_helpers always returns an array object, which may be empty for plugin classes which doesn't use any plugin helpers.
So this line should be unless plugin_helpers.empty?.

dumped_config[:plugin_helpers] = @plugin.class.plugin_helpers
@plugin.class.ancestors.reverse_each do |plugin_class|
next unless plugin_class.respond_to?(:dump)
next if plugin_class == Fluent::Plugin::Base
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is Fluent::Plugin::Base removed? There seems no actual benefits to do it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because Fluent::Plugin::Base has no config_param and config_section.
Fluent::Plugin::Base.dump_config_definition always returns empty hash.
I think it is noise for us.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about to omit classes which returns empty hash, instead of using class name?
There are some other classes which doesn't have any config_param and config_section.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds good. Thanks!


class FluentPluginGenerator
attr_reader :type, :name
attr_reader :license
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's ok to fix the license as Apache-2.0.
If this feature supports GPLv2 or GPLv3 or any others, it means that Fluentd source code tree have the license files/templates of these licenses, or code to download these license files. It sounds very bad situation.

end

def copy_license
# in gem_name directory
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This method should download the original license from https://www.apache.org/licenses/LICENSE-2.0.txt and use it.
We can't assure the correctness of license text (Please remove the license file from template tree).

def prepare_parser
@parser = OptionParser.new
@parser.banner = <<BANNER
Usage: fluent-plugin-generate [options] <type> <name>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's better to show the list of available types.

Fluent::Test::Driver::Filter.new(Fluent::Plugin::<%= class_name %>).configure(conf)
end

def test_failure
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use test 'failure' type testcases to introduce that feature to plugin authors.

test/helper.rb Outdated
@@ -146,6 +146,15 @@ def ipv6_enabled?
end
end

def capture_stdout
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Move this method to fluent/test/helpers because that file already have #capture_log method.

@tagomoris
Copy link
Member

@okkez Nice implementation! I added general review comment and comments for some points.
@repeatedly please add some other points if you have.

init_engine
@plugin = Fluent::Plugin.__send__("new_#{@plugin_type}", @plugin_name)
dumped_config = {}
dumped_config[:plugin_helpers] = @plugin.class.plugin_helpers
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These two lines are merged into dumped_config = {plugin_helpers: @plugin.class.plugin_helpers}

else
dumped << "\n"
end
dumped << "#{dump_section_txt(sub_section, level + 1)}"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why need "#{}" ? Only dump_section_txt(sub_section, level + 1) has a problem?


spec.add_development_dependency "bundler"
spec.add_development_dependency "rake"
spec.add_development_dependency "test-unit"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should add version constraint like ~> 3.0?


TODO: write description for you plugin.

## Configuration
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add ## installation section.

okkez and others added 16 commits January 30, 2017 13:21
In this version we can do following:

```ruby
class TestFoo < Test::Unit::TestCase
  CONF = config_element("ROOT", "", { "key" => "value" })
end
```
Because owned plugins does not includes Fluetn::PluginHelper::Mixin.
But these variables used in templates/plugin_config_formatter/section.md.erb

lib/fluent/command/plugin_config_formatter.rb:167: warning: assigned but unused variable - required
lib/fluent/command/plugin_config_formatter.rb:168: warning: assigned but unused variable - multi
lib/fluent/command/plugin_config_formatter.rb:169: warning: assigned but unused variable - alias_name
@okkez
Copy link
Contributor Author

okkez commented Jan 30, 2017

@tagomoris @repeatedly I've pushed changes for all comments.
Could you check again?

@repeatedly
Copy link
Member

LGTM but all tests failed.
Could you check test?

Because `exit(false)` raises SystemExit.
@okkez
Copy link
Contributor Author

okkez commented Feb 10, 2017

@repeatedly @tagomoris Passed all tests.

@repeatedly repeatedly merged commit f1e8fa4 into fluent:master Feb 16, 2017
@repeatedly
Copy link
Member

Thanks for your work!

@repeatedly repeatedly mentioned this pull request Feb 16, 2017
@okkez okkez deleted the plugin-generator branch February 21, 2018 00:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature request *Deprecated Label* Use enhancement label in general v0.14
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants