einhorn 0.6.5 → 0.7.0
Sign up to get free protection for your applications and to get access to all the features.
- data/bin/einhorn +0 -5
- data/lib/einhorn.rb +0 -33
- data/lib/einhorn/command.rb +0 -5
- data/lib/einhorn/version.rb +1 -1
- metadata +36 -31
- checksums.yaml +0 -7
- data/example/plugin.rb +0 -50
- data/lib/einhorn/third/little-plugger.rb +0 -2
- data/lib/einhorn/third/little-plugger/.gitignore +0 -17
- data/lib/einhorn/third/little-plugger/History.txt +0 -30
- data/lib/einhorn/third/little-plugger/README.rdoc +0 -53
- data/lib/einhorn/third/little-plugger/Rakefile +0 -31
- data/lib/einhorn/third/little-plugger/lib/little-plugger.rb +0 -325
- data/lib/einhorn/third/little-plugger/spec/little-plugger_spec.rb +0 -26
- data/lib/einhorn/third/little-plugger/spec/spec_helper.rb +0 -4
data/bin/einhorn
CHANGED
@@ -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)
|
data/lib/einhorn.rb
CHANGED
@@ -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
|
|
data/lib/einhorn/command.rb
CHANGED
@@ -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
|
|
data/lib/einhorn/version.rb
CHANGED
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.
|
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-
|
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
|
-
-
|
110
|
-
-
|
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:
|
191
|
+
rubygems_version: 1.8.23.2
|
187
192
|
signing_key:
|
188
|
-
specification_version:
|
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
|
data/example/plugin.rb
DELETED
@@ -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,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
|