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.
@@ -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: []