squared 0.5.2 → 0.5.4
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 +74 -0
- data/README.ruby.md +21 -15
- data/lib/squared/common/format.rb +6 -4
- data/lib/squared/common/prompt.rb +3 -3
- data/lib/squared/common/shell.rb +9 -5
- data/lib/squared/common/system.rb +3 -3
- data/lib/squared/common/utils.rb +9 -0
- data/lib/squared/version.rb +1 -1
- data/lib/squared/workspace/application.rb +25 -16
- data/lib/squared/workspace/project/base.rb +201 -140
- data/lib/squared/workspace/project/docker.rb +83 -70
- data/lib/squared/workspace/project/git.rb +234 -152
- data/lib/squared/workspace/project/node.rb +87 -34
- data/lib/squared/workspace/project/python.rb +55 -22
- data/lib/squared/workspace/project/ruby.rb +101 -58
- data/lib/squared/workspace/project/support/class.rb +66 -17
- data/lib/squared/workspace/repo.rb +47 -43
- data/lib/squared/workspace/series.rb +4 -4
- data/lib/squared/workspace/support/base.rb +17 -0
- data/lib/squared/workspace/support.rb +1 -0
- data/lib/squared/workspace.rb +0 -8
- data/squared.gemspec +2 -2
- metadata +2 -1
@@ -19,10 +19,10 @@ module Squared
|
|
19
19
|
include ::Comparable
|
20
20
|
|
21
21
|
VAR_SET = %i[parent global script index envname desc dependfile dependindex theme archive env dev prod graph
|
22
|
-
pass exclude].freeze
|
22
|
+
pass only exclude].freeze
|
23
23
|
BLK_SET = %i[run depend doc lint test copy clean].freeze
|
24
|
-
SEM_VER = /\b(\d+)(?:(\.)(\d+))?(?:(\.)(\d+)(\S+)
|
25
|
-
URI_SCHEME = %r{
|
24
|
+
SEM_VER = /\b(\d+)(?:(\.)(\d+))?(?:(\.)(\d+))?-?(\S+)?\b/.freeze
|
25
|
+
URI_SCHEME = %r{\A([a-z][a-z\d+-.]*)://[^@:\[\]\\^<>|\s]}i.freeze
|
26
26
|
TASK_METADATA = Rake::TaskManager.record_task_metadata
|
27
27
|
private_constant :VAR_SET, :BLK_SET, :SEM_VER, :URI_SCHEME, :TASK_METADATA
|
28
28
|
|
@@ -73,8 +73,8 @@ module Squared
|
|
73
73
|
'unpack' => %i[zip tar gem ext].freeze
|
74
74
|
})
|
75
75
|
|
76
|
-
attr_reader :name, :project, :workspace, :path, :theme, :
|
77
|
-
:
|
76
|
+
attr_reader :name, :project, :workspace, :path, :theme, :group, :parent, :dependfile,
|
77
|
+
:exception, :pipe, :verbose
|
78
78
|
|
79
79
|
def initialize(workspace, path, name, *, group: nil, first: {}, last: {}, error: {}, common: ARG[:COMMON],
|
80
80
|
**kwargs)
|
@@ -89,16 +89,15 @@ module Squared
|
|
89
89
|
@test = kwargs[:test]
|
90
90
|
@copy = kwargs[:copy]
|
91
91
|
@clean = kwargs[:clean]
|
92
|
-
@version = kwargs[:version]
|
93
92
|
@release = kwargs[:release]
|
93
|
+
self.version = kwargs[:version]
|
94
|
+
self.exception = kwargs[:exception]
|
95
|
+
self.pipe = kwargs[:pipe]
|
96
|
+
self.verbose = kwargs[:verbose]
|
94
97
|
@output = []
|
95
98
|
@ref = []
|
96
99
|
@children = []
|
97
|
-
@events = {
|
98
|
-
first: first,
|
99
|
-
last: last,
|
100
|
-
error: error
|
101
|
-
}
|
100
|
+
@events = hashobj.update({ first: first, last: last, error: error })
|
102
101
|
@envname = env_key(@name).freeze
|
103
102
|
@desc = (@name.include?(':') ? @name.split(':').join(ARG[:SPACE]) : @name).freeze
|
104
103
|
@parent = nil
|
@@ -110,11 +109,9 @@ module Squared
|
|
110
109
|
@session = nil
|
111
110
|
@index = -1
|
112
111
|
run_set(kwargs[:run], kwargs[:env], opts: kwargs.fetch(:opts, true))
|
113
|
-
exception_set kwargs[:exception]
|
114
|
-
pipe_set kwargs[:pipe]
|
115
|
-
verbose_set kwargs[:verbose]
|
116
112
|
graph_set kwargs[:graph]
|
117
113
|
pass_set kwargs[:pass]
|
114
|
+
only_set kwargs[:only]
|
118
115
|
exclude_set kwargs[:exclude]
|
119
116
|
archive_set kwargs[:archive]
|
120
117
|
theme_set common
|
@@ -176,9 +173,7 @@ module Squared
|
|
176
173
|
def initialize_events(ref, **)
|
177
174
|
return unless (events = @workspace.events_get(group: @group, ref: ref))
|
178
175
|
|
179
|
-
events.each
|
180
|
-
data.each { |ev, blk| (@events[ev] ||= {})[task] ||= [blk] }
|
181
|
-
end
|
176
|
+
events.each { |task, data| data.each { |ev, blk| @events[ev][task] ||= [blk] } }
|
182
177
|
end
|
183
178
|
|
184
179
|
def initialize_logger(log: nil, **)
|
@@ -218,7 +213,7 @@ module Squared
|
|
218
213
|
def initialize_env(dev: nil, prod: nil, **)
|
219
214
|
@dev = env_match('BUILD', dev, suffix: 'DEV', strict: true)
|
220
215
|
@prod = env_match('BUILD', prod, suffix: 'PROD', strict: true)
|
221
|
-
|
216
|
+
unless @output[2] == false || !(val = env('BUILD', suffix: 'ENV'))
|
222
217
|
@output[2] = parse_json(val, hint: "BUILD_#{@envname}_ENV") || @output[2]
|
223
218
|
end
|
224
219
|
unless @output[0] == false || @output[0].is_a?(Array)
|
@@ -284,6 +279,29 @@ module Squared
|
|
284
279
|
nil
|
285
280
|
end
|
286
281
|
|
282
|
+
def version=(val)
|
283
|
+
@version = val&.to_s
|
284
|
+
end
|
285
|
+
|
286
|
+
def exception=(val)
|
287
|
+
@exception = env_bool(val, workspace.exception, strict: true)
|
288
|
+
end
|
289
|
+
|
290
|
+
def pipe=(val)
|
291
|
+
@pipe = env_pipe(val, workspace.pipe, strict: true)
|
292
|
+
end
|
293
|
+
|
294
|
+
def verbose=(val)
|
295
|
+
@verbose = case val
|
296
|
+
when NilClass
|
297
|
+
workspace.verbose
|
298
|
+
when String
|
299
|
+
env_bool(val, workspace.verbose, strict: true, index: true)
|
300
|
+
else
|
301
|
+
val
|
302
|
+
end
|
303
|
+
end
|
304
|
+
|
287
305
|
def ref
|
288
306
|
Base.ref
|
289
307
|
end
|
@@ -294,7 +312,7 @@ module Squared
|
|
294
312
|
|
295
313
|
namespace name do
|
296
314
|
Base.subtasks do |action, flags|
|
297
|
-
next if
|
315
|
+
next if task_pass?(action)
|
298
316
|
|
299
317
|
namespace action do
|
300
318
|
flags.each do |flag|
|
@@ -500,11 +518,9 @@ module Squared
|
|
500
518
|
if proj.respond_to?(meth.to_sym)
|
501
519
|
begin
|
502
520
|
proj.__send__(meth, sync: sync)
|
503
|
-
rescue StandardError => e
|
504
|
-
ret = on :error, :prereqs, e
|
505
|
-
raise unless ret == true
|
506
|
-
else
|
507
521
|
next
|
522
|
+
rescue StandardError => e
|
523
|
+
on_error(:prereqs, e, exception: true)
|
508
524
|
end
|
509
525
|
end
|
510
526
|
warn log_message(Logger::WARN, name, 'method not found', subject: 'prereqs', hint: meth)
|
@@ -557,9 +573,7 @@ module Squared
|
|
557
573
|
begin
|
558
574
|
@clean.each { |cmd, opts| build(cmd.to_s, opts, sync: sync) }
|
559
575
|
rescue StandardError => e
|
560
|
-
|
561
|
-
ret = on :error, from, e
|
562
|
-
raise if exception && ret != true
|
576
|
+
on_error e, from
|
563
577
|
end
|
564
578
|
else
|
565
579
|
if @clean.is_a?(Enumerable) && !series?(@clean)
|
@@ -608,8 +622,7 @@ module Squared
|
|
608
622
|
end
|
609
623
|
ret = graph_branch(self, data, tasks, out, sync: sync, pass: pass)
|
610
624
|
rescue StandardError => e
|
611
|
-
|
612
|
-
raise unless ret == true
|
625
|
+
on_error(:graph, e, exception: true)
|
613
626
|
else
|
614
627
|
if out
|
615
628
|
[out, ret]
|
@@ -618,13 +631,13 @@ module Squared
|
|
618
631
|
end
|
619
632
|
end
|
620
633
|
|
621
|
-
def unpack(target, uri
|
622
|
-
|
634
|
+
def unpack(target, file = nil, uri: nil, sync: true, digest: nil, ext: nil, force: false, depth: 1, headers: {},
|
635
|
+
verbose: self.verbose, from: :unpack)
|
623
636
|
if !target.exist?
|
624
637
|
target.mkpath
|
625
638
|
elsif !target.directory?
|
626
639
|
raise_error('invalid location', hint: target)
|
627
|
-
elsif !target.empty?
|
640
|
+
elsif !file && !target.empty?
|
628
641
|
raise_error('directory not empty', hint: target) unless force || env('UNPACK_FORCE')
|
629
642
|
create = true
|
630
643
|
end
|
@@ -645,50 +658,59 @@ module Squared
|
|
645
658
|
when 128, 'sha512'
|
646
659
|
Digest::SHA512
|
647
660
|
else
|
648
|
-
raise_error
|
661
|
+
raise_error "invalid checksum: #{digest}"
|
649
662
|
end
|
650
663
|
end
|
651
664
|
if (val = env('HEADERS')) && (val = parse_json(val, hint: "HEADERS_#{@envname}"))
|
652
665
|
headers = headers.is_a?(Hash) ? headers.merge(val) : val
|
653
666
|
end
|
654
|
-
|
655
|
-
|
656
|
-
|
657
|
-
|
658
|
-
|
659
|
-
|
660
|
-
|
661
|
-
|
662
|
-
|
663
|
-
|
664
|
-
|
665
|
-
|
666
|
-
ext
|
667
|
-
|
668
|
-
|
669
|
-
|
670
|
-
|
667
|
+
if file
|
668
|
+
ext ||= File.extname(file)[1..-1]
|
669
|
+
else
|
670
|
+
require 'open-uri'
|
671
|
+
data = nil
|
672
|
+
(uri = Array(uri)).each_with_index do |url, index|
|
673
|
+
URI.open(url, headers) do |f|
|
674
|
+
data = f.read
|
675
|
+
if algo && algo.hexdigest(data) != digest
|
676
|
+
data = nil
|
677
|
+
raise_error("checksum failed: #{digest}", hint: url) if index == uri.size - 1
|
678
|
+
end
|
679
|
+
next if ext && index == 0
|
680
|
+
|
681
|
+
case f.content_type
|
682
|
+
when 'application/zip'
|
683
|
+
ext = 'zip'
|
684
|
+
when 'application/x-gzip'
|
685
|
+
ext = 'tgz'
|
686
|
+
when 'application/x-xz'
|
687
|
+
ext = 'txz'
|
688
|
+
end
|
671
689
|
end
|
690
|
+
break uri = url if data
|
691
|
+
end
|
692
|
+
unless data && (ext ||= URI.parse(uri).path[/\.(\w+)(?:\?|\z)/, 1])
|
693
|
+
raise_error("no content#{data ? ' type' : ''}", hint: uri)
|
672
694
|
end
|
673
|
-
break uri = url if data
|
674
|
-
end
|
675
|
-
unless data && (ext ||= URI.parse(uri).path[/\.(\w+)(?:\?|\z)/, 1])
|
676
|
-
raise_error("no content#{data ? ' type' : ''}", hint: uri)
|
677
695
|
end
|
678
696
|
ext = ext.downcase
|
679
697
|
if (val = env("#{%w[zip 7z gem].include?(ext) ? ext.upcase : 'TAR'}_DEPTH", ignore: false))
|
680
698
|
depth = val.to_i
|
681
699
|
end
|
682
700
|
begin
|
683
|
-
|
684
|
-
|
685
|
-
|
686
|
-
|
687
|
-
|
688
|
-
|
701
|
+
unless file
|
702
|
+
if ext == 'gem'
|
703
|
+
dir = Dir.mktmpdir
|
704
|
+
file = File.new(File.join(dir, File.basename(uri)), 'w')
|
705
|
+
else
|
706
|
+
require 'tempfile'
|
707
|
+
file = Tempfile.new("#{name}-")
|
708
|
+
end
|
709
|
+
file.write(data)
|
710
|
+
file.close
|
711
|
+
file = Pathname.new(file)
|
712
|
+
delete = true
|
689
713
|
end
|
690
|
-
file.write(data)
|
691
|
-
file.close
|
692
714
|
if create
|
693
715
|
warn log_message(Logger::WARN, 'force remove', subject: name, hint: target)
|
694
716
|
target.rmtree
|
@@ -696,7 +718,7 @@ module Squared
|
|
696
718
|
end
|
697
719
|
case ext
|
698
720
|
when 'zip', 'aar'
|
699
|
-
session 'unzip', shell_quote(file
|
721
|
+
session 'unzip', shell_quote(file), quote_option('d', target)
|
700
722
|
when 'tar', 'tgz', 'tar.gz', 'tar.xz', 'gz', 'xz'
|
701
723
|
flags = +(verbose ? 'v' : '')
|
702
724
|
if ext.end_with?('gz')
|
@@ -704,24 +726,24 @@ module Squared
|
|
704
726
|
elsif ext.end_with?('xz')
|
705
727
|
flags += 'J'
|
706
728
|
end
|
707
|
-
session 'tar', "-x#{flags}", basic_option('strip-components', depth), quote_option('f', file
|
729
|
+
session 'tar', "-x#{flags}", basic_option('strip-components', depth), quote_option('f', file),
|
708
730
|
quote_option('C', target)
|
709
731
|
depth = 0
|
710
732
|
when '7z'
|
711
|
-
session '7z', 'x', shell_quote(file
|
733
|
+
session '7z', 'x', shell_quote(file), "-o#{shell_quote(target)}"
|
712
734
|
when 'gem'
|
713
|
-
session 'gem', 'unpack', shell_quote(file
|
735
|
+
session 'gem', 'unpack', shell_quote(file), quote_option('target', target)
|
714
736
|
depth = 0 unless val
|
715
737
|
else
|
716
|
-
raise_error("unsupported format: #{ext}", hint: uri)
|
738
|
+
raise_error("unsupported format: #{ext}", hint: uri || file)
|
717
739
|
end
|
718
|
-
run(sync: sync, from: from)
|
740
|
+
run(sync: sync, banner: verbose, from: from)
|
719
741
|
while depth > 0 && target.children.size == 1
|
720
742
|
entry = target.children.first
|
721
743
|
break unless entry.directory?
|
722
744
|
|
723
745
|
i = 0
|
724
|
-
while (dest = target + "#{File.basename(file
|
746
|
+
while (dest = target + "#{File.basename(file)}-#{i}").exist?
|
725
747
|
i += 1
|
726
748
|
end
|
727
749
|
FileUtils.mv(entry, dest)
|
@@ -733,8 +755,8 @@ module Squared
|
|
733
755
|
ensure
|
734
756
|
if dir
|
735
757
|
remove_entry dir
|
736
|
-
|
737
|
-
file
|
758
|
+
elsif delete && file&.exist?
|
759
|
+
file.unlink
|
738
760
|
end
|
739
761
|
end
|
740
762
|
end
|
@@ -752,7 +774,7 @@ module Squared
|
|
752
774
|
end
|
753
775
|
|
754
776
|
def event(name, key, *args, override: false, **kwargs, &blk)
|
755
|
-
data = @events[name.to_sym]
|
777
|
+
data = @events[name.to_sym]
|
756
778
|
items = if override
|
757
779
|
data[key.to_sym] = []
|
758
780
|
else
|
@@ -806,6 +828,8 @@ module Squared
|
|
806
828
|
graph_set val
|
807
829
|
when :pass
|
808
830
|
pass_set val
|
831
|
+
when :only
|
832
|
+
only_set val
|
809
833
|
when :exclude
|
810
834
|
exclude_set val
|
811
835
|
when :parent
|
@@ -966,11 +990,11 @@ module Squared
|
|
966
990
|
puts_oe(*args, pipe: pipe)
|
967
991
|
end
|
968
992
|
|
969
|
-
def run(cmd = @session, var = nil, exception:
|
970
|
-
interactive: nil, **)
|
993
|
+
def run(cmd = @session, var = nil, exception: self.exception, sync: true, from: nil, banner: true, chdir: path,
|
994
|
+
interactive: nil, hint: nil, **)
|
971
995
|
unless cmd
|
972
|
-
|
973
|
-
return
|
996
|
+
warn log_message(Logger::WARN, 'no command given', subject: project, hint: from || 'unknown', pass: true)
|
997
|
+
return
|
974
998
|
end
|
975
999
|
i = interactive && !(@session && option('y'))
|
976
1000
|
cmd = cmd.target if cmd.is_a?(OptionPartition)
|
@@ -984,9 +1008,7 @@ module Squared
|
|
984
1008
|
else
|
985
1009
|
['Run', 'Y']
|
986
1010
|
end
|
987
|
-
unless confirm("#{title}? [#{sub_style(cmd, styles: theme[:inline])}]", y)
|
988
|
-
raise_error('user cancelled', hint: from)
|
989
|
-
end
|
1011
|
+
exit 1 unless confirm("#{title}? [#{sub_style(cmd, styles: theme[:inline])}]", y)
|
990
1012
|
end
|
991
1013
|
log&.info cmd
|
992
1014
|
on :first, from
|
@@ -995,7 +1017,7 @@ module Squared
|
|
995
1017
|
log&.warn "ENV discarded: #{var}" if var
|
996
1018
|
task_invoke(cmd, exception: exception, warning: warning?)
|
997
1019
|
else
|
998
|
-
print_item format_banner(cmd, banner: banner) if sync
|
1020
|
+
print_item format_banner(hint ? "#{cmd} (#{hint})" : cmd, banner: banner) if sync
|
999
1021
|
if var != false && (pre = runenv)
|
1000
1022
|
case pre
|
1001
1023
|
when Hash
|
@@ -1010,10 +1032,7 @@ module Squared
|
|
1010
1032
|
ret = shell(*args, chdir: chdir, exception: exception)
|
1011
1033
|
end
|
1012
1034
|
rescue StandardError => e
|
1013
|
-
|
1014
|
-
ret = on :error, from, e
|
1015
|
-
raise unless ret == true
|
1016
|
-
|
1035
|
+
on_error(from, e, exception: true)
|
1017
1036
|
false
|
1018
1037
|
else
|
1019
1038
|
on :last, from
|
@@ -1237,7 +1256,7 @@ module Squared
|
|
1237
1256
|
def session_done(cmd)
|
1238
1257
|
return cmd unless cmd.respond_to?(:done)
|
1239
1258
|
|
1240
|
-
raise_error('no args added', hint: cmd.first
|
1259
|
+
raise_error('no args added', hint: cmd.first) unless cmd.size > 1
|
1241
1260
|
@session = nil if cmd == @session
|
1242
1261
|
cmd.done
|
1243
1262
|
end
|
@@ -1269,6 +1288,10 @@ module Squared
|
|
1269
1288
|
puts 'Success'
|
1270
1289
|
end
|
1271
1290
|
|
1291
|
+
def print_error(err, loglevel: Logger::WARN, pass: false)
|
1292
|
+
warn log_message(loglevel, err, pass: pass) if warning?
|
1293
|
+
end
|
1294
|
+
|
1272
1295
|
def print_item(*val)
|
1273
1296
|
puts unless printfirst?
|
1274
1297
|
printsucc
|
@@ -1311,7 +1334,7 @@ module Squared
|
|
1311
1334
|
ret.join("\n")
|
1312
1335
|
end
|
1313
1336
|
|
1314
|
-
def print_status(*args, from: nil)
|
1337
|
+
def print_status(*args, from: nil, **kwargs)
|
1315
1338
|
return if stdin?
|
1316
1339
|
|
1317
1340
|
case from
|
@@ -1320,6 +1343,12 @@ module Squared
|
|
1320
1343
|
out[1] = sub_style(out[1], pat: /^( +major )(\d+)(.+)$/, styles: theme[:major], index: 2)
|
1321
1344
|
out[1] = sub_style(out[1], pat: /^(.+)(minor )(\d+)(.+)$/, styles: theme[:active], index: 3)
|
1322
1345
|
puts out
|
1346
|
+
when :completed
|
1347
|
+
if verbose && kwargs[:start]
|
1348
|
+
msg = sub_style('completed', styles: theme[:active])
|
1349
|
+
puts log_message(Logger::INFO, *args, msg, subject: kwargs[:subject],
|
1350
|
+
hint: time_format(epochtime - kwargs[:start]))
|
1351
|
+
end
|
1323
1352
|
end
|
1324
1353
|
end
|
1325
1354
|
|
@@ -1381,7 +1410,7 @@ module Squared
|
|
1381
1410
|
unless items.empty?
|
1382
1411
|
pad = items.size.to_s.size
|
1383
1412
|
items.each_with_index do |val, i|
|
1384
|
-
next unless
|
1413
|
+
next unless matchany?(val[0], reg)
|
1385
1414
|
|
1386
1415
|
out << ('%*d. %s' % [pad, i.succ, each ? each.call(val) : val[0]])
|
1387
1416
|
end
|
@@ -1484,11 +1513,11 @@ module Squared
|
|
1484
1513
|
list.flatten.each do |opt|
|
1485
1514
|
next unless (val = option(opt, **kwargs))
|
1486
1515
|
|
1487
|
-
return target <<
|
1488
|
-
|
1489
|
-
|
1490
|
-
|
1491
|
-
|
1516
|
+
return target << if flag
|
1517
|
+
shell_option(opt, equals ? val : nil, quote: quote, escape: escape, force: force)
|
1518
|
+
else
|
1519
|
+
shell_quote val
|
1520
|
+
end
|
1492
1521
|
end
|
1493
1522
|
nil
|
1494
1523
|
end
|
@@ -1604,13 +1633,9 @@ module Squared
|
|
1604
1633
|
multiple: false, force: true, **kwargs)
|
1605
1634
|
puts if !series && !printfirst?
|
1606
1635
|
msg = "#{msg} (optional)" unless force
|
1607
|
-
unless (ret = choice(msg, list, multiple: multiple, force: force, **kwargs))
|
1608
|
-
|
1609
|
-
|
1610
|
-
if ret.nil? || ret.empty?
|
1611
|
-
return unless force
|
1612
|
-
|
1613
|
-
exit 1
|
1636
|
+
unless (ret = choice(msg, list, multiple: multiple, force: force, **kwargs)) && !ret.empty?
|
1637
|
+
exit 1 if force
|
1638
|
+
return
|
1614
1639
|
end
|
1615
1640
|
ret = multiple ? ret.map! { |val| val.sub(trim, '') } : ret.sub(trim, '') if trim
|
1616
1641
|
if column
|
@@ -1655,8 +1680,8 @@ module Squared
|
|
1655
1680
|
ret
|
1656
1681
|
end
|
1657
1682
|
|
1658
|
-
def command_args(args, force: false, **kwargs)
|
1659
|
-
return
|
1683
|
+
def command_args(args, min: 0, force: false, **kwargs)
|
1684
|
+
return if args.size > min || option('i', 'interactive', **kwargs, equals: '0')
|
1660
1685
|
|
1661
1686
|
readline('Enter arguments', force: force)
|
1662
1687
|
end
|
@@ -1701,6 +1726,17 @@ module Squared
|
|
1701
1726
|
files.map { |val| val == '.' ? '.' : shell_quote(path + val) }
|
1702
1727
|
end
|
1703
1728
|
|
1729
|
+
def matchmap(list, prefix = nil)
|
1730
|
+
list.map do |val|
|
1731
|
+
if val.is_a?(Regexp)
|
1732
|
+
val
|
1733
|
+
else
|
1734
|
+
val = ".*#{val}" if prefix && !val.sub!(/\A(\^|\\A)/, '')
|
1735
|
+
Regexp.new("#{prefix}#{val == '*' ? '.+' : val}")
|
1736
|
+
end
|
1737
|
+
end
|
1738
|
+
end
|
1739
|
+
|
1704
1740
|
def semver(val)
|
1705
1741
|
return val if val[3]
|
1706
1742
|
|
@@ -1717,6 +1753,26 @@ module Squared
|
|
1717
1753
|
val.scan(SEM_VER).first.yield_self { |data| fill ? semver(data) : data }
|
1718
1754
|
end
|
1719
1755
|
|
1756
|
+
def semcmp(val, other)
|
1757
|
+
return 0 if val == other
|
1758
|
+
|
1759
|
+
a, b = [val, other].map! { |ver| ver.scan(SEM_VER) }
|
1760
|
+
return -1 if b.empty?
|
1761
|
+
return 1 if a.empty?
|
1762
|
+
|
1763
|
+
a, b = [a.first, b.first].map! { |c| [c[0], c[2], c[4] || '0', c[5] ? '-1' : '0'] }
|
1764
|
+
a.each_with_index do |c, index|
|
1765
|
+
next if c == (d = b[index])
|
1766
|
+
|
1767
|
+
return c.to_i < d.to_i ? 1 : -1
|
1768
|
+
end
|
1769
|
+
0
|
1770
|
+
end
|
1771
|
+
|
1772
|
+
def semgte?(val, other)
|
1773
|
+
semcmp(val, other) != 1
|
1774
|
+
end
|
1775
|
+
|
1720
1776
|
def indexitem(val)
|
1721
1777
|
[$1.to_i, $2 && $2[1..-1]] if val =~ /\A[=^#{indexchar}](\d+)(:.+)?\z/
|
1722
1778
|
end
|
@@ -1758,9 +1814,9 @@ module Squared
|
|
1758
1814
|
end
|
1759
1815
|
|
1760
1816
|
def on(event, from, *args, **kwargs)
|
1761
|
-
return unless from &&
|
1817
|
+
return unless from && @events.key?(event)
|
1762
1818
|
|
1763
|
-
|
1819
|
+
Array(@events[event][from]).each do |obj|
|
1764
1820
|
target, opts = if obj.is_a?(Array) && obj[1].is_a?(Hash)
|
1765
1821
|
[obj[0], kwargs.empty? ? obj[1] : obj[1].merge(kwargs)]
|
1766
1822
|
else
|
@@ -1777,27 +1833,31 @@ module Squared
|
|
1777
1833
|
end
|
1778
1834
|
end
|
1779
1835
|
|
1780
|
-
def
|
1781
|
-
|
1782
|
-
|
1783
|
-
|
1784
|
-
ret
|
1785
|
-
else
|
1786
|
-
Dir.chdir(path)
|
1787
|
-
ret = yield
|
1788
|
-
Dir.chdir(pwd)
|
1836
|
+
def on_error(err, from, exception: self.exception, pass: false, dryrun: false)
|
1837
|
+
log&.error err
|
1838
|
+
unless dryrun
|
1839
|
+
ret = on :error, from, err
|
1840
|
+
raise err if exception && ret != true
|
1789
1841
|
end
|
1842
|
+
print_error(err, pass: pass) unless ret
|
1843
|
+
end
|
1844
|
+
|
1845
|
+
def pwd_set(pass: false, dryrun: false, from: nil)
|
1846
|
+
pwd = Dir.pwd
|
1847
|
+
return yield if (path.to_s == pwd || pass == true) && (workspace.mri? || !workspace.windows?)
|
1848
|
+
|
1849
|
+
Dir.chdir path
|
1850
|
+
ret = yield
|
1851
|
+
Dir.chdir pwd
|
1790
1852
|
rescue StandardError => e
|
1791
|
-
|
1792
|
-
ret = on :error, from, e
|
1793
|
-
raise if exception && ret != true
|
1853
|
+
on_error(e, from, dryrun: dryrun)
|
1794
1854
|
else
|
1795
1855
|
ret
|
1796
1856
|
end
|
1797
1857
|
|
1798
1858
|
def run_set(cmd, val = nil, opts: nil, **)
|
1799
|
-
|
1800
|
-
|
1859
|
+
noopt = @output[1] == false && !@output[0].nil?
|
1860
|
+
noenv = @output[2] == false
|
1801
1861
|
parse = lambda do |data|
|
1802
1862
|
ret = []
|
1803
1863
|
if data[:command]
|
@@ -1817,8 +1877,8 @@ module Squared
|
|
1817
1877
|
case cmd
|
1818
1878
|
when Array
|
1819
1879
|
@output = if cmd.all? { |data| data.is_a?(Hash) }
|
1820
|
-
|
1821
|
-
|
1880
|
+
noopt = false
|
1881
|
+
noenv = false
|
1822
1882
|
cmd.map { |data| parse.call(data) }
|
1823
1883
|
else
|
1824
1884
|
cmd.dup
|
@@ -1829,14 +1889,14 @@ module Squared
|
|
1829
1889
|
else
|
1830
1890
|
@output[0] = cmd
|
1831
1891
|
end
|
1832
|
-
unless
|
1892
|
+
unless noopt
|
1833
1893
|
if opts == false
|
1834
1894
|
@output[1] = false
|
1835
1895
|
elsif opts && opts != true
|
1836
1896
|
@output[1] = opts
|
1837
1897
|
end
|
1838
1898
|
end
|
1839
|
-
return if
|
1899
|
+
return if noenv
|
1840
1900
|
|
1841
1901
|
if val.is_a?(Hash)
|
1842
1902
|
@output[2] = val
|
@@ -1865,25 +1925,6 @@ module Squared
|
|
1865
1925
|
@parent = val if val.is_a?(Project::Base)
|
1866
1926
|
end
|
1867
1927
|
|
1868
|
-
def exception_set(val)
|
1869
|
-
@exception = env_bool(val, workspace.exception, strict: true)
|
1870
|
-
end
|
1871
|
-
|
1872
|
-
def pipe_set(val)
|
1873
|
-
@pipe = env_pipe(val, workspace.pipe, strict: true)
|
1874
|
-
end
|
1875
|
-
|
1876
|
-
def verbose_set(val)
|
1877
|
-
@verbose = case val
|
1878
|
-
when NilClass
|
1879
|
-
workspace.verbose
|
1880
|
-
when String
|
1881
|
-
env_bool(val, workspace.verbose, strict: true, index: true)
|
1882
|
-
else
|
1883
|
-
val
|
1884
|
-
end
|
1885
|
-
end
|
1886
|
-
|
1887
1928
|
def graph_set(val)
|
1888
1929
|
@graph = if val
|
1889
1930
|
Array(val).map { |s| workspace.prefix ? workspace.task_name(s).to_sym : s.to_sym }.freeze
|
@@ -1891,7 +1932,11 @@ module Squared
|
|
1891
1932
|
end
|
1892
1933
|
|
1893
1934
|
def pass_set(val)
|
1894
|
-
@pass = (val
|
1935
|
+
@pass = Array(val).freeze
|
1936
|
+
end
|
1937
|
+
|
1938
|
+
def only_set(val)
|
1939
|
+
@only = val && as_a(val, :to_s).freeze
|
1895
1940
|
end
|
1896
1941
|
|
1897
1942
|
def exclude_set(val)
|
@@ -1950,6 +1995,14 @@ module Squared
|
|
1950
1995
|
end
|
1951
1996
|
end
|
1952
1997
|
|
1998
|
+
def task_pass?(key)
|
1999
|
+
@only ? !@only.include?(key) : @pass.include?(key)
|
2000
|
+
end
|
2001
|
+
|
2002
|
+
def matchany?(val, list, empty: true)
|
2003
|
+
list.empty? ? empty : list.any? { |pat| val.match?(pat) }
|
2004
|
+
end
|
2005
|
+
|
1953
2006
|
def projectpath?(val)
|
1954
2007
|
Pathname.new(val).cleanpath.yield_self do |file|
|
1955
2008
|
file.absolute? ? file.to_s.start_with?(File.join(path, '')) : !file.to_s.start_with?(File.join('..', ''))
|
@@ -2051,6 +2104,14 @@ module Squared
|
|
2051
2104
|
BLK_SET
|
2052
2105
|
end
|
2053
2106
|
|
2107
|
+
def hashobj
|
2108
|
+
Workspace::Support.hashobj
|
2109
|
+
end
|
2110
|
+
|
2111
|
+
def hashlist
|
2112
|
+
Workspace::Support.hashlist
|
2113
|
+
end
|
2114
|
+
|
2054
2115
|
def borderstyle
|
2055
2116
|
workspace.banner_get(*@ref, group: group)&.border || theme[:border]
|
2056
2117
|
end
|