pluginfactory 1.0.3 → 1.0.4

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.
data/ChangeLog CHANGED
@@ -1,3 +1,29 @@
1
+ -- Wed, 25 Feb 2009 17:50:55 -0000 by deveiant (r57) -----
2
+ Changed: lib/pluginfactory.rb
3
+
4
+ Incrementing library version.
5
+
6
+
7
+ -- Wed, 25 Feb 2009 16:52:20 -0000 by deveiant (r56) -----
8
+ Added: spec/lib (new)
9
+ spec/lib/helpers.rb (new)
10
+ Changed: lib/pluginfactory.rb
11
+ spec/pluginfactory_spec.rb
12
+
13
+ * Fixes for Ruby 1.9.1.
14
+ * Replace home-grown logger stuff with Logger library
15
+
16
+
17
+ -- Mon, 23 Feb 2009 06:34:03 -0000 by deveiant (r55) -----
18
+ Changed: README
19
+ Rakefile
20
+ utils.rb
21
+ project.yml
22
+ spec/pluginfactory_spec.rb
23
+
24
+ Start of fixes for 1.9.1.
25
+
26
+
1
27
  -- Wed, 13 Aug 2008 21:58:41 -0000 by deveiant (r52) -----
2
28
  Changed: lib/pluginfactory.rb
3
29
  Rakefile
data/README CHANGED
@@ -189,7 +189,7 @@ this might generate a log that looks like:
189
189
 
190
190
  == Subversion ID
191
191
 
192
- $Id: README 50 2008-08-13 21:57:18Z deveiant $
192
+ $Id: README 55 2009-02-23 06:34:03Z deveiant $
193
193
 
194
194
  == Authors
195
195
 
data/Rakefile CHANGED
@@ -4,7 +4,7 @@
4
4
  #
5
5
  # Based on various other Rakefiles, especially one by Ben Bleything
6
6
  #
7
- # Copyright (c) 2008 The FaerieMUD Consortium
7
+ # Copyright (c) 2007-2009 The FaerieMUD Consortium
8
8
  #
9
9
  # Authors:
10
10
  # * Michael Granger <ged@FaerieMUD.org>
@@ -21,39 +21,55 @@ BEGIN {
21
21
  $LOAD_PATH.unshift( extdir.to_s ) unless $LOAD_PATH.include?( extdir.to_s )
22
22
  }
23
23
 
24
-
25
24
  require 'rbconfig'
26
- require 'rubygems'
27
25
  require 'rake'
28
26
  require 'rake/rdoctask'
29
27
  require 'rake/testtask'
30
28
  require 'rake/packagetask'
31
29
  require 'rake/clean'
30
+ require 'rake/191_compat.rb'
32
31
 
33
32
  $dryrun = false
34
33
 
35
34
  ### Config constants
36
35
  BASEDIR = Pathname.new( __FILE__ ).dirname.relative_path_from( Pathname.getwd )
36
+ BINDIR = BASEDIR + 'bin'
37
37
  LIBDIR = BASEDIR + 'lib'
38
38
  EXTDIR = BASEDIR + 'ext'
39
39
  DOCSDIR = BASEDIR + 'docs'
40
40
  PKGDIR = BASEDIR + 'pkg'
41
+ DATADIR = BASEDIR + 'data'
41
42
 
42
- PKG_NAME = 'pluginfactory'
43
+ PROJECT_NAME = 'PluginFactory'
44
+ PKG_NAME = PROJECT_NAME.downcase
43
45
  PKG_SUMMARY = 'A mixin for making plugin classes'
46
+
44
47
  VERSION_FILE = LIBDIR + 'pluginfactory.rb'
45
- PKG_VERSION = VERSION_FILE.read[ /VERSION = '(\d+\.\d+\.\d+)'/, 1 ]
48
+ if VERSION_FILE.exist? && buildrev = ENV['CC_BUILD_LABEL']
49
+ PKG_VERSION = VERSION_FILE.read[ /VERSION\s*=\s*['"](\d+\.\d+\.\d+)['"]/, 1 ] + '.' + buildrev
50
+ elsif VERSION_FILE.exist?
51
+ PKG_VERSION = VERSION_FILE.read[ /VERSION\s*=\s*['"](\d+\.\d+\.\d+)['"]/, 1 ]
52
+ else
53
+ PKG_VERSION = '0.0.0'
54
+ end
55
+
46
56
  PKG_FILE_NAME = "#{PKG_NAME.downcase}-#{PKG_VERSION}"
47
57
  GEM_FILE_NAME = "#{PKG_FILE_NAME}.gem"
48
58
 
59
+ EXTCONF = EXTDIR + 'extconf.rb'
60
+
49
61
  ARTIFACTS_DIR = Pathname.new( ENV['CC_BUILD_ARTIFACTS'] || 'artifacts' )
50
62
 
51
63
  TEXT_FILES = %w( Rakefile ChangeLog README LICENSE ).collect {|filename| BASEDIR + filename }
64
+ BIN_FILES = Pathname.glob( BINDIR + '*' ).delete_if {|item| item =~ /\.svn/ }
52
65
  LIB_FILES = Pathname.glob( LIBDIR + '**/*.rb' ).delete_if {|item| item =~ /\.svn/ }
53
66
  EXT_FILES = Pathname.glob( EXTDIR + '**/*.{c,h,rb}' ).delete_if {|item| item =~ /\.svn/ }
67
+ DATA_FILES = Pathname.glob( DATADIR + '**/*' ).delete_if {|item| item =~ /\.svn/ }
54
68
 
55
69
  SPECDIR = BASEDIR + 'spec'
56
- SPEC_FILES = Pathname.glob( SPECDIR + '**/*_spec.rb' ).delete_if {|item| item =~ /\.svn/ }
70
+ SPECLIBDIR = SPECDIR + 'lib'
71
+ SPEC_FILES = Pathname.glob( SPECDIR + '**/*_spec.rb' ).delete_if {|item| item =~ /\.svn/ } +
72
+ Pathname.glob( SPECLIBDIR + '**/*.rb' ).delete_if {|item| item =~ /\.svn/ }
57
73
 
58
74
  TESTDIR = BASEDIR + 'tests'
59
75
  TEST_FILES = Pathname.glob( TESTDIR + '**/*.tests.rb' ).delete_if {|item| item =~ /\.svn/ }
@@ -68,8 +84,10 @@ EXTRA_PKGFILES = []
68
84
  RELEASE_FILES = TEXT_FILES +
69
85
  SPEC_FILES +
70
86
  TEST_FILES +
87
+ BIN_FILES +
71
88
  LIB_FILES +
72
89
  EXT_FILES +
90
+ DATA_FILES +
73
91
  RAKE_TASKLIBS +
74
92
  EXTRA_PKGFILES
75
93
 
@@ -107,12 +125,14 @@ SNAPSHOT_PKG_NAME = "#{PKG_FILE_NAME}.#{PKG_BUILD}"
107
125
  SNAPSHOT_GEM_NAME = "#{SNAPSHOT_PKG_NAME}.gem"
108
126
 
109
127
  # Documentation constants
128
+ RDOCDIR = DOCSDIR + 'api'
110
129
  RDOC_OPTIONS = [
111
130
  '-w', '4',
112
131
  '-SHN',
113
132
  '-i', '.',
114
133
  '-m', 'README',
115
- '-W', 'http://deveiate.org/projects/PluginFactory//browser/trunk/'
134
+ '-t', PKG_NAME,
135
+ '-W', 'http://deveiate.org/projects/PluginFactory/browser/trunk/'
116
136
  ]
117
137
 
118
138
  # Release constants
@@ -120,10 +140,11 @@ SMTP_HOST = 'mail.faeriemud.org'
120
140
  SMTP_PORT = 465 # SMTP + SSL
121
141
 
122
142
  # Project constants
123
- PROJECT_HOST = 'deveiate.org'
124
- PROJECT_PUBDIR = "/usr/local/www/public/code"
143
+ PROJECT_HOST = 'deveiate'
144
+ PROJECT_PUBDIR = '/usr/local/www/public/code'
125
145
  PROJECT_DOCDIR = "#{PROJECT_PUBDIR}/#{PKG_NAME}"
126
- PROJECT_SCPURL = "#{PROJECT_HOST}:#{PROJECT_DOCDIR}"
146
+ PROJECT_SCPPUBURL = "#{PROJECT_HOST}:#{PROJECT_PUBDIR}"
147
+ PROJECT_SCPDOCURL = "#{PROJECT_HOST}:#{PROJECT_DOCDIR}"
127
148
 
128
149
  # Rubyforge stuff
129
150
  RUBYFORGE_GROUP = 'deveiate'
@@ -133,6 +154,22 @@ RUBYFORGE_PROJECT = 'pluginfactory'
133
154
  DEPENDENCIES = {
134
155
  }
135
156
 
157
+ # Developer Gem dependencies: gemname => version
158
+ DEVELOPMENT_DEPENDENCIES = {
159
+ 'amatch' => '>= 0.2.3',
160
+ 'rake' => '>= 0.8.1',
161
+ 'rcodetools' => '>= 0.7.0.0',
162
+ 'rcov' => '>= 0',
163
+ 'RedCloth' => '>= 4.0.3',
164
+ 'rspec' => '>= 0',
165
+ 'rubyforge' => '>= 0',
166
+ 'termios' => '>= 0',
167
+ 'text-format' => '>= 1.0.0',
168
+ 'tmail' => '>= 1.2.3.1',
169
+ 'ultraviolet' => '>= 0.10.2',
170
+ 'libxml-ruby' => '>= 0.8.3',
171
+ }
172
+
136
173
  # Non-gem requirements: packagename => version
137
174
  REQUIREMENTS = {
138
175
  }
@@ -143,13 +180,13 @@ GEMSPEC = Gem::Specification.new do |gem|
143
180
  gem.version = PKG_VERSION
144
181
 
145
182
  gem.summary = PKG_SUMMARY
146
- gem.description = <<-EOD
147
- PluginFactory is a mixin module that turns an including class into a factory for
148
- its derivatives, capable of searching for and loading them by name. This is
149
- useful when you have an abstract base class which defines an interface and basic
150
- functionality for a part of a larger system, and a collection of subclasses
151
- which implement the interface for different underlying functionality.
152
- EOD
183
+ gem.description = [
184
+ "PluginFactory is a mixin module that turns an including class into a factory for",
185
+ "its derivatives, capable of searching for and loading them by name. This is",
186
+ "useful when you have an abstract base class which defines an interface and basic",
187
+ "functionality for a part of a larger system, and a collection of subclasses",
188
+ "which implement the interface for different underlying functionality.",
189
+ ].join( "\n" )
153
190
 
154
191
  gem.authors = 'Michael Granger'
155
192
  gem.email = 'ged@FaerieMUD.org'
@@ -158,6 +195,15 @@ GEMSPEC = Gem::Specification.new do |gem|
158
195
 
159
196
  gem.has_rdoc = true
160
197
  gem.rdoc_options = RDOC_OPTIONS
198
+ gem.extra_rdoc_files = %w[ChangeLog README LICENSE]
199
+
200
+ gem.bindir = BINDIR.relative_path_from(BASEDIR).to_s
201
+ gem.executables = BIN_FILES.select {|pn| pn.executable? }.
202
+ collect {|pn| pn.relative_path_from(BINDIR).to_s }
203
+
204
+ if EXTCONF.exist?
205
+ gem.extensions << EXTCONF.relative_path_from( BASEDIR ).to_s
206
+ end
161
207
 
162
208
  gem.files = RELEASE_FILES.
163
209
  collect {|f| f.relative_path_from(BASEDIR).to_s }
@@ -166,7 +212,15 @@ GEMSPEC = Gem::Specification.new do |gem|
166
212
 
167
213
  DEPENDENCIES.each do |name, version|
168
214
  version = '>= 0' if version.length.zero?
169
- gem.add_dependency( name, version )
215
+ gem.add_runtime_dependency( name, version )
216
+ end
217
+
218
+ # Developmental dependencies don't work as of RubyGems 1.2.0
219
+ unless Gem::Version.new( Gem::RubyGemsVersion ) <= Gem::Version.new( "1.2.0" )
220
+ DEVELOPMENT_DEPENDENCIES.each do |name, version|
221
+ version = '>= 0' if version.length.zero?
222
+ gem.add_development_dependency( name, version )
223
+ end
170
224
  end
171
225
 
172
226
  REQUIREMENTS.each do |name, version|
@@ -174,6 +228,9 @@ GEMSPEC = Gem::Specification.new do |gem|
174
228
  end
175
229
  end
176
230
 
231
+ # Manual-generation config
232
+ MANUALDIR = DOCSDIR + 'manual'
233
+
177
234
  $trace = Rake.application.options.trace ? true : false
178
235
  $dryrun = Rake.application.options.dryrun ? true : false
179
236
 
@@ -229,13 +286,16 @@ end
229
286
 
230
287
  ### Task: cruise (Cruisecontrol task)
231
288
  desc "Cruisecontrol build"
232
- task :cruise => [:clean, :spec, :package] do |task|
289
+ task :cruise => [:clean, 'spec:quiet', :package] do |task|
233
290
  raise "Artifacts dir not set." if ARTIFACTS_DIR.to_s.empty?
234
- artifact_dir = ARTIFACTS_DIR.cleanpath
291
+ artifact_dir = ARTIFACTS_DIR.cleanpath + ENV['CC_BUILD_LABEL']
235
292
  artifact_dir.mkpath
236
293
 
237
- $stderr.puts "Copying coverage stats..."
238
- FileUtils.cp_r( 'coverage', artifact_dir )
294
+ coverage = BASEDIR + 'coverage'
295
+ if coverage.exist? && coverage.directory?
296
+ $stderr.puts "Copying coverage stats..."
297
+ FileUtils.cp_r( 'coverage', artifact_dir )
298
+ end
239
299
 
240
300
  $stderr.puts "Copying packages..."
241
301
  FileUtils.cp_r( FileList['pkg/*'].to_a, artifact_dir )
@@ -1,5 +1,7 @@
1
1
  #!/usr/bin/env ruby -w
2
2
 
3
+ require 'logger'
4
+
3
5
  ### An exception class for PluginFactory specific errors.
4
6
  class FactoryError < RuntimeError; end
5
7
 
@@ -21,9 +23,7 @@ class FactoryError < RuntimeError; end
21
23
  #
22
24
  # == Creation Argument Variants
23
25
  #
24
- # The +create+ class method added to your class by PluginFactory searches for
25
- # your module using the $LOAD_PATH that require uses. See the README for a
26
- # detailed explanation.
26
+ # The +create+ class method added to your class by PluginFactory searches for your module using
27
27
  #
28
28
  # == Synopsis
29
29
  #
@@ -65,7 +65,7 @@ class FactoryError < RuntimeError; end
65
65
  #
66
66
  # == Subversion ID
67
67
  #
68
- # $Id: pluginfactory.rb 52 2008-08-13 21:58:41Z deveiant $
68
+ # $Id: pluginfactory.rb 57 2009-02-25 17:50:55Z deveiant $
69
69
  #
70
70
  # == Authors
71
71
  #
@@ -80,23 +80,52 @@ class FactoryError < RuntimeError; end
80
80
  #
81
81
  module PluginFactory
82
82
 
83
- VERSION = '1.0.3'
83
+ VERSION = '1.0.4'
84
84
 
85
85
 
86
- ### A callback for logging the various debug and information this module
87
- ### has to log. Should take two arguments, the log level, possibly as a
88
- ### symbol, and the log message itself.
89
- @logger_callback = nil
86
+ ### Logging
87
+ @default_logger = Logger.new( $stderr )
88
+ @default_logger.level = $DEBUG ? Logger::DEBUG : Logger::WARN
89
+
90
+ @logger = @default_logger
91
+
92
+
90
93
  class << self
91
- attr_accessor :logger_callback
94
+ # The logger that will be used when the logging subsystem is reset
95
+ attr_accessor :default_logger
96
+
97
+ # The logger that's currently in effect
98
+ attr_accessor :logger
99
+ alias_method :log, :logger
100
+ alias_method :log=, :logger=
92
101
  end
93
102
 
94
- ### If the logger callback is set, use it to pass on a log entry. First
95
- ### argument is a 'level' which is passed to the logging callback. Any
96
- ### remaining arguments will be joined and passed as a single second
97
- ### argument to the callback.
98
- def self::log( level, *msg )
99
- @logger_callback.call( level, msg.join ) if @logger_callback
103
+
104
+ ### Deprecated: use the Logger object at #log to manipulate logging instead of this
105
+ ### method.
106
+ def self::logger_callback=( callback )
107
+ if callback.nil?
108
+ self.logger.formatter = nil
109
+ else
110
+ self.logger.formatter = lambda {|lvl, _, _, msg|
111
+ callback.call(lvl.downcase.to_sym, msg)
112
+ ''
113
+ }
114
+ end
115
+ end
116
+
117
+
118
+ ### Reset the global logger object to the default
119
+ def self::reset_logger
120
+ self.logger = self.default_logger
121
+ self.logger.level = Logger::WARN
122
+ end
123
+
124
+
125
+ ### Returns +true+ if the global logger has not been set to something other than
126
+ ### the default one.
127
+ def self::using_default_logger?
128
+ return self.logger == self.default_logger
100
129
  end
101
130
 
102
131
 
@@ -122,7 +151,8 @@ module PluginFactory
122
151
  ### the class name.
123
152
  def derivatives
124
153
  ancestors.each do |klass|
125
- if klass.instance_variables.include?( "@derivatives" )
154
+ if klass.instance_variables.include?( :@derivatives ) ||
155
+ klass.instance_variables.include?( "@derivatives" )
126
156
  return klass.instance_variable_get( :@derivatives )
127
157
  end
128
158
  end
@@ -133,7 +163,8 @@ module PluginFactory
133
163
  def factory_type
134
164
  base = nil
135
165
  self.ancestors.each do |klass|
136
- if klass.instance_variables.include?( "@derivatives" )
166
+ if klass.instance_variables.include?( :@derivatives ) ||
167
+ klass.instance_variables.include?( "@derivatives" )
137
168
  base = klass
138
169
  break
139
170
  end
@@ -154,17 +185,26 @@ module PluginFactory
154
185
  ### Inheritance callback -- Register subclasses in the derivatives hash
155
186
  ### so that ::create knows about them.
156
187
  def inherited( subclass )
157
- keys = [ subclass.name, subclass.name.downcase, subclass ]
158
-
159
- # Handle class names like 'FooBar' for 'Bar' factories.
160
- if subclass.name.match( /(?:.*::)?(\w+)(?:#{self.factory_type})/i )
161
- keys << Regexp.last_match[1].downcase
188
+ keys = [ subclass ]
189
+
190
+ # If it's not an anonymous class, make some keys out of variants of its name
191
+ if subclass.name
192
+ simple_name = subclass.name.sub( /#<Class:0x[[:xdigit:]]+>::/i, '' )
193
+ keys << simple_name << simple_name.downcase
194
+
195
+ # Handle class names like 'FooBar' for 'Bar' factories.
196
+ PluginFactory.log.debug "Inherited %p for %p-type plugins" % [ subclass, self.factory_type ]
197
+ if subclass.name.match( /(?:.*::)?(\w+)(?:#{self.factory_type})/i )
198
+ keys << Regexp.last_match[1].downcase
199
+ else
200
+ keys << subclass.name.sub( /.*::/, '' ).downcase
201
+ end
162
202
  else
163
- keys << subclass.name.sub( /.*::/, '' ).downcase
203
+ PluginFactory.log.debug " no name-based variants for anonymous subclass %p" % [ subclass ]
164
204
  end
165
205
 
166
- keys.uniq.each do |key|
167
- PluginFactory.log :info, "Registering %s derivative of %s as %p" %
206
+ keys.compact.uniq.each do |key|
207
+ PluginFactory.log.info "Registering %s derivative of %s as %p" %
168
208
  [ subclass.name, self.name, key ]
169
209
  self.derivatives[ key ] = subclass
170
210
  end
@@ -245,7 +285,7 @@ module PluginFactory
245
285
  ### require line is tried with both <tt>'foo/'</tt> and <tt>'bar/'</tt>
246
286
  ### prepended to it.
247
287
  def load_derivative( class_name )
248
- PluginFactory.log :debug, "Loading derivative #{class_name}"
288
+ PluginFactory.log.debug "Loading derivative #{class_name}"
249
289
 
250
290
  # Get the unique part of the derived class name and try to
251
291
  # load it from one of the derivative subdirs, if there are
@@ -261,7 +301,7 @@ module PluginFactory
261
301
  self.factory_type,
262
302
  class_name.downcase,
263
303
  ]
264
- PluginFactory.log :error, errmsg
304
+ PluginFactory.log.error( errmsg )
265
305
  raise FactoryError, errmsg, caller(3)
266
306
  end
267
307
  end
@@ -303,7 +343,7 @@ module PluginFactory
303
343
  end
304
344
 
305
345
  subdirs = [ subdirs ] unless subdirs.is_a?( Array )
306
- PluginFactory.log :debug, "Subdirs are: %p" % [subdirs]
346
+ PluginFactory.log.debug "Subdirs are: %p" % [subdirs]
307
347
  fatals = []
308
348
  tries = []
309
349
 
@@ -311,7 +351,7 @@ module PluginFactory
311
351
  # module.
312
352
  subdirs.collect {|dir| dir.strip}.each do |subdir|
313
353
  self.make_require_path( mod_name, subdir ).each do |path|
314
- PluginFactory.log :debug, "Trying #{path}..."
354
+ PluginFactory.log.debug "Trying #{path}..."
315
355
  tries << path
316
356
 
317
357
  # Try to require the module, saving errors and jumping
@@ -319,22 +359,20 @@ module PluginFactory
319
359
  begin
320
360
  require( path.untaint )
321
361
  rescue LoadError => err
322
- PluginFactory.log :debug,
323
- "No module at '%s', trying the next alternative: '%s'" %
362
+ PluginFactory.log.debug "No module at '%s', trying the next alternative: '%s'" %
324
363
  [ path, err.message ]
325
364
  rescue Exception => err
326
365
  fatals << err
327
- PluginFactory.log :error,
328
- "Found '#{path}', but encountered an error: %s\n\t%s" %
366
+ PluginFactory.log.error "Found '#{path}', but encountered an error: %s\n\t%s" %
329
367
  [ err.message, err.backtrace.join("\n\t") ]
330
368
  else
331
- PluginFactory.log :info, "Loaded '#{path}' without error."
369
+ PluginFactory.log.info "Loaded '#{path}' without error."
332
370
  return path
333
371
  end
334
372
  end
335
373
  end
336
374
 
337
- PluginFactory.log :debug, "fatals = %p" % [ fatals ]
375
+ PluginFactory.log.debug "fatals = %p" % [ fatals ]
338
376
 
339
377
  # Re-raise is there was a file found, but it didn't load for
340
378
  # some reason.
@@ -344,10 +382,10 @@ module PluginFactory
344
382
  mod_name,
345
383
  tries
346
384
  ]
347
- PluginFactory.log :error, errmsg
385
+ PluginFactory.log.error( errmsg )
348
386
  raise FactoryError, errmsg
349
387
  else
350
- PluginFactory.log :debug, "Re-raising first fatal error"
388
+ PluginFactory.log.debug "Re-raising first fatal error"
351
389
  Kernel.raise( fatals.first )
352
390
  end
353
391
  end
@@ -379,7 +417,7 @@ module PluginFactory
379
417
  path.collect! {|m| File.join(subdir, m)}
380
418
  end
381
419
 
382
- PluginFactory.log :debug, "Path is: #{path.uniq.reverse.inspect}..."
420
+ PluginFactory.log.debug "Path is: #{path.uniq.reverse.inspect}..."
383
421
  return path.uniq.reverse
384
422
  end
385
423
  alias_method :makeRequirePath, :make_require_path