pluggability 0.4.3 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 74b416f4c7869bb0e92694c2cf9204934eb1c34e
4
- data.tar.gz: afc7030991affa25440542dbcc8b2034d5b30a03
2
+ SHA256:
3
+ metadata.gz: 12c5c85715daf5f17c850a2e30068fb8cf9e91e78215228273422093768b040e
4
+ data.tar.gz: 21f1401f755a1f4fc4c0c1d80b40497701a5eddeeb9c78c5851aa1d9d14840ca
5
5
  SHA512:
6
- metadata.gz: baa2b85007768cdcb9737f652b0bff158dfe8126b110894a0f534950ce4d8b0b428794d9567593f261856db5d3f7b64430f01429f03fd06fde016bbc9053c2d5
7
- data.tar.gz: 3073b7764f21c6c25bbf272e5802dcdcf20ea6dcf2af4a14f8e42531c8e50d1d77e520afeee87c2319f40d94d678347654e4ab1c1e506ce89e0790640295443e
6
+ metadata.gz: 294a6fa9924a062b02ed858b87a20d75f298ec47e026fbc9bedb25e61fd4ec8a9f8207a3cb72202317df2a516cf269b7e06089ef008baddd5cd342f0e173e3bf
7
+ data.tar.gz: b50fcf256c417e4e7ff0dff4e09f540c7719320beeae835ac00463a2427056f708f0e3ccc6fa1446046f83cc329e7409c0f8c8b86da4c12c7ee7b67c6dfd3420
Binary file
data.tar.gz.sig CHANGED
Binary file
data/ChangeLog CHANGED
@@ -1,18 +1,92 @@
1
- 2015-03-03 Mahlon E. Smith <mahlon@laika.com>
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 7f6ff521c94a
5
- [5bcb7e1a02d1] [tip]
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.1 for changeset 4b314c3ea2cb
9
- [7f6ff521c94a]
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
- [57f448b3e4a5]
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] [github/master]
102
+ [f17b18fbdb15]
29
103
 
30
104
  * .rvmrc, .travis.yml, Gemfile, Rakefile, loggability.gemspec:
31
105
  Prep for travis-ci builds
@@ -1,18 +1,26 @@
1
- == v0.4.3 [2015-03-04] Michael Granger <ged@FaerieMUD.org>
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
- == v0.4.2 [2015-03-04] Michael Granger <ged@FaerieMUD.org>
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
- == v0.4.1 [2015-03-03] Mahlon E. Smith <mahlon@martini.nu>
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
- == v0.4.0 [2014-01-08] Michael Granger <ged@FaerieMUD.org>
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
- == v0.3.0 [2013-09-25] Michael Granger <ged@FaerieMUD.org>
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
- == v0.2.0 [2013-03-28] Michael Granger <ged@FaerieMUD.org>
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
- == v0.1.0 [2013-03-27] Michael Granger <ged@FaerieMUD.org>
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
- == v0.0.2 [2012-08-13] Michael Granger <ged@FaerieMUD.org>
54
+ ## v0.0.2 [2012-08-13] Michael Granger <ged@FaerieMUD.org>
47
55
 
48
56
  Simplify Pluggability#derivatives.
49
57
 
50
58
 
51
- == v0.0.1 [2012-08-03] Michael Granger <ged@FaerieMUD.org>
59
+ ## v0.0.1 [2012-08-03] Michael Granger <ged@FaerieMUD.org>
52
60
 
53
61
  First release after renaming from PluginFactory.
54
62
 
@@ -1,7 +1,7 @@
1
1
  ChangeLog
2
- History.rdoc
2
+ History.md
3
3
  Manifest.txt
4
- README.rdoc
4
+ README.md
5
5
  Rakefile
6
6
  lib/pluggability.rb
7
7
  spec/helpers.rb
@@ -1,22 +1,32 @@
1
- = pluggability
1
+ # pluggability
2
2
 
3
- project:: https://bitbucket.org/ged/pluggability
4
- docs :: http://deveiate.org/code/pluggability
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
- == Description
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
- An example of where this might be useful is in a program which generates
18
- output with a 'driver' object, which provides a unified interface but
19
- generates different kinds of output.
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", "drivers/compat"
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
- === How Plugins Are Loaded
73
+ ### How Plugins Are Loaded
64
74
 
65
- The +create+ class method added to your class by Pluggability searches
66
- for your module using several different strategies. It tries various
67
- permutations of the base class's name in combination with the derivative
68
- requested. For example, assume we want to make a +LogReader+ base
69
- class, and then use plugins to define readers for different log
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
- so you can also tell Pluggability that plugins should be loaded from a
93
- subdirectory by declaring one or more +plugin_prefixes+ in the base
94
- class. Each prefix will be tried (in the order they're declared) when
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
- the message will list all the permutations that were tried.
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
- === Preloaded Plugins
149
+ ### Preloaded Plugins
142
150
 
143
- Sometimes you don't want to wait for plugins to be loaded on demand. For
144
- that case, Pluggability provides the load_all[rdoc-ref:Pluggability#load_all]
145
- method. This will find all possible matches for plugin files and load
146
- them, returning an Array of all the loaded classes:
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
- === Excluding Some Files
164
+ ### Excluding Some Files
157
165
 
158
- You can also prevent some files from being automatically loaded by
159
- either create[rdoc-ref:Pluggability#create] or
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
- === Logging
175
+ ### Logging
169
176
 
170
- If you need a little more insight into what's going on, Pluggability
171
- uses the Loggability[https://rubygems.org/gems/loggability] library.
172
- Just set the log level to 'debug' and it'll explain what's going on:
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
- == Installation
223
+ ## Installation
217
224
 
218
225
  gem install pluggability
219
226
 
220
227
 
221
- == Contributing
228
+ ## Contributing
222
229
 
223
230
  You can check out the current development source with Mercurial via its
224
- {Mercurial repo}[https://bitbucket.org/ged/pluggability]. Or if you
225
- prefer Git, via {its Github mirror}[https://github.com/ged/pluggability].
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
- == License
242
+ ## License
236
243
 
237
- Copyright (c) 2008-2013, Michael Granger and Martin Chase
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
- self.readme_file = 'README.rdoc'
21
- self.history_file = 'History.rdoc'
22
- self.extra_rdoc_files = Rake::FileList[ '*.rdoc' ]
23
- self.spec_extras[:rdoc_options] = ['-t', 'Pluggability Toolkit']
24
- # self.spec_extras[:required_rubygems_version] = '~> 2.1'
25
-
26
- # Hoops to avoid adding a formatting to the gem's spec, but still build
27
- # with a custom formatter locally
28
- self.spec_extras[:rdoc_options] += [ '-f', 'fivefish' ] if
29
- File.directory?( '.hg' ) && !(ARGV.include?('gem') || ARGV.include?('release'))
30
-
31
- self.developer 'Martin Chase', 'stillflame@FaerieMUD.org'
32
- self.developer 'Michael Granger', 'ged@FaerieMUD.org'
33
-
34
- self.dependency 'loggability', '~> 0.8'
35
-
36
- self.dependency 'hoe-deveiate', '~> 0.6', :development
37
- self.dependency 'hoe-bundler', '~> 1.2', :development
38
-
39
- self.license "BSD"
40
- self.hg_sign_tags = true if self.respond_to?( :hg_sign_tags= )
41
- self.check_history_on_release = true if self.respond_to?( :check_history_on_release= )
42
- self.rdoc_locations << "deveiate:/usr/local/www/public/code/#{remote_rdoc_dir}"
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
+
@@ -12,7 +12,7 @@ module Pluggability
12
12
 
13
13
 
14
14
  # Library version
15
- VERSION = '0.4.3'
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
- require( path )
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
- ### name of the base class and tries to load it via <tt>require</tt>. If
291
- ### the including class responds to a method named
292
- ### <tt>derivativeDirs</tt>, its return value (either a String, or an
293
- ### array of Strings) is added to the list of prefix directories to try
294
- ### when attempting to require a modules. Eg., if
295
- ### <tt>class.derivativeDirs</tt> returns <tt>['foo','bar']</tt> the
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
- subdirs = self.plugin_prefixes
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
- tries
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
 
@@ -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( :require )
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( Plugin ).to receive( :require ).with( 'plugins/dazzle_plugin' ) do |*args|
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( Plugin ).to receive( :require ).at_least(6).times.
114
- and_raise( LoadError.new("path") )
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
- # at least 6 -> 3 variants * 2 paths
124
- expect( Plugin ).to receive( :require ).and_return( true )
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 "will re-raise the first exception raised when attempting to load a " +
133
- "derivative if none of the paths work" do
134
-
135
- # at least 6 -> 3 variants * 2 paths
136
- expect( Plugin ).to receive( :require ).at_least(6).times.
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( Plugin ).to receive( :require ).with( 'plugins/first.rb' ).
172
+ expect( Kernel ).to receive( :load ).with( 'plugins/first.rb' ).
152
173
  and_return( true )
153
- expect( Plugin ).to receive( :require ).with( 'plugins/private/second.rb' ).
174
+ expect( Kernel ).to receive( :load ).with( 'plugins/private/second.rb' ).
154
175
  and_return( true )
155
- expect( Plugin ).to receive( :require ).with( 'plugins/private/third.rb' ).
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( Plugin ).to receive( :require ).with( 'plugins/first.rb' ).
188
+ expect( Kernel ).to receive( :load ).with( '/path/to/plugins/first.rb' ).
169
189
  and_return( true )
170
- expect( Plugin ).to_not receive( :require ).with( 'plugins/private/second.rb' )
171
- expect( Plugin ).to_not receive( :require ).with( 'plugins/private/third.rb' )
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( Plugin ).to receive( :require ).with( 'plugins/first.rb' ).
204
+ expect( Kernel ).to receive( :load ).with( 'plugins/first.rb' ).
185
205
  and_return( true )
186
- expect( Plugin ).to receive( :require ).with( 'plugins/private/second.rb' ).
206
+ expect( Kernel ).to receive( :load ).with( 'plugins/private/second.rb' ).
187
207
  and_return( true )
188
- expect( Plugin ).to_not receive( :require ).with( 'plugins/private/third.rb' )
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.3
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
- MIIDbDCCAlSgAwIBAgIBATANBgkqhkiG9w0BAQUFADA+MQwwCgYDVQQDDANnZWQx
14
+ MIIEbDCCAtSgAwIBAgIBATANBgkqhkiG9w0BAQUFADA+MQwwCgYDVQQDDANnZWQx
15
15
  GTAXBgoJkiaJk/IsZAEZFglGYWVyaWVNVUQxEzARBgoJkiaJk/IsZAEZFgNvcmcw
16
- HhcNMTQwMzE5MDQzNTI2WhcNMTUwMzE5MDQzNTI2WjA+MQwwCgYDVQQDDANnZWQx
16
+ HhcNMTcwOTI3MDAzMDQ0WhcNMTgwOTI3MDAzMDQ0WjA+MQwwCgYDVQQDDANnZWQx
17
17
  GTAXBgoJkiaJk/IsZAEZFglGYWVyaWVNVUQxEzARBgoJkiaJk/IsZAEZFgNvcmcw
18
- ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDb92mkyYwuGBg1oRxt2tkH
19
- +Uo3LAsaL/APBfSLzy8o3+B3AUHKCjMUaVeBoZdWtMHB75X3VQlvXfZMyBxj59Vo
20
- cDthr3zdao4HnyrzAIQf7BO5Y8KBwVD+yyXCD/N65TTwqsQnO3ie7U5/9ut1rnNr
21
- OkOzAscMwkfQxBkXDzjvAWa6UF4c5c9kR/T79iA21kDx9+bUMentU59aCJtUcbxa
22
- 7kcKJhPEYsk4OdxR9q2dphNMFDQsIdRO8rywX5FRHvcb+qnXC17RvxLHtOjysPtp
23
- EWsYoZMxyCDJpUqbwoeiM+tAHoz2ABMv3Ahie3Qeb6+MZNAtMmaWfBx3dg2u+/WN
24
- AgMBAAGjdTBzMAkGA1UdEwQCMAAwCwYDVR0PBAQDAgSwMB0GA1UdDgQWBBSZ0hCV
25
- qoHr122fGKelqffzEQBhszAcBgNVHREEFTATgRFnZWRARmFlcmllTVVELm9yZzAc
26
- BgNVHRIEFTATgRFnZWRARmFlcmllTVVELm9yZzANBgkqhkiG9w0BAQUFAAOCAQEA
27
- TuL1Bzl6TBs1YEzEubFHb9XAPgehWzzUudjDKzTRd+uyZmxnomBqTCQjT5ucNRph
28
- 3jZ6bhLNooLQxTjIuHodeGcEMHZdt4Yi7SyPmw5Nry12z6wrDp+5aGps3HsE5WsQ
29
- Zq2EuyEOc96g31uoIvjNdieKs+1kE+K+dJDjtw+wTH2i63P7r6N/NfPPXpxsFquo
30
- wcYRRrHdR7GhdJeT+V8Q8Bi5bglCUGdx+8scMgkkePc98k9osQHypbACmzO+Bqkv
31
- c7ZKPJcWBv0sm81+FCZXNACn2f9jfF8OQinxVs0O052KbGuEQaaiGIYeuuwQE2q6
32
- ggcrPfcYeTwWlfZPu2LrBg==
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: 2015-03-04 00:00:00.000000000 Z
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.8'
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.8'
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.6'
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.6'
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: '4.0'
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: '4.0'
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.13'
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.13'
134
- description: "Pluggability is a mixin module that turns an including class into a\nfactory
135
- for its derivatives, capable of searching for and loading them\nby name. This is
136
- useful when you have an abstract base class which\ndefines an interface and basic
137
- functionality for a part of a larger\nsystem, and a collection of subclasses which
138
- implement the interface for\ndifferent underlying functionality.\n\nAn example of
139
- where this might be useful is in a program which generates\noutput with a 'driver'
140
- object, which provides a unified interface but\ngenerates different kinds of output.\n\nFirst
141
- the abstract base class, which is extended with Pluggability:\n\n # in mygem/driver.rb:\n
142
- \ require 'pluggability'\n require 'mygem' unless defined?( MyGem )\n \n
143
- \ class MyGem::Driver\n extend Pluggability\n plugin_prefixes \"drivers\",
144
- \"drivers/compat\"\n end\n\nWe can have one driver that outputs PDF documents:\n\n
145
- \ # mygem/drivers/pdf.rb:\n require 'mygem/driver' unless defined?( MyGem::Driver
146
- )\n \n class MyGem::Driver::PDF < Driver\n ...implementation...\n end\n\nand
147
- another that outputs plain ascii text:\n\n #mygem/drivers/ascii.rb:\n require
148
- 'mygem/driver' unless defined?( MyGem::Driver )\n \n class MyGem::Driver::ASCII
149
- < Driver\n ...implementation...\n end\n\nNow the driver is configurable
150
- by the end-user, who can just set\nit by its short name:\n\n require 'mygem'\n
151
- \ \n config[:driver_type] #=> \"pdf\"\n driver = MyGem::Driver.create( config[:driver_type]
152
- )\n driver.class #=> MyGem::Driver::PDF\n\n # You can also pass arguments
153
- to the constructor, too:\n ascii_driver = MyGem::Driver.create( :ascii, :columns
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.rdoc
151
+ - History.md
162
152
  - Manifest.txt
163
- - README.rdoc
153
+ - README.md
164
154
  files:
165
- - ".gemtest"
166
155
  - ChangeLog
167
- - History.rdoc
156
+ - History.md
168
157
  - Manifest.txt
169
- - README.rdoc
158
+ - README.md
170
159
  - Rakefile
171
160
  - lib/pluggability.rb
172
161
  - spec/helpers.rb
173
162
  - spec/pluggability_spec.rb
174
- homepage: https://bitbucket.org/ged/pluggability
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
- - "-t"
181
- - Pluggability Toolkit
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: '0'
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.5
185
+ rubygems_version: 2.7.4
197
186
  signing_key:
198
187
  specification_version: 4
199
- summary: Pluggability is a mixin module that turns an including class into a factory
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