squared 0.6.16 → 0.7.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/CHANGELOG.md +69 -157
- data/README.md +242 -205
- data/lib/squared/common/format.rb +7 -10
- data/lib/squared/common/prompt.rb +23 -24
- data/lib/squared/common/shell.rb +27 -35
- data/lib/squared/common/system.rb +29 -21
- data/lib/squared/common/utils.rb +44 -63
- data/lib/squared/config.rb +17 -16
- data/lib/squared/version.rb +1 -1
- data/lib/squared/workspace/application.rb +292 -186
- data/lib/squared/workspace/project/base.rb +564 -488
- data/lib/squared/workspace/project/docker.rb +177 -169
- data/lib/squared/workspace/project/git.rb +228 -203
- data/lib/squared/workspace/project/node.rb +114 -143
- data/lib/squared/workspace/project/python.rb +248 -161
- data/lib/squared/workspace/project/ruby.rb +405 -294
- data/lib/squared/workspace/project/support/class.rb +13 -7
- data/lib/squared/workspace/project/support/optionpartition.rb +72 -57
- data/lib/squared/workspace/project/support/utils.rb +68 -0
- data/lib/squared/workspace/project.rb +0 -7
- data/lib/squared/workspace/repo.rb +234 -169
- data/lib/squared/workspace/series.rb +91 -86
- data/lib/squared/workspace/support/base.rb +15 -1
- metadata +3 -2
|
@@ -6,35 +6,26 @@ module Squared
|
|
|
6
6
|
include Enumerable
|
|
7
7
|
include Common::Format
|
|
8
8
|
include Utils
|
|
9
|
-
include Support::Variables
|
|
10
9
|
include Rake::DSL
|
|
11
10
|
|
|
12
11
|
TASK_METADATA = Rake::TaskManager.record_task_metadata
|
|
13
12
|
private_constant :TASK_METADATA
|
|
14
13
|
|
|
15
14
|
class << self
|
|
16
|
-
def implement(*objs, base:
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
end
|
|
29
|
-
if (args = obj.batchargs)
|
|
30
|
-
impl_series.batch(*args)
|
|
31
|
-
end
|
|
32
|
-
if (args = obj.aliasargs)
|
|
33
|
-
impl_series.alias(*args)
|
|
34
|
-
end
|
|
35
|
-
if (args = obj.bannerargs)
|
|
36
|
-
attr_banner.merge(args)
|
|
15
|
+
def implement(*objs, base: nil)
|
|
16
|
+
objs.each_with_index do |obj, index|
|
|
17
|
+
if base && index == 0
|
|
18
|
+
case base
|
|
19
|
+
when 0, true
|
|
20
|
+
@kind_extend[0] = obj
|
|
21
|
+
next
|
|
22
|
+
when 1
|
|
23
|
+
@kind_extend.insert(1, obj)
|
|
24
|
+
else
|
|
25
|
+
@kind_extend.push(obj)
|
|
26
|
+
end
|
|
37
27
|
end
|
|
28
|
+
kind_project.unshift(obj) if extends(obj)
|
|
38
29
|
end
|
|
39
30
|
end
|
|
40
31
|
|
|
@@ -42,17 +33,14 @@ module Squared
|
|
|
42
33
|
if ref && (ret = kind_project.find { |proj| proj.ref == ref })
|
|
43
34
|
ret
|
|
44
35
|
elsif path
|
|
45
|
-
kind_project.find { |proj| proj.config?(path) }
|
|
36
|
+
(kind_project - @kind_extend).find { |proj| proj.config?(path) } ||
|
|
37
|
+
@kind_extend.find { |proj| proj.config?(path) }
|
|
46
38
|
end
|
|
47
39
|
end
|
|
48
40
|
|
|
49
|
-
def exclude
|
|
50
|
-
@task_exclude.merge(args.map!(&:to_sym))
|
|
51
|
-
end
|
|
52
|
-
|
|
53
|
-
def register(app)
|
|
41
|
+
def register(app, base, exclude: [])
|
|
54
42
|
@session << app
|
|
55
|
-
impl_series.new(app, exclude:
|
|
43
|
+
impl_series.new(app, (@kind_extend + base).uniq, exclude: exclude.map(&:to_sym))
|
|
56
44
|
end
|
|
57
45
|
|
|
58
46
|
def load_ref(path, gem: nil)
|
|
@@ -65,14 +53,23 @@ module Squared
|
|
|
65
53
|
break
|
|
66
54
|
end
|
|
67
55
|
end
|
|
68
|
-
dir = if gem.match?(/-\d+(
|
|
56
|
+
dir = if gem.match?(/-\d+(\.|$)/)
|
|
69
57
|
gem
|
|
70
58
|
else
|
|
71
59
|
Dir.glob("#{gem}-*", base: @gemsdir).pop
|
|
72
60
|
end
|
|
73
61
|
path = File.join(@gemsdir, dir, path) if dir
|
|
74
62
|
end
|
|
75
|
-
|
|
63
|
+
path = Pathname.new(path)
|
|
64
|
+
@load_project.unshift(path.cleanpath.to_s) if path.absolute? && path.exist?
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def extends(obj)
|
|
68
|
+
@kind_extend.any? { |impl| obj < impl }
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def impl_project
|
|
72
|
+
@kind_extend.first
|
|
76
73
|
end
|
|
77
74
|
|
|
78
75
|
def baseref
|
|
@@ -83,46 +80,42 @@ module Squared
|
|
|
83
80
|
super[/[^:]+\z/, 0]
|
|
84
81
|
end
|
|
85
82
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
attr_reader :kind_project, :load_project, :session
|
|
89
|
-
attr_accessor :impl_series, :impl_project, :attr_banner
|
|
83
|
+
attr_reader :kind_project, :load_project, :attr_banner, :session
|
|
84
|
+
attr_accessor :impl_series
|
|
90
85
|
end
|
|
91
86
|
|
|
92
87
|
@kind_project = []
|
|
93
88
|
@load_project = [File.expand_path('project', __dir__)]
|
|
89
|
+
@attr_banner = Set.new
|
|
90
|
+
@kind_extend = []
|
|
94
91
|
@session = []
|
|
95
|
-
@task_exclude = Set.new
|
|
96
92
|
|
|
97
93
|
attr_reader :root, :home, :main, :prefix, :theme, :series, :closed
|
|
98
94
|
attr_accessor :exception, :pipe, :verbose, :warning
|
|
99
95
|
|
|
100
96
|
def initialize(home = (ARG[:HOME] && ENV[ARG[:HOME]]) || Dir.pwd, *, main: nil, prefix: nil,
|
|
101
97
|
verbose: ARG[:VERBOSE], common: ARG[:COMMON], pipe: ARG[:PIPE], exception: ARG[:FAIL], **)
|
|
102
|
-
|
|
103
|
-
basename =
|
|
98
|
+
home = Pathname.new(home)
|
|
99
|
+
basename = home.basename.to_s
|
|
104
100
|
if main
|
|
105
101
|
@main = main.to_s.freeze
|
|
106
|
-
|
|
102
|
+
home += @main unless @main == basename || (windows? && @main.casecmp?(basename))
|
|
107
103
|
else
|
|
108
104
|
@main = basename.freeze
|
|
109
105
|
end
|
|
110
|
-
@home.mkpath rescue nil
|
|
111
|
-
@root = @home.parent
|
|
112
106
|
@prefix = prefix
|
|
113
|
-
@series = Application.register(self)
|
|
114
107
|
@project = {}
|
|
115
|
-
@
|
|
116
|
-
@
|
|
108
|
+
@base = Set.new
|
|
109
|
+
@kind = Support.hashlist
|
|
110
|
+
@config = {}
|
|
111
|
+
@extensions = Set.new
|
|
112
|
+
@finalize = Set.new([:__chain__])
|
|
117
113
|
@envname = env_key(@main).freeze
|
|
114
|
+
@closed = false
|
|
115
|
+
@stage = Support.hashlist
|
|
116
|
+
self.home = home
|
|
118
117
|
self.exception = env_bool exception
|
|
119
|
-
self.pipe =
|
|
120
|
-
2
|
|
121
|
-
elsif (out = ARG[:OUT]) && out.include?(File::SEPARATOR)
|
|
122
|
-
env_pipe(out, pipe, root: home)
|
|
123
|
-
else
|
|
124
|
-
env_pipe(pipe, (out && env(out)) || 1, root: home)
|
|
125
|
-
end
|
|
118
|
+
self.pipe = $DEBUG ? 2 : env_pipe(pipe, (ARG[:OUT] && env(ARG[:OUT])) || 1, root: home)
|
|
126
119
|
self.verbose = if $VERBOSE.nil?
|
|
127
120
|
false
|
|
128
121
|
elsif verbose.nil?
|
|
@@ -131,102 +124,93 @@ module Squared
|
|
|
131
124
|
env_bool(verbose, verbose.is_a?(String) ? @pipe != 0 : verbose, index: true)
|
|
132
125
|
end
|
|
133
126
|
self.warning = @verbose != false
|
|
134
|
-
@
|
|
135
|
-
@
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
@
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
ref: hashobj,
|
|
145
|
-
group!: {},
|
|
146
|
-
ref!: {}
|
|
147
|
-
}.freeze
|
|
148
|
-
@events = {
|
|
149
|
-
group: hashobj,
|
|
150
|
-
ref: hashobj
|
|
151
|
-
}.freeze
|
|
152
|
-
@pass = {
|
|
153
|
-
group: hashobj,
|
|
154
|
-
ref: hashobj,
|
|
155
|
-
global: {},
|
|
156
|
-
pattern: []
|
|
157
|
-
}.freeze
|
|
158
|
-
@banner = {
|
|
159
|
-
group: {},
|
|
160
|
-
ref: {}
|
|
161
|
-
}.freeze
|
|
127
|
+
@theme = common ? __get__(:theme)[:workspace] : {}
|
|
128
|
+
@chain = Support.hashlist
|
|
129
|
+
@script = Struct::SessionData.new
|
|
130
|
+
@events = Struct::SessionData.new
|
|
131
|
+
@pass = Struct::SessionData.new
|
|
132
|
+
@banner = Struct::SessionData.new
|
|
133
|
+
@timeout = Struct::SessionData.new
|
|
134
|
+
@global = Hash.new do |data, key|
|
|
135
|
+
data[key] = { group: {}, ref: {}, exclude: [], extras: {}, module: nil, script: nil }
|
|
136
|
+
end
|
|
162
137
|
initialize_session
|
|
163
138
|
end
|
|
164
139
|
|
|
165
|
-
def initialize_session
|
|
166
|
-
return unless @pipe.is_a?(Pathname)
|
|
167
|
-
|
|
168
|
-
msg = "Session started on #{Time.now} by #{@main}"
|
|
169
|
-
bord = '#' * msg.size
|
|
170
|
-
puts bord, msg, bord
|
|
171
|
-
end
|
|
172
|
-
|
|
173
140
|
def each(&blk)
|
|
174
141
|
return to_enum(:each) unless block_given?
|
|
175
142
|
|
|
176
143
|
@project.each_value(&blk)
|
|
177
144
|
end
|
|
178
145
|
|
|
179
|
-
def build(parallel: [],
|
|
146
|
+
def build(parallel: [], **kwargs)
|
|
180
147
|
return self unless enabled? && !@closed
|
|
181
148
|
|
|
149
|
+
self.closed = 'init'
|
|
182
150
|
kwargs[:parallel] = if kwargs[:pattern].is_a?(Array)
|
|
183
151
|
parallel.map(&:to_s)
|
|
184
152
|
else
|
|
185
153
|
kwargs[:pattern] = []
|
|
186
|
-
parallel.reject { |val| kwargs[:pattern] << val if val.is_a?(Regexp) }.map
|
|
154
|
+
parallel.reject { |val| kwargs[:pattern] << val if val.is_a?(Regexp) }.map(&:to_s)
|
|
187
155
|
end
|
|
188
|
-
@pass
|
|
189
|
-
series.
|
|
156
|
+
@pass.items.concat(kwargs[:pass].map { |val| val.is_a?(Regexp) ? val : val.to_s }) if kwargs[:pass]
|
|
157
|
+
@series = Application.register(self, @base.to_a, exclude: kwargs.fetch(:exclude, []))
|
|
158
|
+
self.closed = 'begin'
|
|
159
|
+
pb = @stage.key?('project:begin')
|
|
160
|
+
pe = @stage.key?('project:end')
|
|
161
|
+
keys = @series.keys
|
|
190
162
|
each do |proj|
|
|
163
|
+
self.closed = ['project:begin', proj] if pb
|
|
191
164
|
if proj.enabled?
|
|
192
|
-
proj.populate(
|
|
165
|
+
proj.populate(keys.dup, **kwargs)
|
|
193
166
|
elsif proj.enabled?(base: false)
|
|
194
167
|
proj.generate([], **kwargs)
|
|
195
168
|
else
|
|
196
169
|
next
|
|
197
170
|
end
|
|
198
|
-
series.populate(proj, **kwargs)
|
|
171
|
+
@series.populate(proj, **kwargs)
|
|
172
|
+
self.closed = ['project:end', proj] if pe
|
|
199
173
|
end
|
|
200
|
-
|
|
201
|
-
@
|
|
202
|
-
|
|
174
|
+
self.closed = 'populate'
|
|
175
|
+
@base.each { |obj| obj.populate(self, **kwargs) }
|
|
176
|
+
self.closed = 'extensions'
|
|
177
|
+
@extensions.each { |ext| __send__(ext, **kwargs) }
|
|
178
|
+
self.closed = 'series'
|
|
179
|
+
@series.build(**kwargs)
|
|
203
180
|
__build__(**kwargs)
|
|
204
|
-
|
|
205
|
-
|
|
181
|
+
if block_given?
|
|
182
|
+
self.closed = 'yield:begin'
|
|
183
|
+
yield self
|
|
184
|
+
self.closed = 'yield:end'
|
|
185
|
+
end
|
|
186
|
+
self.closed = 'finalize'
|
|
187
|
+
@finalize.each { |ext| __send__(ext, **kwargs) }
|
|
188
|
+
self.closed = 'end'
|
|
206
189
|
@closed = true
|
|
207
190
|
self
|
|
208
191
|
end
|
|
209
192
|
|
|
210
|
-
def with(*val, hide:
|
|
211
|
-
if hide
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
elsif
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
193
|
+
def with(*val, hide: false, group: nil, **kwargs, &blk)
|
|
194
|
+
if hide
|
|
195
|
+
return self if hide == true
|
|
196
|
+
|
|
197
|
+
Array(hide).each do |args|
|
|
198
|
+
if args.is_a?(Array)
|
|
199
|
+
if respond_to?(hint = args.first)
|
|
200
|
+
next unless __send__(*args)
|
|
201
|
+
|
|
202
|
+
return self
|
|
203
|
+
end
|
|
204
|
+
elsif respond_to?(args)
|
|
205
|
+
next unless __send__(args)
|
|
206
|
+
|
|
207
|
+
return self
|
|
225
208
|
end
|
|
209
|
+
raise_error 'method not found'
|
|
210
|
+
rescue => e
|
|
211
|
+
warn log_message(Logger::WARN, e, subject: main, hint: hint || args)
|
|
226
212
|
end
|
|
227
213
|
end
|
|
228
|
-
return self if hide == true || (hide && Array(hide).any? { |s| respond_to?(s) && __send__(s) rescue nil })
|
|
229
|
-
|
|
230
214
|
@group = nil
|
|
231
215
|
@ref = nil
|
|
232
216
|
@withargs = unless kwargs.empty?
|
|
@@ -242,7 +226,7 @@ module Squared
|
|
|
242
226
|
when Symbol
|
|
243
227
|
@ref = val
|
|
244
228
|
else
|
|
245
|
-
raise_error
|
|
229
|
+
raise_error TypeError, "not a group/ref: #{kind || 'nil'}" if block_given?
|
|
246
230
|
end
|
|
247
231
|
if block_given?
|
|
248
232
|
instance_eval(&blk)
|
|
@@ -259,18 +243,18 @@ module Squared
|
|
|
259
243
|
|
|
260
244
|
def chain(task, *action, project: nil, step: 0, with: nil, before: nil, after: nil, sync: false,
|
|
261
245
|
group: @group, ref: @ref)
|
|
262
|
-
if project
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
246
|
+
tasks = if project
|
|
247
|
+
action.map { |val| task_join(project.name, val) }
|
|
248
|
+
elsif (target = group || ref)
|
|
249
|
+
action.map { |val| task_name(task_join(val, target)) }
|
|
250
|
+
else
|
|
251
|
+
keys = @project.keys unless prefix
|
|
252
|
+
action.map { |val| task_name(val) }
|
|
253
|
+
end
|
|
270
254
|
ns = lambda do |val|
|
|
271
255
|
return if (ret = as_a(val, :to_s, flat: true)).empty?
|
|
272
256
|
|
|
273
|
-
ret.map
|
|
257
|
+
ret.map do |arg|
|
|
274
258
|
if arg.include?(':') || (keys && !keys.include?(arg))
|
|
275
259
|
task_name(arg)
|
|
276
260
|
else
|
|
@@ -278,7 +262,7 @@ module Squared
|
|
|
278
262
|
end
|
|
279
263
|
end
|
|
280
264
|
end
|
|
281
|
-
data = Struct::ChainData.new(
|
|
265
|
+
data = Struct::ChainData.new(tasks, step, ns.call(with), ns.call(before), ns.call(after), sync)
|
|
282
266
|
@chain[task_name(task.to_s)] << data
|
|
283
267
|
self
|
|
284
268
|
end
|
|
@@ -321,18 +305,18 @@ module Squared
|
|
|
321
305
|
|
|
322
306
|
def pass(name, group: @group, ref: @ref, &blk)
|
|
323
307
|
data = if group
|
|
324
|
-
@pass
|
|
308
|
+
@pass.group[group.to_s]
|
|
325
309
|
elsif ref
|
|
326
|
-
@pass
|
|
310
|
+
@pass.ref[ref.to_sym]
|
|
327
311
|
else
|
|
328
|
-
@pass
|
|
312
|
+
@pass.store
|
|
329
313
|
end
|
|
330
314
|
data[name.to_sym] = blk
|
|
331
315
|
self
|
|
332
316
|
end
|
|
333
317
|
|
|
334
318
|
def banner(*args, command: true, styles: nil, border: nil, group: @group, ref: @ref)
|
|
335
|
-
data = Struct::BannerData.new(command,
|
|
319
|
+
data = Struct::BannerData.new(command, check_style(styles, empty: false), check_style(border))
|
|
336
320
|
args.each do |meth|
|
|
337
321
|
if meth.is_a?(Array)
|
|
338
322
|
found = false
|
|
@@ -340,7 +324,7 @@ module Squared
|
|
|
340
324
|
case val
|
|
341
325
|
when Symbol
|
|
342
326
|
found = true
|
|
343
|
-
|
|
327
|
+
banner_include?(val)
|
|
344
328
|
when String
|
|
345
329
|
true
|
|
346
330
|
else
|
|
@@ -352,7 +336,7 @@ module Squared
|
|
|
352
336
|
elsif meth.size == 1
|
|
353
337
|
meth = meth.first
|
|
354
338
|
end
|
|
355
|
-
elsif !
|
|
339
|
+
elsif !banner_include?(meth = meth.to_sym)
|
|
356
340
|
next
|
|
357
341
|
end
|
|
358
342
|
data.order << meth
|
|
@@ -367,8 +351,29 @@ module Squared
|
|
|
367
351
|
self
|
|
368
352
|
end
|
|
369
353
|
|
|
354
|
+
def timeout(data, group: @group, ref: @ref)
|
|
355
|
+
if group
|
|
356
|
+
@timeout.group[group.to_s].update(data)
|
|
357
|
+
elsif ref
|
|
358
|
+
@timeout.ref[ref.to_sym].update(data)
|
|
359
|
+
else
|
|
360
|
+
@timeout.store.update(data)
|
|
361
|
+
end
|
|
362
|
+
self
|
|
363
|
+
end
|
|
364
|
+
|
|
365
|
+
def batch(*args)
|
|
366
|
+
(@config[:batch] ||= []) << args
|
|
367
|
+
self
|
|
368
|
+
end
|
|
369
|
+
|
|
370
|
+
def rename(task, val)
|
|
371
|
+
(@config[:rename] ||= {})[task.to_sym] = val.to_s
|
|
372
|
+
self
|
|
373
|
+
end
|
|
374
|
+
|
|
370
375
|
def add(path, project = nil, **kwargs, &blk)
|
|
371
|
-
kwargs = hashdup(@withargs).update(kwargs) if @withargs
|
|
376
|
+
kwargs = Support.hashdup(@withargs).update(kwargs) if @withargs
|
|
372
377
|
ref = kwargs.key?(:ref) ? kwargs.delete(:ref) : @ref
|
|
373
378
|
kwargs[:group] = @group if @group && !kwargs.key?(:group)
|
|
374
379
|
path = rootpath path
|
|
@@ -379,12 +384,20 @@ module Squared
|
|
|
379
384
|
index += 1
|
|
380
385
|
name = task_name "#{project}-#{index}"
|
|
381
386
|
end
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
Application.find(ref, path: path)
|
|
385
|
-
elsif
|
|
387
|
+
unless ref.is_a?(Symbol) && (proj = @base.find { |item| item.ref == ref })
|
|
388
|
+
proj = if !ref.is_a?(Class)
|
|
389
|
+
require_project(ref) || Application.find(ref, path: path)
|
|
390
|
+
elsif Application.extends(ref)
|
|
386
391
|
ref
|
|
387
|
-
end
|
|
392
|
+
end || @kind[name]&.last
|
|
393
|
+
if proj
|
|
394
|
+
@base << proj
|
|
395
|
+
@banner.items.concat(Array(proj.bannerargs))
|
|
396
|
+
else
|
|
397
|
+
proj = Application.impl_project
|
|
398
|
+
end
|
|
399
|
+
end
|
|
400
|
+
proj = proj.new(self, path, name, **kwargs)
|
|
388
401
|
proj.__send__(:index_set, size)
|
|
389
402
|
@project[name] = proj
|
|
390
403
|
__get__(:project)[name] = proj unless kwargs[:private]
|
|
@@ -393,7 +406,7 @@ module Squared
|
|
|
393
406
|
end
|
|
394
407
|
|
|
395
408
|
def group(path, val, override: {}, **kwargs, &blk)
|
|
396
|
-
rootpath(path).children.map
|
|
409
|
+
rootpath(path).children.map do |dir|
|
|
397
410
|
next unless dir.directory?
|
|
398
411
|
|
|
399
412
|
basename = dir.basename.to_s
|
|
@@ -417,6 +430,18 @@ module Squared
|
|
|
417
430
|
self
|
|
418
431
|
end
|
|
419
432
|
|
|
433
|
+
def stage(val, first: false, &blk)
|
|
434
|
+
data = @stage[val]
|
|
435
|
+
if first == true
|
|
436
|
+
data.unshift(blk)
|
|
437
|
+
elsif first.is_a?(Numeric) && first < data.size
|
|
438
|
+
data.insert(first, blk)
|
|
439
|
+
else
|
|
440
|
+
data.push(blk)
|
|
441
|
+
end
|
|
442
|
+
self
|
|
443
|
+
end
|
|
444
|
+
|
|
420
445
|
def style(obj, *args, target: nil, empty: false)
|
|
421
446
|
data = nil
|
|
422
447
|
if target
|
|
@@ -431,7 +456,7 @@ module Squared
|
|
|
431
456
|
if obj.is_a?(String)
|
|
432
457
|
obj = begin
|
|
433
458
|
JSON.parse(homepath(obj).read, { symbolize_names: true })
|
|
434
|
-
rescue
|
|
459
|
+
rescue => e
|
|
435
460
|
warn log_message(Logger::ERROR, e)
|
|
436
461
|
end
|
|
437
462
|
end
|
|
@@ -447,7 +472,7 @@ module Squared
|
|
|
447
472
|
}
|
|
448
473
|
data.each do |key, val|
|
|
449
474
|
key = key.to_s
|
|
450
|
-
if key.start_with?(
|
|
475
|
+
if key.start_with?('\A', '^') || key.end_with?('\z', '$')
|
|
451
476
|
@describe[:replace] << [Regexp.new(key), val]
|
|
452
477
|
else
|
|
453
478
|
@describe[val.is_a?(Regexp) ? :pattern : :alias][key] = val
|
|
@@ -489,7 +514,7 @@ module Squared
|
|
|
489
514
|
end
|
|
490
515
|
|
|
491
516
|
def find_base(obj)
|
|
492
|
-
|
|
517
|
+
@base.find { |proj| obj.instance_of?(proj) }
|
|
493
518
|
end
|
|
494
519
|
|
|
495
520
|
def task_name(val)
|
|
@@ -530,7 +555,7 @@ module Squared
|
|
|
530
555
|
break
|
|
531
556
|
end
|
|
532
557
|
end
|
|
533
|
-
args = split_escape(val, char: ':').map
|
|
558
|
+
args = split_escape(val, char: ':').map { |s| s.gsub('\\:', ':') } if found
|
|
534
559
|
end
|
|
535
560
|
desc message(*args, **kwargs)
|
|
536
561
|
end
|
|
@@ -547,7 +572,7 @@ module Squared
|
|
|
547
572
|
tasks << key if obj.has?(key, baseref)
|
|
548
573
|
elsif (batch = series.batch_get(key))
|
|
549
574
|
obj.allref do |ref|
|
|
550
|
-
next unless obj.has?(key, ref) && (data = batch[ref])
|
|
575
|
+
next unless obj.has?(key, ref, missing: series.missing?(ref, key)) && (data = batch[ref])
|
|
551
576
|
|
|
552
577
|
data.each do |val|
|
|
553
578
|
if (items = task_resolve(obj, val)).empty?
|
|
@@ -607,29 +632,55 @@ module Squared
|
|
|
607
632
|
out ? message(*val) : task_desc(*val)
|
|
608
633
|
end
|
|
609
634
|
|
|
610
|
-
def script_find(*args)
|
|
635
|
+
def script_find(*args, name: nil)
|
|
636
|
+
target = @global[name || '_']
|
|
637
|
+
group, ref, exclude = target.fetch_values(:group, :ref, :exclude)
|
|
638
|
+
ret = nil
|
|
611
639
|
args.reverse_each do |val|
|
|
612
|
-
|
|
613
|
-
|
|
640
|
+
next unless val
|
|
641
|
+
|
|
642
|
+
if exclude.include?(val)
|
|
643
|
+
ret = nil
|
|
644
|
+
break
|
|
645
|
+
elsif ret
|
|
646
|
+
next
|
|
647
|
+
elsif (ret = val.is_a?(Symbol) ? ref[val] : group[val]) && exclude.empty?
|
|
648
|
+
break
|
|
614
649
|
end
|
|
615
650
|
end
|
|
616
|
-
|
|
651
|
+
ret || (target[:script] ||= scriptobj)
|
|
617
652
|
end
|
|
618
653
|
|
|
619
654
|
def script_get(*args, group: nil, ref: nil)
|
|
620
|
-
data_get(*args, group: group, ref: ref
|
|
655
|
+
data_get(*args, target: @script, group: group, ref: ref)
|
|
621
656
|
end
|
|
622
657
|
|
|
623
658
|
def events_get(*args, group: nil, ref: nil)
|
|
624
|
-
data_get(*args, group: group, ref: ref
|
|
659
|
+
data_get(*args, target: @events, group: group, ref: ref)
|
|
625
660
|
end
|
|
626
661
|
|
|
627
662
|
def banner_get(*ref, group: nil)
|
|
628
|
-
|
|
629
|
-
|
|
663
|
+
if group && @banner.group.key?(group = group.to_sym)
|
|
664
|
+
@banner.group[group]
|
|
665
|
+
else
|
|
666
|
+
ref.reverse_each do |val|
|
|
667
|
+
next unless @banner.ref.key?(val)
|
|
630
668
|
|
|
631
|
-
|
|
632
|
-
|
|
669
|
+
return @banner.ref[val]
|
|
670
|
+
end
|
|
671
|
+
@banner.ref[:_] if @banner.ref.key?(:_)
|
|
672
|
+
end
|
|
673
|
+
end
|
|
674
|
+
|
|
675
|
+
def timeout_get(*ref, group: nil)
|
|
676
|
+
ret = @timeout.store.dup
|
|
677
|
+
ref.each { |val| ret.update(@timeout.ref[val]) if @timeout.ref.key?(val) }
|
|
678
|
+
ret.update(@timeout.group[group]) if group && @timeout.group.key?(group)
|
|
679
|
+
ret
|
|
680
|
+
end
|
|
681
|
+
|
|
682
|
+
def config_get(key, default = nil, &blk)
|
|
683
|
+
@config.fetch(key, block_given? ? blk : default)
|
|
633
684
|
end
|
|
634
685
|
|
|
635
686
|
def enabled?
|
|
@@ -652,13 +703,13 @@ module Squared
|
|
|
652
703
|
|
|
653
704
|
def task_exclude?(key, obj = nil)
|
|
654
705
|
if obj
|
|
655
|
-
data = obj.group ? @pass
|
|
656
|
-
blk = (data && data[key.to_sym]) || @pass[
|
|
706
|
+
data = obj.group ? @pass.group[obj.group] : @pass.ref[obj.ref]
|
|
707
|
+
blk = (data && data[key.to_sym]) || @pass.store[key.to_sym]
|
|
657
708
|
return true if blk && obj.instance_eval(&blk)
|
|
658
709
|
|
|
659
710
|
key = task_join(task_localname(obj.name), key)
|
|
660
711
|
end
|
|
661
|
-
@pass
|
|
712
|
+
@pass.items.any? { |item| item.is_a?(Regexp) ? item.match?(key) : item == key }
|
|
662
713
|
end
|
|
663
714
|
|
|
664
715
|
def task_defined?(*key)
|
|
@@ -745,18 +796,43 @@ module Squared
|
|
|
745
796
|
|
|
746
797
|
private
|
|
747
798
|
|
|
748
|
-
def
|
|
749
|
-
unless
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
799
|
+
def initialize_session
|
|
800
|
+
return unless @pipe.is_a?(Pathname)
|
|
801
|
+
|
|
802
|
+
msg = "Session started on #{Time.now} by #{@main}"
|
|
803
|
+
bord = '#' * msg.size
|
|
804
|
+
puts bord, msg, bord
|
|
805
|
+
end
|
|
806
|
+
|
|
807
|
+
def home=(val)
|
|
808
|
+
return if @closed
|
|
809
|
+
|
|
810
|
+
@home = Pathname.new(val).realdirpath
|
|
811
|
+
@root = @home.parent
|
|
812
|
+
@home.mkpath rescue nil
|
|
813
|
+
end
|
|
814
|
+
|
|
815
|
+
def closed=(val)
|
|
816
|
+
if val.is_a?(Array)
|
|
817
|
+
val, target = val
|
|
818
|
+
else
|
|
819
|
+
target = self
|
|
756
820
|
end
|
|
821
|
+
@closed = val
|
|
822
|
+
@stage[val].each { |blk| target.instance_eval(&blk) } if @stage.key?(val)
|
|
823
|
+
end
|
|
824
|
+
|
|
825
|
+
def __build__(*, default: nil, **)
|
|
826
|
+
self.closed = 'build:begin'
|
|
827
|
+
task('squared:version') { puts Squared::VERSION } unless task_defined?('squared:version')
|
|
828
|
+
task Rake.application.default_task_name => task_name(default) if default && task_defined?(task_name(default))
|
|
829
|
+
self.closed = 'build:end'
|
|
757
830
|
end
|
|
758
831
|
|
|
759
832
|
def __chain__(*)
|
|
833
|
+
return if @chain.empty?
|
|
834
|
+
|
|
835
|
+
self.closed = 'chain:begin'
|
|
760
836
|
@chain.each do |key, group|
|
|
761
837
|
level = []
|
|
762
838
|
sync = []
|
|
@@ -867,13 +943,14 @@ module Squared
|
|
|
867
943
|
end
|
|
868
944
|
end
|
|
869
945
|
end
|
|
946
|
+
self.closed = 'chain:end'
|
|
870
947
|
end
|
|
871
948
|
|
|
872
949
|
def puts(*args, **kwargs)
|
|
873
950
|
log_console(*args, pipe: kwargs[:pipe] || pipe)
|
|
874
951
|
end
|
|
875
952
|
|
|
876
|
-
def script_command(task, val, group, ref, on
|
|
953
|
+
def script_command(task, val, group, ref, on, &blk)
|
|
877
954
|
if block_given?
|
|
878
955
|
val = Struct::RunData.new(val, blk)
|
|
879
956
|
elsif !val
|
|
@@ -884,7 +961,7 @@ module Squared
|
|
|
884
961
|
as_a group, :to_sym
|
|
885
962
|
else
|
|
886
963
|
label = :ref
|
|
887
|
-
as_a
|
|
964
|
+
as_a ref, :to_sym
|
|
888
965
|
end.each do |name|
|
|
889
966
|
@script[label][name][task] = val
|
|
890
967
|
@events[label][name][task] = on if on.is_a?(Hash)
|
|
@@ -892,18 +969,39 @@ module Squared
|
|
|
892
969
|
self
|
|
893
970
|
end
|
|
894
971
|
|
|
895
|
-
def script_set(data, group: nil, ref: nil)
|
|
972
|
+
def script_set(from, data, name: nil, extras: nil, group: nil, ref: nil)
|
|
973
|
+
target = @global[name || '_']
|
|
974
|
+
target[:module] = from
|
|
975
|
+
target[:extras].update(extras) if extras
|
|
896
976
|
data.freeze
|
|
897
977
|
if group
|
|
898
|
-
Array(group).each
|
|
978
|
+
Array(group).each do |val|
|
|
979
|
+
val = val.to_s
|
|
980
|
+
if val.start_with?('-')
|
|
981
|
+
target[:exclude] << val[1..-1]
|
|
982
|
+
else
|
|
983
|
+
target[:group][val] = data
|
|
984
|
+
end
|
|
985
|
+
end
|
|
899
986
|
elsif ref
|
|
900
|
-
Array(ref).each
|
|
987
|
+
Array(ref).each do |val|
|
|
988
|
+
val = val.to_s
|
|
989
|
+
if val.start_with?('-')
|
|
990
|
+
target[:exclude] << val[1..-1].to_sym
|
|
991
|
+
else
|
|
992
|
+
target[:ref][val.to_sym] = data
|
|
993
|
+
end
|
|
994
|
+
end
|
|
901
995
|
else
|
|
902
|
-
|
|
996
|
+
target[:script] = data
|
|
903
997
|
end
|
|
904
998
|
end
|
|
905
999
|
|
|
906
|
-
def
|
|
1000
|
+
def script_each(from, &blk)
|
|
1001
|
+
@global.select { |_, data| data[:module] == from }.each(&blk)
|
|
1002
|
+
end
|
|
1003
|
+
|
|
1004
|
+
def data_get(*args, target:, group: nil, ref: nil)
|
|
907
1005
|
if group && target[:group].key?(key = group.to_sym)
|
|
908
1006
|
target[:group][key]
|
|
909
1007
|
elsif ref.is_a?(Enumerable)
|
|
@@ -916,39 +1014,37 @@ module Squared
|
|
|
916
1014
|
nil
|
|
917
1015
|
elsif ref && target[:ref].key?(ref)
|
|
918
1016
|
target[:ref][ref]
|
|
919
|
-
else
|
|
920
|
-
target[:ref][:_]
|
|
921
1017
|
end
|
|
922
1018
|
end
|
|
923
1019
|
|
|
924
1020
|
def require_project(ref)
|
|
925
|
-
|
|
1021
|
+
ret = Application.kind_project.find { |proj| proj.ref == ref }
|
|
1022
|
+
return ret if ret
|
|
926
1023
|
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
next unless File.exist?("#{rb = File.join(val, name)}.rb")
|
|
1024
|
+
Application.load_project.each do |dir|
|
|
1025
|
+
next unless File.exist?("#{rb = File.join(dir, ref.to_s)}.rb")
|
|
930
1026
|
|
|
931
1027
|
require_relative rb
|
|
932
1028
|
break
|
|
933
1029
|
end
|
|
934
|
-
nil
|
|
935
1030
|
end
|
|
936
1031
|
|
|
937
1032
|
def root?(path, pass: [])
|
|
938
1033
|
return false unless path.directory?
|
|
939
1034
|
|
|
940
|
-
path.each_child do |
|
|
941
|
-
|
|
942
|
-
unless
|
|
1035
|
+
path.each_child do |file|
|
|
1036
|
+
s = file.basename.to_s
|
|
1037
|
+
unless file.to_s == __FILE__ || (@main == s && file.directory? && file.empty?) || pass.any? { |val| val == s }
|
|
943
1038
|
return false
|
|
944
1039
|
end
|
|
945
1040
|
end
|
|
946
1041
|
true
|
|
947
1042
|
end
|
|
948
1043
|
|
|
949
|
-
def script?(state, target: nil, pat: nil, group: nil, ref: baseref,
|
|
950
|
-
|
|
951
|
-
|
|
1044
|
+
def script?(state, name: nil, target: nil, pat: nil, group: nil, ref: baseref, type: nil, script: true,
|
|
1045
|
+
global: false)
|
|
1046
|
+
data = script_find(ref, group, name: name)
|
|
1047
|
+
type ||= script ? :script : :run
|
|
952
1048
|
if global
|
|
953
1049
|
target = data[type] if target.nil?
|
|
954
1050
|
pat = data[state] if pat.nil?
|
|
@@ -958,13 +1054,23 @@ module Squared
|
|
|
958
1054
|
target && pat.is_a?(Regexp) ? Array(target).any?(pat) : pat == true
|
|
959
1055
|
end
|
|
960
1056
|
|
|
1057
|
+
def banner_include?(val)
|
|
1058
|
+
Application.attr_banner.include?(val) || @banner.items.include?(val)
|
|
1059
|
+
end
|
|
1060
|
+
|
|
961
1061
|
def scriptobj
|
|
962
1062
|
{
|
|
963
1063
|
run: nil,
|
|
964
1064
|
script: nil,
|
|
965
1065
|
dev: nil,
|
|
966
1066
|
prod: nil,
|
|
967
|
-
global: {
|
|
1067
|
+
global: {
|
|
1068
|
+
script: false,
|
|
1069
|
+
run: false,
|
|
1070
|
+
doc: false,
|
|
1071
|
+
lint: false,
|
|
1072
|
+
test: false
|
|
1073
|
+
},
|
|
968
1074
|
env: {}
|
|
969
1075
|
}
|
|
970
1076
|
end
|