absinthe 0.0.2
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.
- data/lib/absinthe.rb +7 -0
- data/lib/absinthe/distillery.rb +30 -0
- data/lib/absinthe/distillery/context.rb +112 -0
- data/lib/absinthe/distillery/source_loader.rb +47 -0
- data/lib/absinthe/dsl.rb +12 -0
- metadata +50 -0
data/lib/absinthe.rb
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
module Absinthe
|
2
|
+
module Plugins; end
|
3
|
+
|
4
|
+
class Exception < ::Exception; end
|
5
|
+
|
6
|
+
module Distillery
|
7
|
+
require 'distillery/context'
|
8
|
+
require 'distillery/source_loader'
|
9
|
+
|
10
|
+
class Warehouse
|
11
|
+
attr_reader :root_context
|
12
|
+
def initialize main_object
|
13
|
+
raise "Warehouse init failure!" if main_object.nil?
|
14
|
+
@root_context = Context.new
|
15
|
+
root_context.register :namespace, RootNamespace.new(main_object)
|
16
|
+
root_context.register :source_loader, SourceLoader
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.root_context
|
21
|
+
@warehouse.root_context
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.configure main_object
|
25
|
+
@warehouse = Warehouse.new(main_object)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
# Always.
|
30
|
+
Absinthe::Distillery.configure self
|
@@ -0,0 +1,112 @@
|
|
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
|
@@ -0,0 +1,47 @@
|
|
1
|
+
module Absinthe::Distillery
|
2
|
+
class PluginNotFound < Exception; end
|
3
|
+
|
4
|
+
class SourceLoader
|
5
|
+
def boot! ctx
|
6
|
+
if ctx[:app_root]
|
7
|
+
$LOAD_PATH.unshift(File.expand_path(File.join(ctx[:app_root], 'lib')))
|
8
|
+
end
|
9
|
+
|
10
|
+
@plugin_paths = []
|
11
|
+
$LOAD_PATH.each do |path|
|
12
|
+
plugin_path = File.join path, 'absinthe', 'plugins'
|
13
|
+
if File.directory? plugin_path
|
14
|
+
@plugin_paths << plugin_path
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def source_files root, paths
|
20
|
+
# TODO validate the root param
|
21
|
+
sources = []
|
22
|
+
|
23
|
+
# TODO this is a mess
|
24
|
+
paths.each do |path|
|
25
|
+
plugin_sources = []
|
26
|
+
@plugin_paths.each do |plugin_path|
|
27
|
+
target = File.join plugin_path, "#{path}.rb"
|
28
|
+
if File.file? target
|
29
|
+
file = File.new target
|
30
|
+
plugin_sources << file
|
31
|
+
|
32
|
+
support_dir = File.join plugin_path, path.to_s
|
33
|
+
if File.directory? support_dir
|
34
|
+
$LOAD_PATH.unshift support_dir
|
35
|
+
end
|
36
|
+
|
37
|
+
yield file
|
38
|
+
$LOAD_PATH.delete support_dir
|
39
|
+
end
|
40
|
+
end
|
41
|
+
if plugin_sources.empty?
|
42
|
+
raise PluginNotFound, "No plugin named #{path} was found in #{@plugin_paths.join ', '}"
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
data/lib/absinthe/dsl.rb
ADDED
@@ -0,0 +1,12 @@
|
|
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
|
metadata
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: absinthe
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.2
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Lance Cooper
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-04-06 00:00:00.000000000 Z
|
13
|
+
dependencies: []
|
14
|
+
description: Not yet suitable for production use!
|
15
|
+
email: lance.m.cooper@gmail.com
|
16
|
+
executables: []
|
17
|
+
extensions: []
|
18
|
+
extra_rdoc_files: []
|
19
|
+
files:
|
20
|
+
- lib/absinthe/distillery/context.rb
|
21
|
+
- lib/absinthe/distillery/source_loader.rb
|
22
|
+
- lib/absinthe/dsl.rb
|
23
|
+
- lib/absinthe/distillery.rb
|
24
|
+
- lib/absinthe.rb
|
25
|
+
homepage: https://github.com/deathwish/absinthe
|
26
|
+
licenses:
|
27
|
+
- bsd
|
28
|
+
post_install_message:
|
29
|
+
rdoc_options: []
|
30
|
+
require_paths:
|
31
|
+
- lib
|
32
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '0'
|
38
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ! '>='
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: '0'
|
44
|
+
requirements: []
|
45
|
+
rubyforge_project:
|
46
|
+
rubygems_version: 1.8.25
|
47
|
+
signing_key:
|
48
|
+
specification_version: 3
|
49
|
+
summary: Absinthe is an opinioned IoC container for Ruby.
|
50
|
+
test_files: []
|