abid 0.3.0.pre.alpha.3 → 0.3.0.pre.alpha.4
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 +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
|