squared 0.6.2 → 0.6.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.
@@ -3,6 +3,8 @@
3
3
  require 'json'
4
4
  require 'logger'
5
5
 
6
+ require_relative 'support/class'
7
+
6
8
  module Squared
7
9
  module Workspace
8
10
  module Project
@@ -109,12 +111,13 @@ module Squared
109
111
 
110
112
  subtasks({
111
113
  'graph' => %i[run print].freeze,
112
- 'unpack' => %i[zip gz tar ext].freeze,
114
+ 'unpack' => %i[zip gz tar ext],
113
115
  'asdf' => %i[set exec current update latest where reshim]
114
116
  })
115
117
 
116
- attr_reader :name, :project, :workspace, :path, :theme, :group, :parent, :dependfile,
118
+ attr_reader :name, :workspace, :path, :theme, :group, :parent, :children, :dependfile,
117
119
  :exception, :pipe, :verbose, :global
120
+ attr_accessor :project
118
121
 
119
122
  def initialize(workspace, path, name, *, group: nil, first: {}, last: {}, error: {}, common: ARG[:COMMON],
120
123
  **kwargs)
@@ -380,11 +383,7 @@ module Squared
380
383
  if flag == :run
381
384
  graph args
382
385
  else
383
- out, done = graph(args, out: [])
384
- out.map! do |val|
385
- n = done.index { |proj| val.match?(/ #{Regexp.escape(proj.name)}(?:@\d|\z)/) }
386
- n ? val.subhint(n.succ) : val
387
- end
386
+ out = graph(args, out: [], order: {})
388
387
  emphasize(out, title: path, right: true, border: borderstyle, sub: [
389
388
  opt_style(theme[:header], /\A(#{Regexp.escape(path.to_s)})(.*)\z/),
390
389
  opt_style(theme[:active], /\A(#{Regexp.escape(name)})(.*)\z/),
@@ -491,7 +490,7 @@ module Squared
491
490
  proj = self
492
491
  instance_eval(&blk) if block_given?
493
492
  end
494
- @children << proj
493
+ children << proj
495
494
  end
496
495
  self
497
496
  end
@@ -561,10 +560,9 @@ module Squared
561
560
  flags = append_hash(flags, target: []).join(' ') if flags.is_a?(Hash)
562
561
  cmd = case opts
563
562
  when Hash
564
- Array(cmd).push(flags)
565
- .concat(append_hash(opts, target: [], build: true))
566
- .compact
567
- .join(' ')
563
+ [cmd, flags].concat(append_hash(opts, target: [], build: true))
564
+ .compact
565
+ .join(' ')
568
566
  when Enumerable
569
567
  cmd = Array(cmd).concat(opts.to_a)
570
568
  cmd.map! { |val| "#{val} #{flags}" } if flags
@@ -618,7 +616,7 @@ module Squared
618
616
  end
619
617
 
620
618
  def doc(*, sync: invoked_sync?('doc'), **)
621
- run_b(@doc, sync: sync, banner: from_base?('doc') ? verbose? : verbosetype > 0, from: :doc)
619
+ run_b(@doc, sync: sync, banner: from_base?('doc') ? verbose? : !silent?, from: :doc)
622
620
  end
623
621
 
624
622
  def lint(*, sync: invoked_sync?('lint'), **)
@@ -640,10 +638,10 @@ module Squared
640
638
  case @clean
641
639
  when Struct
642
640
  if (val = instance_eval(&@clean.block) || @clean.run)
643
- temp = @clean
644
- @clean = val
645
- clean(*args, sync: sync, pass: true, **kwargs)
646
- @clean = temp
641
+ @clean = @clean.tap do
642
+ @clean = val
643
+ clean(*args, sync: sync, pass: true, **kwargs)
644
+ end
647
645
  end
648
646
  when String
649
647
  run_s(@clean, sync: sync)
@@ -659,7 +657,7 @@ module Squared
659
657
  entry = basepath(val = val.to_s)
660
658
  if entry.directory? && val.match?(%r{[\\/]\z})
661
659
  log&.warn "rm -rf #{entry}"
662
- rm_rf(entry, verbose: verbosetype > 0)
660
+ rm_rf(entry, verbose: !silent?)
663
661
  else
664
662
  log&.warn "rm #{entry}"
665
663
  (val.include?('*') ? Dir[entry] : [entry]).each do |file|
@@ -678,7 +676,7 @@ module Squared
678
676
  on :last, :clean unless pass
679
677
  end
680
678
 
681
- def graph(start = [], tasks = nil, *, sync: invoked_sync?('graph'), pass: [], out: nil, **)
679
+ def graph(start = [], tasks = nil, *, sync: invoked_sync?('graph'), pass: [], out: nil, order: nil, **)
682
680
  env('GRAPH', strict: true) do |val|
683
681
  tasks ||= []
684
682
  split_escape(val) do |task|
@@ -696,12 +694,19 @@ module Squared
696
694
  data[name] << self
697
695
  on :first, :graph
698
696
  end
699
- ret = graph_branch(self, data, tasks, out, sync: sync, pass: pass)
697
+ ret = graph_branch(self, data, tasks, out, sync: sync, pass: pass, order: order)
700
698
  rescue StandardError => e
701
699
  on_error(e, :graph, exception: true)
702
700
  else
703
701
  if out
704
- [out, ret]
702
+ if order
703
+ out.map! do |val|
704
+ name = ret.find { |proj| val.match?(/ #{Regexp.escape(proj.name)}(?:@\d|\z)/) }&.name
705
+ (n = name && order[name]) ? val.subhint(n.succ) : val
706
+ end
707
+ else
708
+ [out, ret]
709
+ end
705
710
  else
706
711
  on :last, :graph
707
712
  end
@@ -770,7 +775,7 @@ module Squared
770
775
  break uri = url if data
771
776
  end
772
777
  unless data && (ext ||= URI.decode_www_form_component(URI.parse(uri).path[/\.([\w%]+)(?:\?|\z)/, 1]))
773
- raise_error(data ? TypeError : RuntimeError, "no content#{data ? ' type' : ''}", hint: uri)
778
+ raise_error(data ? TypeError : RuntimeError, "no content#{' type' if data}", hint: uri)
774
779
  end
775
780
  end
776
781
  ext = ext.downcase
@@ -800,7 +805,7 @@ module Squared
800
805
  when 'zip', 'aar'
801
806
  session 'unzip', shell_quote(file), quote_option('d', target)
802
807
  when 'tar', /\A(?:t|tar\.)?[gx]z\z/
803
- flags = +(verbose ? 'v' : '')
808
+ flags = +(silent? ? '' : 'v')
804
809
  if ext.end_with?('gz')
805
810
  flags += 'z'
806
811
  elsif ext.end_with?('xz')
@@ -865,7 +870,7 @@ module Squared
865
870
  cmd << name
866
871
  else
867
872
  cmd << name
868
- banner = flag == :update || flag == :reshim
873
+ banner = false if flag == :latest || flag == :where
869
874
  end
870
875
  success?(run(banner: banner, from: :"asdf:#{flag}"), flag == :set || flag == :reshim)
871
876
  end
@@ -918,16 +923,16 @@ module Squared
918
923
 
919
924
  cmd = cmd.target if cmd.is_a?(OptionPartition)
920
925
  if interactive && sync && (!@session || !option('y'))
921
- title, y, hint = case interactive
922
- when Array
923
- interactive
924
- when String
925
- [interactive, 'N']
926
- else
927
- ['Run', 'Y']
928
- end
929
- title = "#{title} #{sub_style(hint, styles: theme[:active])}" if hint
930
- exit 1 unless confirm_basic("#{title}?", cmd, y)
926
+ msg, y, h = case interactive
927
+ when Array
928
+ interactive
929
+ when String
930
+ [interactive, 'N']
931
+ else
932
+ %w[Run Y]
933
+ end
934
+ msg = "#{msg} #{sub_style(h, theme[:active])}" if h
935
+ exit 1 unless confirm_basic("#{msg}?", cmd, y)
931
936
  end
932
937
  cmd = session_done cmd
933
938
  log&.info cmd
@@ -1085,6 +1090,10 @@ module Squared
1085
1090
  @prod != false && workspace.prod?(pat: @prod, **scriptargs)
1086
1091
  end
1087
1092
 
1093
+ def empty?
1094
+ children.empty?
1095
+ end
1096
+
1088
1097
  def exclude?(*refs)
1089
1098
  !@exclude.empty? && has_value?(@exclude, refs.flatten)
1090
1099
  end
@@ -1159,7 +1168,7 @@ module Squared
1159
1168
  log_console(*args, pipe: kwargs[:pipe] || pipe)
1160
1169
  end
1161
1170
 
1162
- def run_s(*cmd, sync: true, banner: verbosetype > 0, from: nil, **kwargs)
1171
+ def run_s(*cmd, sync: true, banner: !silent?, from: nil, **kwargs)
1163
1172
  cmd.flatten!
1164
1173
  case cmd.last
1165
1174
  when Hash, TrueClass, FalseClass
@@ -1204,11 +1213,11 @@ module Squared
1204
1213
  end
1205
1214
  end
1206
1215
 
1207
- def graph_branch(target, data, tasks = nil, out = nil, sync: true, pass: [], done: [], depth: 0,
1216
+ def graph_branch(target, data, tasks = nil, out = nil, sync: true, pass: [], done: [], order: nil, depth: 0,
1208
1217
  single: false, last: false, context: nil)
1209
- tag = ->(proj) { "#{proj.name}#{SEM_VER.match?(proj.version) ? "@#{proj.version}" : ''}" }
1218
+ tag = ->(proj) { "#{proj.name}#{"@#{proj.version}" if SEM_VER.match?(proj.version)}" }
1210
1219
  script = ->(proj) { workspace.script_get(:graph, group: proj.group, ref: proj.allref)&.fetch(:graph, nil) }
1211
- dedupe = lambda do |name|
1220
+ uniq = lambda do |name|
1212
1221
  next [] unless (ret = data[name])
1213
1222
 
1214
1223
  ret.dup.each do |proj|
@@ -1219,7 +1228,7 @@ module Squared
1219
1228
  ret
1220
1229
  end
1221
1230
  if depth == 0
1222
- items = dedupe.call(target.name) - done
1231
+ items = uniq.call(target.name) - done
1223
1232
  single = items.size == 1
1224
1233
  else
1225
1234
  items = data[target.name] - done
@@ -1243,7 +1252,7 @@ module Squared
1243
1252
  items.each_with_index do |proj, i|
1244
1253
  next if done.include?(proj)
1245
1254
 
1246
- t = dedupe.call(name = proj.name)
1255
+ t = uniq.call(name = proj.name)
1247
1256
  j = if out
1248
1257
  if i == items.size.pred || (post = items[i.succ..-1] - done).empty?
1249
1258
  true
@@ -1252,10 +1261,41 @@ module Squared
1252
1261
  end
1253
1262
  end
1254
1263
  unless target.name == name || (none = (t - done).empty?)
1255
- graph_branch(proj, data, tasks, out, sync: sync, pass: pass, done: done, depth: depth.succ,
1264
+ graph_branch(proj, data, tasks, out, sync: sync, pass: pass, done: done, order: order, depth: depth.succ,
1256
1265
  single: single, last: j == true, context: target)
1257
1266
  end
1258
- if !out
1267
+ if out
1268
+ if none
1269
+ a, b, c, d = ARG[:GRAPH]
1270
+ out << if depth == 0
1271
+ "#{i == items.size.pred ? d : c}#{b * 4} #{tag.call(proj)}"
1272
+ else
1273
+ s = +''
1274
+ k = 0
1275
+ final = data.keys.last
1276
+ while k < depth
1277
+ indent = k > 0 ? ((last && !j) || (j && k == depth.pred) || single) : j && last && depth == 1
1278
+ s += "#{indent || (last && data[final].last == context) ? ' ' : a} "
1279
+ k += 1
1280
+ end
1281
+ s += "#{j ? d : c}#{b * 3} #{tag.call(proj)}"
1282
+ end
1283
+ end
1284
+ if order
1285
+ n = order.size
1286
+ order[name] ||= if proj.parent
1287
+ if order[s = proj.parent.name]
1288
+ order[s] += 1
1289
+ n.pred
1290
+ else
1291
+ order[s] = n.succ
1292
+ n
1293
+ end
1294
+ else
1295
+ n
1296
+ end
1297
+ end
1298
+ else
1259
1299
  (tasks || (subtasks = script.call(proj)) || (dev? ? %w[build copy] : %w[depend build])).each do |meth|
1260
1300
  next if pass.include?(meth)
1261
1301
 
@@ -1271,21 +1311,6 @@ module Squared
1271
1311
  proj.__send__(meth.to_sym, sync: sync)
1272
1312
  end
1273
1313
  end
1274
- elsif none
1275
- a, b, c, d = ARG[:GRAPH]
1276
- out << if depth == 0
1277
- "#{i == items.size.pred ? d : c}#{b * 4} #{tag.call(proj)}"
1278
- else
1279
- s = ''.dup
1280
- k = 0
1281
- final = data.keys.last
1282
- while k < depth
1283
- indent = k > 0 ? ((last && !j) || (j && k == depth.pred) || single) : j && last && depth == 1
1284
- s += "#{indent || (last && data[final].last == context) ? ' ' : a} "
1285
- k += 1
1286
- end
1287
- s + "#{j ? d : c}#{b * 3} #{tag.call(proj)}"
1288
- end
1289
1314
  end
1290
1315
  done << proj
1291
1316
  end
@@ -1301,16 +1326,22 @@ module Squared
1301
1326
  obj.enabled? ? [obj] : []
1302
1327
  else
1303
1328
  workspace.find(group: val, ref: val.to_sym)
1329
+ end.sort do |a, b|
1330
+ if a.parent == b
1331
+ -1
1332
+ else
1333
+ b.parent == a ? 1 : 0
1334
+ end
1304
1335
  end.each do |proj|
1305
1336
  next if pass.include?(name = proj.name)
1306
1337
 
1307
1338
  if proj.graph? && !data.key?(name) && !root.include?(name)
1308
1339
  graph_collect(proj, data: data, pass: pass, root: root + [name, target.name])
1309
1340
  end
1310
- unless (objs = data.fetch(name, [])).include?(target)
1311
- deps << proj
1312
- deps.concat(objs)
1313
- end
1341
+ next if (objs = data.fetch(name, [])).include?(target)
1342
+
1343
+ deps << proj
1344
+ deps.concat(objs)
1314
1345
  end
1315
1346
  end
1316
1347
  deps.uniq!
@@ -1346,11 +1377,13 @@ module Squared
1346
1377
  ENV[name] || ENV.fetch(key, '')
1347
1378
  end
1348
1379
  if !equals.nil?
1349
- ret = ret == equals.to_s
1380
+ ret = Array(equals).any? { |val| ret == val.to_s }
1350
1381
  elsif ret.empty? || (ignore && Array(ignore).any? { |val| ret == val.to_s })
1351
1382
  ret = default
1352
1383
  end
1353
- block_given? && !ret.nil? ? yield(ret) : ret
1384
+ return yield ret if block_given? && !ret.nil?
1385
+
1386
+ ret
1354
1387
  end
1355
1388
 
1356
1389
  def session(*cmd, prefix: cmd.first, main: true, path: true, options: true)
@@ -1364,11 +1397,13 @@ module Squared
1364
1397
  if val.start_with?('-')
1365
1398
  ret.merge(shell_parse(val))
1366
1399
  else
1367
- split_escape(val) { |opt| ret.last(fill_option(opt), /\A(--?[^\[\]=\s-][^\[\]=\s]*)[=\s].+\z/m) }
1400
+ split_escape(val) { |opt| ret.last(fill_option(opt), /\A(--?[^=\s-][^=\s]*)[=\s].+\z/m) }
1368
1401
  end
1369
1402
  end
1370
1403
  end
1371
- main ? @session = ret : ret
1404
+ return ret unless main
1405
+
1406
+ @session = ret
1372
1407
  end
1373
1408
 
1374
1409
  def session_output(*cmd, **kwargs)
@@ -1497,7 +1532,7 @@ module Squared
1497
1532
  val
1498
1533
  end
1499
1534
  end
1500
- (lines << sub_style(ARG[:BORDER][1] * n, styles: border)).join("\n")
1535
+ (lines << sub_style(ARG[:BORDER][1] * n, border)).join("\n")
1501
1536
  end
1502
1537
 
1503
1538
  def print_footer(*lines, sub: nil, reverse: false, right: false, border: borderstyle, **)
@@ -1505,30 +1540,32 @@ module Squared
1505
1540
  sub = as_a sub
1506
1541
  lines.map! do |val|
1507
1542
  s = right ? val.rjust(n) : val.ljust(n)
1508
- sub.each { |h| s = sub_style(s, **h) }
1543
+ sub.each { |h| sub_style!(s, **h) }
1509
1544
  s
1510
1545
  end
1511
- [sub_style(ARG[:BORDER][1] * n, styles: border)].concat(lines)
1512
- .tap { |ret| ret.reverse! if reverse }
1513
- .join("\n")
1546
+ [sub_style(ARG[:BORDER][1] * n, border)].concat(lines)
1547
+ .tap { |ret| ret.reverse! if reverse }
1548
+ .join("\n")
1514
1549
  end
1515
1550
 
1516
1551
  def print_status(*args, from: nil, **kwargs)
1517
- return if stdin?
1552
+ return if stdin? || silent?
1518
1553
 
1519
1554
  case from
1520
1555
  when :outdated
1521
1556
  out = print_footer("major #{args[0]} / minor #{args[1]} / patch #{args[2]}", right: true).split("\n")
1522
- out[1] = sub_style(out[1], **opt_style(theme[:major], /^( +major )(\d+)(.+)$/, 2))
1523
- out[1] = sub_style(out[1], **opt_style(theme[:active], /^(.+)(minor )(\d+)(.+)$/, 3))
1524
- out[1] = sub_style(out[1], **opt_style(theme[:current], /^(.+)(patch )(\d+)(.+)$/, 3)) if theme[:current]
1525
- puts out
1557
+ sub_style!(out[1], **opt_style(theme[:major], /^( +major )(\d+)(.+)$/, 2))
1558
+ sub_style!(out[1], **opt_style(theme[:active], /^(.+)(minor )(\d+)(.+)$/, 3))
1559
+ sub_style!(out[1], **opt_style(theme[:current], /^(.+)(patch )(\d+)(.+)$/, 3)) if theme[:current]
1526
1560
  when :completed
1527
- return unless verbose && kwargs[:start]
1561
+ return unless kwargs[:start]
1528
1562
 
1529
- puts log_message(Logger::INFO, *args, sub_style('completed', styles: theme[:active]),
1530
- subject: kwargs[:subject], hint: time_format(time_epoch - kwargs[:start]))
1563
+ out = log_message(Logger::INFO, *args, sub_style('completed', theme[:active]),
1564
+ subject: kwargs[:subject], hint: time_format(time_epoch - kwargs[:start]))
1565
+ else
1566
+ return
1531
1567
  end
1568
+ puts out
1532
1569
  end
1533
1570
 
1534
1571
  def format_desc(action, flag, opts = nil, **kwargs)
@@ -1621,7 +1658,7 @@ module Squared
1621
1658
  end
1622
1659
 
1623
1660
  def empty_status(msg, title, obj, always: false)
1624
- "#{msg}#{!always && (!obj || obj == 0 || obj.to_s.empty?) ? '' : message(hint: message(title, obj.to_s))}"
1661
+ "#{msg}#{message(hint: message(title, obj.to_s)) unless !always && (!obj || obj == 0 || obj.to_s.empty?)}"
1625
1662
  end
1626
1663
 
1627
1664
  def append_repeat(flag, opts, target: @session)
@@ -1828,22 +1865,34 @@ module Squared
1828
1865
  end
1829
1866
 
1830
1867
  def confirm_basic(msg, target, default = 'Y', style: :inline, **kwargs)
1831
- confirm("#{msg} [#{sub_style(target.to_s, styles: theme[style])}]", default, **kwargs)
1868
+ confirm("#{msg} [#{sub_style(target.to_s, style.is_a?(Symbol) ? theme[style] : style)}]", default, **kwargs)
1832
1869
  end
1833
1870
 
1834
- def confirm_outdated(pkg, ver, rev, cur = nil, lock: false, col1: 0, **kwargs)
1835
- a = sub_style(case rev
1836
- when 1
1837
- 'MAJOR'
1838
- when 2
1839
- 'MINOR'
1840
- else
1841
- 'PATCH'
1842
- end, styles: (rev == 1 && theme[:major]) || theme[:header])
1843
- b = sub_style(pkg.ljust(col1), styles: theme[:inline])
1844
- c = lock ? sub_style((cur || 'locked').rjust(7), styles: color(:red)) : cur&.rjust(7)
1845
- d = rev == 1 || lock ? 'N' : 'Y'
1846
- confirm("#{a}: #{b}#{c} #{sub_style(ver.rjust(col1 > 0 ? 10 : 0), styles: theme[:inline])} ", d, **kwargs)
1871
+ def confirm_outdated(pkg, ver, type, cur = nil, lock: false, col0: 0, col1: 0, col2: nil, col3: 0, col4: 0,
1872
+ **kwargs)
1873
+ h = sub_style(semrev(type).upcase, (type == 1 && theme[:major]) || theme[:header])
1874
+ case col0
1875
+ when 0
1876
+ col0 = "#{h}: "
1877
+ when Numeric
1878
+ puts h
1879
+ col0 = ' ' * col0
1880
+ else
1881
+ puts h
1882
+ end
1883
+ b = sub_style pkg.ljust(col1), theme[:inline]
1884
+ cur ||= 'locked' if lock
1885
+ c = if cur
1886
+ cur = cur.ljust(col2 || cur.size.succ)
1887
+ lock ? sub_style(cur, color(:red)) : cur
1888
+ end
1889
+ d = type == 1 || lock ? 'N' : 'Y'
1890
+ e = "#{col0}#{b}#{c}#{sub_style(col1 > 0 ? ver.ljust(col3) : ver.rjust(ver.size.succ), theme[:inline])}"
1891
+ confirm("#{e}#{col4 > 0 ? ' ' * [col4 - e.stripstyle.size - 1, 2].max : ' '}", d, **kwargs)
1892
+ end
1893
+
1894
+ def confirm_semver(msg, type, style: (type == 1 && theme[:major]) || :inline, timeout: 0, **kwargs)
1895
+ confirm_basic(msg, semrev(type), type == 1 ? 'N' : 'Y', style: style, timeout: timeout, **kwargs)
1847
1896
  end
1848
1897
 
1849
1898
  def choice_index(msg, list, values: nil, accept: nil, series: false, trim: nil, column: nil, multiple: false,
@@ -1862,12 +1911,12 @@ module Squared
1862
1911
  ret = ret.first unless multiple
1863
1912
  end
1864
1913
  if accept
1865
- hint = Array(ret).map { |val| sub_style(val.to_s, styles: theme[:inline]) }.join(', ')
1914
+ hint = Array(ret).map { |val| sub_style(val.to_s, theme[:inline]) }.join(', ')
1866
1915
  accept = Array(accept).map { |val| Array(val) }
1867
1916
  ret = Array(ret) if accept.any? { |val| val[1] == true }
1868
1917
  loop do
1869
1918
  item = accept.first
1870
- c = confirm("#{item[0]}#{hint ? " [#{hint}]" : ''}", item[2] ? 'Y' : 'N')
1919
+ c = confirm("#{item[0]}#{" [#{hint}]" if hint}", item[2] ? 'Y' : 'N')
1871
1920
  if item[1] == true
1872
1921
  ret << c
1873
1922
  elsif !c
@@ -2012,6 +2061,27 @@ module Squared
2012
2061
  join ? ret.join : ret
2013
2062
  end
2014
2063
 
2064
+ def semtype(cur, lat)
2065
+ if semmajor?(cur, lat)
2066
+ 1
2067
+ else
2068
+ cur[2] == lat[2] ? 3 : 2
2069
+ end
2070
+ end
2071
+
2072
+ def semrev(type)
2073
+ case type
2074
+ when 1
2075
+ 'major'
2076
+ when 2
2077
+ 'minor'
2078
+ when 3
2079
+ 'patch'
2080
+ else
2081
+ 'unknown'
2082
+ end
2083
+ end
2084
+
2015
2085
  def semgte?(val, other)
2016
2086
  semcmp(val, other) != 1
2017
2087
  end
@@ -2028,6 +2098,30 @@ module Squared
2028
2098
  workspace.windows? ? '=' : '^'
2029
2099
  end
2030
2100
 
2101
+ def shortname(*args, suffix: '?', delim: ',', pass: false)
2102
+ return unless TASK_METADATA || pass
2103
+
2104
+ args.map! do |ch|
2105
+ "#{ch}/#{case ch
2106
+ when 'i'
2107
+ 'nteractive'
2108
+ when 's'
2109
+ 'elect'
2110
+ when 'u'
2111
+ 'pdate'
2112
+ when 'h'
2113
+ 'ide'
2114
+ when 'f'
2115
+ 'orce'
2116
+ when 'd'
2117
+ 'ry-run'
2118
+ else
2119
+ next
2120
+ end}#{suffix}"
2121
+ end.compact
2122
+ .join(delim)
2123
+ end
2124
+
2031
2125
  def printsucc
2032
2126
  @@print_order += 1
2033
2127
  end
@@ -2197,7 +2291,7 @@ module Squared
2197
2291
  end
2198
2292
 
2199
2293
  def theme_set(common)
2200
- @theme = if !verbose
2294
+ @theme = if silent?
2201
2295
  {}
2202
2296
  elsif common
2203
2297
  workspace.theme
@@ -2232,7 +2326,7 @@ module Squared
2232
2326
  __send__ key
2233
2327
  end
2234
2328
  end
2235
- next if (items = @children.select { |item| item.task_include?(key) }).empty?
2329
+ next if (items = children.select { |item| item.task_include?(key) }).empty?
2236
2330
 
2237
2331
  ws.task_desc(@desc, action, 'workspace')
2238
2332
  task task_join(action, 'workspace') => items.map! { |item| task_join(item.name, action) }
@@ -2270,7 +2364,7 @@ module Squared
2270
2364
 
2271
2365
  def runnable?(val)
2272
2366
  case val
2273
- when String, Enumerable, Proc, Method
2367
+ when String, Enumerable, Proc, Method, Struct
2274
2368
  true
2275
2369
  else
2276
2370
  false
@@ -2313,7 +2407,13 @@ module Squared
2313
2407
  else
2314
2408
  $?.success?
2315
2409
  end.tap do |ret|
2316
- print_success if ret && stdout? && banner? && cond.none? { |val| val == false }
2410
+ next unless cond.none? { |val| val == false }
2411
+
2412
+ if block_given?
2413
+ yield ret
2414
+ elsif ret && stdout? && banner?
2415
+ print_success
2416
+ end
2317
2417
  end
2318
2418
  end
2319
2419
 
@@ -2337,6 +2437,10 @@ module Squared
2337
2437
  verbosetype > 1
2338
2438
  end
2339
2439
 
2440
+ def silent?
2441
+ verbosetype == 0
2442
+ end
2443
+
2340
2444
  def warning?
2341
2445
  workspace.warning
2342
2446
  end
@@ -2345,12 +2449,7 @@ module Squared
2345
2449
  return false unless target.is_a?(Enumerable)
2346
2450
 
2347
2451
  args = args.first if args.size == 1 && args.first.is_a?(Enumerable)
2348
- case target
2349
- when Hash
2350
- args.is_a?(Enumerable) ? args.any? { |obj| target.value?(obj) } : target.value?(args)
2351
- else
2352
- args.is_a?(Enumerable) ? args.any? { |obj| target.include?(obj) } : target.include?(args)
2353
- end
2452
+ args.any? { |obj| target.include?(obj) }
2354
2453
  end
2355
2454
 
2356
2455
  def has_value!(target, *args, first: false)