Skip to content

Commit bde90d7

Browse files
committed
Adds support to change the top level directory for plugins
* previously by default, pluginator would only look in the directory named plugins. While this is a great notion, many existing plugin systems do not follow this path. This attempts to allow the user to change the default plugins directory to something different. Example: lib/plugins/my_group/plugin_name.rb can now be lib/alt_plugins/my_group/plugin_name.rb.
1 parent e205d0e commit bde90d7

File tree

10 files changed

+188
-10
lines changed

10 files changed

+188
-10
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
/*.gem
2+
.bundle
23
/Gemfile.lock
34
/coverage
45
/doc

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ plugins.types => Array of types
5656
- `type: "<type>"` - Load plugins only of given type, optional, makes `type` method accessible.
5757
- `prefix: "/prefix"` - Load plugins only from this paths, optional, default `/lib`.
5858
- `extends: %i[<extensions>]` - Extend pluginator with given extensions.
59+
- `plugins_dir_name: 'plugins'` - the top level directory name to use when looking for plugins, defaults to "plugins"
5960

6061
## Extensions
6162

lib/pluginator/autodetect.rb

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,11 +41,12 @@ class Autodetect
4141
# @option prefix [String] a prefix for finding plugins if forcing,
4242
# by default only `/lib` is checked,
4343
# regexp notation is allowed, for example `/(lib|local_lib)`
44-
44+
# @option plugins_dir_name [String] the top level directory name to use when looking for plugins
4545
def initialize(group, options={})
4646
super(group)
4747
@force_prefix = options[:prefix]
4848
@force_type = options[:type]
49+
@plugins_dir_name = options[:plugins_dir_name] || 'plugins'
4950
refresh
5051
end
5152

@@ -55,7 +56,7 @@ def initialize(group, options={})
5556
#
5657
# Use it after gem list change, for example after `Gem.install("new_gem")`
5758
def refresh
58-
plugin_lists = FormattedFinder.new(@force_prefix, @group, @force_type)
59+
plugin_lists = FormattedFinder.new(@force_prefix, @group, @force_type, @plugins_dir_name)
5960
register_plugins(plugin_lists.loaded_plugins_path)
6061
load_plugins(plugin_lists.load_path_plugins_paths)
6162
activate_plugins(plugin_lists.gem_plugins_paths)

lib/pluginator/autodetect/finder.rb

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,8 @@ class Autodetect
2323
# Find plugins
2424
class Finder
2525

26-
attr_reader :loaded_plugins_path, :load_path_plugins_paths, :gem_plugins_paths
26+
attr_reader :loaded_plugins_path, :load_path_plugins_paths,
27+
:gem_plugins_paths, :plugins_dir_name, :group
2728

2829
# Automatically load plugins for given group (and type)
2930
#
@@ -32,19 +33,21 @@ class Finder
3233
# regexp notation is allowed, for example `/[lib|]`
3334
# @param group [String] name of the plugins group
3435
# @param force_type [String] name of the plugin type if forcing
35-
def initialize(force_prefix, group, force_type)
36+
# @option plugins_dir_name [String] the top level directory name to use when looking for plugins
37+
def initialize(force_prefix, group, force_type, plugins_dir_name = 'plugins')
3638
@force_prefix = force_prefix
3739
@group = group
3840
@force_type = force_type
3941
@pattern = file_name_pattern
42+
@plugins_dir_name = plugins_dir_name
4043
find_paths
4144
end
4245

4346
private
4447

4548
# group => pattern
4649
def file_name_pattern
47-
"plugins/#{@group}/#{@force_type || "**"}/*.rb"
50+
File.join(plugins_dir_name, group, (force_type || '**'), '*.rb' )
4851
end
4952

5053
def find_paths
@@ -81,7 +84,7 @@ def split_file_names(file_names)
8184
def split_file_name(file_name)
8285
prefix = @force_prefix || "/lib"
8386
type = @force_type || ".*"
84-
match = file_name.match(%r{.*#{prefix}/(plugins/(#{@group}/(#{type})/[^/]*)\.rb)$})
87+
match = file_name.match(%r{.*#{prefix}/(#{plugins_dir_name}/(#{@group}/(#{type})/[^/]*)\.rb)$})
8588
match[-3..-1] if match
8689
end
8790

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
=begin
2+
Copyright 2013 Michal Papis <[email protected]>
3+
4+
This file is part of pluginator.
5+
6+
pluginator is free software: you can redistribute it and/or modify
7+
it under the terms of the GNU Lesser General Public License as published
8+
by the Free Software Foundation, either version 3 of the License, or
9+
(at your option) any later version.
10+
11+
pluginator is distributed in the hope that it will be useful,
12+
but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+
GNU Lesser General Public License for more details.
15+
16+
You should have received a copy of the GNU Lesser General Public License
17+
along with pluginator. If not, see <http://www.gnu.org/licenses/>.
18+
=end
19+
20+
class Something::Math::Decrease
21+
def self.type
22+
"decrease"
23+
end
24+
def self.action(number)
25+
number - 1
26+
end
27+
end
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
=begin
2+
Copyright 2013 Michal Papis <[email protected]>
3+
4+
This file is part of pluginator.
5+
6+
pluginator is free software: you can redistribute it and/or modify
7+
it under the terms of the GNU Lesser General Public License as published
8+
by the Free Software Foundation, either version 3 of the License, or
9+
(at your option) any later version.
10+
11+
pluginator is distributed in the hope that it will be useful,
12+
but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+
GNU Lesser General Public License for more details.
15+
16+
You should have received a copy of the GNU Lesser General Public License
17+
along with pluginator. If not, see <http://www.gnu.org/licenses/>.
18+
=end
19+
20+
class Something::Math::Increase
21+
def self.type
22+
"increase"
23+
end
24+
def self.action(number)
25+
number + 1
26+
end
27+
end
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
=begin
2+
Copyright 2013 Michal Papis <[email protected]>
3+
4+
This file is part of pluginator.
5+
6+
pluginator is free software: you can redistribute it and/or modify
7+
it under the terms of the GNU Lesser General Public License as published
8+
by the Free Software Foundation, either version 3 of the License, or
9+
(at your option) any later version.
10+
11+
pluginator is distributed in the hope that it will be useful,
12+
but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+
GNU Lesser General Public License for more details.
15+
16+
You should have received a copy of the GNU Lesser General Public License
17+
along with pluginator. If not, see <http://www.gnu.org/licenses/>.
18+
=end
19+
20+
class Something::Nested::Structure::Test
21+
22+
def self.action
23+
42
24+
end
25+
end
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
=begin
2+
Copyright 2013 Michal Papis <[email protected]>
3+
4+
This file is part of pluginator.
5+
6+
pluginator is free software: you can redistribute it and/or modify
7+
it under the terms of the GNU Lesser General Public License as published
8+
by the Free Software Foundation, either version 3 of the License, or
9+
(at your option) any later version.
10+
11+
pluginator is distributed in the hope that it will be useful,
12+
but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+
GNU Lesser General Public License for more details.
15+
16+
You should have received a copy of the GNU Lesser General Public License
17+
along with pluginator. If not, see <http://www.gnu.org/licenses/>.
18+
=end
19+
20+
class Something::Stats::Max
21+
22+
def self.handles?(what)
23+
%w{ max maximum }.include?(what)
24+
end
25+
26+
def self.action
27+
42
28+
end
29+
end

test/pluginator/autodetect_test.rb

Lines changed: 67 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,18 +40,81 @@ def gem_files(*paths)
4040
end
4141

4242
describe Pluginator::Autodetect do
43-
before do
44-
@math_parsed = [
43+
let(:math_files) do
44+
gem_files(math_parsed.map(&:first))
45+
end
46+
47+
let(:math_parsed) do
48+
[
4549
["plugins/something/math/increase.rb", "something/math/increase", "math"],
4650
["plugins/something/math/decrease.rb", "something/math/decrease", "math"]
4751
]
48-
@math_files = gem_files(@math_parsed.map(&:first))
49-
@all_files = gem_files(
52+
end
53+
54+
let(:all_files) do
55+
gem_files(
5056
"plugins/something/math/increase.rb", "plugins/something/math/decrease.rb",
5157
"plugins/something/nested/structure/test.rb", "plugins/something/stats/max.rb"
5258
)
5359
end
5460

61+
context :alt_plugins_dir do
62+
let(:math_parsed) do
63+
[
64+
["kitchen/something/math/increase.rb", "something/math/increase", "math"],
65+
["kitchen/something/math/decrease.rb", "something/math/decrease", "math"]
66+
]
67+
end
68+
69+
let(:all_files) do
70+
gem_files(
71+
"kitchen/something/math/increase.rb", "kitchen/something/math/decrease.rb",
72+
"kitchen/something/nested/structure/test.rb", "kitchen/something/stats/max.rb"
73+
)
74+
end
75+
76+
it :loads_plugins_automatically_for_group do
77+
pluginator = Pluginator::Autodetect.new("something")
78+
pluginator.types.must_include("stats")
79+
pluginator.types.must_include("math")
80+
pluginator.types.size.must_equal(3)
81+
plugins = pluginator["math"].map(&:to_s)
82+
plugins.size.must_equal(2)
83+
plugins.must_include("Something::Math::Increase")
84+
plugins.must_include("Something::Math::Decrease")
85+
plugins.wont_include("Something::Math::Add")
86+
end
87+
88+
it :loads_plugins_automatically_for_group_type do
89+
pluginator = Pluginator::Autodetect.new("something", :type => "stats")
90+
pluginator.types.sort.must_equal(["stats"])
91+
end
92+
93+
it :makes_group_plugins_work do
94+
pluginator = Pluginator::Autodetect.new("something")
95+
pluginator.types.must_include("math")
96+
pluginator["math"].detect{|plugin| plugin.type == "increase" }.action(2).must_equal(3)
97+
pluginator["math"].detect{|plugin| plugin.type == "decrease" }.action(5).must_equal(4)
98+
end
99+
100+
it :hides_methods do
101+
pluginator = Pluginator::Autodetect.new("something")
102+
pluginator.public_methods.map(&:to_sym).must_include(:register_plugin)
103+
pluginator.public_methods.map(&:to_sym).wont_include(:split_file_name)
104+
end
105+
106+
it :has_no_type_when_not_forced do
107+
pluginator = Pluginator::Autodetect.new("something")
108+
pluginator.type.must_be_nil
109+
end
110+
111+
it :defines_type_method_dynamically do
112+
pluginator = Pluginator::Autodetect.new("something", :type => "math")
113+
pluginator.type.wont_be_nil
114+
pluginator.type.must_equal(pluginator["math"])
115+
end
116+
end
117+
55118
it :loads_plugins_automatically_for_group do
56119
pluginator = Pluginator::Autodetect.new("something")
57120
pluginator.types.must_include("stats")

0 commit comments

Comments
 (0)