pluggability 0.4.3 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/ChangeLog +82 -8
- data/{History.rdoc → History.md} +17 -9
- data/Manifest.txt +2 -2
- data/{README.rdoc → README.md} +55 -48
- data/Rakefile +27 -26
- data/lib/pluggability.rb +47 -57
- data/spec/pluggability_spec.rb +60 -32
- metadata +63 -75
- metadata.gz.sig +0 -0
- data/.gemtest +0 -0
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
|
-
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 12c5c85715daf5f17c850a2e30068fb8cf9e91e78215228273422093768b040e
|
|
4
|
+
data.tar.gz: 21f1401f755a1f4fc4c0c1d80b40497701a5eddeeb9c78c5851aa1d9d14840ca
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 294a6fa9924a062b02ed858b87a20d75f298ec47e026fbc9bedb25e61fd4ec8a9f8207a3cb72202317df2a516cf269b7e06089ef008baddd5cd342f0e173e3bf
|
|
7
|
+
data.tar.gz: b50fcf256c417e4e7ff0dff4e09f540c7719320beeae835ac00463a2427056f708f0e3ccc6fa1446046f83cc329e7409c0f8c8b86da4c12c7ee7b67c6dfd3420
|
checksums.yaml.gz.sig
CHANGED
|
Binary file
|
data.tar.gz.sig
CHANGED
|
Binary file
|
data/ChangeLog
CHANGED
|
@@ -1,18 +1,92 @@
|
|
|
1
|
-
|
|
1
|
+
2018-01-19 Michael Granger <ged@FaerieMUD.org>
|
|
2
|
+
|
|
3
|
+
* .ruby-version, README.md, Rakefile, pluggability.gemspec:
|
|
4
|
+
Bump testing Ruby to 2.5, update metadata.
|
|
5
|
+
[f251c6649802] [tip]
|
|
6
|
+
|
|
7
|
+
2018-01-19 Mahlon E. Smith <mahlon@laika.com>
|
|
8
|
+
|
|
9
|
+
* lib/pluggability.rb, spec/pluggability_spec.rb:
|
|
10
|
+
Only files should be valid candidates.
|
|
11
|
+
[05d6834adc74]
|
|
12
|
+
|
|
13
|
+
2017-11-20 Michael Granger <ged@FaerieMUD.org>
|
|
14
|
+
|
|
15
|
+
* lib/pluggability.rb, pluggability.gemspec,
|
|
16
|
+
spec/pluggability_spec.rb:
|
|
17
|
+
Don't use require to test for plugins
|
|
18
|
+
[f926443712be] [github/master]
|
|
19
|
+
|
|
20
|
+
2017-08-28 Michael Granger <ged@FaerieMUD.org>
|
|
21
|
+
|
|
22
|
+
* Rakefile, pluggability.gemspec:
|
|
23
|
+
Specify rdoc development version to fix dependency issues.
|
|
24
|
+
[47f7c4369690]
|
|
25
|
+
|
|
26
|
+
* spec/pluggability_spec.rb:
|
|
27
|
+
Remove old loggability spec setup, fix whitespace
|
|
28
|
+
[944359b4db94]
|
|
29
|
+
|
|
30
|
+
* .gems, .ruby-gemset, .ruby-version, .rvm.gems, .rvmrc,
|
|
31
|
+
.tm_properties, History.md, History.rdoc, Manifest.txt, README.md,
|
|
32
|
+
README.rdoc, Rakefile, pluggability.gemspec:
|
|
33
|
+
Update project files/Ruby version.
|
|
34
|
+
[0174f10b17b6]
|
|
35
|
+
|
|
36
|
+
2015-03-04 Michael Granger <ged@FaerieMUD.org>
|
|
37
|
+
|
|
38
|
+
* .hgtags:
|
|
39
|
+
Added tag v0.4.3 for changeset 3aad17b08592
|
|
40
|
+
[5619c48d3790]
|
|
2
41
|
|
|
3
42
|
* .hgsigs:
|
|
4
|
-
Added signature for changeset
|
|
5
|
-
[
|
|
43
|
+
Added signature for changeset 599945826d8b
|
|
44
|
+
[3aad17b08592] [v0.4.3]
|
|
45
|
+
|
|
46
|
+
* History.rdoc, lib/pluggability.rb:
|
|
47
|
+
Bump the patch version, update history.
|
|
48
|
+
[599945826d8b]
|
|
49
|
+
|
|
50
|
+
* Rakefile, lib/pluggability.rb, pluggability.gemspec:
|
|
51
|
+
Add a workaround for older Rubygems to avoid Bundler problems.
|
|
52
|
+
[0ee054190d01]
|
|
6
53
|
|
|
7
54
|
* .hgtags:
|
|
8
|
-
Added tag v0.4.
|
|
9
|
-
[
|
|
55
|
+
Added tag v0.4.2 for changeset 4a2f5cde833c
|
|
56
|
+
[b69ae7e03433]
|
|
57
|
+
|
|
58
|
+
* .hgsigs:
|
|
59
|
+
Added signature for changeset 459f8db09b8c
|
|
60
|
+
[4a2f5cde833c] [v0.4.2]
|
|
61
|
+
|
|
62
|
+
* History.rdoc, lib/pluggability.rb:
|
|
63
|
+
Bump the patch version, update history.
|
|
64
|
+
[459f8db09b8c]
|
|
65
|
+
|
|
66
|
+
* Merged with 5bcb7e1a02d1
|
|
67
|
+
[5a267db5f2fd]
|
|
68
|
+
|
|
69
|
+
* Rakefile, pluggability.gemspec:
|
|
70
|
+
Set the minimum Rubygems version for #find_latest_files support.
|
|
71
|
+
|
|
72
|
+
Fixes #1.
|
|
73
|
+
[192347e63fb3]
|
|
10
74
|
|
|
11
75
|
2015-03-03 Michael Granger <ged@FaerieMUD.org>
|
|
12
76
|
|
|
13
|
-
* History.rdoc, Rakefile:
|
|
77
|
+
* History.rdoc, Rakefile, pluggability.gemspec:
|
|
14
78
|
Update History
|
|
15
|
-
[
|
|
79
|
+
[62ff537bb489]
|
|
80
|
+
|
|
81
|
+
2015-03-03 Mahlon E. Smith <mahlon@laika.com>
|
|
82
|
+
|
|
83
|
+
* .hgsigs:
|
|
84
|
+
Added signature for changeset 7f6ff521c94a
|
|
85
|
+
[5bcb7e1a02d1]
|
|
86
|
+
|
|
87
|
+
* .hgtags:
|
|
88
|
+
Added tag v0.4.1 for changeset 4b314c3ea2cb
|
|
89
|
+
[7f6ff521c94a]
|
|
16
90
|
|
|
17
91
|
2015-03-03 Mahlon E. Smith <mahlon@martini.nu>
|
|
18
92
|
|
|
@@ -25,7 +99,7 @@
|
|
|
25
99
|
|
|
26
100
|
* Rakefile, loggability.gemspec, pluggability.gemspec:
|
|
27
101
|
Fix the gemspec name
|
|
28
|
-
[f17b18fbdb15]
|
|
102
|
+
[f17b18fbdb15]
|
|
29
103
|
|
|
30
104
|
* .rvmrc, .travis.yml, Gemfile, Rakefile, loggability.gemspec:
|
|
31
105
|
Prep for travis-ci builds
|
data/{History.rdoc → History.md}
RENAMED
|
@@ -1,18 +1,26 @@
|
|
|
1
|
-
|
|
1
|
+
## v0.5.0 [2018-01-19] Michael Granger <ged@FaerieMUD.org>
|
|
2
|
+
|
|
3
|
+
Enhancements:
|
|
4
|
+
|
|
5
|
+
- Update the mechanism used to search for derivatives for more-modern Rubygems,
|
|
6
|
+
Bundler, etc.
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
## v0.4.3 [2015-03-04] Michael Granger <ged@FaerieMUD.org>
|
|
2
10
|
|
|
3
11
|
Bugfix:
|
|
4
12
|
|
|
5
13
|
- Add a workaround for older Rubygems to avoid Bundler problems.
|
|
6
14
|
|
|
7
15
|
|
|
8
|
-
|
|
16
|
+
## v0.4.2 [2015-03-04] Michael Granger <ged@FaerieMUD.org>
|
|
9
17
|
|
|
10
18
|
Bugfixes:
|
|
11
19
|
|
|
12
20
|
- Set the minimum Rubygems version for #find_latest_files support [#1].
|
|
13
21
|
|
|
14
22
|
|
|
15
|
-
|
|
23
|
+
## v0.4.1 [2015-03-03] Mahlon E. Smith <mahlon@martini.nu>
|
|
16
24
|
|
|
17
25
|
Bugfix:
|
|
18
26
|
|
|
@@ -20,35 +28,35 @@ Bugfix:
|
|
|
20
28
|
when finding files to load for .load_all.
|
|
21
29
|
|
|
22
30
|
|
|
23
|
-
|
|
31
|
+
## v0.4.0 [2014-01-08] Michael Granger <ged@FaerieMUD.org>
|
|
24
32
|
|
|
25
33
|
- Add a name attribute to plugins for introspection.
|
|
26
34
|
|
|
27
35
|
|
|
28
|
-
|
|
36
|
+
## v0.3.0 [2013-09-25] Michael Granger <ged@FaerieMUD.org>
|
|
29
37
|
|
|
30
38
|
- Add plugin exclusion patterns
|
|
31
39
|
|
|
32
40
|
|
|
33
|
-
|
|
41
|
+
## v0.2.0 [2013-03-28] Michael Granger <ged@FaerieMUD.org>
|
|
34
42
|
|
|
35
43
|
- Fix loading of grandchildren of plugins
|
|
36
44
|
- Rename Pluggability::FactoryError to
|
|
37
45
|
Pluggability::PluginError (with backward-compatibility aliases)
|
|
38
46
|
|
|
39
47
|
|
|
40
|
-
|
|
48
|
+
## v0.1.0 [2013-03-27] Michael Granger <ged@FaerieMUD.org>
|
|
41
49
|
|
|
42
50
|
- Add loading via underbarred name variants (CommaDelimitedThing ->
|
|
43
51
|
comma_delimited)
|
|
44
52
|
- Rename some stuff for consistency.
|
|
45
53
|
|
|
46
|
-
|
|
54
|
+
## v0.0.2 [2012-08-13] Michael Granger <ged@FaerieMUD.org>
|
|
47
55
|
|
|
48
56
|
Simplify Pluggability#derivatives.
|
|
49
57
|
|
|
50
58
|
|
|
51
|
-
|
|
59
|
+
## v0.0.1 [2012-08-03] Michael Granger <ged@FaerieMUD.org>
|
|
52
60
|
|
|
53
61
|
First release after renaming from PluginFactory.
|
|
54
62
|
|
data/Manifest.txt
CHANGED
data/{README.rdoc → README.md}
RENAMED
|
@@ -1,22 +1,32 @@
|
|
|
1
|
-
|
|
1
|
+
# pluggability
|
|
2
2
|
|
|
3
|
-
project
|
|
4
|
-
|
|
5
|
-
github :: http://github.com/ged/pluggability
|
|
3
|
+
project
|
|
4
|
+
: https://bitbucket.org/ged/pluggability
|
|
6
5
|
|
|
6
|
+
docs
|
|
7
|
+
: http://deveiate.org/code/pluggability
|
|
7
8
|
|
|
8
|
-
|
|
9
|
+
github
|
|
10
|
+
: http://github.com/ged/pluggability
|
|
9
11
|
|
|
10
|
-
Pluggability is a mixin module that turns an including class into a
|
|
11
|
-
factory for its derivatives, capable of searching for and loading them
|
|
12
|
-
by name. This is useful when you have an abstract base class which
|
|
13
|
-
defines an interface and basic functionality for a part of a larger
|
|
14
|
-
system, and a collection of subclasses which implement the interface for
|
|
15
|
-
different underlying functionality.
|
|
16
12
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
13
|
+
## Description
|
|
14
|
+
|
|
15
|
+
Pluggability is a toolkit for creating plugins.
|
|
16
|
+
|
|
17
|
+
It provides a mixin that extends your class with methods to load and instantiate its subclasses by name. So instead of:
|
|
18
|
+
|
|
19
|
+
require 'acme/adapter/png'
|
|
20
|
+
png_adapter = Acme::Adapter::PNG.new( 'file.png' )
|
|
21
|
+
|
|
22
|
+
you can do:
|
|
23
|
+
|
|
24
|
+
require 'acme/adapter'
|
|
25
|
+
png_adapter = Acme::Adapter.create( :png, 'file.png' )
|
|
26
|
+
|
|
27
|
+
A full example of where this might be useful is in a program which generates
|
|
28
|
+
output with a 'driver' object, which provides a unified interface but generates
|
|
29
|
+
different kinds of output.
|
|
20
30
|
|
|
21
31
|
First the abstract base class, which is extended with Pluggability:
|
|
22
32
|
|
|
@@ -26,7 +36,7 @@ First the abstract base class, which is extended with Pluggability:
|
|
|
26
36
|
|
|
27
37
|
class MyGem::Driver
|
|
28
38
|
extend Pluggability
|
|
29
|
-
plugin_prefixes "drivers"
|
|
39
|
+
plugin_prefixes "mygem/drivers"
|
|
30
40
|
end
|
|
31
41
|
|
|
32
42
|
We can have one driver that outputs PDF documents:
|
|
@@ -60,14 +70,13 @@ it by its short name:
|
|
|
60
70
|
ascii_driver = MyGem::Driver.create( :ascii, :columns => 80 )
|
|
61
71
|
|
|
62
72
|
|
|
63
|
-
|
|
73
|
+
### How Plugins Are Loaded
|
|
64
74
|
|
|
65
|
-
The
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
formats:
|
|
75
|
+
The `create` class method added to your class by Pluggability searches for your
|
|
76
|
+
module using several different strategies. It tries various permutations of the
|
|
77
|
+
base class's name in combination with the derivative requested. For example,
|
|
78
|
+
assume we want to make a `LogReader` base class, and then use plugins to define
|
|
79
|
+
readers for different log formats:
|
|
71
80
|
|
|
72
81
|
require 'pluggability'
|
|
73
82
|
|
|
@@ -88,11 +97,10 @@ Pluggability searches for modules with the following names:
|
|
|
88
97
|
apache_log_reader
|
|
89
98
|
apache
|
|
90
99
|
|
|
91
|
-
Obviously the last one might load something other than what is intended,
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
searching for a subclass:
|
|
100
|
+
Obviously the last one might load something other than what is intended, so you
|
|
101
|
+
can also tell Pluggability that plugins should be loaded from a subdirectory by
|
|
102
|
+
declaring one or more `plugin_prefixes` in the base class. Each prefix will be
|
|
103
|
+
tried (in the order they're declared) when searching for a subclass:
|
|
96
104
|
|
|
97
105
|
class LogReader
|
|
98
106
|
extend Pluggability
|
|
@@ -134,16 +142,16 @@ will change the search to include:
|
|
|
134
142
|
'logreader/apache'
|
|
135
143
|
'logreader/Apache'
|
|
136
144
|
|
|
137
|
-
If the plugin is not found, a Pluggability::PluginError is raised, and
|
|
138
|
-
|
|
145
|
+
If the plugin is not found, a Pluggability::PluginError is raised, and the
|
|
146
|
+
message will list all the permutations that were tried.
|
|
139
147
|
|
|
140
148
|
|
|
141
|
-
|
|
149
|
+
### Preloaded Plugins
|
|
142
150
|
|
|
143
|
-
Sometimes you don't want to wait for plugins to be loaded on demand. For
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
151
|
+
Sometimes you don't want to wait for plugins to be loaded on demand. For that
|
|
152
|
+
case, Pluggability provides the Pluggability#load_all method. This will find
|
|
153
|
+
all possible matches for plugin files and load them, returning an Array of all
|
|
154
|
+
the loaded classes:
|
|
147
155
|
|
|
148
156
|
class Template::Tag
|
|
149
157
|
extend Pluggability
|
|
@@ -153,11 +161,10 @@ them, returning an Array of all the loaded classes:
|
|
|
153
161
|
tag_classes = Template::Tag.load_all
|
|
154
162
|
|
|
155
163
|
|
|
156
|
-
|
|
164
|
+
### Excluding Some Files
|
|
157
165
|
|
|
158
|
-
You can also prevent some files from being automatically loaded by
|
|
159
|
-
|
|
160
|
-
load_all[rdoc-ref:Pluggability#load_all] by setting one or more exclusion
|
|
166
|
+
You can also prevent some files from being automatically loaded by either
|
|
167
|
+
Pluggability#create or Pluggability#load_all by setting one or more exclusion
|
|
161
168
|
patterns:
|
|
162
169
|
|
|
163
170
|
LogReader.plugin_exclusions 'spec/*', %r{/test/}
|
|
@@ -165,11 +172,11 @@ patterns:
|
|
|
165
172
|
The patterns can either be Regexps or glob Strings.
|
|
166
173
|
|
|
167
174
|
|
|
168
|
-
|
|
175
|
+
### Logging
|
|
169
176
|
|
|
170
|
-
If you need a little more insight into what's going on, Pluggability
|
|
171
|
-
|
|
172
|
-
|
|
177
|
+
If you need a little more insight into what's going on, Pluggability uses the
|
|
178
|
+
[Loggability](https://rubygems.org/gems/loggability) library. Just set the log
|
|
179
|
+
level to 'debug' and it'll explain what's going on:
|
|
173
180
|
|
|
174
181
|
require 'pluggability'
|
|
175
182
|
require 'loggability'
|
|
@@ -213,16 +220,16 @@ this might generate a log that looks (something) like:
|
|
|
213
220
|
"ringbufferlogreader", "ringbufferLogReader", "ringbuffer"]
|
|
214
221
|
|
|
215
222
|
|
|
216
|
-
|
|
223
|
+
## Installation
|
|
217
224
|
|
|
218
225
|
gem install pluggability
|
|
219
226
|
|
|
220
227
|
|
|
221
|
-
|
|
228
|
+
## Contributing
|
|
222
229
|
|
|
223
230
|
You can check out the current development source with Mercurial via its
|
|
224
|
-
|
|
225
|
-
|
|
231
|
+
[Mercurial repo](https://bitbucket.org/ged/pluggability). Or if you prefer Git,
|
|
232
|
+
via [its Github mirror](https://github.com/ged/pluggability).
|
|
226
233
|
|
|
227
234
|
After checking out the source, run:
|
|
228
235
|
|
|
@@ -232,9 +239,9 @@ This task will install any missing dependencies, run the tests/specs,
|
|
|
232
239
|
and generate the API documentation.
|
|
233
240
|
|
|
234
241
|
|
|
235
|
-
|
|
242
|
+
## License
|
|
236
243
|
|
|
237
|
-
Copyright (c) 2008-
|
|
244
|
+
Copyright (c) 2008-2018, Michael Granger and Martin Chase
|
|
238
245
|
All rights reserved.
|
|
239
246
|
|
|
240
247
|
Redistribution and use in source and binary forms, with or without
|
data/Rakefile
CHANGED
|
@@ -16,30 +16,30 @@ Hoe.plugin :deveiate
|
|
|
16
16
|
|
|
17
17
|
Hoe.plugins.delete :rubyforge
|
|
18
18
|
|
|
19
|
-
hoespec = Hoe.spec 'pluggability' do
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
19
|
+
hoespec = Hoe.spec 'pluggability' do |spec|
|
|
20
|
+
spec.readme_file = 'README.md'
|
|
21
|
+
spec.history_file = 'History.md'
|
|
22
|
+
spec.extra_rdoc_files = Rake::FileList[ '*.rdoc', '*.md' ]
|
|
23
|
+
spec.license 'BSD-3-Clause'
|
|
24
|
+
spec.urls = {
|
|
25
|
+
home: 'http://bitbucket.org/ged/pluggability',
|
|
26
|
+
code: 'http://bitbucket.org/ged/pluggability',
|
|
27
|
+
docs: 'http://deveiate.org/code/pluggability',
|
|
28
|
+
github: 'http://github.com/ged/pluggability',
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
spec.developer 'Martin Chase', 'stillflame@FaerieMUD.org'
|
|
32
|
+
spec.developer 'Michael Granger', 'ged@FaerieMUD.org'
|
|
33
|
+
|
|
34
|
+
spec.dependency 'loggability', '~> 0.12'
|
|
35
|
+
spec.dependency 'hoe-deveiate', '~> 0.9', :development
|
|
36
|
+
spec.dependency 'rdoc', '~> 5.1', :development
|
|
37
|
+
|
|
38
|
+
spec.require_ruby_version( '>=2.3.4' )
|
|
39
|
+
spec.hg_sign_tags = true if spec.respond_to?( :hg_sign_tags= )
|
|
40
|
+
spec.check_history_on_release = true if spec.respond_to?( :check_history_on_release= )
|
|
41
|
+
|
|
42
|
+
spec.rdoc_locations << "deveiate:/usr/local/www/public/code/#{remote_rdoc_dir}"
|
|
43
43
|
end
|
|
44
44
|
|
|
45
45
|
ENV['VERSION'] ||= hoespec.spec.version.to_s
|
|
@@ -70,8 +70,7 @@ if File.directory?( '.hg' )
|
|
|
70
70
|
end
|
|
71
71
|
end
|
|
72
72
|
|
|
73
|
-
task :gemspec => GEMSPEC
|
|
74
|
-
file GEMSPEC => __FILE__
|
|
73
|
+
task :gemspec => [ 'ChangeLog', __FILE__, 'Manifest.txt', GEMSPEC ]
|
|
75
74
|
task GEMSPEC do |task|
|
|
76
75
|
spec = $hoespec.spec
|
|
77
76
|
spec.files.delete( '.gemtest' )
|
|
@@ -84,3 +83,5 @@ end
|
|
|
84
83
|
|
|
85
84
|
CLOBBER.include( GEMSPEC.to_s )
|
|
86
85
|
|
|
86
|
+
task :default => :gemspec
|
|
87
|
+
|
data/lib/pluggability.rb
CHANGED
|
@@ -12,7 +12,7 @@ module Pluggability
|
|
|
12
12
|
|
|
13
13
|
|
|
14
14
|
# Library version
|
|
15
|
-
VERSION = '0.
|
|
15
|
+
VERSION = '0.5.0'
|
|
16
16
|
|
|
17
17
|
|
|
18
18
|
# An exception class for Pluggability specific errors.
|
|
@@ -273,12 +273,13 @@ module Pluggability
|
|
|
273
273
|
else
|
|
274
274
|
Gem.find_files( glob )
|
|
275
275
|
end
|
|
276
|
+
|
|
276
277
|
Pluggability.log.debug " found %d matching files" % [ candidates.length ]
|
|
277
278
|
next if candidates.empty?
|
|
278
279
|
|
|
279
280
|
candidates.each do |path|
|
|
280
281
|
next if self.is_excluded_path?( path )
|
|
281
|
-
|
|
282
|
+
Kernel.load( path )
|
|
282
283
|
end
|
|
283
284
|
end
|
|
284
285
|
|
|
@@ -286,15 +287,13 @@ module Pluggability
|
|
|
286
287
|
end
|
|
287
288
|
|
|
288
289
|
|
|
289
|
-
### Calculates an appropriate filename for the derived class using the
|
|
290
|
-
###
|
|
291
|
-
###
|
|
292
|
-
###
|
|
293
|
-
###
|
|
294
|
-
###
|
|
295
|
-
### <tt>
|
|
296
|
-
### require line is tried with both <tt>'foo/'</tt> and <tt>'bar/'</tt>
|
|
297
|
-
### prepended to it.
|
|
290
|
+
### Calculates an appropriate filename for the derived class using the name of
|
|
291
|
+
### the base class and tries to load it via <tt>load</tt>. If the including
|
|
292
|
+
### class responds to a method named <tt>plugin_prefixes</tt>, its return value
|
|
293
|
+
### (either a String, or an array of Strings) is added to the list of prefix
|
|
294
|
+
### directories to try when attempting to load modules. Eg., if
|
|
295
|
+
### <tt>class.plugin_prefixes</tt> returns <tt>['foo','bar']</tt> the require
|
|
296
|
+
### line is tried with both <tt>'foo/'</tt> and <tt>'bar/'</tt> prepended to it.
|
|
298
297
|
def load_derivative( class_name )
|
|
299
298
|
Pluggability.log.debug "Loading derivative #{class_name}"
|
|
300
299
|
|
|
@@ -334,58 +333,49 @@ module Pluggability
|
|
|
334
333
|
|
|
335
334
|
|
|
336
335
|
### Search for the module with the specified <tt>mod_name</tt>, using any
|
|
337
|
-
### #plugin_prefixes that have been set.
|
|
336
|
+
### #plugin_prefixes that have been set. Return the result of +Kernel.load+ing
|
|
337
|
+
### the first candidate.
|
|
338
338
|
def require_derivative( mod_name )
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
subdirs << '' if subdirs.empty?
|
|
342
|
-
Pluggability.log.debug "Subdirs are: %p" % [subdirs]
|
|
343
|
-
fatals = []
|
|
344
|
-
tries = []
|
|
345
|
-
|
|
346
|
-
# Iterate over the subdirs until we successfully require a
|
|
347
|
-
# module.
|
|
348
|
-
subdirs.map( &:strip ).each do |subdir|
|
|
349
|
-
self.make_require_path( mod_name, subdir ).each do |path|
|
|
350
|
-
next if self.is_excluded_path?( path )
|
|
351
|
-
|
|
352
|
-
Pluggability.logger.debug "Trying #{path}..."
|
|
353
|
-
tries << path
|
|
354
|
-
|
|
355
|
-
# Try to require the module, saving errors and jumping
|
|
356
|
-
# out of the catch block on success.
|
|
357
|
-
begin
|
|
358
|
-
require( path.untaint )
|
|
359
|
-
rescue LoadError => err
|
|
360
|
-
Pluggability.log.debug "No module at '%s', trying the next alternative: '%s'" %
|
|
361
|
-
[ path, err.message ]
|
|
362
|
-
rescue Exception => err
|
|
363
|
-
fatals << err
|
|
364
|
-
Pluggability.log.error "Found '#{path}', but encountered an error: %s\n\t%s" %
|
|
365
|
-
[ err.message, err.backtrace.join("\n\t") ]
|
|
366
|
-
else
|
|
367
|
-
Pluggability.log.info "Loaded '#{path}' without error."
|
|
368
|
-
return path
|
|
369
|
-
end
|
|
370
|
-
end
|
|
371
|
-
end
|
|
372
|
-
|
|
373
|
-
Pluggability.logger.debug "fatals = %p" % [ fatals ]
|
|
374
|
-
|
|
375
|
-
# Re-raise is there was a file found, but it didn't load for
|
|
376
|
-
# some reason.
|
|
377
|
-
if fatals.empty?
|
|
339
|
+
plugin_path = self.find_plugin_path( mod_name )
|
|
340
|
+
unless plugin_path
|
|
378
341
|
errmsg = "Couldn't find a %s named '%s': tried %p" % [
|
|
379
342
|
self.plugin_type,
|
|
380
343
|
mod_name,
|
|
381
|
-
|
|
382
|
-
|
|
344
|
+
self.plugin_path_candidates( mod_name )
|
|
345
|
+
]
|
|
383
346
|
Pluggability.log.error( errmsg )
|
|
384
|
-
raise PluginError, errmsg
|
|
385
|
-
else
|
|
386
|
-
Pluggability.log.debug "Re-raising first fatal error"
|
|
387
|
-
Kernel.raise( fatals.first )
|
|
347
|
+
raise Pluggability::PluginError, errmsg
|
|
388
348
|
end
|
|
349
|
+
|
|
350
|
+
Kernel.load( plugin_path.untaint )
|
|
351
|
+
|
|
352
|
+
return plugin_path
|
|
353
|
+
end
|
|
354
|
+
|
|
355
|
+
|
|
356
|
+
### Search for the file that corresponds to +mod_name+ using the plugin prefixes
|
|
357
|
+
### and current Gem load path and return the path to the first candidate that
|
|
358
|
+
### exists.
|
|
359
|
+
def find_plugin_path( mod_name )
|
|
360
|
+
candidates = self.plugin_path_candidates( mod_name )
|
|
361
|
+
Pluggability.log.debug "Candidates for %p are: %p" % [ mod_name, candidates ]
|
|
362
|
+
|
|
363
|
+
candidate_paths = candidates.
|
|
364
|
+
flat_map {|path| Gem.find_latest_files( path ) }.
|
|
365
|
+
reject {|path| self.is_excluded_path?( path ) || ! File.file?(path) }
|
|
366
|
+
Pluggability.log.debug "Valid candidates in the current gemset: %p" % [ candidate_paths ]
|
|
367
|
+
|
|
368
|
+
return candidate_paths.first
|
|
369
|
+
end
|
|
370
|
+
|
|
371
|
+
|
|
372
|
+
### Return an Array of all the filenames a plugin of the given +mod_name+ might
|
|
373
|
+
### map to given the current plugin_prefixes.
|
|
374
|
+
def plugin_path_candidates( mod_name )
|
|
375
|
+
prefixes = self.plugin_prefixes
|
|
376
|
+
prefixes << '' if prefixes.empty?
|
|
377
|
+
|
|
378
|
+
return prefixes.flat_map {|pre| self.make_require_path(mod_name, pre) }
|
|
389
379
|
end
|
|
390
380
|
|
|
391
381
|
|
data/spec/pluggability_spec.rb
CHANGED
|
@@ -29,17 +29,11 @@ class SubSubPlugin < SubPlugin; end
|
|
|
29
29
|
#
|
|
30
30
|
describe Pluggability do
|
|
31
31
|
|
|
32
|
-
before( :all ) do
|
|
33
|
-
setup_logging()
|
|
34
|
-
end
|
|
35
|
-
|
|
36
32
|
before( :each ) do
|
|
37
33
|
Plugin.plugin_exclusions = []
|
|
34
|
+
allow( File ).to receive( :file? ).and_return( true )
|
|
38
35
|
end
|
|
39
36
|
|
|
40
|
-
after( :all ) do
|
|
41
|
-
reset_logging()
|
|
42
|
-
end
|
|
43
37
|
|
|
44
38
|
|
|
45
39
|
it "allows extended objects to declare one or more prefixes to use when requiring derviatives" do
|
|
@@ -47,7 +41,6 @@ describe Pluggability do
|
|
|
47
41
|
end
|
|
48
42
|
|
|
49
43
|
|
|
50
|
-
|
|
51
44
|
context "-extended class" do
|
|
52
45
|
|
|
53
46
|
it "knows about all of its derivatives" do
|
|
@@ -55,15 +48,17 @@ describe Pluggability do
|
|
|
55
48
|
to include( 'sub', 'subplugin', 'SubPlugin', SubPlugin )
|
|
56
49
|
end
|
|
57
50
|
|
|
51
|
+
|
|
58
52
|
it "returns derivatives directly if they're already loaded" do
|
|
59
53
|
class AlreadyLoadedPlugin < Plugin; end
|
|
60
|
-
expect( Kernel ).to_not receive( :
|
|
54
|
+
expect( Kernel ).to_not receive( :load )
|
|
61
55
|
expect( Plugin.create('alreadyloaded') ).to be_an_instance_of( AlreadyLoadedPlugin )
|
|
62
56
|
expect( Plugin.create('AlreadyLoaded') ).to be_an_instance_of( AlreadyLoadedPlugin )
|
|
63
57
|
expect( Plugin.create('AlreadyLoadedPlugin') ).to be_an_instance_of( AlreadyLoadedPlugin )
|
|
64
58
|
expect( Plugin.create(AlreadyLoadedPlugin) ).to be_an_instance_of( AlreadyLoadedPlugin )
|
|
65
59
|
end
|
|
66
60
|
|
|
61
|
+
|
|
67
62
|
it "filters errors that happen when creating an instance of derivatives so they " +
|
|
68
63
|
"point to the right place" do
|
|
69
64
|
class PugilistPlugin < Plugin
|
|
@@ -84,6 +79,7 @@ describe Pluggability do
|
|
|
84
79
|
expect( exception.backtrace.first ).to match(/#{__FILE__}/)
|
|
85
80
|
end
|
|
86
81
|
|
|
82
|
+
|
|
87
83
|
it "will refuse to create an object other than one of its derivatives" do
|
|
88
84
|
class Doppelgaenger; end
|
|
89
85
|
expect {
|
|
@@ -95,7 +91,10 @@ describe Pluggability do
|
|
|
95
91
|
it "will load new plugins from the require path if they're not loaded yet" do
|
|
96
92
|
loaded_class = nil
|
|
97
93
|
|
|
98
|
-
expect(
|
|
94
|
+
expect( Gem ).to receive( :find_latest_files ).
|
|
95
|
+
at_least( :once ).
|
|
96
|
+
and_return( ['/some/path/to/plugins/dazzle.rb'] )
|
|
97
|
+
expect( Kernel ).to receive( :load ).with( '/some/path/to/plugins/dazzle.rb' ) do |*args|
|
|
99
98
|
loaded_class = Class.new( Plugin )
|
|
100
99
|
# Simulate a named class, since we're not really requiring
|
|
101
100
|
Plugin.derivatives['dazzle'] = loaded_class
|
|
@@ -110,8 +109,8 @@ describe Pluggability do
|
|
|
110
109
|
"derivative fails" do
|
|
111
110
|
|
|
112
111
|
# at least 6 -> 3 variants * 2 paths
|
|
113
|
-
expect(
|
|
114
|
-
|
|
112
|
+
expect( Gem ).to receive( :find_latest_files ).at_least( 6 ).times.
|
|
113
|
+
and_return( [] )
|
|
115
114
|
|
|
116
115
|
expect {
|
|
117
116
|
Plugin.create('scintillating')
|
|
@@ -120,8 +119,12 @@ describe Pluggability do
|
|
|
120
119
|
|
|
121
120
|
|
|
122
121
|
it "will output a sensible description when a require succeeds, but it loads something unintended" do
|
|
123
|
-
|
|
124
|
-
|
|
122
|
+
expect( Gem ).to receive( :find_latest_files ).
|
|
123
|
+
at_least( :once ).
|
|
124
|
+
and_return( ['/some/path/to/corruscating.rb'] )
|
|
125
|
+
expect( Kernel ).to receive( :load ).
|
|
126
|
+
with( '/some/path/to/corruscating.rb' ).
|
|
127
|
+
and_return( true )
|
|
125
128
|
|
|
126
129
|
expect {
|
|
127
130
|
Plugin.create('corruscating')
|
|
@@ -129,46 +132,63 @@ describe Pluggability do
|
|
|
129
132
|
end
|
|
130
133
|
|
|
131
134
|
|
|
132
|
-
it "
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
expect(
|
|
135
|
+
it "doesn't rescue LoadErrors raised when loading the plugin" do
|
|
136
|
+
expect( Gem ).to receive( :find_latest_files ).
|
|
137
|
+
at_least( :once ).
|
|
138
|
+
and_return( ['/some/path/to/portable.rb'] )
|
|
139
|
+
expect( Kernel ).to receive( :load ).
|
|
140
|
+
with( '/some/path/to/portable.rb' ).
|
|
137
141
|
and_raise( ScriptError.new("error while parsing path") )
|
|
138
142
|
|
|
139
143
|
expect {
|
|
140
|
-
Plugin.create('portable')
|
|
144
|
+
Plugin.create( 'portable' )
|
|
141
145
|
}.to raise_error( ScriptError, /error while parsing/ )
|
|
142
146
|
end
|
|
143
147
|
|
|
144
148
|
|
|
149
|
+
it "ignores directories when finding derivatives" do
|
|
150
|
+
expect( Gem ).to receive( :find_latest_files ).
|
|
151
|
+
at_least( :once ).
|
|
152
|
+
and_return( ['/some/path/to/portable', '/some/path/to/portable.rb'] )
|
|
153
|
+
expect( File ).to receive( :file? ).and_return( false )
|
|
154
|
+
|
|
155
|
+
expect( Kernel ).to_not receive( :load ).with( '/some/path/to/portable' )
|
|
156
|
+
expect( Kernel ).to receive( :load ).
|
|
157
|
+
with( '/some/path/to/portable.rb' ).
|
|
158
|
+
and_return( true )
|
|
159
|
+
|
|
160
|
+
expect {
|
|
161
|
+
Plugin.create( 'portable' )
|
|
162
|
+
}.to raise_error( Pluggability::PluginError, /Require of '\S+' succeeded, but didn't load a Plugin/i )
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
|
|
145
166
|
it "can preload all of its derivatives" do
|
|
146
167
|
expect( Gem ).to receive( :find_latest_files ).with( 'plugins/*.rb' ).
|
|
147
168
|
and_return([ 'plugins/first.rb' ])
|
|
148
169
|
expect( Gem ).to receive( :find_latest_files ).with( 'plugins/private/*.rb' ).
|
|
149
170
|
and_return([ 'plugins/private/second.rb', 'plugins/private/third.rb' ])
|
|
150
171
|
|
|
151
|
-
expect(
|
|
172
|
+
expect( Kernel ).to receive( :load ).with( 'plugins/first.rb' ).
|
|
152
173
|
and_return( true )
|
|
153
|
-
expect(
|
|
174
|
+
expect( Kernel ).to receive( :load ).with( 'plugins/private/second.rb' ).
|
|
154
175
|
and_return( true )
|
|
155
|
-
expect(
|
|
176
|
+
expect( Kernel ).to receive( :load ).with( 'plugins/private/third.rb' ).
|
|
156
177
|
and_return( true )
|
|
157
178
|
|
|
158
179
|
Plugin.load_all
|
|
159
180
|
end
|
|
160
181
|
|
|
161
|
-
|
|
162
182
|
it "doesn't preload derivatives whose path matches a Regexp exclusion" do
|
|
163
183
|
expect( Gem ).to receive( :find_latest_files ).with( 'plugins/*.rb' ).
|
|
164
|
-
and_return([ 'plugins/first.rb' ])
|
|
184
|
+
and_return([ '/path/to/plugins/first.rb' ])
|
|
165
185
|
expect( Gem ).to receive( :find_latest_files ).with( 'plugins/private/*.rb' ).
|
|
166
|
-
and_return([ 'plugins/private/second.rb', 'plugins/private/third.rb' ])
|
|
186
|
+
and_return([ '/path/to/plugins/private/second.rb', '/path/to/plugins/private/third.rb' ])
|
|
167
187
|
|
|
168
|
-
expect(
|
|
188
|
+
expect( Kernel ).to receive( :load ).with( '/path/to/plugins/first.rb' ).
|
|
169
189
|
and_return( true )
|
|
170
|
-
expect(
|
|
171
|
-
expect(
|
|
190
|
+
expect( Kernel ).to_not receive( :load ).with( '/path/to/plugins/private/second.rb' )
|
|
191
|
+
expect( Kernel ).to_not receive( :load ).with( '/path/to/plugins/private/third.rb' )
|
|
172
192
|
|
|
173
193
|
Plugin.plugin_exclusions( %r{/private} )
|
|
174
194
|
Plugin.load_all
|
|
@@ -181,11 +201,11 @@ describe Pluggability do
|
|
|
181
201
|
expect( Gem ).to receive( :find_latest_files ).with( 'plugins/private/*.rb' ).
|
|
182
202
|
and_return([ 'plugins/private/second.rb', 'plugins/private/third.rb' ])
|
|
183
203
|
|
|
184
|
-
expect(
|
|
204
|
+
expect( Kernel ).to receive( :load ).with( 'plugins/first.rb' ).
|
|
185
205
|
and_return( true )
|
|
186
|
-
expect(
|
|
206
|
+
expect( Kernel ).to receive( :load ).with( 'plugins/private/second.rb' ).
|
|
187
207
|
and_return( true )
|
|
188
|
-
expect(
|
|
208
|
+
expect( Kernel ).to_not receive( :load ).with( 'plugins/private/third.rb' )
|
|
189
209
|
|
|
190
210
|
Plugin.plugin_exclusions( '**/third.rb' )
|
|
191
211
|
Plugin.load_all
|
|
@@ -200,6 +220,7 @@ describe Pluggability do
|
|
|
200
220
|
expect( TestingPlugin.plugin_type ).to eq( 'Plugin' )
|
|
201
221
|
end
|
|
202
222
|
|
|
223
|
+
|
|
203
224
|
it "raises a PluginError if it can't figure out what type of factory loads it" do
|
|
204
225
|
allow( TestingPlugin ).to receive( :ancestors ).and_return( [] )
|
|
205
226
|
expect {
|
|
@@ -207,6 +228,7 @@ describe Pluggability do
|
|
|
207
228
|
}.to raise_error( Pluggability::PluginError, /couldn't find plugin base/i )
|
|
208
229
|
end
|
|
209
230
|
|
|
231
|
+
|
|
210
232
|
it "knows what the simplest version of its plugin name is" do
|
|
211
233
|
expect( TestingPlugin.plugin_name ).to eq( 'testing' )
|
|
212
234
|
end
|
|
@@ -219,10 +241,12 @@ describe Pluggability do
|
|
|
219
241
|
expect( Plugin.create('blacksheep') ).to be_an_instance_of( BlackSheep )
|
|
220
242
|
end
|
|
221
243
|
|
|
244
|
+
|
|
222
245
|
it "is loadable via its underbarred name" do
|
|
223
246
|
expect( Plugin.create('black_sheep') ).to be_an_instance_of( BlackSheep )
|
|
224
247
|
end
|
|
225
248
|
|
|
249
|
+
|
|
226
250
|
it "knows what the simplest version of its plugin name is" do
|
|
227
251
|
expect( BlackSheep.plugin_name ).to eq( 'black_sheep' )
|
|
228
252
|
end
|
|
@@ -235,9 +259,11 @@ describe Pluggability do
|
|
|
235
259
|
expect( Plugin.create('loadable') ).to be_an_instance_of( Test::LoadablePlugin )
|
|
236
260
|
end
|
|
237
261
|
|
|
262
|
+
|
|
238
263
|
it "still knows what the simplest version of its plugin name is" do
|
|
239
264
|
expect( Test::LoadablePlugin.plugin_name ).to eq( 'loadable' )
|
|
240
265
|
end
|
|
266
|
+
|
|
241
267
|
end
|
|
242
268
|
|
|
243
269
|
|
|
@@ -247,9 +273,11 @@ describe Pluggability do
|
|
|
247
273
|
expect( Plugin.derivatives['subsub'] ).to eq( SubSubPlugin )
|
|
248
274
|
end
|
|
249
275
|
|
|
276
|
+
|
|
250
277
|
it "still knows what the simplest version of its plugin name is" do
|
|
251
278
|
expect( SubSubPlugin.plugin_name ).to eq( 'subsub' )
|
|
252
279
|
end
|
|
280
|
+
|
|
253
281
|
end
|
|
254
282
|
|
|
255
283
|
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: pluggability
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.5.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Martin Chase
|
|
@@ -11,27 +11,32 @@ bindir: bin
|
|
|
11
11
|
cert_chain:
|
|
12
12
|
- |
|
|
13
13
|
-----BEGIN CERTIFICATE-----
|
|
14
|
-
|
|
14
|
+
MIIEbDCCAtSgAwIBAgIBATANBgkqhkiG9w0BAQUFADA+MQwwCgYDVQQDDANnZWQx
|
|
15
15
|
GTAXBgoJkiaJk/IsZAEZFglGYWVyaWVNVUQxEzARBgoJkiaJk/IsZAEZFgNvcmcw
|
|
16
|
-
|
|
16
|
+
HhcNMTcwOTI3MDAzMDQ0WhcNMTgwOTI3MDAzMDQ0WjA+MQwwCgYDVQQDDANnZWQx
|
|
17
17
|
GTAXBgoJkiaJk/IsZAEZFglGYWVyaWVNVUQxEzARBgoJkiaJk/IsZAEZFgNvcmcw
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
18
|
+
ggGiMA0GCSqGSIb3DQEBAQUAA4IBjwAwggGKAoIBgQC/JWGRHO+USzR97vXjkFgt
|
|
19
|
+
83qeNf2KHkcvrRTSnR64i6um/ziin0I0oX23H7VYrDJC9A/uoUa5nGRJS5Zw/+wW
|
|
20
|
+
ENcvWVZS4iUzi4dsYJGY6yEOsXh2CcF46+QevV8iE+UmbkU75V7Dy1JCaUOyizEt
|
|
21
|
+
TH5UHsOtUU7k9TYARt/TgYZKuaoAMZZd5qyVqhF1vV+7/Qzmp89NGflXf2xYP26a
|
|
22
|
+
4MAX2qqKX/FKXqmFO+AGsbwYTEds1mksBF3fGsFgsQWxftG8GfZQ9+Cyu2+l1eOw
|
|
23
|
+
cZ+lPcg834G9DrqW2zhqUoLr1MTly4pqxYGb7XoDhoR7dd1kFE2a067+DzWC/ADt
|
|
24
|
+
+QkcqWUm5oh1fN0eqr7NsZlVJDulFgdiiYPQiIN7UNsii4Wc9aZqBoGcYfBeQNPZ
|
|
25
|
+
soo/6za/bWajOKUmDhpqvaiRv9EDpVLzuj53uDoukMMwxCMfgb04+ckQ0t2G7wqc
|
|
26
|
+
/D+K9JW9DDs3Yjgv9k4h7YMhW5gftosd+NkNC/+Y2CkCAwEAAaN1MHMwCQYDVR0T
|
|
27
|
+
BAIwADALBgNVHQ8EBAMCBLAwHQYDVR0OBBYEFHKN/nkRusdqCJEuq3lgB3fJvyTg
|
|
28
|
+
MBwGA1UdEQQVMBOBEWdlZEBGYWVyaWVNVUQub3JnMBwGA1UdEgQVMBOBEWdlZEBG
|
|
29
|
+
YWVyaWVNVUQub3JnMA0GCSqGSIb3DQEBBQUAA4IBgQB/qyi5pCjK8ceoKalfVAjS
|
|
30
|
+
vG64FEnLnD1bm39T5UaFIRmo+abZtfpg2QhwKvPbPjOicau2+m+MDQ2Cc3tgyaC3
|
|
31
|
+
dZxcP6w8APFg4AId09uWAZKf0xajvBMS2aOz8Bbmag6fwqRRkTMqsNYnmqcF7aRT
|
|
32
|
+
DuEzbEMfaOUYjU9RuB48vr4q8yRft0ww+3jq5iwNkrX1buL2pwBbyvgms6D/BV41
|
|
33
|
+
MaTVMjsHqJUwU2xVfhGtxGAWAer5S1HGYHkbio6mGVtiie0uWjmnzi7ppIlMr48a
|
|
34
|
+
7BNTsoZ+/JRk3iQWmmNsyFT7xfqBKye7cH11BX8V8P4MeGB5YWlMI+Myj5DZY3fQ
|
|
35
|
+
st2AGD4rb1l0ia7PfubcBThSIdz61eCb8gRi/RiZZwb3/7+eyEncLJzt2Ob9fGSF
|
|
36
|
+
X0qdrKi+2aZZ0NGuFj9AItBsVmAvkBGIpX4TEKQp5haEbPpmaqO5nIIhV26PXmyT
|
|
37
|
+
OMKv6pWsoS81vw5KAGBmfX8nht/Py90DQrbRvakATGI=
|
|
33
38
|
-----END CERTIFICATE-----
|
|
34
|
-
date:
|
|
39
|
+
date: 2018-01-19 00:00:00.000000000 Z
|
|
35
40
|
dependencies:
|
|
36
41
|
- !ruby/object:Gem::Dependency
|
|
37
42
|
name: loggability
|
|
@@ -39,14 +44,14 @@ dependencies:
|
|
|
39
44
|
requirements:
|
|
40
45
|
- - "~>"
|
|
41
46
|
- !ruby/object:Gem::Version
|
|
42
|
-
version: '0.
|
|
47
|
+
version: '0.12'
|
|
43
48
|
type: :runtime
|
|
44
49
|
prerelease: false
|
|
45
50
|
version_requirements: !ruby/object:Gem::Requirement
|
|
46
51
|
requirements:
|
|
47
52
|
- - "~>"
|
|
48
53
|
- !ruby/object:Gem::Version
|
|
49
|
-
version: '0.
|
|
54
|
+
version: '0.12'
|
|
50
55
|
- !ruby/object:Gem::Dependency
|
|
51
56
|
name: hoe-mercurial
|
|
52
57
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -67,14 +72,14 @@ dependencies:
|
|
|
67
72
|
requirements:
|
|
68
73
|
- - "~>"
|
|
69
74
|
- !ruby/object:Gem::Version
|
|
70
|
-
version: '0.
|
|
75
|
+
version: '0.9'
|
|
71
76
|
type: :development
|
|
72
77
|
prerelease: false
|
|
73
78
|
version_requirements: !ruby/object:Gem::Requirement
|
|
74
79
|
requirements:
|
|
75
80
|
- - "~>"
|
|
76
81
|
- !ruby/object:Gem::Version
|
|
77
|
-
version: '0.
|
|
82
|
+
version: '0.9'
|
|
78
83
|
- !ruby/object:Gem::Dependency
|
|
79
84
|
name: hoe-highline
|
|
80
85
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -95,97 +100,81 @@ dependencies:
|
|
|
95
100
|
requirements:
|
|
96
101
|
- - "~>"
|
|
97
102
|
- !ruby/object:Gem::Version
|
|
98
|
-
version: '
|
|
103
|
+
version: '5.1'
|
|
99
104
|
type: :development
|
|
100
105
|
prerelease: false
|
|
101
106
|
version_requirements: !ruby/object:Gem::Requirement
|
|
102
107
|
requirements:
|
|
103
108
|
- - "~>"
|
|
104
109
|
- !ruby/object:Gem::Version
|
|
105
|
-
version: '
|
|
106
|
-
- !ruby/object:Gem::Dependency
|
|
107
|
-
name: hoe-bundler
|
|
108
|
-
requirement: !ruby/object:Gem::Requirement
|
|
109
|
-
requirements:
|
|
110
|
-
- - "~>"
|
|
111
|
-
- !ruby/object:Gem::Version
|
|
112
|
-
version: '1.2'
|
|
113
|
-
type: :development
|
|
114
|
-
prerelease: false
|
|
115
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
116
|
-
requirements:
|
|
117
|
-
- - "~>"
|
|
118
|
-
- !ruby/object:Gem::Version
|
|
119
|
-
version: '1.2'
|
|
110
|
+
version: '5.1'
|
|
120
111
|
- !ruby/object:Gem::Dependency
|
|
121
112
|
name: hoe
|
|
122
113
|
requirement: !ruby/object:Gem::Requirement
|
|
123
114
|
requirements:
|
|
124
115
|
- - "~>"
|
|
125
116
|
- !ruby/object:Gem::Version
|
|
126
|
-
version: '3.
|
|
117
|
+
version: '3.16'
|
|
127
118
|
type: :development
|
|
128
119
|
prerelease: false
|
|
129
120
|
version_requirements: !ruby/object:Gem::Requirement
|
|
130
121
|
requirements:
|
|
131
122
|
- - "~>"
|
|
132
123
|
- !ruby/object:Gem::Version
|
|
133
|
-
version: '3.
|
|
134
|
-
description: "Pluggability is a
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
\ require '
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
by
|
|
151
|
-
\
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
=> 80 )"
|
|
124
|
+
version: '3.16'
|
|
125
|
+
description: "Pluggability is a toolkit for creating plugins.\n\nIt provides a mixin
|
|
126
|
+
that extends your class with methods to load and instantiate its subclasses by name.
|
|
127
|
+
So instead of:\n\n require 'acme/adapter/png'\n png_adapter = Acme::Adapter::PNG.new(
|
|
128
|
+
'file.png' )\n \nyou can do:\n\n require 'acme/adapter'\n png_adapter = Acme::Adapter.create(
|
|
129
|
+
:png, 'file.png' )\n\nA full example of where this might be useful is in a program
|
|
130
|
+
which generates\noutput with a 'driver' object, which provides a unified interface
|
|
131
|
+
but generates\ndifferent kinds of output.\n\nFirst the abstract base class, which
|
|
132
|
+
is extended with Pluggability:\n\n # in mygem/driver.rb:\n require 'pluggability'\n
|
|
133
|
+
\ require 'mygem' unless defined?( MyGem )\n \n class MyGem::Driver\n extend
|
|
134
|
+
Pluggability\n plugin_prefixes \"mygem/drivers\"\n end\n\nWe can have
|
|
135
|
+
one driver that outputs PDF documents:\n\n # mygem/drivers/pdf.rb:\n require
|
|
136
|
+
'mygem/driver' unless defined?( MyGem::Driver )\n \n class MyGem::Driver::PDF
|
|
137
|
+
< Driver\n ...implementation...\n end\n\nand another that outputs plain
|
|
138
|
+
ascii text:\n\n #mygem/drivers/ascii.rb:\n require 'mygem/driver' unless defined?(
|
|
139
|
+
MyGem::Driver )\n \n class MyGem::Driver::ASCII < Driver\n ...implementation...\n
|
|
140
|
+
\ end\n\nNow the driver is configurable by the end-user, who can just set\nit
|
|
141
|
+
by its short name:\n\n require 'mygem'\n \n config[:driver_type] #=> \"pdf\"\n
|
|
142
|
+
\ driver = MyGem::Driver.create( config[:driver_type] )\n driver.class #=>
|
|
143
|
+
MyGem::Driver::PDF\n\n # You can also pass arguments to the constructor, too:\n
|
|
144
|
+
\ ascii_driver = MyGem::Driver.create( :ascii, :columns => 80 )"
|
|
155
145
|
email:
|
|
156
146
|
- stillflame@FaerieMUD.org
|
|
157
147
|
- ged@FaerieMUD.org
|
|
158
148
|
executables: []
|
|
159
149
|
extensions: []
|
|
160
150
|
extra_rdoc_files:
|
|
161
|
-
- History.
|
|
151
|
+
- History.md
|
|
162
152
|
- Manifest.txt
|
|
163
|
-
- README.
|
|
153
|
+
- README.md
|
|
164
154
|
files:
|
|
165
|
-
- ".gemtest"
|
|
166
155
|
- ChangeLog
|
|
167
|
-
- History.
|
|
156
|
+
- History.md
|
|
168
157
|
- Manifest.txt
|
|
169
|
-
- README.
|
|
158
|
+
- README.md
|
|
170
159
|
- Rakefile
|
|
171
160
|
- lib/pluggability.rb
|
|
172
161
|
- spec/helpers.rb
|
|
173
162
|
- spec/pluggability_spec.rb
|
|
174
|
-
homepage:
|
|
163
|
+
homepage: http://bitbucket.org/ged/pluggability
|
|
175
164
|
licenses:
|
|
176
|
-
- BSD
|
|
165
|
+
- BSD-3-Clause
|
|
177
166
|
metadata: {}
|
|
178
167
|
post_install_message:
|
|
179
168
|
rdoc_options:
|
|
180
|
-
- "
|
|
181
|
-
-
|
|
169
|
+
- "--main"
|
|
170
|
+
- README.md
|
|
182
171
|
require_paths:
|
|
183
172
|
- lib
|
|
184
173
|
required_ruby_version: !ruby/object:Gem::Requirement
|
|
185
174
|
requirements:
|
|
186
175
|
- - ">="
|
|
187
176
|
- !ruby/object:Gem::Version
|
|
188
|
-
version:
|
|
177
|
+
version: 2.3.4
|
|
189
178
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
190
179
|
requirements:
|
|
191
180
|
- - ">="
|
|
@@ -193,9 +182,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
193
182
|
version: '0'
|
|
194
183
|
requirements: []
|
|
195
184
|
rubyforge_project:
|
|
196
|
-
rubygems_version: 2.4
|
|
185
|
+
rubygems_version: 2.7.4
|
|
197
186
|
signing_key:
|
|
198
187
|
specification_version: 4
|
|
199
|
-
summary: Pluggability is a
|
|
200
|
-
for its derivatives, capable of searching for and loading them by name
|
|
188
|
+
summary: Pluggability is a toolkit for creating plugins
|
|
201
189
|
test_files: []
|
metadata.gz.sig
CHANGED
|
Binary file
|
data/.gemtest
DELETED
|
File without changes
|