squared 0.6.8 → 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.
@@ -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: false)
17
- return if base && objs.size > 1
18
-
19
- objs.each do |obj|
20
- next unless base || obj < impl_project
21
-
22
- if base
23
- self.impl_project = obj
24
- impl_series.base_set(obj)
25
- else
26
- kind_project.unshift(obj)
27
- impl_series.extend_set(obj)
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(*args)
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: @task_exclude.to_a)
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
- @load_project.unshift(path.cleanpath.to_s) if (path = Pathname.new(path)).absolute? && path.exist?
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,40 +80,42 @@ module Squared
83
80
  super[/[^:]+\z/, 0]
84
81
  end
85
82
 
86
- alias series_wrap register
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
- @home = Pathname.new(home).realdirpath
103
- basename = @home.basename.to_s
98
+ home = Pathname.new(home)
99
+ basename = home.basename.to_s
104
100
  if main
105
101
  @main = main.to_s.freeze
106
- @home += @main unless @main == basename || (windows? && @main.casecmp?(basename))
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
- @kind = hashlist
116
- @extensions = []
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 = $DEBUG ? 2 : env_pipe(pipe, (ARG[:OUT] && env(ARG[:OUT])) || 1, root: @home)
118
+ self.pipe = $DEBUG ? 2 : env_pipe(pipe, (ARG[:OUT] && env(ARG[:OUT])) || 1, root: home)
120
119
  self.verbose = if $VERBOSE.nil?
121
120
  false
122
121
  elsif verbose.nil?
@@ -125,85 +124,93 @@ module Squared
125
124
  env_bool(verbose, verbose.is_a?(String) ? @pipe != 0 : verbose, index: true)
126
125
  end
127
126
  self.warning = @verbose != false
128
- @closed = false
129
- @theme = if common
130
- ARG[:COLOR] = false if @pipe == 0 || @pipe.is_a?(Pathname)
131
- __get__(:theme)[:workspace]
132
- else
133
- {}
134
- end
135
- @chain = hashlist
136
- @script = {
137
- group: hashobj,
138
- ref: hashobj,
139
- group!: {},
140
- ref!: {}
141
- }.freeze
142
- @events = {
143
- group: hashobj,
144
- ref: hashobj
145
- }.freeze
146
- @pass = {
147
- group: hashobj,
148
- ref: hashobj,
149
- global: {},
150
- pattern: []
151
- }.freeze
152
- @banner = {
153
- group: {},
154
- ref: {}
155
- }.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
156
137
  initialize_session
157
138
  end
158
139
 
159
- def initialize_session
160
- return unless @pipe.is_a?(Pathname)
161
-
162
- msg = "Session started on #{Time.now} by #{@main}"
163
- bord = '#' * msg.size
164
- puts bord, msg, bord
165
- end
166
-
167
140
  def each(&blk)
168
141
  return to_enum(:each) unless block_given?
169
142
 
170
143
  @project.each_value(&blk)
171
144
  end
172
145
 
173
- def build(parallel: [], pass: nil, **kwargs)
146
+ def build(parallel: [], **kwargs)
174
147
  return self unless enabled? && !@closed
175
148
 
149
+ self.closed = 'init'
176
150
  kwargs[:parallel] = if kwargs[:pattern].is_a?(Array)
177
151
  parallel.map(&:to_s)
178
152
  else
179
153
  kwargs[:pattern] = []
180
- parallel.reject { |val| kwargs[:pattern] << val if val.is_a?(Regexp) }.map!(&:to_s)
154
+ parallel.reject { |val| kwargs[:pattern] << val if val.is_a?(Regexp) }.map(&:to_s)
181
155
  end
182
- @pass[:pattern].concat(pass.map { |val| val.is_a?(Regexp) ? val : val.to_s }) if pass
183
- series.reset
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
184
162
  each do |proj|
163
+ self.closed = ['project:begin', proj] if pb
185
164
  if proj.enabled?
186
- proj.populate(series.keys.dup, **kwargs)
165
+ proj.populate(keys.dup, **kwargs)
187
166
  elsif proj.enabled?(base: false)
188
167
  proj.generate([], **kwargs)
189
168
  else
190
169
  next
191
170
  end
192
- series.populate(proj, **kwargs)
171
+ @series.populate(proj, **kwargs)
172
+ self.closed = ['project:end', proj] if pe
193
173
  end
194
- Application.kind_project.each { |obj| obj.populate(self, **kwargs) }
195
- @extensions.uniq.each { |ext| __send__(ext, **kwargs) }
196
- series.build(**kwargs)
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)
197
180
  __build__(**kwargs)
198
- yield self if block_given?
199
- __chain__(**kwargs)
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'
200
189
  @closed = true
201
190
  self
202
191
  end
203
192
 
204
- def with(*val, pass: false, group: nil, **kwargs, &blk)
205
- return self if pass == true || (pass && as_a(pass, :to_s).any? { |s| respond_to?(s) && __send__(s) })
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)
206
201
 
202
+ return self
203
+ end
204
+ elsif respond_to?(args)
205
+ next unless __send__(args)
206
+
207
+ return self
208
+ end
209
+ raise_error 'method not found'
210
+ rescue => e
211
+ warn log_message(Logger::WARN, e, subject: main, hint: hint || args)
212
+ end
213
+ end
207
214
  @group = nil
208
215
  @ref = nil
209
216
  @withargs = unless kwargs.empty?
@@ -219,7 +226,7 @@ module Squared
219
226
  when Symbol
220
227
  @ref = val
221
228
  else
222
- raise_error ArgumentError, 'missing group or ref' if block_given?
229
+ raise_error TypeError, "not a group/ref: #{kind || 'nil'}" if block_given?
223
230
  end
224
231
  if block_given?
225
232
  instance_eval(&blk)
@@ -236,18 +243,18 @@ module Squared
236
243
 
237
244
  def chain(task, *action, project: nil, step: 0, with: nil, before: nil, after: nil, sync: false,
238
245
  group: @group, ref: @ref)
239
- if project
240
- action.map! { |val| task_join(project.name, val) }
241
- elsif (target = group || ref)
242
- action.map! { |val| task_name(task_join(val, target)) }
243
- else
244
- action.map! { |val| task_name(val) }
245
- keys = @project.keys unless prefix
246
- end
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
247
254
  ns = lambda do |val|
248
255
  return if (ret = as_a(val, :to_s, flat: true)).empty?
249
256
 
250
- ret.map! do |arg|
257
+ ret.map do |arg|
251
258
  if arg.include?(':') || (keys && !keys.include?(arg))
252
259
  task_name(arg)
253
260
  else
@@ -255,7 +262,7 @@ module Squared
255
262
  end
256
263
  end
257
264
  end
258
- data = Struct::ChainData.new(action, step, ns.call(with), ns.call(before), ns.call(after), sync)
265
+ data = Struct::ChainData.new(tasks, step, ns.call(with), ns.call(before), ns.call(after), sync)
259
266
  @chain[task_name(task.to_s)] << data
260
267
  self
261
268
  end
@@ -298,18 +305,18 @@ module Squared
298
305
 
299
306
  def pass(name, group: @group, ref: @ref, &blk)
300
307
  data = if group
301
- @pass[:group][group.to_s]
308
+ @pass.group[group.to_s]
302
309
  elsif ref
303
- @pass[:ref][ref.to_sym]
310
+ @pass.ref[ref.to_sym]
304
311
  else
305
- @pass[:global]
312
+ @pass.store
306
313
  end
307
314
  data[name.to_sym] = blk
308
315
  self
309
316
  end
310
317
 
311
318
  def banner(*args, command: true, styles: nil, border: nil, group: @group, ref: @ref)
312
- data = Struct::BannerData.new(command, [], check_style(styles, empty: false), check_style(border))
319
+ data = Struct::BannerData.new(command, check_style(styles, empty: false), check_style(border))
313
320
  args.each do |meth|
314
321
  if meth.is_a?(Array)
315
322
  found = false
@@ -317,7 +324,7 @@ module Squared
317
324
  case val
318
325
  when Symbol
319
326
  found = true
320
- Application.attr_banner.include?(val)
327
+ banner_include?(val)
321
328
  when String
322
329
  true
323
330
  else
@@ -329,7 +336,7 @@ module Squared
329
336
  elsif meth.size == 1
330
337
  meth = meth.first
331
338
  end
332
- elsif !Application.attr_banner.include?(meth = meth.to_sym)
339
+ elsif !banner_include?(meth = meth.to_sym)
333
340
  next
334
341
  end
335
342
  data.order << meth
@@ -344,8 +351,29 @@ module Squared
344
351
  self
345
352
  end
346
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
+
347
375
  def add(path, project = nil, **kwargs, &blk)
348
- kwargs = hashdup(@withargs).update(kwargs) if @withargs
376
+ kwargs = Support.hashdup(@withargs).update(kwargs) if @withargs
349
377
  ref = kwargs.key?(:ref) ? kwargs.delete(:ref) : @ref
350
378
  kwargs[:group] = @group if @group && !kwargs.key?(:group)
351
379
  path = rootpath path
@@ -356,12 +384,20 @@ module Squared
356
384
  index += 1
357
385
  name = task_name "#{project}-#{index}"
358
386
  end
359
- proj = ((if !ref.is_a?(Class)
360
- require_project ref
361
- Application.find(ref, path: path)
362
- elsif ref < Application.impl_project
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)
363
391
  ref
364
- end) || @kind[name]&.last || Application.impl_project).new(self, path, name, **kwargs)
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)
365
401
  proj.__send__(:index_set, size)
366
402
  @project[name] = proj
367
403
  __get__(:project)[name] = proj unless kwargs[:private]
@@ -370,7 +406,7 @@ module Squared
370
406
  end
371
407
 
372
408
  def group(path, val, override: {}, **kwargs, &blk)
373
- rootpath(path).children.map! do |dir|
409
+ rootpath(path).children.map do |dir|
374
410
  next unless dir.directory?
375
411
 
376
412
  basename = dir.basename.to_s
@@ -394,6 +430,18 @@ module Squared
394
430
  self
395
431
  end
396
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
+
397
445
  def style(obj, *args, target: nil, empty: false)
398
446
  data = nil
399
447
  if target
@@ -408,7 +456,7 @@ module Squared
408
456
  if obj.is_a?(String)
409
457
  obj = begin
410
458
  JSON.parse(homepath(obj).read, { symbolize_names: true })
411
- rescue StandardError => e
459
+ rescue => e
412
460
  warn log_message(Logger::ERROR, e)
413
461
  end
414
462
  end
@@ -424,7 +472,7 @@ module Squared
424
472
  }
425
473
  data.each do |key, val|
426
474
  key = key.to_s
427
- if key.start_with?(/(\\A|\^)/) || key.match?(/(\\z|\$)\z/)
475
+ if key.start_with?('\A', '^') || key.end_with?('\z', '$')
428
476
  @describe[:replace] << [Regexp.new(key), val]
429
477
  else
430
478
  @describe[val.is_a?(Regexp) ? :pattern : :alias][key] = val
@@ -466,7 +514,7 @@ module Squared
466
514
  end
467
515
 
468
516
  def find_base(obj)
469
- Application.kind_project.find { |proj| obj.instance_of?(proj) }
517
+ @base.find { |proj| obj.instance_of?(proj) }
470
518
  end
471
519
 
472
520
  def task_name(val)
@@ -507,7 +555,7 @@ module Squared
507
555
  break
508
556
  end
509
557
  end
510
- args = split_escape(val, char: ':').map! { |s| s.gsub('\\:', ':') } if found
558
+ args = split_escape(val, char: ':').map { |s| s.gsub('\\:', ':') } if found
511
559
  end
512
560
  desc message(*args, **kwargs)
513
561
  end
@@ -524,7 +572,7 @@ module Squared
524
572
  tasks << key if obj.has?(key, baseref)
525
573
  elsif (batch = series.batch_get(key))
526
574
  obj.allref do |ref|
527
- next unless obj.has?(key, ref) && (data = batch[ref])
575
+ next unless obj.has?(key, ref, missing: series.missing?(ref, key)) && (data = batch[ref])
528
576
 
529
577
  data.each do |val|
530
578
  if (items = task_resolve(obj, val)).empty?
@@ -584,29 +632,55 @@ module Squared
584
632
  out ? message(*val) : task_desc(*val)
585
633
  end
586
634
 
587
- 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
588
639
  args.reverse_each do |val|
589
- if val && (ret = val.is_a?(Symbol) ? @script[:ref!][val] : @script[:group!][val.to_sym])
590
- return ret
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
591
649
  end
592
650
  end
593
- @script[:ref!][:''] ||= scriptobj
651
+ ret || (target[:script] ||= scriptobj)
594
652
  end
595
653
 
596
654
  def script_get(*args, group: nil, ref: nil)
597
- data_get(*args, group: group, ref: ref, target: @script)
655
+ data_get(*args, target: @script, group: group, ref: ref)
598
656
  end
599
657
 
600
658
  def events_get(*args, group: nil, ref: nil)
601
- data_get(*args, group: group, ref: ref, target: @events)
659
+ data_get(*args, target: @events, group: group, ref: ref)
602
660
  end
603
661
 
604
662
  def banner_get(*ref, group: nil)
605
- ret = nil
606
- return ret if group && (ret = @banner[:group][group.to_sym])
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)
607
668
 
608
- ref.reverse_each { |val| return ret if (ret = @banner[:ref][val]) }
609
- @banner[:ref][:_]
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)
610
684
  end
611
685
 
612
686
  def enabled?
@@ -629,13 +703,13 @@ module Squared
629
703
 
630
704
  def task_exclude?(key, obj = nil)
631
705
  if obj
632
- data = obj.group ? @pass[:group][obj.group] : @pass[:ref][obj.ref]
633
- blk = (data && data[key.to_sym]) || @pass[:global][key.to_sym]
706
+ data = obj.group ? @pass.group[obj.group] : @pass.ref[obj.ref]
707
+ blk = (data && data[key.to_sym]) || @pass.store[key.to_sym]
634
708
  return true if blk && obj.instance_eval(&blk)
635
709
 
636
710
  key = task_join(task_localname(obj.name), key)
637
711
  end
638
- @pass[:pattern].any? { |item| item.is_a?(Regexp) ? key.to_s.match?(item) : key == item }
712
+ @pass.items.any? { |item| item.is_a?(Regexp) ? item.match?(key) : item == key }
639
713
  end
640
714
 
641
715
  def task_defined?(*key)
@@ -722,18 +796,43 @@ module Squared
722
796
 
723
797
  private
724
798
 
725
- def __build__(default: nil, **)
726
- unless task_defined?('squared:version')
727
- task 'squared:version' do
728
- puts Squared::VERSION
729
- end
730
- end
731
- if default && task_defined?(out = task_name(default))
732
- task Rake.application.default_task_name => out
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
733
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'
734
830
  end
735
831
 
736
832
  def __chain__(*)
833
+ return if @chain.empty?
834
+
835
+ self.closed = 'chain:begin'
737
836
  @chain.each do |key, group|
738
837
  level = []
739
838
  sync = []
@@ -844,6 +943,7 @@ module Squared
844
943
  end
845
944
  end
846
945
  end
946
+ self.closed = 'chain:end'
847
947
  end
848
948
 
849
949
  def puts(*args, **kwargs)
@@ -869,18 +969,39 @@ module Squared
869
969
  self
870
970
  end
871
971
 
872
- 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
873
976
  data.freeze
874
977
  if group
875
- Array(group).each { |val| @script[:group!][val.to_sym] = data }
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
876
986
  elsif ref
877
- Array(ref).each { |val| @script[:ref!][val.to_sym] = data }
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
878
995
  else
879
- @script[:ref!][:''] = data
996
+ target[:script] = data
880
997
  end
881
998
  end
882
999
 
883
- def data_get(*args, group: nil, ref: nil, target: nil)
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)
884
1005
  if group && target[:group].key?(key = group.to_sym)
885
1006
  target[:group][key]
886
1007
  elsif ref.is_a?(Enumerable)
@@ -897,11 +1018,11 @@ module Squared
897
1018
  end
898
1019
 
899
1020
  def require_project(ref)
900
- return unless ref.is_a?(Symbol) && Application.kind_project.none? { |proj| proj.ref == ref }
1021
+ ret = Application.kind_project.find { |proj| proj.ref == ref }
1022
+ return ret if ret
901
1023
 
902
- name = ref.to_s
903
- Application.load_project.each do |val|
904
- 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")
905
1026
 
906
1027
  require_relative rb
907
1028
  break
@@ -911,18 +1032,19 @@ module Squared
911
1032
  def root?(path, pass: [])
912
1033
  return false unless path.directory?
913
1034
 
914
- path.each_child do |c|
915
- name = c.basename.to_s
916
- unless c.to_s == __FILE__ || (@main == name && c.directory? && c.empty?) || pass.any? { |val| val == name }
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 }
917
1038
  return false
918
1039
  end
919
1040
  end
920
1041
  true
921
1042
  end
922
1043
 
923
- def script?(state, target: nil, pat: nil, group: nil, ref: baseref, global: false, script: true)
924
- data = script_find ref, group
925
- type = script ? :script : :run
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
926
1048
  if global
927
1049
  target = data[type] if target.nil?
928
1050
  pat = data[state] if pat.nil?
@@ -932,13 +1054,23 @@ module Squared
932
1054
  target && pat.is_a?(Regexp) ? Array(target).any?(pat) : pat == true
933
1055
  end
934
1056
 
1057
+ def banner_include?(val)
1058
+ Application.attr_banner.include?(val) || @banner.items.include?(val)
1059
+ end
1060
+
935
1061
  def scriptobj
936
1062
  {
937
1063
  run: nil,
938
1064
  script: nil,
939
1065
  dev: nil,
940
1066
  prod: nil,
941
- global: {},
1067
+ global: {
1068
+ script: false,
1069
+ run: false,
1070
+ doc: false,
1071
+ lint: false,
1072
+ test: false
1073
+ },
942
1074
  env: {}
943
1075
  }
944
1076
  end