Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
/*.gem
.bundle
/Gemfile.lock
/coverage
/doc
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ plugins.types => Array of types
- `type: "<type>"` - Load plugins only of given type, optional, makes `type` method accessible.
- `prefix: "/prefix"` - Load plugins only from this paths, optional, default `/lib`.
- `extends: %i[<extensions>]` - Extend pluginator with given extensions.
- `plugins_dir_name: 'plugins'` - the top level directory name to use when looking for plugins, defaults to "plugins"

## Extensions

Expand Down
5 changes: 3 additions & 2 deletions lib/pluginator/autodetect.rb
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,12 @@ class Autodetect
# @option prefix [String] a prefix for finding plugins if forcing,
# by default only `/lib` is checked,
# regexp notation is allowed, for example `/(lib|local_lib)`

# @option plugins_dir_name [String] the top level directory name to use when looking for plugins
def initialize(group, options={})
super(group)
@force_prefix = options[:prefix]
@force_type = options[:type]
@plugins_dir_name = options[:plugins_dir_name] || 'plugins'
refresh
end

Expand All @@ -55,7 +56,7 @@ def initialize(group, options={})
#
# Use it after gem list change, for example after `Gem.install("new_gem")`
def refresh
plugin_lists = FormattedFinder.new(@force_prefix, @group, @force_type)
plugin_lists = FormattedFinder.new(@force_prefix, @group, @force_type, @plugins_dir_name)
register_plugins(plugin_lists.loaded_plugins_path)
load_plugins(plugin_lists.load_path_plugins_paths)
activate_plugins(plugin_lists.gem_plugins_paths)
Expand Down
15 changes: 9 additions & 6 deletions lib/pluginator/autodetect/finder.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ class Autodetect
# Find plugins
class Finder

attr_reader :loaded_plugins_path, :load_path_plugins_paths, :gem_plugins_paths
attr_reader :loaded_plugins_path, :load_path_plugins_paths, :force_prefix,
:gem_plugins_paths, :plugins_dir_name, :group, :force_type

# Automatically load plugins for given group (and type)
#
Expand All @@ -32,10 +33,12 @@ class Finder
# regexp notation is allowed, for example `/[lib|]`
# @param group [String] name of the plugins group
# @param force_type [String] name of the plugin type if forcing
def initialize(force_prefix, group, force_type)
# @option plugins_dir_name [String] the top level directory name to use when looking for plugins
def initialize(force_prefix, group, force_type, plugins_dir_name = 'plugins')
@force_prefix = force_prefix
@group = group
@force_type = force_type
@plugins_dir_name = plugins_dir_name || 'plugins'
@pattern = file_name_pattern
find_paths
end
Expand All @@ -44,7 +47,7 @@ def initialize(force_prefix, group, force_type)

# group => pattern
def file_name_pattern
"plugins/#{@group}/#{@force_type || "**"}/*.rb"
File.join(plugins_dir_name, group, (force_type || '**'), '*.rb' )
end

def find_paths
Expand Down Expand Up @@ -79,9 +82,9 @@ def split_file_names(file_names)

# file_name => [ path, full_name, type ]
def split_file_name(file_name)
prefix = @force_prefix || "/lib"
type = @force_type || ".*"
match = file_name.match(%r{.*#{prefix}/(plugins/(#{@group}/(#{type})/[^/]*)\.rb)$})
prefix = force_prefix || "/lib"
type = force_type || ".*"
match = file_name.match(%r{.*#{prefix}/(#{plugins_dir_name}/(#{group}/(#{type})/[^/]*)\.rb)$})
match[-3..-1] if match
end

Expand Down
2 changes: 1 addition & 1 deletion lib/pluginator/autodetect/formatted_finder.rb
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ class Autodetect
class FormattedFinder < Finder

# Reformat plugin lists
def initialize(force_prefix, group, force_type)
def initialize(force_prefix, group, force_type, plugins_dir_name)
super
map_loaded_plugins
map_gem_plugins
Expand Down
3 changes: 2 additions & 1 deletion lib/pluginator/extendable_autodetect.rb
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,9 @@ class ExtendableAutodetect < Autodetect
# @param options [Hash] options to pass to creating Pluginator instance
# @option type [String] name of type to load
# @option extends [Array<Symbol>|Symbol] list of extension to extend into pluginator instance
# @option plugins_dir_name [String] the top level directory name to use when looking for plugins
def initialize(group, options={})
super(group, options)
super
extend_plugins(options[:extends] || [])
end

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
=begin
Copyright 2013 Michal Papis <[email protected]>

This file is part of pluginator.

pluginator is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

pluginator is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with pluginator. If not, see <http://www.gnu.org/licenses/>.
=end

class Something::Math::Decrease
def self.type
"decrease"
end
def self.action(number)
number - 1
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
=begin
Copyright 2013 Michal Papis <[email protected]>

This file is part of pluginator.

pluginator is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

pluginator is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with pluginator. If not, see <http://www.gnu.org/licenses/>.
=end

class Something::Math::Increase
def self.type
"increase"
end
def self.action(number)
number + 1
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
=begin
Copyright 2013 Michal Papis <[email protected]>

This file is part of pluginator.

pluginator is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

pluginator is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with pluginator. If not, see <http://www.gnu.org/licenses/>.
=end

class Something::Nested::Structure::Test

def self.action
42
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
=begin
Copyright 2013 Michal Papis <[email protected]>

This file is part of pluginator.

pluginator is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

pluginator is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with pluginator. If not, see <http://www.gnu.org/licenses/>.
=end

class Something::Stats::Max

def self.handles?(what)
%w{ max maximum }.include?(what)
end

def self.action
42
end
end
71 changes: 67 additions & 4 deletions test/pluginator/autodetect_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -40,18 +40,81 @@ def gem_files(*paths)
end

describe Pluginator::Autodetect do
before do
@math_parsed = [
let(:math_files) do
gem_files(math_parsed.map(&:first))
end

let(:math_parsed) do
[
["plugins/something/math/increase.rb", "something/math/increase", "math"],
["plugins/something/math/decrease.rb", "something/math/decrease", "math"]
]
@math_files = gem_files(@math_parsed.map(&:first))
@all_files = gem_files(
end

let(:all_files) do
gem_files(
"plugins/something/math/increase.rb", "plugins/something/math/decrease.rb",
"plugins/something/nested/structure/test.rb", "plugins/something/stats/max.rb"
)
end

describe :alt_plugins_dir do
let(:math_parsed) do
[
["kitchen/something/math/increase.rb", "something/math/increase", "math"],
["kitchen/something/math/decrease.rb", "something/math/decrease", "math"]
]
end

let(:all_files) do
gem_files(
"kitchen/something/math/increase.rb", "kitchen/something/math/decrease.rb",
"kitchen/something/nested/structure/test.rb", "kitchen/something/stats/max.rb"
)
end

it :loads_plugins_automatically_for_group do
pluginator = Pluginator::Autodetect.new("something", plugins_dir_name: 'kitchen')
pluginator.types.must_include("stats")
pluginator.types.must_include("math")
pluginator.types.size.must_equal(3)
plugins = pluginator["math"].map(&:to_s)
plugins.size.must_equal(2)
plugins.must_include("Something::Math::Increase")
plugins.must_include("Something::Math::Decrease")
plugins.wont_include("Something::Math::Add")
end

it :loads_plugins_automatically_for_group_type do
pluginator = Pluginator::Autodetect.new("something", :type => "stats", plugins_dir_name: 'kitchen')
pluginator.types.sort.must_equal(["stats"])
end

it :makes_group_plugins_work do
pluginator = Pluginator::Autodetect.new("something", plugins_dir_name: 'kitchen')
pluginator.types.must_include("math")
pluginator["math"].detect{|plugin| plugin.type == "increase" }.action(2).must_equal(3)
pluginator["math"].detect{|plugin| plugin.type == "decrease" }.action(5).must_equal(4)
end

it :hides_methods do
pluginator = Pluginator::Autodetect.new("something", plugins_dir_name: 'kitchen')
pluginator.public_methods.map(&:to_sym).must_include(:register_plugin)
pluginator.public_methods.map(&:to_sym).wont_include(:split_file_name)
end

it :has_no_type_when_not_forced do
pluginator = Pluginator::Autodetect.new("something", plugins_dir_name: 'kitchen')
pluginator.type.must_be_nil
end

it :defines_type_method_dynamically do
pluginator = Pluginator::Autodetect.new("something", :type => "math", plugins_dir_name: 'kitchen')
pluginator.type.wont_be_nil
pluginator.type.must_equal(pluginator["math"])
end
end

it :loads_plugins_automatically_for_group do
pluginator = Pluginator::Autodetect.new("something")
pluginator.types.must_include("stats")
Expand Down