absinthe 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ module Absinthe
2
+ $:.unshift(File.expand_path(File.join(File.dirname(__FILE__), 'absinthe')))
3
+ require 'dsl'
4
+ require 'distillery'
5
+
6
+ extend Dsl
7
+ end
@@ -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
@@ -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: []