squared 0.3.10 → 0.4.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 +44 -103
- data/README.md +13 -2
- data/README.ruby.md +169 -89
- data/lib/squared/app.rb +1 -0
- data/lib/squared/common/base.rb +6 -1
- data/lib/squared/common/class.rb +1 -1
- data/lib/squared/common/format.rb +31 -19
- data/lib/squared/common/prompt.rb +3 -3
- data/lib/squared/common/shell.rb +53 -41
- data/lib/squared/common/utils.rb +55 -2
- data/lib/squared/config.rb +1 -1
- data/lib/squared/version.rb +1 -1
- data/lib/squared/workspace/application.rb +18 -15
- data/lib/squared/workspace/project/base.rb +458 -170
- data/lib/squared/workspace/project/docker.rb +572 -0
- data/lib/squared/workspace/project/git.rb +471 -230
- data/lib/squared/workspace/project/node.rb +51 -51
- data/lib/squared/workspace/project/python.rb +130 -41
- data/lib/squared/workspace/project/ruby.rb +47 -58
- data/lib/squared/workspace/project.rb +7 -1
- data/lib/squared/workspace/repo.rb +11 -4
- data/lib/squared/workspace/series.rb +1 -1
- metadata +3 -2
@@ -15,8 +15,10 @@ module Squared
|
|
15
15
|
include Rake::DSL
|
16
16
|
|
17
17
|
VAR_SET = %i[parent global envname dependfile theme run script env pass].freeze
|
18
|
+
BLK_SET = %i[run depend doc lint test copy clean].freeze
|
18
19
|
SEM_VER = /\b(\d+)(?:(\.)(\d+))?(?:(\.)(\d+)(\S+)?)?\b/.freeze
|
19
|
-
|
20
|
+
URI_SCHEME = %r{^([a-z][a-z\d+-.]*)://[^@:\[\]\\^<>|\s]}i.freeze
|
21
|
+
private_constant :VAR_SET, :BLK_SET, :SEM_VER, :URI_SCHEME
|
20
22
|
|
21
23
|
class << self
|
22
24
|
def populate(*); end
|
@@ -25,7 +27,7 @@ module Squared
|
|
25
27
|
def bannerargs(*); end
|
26
28
|
|
27
29
|
def tasks
|
28
|
-
%i[build
|
30
|
+
(%i[build archive graph] + BLK_SET).freeze
|
29
31
|
end
|
30
32
|
|
31
33
|
def as_path(val)
|
@@ -51,7 +53,8 @@ module Squared
|
|
51
53
|
end
|
52
54
|
|
53
55
|
(@@tasks = {})[ref] = {
|
54
|
-
'graph' => %i[run print].freeze
|
56
|
+
'graph' => %i[run print].freeze,
|
57
|
+
'unpack' => %i[zip tar tgz tar.gz txz tar.xz].freeze
|
55
58
|
}.freeze
|
56
59
|
@@task_desc = Rake::TaskManager.record_task_metadata
|
57
60
|
@@print_order = 0
|
@@ -59,8 +62,8 @@ module Squared
|
|
59
62
|
attr_reader :name, :project, :workspace, :path, :theme, :exception, :pipe, :verbose,
|
60
63
|
:group, :parent, :dependfile
|
61
64
|
|
62
|
-
def initialize(workspace, path, name, *, group: nil, graph: nil, pass: nil, exclude: nil,
|
63
|
-
first: {}, last: {}, error: {}, common: ARG[:COMMON], **kwargs)
|
65
|
+
def initialize(workspace, path, name, *, group: nil, graph: nil, pass: nil, exclude: nil, release: nil,
|
66
|
+
archive: nil, first: {}, last: {}, error: {}, common: ARG[:COMMON], **kwargs)
|
64
67
|
@path = path
|
65
68
|
@workspace = workspace
|
66
69
|
@name = name.to_s.freeze
|
@@ -73,6 +76,13 @@ module Squared
|
|
73
76
|
@copy = kwargs[:copy]
|
74
77
|
@clean = kwargs[:clean]
|
75
78
|
@version = kwargs[:version]
|
79
|
+
@archive = case archive
|
80
|
+
when String, Array
|
81
|
+
{ uri: archive }
|
82
|
+
when Hash
|
83
|
+
archive
|
84
|
+
end
|
85
|
+
@release = release
|
76
86
|
@envname = @name.gsub(/[^\w]+/, '_').upcase.freeze
|
77
87
|
@exception = env_bool(kwargs[:exception], workspace.exception, strict: true)
|
78
88
|
@pipe = env_pipe(kwargs[:pipe], workspace.pipe, strict: true)
|
@@ -80,7 +90,7 @@ module Squared
|
|
80
90
|
when nil
|
81
91
|
workspace.verbose
|
82
92
|
when String
|
83
|
-
|
93
|
+
env_pipe(verbose, workspace.verbose, strict: true, index: true)
|
84
94
|
else
|
85
95
|
verbose
|
86
96
|
end
|
@@ -108,7 +118,7 @@ module Squared
|
|
108
118
|
@parent = nil
|
109
119
|
@global = false
|
110
120
|
run_set(kwargs[:run], kwargs[:env], opts: kwargs.fetch(:opts, true))
|
111
|
-
initialize_ref
|
121
|
+
initialize_ref Base.ref
|
112
122
|
end
|
113
123
|
|
114
124
|
def initialize_ref(ref)
|
@@ -116,7 +126,7 @@ module Squared
|
|
116
126
|
end
|
117
127
|
|
118
128
|
def initialize_build(ref, **kwargs)
|
119
|
-
initialize_ref
|
129
|
+
initialize_ref ref
|
120
130
|
if (@script = @workspace.script_get(group: @group, ref: ref))
|
121
131
|
if @script[:log] && !kwargs.key?(:log)
|
122
132
|
kwargs[:log] = @script[:log]
|
@@ -166,43 +176,40 @@ module Squared
|
|
166
176
|
def initialize_events(ref, **)
|
167
177
|
return unless (events = @workspace.events_get(group: @group, ref: ref))
|
168
178
|
|
169
|
-
events.each
|
179
|
+
events.each do |task, data|
|
180
|
+
data.each { |ev, blk| (@events[ev] ||= {})[task] ||= [blk] }
|
181
|
+
end
|
170
182
|
end
|
171
183
|
|
172
184
|
def initialize_logger(log: nil, **)
|
173
185
|
return if @log
|
174
186
|
|
175
187
|
log = log.is_a?(Hash) ? log.dup : { file: log }
|
176
|
-
|
177
|
-
file =
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
elsif (val = log[:file])
|
190
|
-
file = val.is_a?(String) ? DateTime.now.strftime(val) : "#{@name}-#{Date.today}.log"
|
191
|
-
end
|
192
|
-
if file
|
193
|
-
file = (val = env('LOG_DIR')) ? @workspace.home.join(val, file) : @workspace.home.join(file)
|
188
|
+
unless (file = env('LOG_FILE'))
|
189
|
+
file = case env('LOG_AUTO')
|
190
|
+
when 'y', 'year'
|
191
|
+
"#{@name}-#{Date.today.year}.log"
|
192
|
+
when 'm', 'month'
|
193
|
+
"#{@name}-#{Date.today.strftime('%Y-%m')}.log"
|
194
|
+
when 'd', 'day', '1'
|
195
|
+
"#{@name}-#{Date.today}.log"
|
196
|
+
end
|
197
|
+
end
|
198
|
+
if file ||= log[:file]
|
199
|
+
file = Date.today.strftime(file)
|
200
|
+
file = (dir = env('LOG_DIR')) ? @workspace.home.join(dir, file) : @workspace.home.join(file)
|
194
201
|
begin
|
195
202
|
file = file.realdirpath
|
196
203
|
rescue StandardError => e
|
197
204
|
raise if @exception
|
198
205
|
|
199
206
|
file = nil
|
200
|
-
warn log_message(Logger::WARN, e) if warning?
|
207
|
+
warn log_message(Logger::WARN, e, pass: true) if warning?
|
201
208
|
end
|
202
209
|
end
|
203
210
|
log[:progname] ||= @name
|
204
211
|
if (val = env('LOG_LEVEL', ignore: false))
|
205
|
-
log[:level] = val
|
212
|
+
log[:level] = val.match?(/^\d$/) ? log_sym(val.to_i) : val
|
206
213
|
end
|
207
214
|
log.delete(:file)
|
208
215
|
@log = [file, log]
|
@@ -211,20 +218,18 @@ module Squared
|
|
211
218
|
def initialize_env(dev: nil, prod: nil, **)
|
212
219
|
@dev = env_match('BUILD', dev, suffix: 'DEV', strict: true)
|
213
220
|
@prod = env_match('BUILD', prod, suffix: 'PROD', strict: true)
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
221
|
+
unless @output[2] == false || !(val = env('BUILD', suffix: 'ENV'))
|
222
|
+
data = parse_json(val, hint: "BUILD_#{@envname}_ENV")
|
223
|
+
@output[2] = data if data
|
224
|
+
end
|
225
|
+
unless @output[0] == false || @output[0].is_a?(Array)
|
226
|
+
if (val = env('BUILD', suffix: 'OPTS'))
|
227
|
+
n = @output[0] ? 1 : 3
|
228
|
+
@output[n] = merge_opts(@output[n], shell_split(val, escape: false))
|
229
|
+
end
|
230
|
+
if (val = env(ref.to_s.upcase, suffix: 'OPTS'))
|
231
|
+
@output[4] = merge_opts(@output[4], shell_split(val, escape: false))
|
223
232
|
end
|
224
|
-
end
|
225
|
-
if cmd != false && !cmd.is_a?(Array)
|
226
|
-
@output[cmd ? 1 : 3] = shell_split(val, escape: false, join: true) if (val = env('BUILD', suffix: 'OPTS'))
|
227
|
-
@output[4] = shell_split(val, escape: false, join: true) if !cmd && (val = env('SCRIPT', suffix: 'OPTS'))
|
228
233
|
end
|
229
234
|
@version = val if (val = env('BUILD', suffix: 'VERSION'))
|
230
235
|
return unless (val = env('BUILD', strict: true))
|
@@ -259,14 +264,14 @@ module Squared
|
|
259
264
|
|
260
265
|
format_desc action, flag, '(-)project*'
|
261
266
|
task flag do |_, args|
|
262
|
-
args = args.to_a.reject { |val| name == val.to_s }
|
267
|
+
args = param_guard(action, flag, args: args.to_a.reject { |val| name == val.to_s })
|
263
268
|
if flag == :run
|
264
269
|
graph args
|
265
270
|
else
|
266
271
|
out, done = graph(args, out: [])
|
267
272
|
out.map! do |val|
|
268
273
|
done.each_with_index do |proj, i|
|
269
|
-
next unless val
|
274
|
+
next unless val.match?(/ #{Regexp.escape(proj.name)}(?:@\d|\z)/)
|
270
275
|
|
271
276
|
val += " (#{i.succ})"
|
272
277
|
break
|
@@ -280,6 +285,25 @@ module Squared
|
|
280
285
|
])
|
281
286
|
end
|
282
287
|
end
|
288
|
+
when 'unpack'
|
289
|
+
format_desc action, flag, 'tag/url,dir,digest?,f/force?'
|
290
|
+
task flag, [:tag, :dir, :digest, :force] do |_, args|
|
291
|
+
tag = param_guard(action, flag, args: args, key: :tag)
|
292
|
+
dir = param_guard(action, flag, args: args, key: :dir)
|
293
|
+
unless tag.match?(URI_SCHEME)
|
294
|
+
raise_error 'no base uri' unless @release
|
295
|
+
|
296
|
+
tag = "#{@release.include?('??') ? @release.sub('??', tag) : @release + tag}.#{flag}"
|
297
|
+
end
|
298
|
+
case (digest = args.digest)
|
299
|
+
when 'f', 'force'
|
300
|
+
digest = nil
|
301
|
+
force = true
|
302
|
+
else
|
303
|
+
force = args.fetch(:force, false)
|
304
|
+
end
|
305
|
+
unpack(basepath(dir), uri: tag, digest: digest, ext: flag.to_s, force: force)
|
306
|
+
end
|
283
307
|
end
|
284
308
|
end
|
285
309
|
end
|
@@ -348,18 +372,19 @@ module Squared
|
|
348
372
|
|
349
373
|
out = obj.link(self, *args, **kwargs, &blk) if obj.respond_to?(:link)
|
350
374
|
if !out
|
351
|
-
warn log_message(Logger::WARN, 'link not compatible', subject: obj.to_s, hint: name)
|
375
|
+
warn log_message(Logger::WARN, 'link not compatible', subject: obj.to_s, hint: name, pass: true)
|
352
376
|
elsif out.respond_to?(:build)
|
353
377
|
out.build
|
354
378
|
end
|
355
379
|
self
|
356
380
|
end
|
357
381
|
|
358
|
-
def build(*args, sync: invoked_sync?('build'), from: :
|
382
|
+
def build(*args, sync: invoked_sync?('build'), from: @buildtype || :build, **)
|
359
383
|
banner = verbose
|
360
384
|
if args.empty?
|
361
|
-
return unless from == :
|
385
|
+
return unless from == (@buildtype || :build)
|
362
386
|
|
387
|
+
run_b(@run, sync: sync, from: from) if series?(@run)
|
363
388
|
args = @output
|
364
389
|
banner = verbose == 1 if task_invoked?('build', 'build:sync')
|
365
390
|
end
|
@@ -370,7 +395,7 @@ module Squared
|
|
370
395
|
a, b, c, d, e = val
|
371
396
|
case b
|
372
397
|
when Hash
|
373
|
-
b = append_hash(b).join(' ')
|
398
|
+
b = append_hash(b, build: true).join(' ')
|
374
399
|
when Enumerable
|
375
400
|
b = b.to_a.join(' ')
|
376
401
|
end
|
@@ -386,7 +411,7 @@ module Squared
|
|
386
411
|
end
|
387
412
|
cmd = cmd.join(' && ')
|
388
413
|
else
|
389
|
-
cmd, opts, var, flags,
|
414
|
+
cmd, opts, var, flags, extra = args
|
390
415
|
end
|
391
416
|
if cmd
|
392
417
|
cmd = as_get(cmd)
|
@@ -394,7 +419,7 @@ module Squared
|
|
394
419
|
flags = append_hash(flags).join(' ') if flags.is_a?(Hash)
|
395
420
|
case opts
|
396
421
|
when Hash
|
397
|
-
opts = append_hash(opts)
|
422
|
+
opts = append_hash(opts, build: true)
|
398
423
|
cmd = as_a(cmd).push(flags).concat(opts).compact.join(' ')
|
399
424
|
when Enumerable
|
400
425
|
cmd = as_a(cmd).concat(opts.to_a)
|
@@ -404,10 +429,9 @@ module Squared
|
|
404
429
|
cmd = [cmd, flags, opts].compact.join(' ') if opts || flags
|
405
430
|
end
|
406
431
|
else
|
407
|
-
return unless respond_to?(:compose)
|
432
|
+
return unless (opts || extra) && respond_to?(:compose)
|
408
433
|
|
409
|
-
cmd = compose(as_get(opts), flags, script: true, args:
|
410
|
-
from = :script if from == :run && script?
|
434
|
+
cmd = compose(as_get(opts), flags, script: true, args: extra, from: from)
|
411
435
|
end
|
412
436
|
run(cmd, var, from: from, banner: banner, sync: sync)
|
413
437
|
end
|
@@ -416,6 +440,12 @@ module Squared
|
|
416
440
|
run_b(@depend, sync: sync, from: :depend)
|
417
441
|
end
|
418
442
|
|
443
|
+
def archive(*, sync: invoked_sync?('archive'), **)
|
444
|
+
return unless @archive.is_a?(Array)
|
445
|
+
|
446
|
+
unpack(path, **@archive, sync: sync, from: :archive)
|
447
|
+
end
|
448
|
+
|
419
449
|
def doc(*, sync: invoked_sync?('doc'), **)
|
420
450
|
run_b(@doc, sync: sync, from: :doc)
|
421
451
|
end
|
@@ -445,27 +475,31 @@ module Squared
|
|
445
475
|
rescue StandardError => e
|
446
476
|
log&.error e
|
447
477
|
ret = on(:error, from, e)
|
448
|
-
raise if
|
478
|
+
raise if exception && ret != true
|
449
479
|
end
|
450
|
-
|
451
|
-
|
452
|
-
|
453
|
-
|
454
|
-
|
455
|
-
|
456
|
-
|
457
|
-
|
458
|
-
|
459
|
-
|
460
|
-
|
461
|
-
|
462
|
-
|
463
|
-
|
464
|
-
|
465
|
-
|
480
|
+
else
|
481
|
+
if @clean.is_a?(Enumerable) && !series?(@clean)
|
482
|
+
as_a(@clean).each do |val|
|
483
|
+
val = val.to_s
|
484
|
+
path = basepath(val)
|
485
|
+
if path.directory? && val.match?(%r{[\\/]$})
|
486
|
+
log&.warn "rm -rf #{path}"
|
487
|
+
path.rmtree(verbose: verbose)
|
488
|
+
else
|
489
|
+
log&.warn "rm #{path}"
|
490
|
+
(val.include?('*') ? Dir[path] : [path]).each do |file|
|
491
|
+
next unless File.file?(file)
|
492
|
+
|
493
|
+
begin
|
494
|
+
File.delete(file)
|
495
|
+
rescue StandardError => e
|
496
|
+
log&.error e
|
497
|
+
end
|
466
498
|
end
|
467
499
|
end
|
468
500
|
end
|
501
|
+
else
|
502
|
+
run_b(@clean, sync: sync)
|
469
503
|
end
|
470
504
|
end
|
471
505
|
on :last, :clean
|
@@ -502,6 +536,119 @@ module Squared
|
|
502
536
|
end
|
503
537
|
end
|
504
538
|
|
539
|
+
def unpack(target, sync: true, uri: nil, digest: nil, ext: nil, force: false, depth: 1, headers: {},
|
540
|
+
from: :unpack)
|
541
|
+
if !target.exist?
|
542
|
+
target.mkpath
|
543
|
+
elsif !target.directory?
|
544
|
+
raise_error('invalid location', hint: target)
|
545
|
+
elsif !target.empty?
|
546
|
+
raise_error('directory not empty', hint: target) unless force || env('UNPACK_FORCE')
|
547
|
+
create = true
|
548
|
+
end
|
549
|
+
if digest
|
550
|
+
if (n = digest.index(':').to_i) > 0
|
551
|
+
size = digest[0, n].downcase
|
552
|
+
digest = digest[n + 1..-1]
|
553
|
+
else
|
554
|
+
size = digest.size
|
555
|
+
end
|
556
|
+
algo = case size
|
557
|
+
when 32, 'md5'
|
558
|
+
Digest::MD5
|
559
|
+
when 'rmd160'
|
560
|
+
Digest::RMD160
|
561
|
+
when 40, 'sha1'
|
562
|
+
Digest::SHA1
|
563
|
+
when 64, 'sha256'
|
564
|
+
Digest::SHA256
|
565
|
+
when 96, 'sha384'
|
566
|
+
Digest::SHA384
|
567
|
+
when 128, 'sha512'
|
568
|
+
Digest::SHA512
|
569
|
+
else
|
570
|
+
raise_error("invalid checksum: #{digest}", hint: name)
|
571
|
+
end
|
572
|
+
end
|
573
|
+
if (val = env('HEADERS')) && (out = parse_json(val, hint: "HEADERS_#{@envname}"))
|
574
|
+
headers = out
|
575
|
+
end
|
576
|
+
require 'open-uri'
|
577
|
+
data = nil
|
578
|
+
(uri = as_a(uri)).each_with_index do |url, index|
|
579
|
+
last = index == uri.size - 1
|
580
|
+
URI.open(url, headers) do |f|
|
581
|
+
data = f.read
|
582
|
+
if algo && algo.hexdigest(data) != digest
|
583
|
+
data = nil
|
584
|
+
raise_error("checksum failed: #{digest}", hint: url) if last
|
585
|
+
end
|
586
|
+
next if ext && index == 0
|
587
|
+
|
588
|
+
case f.content_type
|
589
|
+
when 'application/zip'
|
590
|
+
ext = 'zip'
|
591
|
+
when 'application/x-gzip'
|
592
|
+
ext = 'tgz'
|
593
|
+
when 'application/x-xz'
|
594
|
+
ext = 'txz'
|
595
|
+
end
|
596
|
+
end
|
597
|
+
if data
|
598
|
+
uri = url
|
599
|
+
break
|
600
|
+
elsif last
|
601
|
+
raise_error('no content', hint: url)
|
602
|
+
end
|
603
|
+
end
|
604
|
+
ext ||= URI.parse(uri).path[/^.+?\.((?:tar\.)?\w+)$/i, 1]
|
605
|
+
if (n = env("#{ext == 'zip' ? 'ZIP' : 'TAR'}_DEPTH", ignore: false))
|
606
|
+
depth = n.to_i
|
607
|
+
end
|
608
|
+
begin
|
609
|
+
require 'tempfile'
|
610
|
+
file = Tempfile.new("#{name}-")
|
611
|
+
file.write(data)
|
612
|
+
file.close
|
613
|
+
if create
|
614
|
+
warn log_message(Logger::WARN, name, 'force remove', hint: target, pass: true)
|
615
|
+
target.rmtree(verbose: true)
|
616
|
+
target.mkpath
|
617
|
+
end
|
618
|
+
case ext
|
619
|
+
when 'zip', 'aar'
|
620
|
+
session 'unzip', shell_quote(file.path), quote_option('d', target)
|
621
|
+
when 'tar', 'tgz', 'tar.gz', 'tar.xz'
|
622
|
+
flags = +(verbose ? 'v' : '')
|
623
|
+
case ext
|
624
|
+
when 'tgz', 'tar.gz'
|
625
|
+
flags += 'z'
|
626
|
+
when 'txz', 'tar.xz'
|
627
|
+
flags += 'J'
|
628
|
+
end
|
629
|
+
session 'tar', "-x#{flags}", basic_option('strip-components', depth), quote_option('f', file.path),
|
630
|
+
quote_option('C', target)
|
631
|
+
depth = 0
|
632
|
+
else
|
633
|
+
raise_error("unsupported format: #{ext}", hint: uri)
|
634
|
+
end
|
635
|
+
run(sync: sync, from: from)
|
636
|
+
while depth > 0 && target.children.size == 1
|
637
|
+
entry = target.children.first
|
638
|
+
break unless entry.directory?
|
639
|
+
|
640
|
+
dest = target.join(File.basename(file.path))
|
641
|
+
FileUtils.mv(entry, dest)
|
642
|
+
dest.children.each { |file| FileUtils.mv(file, target) }
|
643
|
+
dest.rmdir
|
644
|
+
target = entry
|
645
|
+
depth -= 1
|
646
|
+
end
|
647
|
+
ensure
|
648
|
+
file&.unlink
|
649
|
+
end
|
650
|
+
end
|
651
|
+
|
505
652
|
def first(key, *args, **kwargs, &blk)
|
506
653
|
event(:first, key, *args, **kwargs, &blk)
|
507
654
|
end
|
@@ -514,17 +661,38 @@ module Squared
|
|
514
661
|
event(:error, key, *args, **kwargs, &blk)
|
515
662
|
end
|
516
663
|
|
517
|
-
def event(name, key, *args, **kwargs, &blk)
|
518
|
-
|
664
|
+
def event(name, key, *args, override: false, **kwargs, &blk)
|
665
|
+
data = @events[name.to_sym] ||= {}
|
666
|
+
items = if override
|
667
|
+
data[key.to_sym] = []
|
668
|
+
else
|
669
|
+
data[key.to_sym] ||= []
|
670
|
+
end
|
671
|
+
items << [block_given? ? [blk] + args : args, kwargs]
|
672
|
+
self
|
519
673
|
end
|
520
674
|
|
521
675
|
def as(cmd, script, to = nil)
|
522
676
|
script = { "#{script}": to } if to
|
523
677
|
data = (@as ||= {})[cmd.to_sym] ||= {}
|
524
678
|
script.each { |key, val| data[key.to_s] = val }
|
679
|
+
self
|
680
|
+
end
|
681
|
+
|
682
|
+
def series(key, override: false, &blk)
|
683
|
+
if blocks.include?(key.to_sym) && block_given?
|
684
|
+
if !override && series?(target = instance_variable_get(:"@#{key}"))
|
685
|
+
target << blk
|
686
|
+
else
|
687
|
+
instance_variable_set :"@#{key}", [blk]
|
688
|
+
end
|
689
|
+
else
|
690
|
+
log&.warn "series: @#{key} (invalid)"
|
691
|
+
end
|
692
|
+
self
|
525
693
|
end
|
526
694
|
|
527
|
-
def variable_set(key, *val, **kwargs)
|
695
|
+
def variable_set(key, *val, **kwargs, &blk)
|
528
696
|
if variables.include?(key)
|
529
697
|
case key
|
530
698
|
when :build, :run
|
@@ -545,17 +713,22 @@ module Squared
|
|
545
713
|
when :dependfile
|
546
714
|
@dependfile = basepath(*val)
|
547
715
|
else
|
548
|
-
|
716
|
+
if blocks.include?(key) && block_given?
|
717
|
+
series key, &blk
|
718
|
+
else
|
719
|
+
instance_variable_set(:"@#{key}", block_given? && val.empty? ? blk : val.first)
|
720
|
+
end
|
549
721
|
end
|
550
722
|
else
|
551
723
|
log&.warn "variable_set: @#{key} (private)"
|
552
724
|
end
|
725
|
+
self
|
553
726
|
end
|
554
727
|
|
555
728
|
def enabled?(ref = nil, **)
|
556
729
|
return false if ref && !ref?(ref)
|
557
730
|
|
558
|
-
path.directory? && !path.empty?
|
731
|
+
(path.directory? && !path.empty?) || archive?
|
559
732
|
end
|
560
733
|
|
561
734
|
def has?(meth, ref = nil)
|
@@ -569,7 +742,7 @@ module Squared
|
|
569
742
|
end
|
570
743
|
|
571
744
|
def build?
|
572
|
-
!!@output[0] || script?
|
745
|
+
!!@output[0] || script? || series?(@run)
|
573
746
|
end
|
574
747
|
|
575
748
|
def script?
|
@@ -580,6 +753,10 @@ module Squared
|
|
580
753
|
!!@depend
|
581
754
|
end
|
582
755
|
|
756
|
+
def archive?
|
757
|
+
@archive.is_a?(Hash) && (!path.exist? || path.empty?)
|
758
|
+
end
|
759
|
+
|
583
760
|
def graph?
|
584
761
|
@graph.is_a?(Array) && !@graph.empty?
|
585
762
|
end
|
@@ -640,8 +817,12 @@ module Squared
|
|
640
817
|
@ref.reverse_each
|
641
818
|
end
|
642
819
|
|
643
|
-
def basepath(*args
|
644
|
-
|
820
|
+
def basepath(*args)
|
821
|
+
path.join(*args)
|
822
|
+
end
|
823
|
+
|
824
|
+
def rootpath(*args, ascend: nil)
|
825
|
+
ret = basepath(*args)
|
645
826
|
return ret unless ascend && !ret.exist?
|
646
827
|
|
647
828
|
path.parent.ascend.each do |dir|
|
@@ -678,7 +859,7 @@ module Squared
|
|
678
859
|
unless cmd
|
679
860
|
if warning?
|
680
861
|
from &&= from.to_s
|
681
|
-
warn log_message(Logger::WARN, from || 'unknown', subject: project, hint: 'no command given')
|
862
|
+
warn log_message(Logger::WARN, from || 'unknown', subject: project, hint: 'no command given', pass: true)
|
682
863
|
end
|
683
864
|
return
|
684
865
|
end
|
@@ -690,7 +871,7 @@ module Squared
|
|
690
871
|
log&.warn "ENV was discarded: #{var}" if var
|
691
872
|
task_invoke(cmd, exception: exception, warning: warning?)
|
692
873
|
else
|
693
|
-
print_item format_banner(cmd, banner: banner) if sync
|
874
|
+
print_item format_banner(cmd, banner: banner) if sync
|
694
875
|
args = var.is_a?(Hash) ? [var, cmd] : [cmd]
|
695
876
|
shell(*args, chdir: chdir, exception: exception)
|
696
877
|
end
|
@@ -715,18 +896,23 @@ module Squared
|
|
715
896
|
end
|
716
897
|
|
717
898
|
def run_b(obj, from: nil, sync: true)
|
718
|
-
|
719
|
-
|
720
|
-
|
721
|
-
build(*obj, from: from, sync: sync)
|
899
|
+
case obj
|
900
|
+
when Proc, Method
|
901
|
+
obj.call
|
722
902
|
else
|
723
|
-
|
903
|
+
if series?(obj)
|
904
|
+
obj.each(&:call)
|
905
|
+
elsif obj.is_a?(Array) && obj.any? { |val| !val.is_a?(String) }
|
906
|
+
build(*obj, from: from, sync: sync)
|
907
|
+
elsif obj
|
908
|
+
run_s(obj.is_a?(Enumerable) ? obj.to_a : obj, from: from, sync: sync)
|
909
|
+
end
|
724
910
|
end
|
725
911
|
end
|
726
912
|
|
727
913
|
def graph_branch(target, data, tasks = nil, out = nil, sync: true, pass: [], done: [], depth: 0,
|
728
914
|
single: false, last: false, context: nil)
|
729
|
-
tag = ->(proj) { "#{proj.name}#{SEM_VER
|
915
|
+
tag = ->(proj) { "#{proj.name}#{SEM_VER.match?(proj.version) ? "@#{proj.version}" : ''}" }
|
730
916
|
check = ->(deps) { deps.reject { |val| done.include?(val) } }
|
731
917
|
dedupe = lambda do |name|
|
732
918
|
next [] unless (ret = data[name])
|
@@ -784,13 +970,7 @@ module Squared
|
|
784
970
|
next if pass.include?(meth)
|
785
971
|
|
786
972
|
if workspace.task_defined?(cmd = task_join(proj.name, meth))
|
787
|
-
if ENV.key?(key = "BANNER_#{proj.name.upcase}")
|
788
|
-
key = nil
|
789
|
-
else
|
790
|
-
ENV[key] = '0'
|
791
|
-
end
|
792
973
|
run(cmd, sync: false, banner: false)
|
793
|
-
ENV.delete(key) if key
|
794
974
|
elsif proj.has?(meth, tasks || group ? nil : workspace.baseref)
|
795
975
|
proj.__send__(meth.to_sym, sync: sync)
|
796
976
|
end
|
@@ -859,7 +1039,7 @@ module Squared
|
|
859
1039
|
end
|
860
1040
|
|
861
1041
|
def session(*cmd, prefix: cmd.first, main: true, options: true)
|
862
|
-
prefix =
|
1042
|
+
prefix = prefix.to_s.upcase
|
863
1043
|
if (val = PATH[prefix] || PATH[prefix.to_sym])
|
864
1044
|
cmd[0] = shell_quote(val, force: false)
|
865
1045
|
end
|
@@ -873,8 +1053,7 @@ module Squared
|
|
873
1053
|
def session_delete(*list, target: @session)
|
874
1054
|
ret = []
|
875
1055
|
list.each do |val|
|
876
|
-
|
877
|
-
if (key = target.find { |opt| opt =~ pat })
|
1056
|
+
if (key = target.find { |opt| opt.match?(/^#{Regexp.escape(shell_option(val))}(?: |=|$)/o) })
|
878
1057
|
target.delete(key)
|
879
1058
|
ret << key
|
880
1059
|
end
|
@@ -889,30 +1068,33 @@ module Squared
|
|
889
1068
|
def session_done(cmd)
|
890
1069
|
return cmd unless cmd.respond_to?(:done)
|
891
1070
|
|
892
|
-
raise_error('no args
|
1071
|
+
raise_error('no args added', hint: cmd.first || name) unless cmd.size > 1
|
893
1072
|
@session = nil if cmd == @session
|
894
1073
|
cmd.done
|
895
1074
|
end
|
896
1075
|
|
897
|
-
def option(*args,
|
1076
|
+
def option(*args, prefix: @session&.first, **kwargs)
|
898
1077
|
if prefix
|
899
1078
|
args.each do |val|
|
900
|
-
ret = env("#{
|
1079
|
+
ret = env("#{prefix}_#{val.gsub(/\W/, '_')}".upcase, **kwargs)
|
901
1080
|
return ret if ret
|
902
1081
|
end
|
903
1082
|
end
|
904
1083
|
nil
|
905
1084
|
end
|
906
1085
|
|
907
|
-
def option_sanitize(opts, list, target: @session, no: nil,
|
1086
|
+
def option_sanitize(opts, list, target: @session, no: nil, first: false, pass: ['='])
|
908
1087
|
ret = []
|
909
1088
|
reg = []
|
910
1089
|
bare = []
|
911
1090
|
e = []
|
912
1091
|
b = []
|
1092
|
+
m = []
|
913
1093
|
p = []
|
914
1094
|
q = []
|
1095
|
+
qq = []
|
915
1096
|
i = []
|
1097
|
+
f = []
|
916
1098
|
list = list.map do |val|
|
917
1099
|
x, y = val.split('|')
|
918
1100
|
if y
|
@@ -932,16 +1114,19 @@ module Squared
|
|
932
1114
|
e << flag
|
933
1115
|
when 'b'
|
934
1116
|
b << flag
|
1117
|
+
when 'm'
|
1118
|
+
m << flag
|
935
1119
|
when 'q'
|
1120
|
+
qq << flag if val[n + 2] == 'q'
|
936
1121
|
q << flag
|
937
1122
|
when 'p'
|
938
1123
|
p << flag
|
939
1124
|
when 'i'
|
940
1125
|
i << flag
|
941
|
-
when '
|
942
|
-
|
1126
|
+
when 'f'
|
1127
|
+
f << flag
|
943
1128
|
else
|
944
|
-
|
1129
|
+
reg << Regexp.escape(flag)
|
945
1130
|
end
|
946
1131
|
bare << flag if val.end_with?('?')
|
947
1132
|
else
|
@@ -959,36 +1144,37 @@ module Squared
|
|
959
1144
|
elsif opt.start_with?('no-') && no.include?(name = opt[3..-1])
|
960
1145
|
target << "--no-#{name}"
|
961
1146
|
else
|
962
|
-
if opt =~
|
963
|
-
|
964
|
-
|
965
|
-
|
966
|
-
|
967
|
-
target <<
|
968
|
-
elsif
|
969
|
-
target << quote_option(
|
970
|
-
elsif
|
971
|
-
target <<
|
1147
|
+
if opt =~ /^([^=]+)=(.+)$/
|
1148
|
+
key = $1
|
1149
|
+
val = $2
|
1150
|
+
match = ->(flag, pat) { flag.include?(key) && pat.match?(val) }
|
1151
|
+
if e.include?(key)
|
1152
|
+
target << shell_option(key, val)
|
1153
|
+
elsif q.include?(key)
|
1154
|
+
target << quote_option(key, val, double: qq.include?(key))
|
1155
|
+
elsif p.include?(key)
|
1156
|
+
target << quote_option(key, basepath(val))
|
1157
|
+
elsif m.include?(key)
|
1158
|
+
target << basic_option(key, val, merge: true)
|
1159
|
+
elsif b.include?(key) || match.(i, /^\d+$/) || match.(f, /^\d*(?:\.\d+)?$/)
|
1160
|
+
target << basic_option(key, val)
|
972
1161
|
else
|
973
1162
|
ret << opt
|
974
1163
|
end
|
975
|
-
opt =
|
1164
|
+
opt = key
|
976
1165
|
else
|
977
1166
|
ret << opt
|
978
|
-
found = true if args
|
979
1167
|
end
|
980
|
-
found = true if first && pass.none? { |
|
1168
|
+
found = true if first && pass.none? { |s| opt.include?(s) }
|
981
1169
|
end
|
982
1170
|
end
|
983
|
-
[ret, reg.empty? ? /\A\s+\z/ :
|
1171
|
+
[ret, reg.empty? ? /\A\s+\z/ : /^(#{reg.join('|')})=(.+)$/]
|
984
1172
|
end
|
985
1173
|
|
986
1174
|
def option_clear(opts, target: @session, **kwargs)
|
987
|
-
return if opts.empty?
|
988
|
-
|
989
1175
|
kwargs[:subject] ||= target&.first
|
990
|
-
kwargs[:hint] ||= '
|
991
|
-
warn log_message(
|
1176
|
+
kwargs[:hint] ||= 'not used'
|
1177
|
+
warn log_message(Logger::WARN, opts.join(', '), pass: true, **kwargs) unless opts.empty?
|
992
1178
|
end
|
993
1179
|
|
994
1180
|
def print_item(*val)
|
@@ -1018,7 +1204,7 @@ module Squared
|
|
1018
1204
|
val
|
1019
1205
|
end
|
1020
1206
|
end
|
1021
|
-
out << sub_style(
|
1207
|
+
out << sub_style(ARG[:BORDER][1] * n, styles: border)
|
1022
1208
|
out.join("\n")
|
1023
1209
|
end
|
1024
1210
|
|
@@ -1030,7 +1216,7 @@ module Squared
|
|
1030
1216
|
sub.each { |h| s = sub_style(s, **h) }
|
1031
1217
|
s
|
1032
1218
|
end
|
1033
|
-
ret = [sub_style(
|
1219
|
+
ret = [sub_style(ARG[:BORDER][1] * n, styles: kwargs.key?(:border) ? kwargs[:border] : borderstyle), *lines]
|
1034
1220
|
ret.reverse! if reverse
|
1035
1221
|
ret.join("\n")
|
1036
1222
|
end
|
@@ -1056,7 +1242,7 @@ module Squared
|
|
1056
1242
|
if verbose
|
1057
1243
|
out = []
|
1058
1244
|
if data[:command]
|
1059
|
-
if /\A(?:"((?:[^"]|(?<=\\)")+)"|'((?:[^']|(?<=\\)')+)'|(\S+))
|
1245
|
+
if cmd =~ /\A(?:"((?:[^"]|(?<=\\)")+)"|'((?:[^']|(?<=\\)')+)'|(\S+)) /
|
1060
1246
|
path = $3 || $2 || $1
|
1061
1247
|
cmd = cmd.sub(path, File.basename(path).upcase)
|
1062
1248
|
end
|
@@ -1094,9 +1280,9 @@ module Squared
|
|
1094
1280
|
unless items.empty?
|
1095
1281
|
pad = items.size.to_s.size
|
1096
1282
|
items.each_with_index do |val, i|
|
1097
|
-
next unless reg.empty? || reg.any? { |pat| val[0]
|
1283
|
+
next unless reg.empty? || reg.any? { |pat| val[0].match?(pat) }
|
1098
1284
|
|
1099
|
-
out << "#{
|
1285
|
+
out << "#{i.succ.to_s.rjust(pad)}. #{each ? each.(val) : val[0]}"
|
1100
1286
|
end
|
1101
1287
|
end
|
1102
1288
|
sub = [headerstyle]
|
@@ -1130,9 +1316,9 @@ module Squared
|
|
1130
1316
|
opts.each { |val| target << shell_option(flag, val) }
|
1131
1317
|
end
|
1132
1318
|
|
1133
|
-
def append_hash(data, target: @session)
|
1319
|
+
def append_hash(data, target: @session, build: false)
|
1134
1320
|
target ||= []
|
1135
|
-
if (type = env('BUILD', suffix: 'TYPE') || ENV['BUILD_TYPE'])
|
1321
|
+
if build && (type = env('BUILD', suffix: 'TYPE') || ENV['BUILD_TYPE'])
|
1136
1322
|
type = "__#{type}__"
|
1137
1323
|
if (extra = data[type] || data[type.to_sym]).is_a?(Hash)
|
1138
1324
|
data = data.merge(extra)
|
@@ -1161,7 +1347,7 @@ module Squared
|
|
1161
1347
|
target
|
1162
1348
|
end
|
1163
1349
|
|
1164
|
-
def append_any(val, target: @session, delim: false)
|
1350
|
+
def append_any(val, target: @session, build: false, delim: false)
|
1165
1351
|
if delim && !target.include?('--')
|
1166
1352
|
target << '--'
|
1167
1353
|
else
|
@@ -1171,7 +1357,7 @@ module Squared
|
|
1171
1357
|
when String
|
1172
1358
|
target << val
|
1173
1359
|
when Hash
|
1174
|
-
append_hash(val, target: target)
|
1360
|
+
append_hash(val, target: target, build: build)
|
1175
1361
|
when Enumerable
|
1176
1362
|
if target.is_a?(Array)
|
1177
1363
|
target.concat(val.to_a)
|
@@ -1180,6 +1366,7 @@ module Squared
|
|
1180
1366
|
end
|
1181
1367
|
else
|
1182
1368
|
target.delete('--') if delim
|
1369
|
+
nil
|
1183
1370
|
end
|
1184
1371
|
end
|
1185
1372
|
|
@@ -1188,8 +1375,9 @@ module Squared
|
|
1188
1375
|
|
1189
1376
|
target << '--' if delim && !target.include?('--')
|
1190
1377
|
list.map do |val|
|
1191
|
-
|
1192
|
-
|
1378
|
+
item = escape ? shell_escape(val, quote: quote) : shell_quote(val)
|
1379
|
+
target << item
|
1380
|
+
item
|
1193
1381
|
end
|
1194
1382
|
end
|
1195
1383
|
|
@@ -1197,8 +1385,8 @@ module Squared
|
|
1197
1385
|
**kwargs)
|
1198
1386
|
return if (list = list.flatten).empty?
|
1199
1387
|
|
1200
|
-
list.
|
1201
|
-
next unless (val = option(opt,
|
1388
|
+
list.each do |opt|
|
1389
|
+
next unless (val = option(opt, **kwargs))
|
1202
1390
|
|
1203
1391
|
return target << (if flag
|
1204
1392
|
shell_option(opt, equals ? val : nil, quote: quote, escape: escape, force: force)
|
@@ -1214,7 +1402,7 @@ module Squared
|
|
1214
1402
|
return if (list = list.flatten).empty?
|
1215
1403
|
|
1216
1404
|
ret = []
|
1217
|
-
list.
|
1405
|
+
list.each do |flag|
|
1218
1406
|
next unless (val = option(flag, **kwargs))
|
1219
1407
|
|
1220
1408
|
if val == '0' && no
|
@@ -1227,7 +1415,45 @@ module Squared
|
|
1227
1415
|
end
|
1228
1416
|
|
1229
1417
|
def append_nocolor(target: @session)
|
1230
|
-
target << '--no-color' if !ARG[:COLOR] || stdin? || option('no-color',
|
1418
|
+
target << '--no-color' if !ARG[:COLOR] || stdin? || option('no-color', ignore: false)
|
1419
|
+
end
|
1420
|
+
|
1421
|
+
def merge_opts(base, data)
|
1422
|
+
return data unless base
|
1423
|
+
return base unless data
|
1424
|
+
|
1425
|
+
ret = case data
|
1426
|
+
when String
|
1427
|
+
case base
|
1428
|
+
when String
|
1429
|
+
"#{base} #{data}"
|
1430
|
+
when Hash
|
1431
|
+
"#{append_hash(base).join(' ')} #{data}"
|
1432
|
+
when Enumerable
|
1433
|
+
"#{base.to_a.join(' ')} #{data}"
|
1434
|
+
end
|
1435
|
+
when Hash
|
1436
|
+
case base
|
1437
|
+
when String
|
1438
|
+
"#{base} #{append_hash(data).join(' ')}"
|
1439
|
+
when Hash
|
1440
|
+
base.merge(data)
|
1441
|
+
when Enumerable
|
1442
|
+
base.to_a + append_hash(data)
|
1443
|
+
end
|
1444
|
+
when Enumerable
|
1445
|
+
case base
|
1446
|
+
when String
|
1447
|
+
"#{base} #{data.to_a.join(' ')}"
|
1448
|
+
when Hash
|
1449
|
+
"#{append_hash(base).join(' ')} #{data.to_a.join(' ')}"
|
1450
|
+
when Enumerable
|
1451
|
+
base.to_a + data.to_a
|
1452
|
+
end
|
1453
|
+
else
|
1454
|
+
base
|
1455
|
+
end
|
1456
|
+
ret || data
|
1231
1457
|
end
|
1232
1458
|
|
1233
1459
|
def collect_hash(data, pass: [])
|
@@ -1236,10 +1462,19 @@ module Squared
|
|
1236
1462
|
ret
|
1237
1463
|
end
|
1238
1464
|
|
1239
|
-
def
|
1465
|
+
def parse_json(val, hint: nil)
|
1466
|
+
ret = JSON.parse(val)
|
1467
|
+
raise_error('invalid JSON object', val, hint: hint) unless ret.is_a?(Hash)
|
1468
|
+
rescue StandardError => e
|
1469
|
+
log&.warn e
|
1470
|
+
else
|
1471
|
+
ret
|
1472
|
+
end
|
1473
|
+
|
1474
|
+
def param_guard(action, flag, args: nil, key: nil, pat: nil, values: nil)
|
1240
1475
|
if args && key
|
1241
|
-
val = args
|
1242
|
-
return val unless val.nil? || (pat && !val.match?(pat))
|
1476
|
+
val = args[key]
|
1477
|
+
return val unless val.nil? || (pat && !val.match?(pat)) || (values && !values.include?(val))
|
1243
1478
|
|
1244
1479
|
@session = nil
|
1245
1480
|
raise_error(action, "#{flag}[#{key}]", hint: val.nil? ? 'missing' : 'invalid')
|
@@ -1250,6 +1485,17 @@ module Squared
|
|
1250
1485
|
args
|
1251
1486
|
end
|
1252
1487
|
|
1488
|
+
def relativepath(*files, all: false)
|
1489
|
+
return [] if files.empty?
|
1490
|
+
|
1491
|
+
files.flatten.map { |val| Pathname.new(val) }.select { |val| projectpath?(val) }.map do |val|
|
1492
|
+
val = val.absolute? ? val.to_s.sub(/^#{Regexp.escape(File.join(path, ''))}/o, '') : val.to_s
|
1493
|
+
val = val[2..-1] if val.start_with?('./')
|
1494
|
+
val = "#{val}*" if all && val.end_with?('/')
|
1495
|
+
val
|
1496
|
+
end
|
1497
|
+
end
|
1498
|
+
|
1253
1499
|
def projectmap(files, parent: false)
|
1254
1500
|
files = files.select { |val| projectpath?(val) } unless parent
|
1255
1501
|
files.map { |val| val == '.' ? '.' : shell_quote(basepath(val.strip)) }
|
@@ -1291,22 +1537,28 @@ module Squared
|
|
1291
1537
|
val.compact.map { |s| color(s) }.flatten
|
1292
1538
|
end
|
1293
1539
|
|
1540
|
+
def epochtime
|
1541
|
+
DateTime.now.strftime('%Q').to_i
|
1542
|
+
end
|
1543
|
+
|
1294
1544
|
def on(event, from, *args, **kwargs)
|
1295
|
-
return unless from
|
1545
|
+
return unless from
|
1296
1546
|
|
1297
|
-
|
1298
|
-
|
1299
|
-
|
1300
|
-
|
1301
|
-
|
1302
|
-
|
1303
|
-
|
1304
|
-
|
1305
|
-
|
1306
|
-
|
1307
|
-
|
1308
|
-
|
1309
|
-
|
1547
|
+
@events[event][from]&.each do |obj|
|
1548
|
+
if obj.is_a?(Array) && obj[1].is_a?(Hash)
|
1549
|
+
opts = kwargs.empty? ? obj[1] : obj[1].merge(kwargs)
|
1550
|
+
target = obj[0]
|
1551
|
+
else
|
1552
|
+
opts = kwargs
|
1553
|
+
target = obj
|
1554
|
+
end
|
1555
|
+
as_a(target, flat: true).each do |cmd|
|
1556
|
+
case cmd
|
1557
|
+
when Proc, Method
|
1558
|
+
cmd.call(*args, **opts)
|
1559
|
+
when String
|
1560
|
+
run(cmd, **opts)
|
1561
|
+
end
|
1310
1562
|
end
|
1311
1563
|
end
|
1312
1564
|
end
|
@@ -1315,7 +1567,7 @@ module Squared
|
|
1315
1567
|
pwd = Pathname.pwd
|
1316
1568
|
if block_given?
|
1317
1569
|
begin
|
1318
|
-
if path == pwd || pass == true || (pass.is_a?(String) && semscan(pass).join
|
1570
|
+
if path == pwd || pass == true || (pass.is_a?(String) && semscan(pass).join >= RUBY_VERSION)
|
1319
1571
|
ret = instance_eval(&blk)
|
1320
1572
|
else
|
1321
1573
|
Dir.chdir(path)
|
@@ -1347,23 +1599,53 @@ module Squared
|
|
1347
1599
|
end
|
1348
1600
|
|
1349
1601
|
def run_set(cmd, val = nil, opts: nil, **)
|
1350
|
-
|
1351
|
-
|
1352
|
-
|
1602
|
+
diso = @output[1] == false && !@output[0].nil?
|
1603
|
+
dise = @output[2] == false
|
1604
|
+
parse = lambda do |data|
|
1605
|
+
ret = []
|
1606
|
+
if data[:command]
|
1607
|
+
ret[0] = data[:command]
|
1608
|
+
ret[1] = data[:opts] unless diso
|
1609
|
+
ret[3] = data[:args]
|
1610
|
+
elsif data[:script]
|
1611
|
+
ret[1] = data[:script]
|
1612
|
+
ret[3] = data[:opts]
|
1613
|
+
ret[4] = data[:args]
|
1614
|
+
else
|
1615
|
+
ret[0] = false
|
1616
|
+
end
|
1617
|
+
ret[2] = data[:env] unless dise
|
1618
|
+
ret
|
1619
|
+
end
|
1620
|
+
case cmd
|
1621
|
+
when Array
|
1622
|
+
@output = if cmd.all? { |data| data.is_a?(Hash) }
|
1623
|
+
diso = false
|
1624
|
+
dise = false
|
1625
|
+
cmd.map { |data| parse.(data) }
|
1626
|
+
else
|
1627
|
+
cmd.dup
|
1628
|
+
end
|
1629
|
+
return
|
1630
|
+
when Hash
|
1631
|
+
@output = parse.(data)
|
1632
|
+
else
|
1633
|
+
@output[0] = cmd
|
1634
|
+
end
|
1635
|
+
unless diso
|
1353
1636
|
if opts == false
|
1354
1637
|
@output[1] = false
|
1355
1638
|
elsif opts && opts != true
|
1356
1639
|
@output[1] = opts
|
1357
1640
|
end
|
1358
1641
|
end
|
1359
|
-
|
1360
|
-
|
1361
|
-
|
1362
|
-
|
1363
|
-
|
1364
|
-
|
1642
|
+
return if dise
|
1643
|
+
|
1644
|
+
if val.is_a?(Hash)
|
1645
|
+
@output[2] = val
|
1646
|
+
elsif val == false
|
1647
|
+
@output[2] = false
|
1365
1648
|
end
|
1366
|
-
@output[0] = cmd
|
1367
1649
|
end
|
1368
1650
|
|
1369
1651
|
def script_set(cmd, prod: nil, args: nil, **)
|
@@ -1379,6 +1661,8 @@ module Squared
|
|
1379
1661
|
end
|
1380
1662
|
|
1381
1663
|
def as_get(val)
|
1664
|
+
return unless val
|
1665
|
+
|
1382
1666
|
@global && (ret = @as && @as[from] && @as[from][val]) ? ret : val
|
1383
1667
|
end
|
1384
1668
|
|
@@ -1404,8 +1688,7 @@ module Squared
|
|
1404
1688
|
end
|
1405
1689
|
|
1406
1690
|
def projectpath?(val)
|
1407
|
-
val
|
1408
|
-
val.absolute? ? val.to_s.start_with?(File.join(path, '')) : !val.to_s.start_with?(File.join('..', ''))
|
1691
|
+
Pathname.new(val).absolute? ? val.to_s.start_with?(File.join(path, '')) : !val.to_s.start_with?('..')
|
1409
1692
|
end
|
1410
1693
|
|
1411
1694
|
def semmajor?(cur, want)
|
@@ -1414,19 +1697,20 @@ module Squared
|
|
1414
1697
|
|
1415
1698
|
def runnable?(val)
|
1416
1699
|
case val
|
1417
|
-
when String
|
1700
|
+
when String, Enumerable, Proc, Method
|
1418
1701
|
true
|
1419
|
-
when Enumerable
|
1420
|
-
!val.is_a?(Hash)
|
1421
1702
|
else
|
1422
1703
|
false
|
1423
1704
|
end
|
1424
1705
|
end
|
1425
1706
|
|
1707
|
+
def series?(val)
|
1708
|
+
val.is_a?(Array) && val.all? { |p| p.is_a?(Proc) || p.is_a?(Method) }
|
1709
|
+
end
|
1710
|
+
|
1426
1711
|
def session_arg?(*list, target: @session, value: false)
|
1427
1712
|
list.any? do |val|
|
1428
|
-
|
1429
|
-
target.any? { |opt| opt =~ pat }
|
1713
|
+
target.any? { |opt| opt.match?(/^#{Regexp.escape(shell_option(val))}#{value ? '[ =].' : '(?:[ =]|$)'}/o) }
|
1430
1714
|
end
|
1431
1715
|
end
|
1432
1716
|
|
@@ -1463,6 +1747,10 @@ module Squared
|
|
1463
1747
|
Base.tasks + VAR_SET
|
1464
1748
|
end
|
1465
1749
|
|
1750
|
+
def blocks
|
1751
|
+
BLK_SET
|
1752
|
+
end
|
1753
|
+
|
1466
1754
|
def borderstyle
|
1467
1755
|
((data = workspace.banner_get(*@ref, group: group)) && data[:border]) || theme[:border]
|
1468
1756
|
end
|