dry-plugins 0.1.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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 9c3f397db9409161943cf1beb2b08991137bea56
4
+ data.tar.gz: 421e745136b991141b11b2254a9d6d5a4d545ace
5
+ SHA512:
6
+ metadata.gz: 1aafce2b121f32b1c726cf7948dbb9517ec6830e487acdad85c96bccea58e89248a96d47795129968ac34c0d7df05acd1e4fa925eef561d4e869352f030fc387
7
+ data.tar.gz: e3d80259a5e6700e7eb1009726365e319430e164b5c291237cd12e22a88ed6172b7853561298d455bc79c4ccf284119004d9f2405a9e2a2df863221b2fd21631
data/.gitignore ADDED
@@ -0,0 +1,12 @@
1
+ .bundle
2
+ .rspec_status
3
+ .yardoc
4
+ _yardoc
5
+ coverage
6
+ doc
7
+ Gemfile.lock
8
+ pkg
9
+ spec/examples.txt
10
+ spec/reports
11
+ tmp
12
+ vendor/bundle
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --require spec_helper
2
+ --format documentation
3
+ --color
data/.rubocop.yml ADDED
@@ -0,0 +1,32 @@
1
+ AllCops:
2
+ TargetRubyVersion: 2.4
3
+ DefaultFormatter: fuubar
4
+ DisplayCopNames: true
5
+ ExtraDetails: true
6
+ Exclude:
7
+ - vendor/**/*.rb
8
+
9
+ inherit_from: .rubocop_todo.yml
10
+
11
+ Metrics/BlockLength:
12
+ Exclude:
13
+ - rakelib/**/*.rb
14
+ - spec/**/*.rb
15
+ - vendor/**/*.rb
16
+
17
+ # It is 2017, UTF time!
18
+ Style/AsciiComments:
19
+ Enabled: false
20
+
21
+ Style/Documentation:
22
+ Exclude:
23
+ # Specification is doc itself
24
+ - spec/**/*
25
+ # Tests are docs itself
26
+ - test/**/*
27
+
28
+ Style/FileName:
29
+ Exclude:
30
+ # cozy name for gem requirement
31
+ - 'lib/dry-plugins.rb'
32
+ - 'lib/rspec/dry-plugins.rb'
data/.rubocop_todo.yml ADDED
@@ -0,0 +1,35 @@
1
+ # This configuration was generated by
2
+ # `rubocop --auto-gen-config`
3
+ # on 2017-06-15 22:45:51 +0300 using RuboCop version 0.49.0.
4
+ # The point is for the user to remove these configuration records
5
+ # one by one as the offenses are removed from the code base.
6
+ # Note that changes in the inspected code, or installation of new
7
+ # versions of RuboCop, may require this file to be generated again.
8
+
9
+ # Offense count: 1
10
+ # Cop supports --auto-correct.
11
+ # Configuration parameters: AllowUnusedKeywordArguments, IgnoreEmptyMethods.
12
+ Lint/UnusedMethodArgument:
13
+ Exclude:
14
+ - 'lib/rspec/dry-plugins.rb'
15
+
16
+ # Offense count: 1
17
+ # Configuration parameters: ContextCreatingMethods, MethodCreatingMethods.
18
+ Lint/UselessAccessModifier:
19
+ Exclude:
20
+ - 'lib/dry/plugins/registry/builder.rb'
21
+
22
+ # Offense count: 2
23
+ Metrics/AbcSize:
24
+ Max: 20
25
+
26
+ # Offense count: 14
27
+ # Configuration parameters: AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, IgnoredPatterns.
28
+ # URISchemes: http, https
29
+ Metrics/LineLength:
30
+ Max: 120
31
+
32
+ # Offense count: 1
33
+ # Configuration parameters: CountComments.
34
+ Metrics/MethodLength:
35
+ Max: 14
data/.simplecov ADDED
@@ -0,0 +1,6 @@
1
+ SimpleCov.start do
2
+ add_filter '/bin/'
3
+ add_filter '/spec/'
4
+ add_group('Missing') { |src| src.covered_percent < 100 }
5
+ add_group('Covered') { |src| src.covered_percent == 100 }
6
+ end
data/.yardopts ADDED
@@ -0,0 +1,7 @@
1
+ --title 'dry-plugins'
2
+ --plugin yard-commonmarker
3
+ --markup-provider commonmarker
4
+ --markup markdown
5
+ --readme README.md
6
+ --tag "default:Default values"
7
+ lib/**/*.rb
data/Gemfile ADDED
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ source 'https://rubygems.org'
4
+
5
+ gemspec name: 'dry-plugins'
data/Gemfile.lock ADDED
@@ -0,0 +1,99 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ dry-plugins (0.1.0)
5
+ dry-auto_inject
6
+ dry-configurable
7
+ dry-container (~> 0.6.0)
8
+ dry-core
9
+ dry-equalizer
10
+ inflecto
11
+
12
+ GEM
13
+ remote: https://rubygems.org/
14
+ specs:
15
+ ast (2.3.0)
16
+ bundler-audit (0.5.0)
17
+ bundler (~> 1.2)
18
+ thor (~> 0.18)
19
+ commonmarker (0.16.0)
20
+ ruby-enum (~> 0.5)
21
+ concurrent-ruby (1.0.5)
22
+ development-toolbox (0.7.0)
23
+ bundler (~> 1.13)
24
+ bundler-audit (~> 0.5)
25
+ rake (~> 12.0)
26
+ rspec (~> 3.5)
27
+ rspec-its (~> 1.2)
28
+ rubocop (~> 0.48)
29
+ yard-commonmarker (~> 0.3)
30
+ diff-lcs (1.3)
31
+ docile (1.1.5)
32
+ dry-auto_inject (0.4.3)
33
+ dry-container (>= 0.3.4)
34
+ dry-configurable (0.7.0)
35
+ concurrent-ruby (~> 1.0)
36
+ dry-container (0.6.0)
37
+ concurrent-ruby (~> 1.0)
38
+ dry-configurable (~> 0.1, >= 0.1.3)
39
+ dry-core (0.3.1)
40
+ concurrent-ruby (~> 1.0)
41
+ dry-equalizer (0.2.0)
42
+ i18n (0.8.1)
43
+ inflecto (0.0.2)
44
+ json (2.1.0)
45
+ parallel (1.11.2)
46
+ parser (2.4.0.0)
47
+ ast (~> 2.2)
48
+ powerpack (0.1.1)
49
+ rainbow (2.2.2)
50
+ rake
51
+ rake (12.0.0)
52
+ rspec (3.6.0)
53
+ rspec-core (~> 3.6.0)
54
+ rspec-expectations (~> 3.6.0)
55
+ rspec-mocks (~> 3.6.0)
56
+ rspec-core (3.6.0)
57
+ rspec-support (~> 3.6.0)
58
+ rspec-expectations (3.6.0)
59
+ diff-lcs (>= 1.2.0, < 2.0)
60
+ rspec-support (~> 3.6.0)
61
+ rspec-its (1.2.0)
62
+ rspec-core (>= 3.0.0)
63
+ rspec-expectations (>= 3.0.0)
64
+ rspec-mocks (3.6.0)
65
+ diff-lcs (>= 1.2.0, < 2.0)
66
+ rspec-support (~> 3.6.0)
67
+ rspec-support (3.6.0)
68
+ rubocop (0.49.0)
69
+ parallel (~> 1.10)
70
+ parser (>= 2.3.3.1, < 3.0)
71
+ powerpack (~> 0.1)
72
+ rainbow (>= 1.99.1, < 3.0)
73
+ ruby-progressbar (~> 1.7)
74
+ unicode-display_width (~> 1.0, >= 1.0.1)
75
+ ruby-enum (0.7.1)
76
+ i18n
77
+ ruby-progressbar (1.8.1)
78
+ simplecov (0.14.1)
79
+ docile (~> 1.1.0)
80
+ json (>= 1.8, < 3)
81
+ simplecov-html (~> 0.10.0)
82
+ simplecov-html (0.10.1)
83
+ thor (0.19.4)
84
+ unicode-display_width (1.2.1)
85
+ yard (0.9.9)
86
+ yard-commonmarker (0.3.0)
87
+ commonmarker (~> 0.16)
88
+ yard (~> 0.9)
89
+
90
+ PLATFORMS
91
+ ruby
92
+
93
+ DEPENDENCIES
94
+ development-toolbox (~> 0.6)
95
+ dry-plugins!
96
+ simplecov
97
+
98
+ BUNDLED WITH
99
+ 1.15.1
data/LICENSE.md ADDED
@@ -0,0 +1,28 @@
1
+ # @title dry-plugins: The MIT License (MIT)
2
+
3
+ # The MIT License (MIT)
4
+
5
+ ## Copyright
6
+
7
+ * [Alex Semyonov] <[alex@semyonov.us]>, 2017
8
+
9
+ Permission is hereby granted, free of charge, to any person obtaining a copy
10
+ of this software and associated documentation files (the "Software"), to deal
11
+ in the Software without restriction, including without limitation the rights
12
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13
+ copies of the Software, and to permit persons to whom the Software is
14
+ furnished to do so, subject to the following conditions:
15
+
16
+ The above copyright notice and this permission notice shall be included in
17
+ all copies or substantial portions of the Software.
18
+
19
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25
+ THE SOFTWARE.
26
+
27
+ [Alex Semyonov]: https://alex.semyonov.us/ "Alex Semyonov"
28
+ [alex@semyonov.us]: mailto:alex@semyonov.us?subject=dry-plugins "Email Alex about dry-plugins"
data/README.md ADDED
@@ -0,0 +1,32 @@
1
+ # @title dry-plugins: DSL for plugins
2
+ # @author Alex Semyonov <alex@semyonov.us>
3
+
4
+ # dry-plugins: DSL for plugins
5
+
6
+ Abstract DSL for providing plug-in interface for PORO and complex structures.
7
+
8
+ Wikipedia says following:
9
+
10
+ > The host application {Dry::Plugins::Host::DSL provides services} which the plug-in can use, including {Dry::Plugins::Registry#register a way for plug-ins to register themselves} with the host application and a protocol for the exchange of data with plug-ins. Plug-ins depend on the services provided by the host application and do not usually work by themselves. Conversely, the host application operates independently of the plug-ins, making it possible for end-users to add and update plug-ins dynamically without needing to make changes to the host application.
11
+ >
12
+ > Programmers typically implement plug-in functionality using shared libraries installed in a place prescribed by the host application. HyperCard supported a similar facility, but more commonly included the plug-in code in the HyperCard documents (called stacks) themselves. Thus the HyperCard stack became a self-contained application in its own right, distributable as a single entity that end-users could run without the need for additional installation-steps. Programs may also implement plugins by loading a directory of simple script files written in a scripting language like Python or Lua.
13
+
14
+ ## TL;DR
15
+
16
+ dry-plugins is a utility to provide plug-ins interface for your Ruby class (called *host* in documentation).
17
+
18
+ See {Dry::Plugins}.
19
+
20
+ Configuration: see {Dry::Plugins::Config}.
21
+
22
+ ##
23
+
24
+ Documentation:
25
+
26
+ * {Dry::Plugins::Registry} - a plug-ins registry;
27
+ * {Dry::Plugins::Registry::Resolver} - a plug-in resolver;
28
+ * {Dry::Plugins::Plugin} — a proxy for a plug-in;
29
+
30
+ ## Copyright and License
31
+
32
+ © [Alex Semyonov](https://alex.semyonov.us/) <[alex@semyonov.us](mailto:alex@semyonov.us?subject=dry-plugins)>, 2017, [MIT license](LICENSE.md)
data/Rakefile ADDED
@@ -0,0 +1,4 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'development/tasks'
4
+ Development::Tasks.install
data/bin/rake ADDED
@@ -0,0 +1,18 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ #
5
+ # This file was generated by Bundler.
6
+ #
7
+ # The application 'rake' is installed as part of a gem, and
8
+ # this file is here to facilitate running it.
9
+ #
10
+
11
+ require 'pathname'
12
+ ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile',
13
+ Pathname.new(__FILE__).realpath)
14
+
15
+ require 'rubygems'
16
+ require 'bundler/setup'
17
+
18
+ load Gem.bin_path('rake', 'rake')
data/bin/rspec ADDED
@@ -0,0 +1,18 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ #
5
+ # This file was generated by Bundler.
6
+ #
7
+ # The application 'rspec' is installed as part of a gem, and
8
+ # this file is here to facilitate running it.
9
+ #
10
+
11
+ require 'pathname'
12
+ ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile',
13
+ Pathname.new(__FILE__).realpath)
14
+
15
+ require 'rubygems'
16
+ require 'bundler/setup'
17
+
18
+ load Gem.bin_path('rspec-core', 'rspec')
data/bin/yard ADDED
@@ -0,0 +1,18 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ #
5
+ # This file was generated by Bundler.
6
+ #
7
+ # The application 'yard' is installed as part of a gem, and
8
+ # this file is here to facilitate running it.
9
+ #
10
+
11
+ require 'pathname'
12
+ ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile',
13
+ Pathname.new(__FILE__).realpath)
14
+
15
+ require 'rubygems'
16
+ require 'bundler/setup'
17
+
18
+ load Gem.bin_path('yard', 'yard')
data/bin/yardoc ADDED
@@ -0,0 +1,18 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ #
5
+ # This file was generated by Bundler.
6
+ #
7
+ # The application 'yardoc' is installed as part of a gem, and
8
+ # this file is here to facilitate running it.
9
+ #
10
+
11
+ require 'pathname'
12
+ ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile',
13
+ Pathname.new(__FILE__).realpath)
14
+
15
+ require 'rubygems'
16
+ require 'bundler/setup'
17
+
18
+ load Gem.bin_path('yard', 'yardoc')
data/bin/yri ADDED
@@ -0,0 +1,18 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ #
5
+ # This file was generated by Bundler.
6
+ #
7
+ # The application 'yri' is installed as part of a gem, and
8
+ # this file is here to facilitate running it.
9
+ #
10
+
11
+ require 'pathname'
12
+ ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile',
13
+ Pathname.new(__FILE__).realpath)
14
+
15
+ require 'rubygems'
16
+ require 'bundler/setup'
17
+
18
+ load Gem.bin_path('yard', 'yri')
@@ -0,0 +1,35 @@
1
+ # coding: utf-8
2
+ # frozen_string_literal: true
3
+
4
+ lib = File.expand_path('../lib', __FILE__)
5
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
6
+ require 'dry/plugins/version'
7
+
8
+ Gem::Specification.new do |spec|
9
+ spec.name = 'dry-plugins'
10
+ spec.version = Dry::Plugins::VERSION
11
+ spec.authors = ['Alex Semyonov']
12
+ spec.email = ['alex@semyonov.us']
13
+
14
+ spec.summary = 'Dry way to add plugins to your framework'
15
+ spec.description = 'Generic plugin interface.'
16
+ spec.homepage = 'http://alsemyonov.gitlab.com/dry-plugins/'
17
+ spec.license = 'MIT'
18
+
19
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
20
+ f.match(%r{^(test|spec|features)/})
21
+ end
22
+ spec.bindir = 'exe'
23
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
24
+ spec.require_paths = ['lib']
25
+
26
+ spec.add_runtime_dependency 'dry-configurable'
27
+ spec.add_runtime_dependency 'dry-container', '~> 0.6.0'
28
+ spec.add_runtime_dependency 'dry-auto_inject'
29
+ spec.add_runtime_dependency 'dry-equalizer'
30
+ spec.add_runtime_dependency 'dry-core'
31
+ spec.add_runtime_dependency 'inflecto'
32
+
33
+ spec.add_development_dependency 'development-toolbox', '~> 0.6'
34
+ spec.add_development_dependency 'simplecov'
35
+ end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'dry/plugins/config'
4
+ require 'dry/plugins/host/dsl'
5
+
6
+ module Dry
7
+ module Plugins
8
+ # Plug-ins builder
9
+ # @see Builder#call
10
+ class Builder
11
+ # @!method module_builder
12
+ # @return [ModuleBuilder]
13
+ #
14
+ # @!method registry_builder
15
+ # @return [Registry::Builder]
16
+ #
17
+ # @!method host_builder
18
+ # @return [Host::Builder]
19
+ include Import[:module_builder, :registry_builder, :host_builder]
20
+
21
+ # Build a plug-in registry for given `host`
22
+ #
23
+ # 1. Extend `host` with a {Host::DSL plug-ins host DSL}
24
+ # 2. Create a {Registry plug-ins registry} for `host`,
25
+ # Find or create a `Module` containing plug-ins for `host`,
26
+ # and extend it with {DSL plug-ins registry DSL}
27
+ #
28
+ # @param host [Module]
29
+ # @return [Registry]
30
+ def call(host, registry: registry_builder.call(host))
31
+ host_builder.call(host, registry)
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,115 @@
1
+ # frozen_string_literal: true
2
+
3
+ # noinspection RubyConstantNamingConvention
4
+
5
+ require 'dry-auto_inject'
6
+ require 'dry-container'
7
+ require 'dry-configurable'
8
+
9
+ # rubocop:disable Style/Documentation
10
+
11
+ module Dry
12
+ module Plugins
13
+ extend Dry::Container::Mixin
14
+
15
+ Import = Dry.AutoInject(self)
16
+
17
+ # @!parse
18
+ # # Global configuration of {Dry::Plugins}
19
+ # #
20
+ # # @!group Method names
21
+ # #
22
+ # # @!attribute [rw] configure_method
23
+ # # Name of the method that will be used for configuration when
24
+ # # {Dry::Plugins::Host::DSL#use} called with block
25
+ # # @return [Symbol]
26
+ # # @default `:configure`
27
+ # #
28
+ # # @!attribute [rw] load_dependencies_method
29
+ # # Name of the method that will be used for loading dependencies when
30
+ # # {Dry::Plugins::Host::DSL#use} called
31
+ # # @return [Symbol]
32
+ # # @default `:load_dependencies`
33
+ # #
34
+ # # @!attribute [rw] registry_method
35
+ # # @return [Symbol]
36
+ # # @default `:plugins_registry`
37
+ # #
38
+ # # @!group Constant names
39
+ # #
40
+ # # @!attribute [rw] class_interface_name
41
+ # # Name of the module that will be used as a class extension
42
+ # # when plug-in is included
43
+ # # @return [Symbol]
44
+ # # @default `:ClassInterface`
45
+ # #
46
+ # # @!attribute [rw] plugins_module_name
47
+ # # Name of the module that will be used for plug-ins
48
+ # # @return [Symbol]
49
+ # # @default `:Plugins`
50
+ # #
51
+ # # @!attribute [rw] registry_class_name
52
+ # # Name of the class that will be used for plug-ins registry
53
+ # # @return [Symbol]
54
+ # # @default `:Registry`
55
+ # #
56
+ # class Config < Dry::Configurable::Config
57
+ # end
58
+ #
59
+ # @!method self.config
60
+ # @return [Config]
61
+ #
62
+ # @!method self.configure
63
+ # @yieldparam config [Config]
64
+ #
65
+ # @return [Config]
66
+ #
67
+ # @see Config#configure_method config.configure_method
68
+ # @see Config#load_dependencies_method config.load_dependencies_method
69
+ # @see Config#registry_method config.registry_method
70
+ # @see Config#class_interface_name config.class_interface_name
71
+ # @see Config#plugins_module_name config.plugins_module_name
72
+ # @see Config#registry_class_name config.registry_class_name
73
+ #
74
+ # @example dry-plugins default configuration
75
+ # Dry::Plugins.configure do |config|
76
+ # config.configure_method = :configure
77
+ # config.load_dependencies_method = :load_dependencies
78
+ # config.class_interface_name = :ClassInterface
79
+ # config.plugins_module_name = :Plugins
80
+ # config.registry_class_name = :Registry
81
+ # end
82
+ setting :container, Dry::Plugins
83
+ setting :configure_method, :configure
84
+ setting :load_dependencies_method, :load_dependencies
85
+ setting :registry_method, :plugins_registry
86
+ setting :class_interface_name, :ClassInterface
87
+ setting :plugins_module_name, :Plugins
88
+ setting :registry_class_name, :Registry
89
+
90
+ register :host_builder do
91
+ require 'dry/plugins/host/builder'
92
+ Host::Builder.new
93
+ end
94
+
95
+ register :module_builder do
96
+ require 'dry/plugins/module_builder'
97
+ ModuleBuilder.new
98
+ end
99
+
100
+ register :builder do
101
+ require 'dry/plugins/builder'
102
+ Builder.new
103
+ end
104
+
105
+ register :registry_builder do
106
+ require 'dry/plugins/registry/builder'
107
+ Registry::Builder.new
108
+ end
109
+
110
+ register :registry_class_builder do
111
+ require 'dry/plugins/registry/class_builder'
112
+ Registry::ClassBuilder.new
113
+ end
114
+ end
115
+ end
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'forwardable'
4
+
5
+ module Dry
6
+ module Plugins
7
+ # Plug-ins DSL
8
+ module DSL
9
+ # @api private
10
+ def self.extended(plugins)
11
+ super(plugins)
12
+ plugins.extend SingleForwardable
13
+ plugins.def_single_delegators Plugins.config.registry_method,
14
+ :register,
15
+ :resolve,
16
+ :[]
17
+ end
18
+
19
+ # @return [Module, Host::DSL]
20
+ def host
21
+ @host ||= Inflecto.constantize(name.gsub(/::[^:]+$/, ''))
22
+ end
23
+
24
+ # @!method register(name, plugin)
25
+ # @param name [#to_sym]
26
+ # @param plugin [Module, Plugin]
27
+ #
28
+ # @return [Plugin]
29
+ #
30
+ # @see Dry::Plugins::Registry#register
31
+
32
+ # @!method resolve(name)
33
+ # @param name [#to_sym]
34
+ #
35
+ # @return [Plugin]
36
+ #
37
+ # @see Dry::Plugins::Registry#resolve
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Dry
4
+ module Plugins
5
+ # Plug-ins error
6
+ class Error < StandardError
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,46 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'dry/plugins/config'
4
+ require 'dry/plugins/host/dsl'
5
+
6
+ module Dry
7
+ module Plugins
8
+ module Host
9
+ # Extends a host with plug-ins interfaces
10
+ class Builder
11
+ def initialize(registry_method: Plugins.config.registry_method)
12
+ @registry_method = registry_method
13
+ end
14
+
15
+ # @return [Symbol]
16
+ attr_reader :registry_method
17
+
18
+ # @param host [Module]
19
+ #
20
+ # @return [Module]
21
+ #
22
+ # @example
23
+ # require 'dry/plugins/module_builder'
24
+ #
25
+ # class Host
26
+ # end
27
+ #
28
+ # module_builder = Dry::Plugins::HostExtender.new
29
+ # module_builder.call(Host) #=> Host::Plugins
30
+ def call(host, registry)
31
+ unless host.respond_to? registry_method
32
+ host.define_singleton_method registry_method do
33
+ registry
34
+ end
35
+ end
36
+
37
+ unless host.singleton_class.included_modules.include? Host::DSL
38
+ host.extend Host::DSL
39
+ end
40
+
41
+ host
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end