File: README.md

package info (click to toggle)
ruby-ddplugin 1.0.3-1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, forky, sid, trixie
  • size: 132 kB
  • sloc: ruby: 154; makefile: 3
file content (166 lines) | stat: -rw-r--r-- 4,370 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
[![Gem version](http://img.shields.io/gem/v/ddplugin.svg)](http://rubygems.org/gems/ddplugin)
[![Gem downloads](https://img.shields.io/gem/dt/ddplugin.svg)](http://rubygems.org/gems/ddplugin)
[![Build status](http://img.shields.io/travis/ddfreyne/ddplugin.svg)](https://travis-ci.org/ddfreyne/ddplugin)
[![Code Climate](http://img.shields.io/codeclimate/github/ddfreyne/ddplugin.svg)](https://codeclimate.com/github/ddfreyne/ddplugin)
[![Code Coverage](https://img.shields.io/coveralls/ddfreyne/ddplugin.svg)](https://coveralls.io/r/ddfreyne/ddplugin)

# ddplugin

*ddplugin* is a library for managing plugins.

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).

This code was extracted from Nanoc, where it has been in production for years.

## Use case

Many projects can make use of plugins. Here are a few examples:

* a **text processing library** with *filters* such as `colorize-syntax`, `markdown` and `smartify-quotes`.

* an **image processing library** with *filters* such as `resize`, `desaturate` and `rotate`.

* a **database driver abstraction** with *connectors* such as `postgres`, `sqlite3` and `mysql`.

* a **document management system** with *data sources* such as `filesystem` and `database`.

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*.

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.

## Requirements

*ddplugin* requires Ruby 2.3 or higher.

## Versioning

*ddplugin* adheres to [Semantic Versioning 2.0.0](http://semver.org).

## Installation

If your library where you want to use *ddplugin* has a gemspec, add *ddplugin* as a runtime dependency to the gemspec:

```ruby
spec.add_runtime_dependency 'ddplugin', '~> 1.0'
```

If you use Bundler instead, add it to the `Gemfile`:

```ruby
gem 'ddplugin', '~> 1.0'
```

## Usage

Plugin type are classes that extend `DDPlugin::Plugin`:

```ruby
class Filter
  extend DDPlugin::Plugin
end

class DataSource
  extend DDPlugin::Plugin
end
```

To define a plugin, create a class that inherits from the plugin type and sets the identifier, either as a symbol or a string:

```ruby
class ERBFilter < Filter
  # Specify the identifier as a symbol…
  identifier :erb
end

class HamlFilter < Filter
  # … or as a string …
  identifier 'haml'
end

class FilesystemDataSource < DataSource
  # … or even provide multiple.
  identifiers :filesystem, :file_system
end

class PostgresDataSource < DataSource
  # … or mix and match (not sure why you would, though)
  identifier :postgres, 'postgresql'
end
```

To find a plugin of a given type and with a given identifier, call `.named` on the plugin type, passing an identifier:

```ruby
Filter.named(:erb)
# => ERBFilter

Filter.named('haml')
# => HamlFilter

DataSource.named(:filesystem)
# => FilesystemDataSource

DataSource.named(:postgres)
# => PostgresDataSource
```

In a real-world situation, the plugin types could be described in the environment:

```
% cat .env
DATA_SOURCE_TYPE=postgres
```

```ruby
DataSource.named(ENV.fetch('DATA_SOURCE_TYPE'))
# => PostgresDataSource
```

… or in a configuration file:

```
% cat config.yml
data_source: 'filesystem'
```

```ruby
config = YAML.load_file('config.yml')
DataSource.named(config.fetch('data_source'))
# => FilesystemDataSource
```

To get all plugins of a given type, call `.all` on the plugin type:

```ruby
Filter.all
# => [ERBFilter, HamlFilter]

DataSource.all
# => [FilesystemDataSource, PostgresDataSource]
```

To get the identifier of a plugin, call `.identifier`, which returns a symbol:

```ruby
Filter.named(:erb).identifier
# => :erb

Filter.named('haml').identifier
# => :haml

PostgresDataSource.identifier
# => :postgres
```

## Development

Pull requests and issues are greatly appreciated.

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.

To run the tests:

```
% bundle install
% bundle exec rake
```