pluginfactory 1.0.3 → 1.0.4

Sign up to get free protection for your applications and to get access to all the features.
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