squared 0.1.3 → 0.2.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +75 -1
- data/README.md +3 -0
- data/README.ruby.md +120 -40
- data/lib/squared/app.rb +0 -2
- data/lib/squared/common/base.rb +20 -14
- data/lib/squared/common/class.rb +18 -1
- data/lib/squared/common/format.rb +9 -9
- data/lib/squared/common/shell.rb +17 -8
- data/lib/squared/common/system.rb +56 -20
- data/lib/squared/common/utils.rb +5 -5
- data/lib/squared/config.rb +130 -82
- data/lib/squared/version.rb +1 -1
- data/lib/squared/workspace/application.rb +168 -51
- data/lib/squared/workspace/project/base.rb +341 -130
- data/lib/squared/workspace/project/git.rb +705 -270
- data/lib/squared/workspace/project/node.rb +174 -100
- data/lib/squared/workspace/project/python.rb +176 -61
- data/lib/squared/workspace/project/ruby.rb +337 -171
- data/lib/squared/workspace/repo.rb +35 -46
- data/lib/squared/workspace/series.rb +16 -14
- metadata +2 -2
@@ -14,7 +14,7 @@ module Squared
|
|
14
14
|
include Utils
|
15
15
|
include Rake::DSL
|
16
16
|
|
17
|
-
VAR_SET = %i[parent global envname dependfile theme run script env].freeze
|
17
|
+
VAR_SET = %i[parent global envname dependfile theme run script env pass].freeze
|
18
18
|
SEM_VER = /\b(\d+)(?:(\.)(\d+))?(?:(\.)(\d+)(\S+)?)?\b/.freeze
|
19
19
|
private_constant :VAR_SET, :SEM_VER
|
20
20
|
|
@@ -50,18 +50,17 @@ module Squared
|
|
50
50
|
end
|
51
51
|
end
|
52
52
|
|
53
|
-
@@tasks = {
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
}
|
53
|
+
(@@tasks = {})[ref] = {
|
54
|
+
'graph' => %i[run print].freeze
|
55
|
+
}.freeze
|
56
|
+
@@task_desc = Rake::TaskManager.record_task_metadata
|
58
57
|
@@print_order = 0
|
59
58
|
|
60
|
-
attr_reader :name, :project, :workspace, :path, :
|
61
|
-
:
|
59
|
+
attr_reader :name, :project, :workspace, :path, :theme, :exception, :pipe, :verbose,
|
60
|
+
:group, :parent, :dependfile
|
62
61
|
|
63
62
|
def initialize(workspace, path, name, *, group: nil, graph: nil, pass: nil, exclude: nil,
|
64
|
-
common: ARG[:COMMON], **kwargs)
|
63
|
+
first: {}, last: {}, error: {}, common: ARG[:COMMON], **kwargs)
|
65
64
|
@path = path
|
66
65
|
@workspace = workspace
|
67
66
|
@name = name.to_s.freeze
|
@@ -72,6 +71,7 @@ module Squared
|
|
72
71
|
@test = kwargs[:test]
|
73
72
|
@copy = kwargs[:copy]
|
74
73
|
@clean = kwargs[:clean]
|
74
|
+
@version = kwargs[:version]
|
75
75
|
@exception = kwargs.key?(:exception) ? env_bool(kwargs[:exception]) : workspace.exception
|
76
76
|
@pipe = kwargs.key?(:pipe) ? env_pipe(kwargs[:pipe]) : workspace.pipe
|
77
77
|
@verbose = kwargs.key?(:verbose) ? kwargs[:verbose] : workspace.verbose
|
@@ -88,8 +88,13 @@ module Squared
|
|
88
88
|
@graph = if graph
|
89
89
|
as_a(graph, workspace.prefix ? ->(val) { workspace.task_name(val).to_sym } : :to_sym).freeze
|
90
90
|
end
|
91
|
-
@pass = (pass ? as_a(pass
|
91
|
+
@pass = (pass ? as_a(pass) : []).freeze
|
92
92
|
@exclude = (exclude ? as_a(exclude, :to_sym) : []).freeze
|
93
|
+
@events = {
|
94
|
+
first: first,
|
95
|
+
last: last,
|
96
|
+
error: error
|
97
|
+
}
|
93
98
|
@envname = @name.gsub(/[^\w]+/, '_').upcase.freeze
|
94
99
|
@desc = (@name.include?(':') ? @name.split(':').join(ARG[:SPACE]) : @name).freeze
|
95
100
|
@parent = nil
|
@@ -115,6 +120,7 @@ module Squared
|
|
115
120
|
@clean = @script[:clean] if @clean.nil?
|
116
121
|
@exclude = @script[:exclude] if @exclude.empty? && @script.key?(:exclude)
|
117
122
|
end
|
123
|
+
initialize_events(ref, **kwargs)
|
118
124
|
initialize_logger(**kwargs)
|
119
125
|
return if @output[0] == false
|
120
126
|
|
@@ -147,6 +153,12 @@ module Squared
|
|
147
153
|
end
|
148
154
|
end
|
149
155
|
|
156
|
+
def initialize_events(ref, **)
|
157
|
+
return unless (events = @workspace.events_get(group: @group, ref: ref))
|
158
|
+
|
159
|
+
events.each { |task, data| data.each { |ev, blk| (@events[ev] ||= {})[task] ||= blk } }
|
160
|
+
end
|
161
|
+
|
150
162
|
def initialize_logger(log: nil, **)
|
151
163
|
return if @log
|
152
164
|
|
@@ -193,11 +205,13 @@ module Squared
|
|
193
205
|
begin
|
194
206
|
data = JSON.parse(val)
|
195
207
|
raise_error('invalid JSON object', val, hint: "#{prefix}_ENV") unless data.is_a?(Hash)
|
196
|
-
@output[2] = data
|
197
208
|
rescue StandardError => e
|
198
209
|
log.warn e
|
210
|
+
else
|
211
|
+
@output[2] = data
|
199
212
|
end
|
200
213
|
end
|
214
|
+
@version = val if (val = env('BUILD', suffix: 'VERSION'))
|
201
215
|
return unless (val = env('BUILD', strict: true))
|
202
216
|
|
203
217
|
@global = false
|
@@ -214,49 +228,37 @@ module Squared
|
|
214
228
|
Base.ref
|
215
229
|
end
|
216
230
|
|
217
|
-
def populate(
|
218
|
-
|
219
|
-
|
220
|
-
next unless workspace.task_include?(self, key)
|
221
|
-
|
222
|
-
s = workspace.series.name_get(key)
|
223
|
-
unless workspace.task_defined?(name, s)
|
224
|
-
desc message(@desc, s)
|
225
|
-
task s do
|
226
|
-
__send__(key)
|
227
|
-
end
|
228
|
-
end
|
229
|
-
next if (items = @children.select { |item| workspace.task_include?(item, key) }).empty?
|
230
|
-
|
231
|
-
desc message(@desc, s, 'workspace')
|
232
|
-
task task_join(s, 'workspace') => items.map { |item| task_join(item.name, s) }
|
233
|
-
end
|
234
|
-
next unless ref?(Base.ref)
|
231
|
+
def populate(keys, **)
|
232
|
+
task_build keys
|
233
|
+
return unless ref?(Base.ref)
|
235
234
|
|
235
|
+
namespace name do
|
236
236
|
@@tasks[Base.ref].each do |action, flags|
|
237
|
+
next if @pass.include?(action)
|
238
|
+
|
237
239
|
namespace action do
|
238
240
|
flags.each do |flag|
|
239
241
|
case action
|
240
|
-
when
|
242
|
+
when 'graph'
|
241
243
|
next unless graph?
|
242
244
|
|
243
245
|
check = lambda do |args|
|
244
246
|
next args if (args = args.to_a).empty?
|
245
247
|
|
246
|
-
|
248
|
+
param_guard(action, flag, args: args.reject { |val| name == val.to_s })
|
247
249
|
end
|
248
250
|
|
249
|
-
|
251
|
+
format_desc action, flag, 'project*'
|
250
252
|
if flag == :run
|
251
|
-
task flag
|
253
|
+
task flag do |_, args|
|
252
254
|
graph check.(args)
|
253
255
|
end
|
254
256
|
else
|
255
|
-
task flag
|
257
|
+
task flag do |_, args|
|
256
258
|
out, done = graph(check.(args), out: [])
|
257
259
|
out.map! do |val|
|
258
260
|
done.each_with_index do |proj, i|
|
259
|
-
next unless
|
261
|
+
next unless Regexp.new(" #{Regexp.escape(proj.name)}(?:@\\d|\\z)") =~ val
|
260
262
|
|
261
263
|
val += " (#{i.succ})"
|
262
264
|
break
|
@@ -277,6 +279,10 @@ module Squared
|
|
277
279
|
end
|
278
280
|
end
|
279
281
|
|
282
|
+
def generate(keys, **)
|
283
|
+
task_build keys
|
284
|
+
end
|
285
|
+
|
280
286
|
def with(**kwargs, &blk)
|
281
287
|
@withargs = kwargs.empty? ? nil : kwargs
|
282
288
|
if block_given?
|
@@ -329,7 +335,19 @@ module Squared
|
|
329
335
|
self
|
330
336
|
end
|
331
337
|
|
332
|
-
def
|
338
|
+
def inject(obj, *args, **kwargs, &blk)
|
339
|
+
return self unless enabled?
|
340
|
+
|
341
|
+
out = obj.link(self, *args, **kwargs, &blk) if obj.respond_to?(:link)
|
342
|
+
if !out
|
343
|
+
warn log_message(:warn, 'link not compatible', subject: obj.to_s, hint: name)
|
344
|
+
elsif out.respond_to?(:build)
|
345
|
+
out.build
|
346
|
+
end
|
347
|
+
self
|
348
|
+
end
|
349
|
+
|
350
|
+
def build(*args, from: :build, sync: invoked_sync?('build'), **)
|
333
351
|
if args.empty?
|
334
352
|
cmd, opts, var, flags = @output
|
335
353
|
banner = verbose == 1
|
@@ -350,35 +368,46 @@ module Squared
|
|
350
368
|
else
|
351
369
|
return unless respond_to?(:compose)
|
352
370
|
|
353
|
-
cmd = compose(opts, flags, script: true)
|
371
|
+
cmd = compose(opts, flags, from: from, script: true)
|
354
372
|
end
|
355
|
-
run(cmd, var, banner: banner, sync: sync)
|
373
|
+
run(cmd, var, from: from, banner: banner, sync: sync)
|
356
374
|
end
|
357
375
|
|
358
376
|
def depend(*, sync: invoked_sync?('depend'), **)
|
359
|
-
|
377
|
+
return unless @depend
|
378
|
+
|
379
|
+
run(@depend, from: :depend, sync: sync)
|
360
380
|
end
|
361
381
|
|
362
382
|
def copy(*, sync: invoked_sync?('copy'), **)
|
363
|
-
|
383
|
+
return unless @copy
|
384
|
+
|
385
|
+
run_s(@copy, from: :copy, sync: sync)
|
364
386
|
end
|
365
387
|
|
366
388
|
def doc(*, sync: invoked_sync?('doc'), **)
|
367
|
-
|
389
|
+
return unless @doc
|
390
|
+
|
391
|
+
build(@doc, from: :doc, sync: sync)
|
368
392
|
end
|
369
393
|
|
370
394
|
def test(*, sync: invoked_sync?('test'), **)
|
371
|
-
|
395
|
+
return unless @test
|
396
|
+
|
397
|
+
build(@test, from: :test, sync: sync)
|
372
398
|
end
|
373
399
|
|
374
|
-
def clean(
|
400
|
+
def clean(*, sync: invoked_sync?('clean'), **)
|
401
|
+
return unless @clean
|
402
|
+
|
403
|
+
on :first, :clean
|
375
404
|
case @clean
|
376
405
|
when String
|
377
|
-
run_s(@clean, sync:
|
406
|
+
run_s(@clean, from: :clean, sync: sync)
|
378
407
|
when Enumerable
|
379
408
|
as_a(@clean).each do |val|
|
380
|
-
if
|
381
|
-
dir = Pathname.new(val)
|
409
|
+
if val =~ %r{[\\/]$}
|
410
|
+
dir = Pathname.new(val.to_s)
|
382
411
|
dir = basepath(dir) unless dir.absolute?
|
383
412
|
next unless dir.directory?
|
384
413
|
|
@@ -396,6 +425,7 @@ module Squared
|
|
396
425
|
end
|
397
426
|
end
|
398
427
|
end
|
428
|
+
on :last, :clean
|
399
429
|
end
|
400
430
|
|
401
431
|
def graph(start = [], tasks = nil, sync: invoked_sync?('graph'), pass: [], out: nil)
|
@@ -411,9 +441,37 @@ module Squared
|
|
411
441
|
end
|
412
442
|
pass.concat(split_escape(val)) if (val = env('GRAPH_PASS', strict: true))
|
413
443
|
data = graph_collect(self, start)
|
414
|
-
|
415
|
-
|
416
|
-
|
444
|
+
unless out
|
445
|
+
data[name] << self
|
446
|
+
on :first, :graph
|
447
|
+
end
|
448
|
+
begin
|
449
|
+
done = graph_branch(self, data, tasks, out, sync: sync, pass: pass)
|
450
|
+
rescue StandardError => e
|
451
|
+
ret = on(:error, :graph, e)
|
452
|
+
raise unless ret == true
|
453
|
+
end
|
454
|
+
if out
|
455
|
+
[out, done]
|
456
|
+
else
|
457
|
+
on :last, :graph
|
458
|
+
end
|
459
|
+
end
|
460
|
+
|
461
|
+
def first(key, *args, **kwargs, &blk)
|
462
|
+
event(:first, key, *args, **kwargs, &blk)
|
463
|
+
end
|
464
|
+
|
465
|
+
def last(key, *args, **kwargs, &blk)
|
466
|
+
event(:last, key, *args, **kwargs, &blk)
|
467
|
+
end
|
468
|
+
|
469
|
+
def error(key, *args, **kwargs, &blk)
|
470
|
+
event(:error, key, *args, **kwargs, &blk)
|
471
|
+
end
|
472
|
+
|
473
|
+
def event(name, key, *args, **kwargs, &blk)
|
474
|
+
(@events[name.to_sym] ||= {})[key.to_sym] = [block_given? ? [blk] + args : args, kwargs]
|
417
475
|
end
|
418
476
|
|
419
477
|
def variable_set(key, *val, **kwargs)
|
@@ -444,7 +502,7 @@ module Squared
|
|
444
502
|
end
|
445
503
|
end
|
446
504
|
|
447
|
-
def enabled?(ref = nil)
|
505
|
+
def enabled?(ref = nil, **)
|
448
506
|
return false if ref && !ref?(ref)
|
449
507
|
|
450
508
|
path.directory? && !path.empty?
|
@@ -500,7 +558,13 @@ module Squared
|
|
500
558
|
@prod != false && workspace.prod?(pat: @prod, **scriptargs)
|
501
559
|
end
|
502
560
|
|
503
|
-
def
|
561
|
+
def task_include?(key, ref = nil)
|
562
|
+
workspace.task_include?(self, key, ref) && !@pass.include?(key.to_s)
|
563
|
+
end
|
564
|
+
|
565
|
+
def version(*)
|
566
|
+
@version
|
567
|
+
end
|
504
568
|
|
505
569
|
def dependtype(*)
|
506
570
|
@dependindex ? @dependindex.succ : 0
|
@@ -528,6 +592,10 @@ module Squared
|
|
528
592
|
ret
|
529
593
|
end
|
530
594
|
|
595
|
+
def localname
|
596
|
+
workspace.task_localname(name)
|
597
|
+
end
|
598
|
+
|
531
599
|
def inspect
|
532
600
|
"#<#{self.class}: #{name} => #{self}>"
|
533
601
|
end
|
@@ -546,11 +614,12 @@ module Squared
|
|
546
614
|
puts_oe(*args, pipe: pipe)
|
547
615
|
end
|
548
616
|
|
549
|
-
def run(cmd = @session, var = nil, exception: @exception, sync: true, banner: true, chdir: path, **)
|
617
|
+
def run(cmd = @session, var = nil, exception: @exception, sync: true, banner: true, chdir: path, from: nil, **)
|
550
618
|
cmd = session_done(cmd)
|
551
619
|
log.info cmd
|
620
|
+
on :first, from if from
|
552
621
|
begin
|
553
|
-
if cmd
|
622
|
+
if cmd.match?(/\A[^:]+:[^:]/) && workspace.task_defined?(cmd)
|
554
623
|
log.warn "ENV was discarded: #{var}" if var
|
555
624
|
task_invoke(cmd, exception: exception, warning: warning?)
|
556
625
|
else
|
@@ -560,16 +629,27 @@ module Squared
|
|
560
629
|
end
|
561
630
|
rescue StandardError => e
|
562
631
|
log.error e
|
563
|
-
|
632
|
+
ret = on(:error, from, e) if from
|
633
|
+
raise unless ret == true
|
634
|
+
else
|
635
|
+
on :last, from if from
|
564
636
|
end
|
565
637
|
end
|
566
638
|
|
567
|
-
def run_s(*cmd, env: nil, banner: verbose != false, **kwargs)
|
568
|
-
|
639
|
+
def run_s(*cmd, env: nil, sync: true, banner: verbose != false, from: nil, **kwargs)
|
640
|
+
on :first, from if from
|
641
|
+
begin
|
642
|
+
cmd.each { |val| run(val, env, sync: sync, banner: banner, **kwargs) }
|
643
|
+
rescue StandardError => e
|
644
|
+
ret = on(:error, from, e) if from
|
645
|
+
raise unless ret == true
|
646
|
+
end
|
647
|
+
on :last, from if from
|
569
648
|
end
|
570
649
|
|
571
|
-
def
|
572
|
-
|
650
|
+
def graph_branch(target, data, tasks = nil, out = nil, sync: true, pass: [], done: [], depth: 0, last: false,
|
651
|
+
single: false)
|
652
|
+
tag = ->(proj) { "#{proj.name}#{SEM_VER =~ proj.version ? "@#{proj.version}" : ''}" }
|
573
653
|
check = ->(deps) { deps.reject { |val| done.include?(val) } }
|
574
654
|
dedupe = lambda do |name|
|
575
655
|
next [] unless (ret = data[name])
|
@@ -581,6 +661,7 @@ module Squared
|
|
581
661
|
end
|
582
662
|
ret
|
583
663
|
end
|
664
|
+
start = target.name
|
584
665
|
if depth == 0
|
585
666
|
items = check.(dedupe.(start))
|
586
667
|
single = items.size == 1
|
@@ -589,24 +670,24 @@ module Squared
|
|
589
670
|
end
|
590
671
|
if out
|
591
672
|
a, b, c, d, e = ARG[:GRAPH]
|
673
|
+
f = tag.(target)
|
592
674
|
out << case depth
|
593
675
|
when 0
|
594
|
-
|
676
|
+
f
|
595
677
|
when 1
|
596
678
|
if items.empty?
|
597
|
-
"#{d}#{b * 4} #{
|
679
|
+
"#{d}#{b * 4} #{f}"
|
598
680
|
else
|
599
|
-
"#{last ? d : c}#{b * 3}#{e} #{
|
681
|
+
"#{last ? d : c}#{b * 3}#{e} #{f}"
|
600
682
|
end
|
601
683
|
else
|
602
|
-
"#{single ? ' ' : a}#{' ' * (depth - 1)}#{last ? d : c}#{b * 3}#{items.empty? ? b : e} #{
|
684
|
+
"#{single ? ' ' : a}#{' ' * (depth - 1)}#{last ? d : c}#{b * 3}#{items.empty? ? b : e} #{f}"
|
603
685
|
end
|
604
686
|
end
|
605
687
|
items.each_with_index do |proj, i|
|
606
688
|
next if done.include?(proj)
|
607
689
|
|
608
|
-
|
609
|
-
t = dedupe.(s)
|
690
|
+
t = dedupe.(proj.name)
|
610
691
|
j = if out
|
611
692
|
if i == items.size - 1 || check.(post = items[i + 1..-1]).empty?
|
612
693
|
true
|
@@ -614,35 +695,35 @@ module Squared
|
|
614
695
|
post.reject { |pr| t.include?(pr) }.empty?
|
615
696
|
end
|
616
697
|
end
|
617
|
-
unless start ==
|
618
|
-
|
619
|
-
|
698
|
+
unless start == proj.name || (none = check.(t).empty?)
|
699
|
+
graph_branch(proj, data, tasks, out, sync: sync, pass: pass, done: done, depth: depth.succ,
|
700
|
+
single: single, last: j == true)
|
620
701
|
end
|
621
702
|
if !out
|
622
|
-
|
703
|
+
if !tasks && (script = workspace.script_get(:graph, group: proj.group, ref: proj.allref))
|
623
704
|
group = script[:graph]
|
624
705
|
end
|
625
706
|
(tasks || group || (dev? ? ['build', 'copy'] : ['depend', 'build'])).each do |meth|
|
626
707
|
next if pass.include?(meth)
|
627
708
|
|
628
|
-
if workspace.task_defined?(cmd = task_join(
|
709
|
+
if workspace.task_defined?(cmd = task_join(proj.name, meth))
|
629
710
|
run(cmd, sync: false, banner: false)
|
630
|
-
elsif proj.has?(meth)
|
711
|
+
elsif proj.has?(meth, tasks || group ? nil : workspace.baseref)
|
631
712
|
proj.__send__(meth.to_sym, sync: sync)
|
632
713
|
end
|
633
714
|
end
|
634
715
|
elsif none
|
635
716
|
a, b, c, d = ARG[:GRAPH]
|
636
717
|
out << if depth == 0
|
637
|
-
"#{i == items.size - 1 ? d : c}#{b * 4} #{
|
718
|
+
"#{i == items.size - 1 ? d : c}#{b * 4} #{tag.(proj)}"
|
638
719
|
else
|
639
|
-
|
720
|
+
s = ''.dup
|
640
721
|
k = 0
|
641
722
|
while k < depth
|
642
|
-
|
723
|
+
s += "#{(last && !j) || (j && k > 0 && k == depth - 1) || single ? ' ' : a} "
|
643
724
|
k += 1
|
644
725
|
end
|
645
|
-
|
726
|
+
s + "#{j ? d : c}#{b * 3} #{tag.(proj)}"
|
646
727
|
end
|
647
728
|
end
|
648
729
|
done << proj
|
@@ -653,11 +734,20 @@ module Squared
|
|
653
734
|
def graph_collect(target, start = [], data: {})
|
654
735
|
deps = []
|
655
736
|
(start.empty? ? target.instance_variable_get(:@graph) : start)&.each do |val|
|
656
|
-
|
737
|
+
if (obj = workspace.find(name: val))
|
738
|
+
next unless obj.enabled?
|
657
739
|
|
658
|
-
|
659
|
-
|
660
|
-
|
740
|
+
items = [obj]
|
741
|
+
else
|
742
|
+
items = workspace.find(group: val, ref: val.to_sym)
|
743
|
+
end
|
744
|
+
items.each do |proj|
|
745
|
+
graph_collect(proj, data: data) if proj.graph? && !data.key?(proj.name)
|
746
|
+
next if (objs = data.fetch(proj.name, [])).include?(target)
|
747
|
+
|
748
|
+
deps << proj
|
749
|
+
deps += objs
|
750
|
+
end
|
661
751
|
end
|
662
752
|
data[target.name] = deps.uniq.reject { |proj| proj == target }
|
663
753
|
data
|
@@ -678,15 +768,22 @@ module Squared
|
|
678
768
|
ret.empty? || (ignore && as_a(ignore).any? { |val| ret == val.to_s }) ? default : ret
|
679
769
|
end
|
680
770
|
|
681
|
-
def session(*cmd, prefix: cmd.first)
|
682
|
-
|
683
|
-
|
771
|
+
def session(*cmd, prefix: cmd.first, main: true, options: true)
|
772
|
+
prefix = prefix.to_s.upcase
|
773
|
+
if (val = PATH[prefix] || PATH[prefix.to_sym])
|
774
|
+
cmd[0] = shell_quote(val, force: false)
|
684
775
|
end
|
685
|
-
|
776
|
+
split_escape(val).each { |opt| cmd << fill_option(opt) } if options && (val = env("#{prefix}_OPTIONS"))
|
777
|
+
ret = JoinSet.new(cmd.flatten(1))
|
778
|
+
main ? @session = ret : ret
|
779
|
+
end
|
780
|
+
|
781
|
+
def session_output(*cmd, **kwargs)
|
782
|
+
session(*cmd, main: false, options: false, **kwargs)
|
686
783
|
end
|
687
784
|
|
688
785
|
def session_done(cmd)
|
689
|
-
return cmd
|
786
|
+
return cmd unless cmd.respond_to?(:done)
|
690
787
|
|
691
788
|
raise_error('no args were added', hint: cmd.first || name) unless cmd.size > 1
|
692
789
|
@session = nil if cmd == @session
|
@@ -703,6 +800,40 @@ module Squared
|
|
703
800
|
nil
|
704
801
|
end
|
705
802
|
|
803
|
+
def option_partition(opts, list, target: @session, no: [], first: false, pass: ['='])
|
804
|
+
out = []
|
805
|
+
bare = []
|
806
|
+
reg, list = list.partition do |val|
|
807
|
+
next unless (n = val.index('='))
|
808
|
+
|
809
|
+
bare << val[0..n - 1] if val.end_with?('?')
|
810
|
+
true
|
811
|
+
end
|
812
|
+
list += bare
|
813
|
+
no = no.map { |val| (n = val.index('=')) ? val[0..n - 1] : val }
|
814
|
+
found = false
|
815
|
+
opts.each do |opt|
|
816
|
+
next out << opt if found
|
817
|
+
|
818
|
+
if list.include?(opt)
|
819
|
+
target << (opt.size == 1 ? "-#{opt}" : "--#{opt}")
|
820
|
+
elsif opt.start_with?('no-') && no.include?(name = opt[3..-1])
|
821
|
+
target << "--no-#{name}"
|
822
|
+
else
|
823
|
+
out << opt
|
824
|
+
found = true if first && pass.none? { |val| opt.include?(val) }
|
825
|
+
end
|
826
|
+
end
|
827
|
+
pat = Regexp.new("^(#{reg.map { |val| val[0..val.index('=') - 1] }.join('|')})=(.+)$")
|
828
|
+
[out, pat]
|
829
|
+
end
|
830
|
+
|
831
|
+
def option_clear(params, target: @session, **kwargs)
|
832
|
+
kwargs[:subject] ||= target&.first
|
833
|
+
kwargs[:hint] ||= 'not used'
|
834
|
+
warn log_message(:warn, params.join(', '), **kwargs) unless params.empty?
|
835
|
+
end
|
836
|
+
|
706
837
|
def print_item(*val)
|
707
838
|
puts if @@print_order > 0 && verbose && !stdin?
|
708
839
|
@@print_order += 1
|
@@ -715,7 +846,7 @@ module Squared
|
|
715
846
|
if styles.any? { |s| s.to_s.end_with?('!') }
|
716
847
|
pad = 1
|
717
848
|
elsif !client && styles.size <= 1
|
718
|
-
styles =
|
849
|
+
styles = [:bold] + styles
|
719
850
|
end
|
720
851
|
end
|
721
852
|
n = Project.max_width(lines)
|
@@ -748,32 +879,33 @@ module Squared
|
|
748
879
|
ret.join("\n")
|
749
880
|
end
|
750
881
|
|
751
|
-
def format_desc(action, flag, opts = nil,
|
752
|
-
return unless
|
882
|
+
def format_desc(action, flag, opts = nil, **kwargs)
|
883
|
+
return unless @@task_desc
|
753
884
|
|
754
|
-
|
755
|
-
|
756
|
-
|
757
|
-
out << action
|
758
|
-
else
|
759
|
-
flag = action
|
760
|
-
end
|
761
|
-
req &&= opts ? "#{req}," : "[#{req}]"
|
762
|
-
out << (opts ? "#{flag}[#{req}#{opts}]" : "#{flag}#{req}")
|
763
|
-
message(*out)
|
885
|
+
ret = [@desc, action]
|
886
|
+
ret << flag if flag
|
887
|
+
workspace.format_desc(ret, opts, **kwargs)
|
764
888
|
end
|
765
889
|
|
766
890
|
def format_banner(cmd, banner: true)
|
767
891
|
return unless banner && ARG[:BANNER]
|
768
892
|
|
769
893
|
if (data = workspace.banner_get(*@ref, group: group))
|
894
|
+
return if data.empty?
|
895
|
+
|
770
896
|
client = true
|
771
897
|
else
|
772
|
-
data = { command: true, order:
|
898
|
+
data = { command: true, order: [:path], styles: theme[:banner], border: theme[:border] }
|
773
899
|
end
|
774
900
|
if verbose
|
775
901
|
out = []
|
776
|
-
|
902
|
+
if data[:command]
|
903
|
+
if /\A(?:"((?:[^"]|(?<=\\)")+)"|'((?:[^']|(?<=\\)')+)'|(\S+)) /.match(cmd)
|
904
|
+
path = $3 || $2 || $1
|
905
|
+
cmd = cmd.sub(path, File.basename(path).upcase)
|
906
|
+
end
|
907
|
+
out << cmd
|
908
|
+
end
|
777
909
|
data[:order].each do |val|
|
778
910
|
if val.is_a?(Array)
|
779
911
|
s = ' '
|
@@ -803,14 +935,15 @@ module Squared
|
|
803
935
|
def format_list(items, cmd, type, grep: [], from: nil, each: nil)
|
804
936
|
reg = grep.map { |val| Regexp.new(val) }
|
805
937
|
out = []
|
806
|
-
|
807
|
-
pad =
|
938
|
+
unless items.empty?
|
939
|
+
pad = items.size.to_s.size
|
808
940
|
items.each_with_index do |val, i|
|
809
|
-
next unless reg.empty? || reg.any? { |pat|
|
941
|
+
next unless reg.empty? || reg.any? { |pat| val[0] =~ pat }
|
810
942
|
|
811
943
|
out << "#{(i + 1).to_s.rjust(pad)}. #{each ? each.(val) : val[0]}"
|
812
944
|
end
|
813
945
|
end
|
946
|
+
sub = [headerstyle]
|
814
947
|
if out.empty?
|
815
948
|
out = ["No #{type} were found:", '']
|
816
949
|
unless grep.empty?
|
@@ -820,54 +953,81 @@ module Squared
|
|
820
953
|
end
|
821
954
|
if from
|
822
955
|
out << from
|
823
|
-
pat = /\A(#{Regexp.escape(
|
956
|
+
pat = /\A(#{Regexp.escape(from)})(.*)\z/
|
824
957
|
end
|
825
958
|
else
|
826
|
-
pat = /\A(\s*\d+\.)(.+)\z/
|
959
|
+
pat = /\A(\s*\d+\.)(.+)\z/
|
960
|
+
unless grep.empty?
|
961
|
+
footer = "#{out.size} found"
|
962
|
+
sub << { pat: /\A(\d+)( .+)\z/, styles: theme[:inline] }
|
963
|
+
end
|
827
964
|
end
|
828
|
-
sub = [headerstyle]
|
829
965
|
sub << { pat: pat, styles: theme[:active] } if pat
|
830
|
-
emphasize(out, title: task_join(name, cmd), border: borderstyle, sub: sub)
|
966
|
+
emphasize(out, title: task_join(name, cmd), border: borderstyle, sub: sub, footer: footer, right: true)
|
831
967
|
end
|
832
968
|
|
833
969
|
def empty_status(msg, title, obj, always: false)
|
834
970
|
"#{msg}#{!always && (!obj || obj == 0 || obj.to_s.empty?) ? '' : message(hint: message(title, obj.to_s))}"
|
835
971
|
end
|
836
972
|
|
837
|
-
def append_repeat(flag, opts)
|
838
|
-
opts.each { |val|
|
973
|
+
def append_repeat(flag, opts, target: @session)
|
974
|
+
opts.each { |val| target << shell_option(flag, val, quote: true) }
|
839
975
|
end
|
840
976
|
|
841
|
-
def append_value(opts, delim: false, escape: true)
|
842
|
-
|
843
|
-
|
977
|
+
def append_value(opts, target: @session, delim: false, escape: true)
|
978
|
+
return if opts.empty?
|
979
|
+
|
980
|
+
target << '--' if delim
|
981
|
+
opts.each { |val| target << (escape ? shell_escape(val) : shell_quote(val)) }
|
844
982
|
end
|
845
983
|
|
846
|
-
def
|
984
|
+
def append_hash(opts, target: @session)
|
985
|
+
out = target.to_s
|
986
|
+
opts.each do |key, val|
|
987
|
+
key = key.to_s
|
988
|
+
key = "--#{key}" unless key[0] == '-'
|
989
|
+
next if out =~ Regexp.new(" #{key}(?: |=|$)")
|
990
|
+
|
991
|
+
case val
|
992
|
+
when String
|
993
|
+
append_repeat(key, [val], target: target)
|
994
|
+
when Array
|
995
|
+
append_repeat(key, val, target: target)
|
996
|
+
when Numeric
|
997
|
+
target << (key + (key.start_with?('--') ? '=' : '') + val)
|
998
|
+
when false
|
999
|
+
target << key.sub(/^--(?!no-)/, '--no-')
|
1000
|
+
else
|
1001
|
+
target << key
|
1002
|
+
end
|
1003
|
+
end
|
1004
|
+
end
|
1005
|
+
|
1006
|
+
def append_first(list, target: @session, flag: true, equals: false, quote: false, escape: true, **kwargs)
|
847
1007
|
list.each do |opt|
|
848
1008
|
next unless (val = option(opt, **kwargs))
|
849
1009
|
|
850
|
-
return
|
851
|
-
|
852
|
-
|
853
|
-
|
854
|
-
|
1010
|
+
return target << (if flag
|
1011
|
+
shell_option(opt, equals ? val : nil, quote: quote, escape: escape)
|
1012
|
+
else
|
1013
|
+
shell_quote(val)
|
1014
|
+
end)
|
855
1015
|
end
|
856
1016
|
end
|
857
1017
|
|
858
|
-
def append_option(list, equals: false, quote: false, **kwargs)
|
1018
|
+
def append_option(list, target: @session, equals: false, quote: false, escape: true, **kwargs)
|
859
1019
|
list.each do |flag|
|
860
1020
|
next unless (val = option(flag, **kwargs))
|
861
1021
|
|
862
|
-
|
1022
|
+
target << shell_option(flag, equals ? val : nil, quote: quote, escape: escape)
|
863
1023
|
end
|
864
1024
|
end
|
865
1025
|
|
866
|
-
def append_nocolor(
|
867
|
-
|
1026
|
+
def append_nocolor(target: @session)
|
1027
|
+
target << '--no-color' if !ARG[:COLOR] || stdin? || option('no-color', ignore: false)
|
868
1028
|
end
|
869
1029
|
|
870
|
-
def
|
1030
|
+
def param_guard(action, flag, args: nil, key: nil, pat: nil)
|
871
1031
|
if args && key
|
872
1032
|
val = args[key]
|
873
1033
|
return val unless val.nil? || (pat && !val.match?(pat))
|
@@ -918,17 +1078,48 @@ module Squared
|
|
918
1078
|
ret && !ret.empty? ? ret : [val]
|
919
1079
|
end
|
920
1080
|
|
921
|
-
def
|
1081
|
+
def colormap(val)
|
1082
|
+
val.compact.map { |s| color(s) }.flatten
|
1083
|
+
end
|
1084
|
+
|
1085
|
+
def on(event, action, *args, **kwargs)
|
1086
|
+
return unless (obj = @events[event][action])
|
1087
|
+
|
1088
|
+
if obj.is_a?(Array) && obj[1].is_a?(Hash)
|
1089
|
+
opts = kwargs.empty? ? obj[1] : obj[1].merge(kwargs)
|
1090
|
+
target = obj[0]
|
1091
|
+
else
|
1092
|
+
opts = kwargs
|
1093
|
+
target = obj
|
1094
|
+
end
|
1095
|
+
as_a(target, flat: true).each do |cmd|
|
1096
|
+
case cmd
|
1097
|
+
when Proc, Method
|
1098
|
+
cmd.call(*args, **opts)
|
1099
|
+
when String
|
1100
|
+
run_s(cmd, **opts)
|
1101
|
+
end
|
1102
|
+
end
|
1103
|
+
end
|
1104
|
+
|
1105
|
+
def pwd_set(done = nil, pass: false, from: nil, &blk)
|
922
1106
|
pwd = Pathname.pwd
|
923
1107
|
if block_given?
|
924
|
-
|
925
|
-
|
1108
|
+
begin
|
1109
|
+
if path == pwd || pass == true || (pass.is_a?(String) && semscan(pass).join >= RUBY_VERSION)
|
1110
|
+
ret = instance_eval(&blk)
|
1111
|
+
else
|
1112
|
+
Dir.chdir(path)
|
1113
|
+
ret = instance_eval(&blk)
|
1114
|
+
Dir.chdir(pwd)
|
1115
|
+
end
|
1116
|
+
rescue StandardError => e
|
1117
|
+
log.error e
|
1118
|
+
ret = on(:error, from, e) if from
|
1119
|
+
raise if exception && ret != true
|
926
1120
|
else
|
927
|
-
|
928
|
-
ret = instance_eval(&blk)
|
929
|
-
Dir.chdir(pwd)
|
1121
|
+
ret
|
930
1122
|
end
|
931
|
-
ret
|
932
1123
|
elsif @pwd == pwd
|
933
1124
|
@pwd = nil
|
934
1125
|
pwd unless done
|
@@ -973,6 +1164,26 @@ module Squared
|
|
973
1164
|
end
|
974
1165
|
end
|
975
1166
|
|
1167
|
+
def task_build(keys)
|
1168
|
+
namespace name do
|
1169
|
+
keys.each do |key|
|
1170
|
+
next unless workspace.task_include?(self, key)
|
1171
|
+
|
1172
|
+
action = workspace.series.name_get(key)
|
1173
|
+
unless @pass.include?(key.to_s) || workspace.task_defined?(name, action)
|
1174
|
+
workspace.task_desc(@desc, action)
|
1175
|
+
task action do
|
1176
|
+
__send__(key)
|
1177
|
+
end
|
1178
|
+
end
|
1179
|
+
next if (items = @children.select { |item| item.task_include?(key) }).empty?
|
1180
|
+
|
1181
|
+
workspace.task_desc(@desc, action, 'workspace')
|
1182
|
+
task task_join(action, 'workspace') => items.map { |item| task_join(item.name, action) }
|
1183
|
+
end
|
1184
|
+
end
|
1185
|
+
end
|
1186
|
+
|
976
1187
|
def projectpath?(val)
|
977
1188
|
Pathname.new(val).absolute? ? val.to_s.start_with?(File.join(path, '')) : !val.to_s.start_with?('..')
|
978
1189
|
end
|
@@ -1001,7 +1212,7 @@ module Squared
|
|
1001
1212
|
end
|
1002
1213
|
|
1003
1214
|
def invoked_sync?(action, val = nil)
|
1004
|
-
return true if
|
1215
|
+
return true if val || from_sync?(ac = workspace.task_name(action))
|
1005
1216
|
return val if group && !(val = from_sync?(ac, group)).nil?
|
1006
1217
|
return val if (base = workspace.find_base(self)) && !(val = from_sync?(ac, base.ref)).nil?
|
1007
1218
|
|
@@ -1009,7 +1220,7 @@ module Squared
|
|
1009
1220
|
true
|
1010
1221
|
else
|
1011
1222
|
val = workspace.series.name_get(action)
|
1012
|
-
val
|
1223
|
+
val != action && invoked_sync?(val)
|
1013
1224
|
end
|
1014
1225
|
end
|
1015
1226
|
|