mushin 0.4.0 → 0.5.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 +4 -4
- data/README.md +71 -2
- data/lib/mushin/domain.rb +123 -0
- data/lib/mushin/ext.rb +10 -0
- data/lib/mushin/stack.rb +10 -0
- data/lib/mushin/version.rb +1 -1
- data/lib/mushin.rb +8 -21
- data/samples/sample1.rb +168 -0
- data/samples/sample2.rb +165 -0
- data/samples/sample3.rb +105 -0
- data/samples/sample4.rb +155 -0
- data/samples/sample5.rb +186 -0
- metadata +10 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1f70e9a7877e3a7c66d3059d6c532475bd46b461
|
4
|
+
data.tar.gz: e6be036dc7da19ad1cf2a6d1a471f0b4fb20109f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: bff8590b02972719c0c6033f05b5acf7ca3c30e93ff5f653604d106b5541cecd856e939ba48938d4c853c620c803ea57c45e77a790ac48c10d643086feb2d7de
|
7
|
+
data.tar.gz: bab6e09ba6ba66ced0efbc732a8406df66df837fe040a99966301cf00f9eff05d9c5c6d5833d3ec1d29e2ca386ca6d703637569e56e52a00110e7e6e87823d6b
|
data/README.md
CHANGED
@@ -1,8 +1,13 @@
|
|
1
1
|
# Mushin
|
2
|
+
In a mushin app there is two DSLs, domain developer DSL (provided via mushin) and app developer DSL(provided via the domain developer)
|
3
|
+
|
4
|
+
Context is a place to define a DSL
|
5
|
+
A Bounded Context can be considered as a miniature application, containing its own Domain,
|
6
|
+
own code and persistence mechanisms. Within a Bounded Context, there should be logical
|
7
|
+
consistency; each Bounded Context should be independent of any other Bounded Context.
|
2
8
|
|
3
9
|
Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/mushin`. To experiment with that code, run `bin/console` for an interactive prompt.
|
4
10
|
|
5
|
-
TODO: Delete this and the text above, and describe your gem
|
6
11
|
|
7
12
|
## Installation
|
8
13
|
|
@@ -21,8 +26,72 @@ Or install it yourself as:
|
|
21
26
|
$ gem install mushin
|
22
27
|
|
23
28
|
## Usage
|
29
|
+
```
|
30
|
+
mushin new domain
|
31
|
+
```
|
32
|
+
This command generates a new domain that consits of a context.rb and an empty directory of ext/
|
33
|
+
|
34
|
+
The context.rb requires mushin and require_relative everything in the ext directory.
|
35
|
+
Its initialize &block acts as a simple dsl for all the methods it contains.
|
36
|
+
|
37
|
+
```
|
38
|
+
require 'mushin'
|
39
|
+
Dir['./ext/**/*.rb'].each{ |f| require_relative f }
|
40
|
+
|
41
|
+
class Context
|
42
|
+
def initialize &block
|
43
|
+
instance_eval &block
|
44
|
+
end
|
45
|
+
end
|
46
|
+
```
|
24
47
|
|
25
|
-
|
48
|
+
```
|
49
|
+
mushin new ext
|
50
|
+
```
|
51
|
+
This command generates a new domain extension in the ext/ directory
|
52
|
+
|
53
|
+
```
|
54
|
+
module Internal
|
55
|
+
end
|
56
|
+
|
57
|
+
class Main < Mushin::Ext # this raise an error if the inheriting class doens't have :initialize and :call
|
58
|
+
include Internal
|
59
|
+
|
60
|
+
def initialize app=nil, opts={}, params={}
|
61
|
+
@app = app
|
62
|
+
@opts = opts
|
63
|
+
@params = params
|
64
|
+
end
|
65
|
+
|
66
|
+
def call env
|
67
|
+
#NOTE Utter Generated Code: used to provide you an env hash variable
|
68
|
+
env = Hash.new if env.nil?
|
69
|
+
|
70
|
+
p "#{self} ------ Inbound maniuplation"
|
71
|
+
p env
|
72
|
+
p @params
|
73
|
+
env[:query] = @params[:query]
|
74
|
+
# Exception halt the middleware chain that backing out in a reverse order, works really well.
|
75
|
+
case
|
76
|
+
when env[:query].nil?, env[:query].empty?
|
77
|
+
#TODO https://www.sitepoint.com/ruby-error-handling-beyond-basics/
|
78
|
+
#TODO http://ieftimov.com/exception-handling-and-testing
|
79
|
+
#return raise EmptyQuery
|
80
|
+
p "empty is no good"
|
81
|
+
else
|
82
|
+
env[:tpbbot] = search(env[:query])
|
83
|
+
end
|
84
|
+
|
85
|
+
@app.call(env)
|
86
|
+
|
87
|
+
p "#{self} ------ Outbound maniuplation"
|
88
|
+
p env
|
89
|
+
|
90
|
+
end
|
91
|
+
|
92
|
+
```
|
93
|
+
## Reading list
|
94
|
+
[domain-driven design servcies architecture](https://www.thoughtworks.com/insights/blog/domain-driven-design-services-architecture) .
|
26
95
|
|
27
96
|
## Development
|
28
97
|
|
@@ -0,0 +1,123 @@
|
|
1
|
+
# 1- an access method :context is defined in DSLBuilder(thats a module avialable as class methods to the domain class of the application.
|
2
|
+
# 2- the :context takes a name, &block and pass instance_eval it aganist an object created from DSLBuilder::Context
|
3
|
+
# 3- DSLBuilder::Context initialize takes a context_name say "torrent_bots" and create an app_context_klass and creates an access method with the :context_name inside DSL
|
4
|
+
#
|
5
|
+
module Mushin
|
6
|
+
module DSLBuilder
|
7
|
+
class Context
|
8
|
+
attr_accessor :context_name
|
9
|
+
# defines a DSL::Klass of type Context based on :name
|
10
|
+
# Supplies the defined DSL::Klass with a method of the construct
|
11
|
+
def initialize context_name, &block
|
12
|
+
@context_name = context_name.capitalize
|
13
|
+
|
14
|
+
app_context_klass = Class.new(Object) do
|
15
|
+
def initialize &block
|
16
|
+
instance_eval &block
|
17
|
+
end
|
18
|
+
end
|
19
|
+
# creates a context klass dynamically
|
20
|
+
DSL.const_set(context_name.capitalize, app_context_klass) unless DSL.const_defined?(context_name.capitalize)
|
21
|
+
# creates an access method inside DSL for the dynamically created context klass
|
22
|
+
DSL.send(:define_method, context_name) do |&block|
|
23
|
+
DSL.const_get(context_name.capitalize).new &block unless context_name.nil?
|
24
|
+
end
|
25
|
+
|
26
|
+
instance_eval &block
|
27
|
+
end
|
28
|
+
|
29
|
+
# access method for DSLBuilder::Construct klass inside a context object &block
|
30
|
+
def construct name, &block
|
31
|
+
app_context_klass = DSL.const_get(@context_name)
|
32
|
+
Construct.new(name, app_context_klass, &block) #.instance_eval &block
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
class Construct
|
37
|
+
attr_accessor :name, :stack, :app_context_klass
|
38
|
+
def initialize name, app_context_klass, &block
|
39
|
+
@name = name.capitalize
|
40
|
+
@middlewares = []
|
41
|
+
@stack = Mushin::Stack.new
|
42
|
+
@app_context_klass = app_context_klass
|
43
|
+
|
44
|
+
instance_eval &block
|
45
|
+
$log.info "middlewares after instance_eval"
|
46
|
+
$log.info middlewares = @middlewares
|
47
|
+
|
48
|
+
app_construct_klass = Class.new(Object) do
|
49
|
+
@@stack = Mushin::Stack.new
|
50
|
+
@@env = {}
|
51
|
+
@@middlewares = middlewares
|
52
|
+
|
53
|
+
attr_accessor :env
|
54
|
+
def initialize env = {}
|
55
|
+
@env = env
|
56
|
+
#p "merging #{@@env} with #{env_updates} for the result of #{env_updates.merge @@env}"
|
57
|
+
#p "domaindsl construct is ready to activate calling the stack with #{env}"
|
58
|
+
end
|
59
|
+
end # end of app_construct_klass
|
60
|
+
|
61
|
+
DSL.const_set(name.capitalize, app_construct_klass) unless DSL.const_defined?(name.capitalize)
|
62
|
+
# Reopens most recent context klass and add method `def construct_name params; app_construct_class.new(params)`
|
63
|
+
# access method for DSL::Construct dynamic klass inside a context object &block
|
64
|
+
DSL.const_get(@app_context_klass.to_s).send(:define_method, name) do |env|
|
65
|
+
# 1. populate :symbols inside opts and params with values from env
|
66
|
+
@@middlewares.each do |middleware|
|
67
|
+
middleware[:params].each do |key, value|
|
68
|
+
env.each do |env_key, env_value|
|
69
|
+
if env_key.to_sym == value then
|
70
|
+
middleware[:opts][key] = env_value
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
middleware[:opts].each do |key, value|
|
76
|
+
env.each do |env_key, env_value|
|
77
|
+
if env_key.to_sym == value then
|
78
|
+
middleware[:opts][key] = env_value
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
$log.info middleware
|
83
|
+
end
|
84
|
+
# 2. insert
|
85
|
+
@@middlewares.each do |middleware|
|
86
|
+
@@stack.insert_before 0, middleware[:ext], middleware[:opts], middleware[:params]
|
87
|
+
end
|
88
|
+
# 3. call the stack
|
89
|
+
@@stack.call
|
90
|
+
|
91
|
+
DSL.const_get(name.capitalize).new env
|
92
|
+
end
|
93
|
+
#p DSL.constants
|
94
|
+
end
|
95
|
+
|
96
|
+
def use ext:, opts: {}, params: {}
|
97
|
+
@middlewares << {:ext => ext, :opts => opts, :params => params}
|
98
|
+
#p @middlewares
|
99
|
+
# @stack.insert_before 0, ext, opts, params
|
100
|
+
#@stack.call
|
101
|
+
#@stack = Use.new(ext, opts, params, @stack)
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
def context name, &block
|
106
|
+
Context.new(name, &block) #.instance_eval &block
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
module DSL
|
111
|
+
end
|
112
|
+
|
113
|
+
class Domain
|
114
|
+
def self.inherited(subclass)
|
115
|
+
subclass.send :extend, DSLBuilder
|
116
|
+
subclass.send :include, DSL
|
117
|
+
end
|
118
|
+
|
119
|
+
def initialize &block
|
120
|
+
instance_eval &block
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
data/lib/mushin/ext.rb
ADDED
data/lib/mushin/stack.rb
ADDED
data/lib/mushin/version.rb
CHANGED
data/lib/mushin.rb
CHANGED
@@ -1,26 +1,13 @@
|
|
1
|
-
require_relative "mushin/version"
|
2
|
-
require_relative "mushin/generator"
|
3
1
|
require 'middleware'
|
4
2
|
require 'logger'
|
5
3
|
|
6
|
-
|
4
|
+
require_relative "mushin/version"
|
5
|
+
require_relative "mushin/stack"
|
6
|
+
require_relative "mushin/ext"
|
7
|
+
require_relative "mushin/domain"
|
8
|
+
require_relative "mushin/generator"
|
7
9
|
|
8
|
-
|
9
|
-
class Stack < Middleware::Builder
|
10
|
-
def initialize &block
|
11
|
-
# let's use `super` to instance_eval inside Middleware::Builder scope
|
12
|
-
super
|
13
|
-
# Run it!
|
14
|
-
call
|
15
|
-
end
|
16
|
-
end
|
10
|
+
$log = Logger.new(STDOUT)
|
17
11
|
|
18
|
-
|
19
|
-
|
20
|
-
raise NotImplementedError, "Mushin Extenstions implement :initialize that takes an app"
|
21
|
-
end
|
22
|
-
def call env
|
23
|
-
raise NotImplementedError, "Mushin Extenstions implement :call that takes an env"
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
12
|
+
#module Mushin
|
13
|
+
#end
|
data/samples/sample1.rb
ADDED
@@ -0,0 +1,168 @@
|
|
1
|
+
require 'mushin'
|
2
|
+
|
3
|
+
module Sample
|
4
|
+
class Bot < Mushin::Ext
|
5
|
+
def initialize(app=nil, opts: {}, params: {})
|
6
|
+
@app = app
|
7
|
+
@opts = opts
|
8
|
+
@params = params
|
9
|
+
end
|
10
|
+
|
11
|
+
def call(env)
|
12
|
+
# Inbound maniuplation
|
13
|
+
env = Hash.new if env.nil?
|
14
|
+
p env[:var] = "new_value_inbound"
|
15
|
+
@app.call(env)
|
16
|
+
#Outbound maniuplation
|
17
|
+
p env[:var] = "new_value_outbound"
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
module Mushin
|
23
|
+
|
24
|
+
module DSLBuilder
|
25
|
+
def self.context context_name, &block
|
26
|
+
@dsl = Module.new
|
27
|
+
yield
|
28
|
+
end
|
29
|
+
def self.construct construct_name, &block
|
30
|
+
yield
|
31
|
+
end
|
32
|
+
|
33
|
+
def self.use app, opts: {}, params: {}
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
class Domain
|
38
|
+
|
39
|
+
# Responsible for `executing` the DSL methods
|
40
|
+
def initialize &block
|
41
|
+
instance_eval &block
|
42
|
+
end
|
43
|
+
|
44
|
+
def self.inherited(app_domain_class)
|
45
|
+
# Responsible for `building` the DSL methods
|
46
|
+
app_domain_class.extend Mushin::DSLBuilder
|
47
|
+
#super # important?
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
module Sample
|
53
|
+
class Domain < Mushin::Domain
|
54
|
+
# creates the context for torrent_bots
|
55
|
+
context :torrent_bots do
|
56
|
+
# creates the construct for tpb, a `mushin construct` is a stack of extenstions
|
57
|
+
# construct :tpb, { max_results: 10 } do
|
58
|
+
p "Sample:Domain: context shit..."
|
59
|
+
construct "tpb" do
|
60
|
+
p "Sample:Domain: construct shit..."
|
61
|
+
# keeps inserting into the domain's @stack object
|
62
|
+
use Bot, opts: {max_results: 10}, params: {}
|
63
|
+
#use "ssd"
|
64
|
+
#use "logger"
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
class Service
|
70
|
+
def server
|
71
|
+
Domain.new do
|
72
|
+
torrent_bots do
|
73
|
+
p "Sample:Service: service dsl inside the torrent_bots"
|
74
|
+
tpb max_results: 40
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
Sample::Service.new.server
|
81
|
+
|
82
|
+
|
83
|
+
|
84
|
+
|
85
|
+
|
86
|
+
|
87
|
+
|
88
|
+
|
89
|
+
|
90
|
+
|
91
|
+
|
92
|
+
|
93
|
+
=begin
|
94
|
+
|
95
|
+
#extend self.class.dsl
|
96
|
+
|
97
|
+
def self.inherited(app_domain_class)
|
98
|
+
# use it if I want to extend the App Domain Class,
|
99
|
+
# maybe sometimes it will be better to extend the objects itself.
|
100
|
+
#app_domain_class.extend @dsl
|
101
|
+
puts "#{app_domain_class} is ready to be injected with methods"
|
102
|
+
super
|
103
|
+
end
|
104
|
+
|
105
|
+
#attr_accessor :context
|
106
|
+
#
|
107
|
+
|
108
|
+
#@context = @@context.dup
|
109
|
+
# extends
|
110
|
+
#extend @context.dsl
|
111
|
+
|
112
|
+
class ContextBuilder
|
113
|
+
attr_accessor :context_name
|
114
|
+
attr_accessor :stack, :env
|
115
|
+
attr_accessor :dsl
|
116
|
+
|
117
|
+
def initialize context_name, &block
|
118
|
+
@context_name = context_name
|
119
|
+
instance_eval &block
|
120
|
+
end
|
121
|
+
|
122
|
+
def construct construct_name, args={}, &block
|
123
|
+
@dsl = Module.new
|
124
|
+
@dsl.send :define_method, construct_name do |&context_block|
|
125
|
+
#define_method @context_name do |&context_block|
|
126
|
+
instance_eval &context_block
|
127
|
+
end
|
128
|
+
|
129
|
+
p "Mushin::Domain self.construct: #{construct_name.to_sym} is created"
|
130
|
+
define_method(construct_name.to_sym) do |args={}, &construct_block|
|
131
|
+
p "Mushin::Domain self.construct: #{construct_name.to_sym} is executed"
|
132
|
+
@env = {}
|
133
|
+
@stack = Mushin::Stack.new
|
134
|
+
#TODO @stack.env = args oorsomthing
|
135
|
+
p @stack.inspect
|
136
|
+
p @env[construct_name] = args
|
137
|
+
instance_eval &construct_block
|
138
|
+
p "calling the stack to execute"
|
139
|
+
@stack.call # call the stack after adding all the middlewares via use
|
140
|
+
end
|
141
|
+
instance_eval &block
|
142
|
+
end
|
143
|
+
|
144
|
+
# takes a app, opts={} and a params={}
|
145
|
+
def self.use app, opts: {}, params: {}
|
146
|
+
p "Mushin::Domain self.use: #{app}, #{opts}, #{params} is created"
|
147
|
+
define_method(construct_name.to_sym) do |args={}, &construct_block|
|
148
|
+
"@stack.insert_before 0, app, opts, params"
|
149
|
+
p "@stack.insert_before 0, #{app}, #{opts}, #{params}"
|
150
|
+
end
|
151
|
+
yield
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
b = Boy.new
|
156
|
+
b.send(define_method :greeting, -> { puts 'Hello!' })
|
157
|
+
dsl = Module.new
|
158
|
+
dsl.send(define_method :super, -> { puts 'i am super' })
|
159
|
+
b.extend Extras
|
160
|
+
b.extend dsl
|
161
|
+
|
162
|
+
# Responsible for defining the DSL methods
|
163
|
+
#def self.context context_name, &block
|
164
|
+
# @context = ContextBuilder.new context_name, &block
|
165
|
+
# #extend context.dsl
|
166
|
+
#end
|
167
|
+
|
168
|
+
=end
|
data/samples/sample2.rb
ADDED
@@ -0,0 +1,165 @@
|
|
1
|
+
require 'mushin'
|
2
|
+
require 'docile'
|
3
|
+
|
4
|
+
module Sample
|
5
|
+
class Bot < Mushin::Ext
|
6
|
+
def initialize(app=nil, opts: {}, params: {})
|
7
|
+
@app = app
|
8
|
+
@opts = opts
|
9
|
+
@params = params
|
10
|
+
end
|
11
|
+
|
12
|
+
def call(env)
|
13
|
+
# Inbound maniuplation
|
14
|
+
env = Hash.new if env.nil?
|
15
|
+
p env[:var] = "new_value_inbound"
|
16
|
+
|
17
|
+
@app.call(env)
|
18
|
+
|
19
|
+
#Outbound maniuplation
|
20
|
+
p env[:var] = "new_value_outbound"
|
21
|
+
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
module Mushin
|
27
|
+
class ContextBuilder
|
28
|
+
attr_accessor :context_name
|
29
|
+
attr_accessor :stack, :env
|
30
|
+
|
31
|
+
def initialize context_name, &block
|
32
|
+
@context_name = context_name
|
33
|
+
instance_eval &block
|
34
|
+
end
|
35
|
+
|
36
|
+
def construct construct_name, &block
|
37
|
+
p "Mushin::Domain self.construct: #{construct_name.to_sym} is created"
|
38
|
+
define_method(construct_name.to_sym) do |args={}, &construct_block|
|
39
|
+
p "Mushin::Domain self.construct: #{construct_name.to_sym} is executed"
|
40
|
+
@env = {}
|
41
|
+
@stack = Mushin::Stack.new
|
42
|
+
#TODO @stack.env = args oorsomthing
|
43
|
+
p @stack.inspect
|
44
|
+
p @env[construct_name] = args
|
45
|
+
instance_eval &construct_block
|
46
|
+
p "calling the stack to execute"
|
47
|
+
@stack.call # call the stack after adding all the middlewares via use
|
48
|
+
end
|
49
|
+
|
50
|
+
instance_eval &block
|
51
|
+
end
|
52
|
+
|
53
|
+
# takes a app, opts={} and a params={}
|
54
|
+
def self.use app, opts: {}, params: {}
|
55
|
+
p "Mushin::Domain self.use: #{app}, #{opts}, #{params} is created"
|
56
|
+
define_method(construct_name.to_sym) do |args={}, &construct_block|
|
57
|
+
"@stack.insert_before 0, app, opts, params"
|
58
|
+
p "@stack.insert_before 0, #{app}, #{opts}, #{params}"
|
59
|
+
end
|
60
|
+
yield
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
class Domain
|
65
|
+
attr_accessor :context
|
66
|
+
|
67
|
+
def initialize &block
|
68
|
+
instance_eval &block
|
69
|
+
end
|
70
|
+
def self.context context_name, &block
|
71
|
+
#@context = ContextBuilder.new context_name, &block
|
72
|
+
context = Docile.dsl_eval(ContextBuilder.new context_name, &block).build
|
73
|
+
end
|
74
|
+
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
module Sample
|
79
|
+
class Domain
|
80
|
+
#< Mushin::Domain
|
81
|
+
# creates the context for torrent_bots
|
82
|
+
context :torrent_bots do
|
83
|
+
# creates the construct for tpb, a `mushin construct` is a stack of extenstions
|
84
|
+
# construct :tpb, { max_results: 10 } do
|
85
|
+
p "Sample:Domain: context shit..."
|
86
|
+
construct "tpb" do
|
87
|
+
p "Sample:Domain: construct shit..."
|
88
|
+
# keeps inserting into the domain's @stack object
|
89
|
+
use Bot, opts: {max_results: 10}, params: {}
|
90
|
+
#use "ssd"
|
91
|
+
#use "logger"
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
yield @domain
|
96
|
+
end
|
97
|
+
|
98
|
+
class Service
|
99
|
+
def server
|
100
|
+
Domain.new do
|
101
|
+
torrent_bots do
|
102
|
+
p "Sample:Service: service dsl inside the torrent_bots"
|
103
|
+
tpb max_results: 40
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
end
|
110
|
+
|
111
|
+
Sample::Service.new.server
|
112
|
+
|
113
|
+
=begin
|
114
|
+
|
115
|
+
# takes a context_name and a block and dynamically define a :context_name method
|
116
|
+
def self.context context_name #, &block
|
117
|
+
p "Mushin::Domain self.context: #{context_name.to_sym} is created!"
|
118
|
+
define_method(context_name.to_sym) do |args={}, &context_block|
|
119
|
+
p "Mushin::Domain self.context: #{context_name.to_sym} is executed!"
|
120
|
+
instance_exec &context_block
|
121
|
+
end
|
122
|
+
yield
|
123
|
+
end
|
124
|
+
|
125
|
+
# takes a construct_name, args={} and a block and dynamically define a :construct_name method
|
126
|
+
def self.construct construct_name, args = {} , &block
|
127
|
+
DSL.new construct_name, args, &block
|
128
|
+
end
|
129
|
+
|
130
|
+
|
131
|
+
#tpb max_results: params[:max_results]
|
132
|
+
#TODO do i need that, every construct is basically creating a DSL.new line
|
133
|
+
#def torrent_bots &block
|
134
|
+
# DSL.new &block
|
135
|
+
#end
|
136
|
+
|
137
|
+
#Domain.methods
|
138
|
+
|
139
|
+
def use app, opts: {}, params: {}
|
140
|
+
p app
|
141
|
+
p opts
|
142
|
+
p params
|
143
|
+
end
|
144
|
+
=end
|
145
|
+
=begin
|
146
|
+
DSL.new do
|
147
|
+
context 'xx' do
|
148
|
+
construct 'yy' do
|
149
|
+
use 'zz' do
|
150
|
+
end
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
construct 'zz' do
|
155
|
+
end
|
156
|
+
end
|
157
|
+
#TODO do i need that, every construct is basically passing params to a stack middleware
|
158
|
+
#class DSL < Mushin::DSL
|
159
|
+
# def tpb max_results:
|
160
|
+
# p "testing tpb #{max_results}, under the hood will be insert this into the stack and at the end of the block will call the stack, use 'XXX' #, params: {'key' => 's'}"
|
161
|
+
# end
|
162
|
+
#end
|
163
|
+
|
164
|
+
|
165
|
+
=end
|
data/samples/sample3.rb
ADDED
@@ -0,0 +1,105 @@
|
|
1
|
+
require 'mushin'
|
2
|
+
|
3
|
+
module DSLBuilder
|
4
|
+
@@dsl = Module.new do
|
5
|
+
def included mod
|
6
|
+
# determine here if the included is a context_dsl or a construct_dsl
|
7
|
+
# then make constructs nested inside context until a new context is define and repeat
|
8
|
+
# or somthing similar
|
9
|
+
#.respond_to? :context_name
|
10
|
+
#.respond_to? :construct_name
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
@@stack = []
|
15
|
+
|
16
|
+
# context keyword
|
17
|
+
def context context_name, &block
|
18
|
+
|
19
|
+
# construct keyword
|
20
|
+
def construct construct_name, &block
|
21
|
+
#@construct_dsl = Module.new
|
22
|
+
# use keyword
|
23
|
+
def use app, opts: {}, params: {}
|
24
|
+
@@stack << app
|
25
|
+
p "#{app} adding middlewares to the stack"
|
26
|
+
p @@stack
|
27
|
+
end
|
28
|
+
|
29
|
+
@@dsl.send :define_method, construct_name do |&construct_block|
|
30
|
+
p "inside #{construct_name} context method"
|
31
|
+
instance_eval &construct_block
|
32
|
+
|
33
|
+
#remove_method construct_name
|
34
|
+
end
|
35
|
+
|
36
|
+
instance_eval &block
|
37
|
+
|
38
|
+
# force raise error if use keyword is used outside of a construct block
|
39
|
+
undef :use
|
40
|
+
end
|
41
|
+
|
42
|
+
@@dsl.send :define_method, context_name do |&context_block|
|
43
|
+
p "inside #{context_name} context method"
|
44
|
+
instance_eval &context_block
|
45
|
+
end
|
46
|
+
|
47
|
+
instance_eval &block
|
48
|
+
|
49
|
+
# force raise error if construct keyword is used outside of a context block
|
50
|
+
undef :construct
|
51
|
+
end
|
52
|
+
def self.app_domain_dsl
|
53
|
+
@@dsl
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
class Domain
|
58
|
+
extend DSLBuilder
|
59
|
+
def initialize &block
|
60
|
+
extend DSLBuilder.app_domain_dsl
|
61
|
+
instance_eval &block
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
class AppDomain < Domain
|
66
|
+
context :torrent_bots do
|
67
|
+
p "torrent_bots context built"
|
68
|
+
construct :tpb do
|
69
|
+
p "tpb construct built"
|
70
|
+
end
|
71
|
+
construct :rutracker do
|
72
|
+
p "rutracker construct built"
|
73
|
+
use "rutrackerbot"
|
74
|
+
use "ssd"
|
75
|
+
use "logger"
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
context :shit do
|
80
|
+
construct "xxxxxxxxxxxxxxxxxxxxxxxxxxxxlogger" do
|
81
|
+
use "xxxxxxxxxxxxxxxxxxxxxxxxxxxxlogger"
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
params = Hash.new
|
87
|
+
params[:max] = "100000000000000"
|
88
|
+
#p "from inside love #{x}"
|
89
|
+
AppDomain.new do
|
90
|
+
p "AppDomain begins"
|
91
|
+
torrent_bots do
|
92
|
+
tpb do
|
93
|
+
p max_results = params[:max]
|
94
|
+
p max_results = params[:max]
|
95
|
+
p max_results = params[:max]
|
96
|
+
p max_results = params[:max]
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
tpb do
|
101
|
+
p "shit! constructs are its repeateive"
|
102
|
+
end
|
103
|
+
|
104
|
+
p "AppDomain ends"
|
105
|
+
end
|
data/samples/sample4.rb
ADDED
@@ -0,0 +1,155 @@
|
|
1
|
+
require 'mushin'
|
2
|
+
#
|
3
|
+
# Thats the module I want to give to the AppDomain class or AppDomain objects
|
4
|
+
# Usage:
|
5
|
+
# dsl = {
|
6
|
+
# :a => [
|
7
|
+
# :b,
|
8
|
+
# :c
|
9
|
+
# ]
|
10
|
+
# }
|
11
|
+
#create_dsl(dsl)
|
12
|
+
module DSL
|
13
|
+
def new_method_and_class(x, parent_klass = Object)
|
14
|
+
parent_klass.class_eval do
|
15
|
+
define_method(x) do |&block|
|
16
|
+
p x.to_s
|
17
|
+
parent_klass.const_get(x.capitalize).new.instance_eval &block if block
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
parent_klass.const_set(x.capitalize, Class.new)
|
22
|
+
end
|
23
|
+
|
24
|
+
def create_dsl(branch,parent_klass = Object)
|
25
|
+
case branch
|
26
|
+
when Symbol, String
|
27
|
+
new_method_and_class(branch,parent_klass)
|
28
|
+
when Array
|
29
|
+
branch.each do |child|
|
30
|
+
create_dsl(child, parent_klass)
|
31
|
+
end
|
32
|
+
when Hash
|
33
|
+
branch.each do |key, value|
|
34
|
+
create_dsl(value, new_method_and_class(key,parent_klass))
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
#
|
40
|
+
# End of dsl Module
|
41
|
+
#
|
42
|
+
|
43
|
+
class Domain
|
44
|
+
extend DSL
|
45
|
+
def self.inherited(subclass)
|
46
|
+
|
47
|
+
#
|
48
|
+
# Mushin DSL
|
49
|
+
#
|
50
|
+
["context", "construct", "use"].inject(subclass.singleton_class) do |klass, dsl_builder_keyword|
|
51
|
+
|
52
|
+
p "inside inject:: #{subclass} inherited domain self: #{self} -- klass: #{klass} -- dsl_builder_keyword: #{dsl_builder_keyword}"
|
53
|
+
|
54
|
+
# runs class_eval on subclass.singleton_class aka `AppDomain singleton_class`
|
55
|
+
klass.class_eval do #klass.instance_eval do
|
56
|
+
|
57
|
+
# arg not a name
|
58
|
+
define_method(dsl_builder_keyword) do |name, &block|
|
59
|
+
|
60
|
+
case dsl_builder_keyword
|
61
|
+
when "context"
|
62
|
+
p "#{name} context built"
|
63
|
+
p subclass.singleton_class
|
64
|
+
#p "context ............"
|
65
|
+
#p klass.class
|
66
|
+
#z = klass.const_get(dsl_builder_keyword.capitalize).new.instance_eval &block if block
|
67
|
+
#p z.class
|
68
|
+
#p dsl
|
69
|
+
klass.const_get(dsl_builder_keyword.capitalize).new.instance_eval &block if block
|
70
|
+
#context_name = name
|
71
|
+
#dsl.send :define_method, context_name do |&context_block|
|
72
|
+
# instance_eval &context_block
|
73
|
+
#end
|
74
|
+
#p dsl.instance_methods
|
75
|
+
#subclass.send :include, dsl
|
76
|
+
when "construct"
|
77
|
+
#p "#{name} construct built"
|
78
|
+
klass.const_get(dsl_builder_keyword.capitalize).new.instance_eval &block if block
|
79
|
+
|
80
|
+
#construct_name = name
|
81
|
+
#dsl.send :define_method, construct_name do |&context_block|
|
82
|
+
# instance_eval &context_block
|
83
|
+
#end
|
84
|
+
##p dsl.instance_methods
|
85
|
+
#subclass.send :include, dsl
|
86
|
+
when "use"
|
87
|
+
# p "#{name} built"
|
88
|
+
p "add middleware to stack"
|
89
|
+
#klass.const_get(dsl_builder_keyword.capitalize).new.instance_eval &block if block
|
90
|
+
else
|
91
|
+
p "warning or error: unkown mushin dsl builder keyword"
|
92
|
+
end
|
93
|
+
end
|
94
|
+
#remove_method dsl_builder_keyword
|
95
|
+
end
|
96
|
+
klass.const_set(dsl_builder_keyword.capitalize, Class.new)
|
97
|
+
end
|
98
|
+
#
|
99
|
+
# End of Mushin DSL
|
100
|
+
#
|
101
|
+
end
|
102
|
+
|
103
|
+
def initialize &block
|
104
|
+
instance_eval &block
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
class AppDomain < Domain
|
109
|
+
context :torrent_bots do
|
110
|
+
#p "torrent_bots context defined"
|
111
|
+
construct :tpb do
|
112
|
+
end
|
113
|
+
construct :rutracker do
|
114
|
+
#p "rutracker construct built"
|
115
|
+
use "rutrackerbot"
|
116
|
+
use "ssd"
|
117
|
+
use "logger"
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
context :shit do
|
122
|
+
construct "xxxxxxxxxxxxxxxxxxxxxxxxxxxxlogger" do
|
123
|
+
use "xxxxxxxxxxxxxxxxxxxxxxxxxxxxlogger"
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
|
129
|
+
=begin testing if it is clean code and only works inside AppDomain
|
130
|
+
context do
|
131
|
+
p "outsiiiiiiiiiiiiiiiiiiiiiiide"
|
132
|
+
end
|
133
|
+
=end
|
134
|
+
|
135
|
+
params = Hash.new
|
136
|
+
params[:max] = "100000000000000"
|
137
|
+
#p "from inside love #{x}"
|
138
|
+
|
139
|
+
#=begin
|
140
|
+
AppDomain.new do
|
141
|
+
#p "AppDomain begins"
|
142
|
+
torrent_bots do
|
143
|
+
tpb do
|
144
|
+
p max_results = params[:max]
|
145
|
+
p max_results = params[:max]
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
tpb do
|
150
|
+
p "shit! constructs are its repeateive"
|
151
|
+
end
|
152
|
+
|
153
|
+
p "AppDomain ends"
|
154
|
+
end
|
155
|
+
#=end
|
data/samples/sample5.rb
ADDED
@@ -0,0 +1,186 @@
|
|
1
|
+
require 'mushin'
|
2
|
+
#
|
3
|
+
# Thats the module I want to give to the AppDomain class or AppDomain objects
|
4
|
+
# Usage:
|
5
|
+
# dsl = {
|
6
|
+
# :a => [
|
7
|
+
# :b,
|
8
|
+
# :c
|
9
|
+
# ]
|
10
|
+
# }
|
11
|
+
#create_dsl(dsl)
|
12
|
+
class DSL
|
13
|
+
attr_accessor :middlewares, :stack
|
14
|
+
|
15
|
+
def initialize middlewares: [], &block
|
16
|
+
@stack = Mushin::Stack.new
|
17
|
+
#@middlewares.each do |middlewares|
|
18
|
+
# add it to the stack
|
19
|
+
#end
|
20
|
+
#@stack.call run the stack
|
21
|
+
instance_eval &block
|
22
|
+
end
|
23
|
+
|
24
|
+
def new_method_and_class(x, parent_klass = Object)
|
25
|
+
parent_klass.class_eval do
|
26
|
+
define_method(x) do |&block|
|
27
|
+
p x.to_s
|
28
|
+
parent_klass.const_get(x.capitalize).new.instance_eval &block if block
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
parent_klass.const_set(x.capitalize, Class.new)
|
33
|
+
end
|
34
|
+
|
35
|
+
def create_dsl(branch,parent_klass = Object)
|
36
|
+
case branch
|
37
|
+
when Symbol, String
|
38
|
+
new_method_and_class(branch,parent_klass)
|
39
|
+
when Array
|
40
|
+
branch.each do |child|
|
41
|
+
create_dsl(child, parent_klass)
|
42
|
+
end
|
43
|
+
when Hash
|
44
|
+
branch.each do |key, value|
|
45
|
+
create_dsl(value, new_method_and_class(key,parent_klass))
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
#
|
51
|
+
# End of dsl Module
|
52
|
+
#
|
53
|
+
|
54
|
+
class Domain
|
55
|
+
def self.inherited(subclass)
|
56
|
+
dsl_hash = Hash.new
|
57
|
+
#dsl = {:context_name => [:constructA,:constructB]}
|
58
|
+
|
59
|
+
#
|
60
|
+
# Mushin DSL
|
61
|
+
#
|
62
|
+
["context", "construct", "use"].inject(subclass.singleton_class) do |klass, dsl_builder_keyword|
|
63
|
+
|
64
|
+
p "inside inject:: #{subclass} inherited domain self: #{self} -- klass: #{klass} -- dsl_builder_keyword: #{dsl_builder_keyword}"
|
65
|
+
|
66
|
+
# runs class_eval on subclass.singleton_class aka `AppDomain singleton_class`
|
67
|
+
klass.class_eval do #klass.instance_eval do
|
68
|
+
|
69
|
+
# arg not a name
|
70
|
+
define_method(dsl_builder_keyword) do |name, &block|
|
71
|
+
|
72
|
+
p "thats my subclass"
|
73
|
+
subclass.send(:define_method, :torrent_bots) do #|&block|
|
74
|
+
end
|
75
|
+
|
76
|
+
case dsl_builder_keyword
|
77
|
+
when "context"
|
78
|
+
p "#{name} context built"
|
79
|
+
p subclass.singleton_class
|
80
|
+
klass.const_get(dsl_builder_keyword.capitalize).new.instance_eval &block if block
|
81
|
+
when "construct"
|
82
|
+
#p "#{name} construct built"
|
83
|
+
klass.const_get(dsl_builder_keyword.capitalize).new.instance_eval &block if block
|
84
|
+
|
85
|
+
when "use"
|
86
|
+
# p "#{name} built"
|
87
|
+
p "add middleware to stack"
|
88
|
+
#klass.const_get(dsl_builder_keyword.capitalize).new.instance_eval &block if block
|
89
|
+
else
|
90
|
+
p "warning or error: unkown mushin dsl builder keyword"
|
91
|
+
end
|
92
|
+
end
|
93
|
+
#remove_method dsl_builder_keyword
|
94
|
+
end
|
95
|
+
klass.const_set(dsl_builder_keyword.capitalize, Class.new)
|
96
|
+
end
|
97
|
+
#
|
98
|
+
# End of Mushin DSL
|
99
|
+
#
|
100
|
+
end
|
101
|
+
|
102
|
+
def initialize &block
|
103
|
+
instance_eval &block
|
104
|
+
#DSL.new &block
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
class AppDomain < Domain
|
109
|
+
context :torrent_bots do
|
110
|
+
#p "torrent_bots context defined"
|
111
|
+
construct :tpb do
|
112
|
+
end
|
113
|
+
construct :rutracker do
|
114
|
+
#p "rutracker construct built"
|
115
|
+
use "rutrackerbot"
|
116
|
+
use "ssd"
|
117
|
+
use "logger"
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
context :shit do
|
122
|
+
construct "xxxxxxxxxxxxxxxxxxxxxxxxxxxxlogger" do
|
123
|
+
use "xxxxxxxxxxxxxxxxxxxxxxxxxxxxlogger"
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
127
|
+
#=begin
|
128
|
+
AppDomain.new do
|
129
|
+
#p "AppDomain begins"
|
130
|
+
torrent_bots do
|
131
|
+
p "shit"
|
132
|
+
p "shit"
|
133
|
+
p "shit"
|
134
|
+
tpb do
|
135
|
+
p "crazy"
|
136
|
+
p max_results = params[:max]
|
137
|
+
p max_results = params[:max]
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
tpb do
|
142
|
+
p "shit! constructs are its repeateive"
|
143
|
+
end
|
144
|
+
|
145
|
+
p "AppDomain ends"
|
146
|
+
end
|
147
|
+
#=end
|
148
|
+
#
|
149
|
+
|
150
|
+
|
151
|
+
|
152
|
+
|
153
|
+
### HACKS
|
154
|
+
#
|
155
|
+
=begin
|
156
|
+
testing if it is clean code and only works inside AppDomain
|
157
|
+
#p "context ............"
|
158
|
+
#p klass.class
|
159
|
+
#z = klass.const_get(dsl_builder_keyword.capitalize).new.instance_eval &block if block
|
160
|
+
#p z.class
|
161
|
+
#p dsl
|
162
|
+
|
163
|
+
#context_name = name
|
164
|
+
#dsl.send :define_method, context_name do |&context_block|
|
165
|
+
# instance_eval &context_block
|
166
|
+
#end
|
167
|
+
#p dsl.instance_methods
|
168
|
+
#subclass.send :include, dsl
|
169
|
+
|
170
|
+
params = Hash.new
|
171
|
+
params[:max] = "100000000000000"
|
172
|
+
#p "from inside love #{x}"
|
173
|
+
|
174
|
+
|
175
|
+
context do
|
176
|
+
p "outsiiiiiiiiiiiiiiiiiiiiiiide"
|
177
|
+
end
|
178
|
+
=end
|
179
|
+
|
180
|
+
#construct_name = name
|
181
|
+
#dsl.send :define_method, construct_name do |&context_block|
|
182
|
+
# instance_eval &context_block
|
183
|
+
#end
|
184
|
+
##p dsl.instance_methods
|
185
|
+
#subclass.send :include, dsl
|
186
|
+
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mushin
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- zotherstupidguy
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-
|
11
|
+
date: 2016-11-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -128,9 +128,17 @@ files:
|
|
128
128
|
- bin/setup
|
129
129
|
- exe/mushin
|
130
130
|
- lib/mushin.rb
|
131
|
+
- lib/mushin/domain.rb
|
132
|
+
- lib/mushin/ext.rb
|
131
133
|
- lib/mushin/generator.rb
|
134
|
+
- lib/mushin/stack.rb
|
132
135
|
- lib/mushin/version.rb
|
133
136
|
- mushin.gemspec
|
137
|
+
- samples/sample1.rb
|
138
|
+
- samples/sample2.rb
|
139
|
+
- samples/sample3.rb
|
140
|
+
- samples/sample4.rb
|
141
|
+
- samples/sample5.rb
|
134
142
|
homepage: http://mushin-rb.github.io/
|
135
143
|
licenses:
|
136
144
|
- MIT
|