ddplugin 0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/Gemfile +7 -0
- data/Gemfile.lock +40 -0
- data/LICENSE +19 -0
- data/NEWS.md +0 -0
- data/README.md +137 -0
- data/Rakefile +10 -0
- data/ddplugin.gemspec +28 -0
- data/lib/ddplugin.rb +5 -0
- data/lib/ddplugin/plugin.rb +70 -0
- data/lib/ddplugin/registry.rb +76 -0
- data/lib/ddplugin/version.rb +7 -0
- data/test/helper.rb +9 -0
- data/test/test_plugin.rb +80 -0
- metadata +76 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 0de5a9e0217483b21eacdc6668deb299a6dd3e06
|
4
|
+
data.tar.gz: 2e1afa6aed108a66552d3b2e65ecde95cddd838f
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 68d16f23635d03879c49c1322c006a023157292ea6f1844bae05c2bba59f7d6c3e315a54799668c5ba43b98f3ec087f51d57cd27c3f5f366a973a6ad24078626
|
7
|
+
data.tar.gz: fa3a128aac7969bced4dbaf7248871d604fb2e15b97c205a014be6c3d0dc61e62a53026c41c6467ad05fa4a2216de0fc2f3dd1fb988f2c642ce0d82631745295
|
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
ddplugin (0.1)
|
5
|
+
|
6
|
+
GEM
|
7
|
+
remote: https://rubygems.org/
|
8
|
+
specs:
|
9
|
+
coveralls (0.7.0)
|
10
|
+
multi_json (~> 1.3)
|
11
|
+
rest-client
|
12
|
+
simplecov (>= 0.7)
|
13
|
+
term-ansicolor
|
14
|
+
thor
|
15
|
+
docile (1.1.1)
|
16
|
+
mime-types (2.0)
|
17
|
+
minitest (5.0.8)
|
18
|
+
multi_json (1.8.2)
|
19
|
+
rake (10.1.0)
|
20
|
+
rest-client (1.6.7)
|
21
|
+
mime-types (>= 1.16)
|
22
|
+
simplecov (0.8.2)
|
23
|
+
docile (~> 1.1.0)
|
24
|
+
multi_json
|
25
|
+
simplecov-html (~> 0.8.0)
|
26
|
+
simplecov-html (0.8.0)
|
27
|
+
term-ansicolor (1.2.2)
|
28
|
+
tins (~> 0.8)
|
29
|
+
thor (0.18.1)
|
30
|
+
tins (0.13.1)
|
31
|
+
|
32
|
+
PLATFORMS
|
33
|
+
ruby
|
34
|
+
|
35
|
+
DEPENDENCIES
|
36
|
+
bundler
|
37
|
+
coveralls
|
38
|
+
ddplugin!
|
39
|
+
minitest
|
40
|
+
rake
|
data/LICENSE
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
Copyright (c) 2013 Denis Defreyne
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
+
of this software and associated documentation files (the "Software"), to deal
|
5
|
+
in the Software without restriction, including without limitation the rights
|
6
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
+
copies of the Software, and to permit persons to whom the Software is
|
8
|
+
furnished to do so, subject to the following conditions:
|
9
|
+
|
10
|
+
The above copyright notice and this permission notice shall be included in all
|
11
|
+
copies or substantial portions of the Software.
|
12
|
+
|
13
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
19
|
+
SOFTWARE.
|
data/NEWS.md
ADDED
File without changes
|
data/README.md
ADDED
@@ -0,0 +1,137 @@
|
|
1
|
+
[](https://travis-ci.org/ddfreyne/ddplugin)
|
2
|
+
[](https://codeclimate.com/github/ddfreyne/ddplugin)
|
3
|
+
[](https://coveralls.io/r/ddfreyne/ddplugin)
|
4
|
+
|
5
|
+
# ddplugin
|
6
|
+
|
7
|
+
*ddplugin* is a library for managing plugins.
|
8
|
+
|
9
|
+
Designing a library so that third parties can easily extend it greatly improves its usefulness. *ddplugin* helps solve this problem using *plugins*, which are classes of a certain type and with a given identifier (Ruby symbol).
|
10
|
+
|
11
|
+
This code was extracted from nanoc, where it has been in production for years.
|
12
|
+
|
13
|
+
## Use case
|
14
|
+
|
15
|
+
Many projects can make use of plugins. Here are a few examples:
|
16
|
+
|
17
|
+
* a **text processing library** with *filters* such as `colorize-syntax`, `markdown` and `smartify-quotes`.
|
18
|
+
|
19
|
+
* an **image processing library** with *filters* such as `resize`, `desaturate` and `rotate`.
|
20
|
+
|
21
|
+
* a **database driver abstraction** with *connectors* such as `postgres`, `sqlite3` and `mysql`.
|
22
|
+
|
23
|
+
* a **document management system** with *data sources* such as `filesystem` and `database`.
|
24
|
+
|
25
|
+
In *ddplugin*, the filters, connectors and data sources would be *plugin types*, while the actual plugins, such as `markdown`, `rotate`, `postgres` and `database` would be *plugins*.
|
26
|
+
|
27
|
+
A typical way to use plugins would be to store the plugin names in a configuration file, so that the actual plugin implementations can be discovered at runtime.
|
28
|
+
|
29
|
+
## Dependencies
|
30
|
+
|
31
|
+
*ddplugin* requires Ruby 1.9.3 or higher.
|
32
|
+
|
33
|
+
## Versioning
|
34
|
+
|
35
|
+
*ddplugin* adheres to [Semantic Versioning 2.0.0](http://semver.org).
|
36
|
+
|
37
|
+
## Installation
|
38
|
+
|
39
|
+
**NOTE:** *ddplugin* has not been released as a gem yet, so these installation instructions are not usable yet.
|
40
|
+
|
41
|
+
If your library where you want to use *ddplugin* has a gemspec, add *ddplugin* as a runtime dependency to the gemspec:
|
42
|
+
|
43
|
+
```ruby
|
44
|
+
spec.add_runtime_dependency 'ddplugin' '~> 1.0'
|
45
|
+
```
|
46
|
+
|
47
|
+
If you use Bundler instead, add it to the `Gemfile`:
|
48
|
+
|
49
|
+
```ruby
|
50
|
+
gem 'ddplugin', '~> 1.0'
|
51
|
+
```
|
52
|
+
|
53
|
+
## Usage
|
54
|
+
|
55
|
+
Plugin type are classes that extend `DDPlugin::Plugin`:
|
56
|
+
|
57
|
+
```ruby
|
58
|
+
class Filter
|
59
|
+
extend DDPlugin::Plugin
|
60
|
+
end
|
61
|
+
|
62
|
+
class DataSource
|
63
|
+
extend DDPlugin::Plugin
|
64
|
+
end
|
65
|
+
```
|
66
|
+
|
67
|
+
To define a plugin, create a class that inherits from the plugin type and sets the identifier:
|
68
|
+
|
69
|
+
```ruby
|
70
|
+
class ERBFilter < Filter
|
71
|
+
identifier :erb
|
72
|
+
end
|
73
|
+
|
74
|
+
class HamlFilter < Filter
|
75
|
+
identifier :haml
|
76
|
+
end
|
77
|
+
|
78
|
+
class FilesystemDataSource < DataSource
|
79
|
+
identifier :filesystem
|
80
|
+
end
|
81
|
+
|
82
|
+
class PostgresDataSource < DataSource
|
83
|
+
identifier :postgres
|
84
|
+
end
|
85
|
+
```
|
86
|
+
|
87
|
+
To find a plugin of a given type and with a given identifier, call `.named` on the plugin type, passing an identifier:
|
88
|
+
|
89
|
+
```ruby
|
90
|
+
Filter.named(:erb)
|
91
|
+
# => ERBFilter
|
92
|
+
|
93
|
+
Filter.named(:haml)
|
94
|
+
# => HamlFilter
|
95
|
+
|
96
|
+
DataSource.named(:filesystem)
|
97
|
+
# => FilesystemDataSource
|
98
|
+
|
99
|
+
DataSource.named(:postgres)
|
100
|
+
# => PostgresDataSource
|
101
|
+
```
|
102
|
+
|
103
|
+
To get all plugins of a given type, call `.all` on the plugin type:
|
104
|
+
|
105
|
+
```ruby
|
106
|
+
Filter.all
|
107
|
+
# => [ ERBFilter, HamlFilter ]
|
108
|
+
|
109
|
+
DataSource.all
|
110
|
+
# => [ FilesystemDataSource, PostgresDataSource ]
|
111
|
+
```
|
112
|
+
|
113
|
+
To get the identifier of a plugin, call `.identifier`:
|
114
|
+
|
115
|
+
```ruby
|
116
|
+
Filter.named(:erb).identifier
|
117
|
+
# => :erb
|
118
|
+
|
119
|
+
PostgresDataSource.identifier
|
120
|
+
# => :postgres
|
121
|
+
```
|
122
|
+
|
123
|
+
## Development
|
124
|
+
|
125
|
+
Pull requests and issues are greatly appreciated.
|
126
|
+
|
127
|
+
When you submit a pull request, make sure that your change is covered by tests, and that the `README` and [YARD](http://yardoc.org/) source code documentation are still up-to-date.
|
128
|
+
|
129
|
+
To run the tests, execute `rake`:
|
130
|
+
|
131
|
+
```
|
132
|
+
% rake
|
133
|
+
```
|
134
|
+
|
135
|
+
## Contact
|
136
|
+
|
137
|
+
*ddplugin* is written by Denis Defreyne <denis.defreyne@stoneship.org>
|
data/Rakefile
ADDED
data/ddplugin.gemspec
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
$LOAD_PATH.unshift(File.expand_path('../lib/', __FILE__))
|
4
|
+
require 'ddplugin/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = 'ddplugin'
|
8
|
+
s.version = DDPlugin::VERSION
|
9
|
+
s.homepage = 'http://github.com/ddfreyne/ddplugin/'
|
10
|
+
s.summary = 'Plugins for Ruby apps'
|
11
|
+
s.description = 'Provides plugin management for Ruby projects'
|
12
|
+
|
13
|
+
s.author = 'Denis Defreyne'
|
14
|
+
s.email = 'denis.defreyne@stoneship.org'
|
15
|
+
s.license = 'MIT'
|
16
|
+
|
17
|
+
s.required_ruby_version = '>= 1.9.3'
|
18
|
+
|
19
|
+
s.files = Dir['[A-Z]*'] +
|
20
|
+
Dir['{lib,test}/**/*'] +
|
21
|
+
[ 'ddplugin.gemspec' ]
|
22
|
+
s.require_paths = [ 'lib' ]
|
23
|
+
|
24
|
+
s.rdoc_options = [ '--main', 'README.md' ]
|
25
|
+
s.extra_rdoc_files = [ 'LICENSE', 'README.md', 'NEWS.md' ]
|
26
|
+
|
27
|
+
s.add_development_dependency('bundler')
|
28
|
+
end
|
data/lib/ddplugin.rb
ADDED
@@ -0,0 +1,70 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module DDPlugin
|
4
|
+
|
5
|
+
# A module that contains class methods for plugins. It provides functions
|
6
|
+
# for setting identifiers and finding plugins. Plugin classes should extend
|
7
|
+
# this module.
|
8
|
+
module Plugin
|
9
|
+
|
10
|
+
# @overload identifiers(*identifiers)
|
11
|
+
#
|
12
|
+
# Sets the identifiers for this class.
|
13
|
+
#
|
14
|
+
# @param [Array<Symbol>] identifiers A list of identifiers to assign to
|
15
|
+
# this class.
|
16
|
+
#
|
17
|
+
# @return [void]
|
18
|
+
#
|
19
|
+
# @overload identifiers
|
20
|
+
#
|
21
|
+
# @return [Array<Symbol>] The identifiers for this class
|
22
|
+
def identifiers(*identifiers)
|
23
|
+
if identifiers.empty?
|
24
|
+
DDPlugin::Registry.instance.identifiers_of(root_class, self)
|
25
|
+
else
|
26
|
+
DDPlugin::Registry.instance.register(root_class, self, *identifiers)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
# @return [Class] The root class for this class
|
31
|
+
def root_class
|
32
|
+
klass = self
|
33
|
+
klass = klass.superclass while klass.superclass.respond_to?(:identifiers)
|
34
|
+
klass
|
35
|
+
end
|
36
|
+
|
37
|
+
# @overload identifier(identifier)
|
38
|
+
#
|
39
|
+
# Sets the identifier for this class.
|
40
|
+
#
|
41
|
+
# @param [Symbol] identifier The identifier to assign to this class.
|
42
|
+
#
|
43
|
+
# @return [void]
|
44
|
+
#
|
45
|
+
# @overload identifier
|
46
|
+
#
|
47
|
+
# @return [Symbol] The first identifier for this class
|
48
|
+
def identifier(identifier=nil)
|
49
|
+
if identifier
|
50
|
+
self.identifiers(identifier)
|
51
|
+
else
|
52
|
+
self.identifiers.first
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
# @return [Enumerable<Class>] All classes of this type
|
57
|
+
def all
|
58
|
+
DDPlugin::Registry.instance.find_all(self)
|
59
|
+
end
|
60
|
+
|
61
|
+
# @param [Symbol] identifier The identifier of the class to find
|
62
|
+
#
|
63
|
+
# @return [Class] The class with the given identifier
|
64
|
+
def named(identifier)
|
65
|
+
DDPlugin::Registry.instance.find(self, identifier)
|
66
|
+
end
|
67
|
+
|
68
|
+
end
|
69
|
+
|
70
|
+
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module DDPlugin
|
4
|
+
|
5
|
+
# The registry is responsible for keeping track of all loaded plugins.
|
6
|
+
class Registry
|
7
|
+
|
8
|
+
# Returns the shared {DDPlugin::Registry} instance, creating it if none
|
9
|
+
# exists yet.
|
10
|
+
#
|
11
|
+
# @return [DDPlugin::Registry] The shared plugin registry
|
12
|
+
def self.instance
|
13
|
+
@instance ||= self.new
|
14
|
+
end
|
15
|
+
|
16
|
+
# @api private
|
17
|
+
def initialize
|
18
|
+
@identifiers_to_classes = Hash.new { |h,k| h[k] = {}.dup }
|
19
|
+
@classes_to_identifiers = Hash.new { |h,k| h[k] = {}.dup }
|
20
|
+
end
|
21
|
+
|
22
|
+
# Registers the given class as a plugin.
|
23
|
+
#
|
24
|
+
# @param [Class] root_class The root class of the class to register
|
25
|
+
#
|
26
|
+
# @param [Class] klass The class to register
|
27
|
+
#
|
28
|
+
# @param [Symbol] identifiers One or more symbols identifying the class
|
29
|
+
#
|
30
|
+
# @return [void]
|
31
|
+
def register(root_class, klass, *identifiers)
|
32
|
+
identifiers.each do |identifier|
|
33
|
+
@classes_to_identifiers[root_class][klass] ||= []
|
34
|
+
|
35
|
+
@identifiers_to_classes[root_class][identifier] = klass
|
36
|
+
@classes_to_identifiers[root_class][klass] << identifier
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
# @param [Class] root_class The root class of the class to find the
|
41
|
+
# identifiers for
|
42
|
+
#
|
43
|
+
# @param [Class] klass The class to get the identifiers for
|
44
|
+
#
|
45
|
+
# @return [Array<Symbol>] The identifiers for the given class
|
46
|
+
def identifiers_of(root_class, klass)
|
47
|
+
@classes_to_identifiers[root_class] ||= {}
|
48
|
+
@classes_to_identifiers[root_class].fetch(klass, [])
|
49
|
+
end
|
50
|
+
|
51
|
+
# Finds the class that is a descendant of the given class and has the given
|
52
|
+
# identifier.
|
53
|
+
#
|
54
|
+
# @param [Class] root_class The root class of the class to return
|
55
|
+
#
|
56
|
+
# @param [Symbol] identifier The identifier of the class to return
|
57
|
+
#
|
58
|
+
# @return [Class, nil] The class with the given identifier
|
59
|
+
def find(root_class, identifier)
|
60
|
+
@identifiers_to_classes[root_class] ||= {}
|
61
|
+
@identifiers_to_classes[root_class][identifier]
|
62
|
+
end
|
63
|
+
|
64
|
+
# Returns all classes that are registered descendants of the given class.
|
65
|
+
#
|
66
|
+
# @param [Class] root_class The root class of the class to return
|
67
|
+
#
|
68
|
+
# @return [Enumerable<Class>] A collection of registered classes
|
69
|
+
def find_all(root_class)
|
70
|
+
@identifiers_to_classes[root_class] ||= {}
|
71
|
+
@identifiers_to_classes[root_class].values
|
72
|
+
end
|
73
|
+
|
74
|
+
end
|
75
|
+
|
76
|
+
end
|
data/test/helper.rb
ADDED
data/test/test_plugin.rb
ADDED
@@ -0,0 +1,80 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'helper'
|
4
|
+
|
5
|
+
class DDPlugin::PluginTest < Minitest::Test
|
6
|
+
|
7
|
+
class IdentifierSample
|
8
|
+
extend DDPlugin::Plugin
|
9
|
+
end
|
10
|
+
|
11
|
+
class NamedSample
|
12
|
+
extend DDPlugin::Plugin
|
13
|
+
end
|
14
|
+
|
15
|
+
class AllSample
|
16
|
+
extend DDPlugin::Plugin
|
17
|
+
end
|
18
|
+
|
19
|
+
class InheritanceSample
|
20
|
+
extend DDPlugin::Plugin
|
21
|
+
end
|
22
|
+
|
23
|
+
def test_identifier
|
24
|
+
klass = Class.new(IdentifierSample)
|
25
|
+
assert_nil klass.identifier
|
26
|
+
|
27
|
+
klass.identifier :foo
|
28
|
+
assert_equal :foo, klass.identifier
|
29
|
+
|
30
|
+
klass.identifier :bar
|
31
|
+
assert_equal :foo, klass.identifier
|
32
|
+
end
|
33
|
+
|
34
|
+
def test_identifiers
|
35
|
+
klass = Class.new(IdentifierSample)
|
36
|
+
assert_empty klass.identifiers
|
37
|
+
|
38
|
+
klass.identifiers :foo1, :foo2
|
39
|
+
assert_equal [ :foo1, :foo2 ], klass.identifiers
|
40
|
+
|
41
|
+
klass.identifiers :bar1, :bar2
|
42
|
+
assert_equal [ :foo1, :foo2, :bar1, :bar2 ], klass.identifiers
|
43
|
+
end
|
44
|
+
|
45
|
+
def test_root
|
46
|
+
superklass = Class.new(InheritanceSample)
|
47
|
+
superklass.identifier :super
|
48
|
+
|
49
|
+
subklass = Class.new(superklass)
|
50
|
+
subklass.identifiers :sub, :also_sub
|
51
|
+
|
52
|
+
assert_equal superklass, InheritanceSample.named(:super)
|
53
|
+
assert_equal subklass, InheritanceSample.named(:sub)
|
54
|
+
|
55
|
+
assert_equal :sub, subklass.identifier
|
56
|
+
assert_equal [ :sub, :also_sub ], subklass.identifiers
|
57
|
+
|
58
|
+
assert_equal InheritanceSample, superklass.root_class
|
59
|
+
assert_equal InheritanceSample, subklass.root_class
|
60
|
+
end
|
61
|
+
|
62
|
+
def test_named
|
63
|
+
klass = Class.new(NamedSample)
|
64
|
+
klass.identifier :named_test
|
65
|
+
|
66
|
+
assert_nil NamedSample.named(:unknown)
|
67
|
+
assert_equal klass, NamedSample.named(:named_test)
|
68
|
+
end
|
69
|
+
|
70
|
+
def test_all
|
71
|
+
klass1 = Class.new(AllSample)
|
72
|
+
klass1.identifier :one
|
73
|
+
|
74
|
+
klass2 = Class.new(AllSample)
|
75
|
+
klass2.identifier :two
|
76
|
+
|
77
|
+
assert_equal [ klass1, klass2 ], AllSample.all
|
78
|
+
end
|
79
|
+
|
80
|
+
end
|
metadata
ADDED
@@ -0,0 +1,76 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: ddplugin
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: '0.1'
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Denis Defreyne
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2013-12-14 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
description: Provides plugin management for Ruby projects
|
28
|
+
email: denis.defreyne@stoneship.org
|
29
|
+
executables: []
|
30
|
+
extensions: []
|
31
|
+
extra_rdoc_files:
|
32
|
+
- LICENSE
|
33
|
+
- README.md
|
34
|
+
- NEWS.md
|
35
|
+
files:
|
36
|
+
- Gemfile
|
37
|
+
- Gemfile.lock
|
38
|
+
- LICENSE
|
39
|
+
- NEWS.md
|
40
|
+
- Rakefile
|
41
|
+
- README.md
|
42
|
+
- lib/ddplugin/plugin.rb
|
43
|
+
- lib/ddplugin/registry.rb
|
44
|
+
- lib/ddplugin/version.rb
|
45
|
+
- lib/ddplugin.rb
|
46
|
+
- test/helper.rb
|
47
|
+
- test/test_plugin.rb
|
48
|
+
- ddplugin.gemspec
|
49
|
+
homepage: http://github.com/ddfreyne/ddplugin/
|
50
|
+
licenses:
|
51
|
+
- MIT
|
52
|
+
metadata: {}
|
53
|
+
post_install_message:
|
54
|
+
rdoc_options:
|
55
|
+
- "--main"
|
56
|
+
- README.md
|
57
|
+
require_paths:
|
58
|
+
- lib
|
59
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
60
|
+
requirements:
|
61
|
+
- - ">="
|
62
|
+
- !ruby/object:Gem::Version
|
63
|
+
version: 1.9.3
|
64
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
requirements: []
|
70
|
+
rubyforge_project:
|
71
|
+
rubygems_version: 2.0.3
|
72
|
+
signing_key:
|
73
|
+
specification_version: 4
|
74
|
+
summary: Plugins for Ruby apps
|
75
|
+
test_files: []
|
76
|
+
has_rdoc:
|