abid 0.3.0.pre.alpha.3 → 0.3.0.pre.alpha.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +3 -3
- data/abid.gemspec +1 -2
- data/exe/abidsc +1 -1
- data/lib/abid.rb +3 -30
- data/lib/abid/application.rb +83 -13
- data/lib/abid/cli/assume.rb +7 -8
- data/lib/abid/cli/list.rb +2 -2
- data/lib/abid/cli/migrate.rb +1 -1
- data/lib/abid/cli/revoke.rb +9 -10
- data/lib/abid/config.rb +2 -0
- data/lib/abid/dsl/abid_job.rb +58 -0
- data/lib/abid/dsl/actions.rb +36 -0
- data/lib/abid/dsl/job.rb +58 -0
- data/lib/abid/dsl/job_manager.rb +53 -0
- data/lib/abid/dsl/mixin.rb +52 -0
- data/lib/abid/dsl/params_spec.rb +64 -0
- data/lib/abid/dsl/play.rb +35 -0
- data/lib/abid/dsl/play_core.rb +354 -0
- data/lib/abid/dsl/rake_job.rb +41 -0
- data/lib/abid/dsl/syntax.rb +34 -0
- data/lib/abid/dsl/task.rb +53 -0
- data/lib/abid/engine.rb +36 -6
- data/lib/abid/engine/executor.rb +30 -48
- data/lib/abid/engine/process.rb +102 -68
- data/lib/abid/engine/process_manager.rb +72 -28
- data/lib/abid/engine/scheduler.rb +24 -30
- data/lib/abid/engine/waiter.rb +20 -30
- data/lib/abid/engine/worker_manager.rb +26 -60
- data/lib/abid/environment.rb +12 -27
- data/lib/abid/error.rb +2 -0
- data/lib/abid/params_format.rb +29 -12
- data/lib/abid/rake_extensions.rb +11 -3
- data/lib/abid/state_manager.rb +40 -0
- data/lib/abid/state_manager/state.rb +52 -114
- data/lib/abid/state_manager/state_service.rb +88 -0
- data/lib/abid/status.rb +63 -0
- data/lib/abid/version.rb +1 -1
- metadata +19 -32
- data/lib/Abidfile.rb +0 -1
- data/lib/abid/dsl_definition.rb +0 -29
- data/lib/abid/job.rb +0 -67
- data/lib/abid/job_manager.rb +0 -22
- data/lib/abid/mixin_task.rb +0 -29
- data/lib/abid/params_parser.rb +0 -50
- data/lib/abid/play.rb +0 -66
- data/lib/abid/play_core.rb +0 -53
- data/lib/abid/rake_extensions/task.rb +0 -41
- data/lib/abid/state_manager/database.rb +0 -40
- data/lib/abid/state_manager/state_proxy.rb +0 -65
- data/lib/abid/task.rb +0 -123
- data/lib/abid/task_manager.rb +0 -61
data/lib/abid/dsl/job.rb
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
require 'forwardable'
|
2
|
+
|
3
|
+
module Abid
|
4
|
+
module DSL
|
5
|
+
# Common interface for RakeJob and AbidJob
|
6
|
+
class Job
|
7
|
+
extend Forwardable
|
8
|
+
|
9
|
+
def self.interface(name, args = [])
|
10
|
+
class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
11
|
+
def #{name}(#{args.join(', ')})
|
12
|
+
raise NotImplementedError
|
13
|
+
end
|
14
|
+
RUBY
|
15
|
+
end
|
16
|
+
private_class_method :interface
|
17
|
+
|
18
|
+
interface :name
|
19
|
+
interface :arg_names
|
20
|
+
interface :worker
|
21
|
+
interface :prerequisites
|
22
|
+
interface :execute, %w(args)
|
23
|
+
|
24
|
+
interface :volatile?
|
25
|
+
interface :concerned?
|
26
|
+
interface :needed?
|
27
|
+
|
28
|
+
def initialize(task, params)
|
29
|
+
@task = task
|
30
|
+
@params = params
|
31
|
+
@options = task.application.options
|
32
|
+
end
|
33
|
+
attr_reader :task, :params, :options
|
34
|
+
def_delegators :task, :name, :arg_names
|
35
|
+
|
36
|
+
def trace_invoke
|
37
|
+
return unless @task.application.options.trace
|
38
|
+
@task.application.trace "** Invoke #{@task.name}"
|
39
|
+
end
|
40
|
+
|
41
|
+
def to_s
|
42
|
+
ParamsFormat.format_with_name(name, params)
|
43
|
+
end
|
44
|
+
|
45
|
+
def repair?
|
46
|
+
@options.repair
|
47
|
+
end
|
48
|
+
|
49
|
+
def dryrun?
|
50
|
+
@options.dryrun
|
51
|
+
end
|
52
|
+
|
53
|
+
def preview?
|
54
|
+
@options.preview
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
require 'monitor'
|
2
|
+
|
3
|
+
module Abid
|
4
|
+
module DSL
|
5
|
+
# JobManager manages jobs.
|
6
|
+
class JobManager
|
7
|
+
def initialize(application)
|
8
|
+
@app = application
|
9
|
+
@tasks = Hash.new { |h, k| h[k] = {} }
|
10
|
+
@mon = Monitor.new
|
11
|
+
end
|
12
|
+
|
13
|
+
# Resolves params using params_spec and bind the task and resolved params.
|
14
|
+
# @param name [String,Symbol] task name
|
15
|
+
# @param params [Hash]
|
16
|
+
# @param scope [Rake::Scope]
|
17
|
+
# @return [Abid::DSL::TaskInstance]
|
18
|
+
def [](name, params = {}, scope = nil)
|
19
|
+
task = @app[name, scope]
|
20
|
+
resolved = resolve_params(task, params)
|
21
|
+
bind(task.name, resolved)
|
22
|
+
end
|
23
|
+
|
24
|
+
# Binds the task and params.
|
25
|
+
# @param name [String,Symbol] task name
|
26
|
+
# @param params [Hash]
|
27
|
+
# @return [Abid::DSL::TaskInstance]
|
28
|
+
def bind(name, params)
|
29
|
+
return @tasks[name][params] if @tasks[name][params]
|
30
|
+
|
31
|
+
@mon.synchronize do
|
32
|
+
@tasks[name][params.dup.freeze] ||= @app[name].bind(params)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def resolve_params(task, params)
|
37
|
+
ret = task.params_spec.each_with_object({}) do |(key, spec), h|
|
38
|
+
h[key] = fetch_param(task, key, spec, params, @app.global_params)
|
39
|
+
end
|
40
|
+
ParamsFormat.validate_params!(ret)
|
41
|
+
ret
|
42
|
+
end
|
43
|
+
|
44
|
+
def fetch_param(task, key, spec, *params_list)
|
45
|
+
found = params_list.find { |params| params.include?(key) }
|
46
|
+
return found[key] if found
|
47
|
+
return spec[:default] if spec.include?(:default)
|
48
|
+
raise "#{task.name}: param #{key} is not specified"
|
49
|
+
end
|
50
|
+
private :fetch_param
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
require 'abid/dsl/play_core'
|
2
|
+
|
3
|
+
module Abid
|
4
|
+
module DSL
|
5
|
+
# `mixin` definition is evaluated in Mixin module context.
|
6
|
+
#
|
7
|
+
# mixin :foo do
|
8
|
+
# # this is evaluated in Mixin module context
|
9
|
+
# end
|
10
|
+
#
|
11
|
+
module Mixin
|
12
|
+
# Create new Mixin object.
|
13
|
+
# @param task [Rake::Task] owner task
|
14
|
+
def self.create(task)
|
15
|
+
mod = self
|
16
|
+
Module.new do
|
17
|
+
include mod
|
18
|
+
extend Mixin::ClassMethods
|
19
|
+
include task.application.global_mixin
|
20
|
+
extend helpers
|
21
|
+
self.task = task
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
# Create new global mixin.
|
26
|
+
# `global_mixin` does not include Application#global_mixin.
|
27
|
+
def self.create_global_mixin
|
28
|
+
Module.new do
|
29
|
+
include Mixin
|
30
|
+
extend Mixin::ClassMethods
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
include PlayCore
|
35
|
+
|
36
|
+
module ClassMethods
|
37
|
+
include PlayCore::ClassMethods
|
38
|
+
|
39
|
+
def included(obj)
|
40
|
+
return unless obj.is_a? PlayCore::ClassMethods
|
41
|
+
merge_helpers(obj)
|
42
|
+
end
|
43
|
+
|
44
|
+
def merge_helpers(obj)
|
45
|
+
my_helpers = helpers
|
46
|
+
obj.helpers.module_eval { include my_helpers }
|
47
|
+
obj.extend(obj.helpers) # re-extend by helpers
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
module Abid
|
2
|
+
module DSL
|
3
|
+
# ParamsSpec manages params specifications declared in a play definition.
|
4
|
+
#
|
5
|
+
# Ancestors' params_spec are inherited.
|
6
|
+
class ParamsSpec
|
7
|
+
include Enumerable
|
8
|
+
|
9
|
+
attr_reader :specs
|
10
|
+
protected :specs
|
11
|
+
|
12
|
+
def initialize(play_class)
|
13
|
+
@play_class = play_class
|
14
|
+
@specs = {}
|
15
|
+
end
|
16
|
+
|
17
|
+
# @param key [Symbol] param name
|
18
|
+
# @return [Hash] param specification
|
19
|
+
def [](key)
|
20
|
+
@play_class.superplays.each do |sp|
|
21
|
+
h = sp.params_spec.specs
|
22
|
+
return h[key] if h.include?(key)
|
23
|
+
end
|
24
|
+
nil
|
25
|
+
end
|
26
|
+
|
27
|
+
# @param key [Symbol] param name
|
28
|
+
# @param val [Hash] param specification
|
29
|
+
def []=(key, val)
|
30
|
+
@specs[key] = val
|
31
|
+
end
|
32
|
+
|
33
|
+
# Mark given param as deleted.
|
34
|
+
# It does not affect ancestors' params_spec.
|
35
|
+
# @param key [Symbol] param name
|
36
|
+
def delete(key)
|
37
|
+
val = self[key]
|
38
|
+
@specs[key] = nil
|
39
|
+
val
|
40
|
+
end
|
41
|
+
|
42
|
+
# @yield [key, val] param name and spec
|
43
|
+
def each(&block)
|
44
|
+
to_h.each(&block)
|
45
|
+
end
|
46
|
+
|
47
|
+
def to_h
|
48
|
+
h = {}
|
49
|
+
@play_class.superplays.reverse.each do |sp|
|
50
|
+
h.update(sp.params_spec.specs)
|
51
|
+
end
|
52
|
+
h.reject { |_, v| v.nil? }
|
53
|
+
end
|
54
|
+
|
55
|
+
def inspect
|
56
|
+
to_h.inspect
|
57
|
+
end
|
58
|
+
|
59
|
+
def to_s
|
60
|
+
to_h.to_s
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'abid/dsl/play_core'
|
2
|
+
|
3
|
+
module Abid
|
4
|
+
module DSL
|
5
|
+
# `play` definition is evaluated in Play class context.
|
6
|
+
#
|
7
|
+
# play :foo do
|
8
|
+
# # this is evaluated in Play class context
|
9
|
+
# end
|
10
|
+
#
|
11
|
+
class Play
|
12
|
+
def self.create(task)
|
13
|
+
Class.new(self) do
|
14
|
+
include task.application.global_mixin
|
15
|
+
extend helpers
|
16
|
+
self.task = task
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
include PlayCore
|
21
|
+
extend PlayCore::ClassMethods
|
22
|
+
|
23
|
+
def initialize(params)
|
24
|
+
@params = params
|
25
|
+
@prerequisite_tasks = []
|
26
|
+
end
|
27
|
+
|
28
|
+
# default settings
|
29
|
+
worker :default
|
30
|
+
volatile false
|
31
|
+
set :concerned, true
|
32
|
+
set :needed, true
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,354 @@
|
|
1
|
+
module Abid
|
2
|
+
module DSL
|
3
|
+
# Common methods for Play and Mixin
|
4
|
+
module PlayCore
|
5
|
+
attr_reader :prerequisite_tasks
|
6
|
+
attr_reader :params
|
7
|
+
|
8
|
+
# Declared prerequisite tasks.
|
9
|
+
#
|
10
|
+
# play :foo do
|
11
|
+
# setup do
|
12
|
+
# needs :TASK_NAME, bar: 0
|
13
|
+
# end
|
14
|
+
# end
|
15
|
+
#
|
16
|
+
# @param task_name [Symbol, String] task name
|
17
|
+
# @param params [Hash] task params
|
18
|
+
def needs(task_name, **params)
|
19
|
+
t = task.application[task_name, @scope_in_actions]
|
20
|
+
(@prerequisite_tasks ||= []) << [t, self.params.merge(params)]
|
21
|
+
end
|
22
|
+
|
23
|
+
def run
|
24
|
+
# noop
|
25
|
+
end
|
26
|
+
|
27
|
+
def task
|
28
|
+
self.class.task
|
29
|
+
end
|
30
|
+
|
31
|
+
# Evaluates each actions in the task scope where the action is declared.
|
32
|
+
# @param tag [Symbol] action name
|
33
|
+
# @param args [Array] arguments
|
34
|
+
def call_action(tag, *args)
|
35
|
+
self.class.actions[tag].each do |scope, block|
|
36
|
+
@scope_in_actions = scope
|
37
|
+
instance_exec(*args, &block)
|
38
|
+
end
|
39
|
+
ensure
|
40
|
+
@scope_in_actions = nil
|
41
|
+
end
|
42
|
+
|
43
|
+
# @!visibility private
|
44
|
+
def eval_setting(value = nil, &block)
|
45
|
+
return instance_exec(&value) if value.is_a? Proc
|
46
|
+
return value unless value.nil?
|
47
|
+
return instance_exec(&block) if block_given?
|
48
|
+
true
|
49
|
+
end
|
50
|
+
private :eval_setting
|
51
|
+
|
52
|
+
def logger
|
53
|
+
task.application.logger
|
54
|
+
end
|
55
|
+
|
56
|
+
def preview?
|
57
|
+
task.application.options.dryrun || task.application.options.preview
|
58
|
+
end
|
59
|
+
|
60
|
+
# Play definition's body is extended by ClassMethods.
|
61
|
+
#
|
62
|
+
module ClassMethods
|
63
|
+
attr_accessor :task
|
64
|
+
private :task=
|
65
|
+
|
66
|
+
# Task params specification.
|
67
|
+
def params_spec
|
68
|
+
@params_spec ||= ParamsSpec.new(self)
|
69
|
+
end
|
70
|
+
|
71
|
+
# Actions include `setup` blocks and `after` blocks.
|
72
|
+
#
|
73
|
+
# play :foo do
|
74
|
+
# setup { 'this block is added to actions[:setup]' }
|
75
|
+
# after { ... }
|
76
|
+
# end
|
77
|
+
def actions
|
78
|
+
@actions ||= Actions.new(self)
|
79
|
+
end
|
80
|
+
|
81
|
+
# Define helper methods.
|
82
|
+
#
|
83
|
+
# play :foo do
|
84
|
+
# helpers do
|
85
|
+
# def country
|
86
|
+
# :jp
|
87
|
+
# end
|
88
|
+
# end
|
89
|
+
#
|
90
|
+
# today #=> :jp
|
91
|
+
# end
|
92
|
+
#
|
93
|
+
# `helpers` block is evaluated in the helpers module context, which
|
94
|
+
# extends the play class.
|
95
|
+
#
|
96
|
+
# If no block given, it returns the helper module.
|
97
|
+
#
|
98
|
+
# @return [Module] helpers module
|
99
|
+
def helpers(*extensions, &block)
|
100
|
+
@helpers ||= Module.new
|
101
|
+
@helpers.module_eval(&block) if block_given?
|
102
|
+
@helpers.module_eval { include(*extensions) } if extensions.any?
|
103
|
+
@helpers
|
104
|
+
end
|
105
|
+
|
106
|
+
# Declared setting.
|
107
|
+
#
|
108
|
+
# play :foo do
|
109
|
+
# set :first_name, 'Taro'
|
110
|
+
# set :family_name, 'Yamada'
|
111
|
+
# set :full_name, -> { first_name + ' ' + family_name }
|
112
|
+
#
|
113
|
+
# def run
|
114
|
+
# full_name #=> 'Taro Yamada'
|
115
|
+
# end
|
116
|
+
# end
|
117
|
+
#
|
118
|
+
# Settings are defiend as an intance methods of the play.
|
119
|
+
#
|
120
|
+
# If a param is declared with the same name of the setting, the param is
|
121
|
+
# undefined.
|
122
|
+
#
|
123
|
+
# mixin :bar do
|
124
|
+
# param :country
|
125
|
+
# end
|
126
|
+
#
|
127
|
+
# play :baz do
|
128
|
+
# include :bar
|
129
|
+
# set :country, :jp
|
130
|
+
#
|
131
|
+
# params_spec #=> {}
|
132
|
+
# end
|
133
|
+
#
|
134
|
+
# When block is given, it is lazily evaluated in the play context.
|
135
|
+
def set(name, value = nil, &block)
|
136
|
+
var = :"@#{name}"
|
137
|
+
|
138
|
+
params_spec.delete(name) # undef param
|
139
|
+
define_method(name) do
|
140
|
+
unless instance_variable_defined?(var)
|
141
|
+
val = eval_setting(value, &block)
|
142
|
+
instance_variable_set(var, val)
|
143
|
+
end
|
144
|
+
instance_variable_get(var)
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
# Declare task param.
|
149
|
+
#
|
150
|
+
# play :foo do
|
151
|
+
# param :city
|
152
|
+
# param :country, default: 'Japan'
|
153
|
+
#
|
154
|
+
# params_spec # => { city: {}, country: { default: 'Japan'} }
|
155
|
+
#
|
156
|
+
# def run
|
157
|
+
# puts "#{city}, #{country}"
|
158
|
+
# end
|
159
|
+
# end
|
160
|
+
#
|
161
|
+
# $ abid foo city=Tokyo
|
162
|
+
# Tokyo, Japan
|
163
|
+
#
|
164
|
+
# An instance method of the same name is defined.
|
165
|
+
#
|
166
|
+
# @param name [Symbol] param name
|
167
|
+
# @param spec [Hash] specification
|
168
|
+
# @option spec [Object] :default default value
|
169
|
+
def param(name, **spec)
|
170
|
+
define_method(name) do
|
171
|
+
raise NoParamError, "undefined param `#{name}' for #{task.name}" \
|
172
|
+
unless params.include?(name)
|
173
|
+
params[name]
|
174
|
+
end
|
175
|
+
params_spec[name] = spec
|
176
|
+
end
|
177
|
+
|
178
|
+
#
|
179
|
+
# Setting Helpers
|
180
|
+
#
|
181
|
+
|
182
|
+
# @!visibility private
|
183
|
+
def self.def_setting_helper(name)
|
184
|
+
class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
185
|
+
def #{name}(val = nil, &block)
|
186
|
+
set :#{name}, val, &block
|
187
|
+
end
|
188
|
+
RUBY
|
189
|
+
end
|
190
|
+
|
191
|
+
# @!method worker(val = nil, &block)
|
192
|
+
# Set :worker name.
|
193
|
+
#
|
194
|
+
# play :foo do
|
195
|
+
# worker :my_worker
|
196
|
+
# action { ... }
|
197
|
+
# end
|
198
|
+
#
|
199
|
+
# This is short-hand style of `set :worker, :my_worker`
|
200
|
+
def_setting_helper :worker
|
201
|
+
|
202
|
+
# @!method volatile(val = nil, &block)
|
203
|
+
# Set :volatile flag.
|
204
|
+
#
|
205
|
+
# play :foo do
|
206
|
+
# volatile
|
207
|
+
# action { ... }
|
208
|
+
# end
|
209
|
+
#
|
210
|
+
# This is short-hand style of `set :volatile, true`
|
211
|
+
def_setting_helper :volatile
|
212
|
+
|
213
|
+
# Delete the param from params_spec.
|
214
|
+
#
|
215
|
+
# mixin :bar do
|
216
|
+
# param :country
|
217
|
+
# end
|
218
|
+
#
|
219
|
+
# play :baz do
|
220
|
+
# include :bar
|
221
|
+
#
|
222
|
+
# params_spec #=> { country: {} }
|
223
|
+
#
|
224
|
+
# undef_param :country
|
225
|
+
# params_spec #=> {}
|
226
|
+
# end
|
227
|
+
def undef_param(name)
|
228
|
+
params_spec.delete(name)
|
229
|
+
end
|
230
|
+
|
231
|
+
#
|
232
|
+
# Actions
|
233
|
+
#
|
234
|
+
|
235
|
+
# @!visibility :private
|
236
|
+
def self.define_action(name)
|
237
|
+
define_method(name) do |&block|
|
238
|
+
actions.add(name, task.scope, block)
|
239
|
+
end
|
240
|
+
end
|
241
|
+
|
242
|
+
# @!method setup(&block)
|
243
|
+
# Register _setup_ action.
|
244
|
+
#
|
245
|
+
# Setup action is called before #run.
|
246
|
+
# All prerequisites should be declared inside the setup blocks.
|
247
|
+
#
|
248
|
+
# play :foo do
|
249
|
+
# setup do
|
250
|
+
# needs :bar
|
251
|
+
# puts 'Setup!'
|
252
|
+
# end
|
253
|
+
#
|
254
|
+
# def run
|
255
|
+
# puts 'Running!'
|
256
|
+
# end
|
257
|
+
# end
|
258
|
+
#
|
259
|
+
# $ abid foo
|
260
|
+
# ... (:bar is executed)
|
261
|
+
# Setup!
|
262
|
+
# Running!
|
263
|
+
define_action :setup
|
264
|
+
|
265
|
+
# @!method action(&block)
|
266
|
+
# Register main action.
|
267
|
+
#
|
268
|
+
# play :foo do
|
269
|
+
# action { |args| ... }
|
270
|
+
# end
|
271
|
+
#
|
272
|
+
# `action` block is not executed in dryrun mode nor preview mode.
|
273
|
+
#
|
274
|
+
# Main actions of mixis are inherited to play, while `run` method is
|
275
|
+
# overwritten.
|
276
|
+
#
|
277
|
+
# @yieldparam args [Rake::TaskArguments]
|
278
|
+
define_action :action
|
279
|
+
|
280
|
+
# @!method safe_action(&block)
|
281
|
+
# Register safe action.
|
282
|
+
# `safe_action` is similar to `action`, but this block is executed
|
283
|
+
# in preview mode.
|
284
|
+
#
|
285
|
+
# You should guard dangerous operations in a safe_action block.
|
286
|
+
# This is useful to preview detail behavior of play.
|
287
|
+
#
|
288
|
+
# @yieldparam args [Rake::TaskArguments]
|
289
|
+
define_action :safe_action
|
290
|
+
|
291
|
+
# @!method after(&block)
|
292
|
+
# Register _after_ action.
|
293
|
+
#
|
294
|
+
# After action is called after #run.
|
295
|
+
#
|
296
|
+
# play :foo do
|
297
|
+
# def run
|
298
|
+
# ...
|
299
|
+
# end
|
300
|
+
#
|
301
|
+
# after do |error|
|
302
|
+
# next if error.nil?
|
303
|
+
# $syserr.puts "[ERROR] #{task.name} failed:"
|
304
|
+
# $syserr.puts "[ERROR] #{error}"
|
305
|
+
# end
|
306
|
+
# end
|
307
|
+
#
|
308
|
+
# `after` block is not executed in dryrun mode nor preview mode.
|
309
|
+
#
|
310
|
+
# @yieldparam error [StandardError, nil] if run method failed,
|
311
|
+
# otherwise nil.
|
312
|
+
define_action :after
|
313
|
+
|
314
|
+
# Include mixins.
|
315
|
+
#
|
316
|
+
# All methods, actions, settings and params_spec are inherited.
|
317
|
+
#
|
318
|
+
# mixin :foo do
|
319
|
+
# param :country
|
320
|
+
# end
|
321
|
+
#
|
322
|
+
# play :bar do
|
323
|
+
# include :bar
|
324
|
+
# params_spec #=> { country: {} }
|
325
|
+
# end
|
326
|
+
#
|
327
|
+
# When Module objects are given, it includes them as usual.
|
328
|
+
#
|
329
|
+
# @param mod [Array<Symbol, String, Module>] mixin name or module.
|
330
|
+
def include(*mod)
|
331
|
+
ms = mod.map { |m| resolve_mixin(m) }
|
332
|
+
super(*ms)
|
333
|
+
end
|
334
|
+
private :include
|
335
|
+
|
336
|
+
# @!visibility private
|
337
|
+
def resolve_mixin(mod)
|
338
|
+
return mod if mod.is_a? Module
|
339
|
+
|
340
|
+
mixin_task = task.application[mod.to_s, task.scope]
|
341
|
+
raise "#{mod} is not a mixin" unless mixin_task.is_a? MixinTask
|
342
|
+
|
343
|
+
mixin_task.internal
|
344
|
+
end
|
345
|
+
private :resolve_mixin
|
346
|
+
|
347
|
+
# Return a list of Mixin objects included.
|
348
|
+
def superplays
|
349
|
+
ancestors.select { |o| o.is_a? PlayCore::ClassMethods }
|
350
|
+
end
|
351
|
+
end
|
352
|
+
end
|
353
|
+
end
|
354
|
+
end
|