squared 0.6.9 → 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,102 +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, hide: nil, group: nil, **kwargs, &blk)
205
- if hide.nil? && kwargs.key?(:pass)
206
- pass = kwargs[:pass]
207
- case pass
208
- when true, false
209
- hide = pass
210
- kwargs.delete(:pass)
211
- else
212
- hide, pass = Array(pass).partition { |s| respond_to?(s) || s.to_s.end_with?('?') }
213
- if pass.empty?
214
- kwargs.delete(:pass)
215
- elsif hide.empty?
216
- hide = nil
217
- else
218
- kwargs[:pass] = pass
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
219
208
  end
209
+ raise_error 'method not found'
210
+ rescue => e
211
+ warn log_message(Logger::WARN, e, subject: main, hint: hint || args)
220
212
  end
221
213
  end
222
- return self if hide == true || (hide && Array(hide).any? { |s| respond_to?(s) && __send__(s) rescue nil })
223
-
224
214
  @group = nil
225
215
  @ref = nil
226
216
  @withargs = unless kwargs.empty?
@@ -236,7 +226,7 @@ module Squared
236
226
  when Symbol
237
227
  @ref = val
238
228
  else
239
- raise_error ArgumentError, 'missing group or ref' if block_given?
229
+ raise_error TypeError, "not a group/ref: #{kind || 'nil'}" if block_given?
240
230
  end
241
231
  if block_given?
242
232
  instance_eval(&blk)
@@ -253,18 +243,18 @@ module Squared
253
243
 
254
244
  def chain(task, *action, project: nil, step: 0, with: nil, before: nil, after: nil, sync: false,
255
245
  group: @group, ref: @ref)
256
- if project
257
- action.map! { |val| task_join(project.name, val) }
258
- elsif (target = group || ref)
259
- action.map! { |val| task_name(task_join(val, target)) }
260
- else
261
- action.map! { |val| task_name(val) }
262
- keys = @project.keys unless prefix
263
- 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
264
254
  ns = lambda do |val|
265
255
  return if (ret = as_a(val, :to_s, flat: true)).empty?
266
256
 
267
- ret.map! do |arg|
257
+ ret.map do |arg|
268
258
  if arg.include?(':') || (keys && !keys.include?(arg))
269
259
  task_name(arg)
270
260
  else
@@ -272,7 +262,7 @@ module Squared
272
262
  end
273
263
  end
274
264
  end
275
- 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)
276
266
  @chain[task_name(task.to_s)] << data
277
267
  self
278
268
  end
@@ -315,18 +305,18 @@ module Squared
315
305
 
316
306
  def pass(name, group: @group, ref: @ref, &blk)
317
307
  data = if group
318
- @pass[:group][group.to_s]
308
+ @pass.group[group.to_s]
319
309
  elsif ref
320
- @pass[:ref][ref.to_sym]
310
+ @pass.ref[ref.to_sym]
321
311
  else
322
- @pass[:global]
312
+ @pass.store
323
313
  end
324
314
  data[name.to_sym] = blk
325
315
  self
326
316
  end
327
317
 
328
318
  def banner(*args, command: true, styles: nil, border: nil, group: @group, ref: @ref)
329
- 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))
330
320
  args.each do |meth|
331
321
  if meth.is_a?(Array)
332
322
  found = false
@@ -334,7 +324,7 @@ module Squared
334
324
  case val
335
325
  when Symbol
336
326
  found = true
337
- Application.attr_banner.include?(val)
327
+ banner_include?(val)
338
328
  when String
339
329
  true
340
330
  else
@@ -346,7 +336,7 @@ module Squared
346
336
  elsif meth.size == 1
347
337
  meth = meth.first
348
338
  end
349
- elsif !Application.attr_banner.include?(meth = meth.to_sym)
339
+ elsif !banner_include?(meth = meth.to_sym)
350
340
  next
351
341
  end
352
342
  data.order << meth
@@ -361,8 +351,29 @@ module Squared
361
351
  self
362
352
  end
363
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
+
364
375
  def add(path, project = nil, **kwargs, &blk)
365
- kwargs = hashdup(@withargs).update(kwargs) if @withargs
376
+ kwargs = Support.hashdup(@withargs).update(kwargs) if @withargs
366
377
  ref = kwargs.key?(:ref) ? kwargs.delete(:ref) : @ref
367
378
  kwargs[:group] = @group if @group && !kwargs.key?(:group)
368
379
  path = rootpath path
@@ -373,12 +384,20 @@ module Squared
373
384
  index += 1
374
385
  name = task_name "#{project}-#{index}"
375
386
  end
376
- proj = ((if !ref.is_a?(Class)
377
- require_project ref
378
- Application.find(ref, path: path)
379
- 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)
380
391
  ref
381
- 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)
382
401
  proj.__send__(:index_set, size)
383
402
  @project[name] = proj
384
403
  __get__(:project)[name] = proj unless kwargs[:private]
@@ -387,7 +406,7 @@ module Squared
387
406
  end
388
407
 
389
408
  def group(path, val, override: {}, **kwargs, &blk)
390
- rootpath(path).children.map! do |dir|
409
+ rootpath(path).children.map do |dir|
391
410
  next unless dir.directory?
392
411
 
393
412
  basename = dir.basename.to_s
@@ -411,6 +430,18 @@ module Squared
411
430
  self
412
431
  end
413
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
+
414
445
  def style(obj, *args, target: nil, empty: false)
415
446
  data = nil
416
447
  if target
@@ -425,7 +456,7 @@ module Squared
425
456
  if obj.is_a?(String)
426
457
  obj = begin
427
458
  JSON.parse(homepath(obj).read, { symbolize_names: true })
428
- rescue StandardError => e
459
+ rescue => e
429
460
  warn log_message(Logger::ERROR, e)
430
461
  end
431
462
  end
@@ -441,7 +472,7 @@ module Squared
441
472
  }
442
473
  data.each do |key, val|
443
474
  key = key.to_s
444
- if key.start_with?(/(\\A|\^)/) || key.match?(/(\\z|\$)\z/)
475
+ if key.start_with?('\A', '^') || key.end_with?('\z', '$')
445
476
  @describe[:replace] << [Regexp.new(key), val]
446
477
  else
447
478
  @describe[val.is_a?(Regexp) ? :pattern : :alias][key] = val
@@ -483,7 +514,7 @@ module Squared
483
514
  end
484
515
 
485
516
  def find_base(obj)
486
- Application.kind_project.find { |proj| obj.instance_of?(proj) }
517
+ @base.find { |proj| obj.instance_of?(proj) }
487
518
  end
488
519
 
489
520
  def task_name(val)
@@ -524,7 +555,7 @@ module Squared
524
555
  break
525
556
  end
526
557
  end
527
- args = split_escape(val, char: ':').map! { |s| s.gsub('\\:', ':') } if found
558
+ args = split_escape(val, char: ':').map { |s| s.gsub('\\:', ':') } if found
528
559
  end
529
560
  desc message(*args, **kwargs)
530
561
  end
@@ -541,7 +572,7 @@ module Squared
541
572
  tasks << key if obj.has?(key, baseref)
542
573
  elsif (batch = series.batch_get(key))
543
574
  obj.allref do |ref|
544
- next unless obj.has?(key, ref) && (data = batch[ref])
575
+ next unless obj.has?(key, ref, missing: series.missing?(ref, key)) && (data = batch[ref])
545
576
 
546
577
  data.each do |val|
547
578
  if (items = task_resolve(obj, val)).empty?
@@ -601,29 +632,55 @@ module Squared
601
632
  out ? message(*val) : task_desc(*val)
602
633
  end
603
634
 
604
- 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
605
639
  args.reverse_each do |val|
606
- if val && (ret = val.is_a?(Symbol) ? @script[:ref!][val] : @script[:group!][val.to_sym])
607
- 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
608
649
  end
609
650
  end
610
- @script[:ref!][:''] ||= scriptobj
651
+ ret || (target[:script] ||= scriptobj)
611
652
  end
612
653
 
613
654
  def script_get(*args, group: nil, ref: nil)
614
- data_get(*args, group: group, ref: ref, target: @script)
655
+ data_get(*args, target: @script, group: group, ref: ref)
615
656
  end
616
657
 
617
658
  def events_get(*args, group: nil, ref: nil)
618
- data_get(*args, group: group, ref: ref, target: @events)
659
+ data_get(*args, target: @events, group: group, ref: ref)
619
660
  end
620
661
 
621
662
  def banner_get(*ref, group: nil)
622
- ret = nil
623
- 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)
624
668
 
625
- ref.reverse_each { |val| return ret if (ret = @banner[:ref][val]) }
626
- @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)
627
684
  end
628
685
 
629
686
  def enabled?
@@ -646,13 +703,13 @@ module Squared
646
703
 
647
704
  def task_exclude?(key, obj = nil)
648
705
  if obj
649
- data = obj.group ? @pass[:group][obj.group] : @pass[:ref][obj.ref]
650
- 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]
651
708
  return true if blk && obj.instance_eval(&blk)
652
709
 
653
710
  key = task_join(task_localname(obj.name), key)
654
711
  end
655
- @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 }
656
713
  end
657
714
 
658
715
  def task_defined?(*key)
@@ -739,18 +796,43 @@ module Squared
739
796
 
740
797
  private
741
798
 
742
- def __build__(default: nil, **)
743
- unless task_defined?('squared:version')
744
- task 'squared:version' do
745
- puts Squared::VERSION
746
- end
747
- end
748
- if default && task_defined?(out = task_name(default))
749
- 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
750
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'
751
830
  end
752
831
 
753
832
  def __chain__(*)
833
+ return if @chain.empty?
834
+
835
+ self.closed = 'chain:begin'
754
836
  @chain.each do |key, group|
755
837
  level = []
756
838
  sync = []
@@ -861,6 +943,7 @@ module Squared
861
943
  end
862
944
  end
863
945
  end
946
+ self.closed = 'chain:end'
864
947
  end
865
948
 
866
949
  def puts(*args, **kwargs)
@@ -886,18 +969,39 @@ module Squared
886
969
  self
887
970
  end
888
971
 
889
- 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
890
976
  data.freeze
891
977
  if group
892
- 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
893
986
  elsif ref
894
- 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
895
995
  else
896
- @script[:ref!][:''] = data
996
+ target[:script] = data
897
997
  end
898
998
  end
899
999
 
900
- 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)
901
1005
  if group && target[:group].key?(key = group.to_sym)
902
1006
  target[:group][key]
903
1007
  elsif ref.is_a?(Enumerable)
@@ -914,11 +1018,11 @@ module Squared
914
1018
  end
915
1019
 
916
1020
  def require_project(ref)
917
- 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
918
1023
 
919
- name = ref.to_s
920
- Application.load_project.each do |val|
921
- 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")
922
1026
 
923
1027
  require_relative rb
924
1028
  break
@@ -928,18 +1032,19 @@ module Squared
928
1032
  def root?(path, pass: [])
929
1033
  return false unless path.directory?
930
1034
 
931
- path.each_child do |c|
932
- name = c.basename.to_s
933
- 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 }
934
1038
  return false
935
1039
  end
936
1040
  end
937
1041
  true
938
1042
  end
939
1043
 
940
- def script?(state, target: nil, pat: nil, group: nil, ref: baseref, global: false, script: true)
941
- data = script_find ref, group
942
- 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
943
1048
  if global
944
1049
  target = data[type] if target.nil?
945
1050
  pat = data[state] if pat.nil?
@@ -949,13 +1054,23 @@ module Squared
949
1054
  target && pat.is_a?(Regexp) ? Array(target).any?(pat) : pat == true
950
1055
  end
951
1056
 
1057
+ def banner_include?(val)
1058
+ Application.attr_banner.include?(val) || @banner.items.include?(val)
1059
+ end
1060
+
952
1061
  def scriptobj
953
1062
  {
954
1063
  run: nil,
955
1064
  script: nil,
956
1065
  dev: nil,
957
1066
  prod: nil,
958
- global: {},
1067
+ global: {
1068
+ script: false,
1069
+ run: false,
1070
+ doc: false,
1071
+ lint: false,
1072
+ test: false
1073
+ },
959
1074
  env: {}
960
1075
  }
961
1076
  end