einhorn 0.6.5 → 0.7.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.
@@ -187,7 +187,6 @@ if true # $0 == __FILE__
187
187
  Einhorn::TransientState.script_name = $0
188
188
  Einhorn::TransientState.argv = ARGV.dup
189
189
  Einhorn::TransientState.environ = ENV.to_hash
190
- Einhorn.initialize_plugins
191
190
 
192
191
  optparse = OptionParser.new do |opts|
193
192
  opts.on('-b ADDR', '--bind ADDR', 'Bind an address and add the corresponding FD via the environment') do |addr|
@@ -283,8 +282,6 @@ if true # $0 == __FILE__
283
282
  Einhorn::State.reexec_commandline = Shellwords.shellsplit(cmdline)
284
283
  end
285
284
 
286
- Einhorn.plugins_send(:optparse, opts)
287
-
288
285
  opts.on('--nice MASTER[:WORKER=0][:RENICE_CMD=/usr/bin/renice]', 'Unix nice level at which to run the einhorn processes. If not running as root, make sure to ulimit -e as appopriate.') do |nice|
289
286
  master, worker, renice_cmd = nice.split(':')
290
287
  master = Integer(master) if master
@@ -326,8 +323,6 @@ if true # $0 == __FILE__
326
323
  exit(1)
327
324
  end
328
325
 
329
- Einhorn.plugins_send(:post_optparse)
330
-
331
326
  ret = Einhorn.run
332
327
  begin
333
328
  exit(ret)
@@ -7,18 +7,7 @@ require 'tmpdir'
7
7
  require 'yaml'
8
8
  require 'shellwords'
9
9
 
10
- require 'einhorn/third/little-plugger'
11
-
12
10
  module Einhorn
13
- extend Third::LittlePlugger
14
- module Plugins; end
15
-
16
- def self.plugins_send(sym, *args)
17
- plugins.values.each do |plugin|
18
- plugin.send(sym, *args) if plugin.respond_to? sym
19
- end
20
- end
21
-
22
11
  module AbstractState
23
12
  def default_state; raise NotImplementedError.new('Override in extended modules'); end
24
13
  def state; @state ||= default_state; end
@@ -111,11 +100,9 @@ module Einhorn
111
100
  updated_state, message = update_state(Einhorn::State, "einhorn", parsed[:state])
112
101
  Einhorn::State.state = updated_state
113
102
  Einhorn::Event.restore_persistent_descriptors(parsed[:persistent_descriptors])
114
- plugin_messages = update_plugin_states(parsed[:plugins])
115
103
  # Do this after setting state so verbosity is right
116
104
  Einhorn.log_info("Using loaded state: #{parsed.inspect}")
117
105
  Einhorn.log_info(message) if message
118
- plugin_messages.each {|msg| Einhorn.log_info(msg)}
119
106
  end
120
107
 
121
108
  def self.update_state(store, store_name, old_state)
@@ -173,23 +160,6 @@ module Einhorn
173
160
  [updated_state, message]
174
161
  end
175
162
 
176
- def self.update_plugin_states(states)
177
- plugin_messages = []
178
- (states || {}).each do |name, plugin_state|
179
- plugin = Einhorn.plugins[name]
180
- unless plugin && plugin.const_defined?(:State)
181
- plugin_messages << "No state defined in this version of the #{name} " +
182
- "plugin; dropping values for keys #{plugin_state.keys.inspect}"
183
- next
184
- end
185
-
186
- updated_state, plugin_message = update_state(plugin::State, "plugin #{name}", plugin_state)
187
- plugin_messages << plugin_message if plugin_message
188
- plugin::State.state = updated_state
189
- end
190
- plugin_messages
191
- end
192
-
193
163
  def self.print_state
194
164
  log_info(Einhorn::State.state.pretty_inspect)
195
165
  end
@@ -463,7 +433,6 @@ module Einhorn
463
433
 
464
434
  while Einhorn::State.respawn || Einhorn::State.children.size > 0
465
435
  log_debug("Entering event loop")
466
- Einhorn.plugins_send(:event_loop)
467
436
 
468
437
  # All of these are non-blocking
469
438
  Einhorn::Command.reap
@@ -473,8 +442,6 @@ module Einhorn
473
442
  # Make sure to do this last, as it's blocking.
474
443
  Einhorn::Event.loop_once
475
444
  end
476
-
477
- Einhorn.plugins_send(:exit)
478
445
  end
479
446
  end
480
447
 
@@ -188,15 +188,10 @@ module Einhorn
188
188
  descriptor_state = Einhorn::Event.persistent_descriptors.map do |descriptor|
189
189
  descriptor.to_state
190
190
  end
191
- plugin_state = {}
192
- Einhorn.plugins.each do |name, plugin|
193
- plugin_state[name] = plugin::State.dumpable_state if plugin.const_defined?(:State)
194
- end
195
191
 
196
192
  {
197
193
  :state => global_state,
198
194
  :persistent_descriptors => descriptor_state,
199
- :plugins => plugin_state
200
195
  }
201
196
  end
202
197
 
@@ -1,3 +1,3 @@
1
1
  module Einhorn
2
- VERSION = '0.6.5'
2
+ VERSION = '0.7.0'
3
3
  end
metadata CHANGED
@@ -1,97 +1,110 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: einhorn
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.5
4
+ version: 0.7.0
5
+ prerelease:
5
6
  platform: ruby
6
7
  authors:
7
8
  - Greg Brockman
8
9
  autorequire:
9
10
  bindir: bin
10
11
  cert_chain: []
11
- date: 2015-07-31 00:00:00.000000000 Z
12
+ date: 2015-08-20 00:00:00.000000000 Z
12
13
  dependencies:
13
14
  - !ruby/object:Gem::Dependency
14
15
  name: rake
15
16
  requirement: !ruby/object:Gem::Requirement
17
+ none: false
16
18
  requirements:
17
- - - ">="
19
+ - - ! '>='
18
20
  - !ruby/object:Gem::Version
19
21
  version: '0'
20
22
  type: :development
21
23
  prerelease: false
22
24
  version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
23
26
  requirements:
24
- - - ">="
27
+ - - ! '>='
25
28
  - !ruby/object:Gem::Version
26
29
  version: '0'
27
30
  - !ruby/object:Gem::Dependency
28
31
  name: pry
29
32
  requirement: !ruby/object:Gem::Requirement
33
+ none: false
30
34
  requirements:
31
- - - ">="
35
+ - - ! '>='
32
36
  - !ruby/object:Gem::Version
33
37
  version: '0'
34
38
  type: :development
35
39
  prerelease: false
36
40
  version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
37
42
  requirements:
38
- - - ">="
43
+ - - ! '>='
39
44
  - !ruby/object:Gem::Version
40
45
  version: '0'
41
46
  - !ruby/object:Gem::Dependency
42
47
  name: minitest
43
48
  requirement: !ruby/object:Gem::Requirement
49
+ none: false
44
50
  requirements:
45
- - - "<"
51
+ - - <
46
52
  - !ruby/object:Gem::Version
47
53
  version: '5.0'
48
54
  type: :development
49
55
  prerelease: false
50
56
  version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
51
58
  requirements:
52
- - - "<"
59
+ - - <
53
60
  - !ruby/object:Gem::Version
54
61
  version: '5.0'
55
62
  - !ruby/object:Gem::Dependency
56
63
  name: mocha
57
64
  requirement: !ruby/object:Gem::Requirement
65
+ none: false
58
66
  requirements:
59
- - - "~>"
67
+ - - ~>
60
68
  - !ruby/object:Gem::Version
61
69
  version: '0.13'
62
70
  type: :development
63
71
  prerelease: false
64
72
  version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
65
74
  requirements:
66
- - - "~>"
75
+ - - ~>
67
76
  - !ruby/object:Gem::Version
68
77
  version: '0.13'
69
78
  - !ruby/object:Gem::Dependency
70
79
  name: chalk-rake
71
80
  requirement: !ruby/object:Gem::Requirement
81
+ none: false
72
82
  requirements:
73
- - - ">="
83
+ - - ! '>='
74
84
  - !ruby/object:Gem::Version
75
85
  version: '0'
76
86
  type: :development
77
87
  prerelease: false
78
88
  version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
79
90
  requirements:
80
- - - ">="
91
+ - - ! '>='
81
92
  - !ruby/object:Gem::Version
82
93
  version: '0'
83
94
  - !ruby/object:Gem::Dependency
84
95
  name: subprocess
85
96
  requirement: !ruby/object:Gem::Requirement
97
+ none: false
86
98
  requirements:
87
- - - ">="
99
+ - - ! '>='
88
100
  - !ruby/object:Gem::Version
89
101
  version: '0'
90
102
  type: :development
91
103
  prerelease: false
92
104
  version_requirements: !ruby/object:Gem::Requirement
105
+ none: false
93
106
  requirements:
94
- - - ">="
107
+ - - ! '>='
95
108
  - !ruby/object:Gem::Version
96
109
  version: '0'
97
110
  description: Einhorn makes it easy to run multiple instances of an application server,
@@ -106,8 +119,8 @@ executables:
106
119
  extensions: []
107
120
  extra_rdoc_files: []
108
121
  files:
109
- - ".gitignore"
110
- - ".travis.yml"
122
+ - .gitignore
123
+ - .travis.yml
111
124
  - CONTRIBUTORS
112
125
  - Gemfile
113
126
  - History.txt
@@ -118,7 +131,6 @@ files:
118
131
  - bin/einhorn
119
132
  - bin/einhornsh
120
133
  - einhorn.gemspec
121
- - example/plugin.rb
122
134
  - example/pool_worker.rb
123
135
  - example/thin_example
124
136
  - example/time_server
@@ -136,14 +148,6 @@ files:
136
148
  - lib/einhorn/event/persistent.rb
137
149
  - lib/einhorn/event/timer.rb
138
150
  - lib/einhorn/third.rb
139
- - lib/einhorn/third/little-plugger.rb
140
- - lib/einhorn/third/little-plugger/.gitignore
141
- - lib/einhorn/third/little-plugger/History.txt
142
- - lib/einhorn/third/little-plugger/README.rdoc
143
- - lib/einhorn/third/little-plugger/Rakefile
144
- - lib/einhorn/third/little-plugger/lib/little-plugger.rb
145
- - lib/einhorn/third/little-plugger/spec/little-plugger_spec.rb
146
- - lib/einhorn/third/little-plugger/spec/spec_helper.rb
147
151
  - lib/einhorn/version.rb
148
152
  - lib/einhorn/worker.rb
149
153
  - lib/einhorn/worker_pool.rb
@@ -166,27 +170,28 @@ files:
166
170
  homepage: https://github.com/stripe/einhorn
167
171
  licenses:
168
172
  - MIT
169
- metadata: {}
170
173
  post_install_message:
171
174
  rdoc_options: []
172
175
  require_paths:
173
176
  - lib
174
177
  required_ruby_version: !ruby/object:Gem::Requirement
178
+ none: false
175
179
  requirements:
176
- - - ">="
180
+ - - ! '>='
177
181
  - !ruby/object:Gem::Version
178
182
  version: '0'
179
183
  required_rubygems_version: !ruby/object:Gem::Requirement
184
+ none: false
180
185
  requirements:
181
- - - ">="
186
+ - - ! '>='
182
187
  - !ruby/object:Gem::Version
183
188
  version: '0'
184
189
  requirements: []
185
190
  rubyforge_project:
186
- rubygems_version: 2.2.2
191
+ rubygems_version: 1.8.23.2
187
192
  signing_key:
188
- specification_version: 4
189
- summary: 'Einhorn: the language-independent shared socket manager'
193
+ specification_version: 3
194
+ summary: ! 'Einhorn: the language-independent shared socket manager'
190
195
  test_files:
191
196
  - test/_lib.rb
192
197
  - test/integration/_lib.rb
checksums.yaml DELETED
@@ -1,7 +0,0 @@
1
- ---
2
- SHA1:
3
- metadata.gz: 739d5b1792e08e0e7ae6fa66233b4ee2c4b5d7b6
4
- data.tar.gz: 186f3923ab82dc0c45c47c889f1e0c886276af95
5
- SHA512:
6
- metadata.gz: cb199e87bb760683cd8eac18d8d2259f7c81b24973bc17be0d3c06939c81cf510420ce63d07b98dd979b7cb5e8f6b693a91025b7e300c3b89e9e4bdc3ef9f0d2
7
- data.tar.gz: 11a681f8e8cd2ae8c18814a8bd8ea650be8bd84bea0cd9264620a30dd25f9b423235ab691a0c85cde2393edd179308d5bc23fb992119e049d3112ec8b0be53a0
@@ -1,50 +0,0 @@
1
- #
2
- # plugin.rb - An example Einhorn plugin.
3
- #
4
- # Including this file in [yourgemhere]/lib/einhorn/plugins/ will cause Einhorn
5
- # to load it. This example plugin defines all the methods that Einhorn
6
- # recognizes and will invoke, although none of these methods is required.
7
- #
8
-
9
- module Einhorn::Plugins
10
- module ExamplePlugin
11
- # If a State module is defined, its contents will be passed to new
12
- # einhorn processes when einhorn is reloaded
13
- module State
14
- extend Einhorn::AbstractState
15
- def self.default_state
16
- {
17
- :yay => nil
18
- }
19
- end
20
- end
21
-
22
- def self.initialize_example_plugin
23
- # The initializer method must be named `initialize_##[plugin_name]',
24
- # where [plugin_name] is the name of the plugin module or class in
25
- # lower_case_with_underscores.
26
- puts 'I will be called before einhorn does any work.'
27
- end
28
-
29
- def self.optparse(opts)
30
- opts.on("--my-option X", "Patch einhorn with additional options!") do |x|
31
- State.yay = x
32
- end
33
- end
34
-
35
- def self.post_optparse
36
- # Called after all options native to einhorn or patched by any plugins
37
- # are parsed. Good place to do argument validation
38
- raise "Argument --my-option is required" unless State.yay
39
- end
40
-
41
- def self.event_loop
42
- # Called each time einhorn enters its event loop, in which it cleans up
43
- # any terminated children and respawns them.
44
- end
45
-
46
- def self.exit
47
- # Called after the event loop terminates, just before einhorn exits.
48
- end
49
- end
50
- end
@@ -1,2 +0,0 @@
1
- require 'einhorn/third'
2
- require 'einhorn/third/little-plugger/lib/little-plugger'
@@ -1,17 +0,0 @@
1
- # The list of files that should be ignored by Mr Bones.
2
- # Lines that start with '#' are comments.
3
- #
4
- # A .gitignore file can be used instead by setting it as the ignore
5
- # file in your Rakefile:
6
- #
7
- # PROJ.ignore_file = '.gitignore'
8
- #
9
- # For a project with a C extension, the following would be a good set of
10
- # exclude patterns (uncomment them if you want to use them):
11
- # *.[oa]
12
- # *~
13
- announcement.txt
14
- coverage
15
- doc
16
- pkg
17
- .rvmrc
@@ -1,30 +0,0 @@
1
- == 1.1.3 / 2011-11-17
2
-
3
- * 1 bug fix
4
- * Ensuring gem files are in a sorted order
5
-
6
- == 1.1.2 / 2010-02-01
7
-
8
- * 1 bug fix
9
- * Resovling some circular dependencies
10
-
11
- == 1.1.1 / 2009-11-08
12
-
13
- * 1 bug fix
14
- * Catching script errors and standard errors when loading plugins
15
-
16
- == 1.1.0 / 2009-11-04
17
-
18
- * 2 minor enhancements
19
- * Loading the first plugin found by name (instead of the last)
20
- * Plugins can be disregarded so they will not be loaded
21
-
22
- == 1.0.1 / 2009-08-14
23
-
24
- * 1 bug fix
25
- * Using the wrong file extension for the File#basename call
26
-
27
- == 1.0.0 / 2009-07-16
28
-
29
- * 1 major enhancement
30
- * Birthday!
@@ -1,53 +0,0 @@
1
- = Little Plugger
2
- * by Tim Pease
3
- * http://github.com/TwP/little-plugger/tree/master
4
-
5
- === DESCRIPTION:
6
-
7
- LittlePlugger is a module that provides Gem based plugin management.
8
- By extending your own class or module with LittlePlugger you can easily
9
- manage the loading and initializing of plugins provided by other gems.
10
-
11
- === FEATURES:
12
-
13
- * List of plugins so that some plugins can be excluded while others are
14
- loaded by default.
15
- * Loading and initializing of plugins.
16
- * Access to the plugin classes and modules.
17
-
18
- LittlePlugger is a distallation of the plugin system from Hoe. It has been
19
- "genericized" and encapsulated into its own easy to use module.
20
-
21
- === REQUIREMENTS:
22
-
23
- Since Little Plugger is a Gem based plugin system, Ruby Gems must be
24
- installed on your system.
25
-
26
- === INSTALL:
27
-
28
- gem install little-plugger
29
-
30
- === LICENSE:
31
-
32
- (The MIT License)
33
-
34
- Copyright (c) 2009-2011
35
-
36
- Permission is hereby granted, free of charge, to any person obtaining
37
- a copy of this software and associated documentation files (the
38
- 'Software'), to deal in the Software without restriction, including
39
- without limitation the rights to use, copy, modify, merge, publish,
40
- distribute, sublicense, and/or sell copies of the Software, and to
41
- permit persons to whom the Software is furnished to do so, subject to
42
- the following conditions:
43
-
44
- The above copyright notice and this permission notice shall be
45
- included in all copies or substantial portions of the Software.
46
-
47
- THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
48
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
49
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
50
- IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
51
- CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
52
- TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
53
- SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -1,31 +0,0 @@
1
-
2
- begin
3
- require 'bones'
4
- rescue LoadError
5
- abort '### please install the "bones" gem ###'
6
- end
7
-
8
- ensure_in_path 'lib'
9
- require 'little-plugger'
10
-
11
- task :default => 'spec:run'
12
- task 'gem:release' => 'spec:run'
13
-
14
- Bones {
15
- name 'little-plugger'
16
- authors 'Tim Pease'
17
- email 'tim.pease@gmail.com'
18
- url 'http://gemcutter.org/gems/little-plugger'
19
- version LittlePlugger::VERSION
20
- readme_file 'README.rdoc'
21
-
22
- spec.opts.concat %w[--color --format documentation]
23
- use_gmail
24
-
25
- depend_on 'rspec', :development => true
26
- }
27
-
28
- # depending on bones (even as a development dependency) creates a circular
29
- # reference that prevents the auto install of little-plugger when instsalling
30
- # bones
31
- ::Bones.config.gem._spec.dependencies.delete_if {|d| d.name == 'bones'}
@@ -1,325 +0,0 @@
1
-
2
- # == Synopsis
3
- # LittlePlugger is a module that provides Gem based plugin management.
4
- # By extending your own class or module with LittlePlugger you can easily
5
- # manage the loading and initializing of plugins provided by other gems.
6
- #
7
- # == Details
8
- # Plugins are great! They allow other developers to add functionality to
9
- # an application but relieve the application developer of the responsibility
10
- # for mainting some other developer's plugin code. LittlePlugger aims to
11
- # make it dead simple to manage external plugins as gems.
12
- #
13
- # === Naming
14
- # Every plugin managed by LittlePlugger will have a name represented as a
15
- # Symbol. This name is used to register the plugin, load the plugin file,
16
- # and manage the plugin class/module. Here are the three rules for plugin
17
- # names:
18
- #
19
- # 1) all lowercase with underscores
20
- # 2) maps to a file of the same name with an '.rb' extension
21
- # 3) converting the name to camel case yields the plugin class / module
22
- #
23
- # These rules are essentially the standard ruby practice of naming files
24
- # after the class / module the file defines.
25
- #
26
- # === Finding & Loading
27
- # Plugins are found by searching through the lib folders of all installed
28
- # gems; these gems are not necessarily loaded - just searched. If the lib
29
- # folder has a subdirectory that matches the +plugin_path+, then all ruby
30
- # files in the gem's +plugin_path+ are noted for later loading.
31
- #
32
- # A file is only loaded if the basename of the file matches one of the
33
- # registered plugin names. If no plugins are registered, then every file in
34
- # the +plugin_path+ is loaded.
35
- #
36
- # The plugin classes / modules are all expected to live in the same
37
- # namespace for a particular application. For example, all plugins for the
38
- # "Foo" application should reside in a "Foo::Plugins" namespace. This allows
39
- # the plugins to be automatically initialized by LittlePlugger.
40
- #
41
- # === Initializing
42
- # Optionally, plugins can provide an initialization method for running any
43
- # setup code needed by the plugin. This initialize method should be named as
44
- # follows: "initializer_#{plugin_name}" where the name of the plugin is
45
- # appended to the end of the initializer method name.
46
- #
47
- # If this method exists, it will be called automatically when plugins are
48
- # loaded. The order of loading of initialization is not strictly defined, so
49
- # do not rely on another plugin being initialized for your own plugin
50
- # successfully initialize.
51
- #
52
- # == Usage
53
- # LittlePlugger is used by extending your own class or module with the
54
- # LittlePlugger module.
55
- #
56
- # module Logging
57
- # extend LittlePlugger
58
- # end
59
- #
60
- # This defines a +plugin_path+ and a +plugin_module+ for our Logging module.
61
- # The +plugin_path+ is set to "logging/plugins", and therefore, the
62
- # +plugin_modlue+ is defined as Logging::Plugins. All plugins for the
63
- # Logging module should be found underneath this plugin module.
64
- #
65
- # The plugins for the Logging module are loaded and initialized by calling
66
- # the +initialize_plugins+ method.
67
- #
68
- # Logging.initialize_plugins
69
- #
70
- # If you only want to load the plugin files but not initialize the plugin
71
- # classes / modules then you can call the +load_plugins+ method.
72
- #
73
- # Logging.load_plugins
74
- #
75
- # Finally, you can get a hash of all the loaded plugins.
76
- #
77
- # Logging.plugins
78
- #
79
- # This returns a hash keyed by the plugin names with the plugin class /
80
- # module as the value.
81
- #
82
- # If you only want a certain set of plugins to be loaded, then pass the
83
- # names to the +plugin+ method.
84
- #
85
- # Logging.plugin :foo, :bar, :baz
86
- #
87
- # Now only three plugins for the Logging module will be loaded.
88
- #
89
- # === Customizing
90
- # LittlePlugger allows the use of a custom plugin path and module. These are
91
- # specified when extending with LilttlePlugger by passing the specific path
92
- # and module to LittlePlugger.
93
- #
94
- # class Hoe
95
- # extend LittlePlugger( :path => 'hoe', :module => Hoe )
96
- #
97
- # plugin(
98
- # :clean, :debug, :deps, :flay, :flog, :package,
99
- # :publish, :rcov, :signing, :test
100
- # )
101
- # end
102
- #
103
- # All ruby files found under the "hoe" directory will be treated as
104
- # plugins, and the plugin classes / modules should reside directly under the
105
- # Hoe namespace.
106
- #
107
- # We also specify a list of plugins to be loaded. Only these plugins will be
108
- # loaded and initialized by the LittlePlugger module. The +plugin+ method
109
- # can be called multiple times to add more plugins.
110
- #
111
- module Einhorn::Third::LittlePlugger
112
-
113
- VERSION = '1.1.3' # :nodoc:
114
-
115
- # Returns the version string for the library.
116
- #
117
- def self.version
118
- VERSION
119
- end
120
-
121
- module ClassMethods
122
-
123
- # Add the _names_ to the list of plugins that will be loaded.
124
- #
125
- def plugin( *names )
126
- plugin_names.concat(names.map! {|n| n.to_sym})
127
- end
128
-
129
- # Add the _names_ to the list of plugins that will *not* be loaded. This
130
- # list prevents the plugin system from loading unwanted or unneeded
131
- # plugins.
132
- #
133
- # If a plugin name appears in both the 'disregard_plugin' list and the
134
- # 'plugin' list, the disregard list takes precedence; that is, the plugin
135
- # will not be loaded.
136
- #
137
- def disregard_plugin( *names )
138
- @disregard_plugin ||= []
139
- @disregard_plugin.concat(names.map! {|n| n.to_sym})
140
- @disregard_plugin
141
- end
142
- alias :disregard_plugins :disregard_plugin
143
-
144
- # Returns the array of plugin names that will be loaded. If the array is
145
- # empty, then any plugin found in the +plugin_path+ will be loaded.
146
- #
147
- def plugin_names
148
- @plugin_names ||= []
149
- end
150
-
151
- # Loads the desired plugins and returns a hash. The hash contains all
152
- # the plugin classes and modules keyed by the plugin name.
153
- #
154
- def plugins
155
- load_plugins
156
- pm = plugin_module
157
- names = pm.constants.map { |s| s.to_s }
158
- names.reject! { |n| n =~ %r/^[A-Z_]+$/ }
159
-
160
- h = {}
161
- names.each do |name|
162
- sym = ::Einhorn::Third::LittlePlugger.underscore(name).to_sym
163
- next unless plugin_names.empty? or plugin_names.include? sym
164
- next if disregard_plugins.include? sym
165
- h[sym] = pm.const_get name
166
- end
167
- h
168
- end
169
-
170
- # Iterate over the loaded plugin classes and modules and call the
171
- # initialize method for each plugin. The plugin's initialize method is
172
- # defeind as +initialize_plugin_name+, where the plugin name is unique
173
- # to each plugin.
174
- #
175
- def initialize_plugins
176
- plugins.each do |name, klass|
177
- msg = "initialize_#{name}"
178
- klass.send msg if klass.respond_to? msg
179
- end
180
- end
181
-
182
- # Iterate through all installed gems looking for those that have the
183
- # +plugin_path+ in their "lib" folder, and load all .rb files found in
184
- # the gem's plugin path. Each .rb file should define one class or module
185
- # that will be used as a plugin.
186
- #
187
- def load_plugins
188
- @loaded ||= {}
189
- found = {}
190
-
191
- Gem.find_files(File.join(plugin_path, '*.rb')).sort!.reverse_each do |path|
192
- name = File.basename(path, '.rb').to_sym
193
- found[name] = path unless found.key? name
194
- end
195
-
196
- :keep_on_truckin while found.map { |name, path|
197
- next unless plugin_names.empty? or plugin_names.include? name
198
- next if disregard_plugins.include? name
199
- next if @loaded[name]
200
- begin
201
- @loaded[name] = load path
202
- rescue ScriptError, StandardError => err
203
- warn "Error loading #{path.inspect}: #{err.message}. skipping..."
204
- end
205
- }.any?
206
- end
207
-
208
- # The path to search in a gem's 'lib' folder for plugins.
209
- #
210
- def plugin_path
211
- ::Einhorn::Third::LittlePlugger.default_plugin_path(self)
212
- end
213
-
214
- # This module or class where plugins are located.
215
- #
216
- def plugin_module
217
- ::Einhorn::Third::LittlePlugger.default_plugin_module(plugin_path)
218
- end
219
-
220
- end # module ClassMethods
221
-
222
- # :stopdoc:
223
-
224
- # Called when another object extends itself with LittlePlugger.
225
- #
226
- def self.extended( other )
227
- other.extend ClassMethods
228
- end
229
-
230
- # Convert the given string from camel case to snake case. Method liberally
231
- # stolen from ActiveSupport.
232
- #
233
- # underscore( "FooBar" ) #=> "foo_bar"
234
- #
235
- def self.underscore( string )
236
- string.to_s.
237
- gsub(%r/::/, '/').
238
- gsub(%r/([A-Z]+)([A-Z][a-z])/,'\1_\2').
239
- gsub(%r/([a-z\d])([A-Z])/,'\1_\2').
240
- tr('-', '_').
241
- downcase
242
- end
243
-
244
- # For a given object returns a default plugin path. The path is
245
- # created by splitting the object's class name on the namespace separator
246
- # "::" and converting each part of the namespace into an underscored
247
- # string (see the +underscore+ method). The strings are then joined using
248
- # the File#join method to give a filesystem path. Appended to this path is
249
- # the 'plugins' directory.
250
- #
251
- # default_plugin_path( FooBar::Baz ) #=> "foo_bar/baz/plugins"
252
- #
253
- def self.default_plugin_path( obj )
254
- obj = obj.class unless obj.is_a? Module
255
- File.join(underscore(obj.name), 'plugins')
256
- end
257
-
258
- # For a given path returns the class or module corresponding to the
259
- # path. This method assumes a correspondence between directory names and
260
- # Ruby namespaces.
261
- #
262
- # default_plugin_module( "foo_bar/baz/plugins" ) #=> FooBar::Baz::Plugins
263
- #
264
- # This method will fail if any of the namespaces have not yet been
265
- # defined.
266
- #
267
- def self.default_plugin_module( path )
268
- path.split(File::SEPARATOR).inject(Object) do |mod, const|
269
- const = const.split('_').map { |s| s.capitalize }.join
270
- mod.const_get const
271
- end
272
- end
273
- # :startdoc:
274
-
275
- end # module Einhorn::Third::LittlePlugger
276
-
277
-
278
- module Kernel
279
- module Einhorn::Third
280
-
281
- # call-seq:
282
- # LittlePlugger( opts = {} )
283
- #
284
- # This method allows the user to override some of LittlePlugger's default
285
- # settings when mixed into a module or class.
286
- #
287
- # See the "Customizing" section of the LittlePlugger documentation for an
288
- # example of how this method is used.
289
- #
290
- # ==== Options
291
- #
292
- # * :path <String>
293
- # The default plugin path. Defaults to "module_name/plugins".
294
- #
295
- # * :module <Module>
296
- # The module where plugins will be loaded. Defaults to
297
- # ModuleName::Plugins.
298
- #
299
- # * :plugins <Array>
300
- # The array of default plugins to load. Only the plugins listed in this
301
- # array will be loaded by LittlePlugger.
302
- #
303
- def LittlePlugger( opts = {} )
304
- return ::Einhorn::LittlePlugger::ClassMethods if opts.empty?
305
- Module.new {
306
- include ::Einhorn::LittlePlugger::ClassMethods
307
-
308
- if opts.key?(:path)
309
- eval %Q{def plugin_path() #{opts[:path].to_s.inspect} end}
310
- end
311
-
312
- if opts.key?(:module)
313
- eval %Q{def plugin_module() #{opts[:module].name} end}
314
- end
315
-
316
- if opts.key?(:plugins)
317
- plugins = Array(opts[:plugins]).map {|val| val.to_sym.inspect}.join(',')
318
- eval %Q{def plugin_names() @plugin_names ||= [#{plugins}] end}
319
- end
320
- }
321
- end
322
- end # module Einhorn::Third
323
- end # module Kernel
324
-
325
- # EOF
@@ -1,26 +0,0 @@
1
-
2
- require File.join(File.dirname(__FILE__), %w[spec_helper])
3
-
4
- describe LittlePlugger do
5
-
6
- it "converts a string from camel-case to underscore" do
7
- LittlePlugger.underscore('FooBarBaz').should be == 'foo_bar_baz'
8
- LittlePlugger.underscore('CouchDB').should be == 'couch_db'
9
- LittlePlugger.underscore('FOOBar').should be == 'foo_bar'
10
- LittlePlugger.underscore('Foo::Bar::BazBuz').should be == 'foo/bar/baz_buz'
11
- end
12
-
13
- it "generates a default plugin path" do
14
- LittlePlugger.default_plugin_path(LittlePlugger).should be == 'little_plugger/plugins'
15
- LittlePlugger.default_plugin_path(Process::Status).should be == 'process/status/plugins'
16
- end
17
-
18
- it "generates a default plugin module" do
19
- LittlePlugger.default_plugin_module('little_plugger').should be == LittlePlugger
20
- lambda {LittlePlugger.default_plugin_module('little_plugger/plugins')}.
21
- should raise_error(NameError, 'uninitialized constant LittlePlugger::Plugins')
22
- LittlePlugger.default_plugin_module('process/status').should be == Process::Status
23
- end
24
- end
25
-
26
- # EOF
@@ -1,4 +0,0 @@
1
-
2
- require File.expand_path(
3
- File.join(File.dirname(__FILE__), %w[.. lib little-plugger]))
4
-