squared 0.1.4 → 0.2.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 +64 -7
- data/README.md +3 -0
- data/README.ruby.md +126 -46
- 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 +350 -139
- 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 +190 -75
- 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 +3 -3
@@ -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
|
@@ -343,52 +361,63 @@ module Squared
|
|
343
361
|
when String
|
344
362
|
cmd = "#{cmd} #{opts}"
|
345
363
|
when Array
|
346
|
-
cmd =
|
364
|
+
cmd = cmd.join(' && ')
|
347
365
|
else
|
348
366
|
cmd = [cmd, compose(opts, script: false)].compact.join(' ') unless opts == false || !respond_to?(:compose)
|
349
367
|
end
|
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
|
-
|
380
|
-
val
|
381
|
-
|
382
|
-
|
383
|
-
|
384
|
-
|
408
|
+
as_a(@clean).each do |val|
|
409
|
+
if val =~ %r{[\\/]$}
|
410
|
+
dir = Pathname.new(val.to_s)
|
411
|
+
dir = basepath(dir) unless dir.absolute?
|
412
|
+
next unless dir.directory?
|
413
|
+
|
414
|
+
log.warn "rm -rf #{dir}"
|
415
|
+
dir.rmtree
|
385
416
|
else
|
386
|
-
files = val.include?('*') ? Dir[
|
417
|
+
files = val.include?('*') ? Dir[basepath(val)] : [basepath(val)]
|
387
418
|
files.each do |file|
|
388
|
-
next unless File.file?(file)
|
389
|
-
|
390
419
|
begin
|
391
|
-
File.delete(file)
|
420
|
+
File.delete(file) if File.file?(file)
|
392
421
|
rescue StandardError => e
|
393
422
|
log.error e
|
394
423
|
end
|
@@ -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
|
|