Project

ddplugin

0.01
No release in over 3 years
Low commit activity in last 3 years
Provides plugin management for Ruby projects
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
 Dependencies
 Project Readme

Gem version Gem downloads Build status

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.

Installation

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

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

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

gem 'ddplugin', '~> 1.0'

Usage

Plugin type are classes that extend DDPlugin::Plugin:

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:

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:

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
DataSource.named(ENV.fetch('DATA_SOURCE_TYPE')) # => PostgresDataSource

… or in a configuration file:

% cat config.yml
data_source: 'filesystem'
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:

Filter.all

DataSource.all # => [FilesystemDataSource, PostgresDataSource]

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

Filter.named(:erb).identifier

Filter.named('haml').identifier

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 source code documentation are still up-to-date.

To run the tests:

% bundle install
% bundle exec rake