squared 0.4.12 → 0.4.14
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 +100 -0
- data/README.ruby.md +6 -2
- data/lib/squared/common/base.rb +5 -2
- data/lib/squared/common/format.rb +8 -2
- data/lib/squared/common/prompt.rb +1 -1
- data/lib/squared/common/shell.rb +14 -14
- data/lib/squared/common/system.rb +21 -14
- data/lib/squared/common/utils.rb +7 -3
- data/lib/squared/config.rb +6 -5
- data/lib/squared/version.rb +1 -1
- data/lib/squared/workspace/application.rb +21 -12
- data/lib/squared/workspace/project/base.rb +348 -137
- data/lib/squared/workspace/project/docker.rb +95 -52
- data/lib/squared/workspace/project/git.rb +86 -52
- data/lib/squared/workspace/project/node.rb +71 -44
- data/lib/squared/workspace/project/python.rb +360 -131
- data/lib/squared/workspace/project/ruby.rb +140 -103
- data/lib/squared/workspace/project/support/class.rb +39 -3
- data/lib/squared/workspace/repo.rb +2 -1
- data/lib/squared/workspace/support/data.rb +2 -2
- metadata +1 -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, first: {}, last: {}, error: {}, common: ARG[:COMMON],
|
80
|
+
**kwargs)
|
78
81
|
@path = path
|
79
82
|
@workspace = workspace
|
80
83
|
@name = name.to_s.freeze
|
@@ -87,48 +90,29 @@ module Squared
|
|
87
90
|
@copy = kwargs[:copy]
|
88
91
|
@clean = kwargs[:clean]
|
89
92
|
@version = kwargs[:version]
|
90
|
-
@
|
91
|
-
when String, Array
|
92
|
-
{ uri: archive }
|
93
|
-
when Hash
|
94
|
-
archive
|
95
|
-
end
|
96
|
-
@release = release
|
97
|
-
@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
|
93
|
+
@release = kwargs[:release]
|
115
94
|
@output = []
|
116
95
|
@ref = []
|
117
96
|
@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
97
|
@events = {
|
124
98
|
first: first,
|
125
99
|
last: last,
|
126
100
|
error: error
|
127
101
|
}
|
102
|
+
@envname = env_key(@name).freeze
|
128
103
|
@desc = (@name.include?(':') ? @name.split(':').join(ARG[:SPACE]) : @name).freeze
|
129
104
|
@parent = nil
|
130
105
|
@global = false
|
106
|
+
@index = -1
|
131
107
|
run_set(kwargs[:run], kwargs[:env], opts: kwargs.fetch(:opts, true))
|
108
|
+
exception_set kwargs[:exception]
|
109
|
+
pipe_set kwargs[:pipe]
|
110
|
+
verbose_set kwargs[:verbose]
|
111
|
+
graph_set kwargs[:graph]
|
112
|
+
pass_set kwargs[:pass]
|
113
|
+
exclude_set kwargs[:exclude]
|
114
|
+
archive_set kwargs[:archive]
|
115
|
+
theme_set common
|
132
116
|
initialize_ref Base.ref
|
133
117
|
end
|
134
118
|
|
@@ -216,7 +200,7 @@ module Squared
|
|
216
200
|
file &&= @workspace.home.join(env('LOG_DIR', ''), file).realdirpath
|
217
201
|
rescue StandardError => e
|
218
202
|
file = nil
|
219
|
-
warn log_message(Logger::WARN, e
|
203
|
+
warn log_message(Logger::WARN, e) if warning?
|
220
204
|
end
|
221
205
|
log[:progname] ||= @name
|
222
206
|
if (val = env('LOG_LEVEL', ignore: false))
|
@@ -254,6 +238,44 @@ module Squared
|
|
254
238
|
end
|
255
239
|
end
|
256
240
|
|
241
|
+
def <=>(other)
|
242
|
+
return 0 unless workspace == other.workspace
|
243
|
+
|
244
|
+
a, b = graph_deps
|
245
|
+
return 1 if a.include?(other)
|
246
|
+
|
247
|
+
c, d = graph_deps other
|
248
|
+
e = b - d
|
249
|
+
f = d - b
|
250
|
+
if parent == other.parent
|
251
|
+
g = []
|
252
|
+
h = []
|
253
|
+
else
|
254
|
+
g = a - c
|
255
|
+
h = c - a
|
256
|
+
end
|
257
|
+
g << self
|
258
|
+
h << other
|
259
|
+
e.concat(g)
|
260
|
+
f.concat(h)
|
261
|
+
if g.any? { |val| f.include?(val) }
|
262
|
+
-1
|
263
|
+
elsif h.any? { |val| e.include?(val) }
|
264
|
+
1
|
265
|
+
elsif e.any? { |val| f.include?(val) }
|
266
|
+
-1
|
267
|
+
elsif f.any? { |val| e.include?(val) }
|
268
|
+
1
|
269
|
+
elsif @index != -1 && (i = other.instance_variable_get(:@index)) != -1
|
270
|
+
@index < i ? -1 : 1
|
271
|
+
else
|
272
|
+
0
|
273
|
+
end
|
274
|
+
rescue StandardError => e
|
275
|
+
log&.debug e
|
276
|
+
0
|
277
|
+
end
|
278
|
+
|
257
279
|
def ref
|
258
280
|
Base.ref
|
259
281
|
end
|
@@ -342,24 +364,16 @@ module Squared
|
|
342
364
|
end
|
343
365
|
|
344
366
|
def add(path, name = nil, **kwargs, &blk)
|
345
|
-
checkdir = lambda do |val|
|
346
|
-
if val.directory? && !val.empty?
|
347
|
-
true
|
348
|
-
else
|
349
|
-
log&.warn "workspace \"#{val}\" (#{val.empty? ? 'empty' : 'not found'})"
|
350
|
-
false
|
351
|
-
end
|
352
|
-
end
|
353
367
|
if path.is_a?(String) && (seg = path[%r{\A(.+)[\\/]\*+\z}, 1])
|
354
|
-
return self unless checkdir
|
368
|
+
return self unless checkdir?(path = basepath(seg))
|
355
369
|
|
356
|
-
path = path.children.select { |val| checkdir
|
370
|
+
path = path.children.select { |val| checkdir?(val) }
|
357
371
|
end
|
358
372
|
if path.is_a?(Array)
|
359
373
|
name = @name if name == true
|
360
374
|
path.each { |val| add(val, name && task_join(name, File.basename(val)), **kwargs, &blk) }
|
361
375
|
return self
|
362
|
-
elsif !projectpath?(path = basepath(path)) || !checkdir
|
376
|
+
elsif !projectpath?(path = basepath(path)) || !checkdir?(path)
|
363
377
|
return self
|
364
378
|
else
|
365
379
|
name = case name
|
@@ -376,8 +390,14 @@ module Squared
|
|
376
390
|
kwargs[:ref] = ref unless kwargs.key?(:ref)
|
377
391
|
parent = self
|
378
392
|
proj = nil
|
379
|
-
|
380
|
-
|
393
|
+
name = case name
|
394
|
+
when String, Symbol
|
395
|
+
name.to_s
|
396
|
+
else
|
397
|
+
path.basename
|
398
|
+
end
|
399
|
+
workspace.add(path, name, **kwargs) do
|
400
|
+
__send__ :parent_set, parent
|
381
401
|
proj = self
|
382
402
|
end
|
383
403
|
@children << proj
|
@@ -395,7 +415,7 @@ module Squared
|
|
395
415
|
|
396
416
|
out = obj.link(self, *args, **kwargs, &blk) if obj.respond_to?(:link)
|
397
417
|
if !out
|
398
|
-
warn log_message(Logger::WARN, 'link not compatible', subject: obj.to_s, hint: name
|
418
|
+
warn log_message(Logger::WARN, 'link not compatible', subject: obj.to_s, hint: name)
|
399
419
|
elsif out.respond_to?(:build)
|
400
420
|
out.build
|
401
421
|
end
|
@@ -409,7 +429,7 @@ module Squared
|
|
409
429
|
|
410
430
|
run_b(@run, sync: sync, from: from) if series?(@run)
|
411
431
|
args = @output
|
412
|
-
banner = verbosetype > 1 if
|
432
|
+
banner = verbosetype > 1 if from_base?('build')
|
413
433
|
end
|
414
434
|
if args.first.is_a?(Struct)
|
415
435
|
f, blk = args.first.to_a
|
@@ -450,9 +470,9 @@ module Squared
|
|
450
470
|
case opts
|
451
471
|
when Hash
|
452
472
|
opts = append_hash(opts, build: true)
|
453
|
-
cmd =
|
473
|
+
cmd = Array(cmd).push(flags).concat(opts).compact.join(' ')
|
454
474
|
when Enumerable
|
455
|
-
cmd =
|
475
|
+
cmd = Array(cmd).concat(opts.to_a)
|
456
476
|
cmd.map! { |val| "#{val} #{flags}" } if flags
|
457
477
|
cmd = cmd.join(' && ')
|
458
478
|
else
|
@@ -464,13 +484,40 @@ module Squared
|
|
464
484
|
cmd = compose(as_get(opts), flags, script: true, args: extra, from: from)
|
465
485
|
from = :script if from == :run && script?
|
466
486
|
end
|
467
|
-
run(cmd, var, from: from, banner: banner
|
487
|
+
run(cmd, var, sync: sync, from: from, banner: banner)
|
468
488
|
end
|
469
489
|
|
470
490
|
def depend(*, sync: invoked_sync?('depend'), **)
|
471
491
|
run_b(@depend, sync: sync, from: :depend)
|
472
492
|
end
|
473
493
|
|
494
|
+
def prereqs(*, sync: invoked_sync?('prereqs'), **)
|
495
|
+
on :first, :prereqs
|
496
|
+
graph_deps.flatten(1).sort.each do |proj|
|
497
|
+
next if @@graph[:_].include?(proj)
|
498
|
+
|
499
|
+
if (val = ENV["PREREQS_#{proj.instance_variable_get(:@envname)}"] || ENV["PREREQS_#{proj.ref.upcase}"])
|
500
|
+
val.split(/\s*,\s*/).each do |meth|
|
501
|
+
if proj.respond_to?(meth.to_sym)
|
502
|
+
begin
|
503
|
+
proj.__send__(meth, sync: sync)
|
504
|
+
rescue StandardError => e
|
505
|
+
ret = on(:error, :prereqs, e)
|
506
|
+
raise unless ret == true
|
507
|
+
else
|
508
|
+
next
|
509
|
+
end
|
510
|
+
end
|
511
|
+
warn log_message(Logger::WARN, name, 'method not found', subject: 'prereqs', hint: meth)
|
512
|
+
end
|
513
|
+
elsif proj.build?
|
514
|
+
proj.build(sync: sync)
|
515
|
+
end
|
516
|
+
@@graph[:_] << proj
|
517
|
+
end
|
518
|
+
on :last, :prereqs
|
519
|
+
end
|
520
|
+
|
474
521
|
def archive(*, sync: invoked_sync?('archive'), **)
|
475
522
|
return unless @archive.is_a?(Hash)
|
476
523
|
|
@@ -478,7 +525,7 @@ module Squared
|
|
478
525
|
end
|
479
526
|
|
480
527
|
def doc(*, sync: invoked_sync?('doc'), **)
|
481
|
-
run_b(@doc, sync: sync, from: :doc)
|
528
|
+
run_b(@doc, sync: sync, from: :doc, banner: from_base?('doc') ? verbosetype > 1 : verbose)
|
482
529
|
end
|
483
530
|
|
484
531
|
def lint(*, sync: invoked_sync?('lint'), **)
|
@@ -542,7 +589,7 @@ module Squared
|
|
542
589
|
on :last, :clean unless pass
|
543
590
|
end
|
544
591
|
|
545
|
-
def graph(start = [], tasks = nil, sync: invoked_sync?('graph'), pass: [], out: nil)
|
592
|
+
def graph(start = [], tasks = nil, *, sync: invoked_sync?('graph'), pass: [], out: nil, **)
|
546
593
|
if (val = env('GRAPH', strict: true))
|
547
594
|
tasks ||= []
|
548
595
|
split_escape(val).each do |task|
|
@@ -560,14 +607,13 @@ module Squared
|
|
560
607
|
data[name] << self
|
561
608
|
on :first, :graph
|
562
609
|
end
|
563
|
-
|
564
|
-
|
565
|
-
|
566
|
-
|
567
|
-
|
568
|
-
end
|
610
|
+
ret = graph_branch(self, data, tasks, out, sync: sync, pass: pass)
|
611
|
+
rescue StandardError => e
|
612
|
+
ret = on(:error, :graph, e)
|
613
|
+
raise unless ret == true
|
614
|
+
else
|
569
615
|
if out
|
570
|
-
[out,
|
616
|
+
[out, ret]
|
571
617
|
else
|
572
618
|
on :last, :graph
|
573
619
|
end
|
@@ -606,7 +652,7 @@ module Squared
|
|
606
652
|
headers = headers.is_a?(Hash) ? headers.merge(val) : val
|
607
653
|
end
|
608
654
|
data = nil
|
609
|
-
(uri =
|
655
|
+
(uri = Array(uri)).each_with_index do |url, index|
|
610
656
|
fetch_uri(url, headers) do |f|
|
611
657
|
data = f.read
|
612
658
|
if algo && algo.hexdigest(data) != digest
|
@@ -644,7 +690,7 @@ module Squared
|
|
644
690
|
file.write(data)
|
645
691
|
file.close
|
646
692
|
if create
|
647
|
-
warn log_message(Logger::WARN, 'force remove', subject: name, hint: target
|
693
|
+
warn log_message(Logger::WARN, 'force remove', subject: name, hint: target)
|
648
694
|
target.rmtree
|
649
695
|
target.mkpath
|
650
696
|
end
|
@@ -736,32 +782,46 @@ module Squared
|
|
736
782
|
self
|
737
783
|
end
|
738
784
|
|
739
|
-
def variable_set(key, *
|
740
|
-
if variables.include?(key)
|
785
|
+
def variable_set(key, *args, **kwargs, &blk)
|
786
|
+
if variables.include?(key) || blocks.include?(key)
|
787
|
+
val = case args.size
|
788
|
+
when 0
|
789
|
+
nil
|
790
|
+
when 1
|
791
|
+
args.first
|
792
|
+
else
|
793
|
+
args
|
794
|
+
end
|
741
795
|
case key
|
742
|
-
when :
|
743
|
-
|
796
|
+
when :index
|
797
|
+
index_set val
|
798
|
+
when :graph
|
799
|
+
graph_set val
|
800
|
+
when :pass
|
801
|
+
pass_set val
|
802
|
+
when :exclude
|
803
|
+
exclude_set val
|
804
|
+
when :parent
|
805
|
+
parent_set val
|
806
|
+
when :archive
|
807
|
+
archive_set val
|
808
|
+
when :run
|
809
|
+
run_set(*args, **kwargs)
|
744
810
|
when :script
|
745
|
-
script_set(*
|
811
|
+
script_set(*args, **kwargs)
|
746
812
|
when :env
|
747
|
-
run_set(output[0], *
|
748
|
-
when :parent
|
749
|
-
@parent = val if (val = val.first).is_a?(Project::Base)
|
750
|
-
when :graph
|
751
|
-
@graph = case val.first
|
752
|
-
when NilClass, FalseClass
|
753
|
-
nil
|
754
|
-
else
|
755
|
-
val.flatten.map!(&:to_s).freeze
|
756
|
-
end
|
813
|
+
run_set(output[0], *args, **kwargs)
|
757
814
|
when :dependfile
|
758
|
-
@dependfile = basepath(*
|
815
|
+
@dependfile = basepath(*args)
|
759
816
|
else
|
760
|
-
if
|
761
|
-
|
762
|
-
|
763
|
-
|
817
|
+
if block_given?
|
818
|
+
if blocks.include?(key)
|
819
|
+
series key, &blk
|
820
|
+
return self
|
821
|
+
end
|
822
|
+
val = block_args val, &blk
|
764
823
|
end
|
824
|
+
instance_variable_set(:"@#{key}", val.first)
|
765
825
|
end
|
766
826
|
else
|
767
827
|
log&.warn "variable_set: @#{key} (private)"
|
@@ -805,6 +865,15 @@ module Squared
|
|
805
865
|
@graph.is_a?(Array) && !@graph.empty?
|
806
866
|
end
|
807
867
|
|
868
|
+
def prereqs?
|
869
|
+
target = self
|
870
|
+
loop do
|
871
|
+
return true if target.graph?
|
872
|
+
break unless (target = target.parent)
|
873
|
+
end
|
874
|
+
false
|
875
|
+
end
|
876
|
+
|
808
877
|
def copy?
|
809
878
|
runnable?(@copy) || workspace.task_defined?(name, 'copy')
|
810
879
|
end
|
@@ -897,16 +966,28 @@ module Squared
|
|
897
966
|
puts_oe(*args, pipe: pipe)
|
898
967
|
end
|
899
968
|
|
900
|
-
def run(cmd = @session, var = nil, exception: @exception, sync: true, banner: true, chdir: path,
|
969
|
+
def run(cmd = @session, var = nil, exception: @exception, sync: true, from: nil, banner: true, chdir: path,
|
970
|
+
interactive: nil, **)
|
901
971
|
unless cmd
|
902
|
-
|
903
|
-
|
904
|
-
warn log_message(Logger::WARN, from || 'unknown', subject: project, hint: 'no command given', pass: true)
|
905
|
-
end
|
906
|
-
return
|
972
|
+
from = from&.to_s || 'unknown'
|
973
|
+
return warn log_message(Logger::WARN, 'no command given', subject: project, hint: from, pass: true)
|
907
974
|
end
|
975
|
+
i = interactive && !(@session && option('y'))
|
908
976
|
cmd = cmd.target if cmd.is_a?(OptionPartition)
|
909
977
|
cmd = session_done cmd
|
978
|
+
if i
|
979
|
+
title, y = case interactive
|
980
|
+
when Array
|
981
|
+
interactive
|
982
|
+
when String
|
983
|
+
[interactive, 'N']
|
984
|
+
else
|
985
|
+
['Run', 'Y']
|
986
|
+
end
|
987
|
+
unless confirm("#{title}? [#{sub_style(cmd, styles: theme[:inline])}] #{y == 'Y' ? '[Y/n]' : '[y/N]'} ", y)
|
988
|
+
raise_error('user cancelled', hint: from)
|
989
|
+
end
|
990
|
+
end
|
910
991
|
log&.info cmd
|
911
992
|
on :first, from
|
912
993
|
begin
|
@@ -940,7 +1021,7 @@ module Squared
|
|
940
1021
|
end
|
941
1022
|
end
|
942
1023
|
|
943
|
-
def run_s(*cmd, env: nil, sync: true, banner: verbose != false,
|
1024
|
+
def run_s(*cmd, env: nil, sync: true, from: nil, banner: verbose != false, **kwargs)
|
944
1025
|
on :first, from
|
945
1026
|
begin
|
946
1027
|
cmd.flatten.each { |val| run(val, env, sync: sync, banner: banner, **kwargs) }
|
@@ -951,11 +1032,11 @@ module Squared
|
|
951
1032
|
on :last, from
|
952
1033
|
end
|
953
1034
|
|
954
|
-
def run_b(obj,
|
1035
|
+
def run_b(obj, **kwargs)
|
955
1036
|
case obj
|
956
1037
|
when Struct
|
957
1038
|
if (any = instance_eval(&obj.block) || obj.run)
|
958
|
-
run_b(any,
|
1039
|
+
run_b(any, **kwargs)
|
959
1040
|
end
|
960
1041
|
when Proc
|
961
1042
|
instance_eval(&obj)
|
@@ -965,9 +1046,9 @@ module Squared
|
|
965
1046
|
if series?(obj)
|
966
1047
|
obj.each(&:call)
|
967
1048
|
elsif obj.is_a?(Array) && obj.any? { |val| !val.is_a?(String) }
|
968
|
-
build(*obj,
|
1049
|
+
build(*obj, **kwargs)
|
969
1050
|
elsif obj
|
970
|
-
run_s(obj
|
1051
|
+
run_s(*Array(obj), **kwargs)
|
971
1052
|
end
|
972
1053
|
end
|
973
1054
|
end
|
@@ -1014,7 +1095,7 @@ module Squared
|
|
1014
1095
|
|
1015
1096
|
t = dedupe.call(proj.name)
|
1016
1097
|
j = if out
|
1017
|
-
if i == items.size - 1 || check.call(post = items[i + 1..-1]).empty?
|
1098
|
+
if i == items.size - 1 || check.call(post = items[(i + 1)..-1]).empty?
|
1018
1099
|
true
|
1019
1100
|
elsif !t.empty? && depth > 0
|
1020
1101
|
post.reject { |pr| t.include?(pr) }.empty?
|
@@ -1026,9 +1107,9 @@ module Squared
|
|
1026
1107
|
end
|
1027
1108
|
if !out
|
1028
1109
|
if !tasks && (script = workspace.script_get(:graph, group: proj.group, ref: proj.allref))
|
1029
|
-
|
1110
|
+
tasks = script[:graph]
|
1030
1111
|
end
|
1031
|
-
(tasks ||
|
1112
|
+
(tasks || (dev? ? ['build', 'copy'] : ['depend', 'build'])).each do |meth|
|
1032
1113
|
next if pass.include?(meth)
|
1033
1114
|
|
1034
1115
|
if workspace.task_defined?(cmd = task_join(proj.name, meth))
|
@@ -1039,7 +1120,7 @@ module Squared
|
|
1039
1120
|
end
|
1040
1121
|
run(cmd, sync: false, banner: false)
|
1041
1122
|
ENV.delete(key) if key
|
1042
|
-
elsif proj.has?(meth, tasks
|
1123
|
+
elsif proj.has?(meth, tasks ? nil : workspace.baseref)
|
1043
1124
|
proj.__send__(meth.to_sym, sync: sync)
|
1044
1125
|
end
|
1045
1126
|
end
|
@@ -1052,7 +1133,7 @@ module Squared
|
|
1052
1133
|
k = 0
|
1053
1134
|
final = data.keys.last
|
1054
1135
|
while k < depth
|
1055
|
-
indent = k > 0
|
1136
|
+
indent = k > 0 ? ((last && !j) || (j && k == depth - 1) || single) : j && last && depth == 1
|
1056
1137
|
s += "#{indent || (last && data[final].last == context) ? ' ' : a} "
|
1057
1138
|
k += 1
|
1058
1139
|
end
|
@@ -1076,7 +1157,6 @@ module Squared
|
|
1076
1157
|
else
|
1077
1158
|
items = workspace.find(group: val, ref: val.to_sym)
|
1078
1159
|
end
|
1079
|
-
|
1080
1160
|
items.each do |proj|
|
1081
1161
|
next if pass.include?(proj.name)
|
1082
1162
|
|
@@ -1087,10 +1167,28 @@ module Squared
|
|
1087
1167
|
deps.concat(objs)
|
1088
1168
|
end
|
1089
1169
|
end
|
1090
|
-
|
1170
|
+
deps.uniq!
|
1171
|
+
deps.delete(target)
|
1172
|
+
data[target.name] = deps
|
1091
1173
|
data
|
1092
1174
|
end
|
1093
1175
|
|
1176
|
+
def graph_deps(target = self)
|
1177
|
+
key = target.name
|
1178
|
+
return @@graph[key] if @@graph.key?(key)
|
1179
|
+
|
1180
|
+
base = []
|
1181
|
+
deps = []
|
1182
|
+
loop do
|
1183
|
+
deps.concat(graph_branch(target, graph_collect(target), []))
|
1184
|
+
break unless (target = target.parent)
|
1185
|
+
|
1186
|
+
base << target
|
1187
|
+
end
|
1188
|
+
deps.uniq!
|
1189
|
+
@@graph[key] = [base, deps]
|
1190
|
+
end
|
1191
|
+
|
1094
1192
|
def env(key, default = nil, suffix: nil, equals: nil, ignore: nil, strict: false)
|
1095
1193
|
a = "#{key}_#{@envname}"
|
1096
1194
|
ret = if suffix
|
@@ -1103,7 +1201,7 @@ module Squared
|
|
1103
1201
|
end
|
1104
1202
|
return ret == equals.to_s unless equals.nil?
|
1105
1203
|
|
1106
|
-
ret.empty? || (ignore &&
|
1204
|
+
ret.empty? || (ignore && Array(ignore).any? { |val| ret == val.to_s }) ? default : ret
|
1107
1205
|
end
|
1108
1206
|
|
1109
1207
|
def session(*cmd, prefix: cmd.first, main: true, path: true, options: true)
|
@@ -1142,10 +1240,16 @@ module Squared
|
|
1142
1240
|
cmd.done
|
1143
1241
|
end
|
1144
1242
|
|
1243
|
+
def session_arg?(*args, target: @session, **kwargs)
|
1244
|
+
return false unless target
|
1245
|
+
|
1246
|
+
OptionPartition.arg?(target, *args, **kwargs)
|
1247
|
+
end
|
1248
|
+
|
1145
1249
|
def option(*args, target: @session, prefix: target&.first, **kwargs)
|
1146
1250
|
if prefix
|
1147
1251
|
args.each do |val|
|
1148
|
-
ret = env(
|
1252
|
+
ret = env(env_key(stripext(prefix), val), **kwargs)
|
1149
1253
|
return ret if ret
|
1150
1254
|
end
|
1151
1255
|
end
|
@@ -1168,7 +1272,7 @@ module Squared
|
|
1168
1272
|
end
|
1169
1273
|
|
1170
1274
|
def print_item(*val)
|
1171
|
-
puts
|
1275
|
+
puts unless printfirst?
|
1172
1276
|
printsucc
|
1173
1277
|
puts val unless val.empty? || (val.size == 1 && val.first.nil?)
|
1174
1278
|
end
|
@@ -1209,6 +1313,18 @@ module Squared
|
|
1209
1313
|
ret.join("\n")
|
1210
1314
|
end
|
1211
1315
|
|
1316
|
+
def print_status(*args, from: nil)
|
1317
|
+
return if stdin?
|
1318
|
+
|
1319
|
+
case from
|
1320
|
+
when :outdated
|
1321
|
+
out = print_footer("major #{args[0]} / minor #{args[1]} / patch #{args[2]}", right: true).split("\n")
|
1322
|
+
out[1] = sub_style(out[1], pat: /^( +major )(\d+)(.+)$/, styles: theme[:major], index: 2)
|
1323
|
+
out[1] = sub_style(out[1], pat: /^(.+)(minor )(\d+)(.+)$/, styles: theme[:active], index: 3)
|
1324
|
+
puts out
|
1325
|
+
end
|
1326
|
+
end
|
1327
|
+
|
1212
1328
|
def format_desc(action, flag, opts = nil, **kwargs)
|
1213
1329
|
return unless TASK_METADATA
|
1214
1330
|
|
@@ -1230,7 +1346,7 @@ module Squared
|
|
1230
1346
|
if verbose
|
1231
1347
|
out = []
|
1232
1348
|
if data[:command]
|
1233
|
-
if cmd =~ /\A(?:"((?:[^"]|(?<=\\)")+)"|'((?:[^']|(?<=\\)')+)'|(\S+)) /
|
1349
|
+
if cmd =~ /\A(?:"((?:[^"]|(?<=\\)")+)"|'((?:[^']|(?<=\\)')+)'|(\S+))( |\z)/
|
1234
1350
|
path = $3 || $2 || $1
|
1235
1351
|
cmd = cmd.sub(path, stripext(path).upcase)
|
1236
1352
|
end
|
@@ -1282,7 +1398,7 @@ module Squared
|
|
1282
1398
|
out << ''
|
1283
1399
|
end
|
1284
1400
|
if from
|
1285
|
-
out << from
|
1401
|
+
out << (from = from.to_s)
|
1286
1402
|
pat = /\A(#{Regexp.escape(from)})(.*)\z/
|
1287
1403
|
end
|
1288
1404
|
else
|
@@ -1451,7 +1567,7 @@ module Squared
|
|
1451
1567
|
raise_error("invalid JSON #{kind.name}", val, hint: hint) if kind && !ret.is_a?(kind)
|
1452
1568
|
rescue StandardError => e
|
1453
1569
|
log&.warn e
|
1454
|
-
warn log_message(Logger::WARN, e, subject: name
|
1570
|
+
warn log_message(Logger::WARN, e, subject: name) if warning?
|
1455
1571
|
else
|
1456
1572
|
ret
|
1457
1573
|
end
|
@@ -1508,25 +1624,28 @@ module Squared
|
|
1508
1624
|
end
|
1509
1625
|
ret = multiple ? ret.map! { |val| val.sub(trim, '') } : ret.sub(trim, '') if trim
|
1510
1626
|
if column
|
1511
|
-
a, b =
|
1512
|
-
ret =
|
1627
|
+
a, b = Array(column)
|
1628
|
+
ret = Array(ret).map! { |val| val[a, b || 1] }
|
1513
1629
|
ret = ret.first unless multiple
|
1514
1630
|
end
|
1515
1631
|
if accept
|
1516
|
-
|
1517
|
-
accept =
|
1632
|
+
hint = Array(ret).map { |val| sub_style(val, styles: theme[:inline]) }.join(', ')
|
1633
|
+
accept = Array(accept).map { |val| Array(val) }
|
1518
1634
|
if accept.any? { |val| val[1] == true }
|
1519
1635
|
ret = [ret]
|
1520
1636
|
multiple = -1
|
1521
1637
|
end
|
1522
1638
|
loop do
|
1523
|
-
|
1524
|
-
|
1639
|
+
item = accept.first
|
1640
|
+
d, e = item[2] ? ['Y', '[Y/n]'] : ['N', '[y/N]']
|
1641
|
+
c = confirm("#{item[0]}#{a ? " [#{a}]" : ''} #{e} ", d, timeout: 60)
|
1642
|
+
if item[1] == true
|
1525
1643
|
ret << c
|
1526
1644
|
elsif !c
|
1527
1645
|
break
|
1528
1646
|
end
|
1529
|
-
|
1647
|
+
hint = nil
|
1648
|
+
accept.shift
|
1530
1649
|
break if accept.empty?
|
1531
1650
|
end
|
1532
1651
|
exit 1 unless accept.empty?
|
@@ -1547,6 +1666,20 @@ module Squared
|
|
1547
1666
|
ret
|
1548
1667
|
end
|
1549
1668
|
|
1669
|
+
def command_args(args, force: false, **kwargs)
|
1670
|
+
return unless args.size == 1 && !option('i', 'interactive', **kwargs, equals: '0')
|
1671
|
+
|
1672
|
+
readline('Enter arguments', force: force)
|
1673
|
+
end
|
1674
|
+
|
1675
|
+
def block_args(val = nil, &blk)
|
1676
|
+
if (ret = instance_eval(&blk)).nil?
|
1677
|
+
val
|
1678
|
+
else
|
1679
|
+
Array(ret)
|
1680
|
+
end
|
1681
|
+
end
|
1682
|
+
|
1550
1683
|
def runenv
|
1551
1684
|
nil
|
1552
1685
|
end
|
@@ -1597,13 +1730,17 @@ module Squared
|
|
1597
1730
|
end
|
1598
1731
|
|
1599
1732
|
def indexitem(val)
|
1600
|
-
[$1.to_i, $2 && $2[1..-1]] if val =~ /\A
|
1733
|
+
[$1.to_i, $2 && $2[1..-1]] if val =~ /\A[=^#{indexchar}](\d+)(:.+)?\z/
|
1601
1734
|
end
|
1602
1735
|
|
1603
1736
|
def indexerror(val, list = nil)
|
1604
1737
|
raise_error("requested index #{val}", hint: list && "of #{list.size}")
|
1605
1738
|
end
|
1606
1739
|
|
1740
|
+
def indexchar
|
1741
|
+
workspace.windows? ? '=' : '^'
|
1742
|
+
end
|
1743
|
+
|
1607
1744
|
def printsucc
|
1608
1745
|
@@print_order += 1
|
1609
1746
|
end
|
@@ -1656,7 +1793,8 @@ module Squared
|
|
1656
1793
|
pwd = Pathname.pwd
|
1657
1794
|
if block_given?
|
1658
1795
|
begin
|
1659
|
-
|
1796
|
+
pass = semscan(pass).join <= RUBY_VERSION if pass.is_a?(String)
|
1797
|
+
if (path == pwd || pass == true) && !workspace.jruby_win?
|
1660
1798
|
ret = yield
|
1661
1799
|
else
|
1662
1800
|
Dir.chdir(path)
|
@@ -1749,6 +1887,72 @@ module Squared
|
|
1749
1887
|
@output[4] = args unless @output[4] == false || args.nil?
|
1750
1888
|
end
|
1751
1889
|
|
1890
|
+
def index_set(val)
|
1891
|
+
@index = val if val.is_a?(Numeric)
|
1892
|
+
end
|
1893
|
+
|
1894
|
+
def parent_set(val)
|
1895
|
+
@parent = val if val.is_a?(Project::Base)
|
1896
|
+
end
|
1897
|
+
|
1898
|
+
def exception_set(val)
|
1899
|
+
@exception = env_bool(val, workspace.exception, strict: true)
|
1900
|
+
end
|
1901
|
+
|
1902
|
+
def pipe_set(val)
|
1903
|
+
@pipe = env_pipe(val, workspace.pipe, strict: true)
|
1904
|
+
end
|
1905
|
+
|
1906
|
+
def verbose_set(val)
|
1907
|
+
@verbose = case val
|
1908
|
+
when NilClass
|
1909
|
+
workspace.verbose
|
1910
|
+
when String
|
1911
|
+
env_bool(val, workspace.verbose, strict: true, index: true)
|
1912
|
+
else
|
1913
|
+
val
|
1914
|
+
end
|
1915
|
+
end
|
1916
|
+
|
1917
|
+
def graph_set(val)
|
1918
|
+
@graph = if val
|
1919
|
+
Array(val).map { |s| workspace.prefix ? workspace.task_name(s).to_sym : s.to_sym }.freeze
|
1920
|
+
end
|
1921
|
+
end
|
1922
|
+
|
1923
|
+
def pass_set(val)
|
1924
|
+
@pass = (val ? as_a(val, :to_s) : []).freeze
|
1925
|
+
end
|
1926
|
+
|
1927
|
+
def exclude_set(val)
|
1928
|
+
@exclude = (val ? as_a(val, :to_sym) : []).freeze
|
1929
|
+
end
|
1930
|
+
|
1931
|
+
def archive_set(val)
|
1932
|
+
@archive = case val
|
1933
|
+
when String, Array
|
1934
|
+
{ uri: val }
|
1935
|
+
when Hash
|
1936
|
+
val
|
1937
|
+
end
|
1938
|
+
end
|
1939
|
+
|
1940
|
+
def theme_set(common)
|
1941
|
+
@theme = if !verbose
|
1942
|
+
{}
|
1943
|
+
elsif common
|
1944
|
+
workspace.theme
|
1945
|
+
else
|
1946
|
+
__get__(:theme)[:project][to_sym] ||= {}
|
1947
|
+
end
|
1948
|
+
end
|
1949
|
+
|
1950
|
+
def dependfile_set(list)
|
1951
|
+
@dependindex = list.index { |file| basepath(file).exist? }.tap do |index|
|
1952
|
+
@dependfile = @path + list[index || 0]
|
1953
|
+
end
|
1954
|
+
end
|
1955
|
+
|
1752
1956
|
def as_get(val)
|
1753
1957
|
return unless val
|
1754
1958
|
|
@@ -1781,6 +1985,15 @@ module Squared
|
|
1781
1985
|
val.absolute? ? val.to_s.start_with?(File.join(path, '')) : !val.to_s.start_with?(File.join('..', ''))
|
1782
1986
|
end
|
1783
1987
|
|
1988
|
+
def checkdir?(val)
|
1989
|
+
if val.directory? && !val.empty?
|
1990
|
+
true
|
1991
|
+
else
|
1992
|
+
log&.warn "directory \"#{val}\" (#{val.empty? ? 'empty' : 'not found'})"
|
1993
|
+
false
|
1994
|
+
end
|
1995
|
+
end
|
1996
|
+
|
1784
1997
|
def semmajor?(cur, want)
|
1785
1998
|
(cur[0] == '0' && want[0] == '0' ? cur[2] != want[2] : cur[0] != want[0]) && !want[5]
|
1786
1999
|
end
|
@@ -1802,8 +2015,8 @@ module Squared
|
|
1802
2015
|
val.is_a?(Array) && val.all? { |p| p.is_a?(Proc) || p.is_a?(Method) }
|
1803
2016
|
end
|
1804
2017
|
|
1805
|
-
def
|
1806
|
-
|
2018
|
+
def from_base?(val)
|
2019
|
+
task_invoked?(val, "#{val}:sync", 'default')
|
1807
2020
|
end
|
1808
2021
|
|
1809
2022
|
def from_sync?(*val)
|
@@ -1819,13 +2032,10 @@ module Squared
|
|
1819
2032
|
return val if group && !(val = from_sync?(ac, group)).nil?
|
1820
2033
|
return val if (base = workspace.find_base(self)) && !(val = from_sync?(ac, base.ref)).nil?
|
1821
2034
|
return false if workspace.series.chain?(val = task_join(name, action))
|
2035
|
+
return true if task_invoked?(val) && (!task_invoked?(ac) || !workspace.task_defined?(ac, 'sync'))
|
1822
2036
|
|
1823
|
-
|
1824
|
-
|
1825
|
-
else
|
1826
|
-
val = workspace.series.name_get(action)
|
1827
|
-
val != action && invoked_sync?(val)
|
1828
|
-
end
|
2037
|
+
val = workspace.series.name_get(action)
|
2038
|
+
val != action && invoked_sync?(val)
|
1829
2039
|
end
|
1830
2040
|
|
1831
2041
|
def success?(ret)
|
@@ -1836,6 +2046,10 @@ module Squared
|
|
1836
2046
|
ARG[:BANNER] && !env('BANNER', equals: '0')
|
1837
2047
|
end
|
1838
2048
|
|
2049
|
+
def pwd?
|
2050
|
+
path == Pathname.pwd
|
2051
|
+
end
|
2052
|
+
|
1839
2053
|
def stdin?
|
1840
2054
|
pipe == 0
|
1841
2055
|
end
|
@@ -1848,22 +2062,19 @@ module Squared
|
|
1848
2062
|
workspace.warning
|
1849
2063
|
end
|
1850
2064
|
|
1851
|
-
def has_value?(data,
|
1852
|
-
|
1853
|
-
|
1854
|
-
|
1855
|
-
|
1856
|
-
|
1857
|
-
|
1858
|
-
|
1859
|
-
when Enumerable
|
1860
|
-
data.to_a.include?(obj)
|
1861
|
-
end
|
2065
|
+
def has_value?(data, other)
|
2066
|
+
case data
|
2067
|
+
when Hash
|
2068
|
+
other.is_a?(Enumerable) ? other.any? { |obj| data.value?(obj) } : data.value?(other)
|
2069
|
+
when Enumerable
|
2070
|
+
other.is_a?(Enumerable) ? other.any? { |obj| data.include?(obj) } : data.include?(other)
|
2071
|
+
else
|
2072
|
+
false
|
1862
2073
|
end
|
1863
2074
|
end
|
1864
2075
|
|
1865
2076
|
def variables
|
1866
|
-
|
2077
|
+
VAR_SET
|
1867
2078
|
end
|
1868
2079
|
|
1869
2080
|
def blocks
|