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 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