absinthe 0.0.2 → 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.md +25 -0
- data/LICENCE +9 -0
- data/README.md +15 -0
- data/lib/absinthe.rb +13 -2
- data/lib/absinthe/distillery.rb +10 -15
- data/lib/absinthe/distillery/injector.rb +30 -0
- data/lib/absinthe/distillery/plugin.rb +35 -0
- data/lib/absinthe/distillery/root_namespace.rb +27 -0
- data/lib/absinthe/distillery/source_loader.rb +29 -15
- data/lib/absinthe/plugins/context.rb +55 -0
- data/lib/absinthe/plugins/plugin_injector.rb +25 -0
- data/lib/absinthe/version.rb +3 -0
- data/test/integration/test_absinthe_boot.rb +20 -0
- data/test/integration/test_plugin_injector.rb +30 -0
- data/test/integration/test_root_context.rb +21 -0
- data/test/test_helper.rb +2 -0
- metadata +16 -5
- data/lib/absinthe/distillery/context.rb +0 -112
- data/lib/absinthe/dsl.rb +0 -12
data/CHANGELOG.md
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
# Changelog
|
2
|
+
|
3
|
+
Breaking changes, bugfixes, and new features for each release are summarized here.
|
4
|
+
For full details, please consult the SCM changelog.
|
5
|
+
|
6
|
+
## v0.0.3
|
7
|
+
* Breaking change: Moved require_dir from :namespace to :source_loader.
|
8
|
+
* Breaking change: Plugins are now loaded into the injected module.
|
9
|
+
This will break any load path manipulation or lazy require usage.
|
10
|
+
* Breaking change: The block passed to boot is now evaluated directly
|
11
|
+
against the context, rather then the provided object or main.
|
12
|
+
* Add support for registering run blocks which will run against the
|
13
|
+
provided object or main.
|
14
|
+
* Add the beginnings of a test suite.
|
15
|
+
* Add supporting documents to gem build.
|
16
|
+
* Add the plugin_injector plugin, which creates proxy classes
|
17
|
+
for all registered plugins on the root namespace. For example,
|
18
|
+
the context plugin instance will be available through the Context
|
19
|
+
class in the namespace.
|
20
|
+
|
21
|
+
## v0.0.2
|
22
|
+
* Fixed gemspec.
|
23
|
+
|
24
|
+
## v0.0.1
|
25
|
+
* First release, yanked due to invalid gemspec.
|
data/LICENCE
ADDED
@@ -0,0 +1,9 @@
|
|
1
|
+
Copyright (c) 2013, Lance Cooper <lance.m.cooper@gmail.com>
|
2
|
+
All rights reserved.
|
3
|
+
|
4
|
+
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
5
|
+
|
6
|
+
Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
7
|
+
Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
|
8
|
+
Neither the name of the Absinthe Project nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
|
9
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
data/README.md
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
# Absinthe
|
2
|
+
|
3
|
+
Absinthe is a lightweight IoC container for Ruby applications.
|
4
|
+
|
5
|
+
## Philosophy
|
6
|
+
|
7
|
+
Absinthe is designed around the premise that all metaprogramming in a Ruby application must be done via IoC if it is to be reliable, performant, or testable.
|
8
|
+
|
9
|
+
## Status
|
10
|
+
|
11
|
+
The project is currently experimental and should not be used for production applications.
|
12
|
+
|
13
|
+
## Licence
|
14
|
+
|
15
|
+
The 'new' or '3 clause' BSD licence, see LICENCE for details.
|
data/lib/absinthe.rb
CHANGED
@@ -1,7 +1,18 @@
|
|
1
1
|
module Absinthe
|
2
2
|
$:.unshift(File.expand_path(File.join(File.dirname(__FILE__), 'absinthe')))
|
3
|
-
require 'dsl'
|
4
3
|
require 'distillery'
|
5
4
|
|
6
|
-
|
5
|
+
def boot! boot_file, calling_context = nil, &block
|
6
|
+
injector = Distillery.injector
|
7
|
+
injector.register :app_root, File.expand_path(File.dirname(boot_file))
|
8
|
+
injector.register :calling_context, calling_context
|
9
|
+
injector.register :boot_proc, block
|
10
|
+
injector.inject(:plugin).tap do |plugin|
|
11
|
+
plugin.load :context
|
12
|
+
plugin.boot!
|
13
|
+
end
|
14
|
+
injector.inject(:context)
|
15
|
+
end
|
16
|
+
|
17
|
+
extend self
|
7
18
|
end
|
data/lib/absinthe/distillery.rb
CHANGED
@@ -1,28 +1,23 @@
|
|
1
1
|
module Absinthe
|
2
|
-
module Plugins; end
|
3
|
-
|
4
2
|
class Exception < ::Exception; end
|
5
3
|
|
6
4
|
module Distillery
|
7
|
-
require 'distillery/
|
5
|
+
require 'distillery/injector'
|
6
|
+
require 'distillery/root_namespace'
|
8
7
|
require 'distillery/source_loader'
|
8
|
+
require 'distillery/plugin'
|
9
9
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
root_context.register :source_loader, SourceLoader
|
10
|
+
def self.injector
|
11
|
+
Injector.new.tap do |injector|
|
12
|
+
injector.register :main_object, @main_object
|
13
|
+
injector.register :namespace, RootNamespace, :main_object
|
14
|
+
injector.register :source_loader, SourceLoader, :app_root, :namespace
|
15
|
+
injector.register :plugin, Plugin, :injector, :namespace, :source_loader
|
17
16
|
end
|
18
17
|
end
|
19
18
|
|
20
|
-
def self.root_context
|
21
|
-
@warehouse.root_context
|
22
|
-
end
|
23
|
-
|
24
19
|
def self.configure main_object
|
25
|
-
@
|
20
|
+
@main_object = main_object
|
26
21
|
end
|
27
22
|
end
|
28
23
|
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module Absinthe
|
2
|
+
module Distillery
|
3
|
+
class Injector
|
4
|
+
attr_reader :service_names
|
5
|
+
|
6
|
+
def initialize
|
7
|
+
@parameters = { }
|
8
|
+
@args = { }
|
9
|
+
@service_names = []
|
10
|
+
register :injector, self
|
11
|
+
end
|
12
|
+
|
13
|
+
def register name, clazz, *args
|
14
|
+
@parameters[name] = clazz
|
15
|
+
if @parameters[name].is_a?(Class)
|
16
|
+
@args[name] = args
|
17
|
+
@service_names << name # we lack ordered hash traversal on 1.8.
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def inject name
|
22
|
+
return @parameters[name] unless @parameters[name].is_a?(Class)
|
23
|
+
injections = @args[name].map do |injection|
|
24
|
+
injection.is_a?(Symbol) ? inject(injection) : injection
|
25
|
+
end
|
26
|
+
@parameters[name] = @parameters[name].new(*injections)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module Absinthe
|
2
|
+
module Plugins; end
|
3
|
+
|
4
|
+
module Distillery
|
5
|
+
class Plugin
|
6
|
+
class NotLoaded < Exception; end
|
7
|
+
|
8
|
+
attr_reader :injector, :namespace, :names
|
9
|
+
def initialize injector, namespace, source_loader
|
10
|
+
@injector, @namespace, @source_loader = injector, namespace, source_loader
|
11
|
+
@names = []
|
12
|
+
end
|
13
|
+
|
14
|
+
def load name
|
15
|
+
@source_loader.require_dir :plugins, name
|
16
|
+
|
17
|
+
# HACK not like this!
|
18
|
+
mod = @namespace.root::Absinthe::Plugins
|
19
|
+
plugin_name = mod.constants.grep(/#{name.to_s.gsub('_', '')}/i).first
|
20
|
+
raise NotLoaded, "#{name} was not found in Absinthe::Plugins" unless plugin_name
|
21
|
+
plugin = mod.const_get plugin_name
|
22
|
+
plugin.register @injector if plugin.respond_to? :register
|
23
|
+
@names << name
|
24
|
+
end
|
25
|
+
|
26
|
+
def boot!
|
27
|
+
@names.map do |name|
|
28
|
+
@injector.inject(name)
|
29
|
+
end.reverse.each do |plugin|
|
30
|
+
plugin.boot! if plugin.respond_to?(:boot!)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Absinthe
|
2
|
+
module Distillery
|
3
|
+
class RootNamespace
|
4
|
+
class LoadFailed < Exception; end
|
5
|
+
|
6
|
+
attr_reader :root, :main
|
7
|
+
def initialize main
|
8
|
+
@main = main
|
9
|
+
@root = Module.new { extend self }
|
10
|
+
main.include root
|
11
|
+
end
|
12
|
+
|
13
|
+
def register name, value
|
14
|
+
@root.send(:define_method, name) { value }
|
15
|
+
end
|
16
|
+
|
17
|
+
def load_file file
|
18
|
+
begin
|
19
|
+
@root.send(:module_eval, file.read, file.path, 1)
|
20
|
+
rescue Exception => ex
|
21
|
+
puts "Failed to load #{file.path}: #{ex.message}"
|
22
|
+
raise LoadFailed, ex
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -2,9 +2,10 @@ module Absinthe::Distillery
|
|
2
2
|
class PluginNotFound < Exception; end
|
3
3
|
|
4
4
|
class SourceLoader
|
5
|
-
def
|
6
|
-
|
7
|
-
|
5
|
+
def initialize app_root, namespace
|
6
|
+
@namespace = namespace
|
7
|
+
if app_root
|
8
|
+
$LOAD_PATH.unshift(File.expand_path(File.join(app_root, 'lib')))
|
8
9
|
end
|
9
10
|
|
10
11
|
@plugin_paths = []
|
@@ -16,32 +17,45 @@ module Absinthe::Distillery
|
|
16
17
|
end
|
17
18
|
end
|
18
19
|
|
19
|
-
def
|
20
|
+
def require_dir root, *paths
|
20
21
|
# TODO validate the root param
|
21
|
-
sources = []
|
22
|
-
|
23
22
|
# TODO this is a mess
|
24
23
|
paths.each do |path|
|
25
24
|
plugin_sources = []
|
26
25
|
@plugin_paths.each do |plugin_path|
|
27
26
|
target = File.join plugin_path, "#{path}.rb"
|
28
|
-
|
29
|
-
file = File.new target
|
30
|
-
plugin_sources << file
|
27
|
+
next unless File.file? target
|
31
28
|
|
32
|
-
|
33
|
-
if File.directory? support_dir
|
34
|
-
$LOAD_PATH.unshift support_dir
|
35
|
-
end
|
29
|
+
support_dir = File.join plugin_path, path.to_s
|
36
30
|
|
37
|
-
|
38
|
-
|
31
|
+
with_hooked_require(support_dir) do
|
32
|
+
plugin_sources << target
|
33
|
+
@namespace.load_file File.new(target)
|
39
34
|
end
|
40
35
|
end
|
36
|
+
|
41
37
|
if plugin_sources.empty?
|
42
38
|
raise PluginNotFound, "No plugin named #{path} was found in #{@plugin_paths.join ', '}"
|
43
39
|
end
|
44
40
|
end
|
45
41
|
end
|
42
|
+
|
43
|
+
private
|
44
|
+
def with_hooked_require support_dir
|
45
|
+
original_require = ::Kernel.method(:require)
|
46
|
+
namespace = @namespace
|
47
|
+
::Kernel.send(:define_method, :require) do |filename|
|
48
|
+
target = File.join support_dir, "#{filename}.rb"
|
49
|
+
if File.file? target
|
50
|
+
namespace.load_file File.new(target)
|
51
|
+
else
|
52
|
+
original_require.call filename
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
yield
|
57
|
+
ensure
|
58
|
+
::Kernel.send(:define_method, :require, &original_require)
|
59
|
+
end
|
46
60
|
end
|
47
61
|
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
module Absinthe
|
2
|
+
module Plugins
|
3
|
+
class Context
|
4
|
+
def self.register injector
|
5
|
+
injector.register :context, Context, :injector
|
6
|
+
end
|
7
|
+
|
8
|
+
def initialize injector
|
9
|
+
@injector = injector
|
10
|
+
@run_blocks = []
|
11
|
+
self[:namespace].register :context, self
|
12
|
+
instance_exec(&self[:boot_proc]) if self[:boot_proc]
|
13
|
+
end
|
14
|
+
|
15
|
+
def configure &block
|
16
|
+
self.instance_eval &block
|
17
|
+
end
|
18
|
+
|
19
|
+
def const name, value
|
20
|
+
@injector.register name, value
|
21
|
+
end
|
22
|
+
|
23
|
+
def register name, clazz, *args
|
24
|
+
@injector.register name, clazz, *args
|
25
|
+
end
|
26
|
+
|
27
|
+
def inject name
|
28
|
+
@injector.inject name
|
29
|
+
end
|
30
|
+
|
31
|
+
def [] name
|
32
|
+
inject name
|
33
|
+
end
|
34
|
+
|
35
|
+
def plugin! name
|
36
|
+
self[:plugin].load name
|
37
|
+
end
|
38
|
+
|
39
|
+
def run *args, &block
|
40
|
+
@run_blocks << {
|
41
|
+
:args => args,
|
42
|
+
:block => block
|
43
|
+
}
|
44
|
+
end
|
45
|
+
|
46
|
+
def boot!
|
47
|
+
boot_scope = (self[:calling_context] || self[:main_object])
|
48
|
+
@run_blocks.each do |run|
|
49
|
+
injections = run[:args].map(&method(:inject))
|
50
|
+
boot_scope.instance_exec(*injections, &run[:block])
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Absinthe::Plugins
|
2
|
+
class PluginInjector
|
3
|
+
def self.register injector
|
4
|
+
injector.register :plugin_injector, PluginInjector, :plugin
|
5
|
+
end
|
6
|
+
|
7
|
+
def initialize plugin
|
8
|
+
@plugin = plugin
|
9
|
+
end
|
10
|
+
|
11
|
+
def boot!
|
12
|
+
@plugin.names.each do |service_name|
|
13
|
+
service = @plugin.injector.inject(service_name)
|
14
|
+
proxy = Module.new { extend self }
|
15
|
+
proxy.send(:define_method, :method_missing) do |meth, *args, &block|
|
16
|
+
service.send meth, *args, &block
|
17
|
+
end
|
18
|
+
|
19
|
+
# TODO should be elsewhere.
|
20
|
+
clazz_name = service_name.to_s.split('_').map(&:capitalize!).join ''
|
21
|
+
@plugin.namespace.root.send :const_set, clazz_name, proxy
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class TestAbsintheBoot < Test::Unit::TestCase
|
4
|
+
def test_registers_constants_on_the_returned_context
|
5
|
+
context = Absinthe.boot!(__FILE__) {
|
6
|
+
const :foo, :bar
|
7
|
+
}
|
8
|
+
assert_equal :bar, context[:foo]
|
9
|
+
end
|
10
|
+
|
11
|
+
def test_calls_run_blocks_in_the_given_scope
|
12
|
+
calling_context = Object.new
|
13
|
+
Absinthe.boot!(__FILE__, calling_context) do
|
14
|
+
run do
|
15
|
+
@scope_var = 'set_on_scope'
|
16
|
+
end
|
17
|
+
end
|
18
|
+
assert_equal 'set_on_scope', calling_context.instance_variable_get(:@scope_var)
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class TestPluginInjector < Test::Unit::TestCase
|
4
|
+
class Foo
|
5
|
+
attr_reader :msg
|
6
|
+
|
7
|
+
def initialize msg
|
8
|
+
@msg = msg
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
def test_injector_is_available_in_run_blocks
|
13
|
+
Absinthe.boot!(__FILE__, self) do
|
14
|
+
plugin! :plugin_injector
|
15
|
+
run do
|
16
|
+
assert PluginInjector.class
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def test_injected_plugins_are_proxied_on_the_namespace
|
22
|
+
context = Absinthe.boot!(__FILE__) do
|
23
|
+
register :baxter, Foo, 'hi!'
|
24
|
+
plugin! :plugin_injector
|
25
|
+
end
|
26
|
+
|
27
|
+
msg = context[:namespace].root::Context[:baxter].msg
|
28
|
+
assert_equal 'hi!', msg
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
TOPLEVEL = self
|
4
|
+
class TestRootContext < Test::Unit::TestCase
|
5
|
+
def test_contexts_namespace_has_main
|
6
|
+
context = Absinthe.boot! __FILE__
|
7
|
+
assert_equal TOPLEVEL, context[:namespace].main
|
8
|
+
end
|
9
|
+
|
10
|
+
def test_context_injects_params_for_run_blocks
|
11
|
+
params = nil
|
12
|
+
Absinthe.boot!(__FILE__) do
|
13
|
+
const :a, 1
|
14
|
+
const :b, 2
|
15
|
+
run :a, :b, do |a, b|
|
16
|
+
params = [a, b]
|
17
|
+
end
|
18
|
+
end
|
19
|
+
assert_equal [1, 2], params
|
20
|
+
end
|
21
|
+
end
|
data/test/test_helper.rb
ADDED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: absinthe
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.3
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-
|
12
|
+
date: 2013-06-09 00:00:00.000000000Z
|
13
13
|
dependencies: []
|
14
14
|
description: Not yet suitable for production use!
|
15
15
|
email: lance.m.cooper@gmail.com
|
@@ -17,11 +17,22 @@ executables: []
|
|
17
17
|
extensions: []
|
18
18
|
extra_rdoc_files: []
|
19
19
|
files:
|
20
|
-
-
|
20
|
+
- README.md
|
21
|
+
- CHANGELOG.md
|
22
|
+
- LICENCE
|
23
|
+
- lib/absinthe/distillery/injector.rb
|
24
|
+
- lib/absinthe/distillery/root_namespace.rb
|
21
25
|
- lib/absinthe/distillery/source_loader.rb
|
22
|
-
- lib/absinthe/
|
26
|
+
- lib/absinthe/distillery/plugin.rb
|
23
27
|
- lib/absinthe/distillery.rb
|
28
|
+
- lib/absinthe/plugins/context.rb
|
29
|
+
- lib/absinthe/plugins/plugin_injector.rb
|
30
|
+
- lib/absinthe/version.rb
|
24
31
|
- lib/absinthe.rb
|
32
|
+
- test/integration/test_absinthe_boot.rb
|
33
|
+
- test/integration/test_plugin_injector.rb
|
34
|
+
- test/integration/test_root_context.rb
|
35
|
+
- test/test_helper.rb
|
25
36
|
homepage: https://github.com/deathwish/absinthe
|
26
37
|
licenses:
|
27
38
|
- bsd
|
@@ -43,7 +54,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
43
54
|
version: '0'
|
44
55
|
requirements: []
|
45
56
|
rubyforge_project:
|
46
|
-
rubygems_version: 1.8.
|
57
|
+
rubygems_version: 1.8.10
|
47
58
|
signing_key:
|
48
59
|
specification_version: 3
|
49
60
|
summary: Absinthe is an opinioned IoC container for Ruby.
|
@@ -1,112 +0,0 @@
|
|
1
|
-
module Absinthe
|
2
|
-
module Distillery
|
3
|
-
class RootNamespace
|
4
|
-
class LoadFailed < Exception; end
|
5
|
-
|
6
|
-
attr_reader :root, :main
|
7
|
-
def initialize main_object
|
8
|
-
@main = main_object
|
9
|
-
@plugins = []
|
10
|
-
end
|
11
|
-
|
12
|
-
def boot! ctx
|
13
|
-
@context = ctx
|
14
|
-
@root = Module.new { extend self }
|
15
|
-
|
16
|
-
# Import ourselves into the new namespace, and remove ourselves from main.
|
17
|
-
@root.const_set :Absinthe, ::Absinthe
|
18
|
-
Object.send :remove_const, :Absinthe
|
19
|
-
|
20
|
-
root.send(:define_method, :context) { ctx }
|
21
|
-
main.include root
|
22
|
-
(ctx[:calling_context] || main).instance_eval {
|
23
|
-
ctx[:boot_proc].call ctx if ctx[:boot_proc]
|
24
|
-
}
|
25
|
-
end
|
26
|
-
|
27
|
-
def load_plugin name
|
28
|
-
require_dir :plugins, name
|
29
|
-
|
30
|
-
# HACK not like this!
|
31
|
-
plugin_name = Absinthe::Plugins.constants.grep(/#{name.to_s.gsub('_', '')}/i).first
|
32
|
-
plugin = Absinthe::Plugins.const_get plugin_name
|
33
|
-
plugin
|
34
|
-
end
|
35
|
-
|
36
|
-
def require_dir root, *paths
|
37
|
-
@context[:source_loader].source_files(root, paths) do |file|
|
38
|
-
eval_in_scope file
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
private
|
43
|
-
def eval_in_scope file
|
44
|
-
begin
|
45
|
-
@root.send(:module_eval, file.read, file.path, 1)
|
46
|
-
rescue Exception => ex
|
47
|
-
puts "Failed to load #{file.path}: #{ex.message}"
|
48
|
-
raise LoadFailed, ex
|
49
|
-
end
|
50
|
-
end
|
51
|
-
end
|
52
|
-
|
53
|
-
class Context
|
54
|
-
module Dsl
|
55
|
-
def configure &block
|
56
|
-
self.instance_eval &block
|
57
|
-
end
|
58
|
-
|
59
|
-
def const name, value
|
60
|
-
register name, value
|
61
|
-
end
|
62
|
-
|
63
|
-
def [] name, *args
|
64
|
-
inject name, *args
|
65
|
-
end
|
66
|
-
end
|
67
|
-
include Dsl
|
68
|
-
|
69
|
-
attr_reader :parameters, :args
|
70
|
-
def initialize
|
71
|
-
@parameters = { }
|
72
|
-
@args = { }
|
73
|
-
end
|
74
|
-
|
75
|
-
def boot!
|
76
|
-
inject(:namespace).boot! self
|
77
|
-
end
|
78
|
-
|
79
|
-
def register name, clazz, *args
|
80
|
-
@parameters[name] = clazz
|
81
|
-
@args[name] = args if @parameters[name].is_a?(Class)
|
82
|
-
end
|
83
|
-
|
84
|
-
def inject name, *args
|
85
|
-
return @parameters[name] unless @parameters[name].is_a?(Class)
|
86
|
-
injections = (@args[name] + args).map do |injection|
|
87
|
-
injection.is_a?(Symbol) ? inject(injection) : injection
|
88
|
-
end
|
89
|
-
@parameters[name].new(*injections).tap do |obj|
|
90
|
-
if obj.respond_to?(:boot!)
|
91
|
-
# anything responding to boot is treated as a singleton service.
|
92
|
-
@parameters[name] = obj
|
93
|
-
case obj.method(:boot!).arity
|
94
|
-
when 0
|
95
|
-
obj.boot!
|
96
|
-
when 1
|
97
|
-
obj.boot! self
|
98
|
-
else
|
99
|
-
raise "Invalid boot method for #{name}"
|
100
|
-
end
|
101
|
-
end
|
102
|
-
end
|
103
|
-
end
|
104
|
-
|
105
|
-
def plugin! name
|
106
|
-
plugin = inject(:namespace).load_plugin name
|
107
|
-
plugin.register self if plugin.respond_to? :register
|
108
|
-
inject name
|
109
|
-
end
|
110
|
-
end
|
111
|
-
end
|
112
|
-
end
|
data/lib/absinthe/dsl.rb
DELETED
@@ -1,12 +0,0 @@
|
|
1
|
-
module Absinthe
|
2
|
-
module Dsl
|
3
|
-
def boot! boot_file, calling_context = nil, &block
|
4
|
-
Distillery.root_context.configure do
|
5
|
-
const :app_root, File.expand_path(File.dirname(boot_file))
|
6
|
-
const :calling_context, calling_context
|
7
|
-
const :boot_proc, block
|
8
|
-
boot!
|
9
|
-
end
|
10
|
-
end
|
11
|
-
end
|
12
|
-
end
|