squared 0.2.9 → 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 +55 -83
- 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 +11 -11
- data/lib/squared/common/shell.rb +10 -12
- 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 -157
- data/lib/squared/workspace/project/git.rb +514 -316
- 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 +175 -163
- data/lib/squared/workspace/repo.rb +7 -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,63 +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
|
-
return unless from == :
|
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,
|
402
|
+
cmd = compose(as_get(opts), flags, script: true, args: scr, from: from)
|
379
403
|
end
|
380
404
|
run(cmd, var, from: from, banner: banner, sync: sync)
|
381
405
|
end
|
382
406
|
|
383
407
|
def depend(*, sync: invoked_sync?('depend'), **)
|
384
|
-
|
385
|
-
|
386
|
-
run(@depend, from: :depend, sync: sync)
|
387
|
-
end
|
388
|
-
|
389
|
-
def copy(*, sync: invoked_sync?('copy'), **)
|
390
|
-
return unless @copy
|
391
|
-
|
392
|
-
run_s(@copy, from: :copy, sync: sync)
|
408
|
+
run_b(@depend, sync: sync, from: :depend)
|
393
409
|
end
|
394
410
|
|
395
411
|
def doc(*, sync: invoked_sync?('doc'), **)
|
396
|
-
|
412
|
+
run_b(@doc, sync: sync, from: :doc)
|
413
|
+
end
|
397
414
|
|
398
|
-
|
415
|
+
def lint(*, sync: invoked_sync?('lint'), **)
|
416
|
+
run_b(@lint, sync: sync, from: :lint)
|
399
417
|
end
|
400
418
|
|
401
419
|
def test(*, sync: invoked_sync?('test'), **)
|
402
|
-
|
420
|
+
run_b(@test, sync: sync, from: :test)
|
421
|
+
end
|
403
422
|
|
404
|
-
|
423
|
+
def copy(*, sync: invoked_sync?('copy'), **)
|
424
|
+
run_b(@copy, sync: sync, from: :copy)
|
405
425
|
end
|
406
426
|
|
407
427
|
def clean(*, sync: invoked_sync?('clean'), **)
|
@@ -410,23 +430,31 @@ module Squared
|
|
410
430
|
on :first, :clean
|
411
431
|
case @clean
|
412
432
|
when String
|
413
|
-
|
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
|
414
442
|
when Enumerable
|
415
|
-
|
443
|
+
as_a(@clean).each do |val|
|
416
444
|
val = val.to_s
|
417
445
|
path = basepath(val)
|
418
446
|
if path.directory? && val =~ %r{[\\/]\z}
|
419
|
-
log
|
420
|
-
|
447
|
+
log.warn "rm -rf #{path}"
|
448
|
+
path.rmtree(verbose: verbose)
|
421
449
|
else
|
422
|
-
log
|
450
|
+
log.warn "rm #{path}"
|
423
451
|
(val.include?('*') ? Dir[path] : [path]).each do |file|
|
424
452
|
next unless File.file?(file)
|
425
453
|
|
426
454
|
begin
|
427
455
|
File.delete(file)
|
428
456
|
rescue StandardError => e
|
429
|
-
log
|
457
|
+
log.error e
|
430
458
|
end
|
431
459
|
end
|
432
460
|
end
|
@@ -446,8 +474,9 @@ module Squared
|
|
446
474
|
end
|
447
475
|
end
|
448
476
|
end
|
449
|
-
pass
|
450
|
-
|
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] })
|
451
480
|
unless out
|
452
481
|
data[name] << self
|
453
482
|
on :first, :graph
|
@@ -481,6 +510,12 @@ module Squared
|
|
481
510
|
(@events[name.to_sym] ||= {})[key.to_sym] = [block_given? ? [blk] + args : args, kwargs]
|
482
511
|
end
|
483
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
|
+
|
484
519
|
def variable_set(key, *val, **kwargs)
|
485
520
|
if variables.include?(key)
|
486
521
|
case key
|
@@ -505,7 +540,7 @@ module Squared
|
|
505
540
|
instance_variable_set :"@#{key}", val.first
|
506
541
|
end
|
507
542
|
else
|
508
|
-
log
|
543
|
+
log.warn "variable_set: @#{key} (private)"
|
509
544
|
end
|
510
545
|
end
|
511
546
|
|
@@ -549,6 +584,10 @@ module Squared
|
|
549
584
|
!!@doc
|
550
585
|
end
|
551
586
|
|
587
|
+
def lint?
|
588
|
+
!!@lint
|
589
|
+
end
|
590
|
+
|
552
591
|
def test?
|
553
592
|
!!@test
|
554
593
|
end
|
@@ -628,12 +667,19 @@ module Squared
|
|
628
667
|
end
|
629
668
|
|
630
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
|
631
677
|
cmd = session_done(cmd)
|
632
|
-
log
|
633
|
-
on :first, from
|
678
|
+
log.info cmd
|
679
|
+
on :first, from
|
634
680
|
begin
|
635
681
|
if cmd.match?(/\A[^:]+:[^:]/) && workspace.task_defined?(cmd)
|
636
|
-
log
|
682
|
+
log.warn "ENV was discarded: #{var}" if var
|
637
683
|
task_invoke(cmd, exception: exception, warning: warning?)
|
638
684
|
else
|
639
685
|
print_item format_banner(cmd, banner: banner) if sync
|
@@ -641,23 +687,33 @@ module Squared
|
|
641
687
|
shell(*args, chdir: chdir, exception: exception)
|
642
688
|
end
|
643
689
|
rescue StandardError => e
|
644
|
-
log
|
645
|
-
ret = on(:error, from, e)
|
690
|
+
log.error e
|
691
|
+
ret = on(:error, from, e)
|
646
692
|
raise unless ret == true
|
647
693
|
else
|
648
|
-
on :last, from
|
694
|
+
on :last, from
|
649
695
|
end
|
650
696
|
end
|
651
697
|
|
652
698
|
def run_s(*cmd, env: nil, sync: true, banner: verbose != false, from: nil, **kwargs)
|
653
|
-
on :first, from
|
699
|
+
on :first, from
|
654
700
|
begin
|
655
701
|
cmd.flatten.each { |val| run(val, env, sync: sync, banner: banner, **kwargs) }
|
656
702
|
rescue StandardError => e
|
657
|
-
ret = on(:error, from, e)
|
703
|
+
ret = on(:error, from, e)
|
658
704
|
raise unless ret == true
|
659
705
|
end
|
660
|
-
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
|
661
717
|
end
|
662
718
|
|
663
719
|
def graph_branch(target, data, tasks = nil, out = nil, sync: true, pass: [], done: [], depth: 0, last: false,
|
@@ -744,9 +800,11 @@ module Squared
|
|
744
800
|
done
|
745
801
|
end
|
746
802
|
|
747
|
-
def graph_collect(target, start = [], data: {})
|
803
|
+
def graph_collect(target, start = [], data: {}, pass: [])
|
748
804
|
deps = []
|
749
805
|
(start.empty? ? target.instance_variable_get(:@graph) : start)&.each do |val|
|
806
|
+
next if pass.include?(val)
|
807
|
+
|
750
808
|
if (obj = workspace.find(name: val))
|
751
809
|
next unless obj.enabled?
|
752
810
|
|
@@ -754,8 +812,11 @@ module Squared
|
|
754
812
|
else
|
755
813
|
items = workspace.find(group: val, ref: val.to_sym)
|
756
814
|
end
|
815
|
+
|
757
816
|
items.each do |proj|
|
758
|
-
|
817
|
+
next if pass.include?(proj.name)
|
818
|
+
|
819
|
+
graph_collect(proj, data: data, pass: pass) if proj.graph? && !data.key?(proj.name)
|
759
820
|
next if (objs = data.fetch(proj.name, [])).include?(target)
|
760
821
|
|
761
822
|
deps << proj
|
@@ -782,15 +843,29 @@ module Squared
|
|
782
843
|
end
|
783
844
|
|
784
845
|
def session(*cmd, prefix: cmd.first, main: true, options: true)
|
785
|
-
prefix =
|
846
|
+
prefix = prefix.to_s.upcase
|
786
847
|
if (val = PATH[prefix] || PATH[prefix.to_sym])
|
787
848
|
cmd[0] = shell_quote(val, force: false)
|
788
849
|
end
|
789
|
-
split_escape(val).each { |opt| cmd << fill_option(opt) } if options && (val = env("#{prefix}_OPTIONS"))
|
790
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
|
791
854
|
main ? @session = ret : ret
|
792
855
|
end
|
793
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
|
+
|
794
869
|
def session_output(*cmd, **kwargs)
|
795
870
|
session(*cmd, main: false, options: false, **kwargs)
|
796
871
|
end
|
@@ -803,50 +878,96 @@ module Squared
|
|
803
878
|
cmd.done
|
804
879
|
end
|
805
880
|
|
806
|
-
def option(*args,
|
881
|
+
def option(*args, prefix: @session&.first, **kwargs)
|
807
882
|
if prefix
|
808
883
|
args.each do |val|
|
809
|
-
ret = env("#{
|
884
|
+
ret = env("#{prefix}_#{val.gsub(/\W/, '_')}".upcase, **kwargs)
|
810
885
|
return ret if ret
|
811
886
|
end
|
812
887
|
end
|
813
888
|
nil
|
814
889
|
end
|
815
890
|
|
816
|
-
def
|
817
|
-
|
891
|
+
def option_sanitize(opts, list, target: @session, no: nil, first: false, pass: ['='])
|
892
|
+
ret = []
|
893
|
+
reg = []
|
818
894
|
bare = []
|
819
|
-
|
820
|
-
|
821
|
-
|
822
|
-
|
823
|
-
|
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
|
824
910
|
end
|
825
|
-
list
|
826
|
-
|
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
|
827
935
|
found = false
|
828
936
|
opts.each do |opt|
|
829
|
-
next
|
937
|
+
next ret << opt if found
|
830
938
|
|
831
|
-
if
|
939
|
+
if bare.include?(opt)
|
832
940
|
target << (opt.size == 1 ? "-#{opt}" : "--#{opt}")
|
833
941
|
elsif opt.start_with?('no-') && no.include?(name = opt[3..-1])
|
834
942
|
target << "--no-#{name}"
|
835
943
|
else
|
836
|
-
|
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
|
837
961
|
found = true if first && pass.none? { |val| opt.include?(val) }
|
838
962
|
end
|
839
963
|
end
|
840
|
-
|
841
|
-
[out, pat]
|
964
|
+
[ret, reg.empty? ? /\A\s+\z/ : /^(#{reg.join('|')})=(.+)$/]
|
842
965
|
end
|
843
966
|
|
844
|
-
def option_clear(
|
845
|
-
return if params.empty?
|
846
|
-
|
967
|
+
def option_clear(opts, target: @session, **kwargs)
|
847
968
|
kwargs[:subject] ||= target&.first
|
848
|
-
kwargs[:hint] ||= '
|
849
|
-
warn log_message(
|
969
|
+
kwargs[:hint] ||= 'not used'
|
970
|
+
warn log_message(Logger::WARN, opts.join(', '), **kwargs) unless opts.empty?
|
850
971
|
end
|
851
972
|
|
852
973
|
def print_item(*val)
|
@@ -989,18 +1110,23 @@ module Squared
|
|
989
1110
|
opts.each { |val| target << shell_option(flag, val) }
|
990
1111
|
end
|
991
1112
|
|
992
|
-
def
|
993
|
-
|
994
|
-
|
995
|
-
|
996
|
-
|
997
|
-
|
998
|
-
|
999
|
-
|
1000
|
-
|
1001
|
-
|
1002
|
-
|
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?('__')
|
1003
1125
|
|
1126
|
+
if val.nil? || extra || session_arg?(key, target: target)
|
1127
|
+
session_delete(key, target: target)
|
1128
|
+
next if val.nil?
|
1129
|
+
end
|
1004
1130
|
case val
|
1005
1131
|
when Array
|
1006
1132
|
append_repeat(key, val, target: target)
|
@@ -1012,14 +1138,50 @@ module Squared
|
|
1012
1138
|
target << shell_option(key, val.is_a?(String) ? val : nil)
|
1013
1139
|
end
|
1014
1140
|
end
|
1141
|
+
target
|
1015
1142
|
end
|
1016
1143
|
|
1017
|
-
def
|
1018
|
-
|
1019
|
-
|
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))
|
1020
1182
|
|
1021
1183
|
return target << (if flag
|
1022
|
-
shell_option(opt, equals ? val : nil, quote: quote, escape: escape)
|
1184
|
+
shell_option(opt, equals ? val : nil, quote: quote, escape: escape, force: force)
|
1023
1185
|
else
|
1024
1186
|
shell_quote(val)
|
1025
1187
|
end)
|
@@ -1027,21 +1189,36 @@ module Squared
|
|
1027
1189
|
nil
|
1028
1190
|
end
|
1029
1191
|
|
1030
|
-
def append_option(list, target: @session,
|
1031
|
-
|
1032
|
-
|
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?
|
1033
1195
|
|
1034
|
-
|
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)
|
1035
1205
|
end
|
1206
|
+
ret.each { |val| target << val } unless ret.empty?
|
1036
1207
|
end
|
1037
1208
|
|
1038
1209
|
def append_nocolor(target: @session)
|
1039
|
-
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
|
1040
1217
|
end
|
1041
1218
|
|
1042
1219
|
def param_guard(action, flag, args: nil, key: nil, pat: nil)
|
1043
1220
|
if args && key
|
1044
|
-
val = args
|
1221
|
+
val = args[key]
|
1045
1222
|
return val unless val.nil? || (pat && !val.match?(pat))
|
1046
1223
|
|
1047
1224
|
@session = nil
|
@@ -1076,9 +1253,9 @@ module Squared
|
|
1076
1253
|
end
|
1077
1254
|
|
1078
1255
|
def indexitem(val)
|
1079
|
-
return unless
|
1256
|
+
return unless val =~ /\A\^(\d+)(:.+)?\z/
|
1080
1257
|
|
1081
|
-
[
|
1258
|
+
[$1.to_i, $2 && $2[1..-1]]
|
1082
1259
|
end
|
1083
1260
|
|
1084
1261
|
def indexerror(val, list = nil)
|
@@ -1094,8 +1271,8 @@ module Squared
|
|
1094
1271
|
val.compact.map { |s| color(s) }.flatten
|
1095
1272
|
end
|
1096
1273
|
|
1097
|
-
def on(event,
|
1098
|
-
return unless (obj = @events[event][
|
1274
|
+
def on(event, from, *args, **kwargs)
|
1275
|
+
return unless from && (obj = @events[event][from])
|
1099
1276
|
|
1100
1277
|
if obj.is_a?(Array) && obj[1].is_a?(Hash)
|
1101
1278
|
opts = kwargs.empty? ? obj[1] : obj[1].merge(kwargs)
|
@@ -1114,7 +1291,7 @@ module Squared
|
|
1114
1291
|
end
|
1115
1292
|
end
|
1116
1293
|
|
1117
|
-
def pwd_set(done = nil, pass: false, from: nil, &blk)
|
1294
|
+
def pwd_set(done = nil, pass: false, from: nil, dryrun: false, &blk)
|
1118
1295
|
pwd = Pathname.pwd
|
1119
1296
|
if block_given?
|
1120
1297
|
begin
|
@@ -1126,9 +1303,11 @@ module Squared
|
|
1126
1303
|
Dir.chdir(pwd)
|
1127
1304
|
end
|
1128
1305
|
rescue StandardError => e
|
1129
|
-
log
|
1130
|
-
|
1131
|
-
|
1306
|
+
log.error e
|
1307
|
+
unless dryrun
|
1308
|
+
ret = on(:error, from, e)
|
1309
|
+
raise if exception && ret != true
|
1310
|
+
end
|
1132
1311
|
else
|
1133
1312
|
ret
|
1134
1313
|
end
|
@@ -1148,6 +1327,8 @@ module Squared
|
|
1148
1327
|
end
|
1149
1328
|
|
1150
1329
|
def run_set(cmd, val = nil, opts: nil, **)
|
1330
|
+
return @output = cmd.dup if cmd.is_a?(Array)
|
1331
|
+
|
1151
1332
|
unless @output[1] == false && !@output[0].nil?
|
1152
1333
|
if opts == false
|
1153
1334
|
@output[1] = false
|
@@ -1165,7 +1346,7 @@ module Squared
|
|
1165
1346
|
@output[0] = cmd
|
1166
1347
|
end
|
1167
1348
|
|
1168
|
-
def script_set(cmd, prod: nil, **)
|
1349
|
+
def script_set(cmd, prod: nil, args: nil, **)
|
1169
1350
|
return if @output[1] == false && @output[0].nil?
|
1170
1351
|
|
1171
1352
|
@output[0] = nil
|
@@ -1174,31 +1355,36 @@ module Squared
|
|
1174
1355
|
else
|
1175
1356
|
cmd
|
1176
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
|
1177
1363
|
end
|
1178
1364
|
|
1179
1365
|
def task_build(keys)
|
1180
1366
|
namespace name do
|
1367
|
+
ws = workspace
|
1181
1368
|
keys.each do |key|
|
1182
|
-
next unless
|
1369
|
+
next unless ws.task_include?(self, key)
|
1183
1370
|
|
1184
|
-
action =
|
1185
|
-
unless @pass.include?(key.to_s) ||
|
1186
|
-
|
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)
|
1187
1374
|
task action do
|
1188
1375
|
__send__(key)
|
1189
1376
|
end
|
1190
1377
|
end
|
1191
1378
|
next if (items = @children.select { |item| item.task_include?(key) }).empty?
|
1192
1379
|
|
1193
|
-
|
1380
|
+
ws.task_desc(@desc, action, 'workspace')
|
1194
1381
|
task task_join(action, 'workspace') => items.map { |item| task_join(item.name, action) }
|
1195
1382
|
end
|
1196
1383
|
end
|
1197
1384
|
end
|
1198
1385
|
|
1199
1386
|
def projectpath?(val)
|
1200
|
-
val
|
1201
|
-
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?('..')
|
1202
1388
|
end
|
1203
1389
|
|
1204
1390
|
def semmajor?(cur, want)
|
@@ -1216,6 +1402,13 @@ module Squared
|
|
1216
1402
|
end
|
1217
1403
|
end
|
1218
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
|
+
|
1219
1412
|
def from_sync?(*val)
|
1220
1413
|
if task_invoked?(key = task_join(*val))
|
1221
1414
|
!workspace.task_defined?(key, 'sync')
|