squared 0.4.11 → 0.4.13
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 +76 -0
- data/README.md +3 -3
- data/README.ruby.md +68 -11
- data/lib/squared/common/base.rb +1 -0
- data/lib/squared/common/format.rb +8 -5
- data/lib/squared/common/shell.rb +14 -14
- data/lib/squared/common/system.rb +2 -2
- data/lib/squared/common/utils.rb +4 -8
- data/lib/squared/version.rb +1 -1
- data/lib/squared/workspace/application.rb +154 -5
- data/lib/squared/workspace/project/base.rb +327 -161
- data/lib/squared/workspace/project/docker.rb +87 -47
- data/lib/squared/workspace/project/git.rb +62 -52
- data/lib/squared/workspace/project/node.rb +111 -59
- data/lib/squared/workspace/project/python.rb +143 -104
- data/lib/squared/workspace/project/ruby.rb +33 -22
- data/lib/squared/workspace/project/support/class.rb +6 -6
- data/lib/squared/workspace/project.rb +2 -7
- data/lib/squared/workspace/series.rb +34 -0
- data/lib/squared/workspace/support/data.rb +10 -0
- data/lib/squared/workspace/support.rb +3 -0
- data/lib/squared/workspace.rb +1 -0
- metadata +3 -1
@@ -9,6 +9,7 @@ module Squared
|
|
9
9
|
module Workspace
|
10
10
|
module Project
|
11
11
|
class Base
|
12
|
+
include Comparable
|
12
13
|
include Common::Format
|
13
14
|
include System
|
14
15
|
include Shell
|
@@ -17,7 +18,8 @@ module Squared
|
|
17
18
|
include Support
|
18
19
|
include Rake::DSL
|
19
20
|
|
20
|
-
VAR_SET = %i[parent global envname dependfile dependindex theme
|
21
|
+
VAR_SET = %i[parent global script index envname desc dependfile dependindex theme archive env dev prod graph
|
22
|
+
pass exclude].freeze
|
21
23
|
BLK_SET = %i[run depend doc lint test copy clean].freeze
|
22
24
|
SEM_VER = /\b(\d+)(?:(\.)(\d+))?(?:(\.)(\d+)(\S+)?)?\b/.freeze
|
23
25
|
URI_SCHEME = %r{^([a-z][a-z\d+-.]*)://[^@:\[\]\\^<>|\s]}i.freeze
|
@@ -31,7 +33,7 @@ module Squared
|
|
31
33
|
def bannerargs(*); end
|
32
34
|
|
33
35
|
def tasks
|
34
|
-
(%i[build archive graph] + BLK_SET).freeze
|
36
|
+
(%i[build archive graph prereqs] + BLK_SET).freeze
|
35
37
|
end
|
36
38
|
|
37
39
|
def as_path(val)
|
@@ -63,6 +65,7 @@ module Squared
|
|
63
65
|
end
|
64
66
|
|
65
67
|
@@tasks = {}
|
68
|
+
@@graph = { _: [] }
|
66
69
|
@@print_order = 0
|
67
70
|
|
68
71
|
subtasks({
|
@@ -73,8 +76,8 @@ module Squared
|
|
73
76
|
attr_reader :name, :project, :workspace, :path, :theme, :exception, :pipe, :verbose,
|
74
77
|
:group, :parent, :dependfile
|
75
78
|
|
76
|
-
def initialize(workspace, path, name, *, group: nil,
|
77
|
-
|
79
|
+
def initialize(workspace, path, name, *, group: nil, archive: nil, first: {}, last: {}, error: {},
|
80
|
+
common: ARG[:COMMON], **kwargs)
|
78
81
|
@path = path
|
79
82
|
@workspace = workspace
|
80
83
|
@name = name.to_s.freeze
|
@@ -93,33 +96,11 @@ module Squared
|
|
93
96
|
when Hash
|
94
97
|
archive
|
95
98
|
end
|
96
|
-
@release = release
|
99
|
+
@release = kwargs[:release]
|
97
100
|
@envname = @name.gsub(/[^\w]+/, '_').upcase.freeze
|
98
|
-
@exception = env_bool(kwargs[:exception], workspace.exception, strict: true)
|
99
|
-
@pipe = env_pipe(kwargs[:pipe], workspace.pipe, strict: true)
|
100
|
-
@verbose = case verbose
|
101
|
-
when NilClass
|
102
|
-
workspace.verbose
|
103
|
-
when String
|
104
|
-
env_bool(verbose, workspace.verbose, strict: true, index: true)
|
105
|
-
else
|
106
|
-
verbose
|
107
|
-
end
|
108
|
-
@theme = if !@verbose
|
109
|
-
{}
|
110
|
-
elsif common
|
111
|
-
workspace.theme
|
112
|
-
else
|
113
|
-
__get__(:theme)[:project][to_sym] ||= {}
|
114
|
-
end
|
115
101
|
@output = []
|
116
102
|
@ref = []
|
117
103
|
@children = []
|
118
|
-
@graph = if graph
|
119
|
-
as_a(graph, workspace.prefix ? ->(val) { workspace.task_name(val).to_sym } : :to_sym).freeze
|
120
|
-
end
|
121
|
-
@pass = (pass ? as_a(pass) : []).freeze
|
122
|
-
@exclude = (exclude ? as_a(exclude, :to_sym) : []).freeze
|
123
104
|
@events = {
|
124
105
|
first: first,
|
125
106
|
last: last,
|
@@ -128,7 +109,15 @@ module Squared
|
|
128
109
|
@desc = (@name.include?(':') ? @name.split(':').join(ARG[:SPACE]) : @name).freeze
|
129
110
|
@parent = nil
|
130
111
|
@global = false
|
112
|
+
@index = -1
|
131
113
|
run_set(kwargs[:run], kwargs[:env], opts: kwargs.fetch(:opts, true))
|
114
|
+
exception_set kwargs[:exception]
|
115
|
+
pipe_set kwargs[:pipe]
|
116
|
+
verbose_set kwargs[:verbose]
|
117
|
+
theme_set common
|
118
|
+
graph_set kwargs[:graph]
|
119
|
+
pass_set kwargs[:pass]
|
120
|
+
exclude_set kwargs[:exclude]
|
132
121
|
initialize_ref Base.ref
|
133
122
|
end
|
134
123
|
|
@@ -212,16 +201,11 @@ module Squared
|
|
212
201
|
elsif (val = log[:file])
|
213
202
|
file = val.is_a?(String) ? Time.now.strftime(val) : "#{@name}-#{Date.today}.log"
|
214
203
|
end
|
215
|
-
|
216
|
-
file
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
raise if @exception
|
221
|
-
|
222
|
-
file = nil
|
223
|
-
warn log_message(Logger::WARN, e, pass: true) if warning?
|
224
|
-
end
|
204
|
+
begin
|
205
|
+
file &&= @workspace.home.join(env('LOG_DIR', ''), file).realdirpath
|
206
|
+
rescue StandardError => e
|
207
|
+
file = nil
|
208
|
+
warn log_message(Logger::WARN, e, pass: true) if warning?
|
225
209
|
end
|
226
210
|
log[:progname] ||= @name
|
227
211
|
if (val = env('LOG_LEVEL', ignore: false))
|
@@ -259,6 +243,44 @@ module Squared
|
|
259
243
|
end
|
260
244
|
end
|
261
245
|
|
246
|
+
def <=>(other)
|
247
|
+
return 0 unless workspace == other.workspace
|
248
|
+
|
249
|
+
a, b = graph_deps
|
250
|
+
return 1 if a.include?(other)
|
251
|
+
|
252
|
+
c, d = graph_deps other
|
253
|
+
e = b.reject { |val| d.include?(val) }
|
254
|
+
f = d.reject { |val| b.include?(val) }
|
255
|
+
if parent == other.parent
|
256
|
+
g = []
|
257
|
+
h = []
|
258
|
+
else
|
259
|
+
g = a.reject { |val| c.include?(val) }
|
260
|
+
h = c.reject { |val| a.include?(val) }
|
261
|
+
end
|
262
|
+
g << self
|
263
|
+
h << other
|
264
|
+
e.concat(g)
|
265
|
+
f.concat(h)
|
266
|
+
if g.any? { |val| f.include?(val) }
|
267
|
+
-1
|
268
|
+
elsif h.any? { |val| e.include?(val) }
|
269
|
+
1
|
270
|
+
elsif e.any? { |val| f.include?(val) }
|
271
|
+
-1
|
272
|
+
elsif f.any? { |val| e.include?(val) }
|
273
|
+
1
|
274
|
+
elsif @index != -1 && (i = other.instance_variable_get(:@index)) != -1
|
275
|
+
@index < i ? -1 : 1
|
276
|
+
else
|
277
|
+
0
|
278
|
+
end
|
279
|
+
rescue StandardError => e
|
280
|
+
log&.debug e
|
281
|
+
0
|
282
|
+
end
|
283
|
+
|
262
284
|
def ref
|
263
285
|
Base.ref
|
264
286
|
end
|
@@ -347,29 +369,22 @@ module Squared
|
|
347
369
|
end
|
348
370
|
|
349
371
|
def add(path, name = nil, **kwargs, &blk)
|
350
|
-
|
351
|
-
|
352
|
-
true
|
353
|
-
else
|
354
|
-
log&.warn "workspace \"#{val}\" (#{val.empty? ? 'empty' : 'not found'})"
|
355
|
-
false
|
356
|
-
end
|
357
|
-
end
|
358
|
-
if path.is_a?(String) && (seg = path[%r{^(.+)[\\/]\*+$}, 1])
|
359
|
-
return self unless checkdir.call(path = basepath(seg))
|
372
|
+
if path.is_a?(String) && (seg = path[%r{\A(.+)[\\/]\*+\z}, 1])
|
373
|
+
return self unless checkdir?(path = basepath(seg))
|
360
374
|
|
361
|
-
path = path.children.select { |val| checkdir
|
375
|
+
path = path.children.select { |val| checkdir?(val) }
|
362
376
|
end
|
363
377
|
if path.is_a?(Array)
|
364
378
|
name = @name if name == true
|
365
379
|
path.each { |val| add(val, name && task_join(name, File.basename(val)), **kwargs, &blk) }
|
366
380
|
return self
|
367
|
-
elsif !projectpath?(path = basepath(path)) || !checkdir
|
381
|
+
elsif !projectpath?(path = basepath(path)) || !checkdir?(path)
|
368
382
|
return self
|
369
|
-
|
370
|
-
name = name
|
371
|
-
|
372
|
-
|
383
|
+
else
|
384
|
+
name = case name
|
385
|
+
when String, Symbol
|
386
|
+
name.to_s
|
387
|
+
end
|
373
388
|
end
|
374
389
|
if @withargs
|
375
390
|
data = @withargs.dup
|
@@ -380,8 +395,14 @@ module Squared
|
|
380
395
|
kwargs[:ref] = ref unless kwargs.key?(:ref)
|
381
396
|
parent = self
|
382
397
|
proj = nil
|
383
|
-
|
384
|
-
|
398
|
+
name = case name
|
399
|
+
when String, Symbol
|
400
|
+
name.to_s
|
401
|
+
else
|
402
|
+
path.basename
|
403
|
+
end
|
404
|
+
workspace.add(path, name, **kwargs) do
|
405
|
+
__send__ :parent_set, parent
|
385
406
|
proj = self
|
386
407
|
end
|
387
408
|
@children << proj
|
@@ -389,6 +410,11 @@ module Squared
|
|
389
410
|
self
|
390
411
|
end
|
391
412
|
|
413
|
+
def chain(*args, **kwargs)
|
414
|
+
workspace.chain(*args, project: self, **kwargs)
|
415
|
+
self
|
416
|
+
end
|
417
|
+
|
392
418
|
def inject(obj, *args, **kwargs, &blk)
|
393
419
|
return self unless enabled?
|
394
420
|
|
@@ -408,7 +434,7 @@ module Squared
|
|
408
434
|
|
409
435
|
run_b(@run, sync: sync, from: from) if series?(@run)
|
410
436
|
args = @output
|
411
|
-
banner = verbosetype > 1 if
|
437
|
+
banner = verbosetype > 1 if from_base?('build')
|
412
438
|
end
|
413
439
|
if args.first.is_a?(Struct)
|
414
440
|
f, blk = args.first.to_a
|
@@ -463,13 +489,42 @@ module Squared
|
|
463
489
|
cmd = compose(as_get(opts), flags, script: true, args: extra, from: from)
|
464
490
|
from = :script if from == :run && script?
|
465
491
|
end
|
466
|
-
run(cmd, var, from: from, banner: banner
|
492
|
+
run(cmd, var, sync: sync, from: from, banner: banner)
|
467
493
|
end
|
468
494
|
|
469
495
|
def depend(*, sync: invoked_sync?('depend'), **)
|
470
496
|
run_b(@depend, sync: sync, from: :depend)
|
471
497
|
end
|
472
498
|
|
499
|
+
def prereqs(*, sync: invoked_sync?('prereqs'), **)
|
500
|
+
on :first, :prereqs
|
501
|
+
graph_deps.flatten(1).sort.each do |proj|
|
502
|
+
next if @@graph[:_].include?(proj)
|
503
|
+
|
504
|
+
if (val = ENV["PREREQS_#{proj.instance_variable_get(:@envname)}"] || ENV["PREREQS_#{proj.ref.upcase}"])
|
505
|
+
val.split(/\s*,\s*/).each do |meth|
|
506
|
+
if proj.respond_to?(meth.to_sym)
|
507
|
+
begin
|
508
|
+
proj.__send__(meth, sync: sync)
|
509
|
+
rescue StandardError => e
|
510
|
+
ret = on(:error, :prereqs, e)
|
511
|
+
raise unless ret == true
|
512
|
+
else
|
513
|
+
next
|
514
|
+
end
|
515
|
+
end
|
516
|
+
if warning?
|
517
|
+
warn log_message(Logger::WARN, name, 'method not found', subject: 'prereqs', hint: meth, pass: true)
|
518
|
+
end
|
519
|
+
end
|
520
|
+
elsif proj.build?
|
521
|
+
proj.build(sync: sync)
|
522
|
+
end
|
523
|
+
@@graph[:_] << proj
|
524
|
+
end
|
525
|
+
on :last, :prereqs
|
526
|
+
end
|
527
|
+
|
473
528
|
def archive(*, sync: invoked_sync?('archive'), **)
|
474
529
|
return unless @archive.is_a?(Hash)
|
475
530
|
|
@@ -477,7 +532,7 @@ module Squared
|
|
477
532
|
end
|
478
533
|
|
479
534
|
def doc(*, sync: invoked_sync?('doc'), **)
|
480
|
-
run_b(@doc, sync: sync, from: :doc)
|
535
|
+
run_b(@doc, sync: sync, from: :doc, banner: from_base?('doc') ? verbosetype > 1 : verbose)
|
481
536
|
end
|
482
537
|
|
483
538
|
def lint(*, sync: invoked_sync?('lint'), **)
|
@@ -518,7 +573,7 @@ module Squared
|
|
518
573
|
if @clean.is_a?(Enumerable) && !series?(@clean)
|
519
574
|
@clean.each do |val|
|
520
575
|
entry = path + (val = val.to_s)
|
521
|
-
if entry.directory? && val.match?(%r{[\\/]
|
576
|
+
if entry.directory? && val.match?(%r{[\\/]\z})
|
522
577
|
log&.warn "rm -rf #{entry}"
|
523
578
|
rm_rf(entry, verbose: verbose)
|
524
579
|
else
|
@@ -541,7 +596,7 @@ module Squared
|
|
541
596
|
on :last, :clean unless pass
|
542
597
|
end
|
543
598
|
|
544
|
-
def graph(start = [], tasks = nil, sync: invoked_sync?('graph'), pass: [], out: nil)
|
599
|
+
def graph(start = [], tasks = nil, *, sync: invoked_sync?('graph'), pass: [], out: nil, **)
|
545
600
|
if (val = env('GRAPH', strict: true))
|
546
601
|
tasks ||= []
|
547
602
|
split_escape(val).each do |task|
|
@@ -559,21 +614,19 @@ module Squared
|
|
559
614
|
data[name] << self
|
560
615
|
on :first, :graph
|
561
616
|
end
|
562
|
-
|
563
|
-
|
564
|
-
|
565
|
-
|
566
|
-
|
567
|
-
end
|
617
|
+
ret = graph_branch(self, data, tasks, out, sync: sync, pass: pass)
|
618
|
+
rescue StandardError => e
|
619
|
+
ret = on(:error, :graph, e)
|
620
|
+
raise unless ret == true
|
621
|
+
else
|
568
622
|
if out
|
569
|
-
[out,
|
623
|
+
[out, ret]
|
570
624
|
else
|
571
625
|
on :last, :graph
|
572
626
|
end
|
573
627
|
end
|
574
628
|
|
575
|
-
def unpack(target, uri:, sync: true, digest: nil, ext: nil, force: false, depth: 1, headers: {},
|
576
|
-
from: :unpack)
|
629
|
+
def unpack(target, uri:, sync: true, digest: nil, ext: nil, force: false, depth: 1, headers: {}, from: :unpack)
|
577
630
|
if !target.exist?
|
578
631
|
target.mkpath
|
579
632
|
elsif !target.directory?
|
@@ -581,18 +634,11 @@ module Squared
|
|
581
634
|
elsif !target.empty?
|
582
635
|
raise_error('directory not empty', hint: target) unless force || env('UNPACK_FORCE')
|
583
636
|
create = true
|
584
|
-
elsif !uri
|
585
|
-
raise_error('no download uri', hint: target)
|
586
637
|
end
|
587
638
|
if digest
|
588
639
|
require 'digest'
|
589
|
-
|
590
|
-
|
591
|
-
digest = digest[n + 1..-1]
|
592
|
-
else
|
593
|
-
size = digest.size
|
594
|
-
end
|
595
|
-
algo = case size
|
640
|
+
digest, type = digest.split(':', 2).reverse
|
641
|
+
algo = case type&.downcase || digest.size
|
596
642
|
when 32, 'md5'
|
597
643
|
Digest::MD5
|
598
644
|
when 'rmd160'
|
@@ -610,16 +656,15 @@ module Squared
|
|
610
656
|
end
|
611
657
|
end
|
612
658
|
if (val = env('HEADERS')) && (val = parse_json(val, hint: "HEADERS_#{@envname}"))
|
613
|
-
headers = val
|
659
|
+
headers = headers.is_a?(Hash) ? headers.merge(val) : val
|
614
660
|
end
|
615
661
|
data = nil
|
616
662
|
(uri = as_a(uri)).each_with_index do |url, index|
|
617
|
-
last = index == uri.size - 1
|
618
663
|
fetch_uri(url, headers) do |f|
|
619
664
|
data = f.read
|
620
665
|
if algo && algo.hexdigest(data) != digest
|
621
666
|
data = nil
|
622
|
-
raise_error("checksum failed: #{digest}", hint: url) if
|
667
|
+
raise_error("checksum failed: #{digest}", hint: url) if index == uri.size - 1
|
623
668
|
end
|
624
669
|
next if ext && index == 0
|
625
670
|
|
@@ -632,14 +677,11 @@ module Squared
|
|
632
677
|
ext = 'txz'
|
633
678
|
end
|
634
679
|
end
|
635
|
-
if data
|
636
|
-
|
637
|
-
|
638
|
-
|
639
|
-
raise_error('no content', hint: url)
|
640
|
-
end
|
680
|
+
break uri = url if data
|
681
|
+
end
|
682
|
+
unless data && (ext ||= URI.parse(uri).path[/\.(\w+)(?:\?|\z)/, 1])
|
683
|
+
raise_error("no content#{data ? ' type' : ''}", hint: uri)
|
641
684
|
end
|
642
|
-
raise_error('no content type', hint: uri) unless ext ||= URI.parse(uri).path[/\.(\w+)(\?|$)/i, 1]
|
643
685
|
ext = ext.downcase
|
644
686
|
if (val = env("#{%w[zip 7z gem].include?(ext) ? ext.upcase : 'TAR'}_DEPTH", ignore: false))
|
645
687
|
depth = val.to_i
|
@@ -698,8 +740,8 @@ module Squared
|
|
698
740
|
ensure
|
699
741
|
if dir
|
700
742
|
remove_entry dir
|
701
|
-
|
702
|
-
file
|
743
|
+
else
|
744
|
+
file&.unlink
|
703
745
|
end
|
704
746
|
end
|
705
747
|
end
|
@@ -747,32 +789,44 @@ module Squared
|
|
747
789
|
self
|
748
790
|
end
|
749
791
|
|
750
|
-
def variable_set(key, *
|
751
|
-
if variables.include?(key)
|
792
|
+
def variable_set(key, *args, **kwargs, &blk)
|
793
|
+
if variables.include?(key) || blocks.include?(key)
|
794
|
+
val = case args.size
|
795
|
+
when 0
|
796
|
+
nil
|
797
|
+
when 1
|
798
|
+
args.first
|
799
|
+
else
|
800
|
+
args
|
801
|
+
end
|
752
802
|
case key
|
753
|
-
when :
|
754
|
-
|
803
|
+
when :index
|
804
|
+
index_set val
|
805
|
+
when :graph
|
806
|
+
graph_set val
|
807
|
+
when :pass
|
808
|
+
pass_set val
|
809
|
+
when :exclude
|
810
|
+
exclude_set val
|
811
|
+
when :parent
|
812
|
+
parent_set val
|
813
|
+
when :run
|
814
|
+
run_set(*args, **kwargs)
|
755
815
|
when :script
|
756
|
-
script_set(*
|
816
|
+
script_set(*args, **kwargs)
|
757
817
|
when :env
|
758
|
-
run_set(output[0], *
|
759
|
-
when :parent
|
760
|
-
@parent = val if (val = val.first).is_a?(Project::Base)
|
761
|
-
when :graph
|
762
|
-
@graph = case val.first
|
763
|
-
when NilClass, FalseClass
|
764
|
-
nil
|
765
|
-
else
|
766
|
-
val.flatten.map!(&:to_s).freeze
|
767
|
-
end
|
818
|
+
run_set(output[0], *args, **kwargs)
|
768
819
|
when :dependfile
|
769
|
-
@dependfile = basepath(*
|
820
|
+
@dependfile = basepath(*args)
|
770
821
|
else
|
771
|
-
if
|
772
|
-
|
773
|
-
|
774
|
-
|
822
|
+
if block_given?
|
823
|
+
if blocks.include?(key)
|
824
|
+
series key, &blk
|
825
|
+
return self
|
826
|
+
end
|
827
|
+
val = block_args val, &blk
|
775
828
|
end
|
829
|
+
instance_variable_set(:"@#{key}", val.first)
|
776
830
|
end
|
777
831
|
else
|
778
832
|
log&.warn "variable_set: @#{key} (private)"
|
@@ -816,6 +870,15 @@ module Squared
|
|
816
870
|
@graph.is_a?(Array) && !@graph.empty?
|
817
871
|
end
|
818
872
|
|
873
|
+
def prereqs?
|
874
|
+
target = self
|
875
|
+
loop do
|
876
|
+
return true if target.graph?
|
877
|
+
break unless (target = target.parent)
|
878
|
+
end
|
879
|
+
false
|
880
|
+
end
|
881
|
+
|
819
882
|
def copy?
|
820
883
|
runnable?(@copy) || workspace.task_defined?(name, 'copy')
|
821
884
|
end
|
@@ -908,7 +971,7 @@ module Squared
|
|
908
971
|
puts_oe(*args, pipe: pipe)
|
909
972
|
end
|
910
973
|
|
911
|
-
def run(cmd = @session, var = nil, exception: @exception, sync: true, banner: true, chdir: path,
|
974
|
+
def run(cmd = @session, var = nil, exception: @exception, sync: true, from: nil, banner: true, chdir: path, **)
|
912
975
|
unless cmd
|
913
976
|
if warning?
|
914
977
|
from &&= from.to_s
|
@@ -916,6 +979,7 @@ module Squared
|
|
916
979
|
end
|
917
980
|
return
|
918
981
|
end
|
982
|
+
cmd = cmd.target if cmd.is_a?(OptionPartition)
|
919
983
|
cmd = session_done cmd
|
920
984
|
log&.info cmd
|
921
985
|
on :first, from
|
@@ -950,7 +1014,7 @@ module Squared
|
|
950
1014
|
end
|
951
1015
|
end
|
952
1016
|
|
953
|
-
def run_s(*cmd, env: nil, sync: true, banner: verbose != false,
|
1017
|
+
def run_s(*cmd, env: nil, sync: true, from: nil, banner: verbose != false, **kwargs)
|
954
1018
|
on :first, from
|
955
1019
|
begin
|
956
1020
|
cmd.flatten.each { |val| run(val, env, sync: sync, banner: banner, **kwargs) }
|
@@ -961,11 +1025,11 @@ module Squared
|
|
961
1025
|
on :last, from
|
962
1026
|
end
|
963
1027
|
|
964
|
-
def run_b(obj,
|
1028
|
+
def run_b(obj, **kwargs)
|
965
1029
|
case obj
|
966
1030
|
when Struct
|
967
1031
|
if (any = instance_eval(&obj.block) || obj.run)
|
968
|
-
run_b(any,
|
1032
|
+
run_b(any, **kwargs)
|
969
1033
|
end
|
970
1034
|
when Proc
|
971
1035
|
instance_eval(&obj)
|
@@ -975,9 +1039,9 @@ module Squared
|
|
975
1039
|
if series?(obj)
|
976
1040
|
obj.each(&:call)
|
977
1041
|
elsif obj.is_a?(Array) && obj.any? { |val| !val.is_a?(String) }
|
978
|
-
build(*obj,
|
1042
|
+
build(*obj, **kwargs)
|
979
1043
|
elsif obj
|
980
|
-
run_s(obj.is_a?(Enumerable) ? obj.to_a : obj,
|
1044
|
+
run_s(obj.is_a?(Enumerable) ? obj.to_a : obj, **kwargs)
|
981
1045
|
end
|
982
1046
|
end
|
983
1047
|
end
|
@@ -1062,7 +1126,7 @@ module Squared
|
|
1062
1126
|
k = 0
|
1063
1127
|
final = data.keys.last
|
1064
1128
|
while k < depth
|
1065
|
-
indent = k > 0
|
1129
|
+
indent = k > 0 ? ((last && !j) || (j && k == depth - 1) || single) : j && last && depth == 1
|
1066
1130
|
s += "#{indent || (last && data[final].last == context) ? ' ' : a} "
|
1067
1131
|
k += 1
|
1068
1132
|
end
|
@@ -1097,10 +1161,28 @@ module Squared
|
|
1097
1161
|
deps.concat(objs)
|
1098
1162
|
end
|
1099
1163
|
end
|
1100
|
-
|
1164
|
+
deps.uniq!
|
1165
|
+
deps.delete(target)
|
1166
|
+
data[target.name] = deps
|
1101
1167
|
data
|
1102
1168
|
end
|
1103
1169
|
|
1170
|
+
def graph_deps(target = self)
|
1171
|
+
key = target.name
|
1172
|
+
return @@graph[key] if @@graph.key?(key)
|
1173
|
+
|
1174
|
+
base = []
|
1175
|
+
deps = []
|
1176
|
+
loop do
|
1177
|
+
deps.concat(graph_branch(target, graph_collect(target), []))
|
1178
|
+
break unless (target = target.parent)
|
1179
|
+
|
1180
|
+
base << target
|
1181
|
+
end
|
1182
|
+
deps.uniq!
|
1183
|
+
@@graph[key] = [base, deps]
|
1184
|
+
end
|
1185
|
+
|
1104
1186
|
def env(key, default = nil, suffix: nil, equals: nil, ignore: nil, strict: false)
|
1105
1187
|
a = "#{key}_#{@envname}"
|
1106
1188
|
ret = if suffix
|
@@ -1152,6 +1234,12 @@ module Squared
|
|
1152
1234
|
cmd.done
|
1153
1235
|
end
|
1154
1236
|
|
1237
|
+
def session_arg?(*args, target: @session, **kwargs)
|
1238
|
+
return false unless target
|
1239
|
+
|
1240
|
+
OptionPartition.arg?(target, *args, **kwargs)
|
1241
|
+
end
|
1242
|
+
|
1155
1243
|
def option(*args, target: @session, prefix: target&.first, **kwargs)
|
1156
1244
|
if prefix
|
1157
1245
|
args.each do |val|
|
@@ -1178,8 +1266,8 @@ module Squared
|
|
1178
1266
|
end
|
1179
1267
|
|
1180
1268
|
def print_item(*val)
|
1181
|
-
puts
|
1182
|
-
|
1269
|
+
puts unless printfirst?
|
1270
|
+
printsucc
|
1183
1271
|
puts val unless val.empty? || (val.size == 1 && val.first.nil?)
|
1184
1272
|
end
|
1185
1273
|
|
@@ -1209,10 +1297,9 @@ module Squared
|
|
1209
1297
|
|
1210
1298
|
def print_footer(*lines, sub: nil, reverse: false, right: false, **kwargs)
|
1211
1299
|
n = Project.max_width(lines)
|
1212
|
-
sub = as_a sub
|
1213
1300
|
lines.map! do |val|
|
1214
1301
|
s = right ? val.rjust(n) : val.ljust(n)
|
1215
|
-
sub
|
1302
|
+
sub&.each { |h| s = sub_style(s, **h) }
|
1216
1303
|
s
|
1217
1304
|
end
|
1218
1305
|
ret = [sub_style(ARG[:BORDER][1] * n, styles: kwargs.key?(:border) ? kwargs[:border] : borderstyle), *lines]
|
@@ -1241,9 +1328,9 @@ module Squared
|
|
1241
1328
|
if verbose
|
1242
1329
|
out = []
|
1243
1330
|
if data[:command]
|
1244
|
-
if cmd =~ /\A(?:"((?:[^"]|(?<=\\)")+)"|'((?:[^']|(?<=\\)')+)'|(\S+)) /
|
1331
|
+
if cmd =~ /\A(?:"((?:[^"]|(?<=\\)")+)"|'((?:[^']|(?<=\\)')+)'|(\S+))( |\z)/
|
1245
1332
|
path = $3 || $2 || $1
|
1246
|
-
cmd = cmd.sub(path,
|
1333
|
+
cmd = cmd.sub(path, stripext(path).upcase)
|
1247
1334
|
end
|
1248
1335
|
out << cmd
|
1249
1336
|
end
|
@@ -1502,12 +1589,12 @@ module Squared
|
|
1502
1589
|
b = sub_style("#{pkg} #{ver}", styles: theme[:inline])
|
1503
1590
|
c, d = rev == 1 || lock ? ['y/N', 'N'] : ['Y/n', 'Y']
|
1504
1591
|
e = lock ? " #{sub_style('(locked)', styles: color(:red))}" : ''
|
1505
|
-
confirm
|
1592
|
+
confirm "Upgrade to #{a}? #{b + e} [#{c}] ", d
|
1506
1593
|
end
|
1507
1594
|
|
1508
1595
|
def choice_index(msg, list, values: nil, accept: nil, series: false, trim: nil, column: nil,
|
1509
1596
|
multiple: false, force: true, **kwargs)
|
1510
|
-
puts if !series &&
|
1597
|
+
puts if !series && !printfirst?
|
1511
1598
|
msg = "#{msg} (optional)" unless force
|
1512
1599
|
unless (ret = choice(msg, list, multiple: multiple, force: force, **kwargs)) || !force
|
1513
1600
|
raise_error 'user cancelled'
|
@@ -1519,7 +1606,7 @@ module Squared
|
|
1519
1606
|
end
|
1520
1607
|
ret = multiple ? ret.map! { |val| val.sub(trim, '') } : ret.sub(trim, '') if trim
|
1521
1608
|
if column
|
1522
|
-
a, b = as_a
|
1609
|
+
a, b = as_a column
|
1523
1610
|
ret = as_a(ret).map! { |val| val[a, b || 1] }
|
1524
1611
|
ret = ret.first unless multiple
|
1525
1612
|
end
|
@@ -1554,10 +1641,24 @@ module Squared
|
|
1554
1641
|
ret << (val.empty? ? nil : val)
|
1555
1642
|
end
|
1556
1643
|
end
|
1557
|
-
|
1644
|
+
printsucc unless series
|
1558
1645
|
ret
|
1559
1646
|
end
|
1560
1647
|
|
1648
|
+
def command_args(args, force: false, **kwargs)
|
1649
|
+
return unless args.size == 1 && !option('i', 'interactive', **kwargs, equals: '0')
|
1650
|
+
|
1651
|
+
readline('Enter arguments', force: force)
|
1652
|
+
end
|
1653
|
+
|
1654
|
+
def block_args(val = nil, &blk)
|
1655
|
+
if (ret = instance_eval(&blk)).nil?
|
1656
|
+
val
|
1657
|
+
else
|
1658
|
+
ret.is_a?(Array) ? ret : [ret]
|
1659
|
+
end
|
1660
|
+
end
|
1661
|
+
|
1561
1662
|
def runenv
|
1562
1663
|
nil
|
1563
1664
|
end
|
@@ -1608,15 +1709,17 @@ module Squared
|
|
1608
1709
|
end
|
1609
1710
|
|
1610
1711
|
def indexitem(val)
|
1611
|
-
|
1612
|
-
|
1613
|
-
[$1.to_i, $2 && $2[1..-1]]
|
1712
|
+
[$1.to_i, $2 && $2[1..-1]] if val =~ /\A\^(\d+)(:.+)?\z/
|
1614
1713
|
end
|
1615
1714
|
|
1616
1715
|
def indexerror(val, list = nil)
|
1617
1716
|
raise_error("requested index #{val}", hint: list && "of #{list.size}")
|
1618
1717
|
end
|
1619
1718
|
|
1719
|
+
def printsucc
|
1720
|
+
@@print_order += 1
|
1721
|
+
end
|
1722
|
+
|
1620
1723
|
def color(val)
|
1621
1724
|
ret = theme[val]
|
1622
1725
|
ret && !ret.empty? ? ret : [val]
|
@@ -1642,16 +1745,14 @@ module Squared
|
|
1642
1745
|
end
|
1643
1746
|
|
1644
1747
|
def on(event, from, *args, **kwargs)
|
1645
|
-
return unless from
|
1646
|
-
|
1647
|
-
|
1648
|
-
if obj.is_a?(Array) && obj[1].is_a?(Hash)
|
1649
|
-
|
1650
|
-
|
1651
|
-
|
1652
|
-
|
1653
|
-
target = obj
|
1654
|
-
end
|
1748
|
+
return unless from && (data = @events[event])
|
1749
|
+
|
1750
|
+
data[from]&.each do |obj|
|
1751
|
+
target, opts = if obj.is_a?(Array) && obj[1].is_a?(Hash)
|
1752
|
+
[obj[0], kwargs.empty? ? obj[1] : obj[1].merge(kwargs)]
|
1753
|
+
else
|
1754
|
+
[obj, kwargs]
|
1755
|
+
end
|
1655
1756
|
as_a(target, flat: true).each do |cmd|
|
1656
1757
|
case cmd
|
1657
1758
|
when Proc, Method
|
@@ -1760,6 +1861,63 @@ module Squared
|
|
1760
1861
|
@output[4] = args unless @output[4] == false || args.nil?
|
1761
1862
|
end
|
1762
1863
|
|
1864
|
+
def index_set(val)
|
1865
|
+
@index = val if val.is_a?(Numeric)
|
1866
|
+
end
|
1867
|
+
|
1868
|
+
def parent_set(val)
|
1869
|
+
@parent = val if val.is_a?(Project::Base)
|
1870
|
+
end
|
1871
|
+
|
1872
|
+
def exception_set(val)
|
1873
|
+
@exception = env_bool(val, workspace.exception, strict: true)
|
1874
|
+
end
|
1875
|
+
|
1876
|
+
def pipe_set(val)
|
1877
|
+
@pipe = env_pipe(val, workspace.pipe, strict: true)
|
1878
|
+
end
|
1879
|
+
|
1880
|
+
def verbose_set(val)
|
1881
|
+
@verbose = case val
|
1882
|
+
when NilClass
|
1883
|
+
workspace.verbose
|
1884
|
+
when String
|
1885
|
+
env_bool(val, workspace.verbose, strict: true, index: true)
|
1886
|
+
else
|
1887
|
+
val
|
1888
|
+
end
|
1889
|
+
end
|
1890
|
+
|
1891
|
+
def theme_set(common)
|
1892
|
+
@theme = if !verbose
|
1893
|
+
{}
|
1894
|
+
elsif common
|
1895
|
+
workspace.theme
|
1896
|
+
else
|
1897
|
+
__get__(:theme)[:project][to_sym] ||= {}
|
1898
|
+
end
|
1899
|
+
end
|
1900
|
+
|
1901
|
+
def graph_set(val)
|
1902
|
+
@graph = if val
|
1903
|
+
as_a(val).map { |s| workspace.prefix ? workspace.task_name(s).to_sym : s.to_sym }.freeze
|
1904
|
+
end
|
1905
|
+
end
|
1906
|
+
|
1907
|
+
def pass_set(val)
|
1908
|
+
@pass = (val ? as_a(val, :to_s) : []).freeze
|
1909
|
+
end
|
1910
|
+
|
1911
|
+
def exclude_set(val)
|
1912
|
+
@exclude = (val ? as_a(val, :to_sym) : []).freeze
|
1913
|
+
end
|
1914
|
+
|
1915
|
+
def dependfile_set(list)
|
1916
|
+
@dependindex = list.index { |file| basepath(file).exist? }.tap do |index|
|
1917
|
+
@dependfile = @path + list[index || 0]
|
1918
|
+
end
|
1919
|
+
end
|
1920
|
+
|
1763
1921
|
def as_get(val)
|
1764
1922
|
return unless val
|
1765
1923
|
|
@@ -1792,10 +1950,23 @@ module Squared
|
|
1792
1950
|
val.absolute? ? val.to_s.start_with?(File.join(path, '')) : !val.to_s.start_with?(File.join('..', ''))
|
1793
1951
|
end
|
1794
1952
|
|
1953
|
+
def checkdir?(val)
|
1954
|
+
if val.directory? && !val.empty?
|
1955
|
+
true
|
1956
|
+
else
|
1957
|
+
log&.warn "directory \"#{val}\" (#{val.empty? ? 'empty' : 'not found'})"
|
1958
|
+
false
|
1959
|
+
end
|
1960
|
+
end
|
1961
|
+
|
1795
1962
|
def semmajor?(cur, want)
|
1796
1963
|
(cur[0] == '0' && want[0] == '0' ? cur[2] != want[2] : cur[0] != want[0]) && !want[5]
|
1797
1964
|
end
|
1798
1965
|
|
1966
|
+
def printfirst?
|
1967
|
+
@@print_order == 0
|
1968
|
+
end
|
1969
|
+
|
1799
1970
|
def runnable?(val)
|
1800
1971
|
case val
|
1801
1972
|
when String, Enumerable, Proc, Method
|
@@ -1809,8 +1980,8 @@ module Squared
|
|
1809
1980
|
val.is_a?(Array) && val.all? { |p| p.is_a?(Proc) || p.is_a?(Method) }
|
1810
1981
|
end
|
1811
1982
|
|
1812
|
-
def
|
1813
|
-
|
1983
|
+
def from_base?(val)
|
1984
|
+
task_invoked?(val, "#{val}:sync", 'default')
|
1814
1985
|
end
|
1815
1986
|
|
1816
1987
|
def from_sync?(*val)
|
@@ -1825,13 +1996,11 @@ module Squared
|
|
1825
1996
|
return true if val || from_sync?(ac = workspace.task_name(action))
|
1826
1997
|
return val if group && !(val = from_sync?(ac, group)).nil?
|
1827
1998
|
return val if (base = workspace.find_base(self)) && !(val = from_sync?(ac, base.ref)).nil?
|
1999
|
+
return false if workspace.series.chain?(val = task_join(name, action))
|
2000
|
+
return true if task_invoked?(val) && (!task_invoked?(ac) || !workspace.task_defined?(ac, 'sync'))
|
1828
2001
|
|
1829
|
-
|
1830
|
-
|
1831
|
-
else
|
1832
|
-
val = workspace.series.name_get(action)
|
1833
|
-
val != action && invoked_sync?(val)
|
1834
|
-
end
|
2002
|
+
val = workspace.series.name_get(action)
|
2003
|
+
val != action && invoked_sync?(val)
|
1835
2004
|
end
|
1836
2005
|
|
1837
2006
|
def success?(ret)
|
@@ -1854,22 +2023,19 @@ module Squared
|
|
1854
2023
|
workspace.warning
|
1855
2024
|
end
|
1856
2025
|
|
1857
|
-
def has_value?(data,
|
1858
|
-
|
1859
|
-
|
1860
|
-
|
1861
|
-
|
1862
|
-
|
1863
|
-
|
1864
|
-
|
1865
|
-
when Enumerable
|
1866
|
-
data.to_a.include?(obj)
|
1867
|
-
end
|
2026
|
+
def has_value?(data, other)
|
2027
|
+
case data
|
2028
|
+
when Hash
|
2029
|
+
other.is_a?(Enumerable) ? other.any? { |obj| data.value?(obj) } : data.value?(other)
|
2030
|
+
when Enumerable
|
2031
|
+
other.is_a?(Enumerable) ? other.any? { |obj| data.include?(obj) } : data.include?(other)
|
2032
|
+
else
|
2033
|
+
false
|
1868
2034
|
end
|
1869
2035
|
end
|
1870
2036
|
|
1871
2037
|
def variables
|
1872
|
-
|
2038
|
+
VAR_SET
|
1873
2039
|
end
|
1874
2040
|
|
1875
2041
|
def blocks
|