squared 0.4.15 → 0.4.17

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.
@@ -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+)?)?\b/.freeze
25
- URI_SCHEME = %r{^([a-z][a-z\d+-.]*)://[^@:\[\]\\^<>|\s]}i.freeze
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, :exception, :pipe, :verbose,
77
- :group, :parent, :dependfile
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,27 +89,24 @@ 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
105
104
  @global = false
106
105
  @index = -1
107
106
  run_set(kwargs[:run], kwargs[:env], opts: kwargs.fetch(:opts, true))
108
- exception_set kwargs[:exception]
109
- pipe_set kwargs[:pipe]
110
- verbose_set kwargs[:verbose]
111
107
  graph_set kwargs[:graph]
112
108
  pass_set kwargs[:pass]
109
+ only_set kwargs[:only]
113
110
  exclude_set kwargs[:exclude]
114
111
  archive_set kwargs[:archive]
115
112
  theme_set common
@@ -171,9 +168,7 @@ module Squared
171
168
  def initialize_events(ref, **)
172
169
  return unless (events = @workspace.events_get(group: @group, ref: ref))
173
170
 
174
- events.each do |task, data|
175
- data.each { |ev, blk| (@events[ev] ||= {})[task] ||= [blk] }
176
- end
171
+ events.each { |task, data| data.each { |ev, blk| @events[ev][task] ||= [blk] } }
177
172
  end
178
173
 
179
174
  def initialize_logger(log: nil, **)
@@ -213,7 +208,7 @@ module Squared
213
208
  def initialize_env(dev: nil, prod: nil, **)
214
209
  @dev = env_match('BUILD', dev, suffix: 'DEV', strict: true)
215
210
  @prod = env_match('BUILD', prod, suffix: 'PROD', strict: true)
216
- if @output[2] != false && (val = env('BUILD', suffix: 'ENV'))
211
+ unless @output[2] == false || !(val = env('BUILD', suffix: 'ENV'))
217
212
  @output[2] = parse_json(val, hint: "BUILD_#{@envname}_ENV") || @output[2]
218
213
  end
219
214
  unless @output[0] == false || @output[0].is_a?(Array)
@@ -279,6 +274,29 @@ module Squared
279
274
  nil
280
275
  end
281
276
 
277
+ def version=(val)
278
+ @version = val&.to_s
279
+ end
280
+
281
+ def exception=(val)
282
+ @exception = env_bool(val, workspace.exception, strict: true)
283
+ end
284
+
285
+ def pipe=(val)
286
+ @pipe = env_pipe(val, workspace.pipe, strict: true)
287
+ end
288
+
289
+ def verbose=(val)
290
+ @verbose = case val
291
+ when NilClass
292
+ workspace.verbose
293
+ when String
294
+ env_bool(val, workspace.verbose, strict: true, index: true)
295
+ else
296
+ val
297
+ end
298
+ end
299
+
282
300
  def ref
283
301
  Base.ref
284
302
  end
@@ -289,7 +307,7 @@ module Squared
289
307
 
290
308
  namespace name do
291
309
  Base.subtasks do |action, flags|
292
- next if @pass.include?(action)
310
+ next if task_pass?(action)
293
311
 
294
312
  namespace action do
295
313
  flags.each do |flag|
@@ -504,11 +522,9 @@ module Squared
504
522
  if proj.respond_to?(meth.to_sym)
505
523
  begin
506
524
  proj.__send__(meth, sync: sync)
507
- rescue StandardError => e
508
- ret = on(:error, :prereqs, e)
509
- raise unless ret == true
510
- else
511
525
  next
526
+ rescue StandardError => e
527
+ on_error(:prereqs, e, exception: true)
512
528
  end
513
529
  end
514
530
  warn log_message(Logger::WARN, name, 'method not found', subject: 'prereqs', hint: meth)
@@ -561,9 +577,7 @@ module Squared
561
577
  begin
562
578
  @clean.each { |cmd, opts| build(cmd.to_s, opts, sync: sync) }
563
579
  rescue StandardError => e
564
- log&.error e
565
- ret = on(:error, from, e)
566
- raise if exception && ret != true
580
+ on_error e, from
567
581
  end
568
582
  else
569
583
  if @clean.is_a?(Enumerable) && !series?(@clean)
@@ -612,8 +626,7 @@ module Squared
612
626
  end
613
627
  ret = graph_branch(self, data, tasks, out, sync: sync, pass: pass)
614
628
  rescue StandardError => e
615
- ret = on(:error, :graph, e)
616
- raise unless ret == true
629
+ on_error(:graph, e, exception: true)
617
630
  else
618
631
  if out
619
632
  [out, ret]
@@ -622,12 +635,13 @@ module Squared
622
635
  end
623
636
  end
624
637
 
625
- def unpack(target, uri:, sync: true, digest: nil, ext: nil, force: false, depth: 1, headers: {}, from: :unpack)
638
+ def unpack(target, file = nil, uri: nil, sync: true, digest: nil, ext: nil, force: false, depth: 1, headers: {},
639
+ verbose: self.verbose, from: :unpack)
626
640
  if !target.exist?
627
641
  target.mkpath
628
642
  elsif !target.directory?
629
643
  raise_error('invalid location', hint: target)
630
- elsif !target.empty?
644
+ elsif !file && !target.empty?
631
645
  raise_error('directory not empty', hint: target) unless force || env('UNPACK_FORCE')
632
646
  create = true
633
647
  end
@@ -648,50 +662,58 @@ module Squared
648
662
  when 128, 'sha512'
649
663
  Digest::SHA512
650
664
  else
651
- raise_error("invalid checksum: #{digest}", hint: name)
665
+ raise_error "invalid checksum: #{digest}"
652
666
  end
653
667
  end
654
668
  if (val = env('HEADERS')) && (val = parse_json(val, hint: "HEADERS_#{@envname}"))
655
669
  headers = headers.is_a?(Hash) ? headers.merge(val) : val
656
670
  end
657
- data = nil
658
- (uri = Array(uri)).each_with_index do |url, index|
659
- fetch_uri(url, headers) do |f|
660
- data = f.read
661
- if algo && algo.hexdigest(data) != digest
662
- data = nil
663
- raise_error("checksum failed: #{digest}", hint: url) if index == uri.size - 1
664
- end
665
- next if ext && index == 0
666
-
667
- case f.content_type
668
- when 'application/zip'
669
- ext = 'zip'
670
- when 'application/x-gzip'
671
- ext = 'tgz'
672
- when 'application/x-xz'
673
- ext = 'txz'
671
+ if file
672
+ ext ||= File.extname(file)[1..-1]
673
+ else
674
+ data = nil
675
+ (uri = Array(uri)).each_with_index do |url, index|
676
+ fetch_uri(url, headers) do |f|
677
+ data = f.read
678
+ if algo && algo.hexdigest(data) != digest
679
+ data = nil
680
+ raise_error("checksum failed: #{digest}", hint: url) if index == uri.size - 1
681
+ end
682
+ next if ext && index == 0
683
+
684
+ case f.content_type
685
+ when 'application/zip'
686
+ ext = 'zip'
687
+ when 'application/x-gzip'
688
+ ext = 'tgz'
689
+ when 'application/x-xz'
690
+ ext = 'txz'
691
+ end
674
692
  end
693
+ break uri = url if data
694
+ end
695
+ unless data && (ext ||= URI.parse(uri).path[/\.(\w+)(?:\?|\z)/, 1])
696
+ raise_error("no content#{data ? ' type' : ''}", hint: uri)
675
697
  end
676
- break uri = url if data
677
- end
678
- unless data && (ext ||= URI.parse(uri).path[/\.(\w+)(?:\?|\z)/, 1])
679
- raise_error("no content#{data ? ' type' : ''}", hint: uri)
680
698
  end
681
699
  ext = ext.downcase
682
700
  if (val = env("#{%w[zip 7z gem].include?(ext) ? ext.upcase : 'TAR'}_DEPTH", ignore: false))
683
701
  depth = val.to_i
684
702
  end
685
703
  begin
686
- if ext == 'gem'
687
- dir = Dir.mktmpdir
688
- file = File.new(File.join(dir, File.basename(uri)), 'w')
689
- else
690
- require 'tempfile'
691
- file = Tempfile.new("#{name}-")
704
+ unless file
705
+ if ext == 'gem'
706
+ dir = Dir.mktmpdir
707
+ file = File.new(File.join(dir, File.basename(uri)), 'w')
708
+ else
709
+ require 'tempfile'
710
+ file = Tempfile.new("#{name}-")
711
+ end
712
+ file.write(data)
713
+ file.close
714
+ file = Pathname.new(file)
715
+ delete = true
692
716
  end
693
- file.write(data)
694
- file.close
695
717
  if create
696
718
  warn log_message(Logger::WARN, 'force remove', subject: name, hint: target)
697
719
  target.rmtree
@@ -699,7 +721,7 @@ module Squared
699
721
  end
700
722
  case ext
701
723
  when 'zip', 'aar'
702
- session 'unzip', shell_quote(file.path), quote_option('d', target)
724
+ session 'unzip', shell_quote(file), quote_option('d', target)
703
725
  when 'tar', 'tgz', 'tar.gz', 'tar.xz', 'gz', 'xz'
704
726
  flags = +(verbose ? 'v' : '')
705
727
  if ext.end_with?('gz')
@@ -707,24 +729,24 @@ module Squared
707
729
  elsif ext.end_with?('xz')
708
730
  flags += 'J'
709
731
  end
710
- session 'tar', "-x#{flags}", basic_option('strip-components', depth), quote_option('f', file.path),
732
+ session 'tar', "-x#{flags}", basic_option('strip-components', depth), quote_option('f', file),
711
733
  quote_option('C', target)
712
734
  depth = 0
713
735
  when '7z'
714
- session '7z', 'x', shell_quote(file.path), "-o#{shell_quote(target)}"
736
+ session '7z', 'x', shell_quote(file), "-o#{shell_quote(target)}"
715
737
  when 'gem'
716
- session 'gem', 'unpack', shell_quote(file.path), quote_option('target', target)
738
+ session 'gem', 'unpack', shell_quote(file), quote_option('target', target)
717
739
  depth = 0 unless val
718
740
  else
719
- raise_error("unsupported format: #{ext}", hint: uri)
741
+ raise_error("unsupported format: #{ext}", hint: uri || file)
720
742
  end
721
- run(sync: sync, from: from)
743
+ run(sync: sync, banner: verbose, from: from)
722
744
  while depth > 0 && target.children.size == 1
723
745
  entry = target.children.first
724
746
  break unless entry.directory?
725
747
 
726
748
  i = 0
727
- while (dest = target + "#{File.basename(file.path)}-#{i}").exist?
749
+ while (dest = target + "#{File.basename(file)}-#{i}").exist?
728
750
  i += 1
729
751
  end
730
752
  FileUtils.mv(entry, dest)
@@ -736,8 +758,8 @@ module Squared
736
758
  ensure
737
759
  if dir
738
760
  remove_entry dir
739
- else
740
- file&.unlink
761
+ elsif delete && file&.exist?
762
+ file.unlink
741
763
  end
742
764
  end
743
765
  end
@@ -755,7 +777,7 @@ module Squared
755
777
  end
756
778
 
757
779
  def event(name, key, *args, override: false, **kwargs, &blk)
758
- data = @events[name.to_sym] ||= {}
780
+ data = @events[name.to_sym]
759
781
  items = if override
760
782
  data[key.to_sym] = []
761
783
  else
@@ -802,6 +824,8 @@ module Squared
802
824
  graph_set val
803
825
  when :pass
804
826
  pass_set val
827
+ when :only
828
+ only_set val
805
829
  when :exclude
806
830
  exclude_set val
807
831
  when :parent
@@ -969,11 +993,11 @@ module Squared
969
993
  puts_oe(*args, pipe: pipe)
970
994
  end
971
995
 
972
- def run(cmd = @session, var = nil, exception: @exception, sync: true, from: nil, banner: true, chdir: path,
973
- interactive: nil, **)
996
+ def run(cmd = @session, var = nil, exception: self.exception, sync: true, from: nil, banner: true, chdir: path,
997
+ interactive: nil, hint: nil, **)
974
998
  unless cmd
975
- from = from&.to_s || 'unknown'
976
- return warn log_message(Logger::WARN, 'no command given', subject: project, hint: from, pass: true)
999
+ warn log_message(Logger::WARN, 'no command given', subject: project, hint: from || 'unknown', pass: true)
1000
+ return
977
1001
  end
978
1002
  i = interactive && !(@session && option('y'))
979
1003
  cmd = cmd.target if cmd.is_a?(OptionPartition)
@@ -988,7 +1012,7 @@ module Squared
988
1012
  ['Run', 'Y']
989
1013
  end
990
1014
  unless confirm("#{title}? [#{sub_style(cmd, styles: theme[:inline])}] #{y == 'Y' ? '[Y/n]' : '[y/N]'} ", y)
991
- raise_error('user cancelled', hint: from)
1015
+ exit 1
992
1016
  end
993
1017
  end
994
1018
  log&.info cmd
@@ -998,7 +1022,7 @@ module Squared
998
1022
  log&.warn "ENV discarded: #{var}" if var
999
1023
  task_invoke(cmd, exception: exception, warning: warning?)
1000
1024
  else
1001
- print_item format_banner(cmd, banner: banner) if sync
1025
+ print_item format_banner(hint ? "#{cmd} (#{hint})" : cmd, banner: banner) if sync
1002
1026
  if var != false && (pre = runenv)
1003
1027
  case pre
1004
1028
  when Hash
@@ -1013,10 +1037,7 @@ module Squared
1013
1037
  ret = shell(*args, chdir: chdir, exception: exception)
1014
1038
  end
1015
1039
  rescue StandardError => e
1016
- log&.error e
1017
- ret = on(:error, from, e)
1018
- raise unless ret == true
1019
-
1040
+ on_error(from, e, exception: true)
1020
1041
  false
1021
1042
  else
1022
1043
  on :last, from
@@ -1029,7 +1050,7 @@ module Squared
1029
1050
  begin
1030
1051
  cmd.flatten.each { |val| run(val, env, sync: sync, banner: banner, **kwargs) }
1031
1052
  rescue StandardError => e
1032
- ret = on(:error, from, e)
1053
+ ret = on :error, from, e
1033
1054
  raise unless ret == true
1034
1055
  end
1035
1056
  on :last, from
@@ -1240,7 +1261,7 @@ module Squared
1240
1261
  def session_done(cmd)
1241
1262
  return cmd unless cmd.respond_to?(:done)
1242
1263
 
1243
- raise_error('no args added', hint: cmd.first || name) unless cmd.size > 1
1264
+ raise_error('no args added', hint: cmd.first) unless cmd.size > 1
1244
1265
  @session = nil if cmd == @session
1245
1266
  cmd.done
1246
1267
  end
@@ -1276,6 +1297,10 @@ module Squared
1276
1297
  puts 'Success'
1277
1298
  end
1278
1299
 
1300
+ def print_error(err, loglevel: Logger::WARN, pass: false)
1301
+ warn log_message(loglevel, err, pass: pass) if warning?
1302
+ end
1303
+
1279
1304
  def print_item(*val)
1280
1305
  puts unless printfirst?
1281
1306
  printsucc
@@ -1318,7 +1343,7 @@ module Squared
1318
1343
  ret.join("\n")
1319
1344
  end
1320
1345
 
1321
- def print_status(*args, from: nil)
1346
+ def print_status(*args, from: nil, **kwargs)
1322
1347
  return if stdin?
1323
1348
 
1324
1349
  case from
@@ -1327,6 +1352,12 @@ module Squared
1327
1352
  out[1] = sub_style(out[1], pat: /^( +major )(\d+)(.+)$/, styles: theme[:major], index: 2)
1328
1353
  out[1] = sub_style(out[1], pat: /^(.+)(minor )(\d+)(.+)$/, styles: theme[:active], index: 3)
1329
1354
  puts out
1355
+ when :completed
1356
+ if verbose && kwargs[:start]
1357
+ msg = sub_style('completed', styles: theme[:active])
1358
+ puts log_message(Logger::INFO, *args, msg, subject: kwargs[:subject],
1359
+ hint: time_format(epochtime - kwargs[:start]))
1360
+ end
1330
1361
  end
1331
1362
  end
1332
1363
 
@@ -1389,7 +1420,7 @@ module Squared
1389
1420
  unless items.empty?
1390
1421
  pad = items.size.to_s.size
1391
1422
  items.each_with_index do |val, i|
1392
- next unless reg.empty? || reg.any? { |pat| val[0].match?(pat) }
1423
+ next unless matchany?(val[0], reg)
1393
1424
 
1394
1425
  out << "#{i.succ.to_s.rjust(pad)}. #{each ? each.call(val) : val[0]}"
1395
1426
  end
@@ -1619,13 +1650,9 @@ module Squared
1619
1650
  multiple: false, force: true, **kwargs)
1620
1651
  puts if !series && !printfirst?
1621
1652
  msg = "#{msg} (optional)" unless force
1622
- unless (ret = choice(msg, list, multiple: multiple, force: force, **kwargs)) || !force
1623
- raise_error 'user cancelled'
1624
- end
1625
- if ret.nil? || ret.empty?
1626
- return unless force
1627
-
1628
- exit 1
1653
+ unless (ret = choice(msg, list, multiple: multiple, force: force, **kwargs)) && !ret.empty?
1654
+ exit 1 if force
1655
+ return
1629
1656
  end
1630
1657
  ret = multiple ? ret.map! { |val| val.sub(trim, '') } : ret.sub(trim, '') if trim
1631
1658
  if column
@@ -1671,8 +1698,8 @@ module Squared
1671
1698
  ret
1672
1699
  end
1673
1700
 
1674
- def command_args(args, force: false, **kwargs)
1675
- return unless args.size == 1 && !option('i', 'interactive', **kwargs, equals: '0')
1701
+ def command_args(args, min: 0, force: false, **kwargs)
1702
+ return if args.size > min || option('i', 'interactive', **kwargs, equals: '0')
1676
1703
 
1677
1704
  readline('Enter arguments', force: force)
1678
1705
  end
@@ -1717,6 +1744,17 @@ module Squared
1717
1744
  files.map { |val| val == '.' ? '.' : shell_quote(path + val) }
1718
1745
  end
1719
1746
 
1747
+ def matchmap(list, prefix = nil)
1748
+ list.map do |val|
1749
+ if val.is_a?(Regexp)
1750
+ val
1751
+ else
1752
+ val = ".*#{val}" if prefix && !val.sub!(/\A(\^|\\A)/, '')
1753
+ Regexp.new("#{prefix}#{val == '*' ? '.+' : val}")
1754
+ end
1755
+ end
1756
+ end
1757
+
1720
1758
  def semver(val)
1721
1759
  return val if val[3]
1722
1760
 
@@ -1734,6 +1772,26 @@ module Squared
1734
1772
  fill ? semver(ret) : ret
1735
1773
  end
1736
1774
 
1775
+ def semcmp(val, other)
1776
+ return 0 if val == other
1777
+
1778
+ a, b = [val, other].map! { |ver| ver.scan(SEM_VER) }
1779
+ return -1 if b.empty?
1780
+ return 1 if a.empty?
1781
+
1782
+ a, b = [a.first, b.first].map! { |c| [c[0], c[2], c[4] || '0', c[5] ? '-1' : '0'] }
1783
+ a.each_with_index do |c, index|
1784
+ next if c == (d = b[index])
1785
+
1786
+ return c.to_i < d.to_i ? 1 : -1
1787
+ end
1788
+ 0
1789
+ end
1790
+
1791
+ def semgte?(val, other)
1792
+ semcmp(val, other) != 1
1793
+ end
1794
+
1737
1795
  def indexitem(val)
1738
1796
  [$1.to_i, $2 && $2[1..-1]] if val =~ /\A[=^#{indexchar}](\d+)(:.+)?\z/
1739
1797
  end
@@ -1775,9 +1833,9 @@ module Squared
1775
1833
  end
1776
1834
 
1777
1835
  def on(event, from, *args, **kwargs)
1778
- return unless from && (data = @events[event])
1836
+ return unless from && @events.key?(event)
1779
1837
 
1780
- data[from]&.each do |obj|
1838
+ Array(@events[event][from]).each do |obj|
1781
1839
  target, opts = if obj.is_a?(Array) && obj[1].is_a?(Hash)
1782
1840
  [obj[0], kwargs.empty? ? obj[1] : obj[1].merge(kwargs)]
1783
1841
  else
@@ -1794,24 +1852,28 @@ module Squared
1794
1852
  end
1795
1853
  end
1796
1854
 
1855
+ def on_error(err, from, exception: self.exception, pass: false, dryrun: false)
1856
+ log&.error err
1857
+ unless dryrun
1858
+ ret = on :error, from, err
1859
+ raise err if exception && ret != true
1860
+ end
1861
+ print_error(err, pass: pass) unless ret
1862
+ end
1863
+
1797
1864
  def pwd_set(done = nil, pass: false, from: nil, dryrun: false)
1798
1865
  pwd = Pathname.pwd
1799
1866
  if block_given?
1800
1867
  begin
1801
- pass = semscan(pass).join <= RUBY_VERSION if pass.is_a?(String)
1802
- if (path == pwd || pass == true) && !workspace.jruby_win?
1868
+ if (path == pwd || pass == true) && (workspace.mri? || !workspace.windows?)
1803
1869
  ret = yield
1804
1870
  else
1805
- Dir.chdir(path)
1871
+ Dir.chdir path
1806
1872
  ret = yield
1807
- Dir.chdir(pwd)
1873
+ Dir.chdir pwd
1808
1874
  end
1809
1875
  rescue StandardError => e
1810
- log&.error e
1811
- unless dryrun
1812
- ret = on(:error, from, e)
1813
- raise if exception && ret != true
1814
- end
1876
+ on_error(e, from, dryrun: dryrun)
1815
1877
  else
1816
1878
  ret
1817
1879
  end
@@ -1831,8 +1893,8 @@ module Squared
1831
1893
  end
1832
1894
 
1833
1895
  def run_set(cmd, val = nil, opts: nil, **)
1834
- diso = @output[1] == false && !@output[0].nil?
1835
- dise = @output[2] == false
1896
+ noopt = @output[1] == false && !@output[0].nil?
1897
+ noenv = @output[2] == false
1836
1898
  parse = lambda do |data|
1837
1899
  ret = []
1838
1900
  if data[:command]
@@ -1852,8 +1914,8 @@ module Squared
1852
1914
  case cmd
1853
1915
  when Array
1854
1916
  @output = if cmd.all? { |data| data.is_a?(Hash) }
1855
- diso = false
1856
- dise = false
1917
+ noopt = false
1918
+ noenv = false
1857
1919
  cmd.map { |data| parse.call(data) }
1858
1920
  else
1859
1921
  cmd.dup
@@ -1864,14 +1926,14 @@ module Squared
1864
1926
  else
1865
1927
  @output[0] = cmd
1866
1928
  end
1867
- unless diso
1929
+ unless noopt
1868
1930
  if opts == false
1869
1931
  @output[1] = false
1870
1932
  elsif opts && opts != true
1871
1933
  @output[1] = opts
1872
1934
  end
1873
1935
  end
1874
- return if dise
1936
+ return if noenv
1875
1937
 
1876
1938
  if val.is_a?(Hash)
1877
1939
  @output[2] = val
@@ -1900,25 +1962,6 @@ module Squared
1900
1962
  @parent = val if val.is_a?(Project::Base)
1901
1963
  end
1902
1964
 
1903
- def exception_set(val)
1904
- @exception = env_bool(val, workspace.exception, strict: true)
1905
- end
1906
-
1907
- def pipe_set(val)
1908
- @pipe = env_pipe(val, workspace.pipe, strict: true)
1909
- end
1910
-
1911
- def verbose_set(val)
1912
- @verbose = case val
1913
- when NilClass
1914
- workspace.verbose
1915
- when String
1916
- env_bool(val, workspace.verbose, strict: true, index: true)
1917
- else
1918
- val
1919
- end
1920
- end
1921
-
1922
1965
  def graph_set(val)
1923
1966
  @graph = if val
1924
1967
  Array(val).map { |s| workspace.prefix ? workspace.task_name(s).to_sym : s.to_sym }.freeze
@@ -1926,7 +1969,11 @@ module Squared
1926
1969
  end
1927
1970
 
1928
1971
  def pass_set(val)
1929
- @pass = (val ? as_a(val, :to_s) : []).freeze
1972
+ @pass = Array(val).freeze
1973
+ end
1974
+
1975
+ def only_set(val)
1976
+ @only = val && as_a(val, :to_s).freeze
1930
1977
  end
1931
1978
 
1932
1979
  def exclude_set(val)
@@ -1985,6 +2032,14 @@ module Squared
1985
2032
  end
1986
2033
  end
1987
2034
 
2035
+ def task_pass?(key)
2036
+ @only ? !@only.include?(key) : @pass.include?(key)
2037
+ end
2038
+
2039
+ def matchany?(val, list, empty: true)
2040
+ list.empty? ? empty : list.any? { |pat| val.match?(pat) }
2041
+ end
2042
+
1988
2043
  def projectpath?(val)
1989
2044
  val = Pathname.new(val).cleanpath
1990
2045
  val.absolute? ? val.to_s.start_with?(File.join(path, '')) : !val.to_s.start_with?(File.join('..', ''))
@@ -2086,6 +2141,14 @@ module Squared
2086
2141
  BLK_SET
2087
2142
  end
2088
2143
 
2144
+ def hashobj
2145
+ Workspace::Support.hashobj
2146
+ end
2147
+
2148
+ def hashlist
2149
+ Workspace::Support.hashlist
2150
+ end
2151
+
2089
2152
  def borderstyle
2090
2153
  ((data = workspace.banner_get(*@ref, group: group)) && data[:border]) || theme[:border]
2091
2154
  end