squared 0.2.10 → 0.3.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 +54 -101
- data/README.ruby.md +150 -68
- data/lib/squared/common/base.rb +3 -1
- data/lib/squared/common/class.rb +27 -2
- data/lib/squared/common/format.rb +12 -12
- data/lib/squared/common/prompt.rb +1 -1
- data/lib/squared/common/shell.rb +11 -13
- data/lib/squared/common/utils.rb +24 -13
- data/lib/squared/config.rb +4 -3
- data/lib/squared/version.rb +1 -1
- data/lib/squared/workspace/application.rb +54 -19
- data/lib/squared/workspace/project/base.rb +350 -158
- data/lib/squared/workspace/project/git.rb +543 -338
- data/lib/squared/workspace/project/node.rb +248 -107
- data/lib/squared/workspace/project/python.rb +101 -78
- data/lib/squared/workspace/project/ruby.rb +179 -169
- data/lib/squared/workspace/repo.rb +9 -4
- data/lib/squared/workspace/series.rb +10 -4
- data/squared.gemspec +0 -1
- metadata +3 -17
@@ -25,7 +25,7 @@ module Squared
|
|
25
25
|
def bannerargs(*); end
|
26
26
|
|
27
27
|
def tasks
|
28
|
-
%i[build depend graph doc test copy clean].freeze
|
28
|
+
%i[build depend graph doc lint test copy clean].freeze
|
29
29
|
end
|
30
30
|
|
31
31
|
def as_path(val)
|
@@ -46,7 +46,7 @@ module Squared
|
|
46
46
|
end
|
47
47
|
|
48
48
|
def to_s
|
49
|
-
super
|
49
|
+
super[/[^:]+\z/, 0]
|
50
50
|
end
|
51
51
|
end
|
52
52
|
|
@@ -68,12 +68,19 @@ module Squared
|
|
68
68
|
@group = group&.to_s.freeze
|
69
69
|
@depend = kwargs[:depend]
|
70
70
|
@doc = kwargs[:doc]
|
71
|
+
@lint = kwargs[:lint]
|
71
72
|
@test = kwargs[:test]
|
72
73
|
@copy = kwargs[:copy]
|
73
74
|
@clean = kwargs[:clean]
|
74
75
|
@version = kwargs[:version]
|
75
|
-
@
|
76
|
-
|
76
|
+
@envname = @name.gsub(/[^\w]+/, '_').upcase.freeze
|
77
|
+
kwargs[:exception] = 'PIPE_FAIL'
|
78
|
+
@exception = if kwargs.key?(:exception)
|
79
|
+
env_bool(kwargs[:exception], workspace.exception, strict: true)
|
80
|
+
else
|
81
|
+
workspace.exception
|
82
|
+
end
|
83
|
+
@pipe = kwargs.key?(:pipe) ? env_pipe(kwargs[:pipe], workspace.pipe, strict: true) : workspace.pipe
|
77
84
|
@verbose = kwargs.key?(:verbose) ? kwargs[:verbose] : workspace.verbose
|
78
85
|
@theme = if !@verbose
|
79
86
|
{}
|
@@ -95,7 +102,6 @@ module Squared
|
|
95
102
|
last: last,
|
96
103
|
error: error
|
97
104
|
}
|
98
|
-
@envname = @name.gsub(/[^\w]+/, '_').upcase.freeze
|
99
105
|
@desc = (@name.include?(':') ? @name.split(':').join(ARG[:SPACE]) : @name).freeze
|
100
106
|
@parent = nil
|
101
107
|
@global = false
|
@@ -116,6 +122,7 @@ module Squared
|
|
116
122
|
end
|
117
123
|
@depend = @script[:depend] if @depend.nil?
|
118
124
|
@doc = @script[:doc] if @doc.nil?
|
125
|
+
@lint = @script[:lint] if @lint.nil?
|
119
126
|
@test = @script[:test] if @test.nil?
|
120
127
|
@clean = @script[:clean] if @clean.nil?
|
121
128
|
@exclude = @script[:exclude] if @exclude.empty? && @script.key?(:exclude)
|
@@ -128,7 +135,7 @@ module Squared
|
|
128
135
|
if @output[0].nil?
|
129
136
|
if (scr = data[:script])
|
130
137
|
@global = true
|
131
|
-
script_set(scr, prod: kwargs[:prod])
|
138
|
+
script_set(scr, args: data.fetch(:args, kwargs[:args]), prod: kwargs[:prod])
|
132
139
|
elsif (run = data[:run])
|
133
140
|
@global = true
|
134
141
|
run_set run
|
@@ -136,11 +143,11 @@ module Squared
|
|
136
143
|
unless data[:env]
|
137
144
|
if (scr = kwargs[:script])
|
138
145
|
@global = false
|
139
|
-
script_set
|
146
|
+
script_set(scr, args: kwargs[:args])
|
140
147
|
elsif @script && !data[:global]
|
141
148
|
if (scr = @script[:script])
|
142
149
|
@global = false
|
143
|
-
script_set
|
150
|
+
script_set(scr, args: @script.fetch(:args, kwargs[:args]))
|
144
151
|
elsif (run = @script[:run])
|
145
152
|
@global = false
|
146
153
|
run_set run
|
@@ -151,6 +158,7 @@ module Squared
|
|
151
158
|
@global = true
|
152
159
|
run_set data[:run]
|
153
160
|
end
|
161
|
+
@global = true
|
154
162
|
end
|
155
163
|
|
156
164
|
def initialize_events(ref, **)
|
@@ -163,24 +171,19 @@ module Squared
|
|
163
171
|
return if @log
|
164
172
|
|
165
173
|
log = log.is_a?(Hash) ? log.dup : { file: log }
|
166
|
-
|
167
|
-
file =
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
elsif (val = log[:file])
|
180
|
-
file = val.is_a?(String) ? DateTime.now.strftime(val) : "#{@name}-#{Date.today}.log"
|
181
|
-
end
|
182
|
-
if file
|
183
|
-
file = (val = env('LOG_DIR')) ? @workspace.home.join(val, file) : @workspace.home.join(file)
|
174
|
+
unless (file = env('LOG_FILE'))
|
175
|
+
file = case env('LOG_AUTO')
|
176
|
+
when 'y', 'year'
|
177
|
+
"#{@name}-#{Date.today.year}.log"
|
178
|
+
when 'm', 'month'
|
179
|
+
"#{@name}-#{Date.today.strftime('%Y-%m')}.log"
|
180
|
+
when 'd', 'day', '1'
|
181
|
+
"#{@name}-#{Date.today}.log"
|
182
|
+
end
|
183
|
+
end
|
184
|
+
if file ||= log[:file]
|
185
|
+
file = Date.today.strftime(file)
|
186
|
+
file = (dir = env('LOG_DIR')) ? @workspace.home.join(dir, file) : @workspace.home.join(file)
|
184
187
|
begin
|
185
188
|
file = file.realdirpath
|
186
189
|
rescue StandardError => e
|
@@ -199,23 +202,23 @@ module Squared
|
|
199
202
|
end
|
200
203
|
|
201
204
|
def initialize_env(dev: nil, prod: nil, **)
|
202
|
-
|
203
|
-
@
|
204
|
-
@prod = env_match("#{pre}_PROD", prod)
|
205
|
+
@dev = env_match('BUILD', dev, suffix: 'DEV', strict: true)
|
206
|
+
@prod = env_match('BUILD', prod, suffix: 'PROD', strict: true)
|
205
207
|
cmd = @output[0]
|
206
|
-
|
207
|
-
@output[cmd ? 1 : 3] = shell_split(val, escape: false, join: true)
|
208
|
-
end
|
209
|
-
unless @output[2] == false || (val = env('BUILD', suffix: 'ENV')).nil?
|
208
|
+
if @output[2] != false && (val = env('BUILD', suffix: 'ENV'))
|
210
209
|
begin
|
211
210
|
data = JSON.parse(val)
|
212
211
|
raise_error('invalid JSON object', val, hint: "#{prefix}_ENV") unless data.is_a?(Hash)
|
213
212
|
rescue StandardError => e
|
214
|
-
log
|
213
|
+
log.warn e
|
215
214
|
else
|
216
215
|
@output[2] = data
|
217
216
|
end
|
218
217
|
end
|
218
|
+
if cmd != false && !cmd.is_a?(Array)
|
219
|
+
@output[cmd ? 1 : 3] = shell_split(val, join: true) if (val = env('BUILD', suffix: 'OPTS'))
|
220
|
+
@output[4] = shell_split(val, join: true) if cmd.nil? && (val = env('SCRIPT', suffix: 'OPTS'))
|
221
|
+
end
|
219
222
|
@version = val if (val = env('BUILD', suffix: 'VERSION'))
|
220
223
|
return unless (val = env('BUILD', strict: true))
|
221
224
|
|
@@ -247,23 +250,16 @@ module Squared
|
|
247
250
|
when 'graph'
|
248
251
|
next unless graph?
|
249
252
|
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
if flag == :run
|
258
|
-
task flag do |_, args|
|
259
|
-
graph check.(args)
|
260
|
-
end
|
261
|
-
else
|
262
|
-
task flag do |_, args|
|
263
|
-
out, done = graph(check.(args), out: [])
|
253
|
+
format_desc action, flag, '(-)project*'
|
254
|
+
task flag do |_, args|
|
255
|
+
args = param_guard(action, flag, args: args.to_a.reject { |val| name == val.to_s })
|
256
|
+
if flag == :run
|
257
|
+
graph args
|
258
|
+
else
|
259
|
+
out, done = graph(args, out: [])
|
264
260
|
out.map! do |val|
|
265
261
|
done.each_with_index do |proj, i|
|
266
|
-
next unless
|
262
|
+
next unless val =~ / #{Regexp.escape(proj.name)}(?:@\d|\z)/
|
267
263
|
|
268
264
|
val += " (#{i.succ})"
|
269
265
|
break
|
@@ -302,12 +298,12 @@ module Squared
|
|
302
298
|
if val.directory? && !val.empty?
|
303
299
|
true
|
304
300
|
else
|
305
|
-
log
|
301
|
+
log.warn "workspace \"#{val}\" (#{val.empty? ? 'empty' : 'not found'})"
|
306
302
|
false
|
307
303
|
end
|
308
304
|
end
|
309
|
-
if path.is_a?(String) && (
|
310
|
-
return self unless checkdir.(path = basepath(
|
305
|
+
if path.is_a?(String) && (seg = path[%r{^(.+)[\\/]\*+$}, 1])
|
306
|
+
return self unless checkdir.(path = basepath(seg))
|
311
307
|
|
312
308
|
path = path.children.select { |val| checkdir.(val) }
|
313
309
|
end
|
@@ -345,64 +341,87 @@ module Squared
|
|
345
341
|
|
346
342
|
out = obj.link(self, *args, **kwargs, &blk) if obj.respond_to?(:link)
|
347
343
|
if !out
|
348
|
-
warn log_message(
|
344
|
+
warn log_message(Logger::WARN, 'link not compatible', subject: obj.to_s, hint: name)
|
349
345
|
elsif out.respond_to?(:build)
|
350
346
|
out.build
|
351
347
|
end
|
352
348
|
self
|
353
349
|
end
|
354
350
|
|
355
|
-
def build(*args,
|
351
|
+
def build(*args, sync: invoked_sync?('build'), from: :run, **)
|
356
352
|
banner = verbose
|
357
353
|
if args.empty?
|
358
354
|
return unless from == :run
|
359
355
|
|
360
|
-
|
356
|
+
args = @output
|
361
357
|
banner = verbose == 1 if task_invoked?('build', 'build:sync')
|
358
|
+
end
|
359
|
+
if args.all? { |val| val.is_a?(Array) }
|
360
|
+
cmd = []
|
361
|
+
var = {}
|
362
|
+
args.each do |val|
|
363
|
+
a, b, c, d, e = val
|
364
|
+
case b
|
365
|
+
when Hash
|
366
|
+
b = append_hash(b).join(' ')
|
367
|
+
when Enumerable
|
368
|
+
b = b.to_a.join(' ')
|
369
|
+
end
|
370
|
+
d = append_hash(d).join(' ') if d.is_a?(Hash)
|
371
|
+
if a
|
372
|
+
cmd << [a, d, b].compact.join(' ')
|
373
|
+
else
|
374
|
+
next unless respond_to?(:compose)
|
375
|
+
|
376
|
+
cmd << a if (a = compose(as_get(b), d, script: true, args: e, from: from))
|
377
|
+
end
|
378
|
+
var.merge!(c) if c.is_a?(Hash)
|
379
|
+
end
|
380
|
+
cmd = cmd.join(' && ')
|
362
381
|
else
|
363
|
-
cmd = args
|
364
|
-
opts = args.map { |val| shell_quote(val, force: false) }.join(' ')
|
382
|
+
cmd, opts, var, flags, scr = args
|
365
383
|
end
|
366
384
|
if cmd
|
385
|
+
cmd = as_get(cmd)
|
386
|
+
opts = compose(opts, script: false) if opts && respond_to?(:compose)
|
387
|
+
flags = append_hash(flags).join(' ') if flags.is_a?(Hash)
|
367
388
|
case opts
|
368
|
-
when
|
369
|
-
|
370
|
-
|
371
|
-
|
389
|
+
when Hash
|
390
|
+
opts = append_hash(opts)
|
391
|
+
cmd = as_a(cmd).push(flags).concat(opts).compact.join(' ')
|
392
|
+
when Enumerable
|
393
|
+
cmd = as_a(cmd).concat(opts.to_a)
|
394
|
+
cmd.map! { |val| "#{val} #{flags}" } if flags
|
395
|
+
cmd = cmd.join(' && ')
|
372
396
|
else
|
373
|
-
cmd = [cmd,
|
397
|
+
cmd = [cmd, flags, opts].compact.join(' ') if opts || flags
|
374
398
|
end
|
375
399
|
else
|
376
400
|
return unless respond_to?(:compose)
|
377
401
|
|
378
|
-
cmd = compose(opts, flags,
|
379
|
-
from = :script if from == :run && script?
|
402
|
+
cmd = compose(as_get(opts), flags, script: true, args: scr, from: from)
|
380
403
|
end
|
381
404
|
run(cmd, var, from: from, banner: banner, sync: sync)
|
382
405
|
end
|
383
406
|
|
384
407
|
def depend(*, sync: invoked_sync?('depend'), **)
|
385
|
-
|
386
|
-
|
387
|
-
run(@depend, from: :depend, sync: sync)
|
388
|
-
end
|
389
|
-
|
390
|
-
def copy(*, sync: invoked_sync?('copy'), **)
|
391
|
-
return unless @copy
|
392
|
-
|
393
|
-
run_s(@copy, from: :copy, sync: sync)
|
408
|
+
run_b(@depend, sync: sync, from: :depend)
|
394
409
|
end
|
395
410
|
|
396
411
|
def doc(*, sync: invoked_sync?('doc'), **)
|
397
|
-
|
412
|
+
run_b(@doc, sync: sync, from: :doc)
|
413
|
+
end
|
398
414
|
|
399
|
-
|
415
|
+
def lint(*, sync: invoked_sync?('lint'), **)
|
416
|
+
run_b(@lint, sync: sync, from: :lint)
|
400
417
|
end
|
401
418
|
|
402
419
|
def test(*, sync: invoked_sync?('test'), **)
|
403
|
-
|
420
|
+
run_b(@test, sync: sync, from: :test)
|
421
|
+
end
|
404
422
|
|
405
|
-
|
423
|
+
def copy(*, sync: invoked_sync?('copy'), **)
|
424
|
+
run_b(@copy, sync: sync, from: :copy)
|
406
425
|
end
|
407
426
|
|
408
427
|
def clean(*, sync: invoked_sync?('clean'), **)
|
@@ -411,23 +430,31 @@ module Squared
|
|
411
430
|
on :first, :clean
|
412
431
|
case @clean
|
413
432
|
when String
|
414
|
-
|
433
|
+
run_s(@clean, from: :clean, sync: sync)
|
434
|
+
when Hash
|
435
|
+
begin
|
436
|
+
@clean.each { |cmd, opts| build(cmd.to_s, opts, sync: sync) }
|
437
|
+
rescue StandardError => e
|
438
|
+
log.error e
|
439
|
+
ret = on(:error, from, e)
|
440
|
+
raise if @exception && ret != true
|
441
|
+
end
|
415
442
|
when Enumerable
|
416
|
-
|
443
|
+
as_a(@clean).each do |val|
|
417
444
|
val = val.to_s
|
418
445
|
path = basepath(val)
|
419
446
|
if path.directory? && val =~ %r{[\\/]\z}
|
420
|
-
log
|
421
|
-
|
447
|
+
log.warn "rm -rf #{path}"
|
448
|
+
path.rmtree(verbose: verbose)
|
422
449
|
else
|
423
|
-
log
|
450
|
+
log.warn "rm #{path}"
|
424
451
|
(val.include?('*') ? Dir[path] : [path]).each do |file|
|
425
452
|
next unless File.file?(file)
|
426
453
|
|
427
454
|
begin
|
428
455
|
File.delete(file)
|
429
456
|
rescue StandardError => e
|
430
|
-
log
|
457
|
+
log.error e
|
431
458
|
end
|
432
459
|
end
|
433
460
|
end
|
@@ -447,8 +474,9 @@ module Squared
|
|
447
474
|
end
|
448
475
|
end
|
449
476
|
end
|
450
|
-
pass
|
451
|
-
|
477
|
+
pass += split_escape(val) if (val = env('GRAPH', suffix: 'PASS'))
|
478
|
+
start, neg = start.partition { |name| !name.start_with?('-') }
|
479
|
+
data = graph_collect(self, start, pass: neg.map { |name| name[1..-1] })
|
452
480
|
unless out
|
453
481
|
data[name] << self
|
454
482
|
on :first, :graph
|
@@ -482,6 +510,12 @@ module Squared
|
|
482
510
|
(@events[name.to_sym] ||= {})[key.to_sym] = [block_given? ? [blk] + args : args, kwargs]
|
483
511
|
end
|
484
512
|
|
513
|
+
def as(cmd, script, to = nil)
|
514
|
+
script = { "#{script}": to } if to
|
515
|
+
data = (@as ||= {})[cmd.to_sym] ||= {}
|
516
|
+
script.each { |key, val| data[key.to_s] = val }
|
517
|
+
end
|
518
|
+
|
485
519
|
def variable_set(key, *val, **kwargs)
|
486
520
|
if variables.include?(key)
|
487
521
|
case key
|
@@ -506,7 +540,7 @@ module Squared
|
|
506
540
|
instance_variable_set :"@#{key}", val.first
|
507
541
|
end
|
508
542
|
else
|
509
|
-
log
|
543
|
+
log.warn "variable_set: @#{key} (private)"
|
510
544
|
end
|
511
545
|
end
|
512
546
|
|
@@ -550,6 +584,10 @@ module Squared
|
|
550
584
|
!!@doc
|
551
585
|
end
|
552
586
|
|
587
|
+
def lint?
|
588
|
+
!!@lint
|
589
|
+
end
|
590
|
+
|
553
591
|
def test?
|
554
592
|
!!@test
|
555
593
|
end
|
@@ -629,12 +667,19 @@ module Squared
|
|
629
667
|
end
|
630
668
|
|
631
669
|
def run(cmd = @session, var = nil, exception: @exception, sync: true, banner: true, chdir: path, from: nil, **)
|
670
|
+
unless cmd
|
671
|
+
if warning?
|
672
|
+
from &&= from.to_s
|
673
|
+
warn log_message(Logger::WARN, from || 'unknown', subject: project, hint: 'no command given')
|
674
|
+
end
|
675
|
+
return
|
676
|
+
end
|
632
677
|
cmd = session_done(cmd)
|
633
|
-
log
|
634
|
-
on :first, from
|
678
|
+
log.info cmd
|
679
|
+
on :first, from
|
635
680
|
begin
|
636
681
|
if cmd.match?(/\A[^:]+:[^:]/) && workspace.task_defined?(cmd)
|
637
|
-
log
|
682
|
+
log.warn "ENV was discarded: #{var}" if var
|
638
683
|
task_invoke(cmd, exception: exception, warning: warning?)
|
639
684
|
else
|
640
685
|
print_item format_banner(cmd, banner: banner) if sync
|
@@ -642,23 +687,33 @@ module Squared
|
|
642
687
|
shell(*args, chdir: chdir, exception: exception)
|
643
688
|
end
|
644
689
|
rescue StandardError => e
|
645
|
-
log
|
646
|
-
ret = on(:error, from, e)
|
690
|
+
log.error e
|
691
|
+
ret = on(:error, from, e)
|
647
692
|
raise unless ret == true
|
648
693
|
else
|
649
|
-
on :last, from
|
694
|
+
on :last, from
|
650
695
|
end
|
651
696
|
end
|
652
697
|
|
653
698
|
def run_s(*cmd, env: nil, sync: true, banner: verbose != false, from: nil, **kwargs)
|
654
|
-
on :first, from
|
699
|
+
on :first, from
|
655
700
|
begin
|
656
701
|
cmd.flatten.each { |val| run(val, env, sync: sync, banner: banner, **kwargs) }
|
657
702
|
rescue StandardError => e
|
658
|
-
ret = on(:error, from, e)
|
703
|
+
ret = on(:error, from, e)
|
659
704
|
raise unless ret == true
|
660
705
|
end
|
661
|
-
on :last, from
|
706
|
+
on :last, from
|
707
|
+
end
|
708
|
+
|
709
|
+
def run_b(obj, from: nil, sync: true)
|
710
|
+
return unless obj
|
711
|
+
|
712
|
+
if obj.is_a?(Array) && obj.any? { |val| !val.is_a?(String) }
|
713
|
+
build(*obj, from: from, sync: sync)
|
714
|
+
else
|
715
|
+
run_s(obj.is_a?(Enumerable) ? obj.to_a : obj, from: from, sync: sync)
|
716
|
+
end
|
662
717
|
end
|
663
718
|
|
664
719
|
def graph_branch(target, data, tasks = nil, out = nil, sync: true, pass: [], done: [], depth: 0, last: false,
|
@@ -745,9 +800,11 @@ module Squared
|
|
745
800
|
done
|
746
801
|
end
|
747
802
|
|
748
|
-
def graph_collect(target, start = [], data: {})
|
803
|
+
def graph_collect(target, start = [], data: {}, pass: [])
|
749
804
|
deps = []
|
750
805
|
(start.empty? ? target.instance_variable_get(:@graph) : start)&.each do |val|
|
806
|
+
next if pass.include?(val)
|
807
|
+
|
751
808
|
if (obj = workspace.find(name: val))
|
752
809
|
next unless obj.enabled?
|
753
810
|
|
@@ -755,8 +812,11 @@ module Squared
|
|
755
812
|
else
|
756
813
|
items = workspace.find(group: val, ref: val.to_sym)
|
757
814
|
end
|
815
|
+
|
758
816
|
items.each do |proj|
|
759
|
-
|
817
|
+
next if pass.include?(proj.name)
|
818
|
+
|
819
|
+
graph_collect(proj, data: data, pass: pass) if proj.graph? && !data.key?(proj.name)
|
760
820
|
next if (objs = data.fetch(proj.name, [])).include?(target)
|
761
821
|
|
762
822
|
deps << proj
|
@@ -783,15 +843,29 @@ module Squared
|
|
783
843
|
end
|
784
844
|
|
785
845
|
def session(*cmd, prefix: cmd.first, main: true, options: true)
|
786
|
-
prefix =
|
846
|
+
prefix = prefix.to_s.upcase
|
787
847
|
if (val = PATH[prefix] || PATH[prefix.to_sym])
|
788
848
|
cmd[0] = shell_quote(val, force: false)
|
789
849
|
end
|
790
|
-
split_escape(val).each { |opt| cmd << fill_option(opt) } if options && (val = env("#{prefix}_OPTIONS"))
|
791
850
|
ret = JoinSet.new(cmd.flatten(1))
|
851
|
+
if options && (val = env("#{prefix}_OPTIONS"))
|
852
|
+
split_escape(val).each { |opt| ret.last(fill_option(opt), /^(--?[^ =]+)[ =].+$/) }
|
853
|
+
end
|
792
854
|
main ? @session = ret : ret
|
793
855
|
end
|
794
856
|
|
857
|
+
def session_delete(*list, target: @session)
|
858
|
+
ret = []
|
859
|
+
list.each do |val|
|
860
|
+
pat = /^#{Regexp.escape(shell_option(val))}(?: |=|$)/
|
861
|
+
if (key = target.find { |opt| opt =~ pat })
|
862
|
+
target.delete(key)
|
863
|
+
ret << key
|
864
|
+
end
|
865
|
+
end
|
866
|
+
ret
|
867
|
+
end
|
868
|
+
|
795
869
|
def session_output(*cmd, **kwargs)
|
796
870
|
session(*cmd, main: false, options: false, **kwargs)
|
797
871
|
end
|
@@ -804,50 +878,96 @@ module Squared
|
|
804
878
|
cmd.done
|
805
879
|
end
|
806
880
|
|
807
|
-
def option(*args,
|
881
|
+
def option(*args, prefix: @session&.first, **kwargs)
|
808
882
|
if prefix
|
809
883
|
args.each do |val|
|
810
|
-
ret = env("#{
|
884
|
+
ret = env("#{prefix}_#{val.gsub(/\W/, '_')}".upcase, **kwargs)
|
811
885
|
return ret if ret
|
812
886
|
end
|
813
887
|
end
|
814
888
|
nil
|
815
889
|
end
|
816
890
|
|
817
|
-
def
|
818
|
-
|
891
|
+
def option_sanitize(opts, list, target: @session, no: nil, first: false, pass: ['='])
|
892
|
+
ret = []
|
893
|
+
reg = []
|
819
894
|
bare = []
|
820
|
-
|
821
|
-
|
822
|
-
|
823
|
-
|
824
|
-
|
895
|
+
e = []
|
896
|
+
b = []
|
897
|
+
p = []
|
898
|
+
q = []
|
899
|
+
i = []
|
900
|
+
list = list.map do |val|
|
901
|
+
x, y = val.split('|')
|
902
|
+
if y
|
903
|
+
if (n = val.index('='))
|
904
|
+
x += val[n..-1]
|
905
|
+
end
|
906
|
+
[x, y]
|
907
|
+
else
|
908
|
+
x
|
909
|
+
end
|
825
910
|
end
|
826
|
-
list
|
827
|
-
|
911
|
+
list.flatten.each do |val|
|
912
|
+
if (n = val.index('='))
|
913
|
+
flag = val[0, n]
|
914
|
+
case val[n + 1]
|
915
|
+
when 'e'
|
916
|
+
e << flag
|
917
|
+
when 'b'
|
918
|
+
b << flag
|
919
|
+
when 'q'
|
920
|
+
q << flag
|
921
|
+
when 'p'
|
922
|
+
p << flag
|
923
|
+
when 'i'
|
924
|
+
i << flag
|
925
|
+
else
|
926
|
+
reg << Regexp.escape(flag)
|
927
|
+
end
|
928
|
+
bare << flag if val.end_with?('?')
|
929
|
+
else
|
930
|
+
bare << val
|
931
|
+
end
|
932
|
+
end
|
933
|
+
no = (no || []).map { |val| (n = val.index('=')) ? val[0, n] : val }
|
934
|
+
bare += no
|
828
935
|
found = false
|
829
936
|
opts.each do |opt|
|
830
|
-
next
|
937
|
+
next ret << opt if found
|
831
938
|
|
832
|
-
if
|
939
|
+
if bare.include?(opt)
|
833
940
|
target << (opt.size == 1 ? "-#{opt}" : "--#{opt}")
|
834
941
|
elsif opt.start_with?('no-') && no.include?(name = opt[3..-1])
|
835
942
|
target << "--no-#{name}"
|
836
943
|
else
|
837
|
-
|
944
|
+
if opt =~ /^([^=]+)=(.+)$/
|
945
|
+
a = $1
|
946
|
+
if e.include?(a)
|
947
|
+
target << shell_option(a, $2)
|
948
|
+
elsif q.include?(a)
|
949
|
+
target << quote_option(a, $2)
|
950
|
+
elsif p.include?(a)
|
951
|
+
target << quote_option(a, basepath($2))
|
952
|
+
elsif b.include?(a) || (i.include?(a) && /^\d+$/.match?($2))
|
953
|
+
target << basic_option(a, $2)
|
954
|
+
else
|
955
|
+
ret << opt
|
956
|
+
end
|
957
|
+
opt = a
|
958
|
+
else
|
959
|
+
ret << opt
|
960
|
+
end
|
838
961
|
found = true if first && pass.none? { |val| opt.include?(val) }
|
839
962
|
end
|
840
963
|
end
|
841
|
-
|
842
|
-
[out, pat]
|
964
|
+
[ret, reg.empty? ? /\A\s+\z/ : /^(#{reg.join('|')})=(.+)$/]
|
843
965
|
end
|
844
966
|
|
845
|
-
def option_clear(
|
846
|
-
return if params.empty?
|
847
|
-
|
967
|
+
def option_clear(opts, target: @session, **kwargs)
|
848
968
|
kwargs[:subject] ||= target&.first
|
849
|
-
kwargs[:hint] ||= '
|
850
|
-
warn log_message(
|
969
|
+
kwargs[:hint] ||= 'not used'
|
970
|
+
warn log_message(Logger::WARN, opts.join(', '), **kwargs) unless opts.empty?
|
851
971
|
end
|
852
972
|
|
853
973
|
def print_item(*val)
|
@@ -990,18 +1110,23 @@ module Squared
|
|
990
1110
|
opts.each { |val| target << shell_option(flag, val) }
|
991
1111
|
end
|
992
1112
|
|
993
|
-
def
|
994
|
-
|
995
|
-
|
996
|
-
|
997
|
-
|
998
|
-
|
999
|
-
|
1000
|
-
|
1001
|
-
|
1002
|
-
|
1003
|
-
|
1113
|
+
def append_hash(data, target: @session)
|
1114
|
+
target ||= []
|
1115
|
+
if (type = env('BUILD', suffix: 'TYPE') || ENV['BUILD_TYPE'])
|
1116
|
+
type = "__#{type}__"
|
1117
|
+
if (extra = data[type] || data[type.to_sym]).is_a?(Hash)
|
1118
|
+
data = data.merge(extra)
|
1119
|
+
else
|
1120
|
+
extra = nil
|
1121
|
+
end
|
1122
|
+
end
|
1123
|
+
data.each do |key, val|
|
1124
|
+
next if (key = key.to_s).start_with?('__')
|
1004
1125
|
|
1126
|
+
if val.nil? || extra || session_arg?(key, target: target)
|
1127
|
+
session_delete(key, target: target)
|
1128
|
+
next if val.nil?
|
1129
|
+
end
|
1005
1130
|
case val
|
1006
1131
|
when Array
|
1007
1132
|
append_repeat(key, val, target: target)
|
@@ -1013,14 +1138,50 @@ module Squared
|
|
1013
1138
|
target << shell_option(key, val.is_a?(String) ? val : nil)
|
1014
1139
|
end
|
1015
1140
|
end
|
1141
|
+
target
|
1016
1142
|
end
|
1017
1143
|
|
1018
|
-
def
|
1019
|
-
|
1020
|
-
|
1144
|
+
def append_any(val, target: @session, delim: false)
|
1145
|
+
if delim && !target.include?('--')
|
1146
|
+
target << '--'
|
1147
|
+
else
|
1148
|
+
delim = false
|
1149
|
+
end
|
1150
|
+
case val
|
1151
|
+
when String
|
1152
|
+
target << val
|
1153
|
+
when Hash
|
1154
|
+
append_hash(val, target: target)
|
1155
|
+
when Enumerable
|
1156
|
+
if target.is_a?(Array)
|
1157
|
+
target.concat(val.to_a)
|
1158
|
+
else
|
1159
|
+
target.merge(val.to_a)
|
1160
|
+
end
|
1161
|
+
else
|
1162
|
+
target.delete('--') if delim
|
1163
|
+
end
|
1164
|
+
end
|
1165
|
+
|
1166
|
+
def append_value(*list, target: @session, delim: false, escape: false, quote: true)
|
1167
|
+
return if (list = list.flatten).empty?
|
1168
|
+
|
1169
|
+
target << '--' if delim && !target.include?('--')
|
1170
|
+
list.map do |val|
|
1171
|
+
target << (val = escape ? shell_escape(val, quote: quote) : shell_quote(val))
|
1172
|
+
val
|
1173
|
+
end
|
1174
|
+
end
|
1175
|
+
|
1176
|
+
def append_first(*list, target: @session, flag: true, equals: false, escape: true, quote: true, force: true,
|
1177
|
+
**kwargs)
|
1178
|
+
return if (list = list.flatten).empty?
|
1179
|
+
|
1180
|
+
list.flatten.each do |opt|
|
1181
|
+
next unless (val = option(opt, **kwargs))
|
1021
1182
|
|
1022
1183
|
return target << (if flag
|
1023
|
-
shell_option(opt, equals ? val : nil, quote: quote, escape: escape)
|
1184
|
+
shell_option(opt, equals ? val : nil, quote: quote, escape: escape, force: force)
|
1024
1185
|
else
|
1025
1186
|
shell_quote(val)
|
1026
1187
|
end)
|
@@ -1028,21 +1189,36 @@ module Squared
|
|
1028
1189
|
nil
|
1029
1190
|
end
|
1030
1191
|
|
1031
|
-
def append_option(list, target: @session,
|
1032
|
-
|
1033
|
-
|
1192
|
+
def append_option(*list, target: @session, no: false, equals: false, escape: true, quote: true, force: true,
|
1193
|
+
**kwargs)
|
1194
|
+
return if (list = list.flatten).empty?
|
1034
1195
|
|
1035
|
-
|
1196
|
+
ret = []
|
1197
|
+
list.flatten.each do |flag|
|
1198
|
+
next unless (val = option(flag, **kwargs))
|
1199
|
+
|
1200
|
+
if val == '0' && no
|
1201
|
+
flag = "no-#{flag}"
|
1202
|
+
val = nil
|
1203
|
+
end
|
1204
|
+
ret << shell_option(flag, equals ? val : nil, escape: escape, quote: quote, force: force)
|
1036
1205
|
end
|
1206
|
+
ret.each { |val| target << val } unless ret.empty?
|
1037
1207
|
end
|
1038
1208
|
|
1039
1209
|
def append_nocolor(target: @session)
|
1040
|
-
target << '--no-color' if !ARG[:COLOR] || stdin? || option('no-color',
|
1210
|
+
target << '--no-color' if !ARG[:COLOR] || stdin? || option('no-color', ignore: false)
|
1211
|
+
end
|
1212
|
+
|
1213
|
+
def collect_hash(data, pass: [])
|
1214
|
+
ret = []
|
1215
|
+
data.each { |key, val| ret += val unless pass.include?(key) }
|
1216
|
+
ret
|
1041
1217
|
end
|
1042
1218
|
|
1043
1219
|
def param_guard(action, flag, args: nil, key: nil, pat: nil)
|
1044
1220
|
if args && key
|
1045
|
-
val = args
|
1221
|
+
val = args[key]
|
1046
1222
|
return val unless val.nil? || (pat && !val.match?(pat))
|
1047
1223
|
|
1048
1224
|
@session = nil
|
@@ -1077,9 +1253,9 @@ module Squared
|
|
1077
1253
|
end
|
1078
1254
|
|
1079
1255
|
def indexitem(val)
|
1080
|
-
return unless
|
1256
|
+
return unless val =~ /\A\^(\d+)(:.+)?\z/
|
1081
1257
|
|
1082
|
-
[
|
1258
|
+
[$1.to_i, $2 && $2[1..-1]]
|
1083
1259
|
end
|
1084
1260
|
|
1085
1261
|
def indexerror(val, list = nil)
|
@@ -1095,8 +1271,8 @@ module Squared
|
|
1095
1271
|
val.compact.map { |s| color(s) }.flatten
|
1096
1272
|
end
|
1097
1273
|
|
1098
|
-
def on(event,
|
1099
|
-
return unless (obj = @events[event][
|
1274
|
+
def on(event, from, *args, **kwargs)
|
1275
|
+
return unless from && (obj = @events[event][from])
|
1100
1276
|
|
1101
1277
|
if obj.is_a?(Array) && obj[1].is_a?(Hash)
|
1102
1278
|
opts = kwargs.empty? ? obj[1] : obj[1].merge(kwargs)
|
@@ -1115,11 +1291,11 @@ module Squared
|
|
1115
1291
|
end
|
1116
1292
|
end
|
1117
1293
|
|
1118
|
-
def pwd_set(done = nil, pass: false, from: nil, &blk)
|
1294
|
+
def pwd_set(done = nil, pass: false, from: nil, dryrun: false, &blk)
|
1119
1295
|
pwd = Pathname.pwd
|
1120
1296
|
if block_given?
|
1121
1297
|
begin
|
1122
|
-
if path == pwd || pass == true || (pass.is_a?(String) && semscan(pass).join
|
1298
|
+
if path == pwd || pass == true || (pass.is_a?(String) && semscan(pass).join >= RUBY_VERSION)
|
1123
1299
|
ret = instance_eval(&blk)
|
1124
1300
|
else
|
1125
1301
|
Dir.chdir(path)
|
@@ -1127,9 +1303,11 @@ module Squared
|
|
1127
1303
|
Dir.chdir(pwd)
|
1128
1304
|
end
|
1129
1305
|
rescue StandardError => e
|
1130
|
-
log
|
1131
|
-
|
1132
|
-
|
1306
|
+
log.error e
|
1307
|
+
unless dryrun
|
1308
|
+
ret = on(:error, from, e)
|
1309
|
+
raise if exception && ret != true
|
1310
|
+
end
|
1133
1311
|
else
|
1134
1312
|
ret
|
1135
1313
|
end
|
@@ -1149,6 +1327,8 @@ module Squared
|
|
1149
1327
|
end
|
1150
1328
|
|
1151
1329
|
def run_set(cmd, val = nil, opts: nil, **)
|
1330
|
+
return @output = cmd.dup if cmd.is_a?(Array)
|
1331
|
+
|
1152
1332
|
unless @output[1] == false && !@output[0].nil?
|
1153
1333
|
if opts == false
|
1154
1334
|
@output[1] = false
|
@@ -1166,7 +1346,7 @@ module Squared
|
|
1166
1346
|
@output[0] = cmd
|
1167
1347
|
end
|
1168
1348
|
|
1169
|
-
def script_set(cmd, prod: nil, **)
|
1349
|
+
def script_set(cmd, prod: nil, args: nil, **)
|
1170
1350
|
return if @output[1] == false && @output[0].nil?
|
1171
1351
|
|
1172
1352
|
@output[0] = nil
|
@@ -1175,31 +1355,36 @@ module Squared
|
|
1175
1355
|
else
|
1176
1356
|
cmd
|
1177
1357
|
end
|
1358
|
+
@output[4] = args unless @output[4] == false || args.nil?
|
1359
|
+
end
|
1360
|
+
|
1361
|
+
def as_get(val)
|
1362
|
+
@global && (ret = @as && @as[from] && @as[from][val]) ? ret : val
|
1178
1363
|
end
|
1179
1364
|
|
1180
1365
|
def task_build(keys)
|
1181
1366
|
namespace name do
|
1367
|
+
ws = workspace
|
1182
1368
|
keys.each do |key|
|
1183
|
-
next unless
|
1369
|
+
next unless ws.task_include?(self, key)
|
1184
1370
|
|
1185
|
-
action =
|
1186
|
-
unless @pass.include?(key.to_s) ||
|
1187
|
-
|
1371
|
+
action = ws.series.name_get(key)
|
1372
|
+
unless @pass.include?(key.to_s) || ws.task_defined?(name, action) || ws.task_exclude?(action, self)
|
1373
|
+
ws.task_desc(@desc, action)
|
1188
1374
|
task action do
|
1189
1375
|
__send__(key)
|
1190
1376
|
end
|
1191
1377
|
end
|
1192
1378
|
next if (items = @children.select { |item| item.task_include?(key) }).empty?
|
1193
1379
|
|
1194
|
-
|
1380
|
+
ws.task_desc(@desc, action, 'workspace')
|
1195
1381
|
task task_join(action, 'workspace') => items.map { |item| task_join(item.name, action) }
|
1196
1382
|
end
|
1197
1383
|
end
|
1198
1384
|
end
|
1199
1385
|
|
1200
1386
|
def projectpath?(val)
|
1201
|
-
val
|
1202
|
-
val.absolute? ? val.to_s.start_with?(File.join(path, '')) : !val.to_s.start_with?(File.join('..', ''))
|
1387
|
+
Pathname.new(val).absolute? ? val.to_s.start_with?(File.join(path, '')) : !val.to_s.start_with?('..')
|
1203
1388
|
end
|
1204
1389
|
|
1205
1390
|
def semmajor?(cur, want)
|
@@ -1217,6 +1402,13 @@ module Squared
|
|
1217
1402
|
end
|
1218
1403
|
end
|
1219
1404
|
|
1405
|
+
def session_arg?(*list, target: @session, value: false)
|
1406
|
+
list.any? do |val|
|
1407
|
+
pat = /^#{Regexp.escape(shell_option(val))}#{value ? '[ =].' : '(?:[ =]|$)'}/
|
1408
|
+
target.any? { |opt| opt =~ pat }
|
1409
|
+
end
|
1410
|
+
end
|
1411
|
+
|
1220
1412
|
def from_sync?(*val)
|
1221
1413
|
if task_invoked?(key = task_join(*val))
|
1222
1414
|
!workspace.task_defined?(key, 'sync')
|