squared 0.2.13 → 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 -158
- data/README.ruby.md +150 -68
- data/lib/squared/common/base.rb +5 -6
- data/lib/squared/common/class.rb +27 -2
- data/lib/squared/common/format.rb +13 -15
- data/lib/squared/common/prompt.rb +1 -1
- data/lib/squared/common/shell.rb +11 -13
- data/lib/squared/common/system.rb +14 -21
- data/lib/squared/common/utils.rb +24 -13
- data/lib/squared/config.rb +4 -5
- data/lib/squared/version.rb +1 -1
- data/lib/squared/workspace/application.rb +69 -41
- data/lib/squared/workspace/project/base.rb +356 -172
- data/lib/squared/workspace/project/git.rb +556 -359
- data/lib/squared/workspace/project/node.rb +250 -114
- data/lib/squared/workspace/project/python.rb +101 -78
- data/lib/squared/workspace/project/ruby.rb +182 -172
- data/lib/squared/workspace/repo.rb +10 -5
- 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,
|
@@ -703,7 +758,7 @@ module Squared
|
|
703
758
|
|
704
759
|
t = dedupe.(proj.name)
|
705
760
|
j = if out
|
706
|
-
if i == items.size - 1 || check.(post = items[
|
761
|
+
if i == items.size - 1 || check.(post = items[i + 1..-1]).empty?
|
707
762
|
true
|
708
763
|
elsif !t.empty? && depth > 0
|
709
764
|
post.reject { |pr| t.include?(pr) }.empty?
|
@@ -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,20 +812,18 @@ 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
|
-
|
760
|
-
|
761
|
-
|
762
|
-
|
763
|
-
next if (objs = data.fetch(name, [])).include?(target)
|
817
|
+
next if pass.include?(proj.name)
|
818
|
+
|
819
|
+
graph_collect(proj, data: data, pass: pass) if proj.graph? && !data.key?(proj.name)
|
820
|
+
next if (objs = data.fetch(proj.name, [])).include?(target)
|
764
821
|
|
765
822
|
deps << proj
|
766
|
-
deps
|
823
|
+
deps += objs
|
767
824
|
end
|
768
825
|
end
|
769
|
-
deps.uniq
|
770
|
-
deps.delete(target)
|
771
|
-
data[target.name] = deps
|
826
|
+
data[target.name] = deps.uniq.reject { |proj| proj == target }
|
772
827
|
data
|
773
828
|
end
|
774
829
|
|
@@ -788,15 +843,29 @@ module Squared
|
|
788
843
|
end
|
789
844
|
|
790
845
|
def session(*cmd, prefix: cmd.first, main: true, options: true)
|
791
|
-
prefix =
|
846
|
+
prefix = prefix.to_s.upcase
|
792
847
|
if (val = PATH[prefix] || PATH[prefix.to_sym])
|
793
848
|
cmd[0] = shell_quote(val, force: false)
|
794
849
|
end
|
795
|
-
split_escape(val).each { |opt| cmd << fill_option(opt) } if options && (val = env("#{prefix}_OPTIONS"))
|
796
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
|
797
854
|
main ? @session = ret : ret
|
798
855
|
end
|
799
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
|
+
|
800
869
|
def session_output(*cmd, **kwargs)
|
801
870
|
session(*cmd, main: false, options: false, **kwargs)
|
802
871
|
end
|
@@ -809,54 +878,100 @@ module Squared
|
|
809
878
|
cmd.done
|
810
879
|
end
|
811
880
|
|
812
|
-
def option(*args,
|
881
|
+
def option(*args, prefix: @session&.first, **kwargs)
|
813
882
|
if prefix
|
814
883
|
args.each do |val|
|
815
|
-
ret = env("#{
|
884
|
+
ret = env("#{prefix}_#{val.gsub(/\W/, '_')}".upcase, **kwargs)
|
816
885
|
return ret if ret
|
817
886
|
end
|
818
887
|
end
|
819
888
|
nil
|
820
889
|
end
|
821
890
|
|
822
|
-
def
|
823
|
-
|
891
|
+
def option_sanitize(opts, list, target: @session, no: nil, first: false, pass: ['='])
|
892
|
+
ret = []
|
893
|
+
reg = []
|
824
894
|
bare = []
|
825
|
-
|
826
|
-
|
827
|
-
|
828
|
-
|
829
|
-
|
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
|
910
|
+
end
|
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
|
830
932
|
end
|
831
|
-
|
832
|
-
|
933
|
+
no = (no || []).map { |val| (n = val.index('=')) ? val[0, n] : val }
|
934
|
+
bare += no
|
833
935
|
found = false
|
834
936
|
opts.each do |opt|
|
835
|
-
next
|
937
|
+
next ret << opt if found
|
836
938
|
|
837
|
-
if
|
939
|
+
if bare.include?(opt)
|
838
940
|
target << (opt.size == 1 ? "-#{opt}" : "--#{opt}")
|
839
941
|
elsif opt.start_with?('no-') && no.include?(name = opt[3..-1])
|
840
942
|
target << "--no-#{name}"
|
841
943
|
else
|
842
|
-
|
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
|
843
961
|
found = true if first && pass.none? { |val| opt.include?(val) }
|
844
962
|
end
|
845
963
|
end
|
846
|
-
|
847
|
-
[out, pat]
|
964
|
+
[ret, reg.empty? ? /\A\s+\z/ : /^(#{reg.join('|')})=(.+)$/]
|
848
965
|
end
|
849
966
|
|
850
|
-
def option_clear(
|
851
|
-
return if params.empty?
|
852
|
-
|
967
|
+
def option_clear(opts, target: @session, **kwargs)
|
853
968
|
kwargs[:subject] ||= target&.first
|
854
|
-
kwargs[:hint] ||= '
|
855
|
-
warn log_message(
|
969
|
+
kwargs[:hint] ||= 'not used'
|
970
|
+
warn log_message(Logger::WARN, opts.join(', '), **kwargs) unless opts.empty?
|
856
971
|
end
|
857
972
|
|
858
973
|
def print_item(*val)
|
859
|
-
puts if @@print_order > 0
|
974
|
+
puts if @@print_order > 0 && verbose && !stdin?
|
860
975
|
@@print_order += 1
|
861
976
|
puts val unless val.empty? || (val.size == 1 && val.first.nil?)
|
862
977
|
end
|
@@ -995,18 +1110,23 @@ module Squared
|
|
995
1110
|
opts.each { |val| target << shell_option(flag, val) }
|
996
1111
|
end
|
997
1112
|
|
998
|
-
def
|
999
|
-
|
1000
|
-
|
1001
|
-
|
1002
|
-
|
1003
|
-
|
1004
|
-
|
1005
|
-
|
1006
|
-
|
1007
|
-
|
1008
|
-
|
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?('__')
|
1009
1125
|
|
1126
|
+
if val.nil? || extra || session_arg?(key, target: target)
|
1127
|
+
session_delete(key, target: target)
|
1128
|
+
next if val.nil?
|
1129
|
+
end
|
1010
1130
|
case val
|
1011
1131
|
when Array
|
1012
1132
|
append_repeat(key, val, target: target)
|
@@ -1018,14 +1138,50 @@ module Squared
|
|
1018
1138
|
target << shell_option(key, val.is_a?(String) ? val : nil)
|
1019
1139
|
end
|
1020
1140
|
end
|
1141
|
+
target
|
1021
1142
|
end
|
1022
1143
|
|
1023
|
-
def
|
1024
|
-
|
1025
|
-
|
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))
|
1026
1182
|
|
1027
1183
|
return target << (if flag
|
1028
|
-
shell_option(opt, equals ? val : nil, quote: quote, escape: escape)
|
1184
|
+
shell_option(opt, equals ? val : nil, quote: quote, escape: escape, force: force)
|
1029
1185
|
else
|
1030
1186
|
shell_quote(val)
|
1031
1187
|
end)
|
@@ -1033,21 +1189,36 @@ module Squared
|
|
1033
1189
|
nil
|
1034
1190
|
end
|
1035
1191
|
|
1036
|
-
def append_option(list, target: @session,
|
1037
|
-
|
1038
|
-
|
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?
|
1195
|
+
|
1196
|
+
ret = []
|
1197
|
+
list.flatten.each do |flag|
|
1198
|
+
next unless (val = option(flag, **kwargs))
|
1039
1199
|
|
1040
|
-
|
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)
|
1041
1205
|
end
|
1206
|
+
ret.each { |val| target << val } unless ret.empty?
|
1042
1207
|
end
|
1043
1208
|
|
1044
1209
|
def append_nocolor(target: @session)
|
1045
|
-
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
|
1046
1217
|
end
|
1047
1218
|
|
1048
1219
|
def param_guard(action, flag, args: nil, key: nil, pat: nil)
|
1049
1220
|
if args && key
|
1050
|
-
val = args
|
1221
|
+
val = args[key]
|
1051
1222
|
return val unless val.nil? || (pat && !val.match?(pat))
|
1052
1223
|
|
1053
1224
|
@session = nil
|
@@ -1082,17 +1253,15 @@ module Squared
|
|
1082
1253
|
end
|
1083
1254
|
|
1084
1255
|
def indexitem(val)
|
1085
|
-
|
1256
|
+
return unless val =~ /\A\^(\d+)(:.+)?\z/
|
1257
|
+
|
1258
|
+
[$1.to_i, $2 && $2[1..-1]]
|
1086
1259
|
end
|
1087
1260
|
|
1088
1261
|
def indexerror(val, list = nil)
|
1089
1262
|
raise_error("requested index #{val}", hint: list && "of #{list.size}")
|
1090
1263
|
end
|
1091
1264
|
|
1092
|
-
def indexchar
|
1093
|
-
workspace.windows? ? '+' : '^'
|
1094
|
-
end
|
1095
|
-
|
1096
1265
|
def color(val)
|
1097
1266
|
ret = theme[val]
|
1098
1267
|
ret && !ret.empty? ? ret : [val]
|
@@ -1102,8 +1271,8 @@ module Squared
|
|
1102
1271
|
val.compact.map { |s| color(s) }.flatten
|
1103
1272
|
end
|
1104
1273
|
|
1105
|
-
def on(event,
|
1106
|
-
return unless (obj = @events[event][
|
1274
|
+
def on(event, from, *args, **kwargs)
|
1275
|
+
return unless from && (obj = @events[event][from])
|
1107
1276
|
|
1108
1277
|
if obj.is_a?(Array) && obj[1].is_a?(Hash)
|
1109
1278
|
opts = kwargs.empty? ? obj[1] : obj[1].merge(kwargs)
|
@@ -1122,12 +1291,11 @@ module Squared
|
|
1122
1291
|
end
|
1123
1292
|
end
|
1124
1293
|
|
1125
|
-
def pwd_set(done = nil, pass: false, from: nil, &blk)
|
1294
|
+
def pwd_set(done = nil, pass: false, from: nil, dryrun: false, &blk)
|
1126
1295
|
pwd = Pathname.pwd
|
1127
1296
|
if block_given?
|
1128
1297
|
begin
|
1129
|
-
|
1130
|
-
if (path == pwd || pass == true) && !workspace.jruby_win?
|
1298
|
+
if path == pwd || pass == true || (pass.is_a?(String) && semscan(pass).join >= RUBY_VERSION)
|
1131
1299
|
ret = instance_eval(&blk)
|
1132
1300
|
else
|
1133
1301
|
Dir.chdir(path)
|
@@ -1135,9 +1303,11 @@ module Squared
|
|
1135
1303
|
Dir.chdir(pwd)
|
1136
1304
|
end
|
1137
1305
|
rescue StandardError => e
|
1138
|
-
log
|
1139
|
-
|
1140
|
-
|
1306
|
+
log.error e
|
1307
|
+
unless dryrun
|
1308
|
+
ret = on(:error, from, e)
|
1309
|
+
raise if exception && ret != true
|
1310
|
+
end
|
1141
1311
|
else
|
1142
1312
|
ret
|
1143
1313
|
end
|
@@ -1157,6 +1327,8 @@ module Squared
|
|
1157
1327
|
end
|
1158
1328
|
|
1159
1329
|
def run_set(cmd, val = nil, opts: nil, **)
|
1330
|
+
return @output = cmd.dup if cmd.is_a?(Array)
|
1331
|
+
|
1160
1332
|
unless @output[1] == false && !@output[0].nil?
|
1161
1333
|
if opts == false
|
1162
1334
|
@output[1] = false
|
@@ -1174,7 +1346,7 @@ module Squared
|
|
1174
1346
|
@output[0] = cmd
|
1175
1347
|
end
|
1176
1348
|
|
1177
|
-
def script_set(cmd, prod: nil, **)
|
1349
|
+
def script_set(cmd, prod: nil, args: nil, **)
|
1178
1350
|
return if @output[1] == false && @output[0].nil?
|
1179
1351
|
|
1180
1352
|
@output[0] = nil
|
@@ -1183,31 +1355,36 @@ module Squared
|
|
1183
1355
|
else
|
1184
1356
|
cmd
|
1185
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
|
1186
1363
|
end
|
1187
1364
|
|
1188
1365
|
def task_build(keys)
|
1189
1366
|
namespace name do
|
1367
|
+
ws = workspace
|
1190
1368
|
keys.each do |key|
|
1191
|
-
next unless
|
1369
|
+
next unless ws.task_include?(self, key)
|
1192
1370
|
|
1193
|
-
action =
|
1194
|
-
unless @pass.include?(key.to_s) ||
|
1195
|
-
|
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)
|
1196
1374
|
task action do
|
1197
1375
|
__send__(key)
|
1198
1376
|
end
|
1199
1377
|
end
|
1200
1378
|
next if (items = @children.select { |item| item.task_include?(key) }).empty?
|
1201
1379
|
|
1202
|
-
|
1380
|
+
ws.task_desc(@desc, action, 'workspace')
|
1203
1381
|
task task_join(action, 'workspace') => items.map { |item| task_join(item.name, action) }
|
1204
1382
|
end
|
1205
1383
|
end
|
1206
1384
|
end
|
1207
1385
|
|
1208
1386
|
def projectpath?(val)
|
1209
|
-
val
|
1210
|
-
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?('..')
|
1211
1388
|
end
|
1212
1389
|
|
1213
1390
|
def semmajor?(cur, want)
|
@@ -1225,6 +1402,13 @@ module Squared
|
|
1225
1402
|
end
|
1226
1403
|
end
|
1227
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
|
+
|
1228
1412
|
def from_sync?(*val)
|
1229
1413
|
if task_invoked?(key = task_join(*val))
|
1230
1414
|
!workspace.task_defined?(key, 'sync')
|