squared 0.4.14 → 0.5.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.
@@ -99,10 +99,15 @@ module Squared
99
99
  last: last,
100
100
  error: error
101
101
  }
102
- @envname = env_key(@name).freeze
102
+ @envname = @name.gsub(/[^\w]+/, '_').upcase.freeze
103
103
  @desc = (@name.include?(':') ? @name.split(':').join(ARG[:SPACE]) : @name).freeze
104
104
  @parent = nil
105
105
  @global = false
106
+ @log = nil
107
+ @dev = nil
108
+ @prod = nil
109
+ @withargs = nil
110
+ @session = nil
106
111
  @index = -1
107
112
  run_set(kwargs[:run], kwargs[:env], opts: kwargs.fetch(:opts, true))
108
113
  exception_set kwargs[:exception]
@@ -200,7 +205,7 @@ module Squared
200
205
  file &&= @workspace.home.join(env('LOG_DIR', ''), file).realdirpath
201
206
  rescue StandardError => e
202
207
  file = nil
203
- warn log_message(Logger::WARN, e) if warning?
208
+ warn log_message(Logger::WARN, e, pass: true) if warning?
204
209
  end
205
210
  log[:progname] ||= @name
206
211
  if (val = env('LOG_LEVEL', ignore: false))
@@ -245,14 +250,14 @@ module Squared
245
250
  return 1 if a.include?(other)
246
251
 
247
252
  c, d = graph_deps other
248
- e = b - d
249
- f = d - b
253
+ e = b.reject { |val| d.include?(val) }
254
+ f = d.reject { |val| b.include?(val) }
250
255
  if parent == other.parent
251
256
  g = []
252
257
  h = []
253
258
  else
254
- g = a - c
255
- h = c - a
259
+ g = a.reject { |val| c.include?(val) }
260
+ h = c.reject { |val| a.include?(val) }
256
261
  end
257
262
  g << self
258
263
  h << other
@@ -266,8 +271,8 @@ module Squared
266
271
  -1
267
272
  elsif f.any? { |val| e.include?(val) }
268
273
  1
269
- elsif @index != -1 && (i = other.instance_variable_get(:@index)) != -1
270
- @index < i ? -1 : 1
274
+ elsif @index >= 0 && (i = other.instance_variable_get(:@index)) >= 0
275
+ @index <= i ? -1 : 1
271
276
  else
272
277
  0
273
278
  end
@@ -296,31 +301,31 @@ module Squared
296
301
 
297
302
  format_desc action, flag, '(-)project*'
298
303
  task flag do |_, args|
299
- args = args.to_a.reject { |val| name == val.to_s }
304
+ args = args.to_a.reject { |val| name == val }
300
305
  if flag == :run
301
306
  graph args
302
307
  else
303
308
  out, done = graph(args, out: [])
304
309
  out.map! do |val|
305
310
  done.each_with_index do |proj, i|
306
- next unless val.match?(/ #{Regexp.escape(proj.name)}(?:@\d|\z)/)
307
-
308
- val += " (#{i.succ})"
309
- break
311
+ if val.match?(/ #{Regexp.escape(proj.name)}(?:@\d|\z)/)
312
+ val += " (#{i.succ})"
313
+ break
314
+ end
310
315
  end
311
316
  val
312
317
  end
313
318
  emphasize(out, title: path, right: true, border: borderstyle, sub: [
314
319
  { pat: /\A(#{Regexp.escape(path.to_s)})(.*)\z/, styles: theme[:header] },
315
320
  { pat: /\A(#{Regexp.escape(name)})(.*)\z/, styles: theme[:active] },
316
- { pat: /\A(.+ )(\()(\d+)(\))(.*)\z/, styles: theme[:inline], index: 3 }
321
+ { pat: /\A((?~ \() \()(\d+)(\).*)\z/, styles: theme[:inline], index: 2 }
317
322
  ])
318
323
  end
319
324
  end
320
325
  when 'unpack'
321
326
  format_desc(action, flag, 'tag/url,dir,digest?,f|force?', before: flag == :ext ? 'ext' : nil)
322
327
  params = %i[tag dir digest force]
323
- params.unshift(:ext) if flag == :ext
328
+ params.prepend(:ext) if flag == :ext
324
329
  task flag, params do |_, args|
325
330
  ext = flag == :ext ? param_guard(action, flag, args: args, key: :ext) : flag.to_s
326
331
  tag = param_guard(action, flag, args: args, key: :tag)
@@ -375,17 +380,8 @@ module Squared
375
380
  return self
376
381
  elsif !projectpath?(path = basepath(path)) || !checkdir?(path)
377
382
  return self
378
- else
379
- name = case name
380
- when String, Symbol
381
- name.to_s
382
- end
383
- end
384
- if @withargs
385
- data = @withargs.dup
386
- data.merge!(kwargs)
387
- kwargs = data
388
383
  end
384
+ kwargs = @withargs.yield_self { |data| data.dup.update(kwargs) } if @withargs
389
385
  kwargs[:group] = group unless kwargs.key?(:group)
390
386
  kwargs[:ref] = ref unless kwargs.key?(:ref)
391
387
  parent = self
@@ -415,7 +411,7 @@ module Squared
415
411
 
416
412
  out = obj.link(self, *args, **kwargs, &blk) if obj.respond_to?(:link)
417
413
  if !out
418
- warn log_message(Logger::WARN, 'link not compatible', subject: obj.to_s, hint: name)
414
+ warn log_message(Logger::WARN, 'link not compatible', subject: obj.to_s, hint: name, pass: true)
419
415
  elsif out.respond_to?(:build)
420
416
  out.build
421
417
  end
@@ -457,7 +453,7 @@ module Squared
457
453
 
458
454
  cmd << a if (a = compose(as_get(b), d, script: true, args: e, from: from))
459
455
  end
460
- var.merge!(c) if c.is_a?(Hash)
456
+ var.update(c) if c.is_a?(Hash)
461
457
  end
462
458
  cmd = cmd.join(' && ')
463
459
  else
@@ -470,9 +466,9 @@ module Squared
470
466
  case opts
471
467
  when Hash
472
468
  opts = append_hash(opts, build: true)
473
- cmd = Array(cmd).push(flags).concat(opts).compact.join(' ')
469
+ cmd = as_a(cmd).append(flags).concat(opts).compact.join(' ')
474
470
  when Enumerable
475
- cmd = Array(cmd).concat(opts.to_a)
471
+ cmd = as_a(cmd).concat(opts.to_a)
476
472
  cmd.map! { |val| "#{val} #{flags}" } if flags
477
473
  cmd = cmd.join(' && ')
478
474
  else
@@ -508,7 +504,9 @@ module Squared
508
504
  next
509
505
  end
510
506
  end
511
- warn log_message(Logger::WARN, name, 'method not found', subject: 'prereqs', hint: meth)
507
+ if warning?
508
+ warn log_message(Logger::WARN, name, 'method not found', subject: 'prereqs', hint: meth, pass: true)
509
+ end
512
510
  end
513
511
  elsif proj.build?
514
512
  proj.build(sync: sync)
@@ -620,6 +618,7 @@ module Squared
620
618
  end
621
619
 
622
620
  def unpack(target, uri:, sync: true, digest: nil, ext: nil, force: false, depth: 1, headers: {}, from: :unpack)
621
+ require 'open-uri'
623
622
  if !target.exist?
624
623
  target.mkpath
625
624
  elsif !target.directory?
@@ -652,8 +651,8 @@ module Squared
652
651
  headers = headers.is_a?(Hash) ? headers.merge(val) : val
653
652
  end
654
653
  data = nil
655
- (uri = Array(uri)).each_with_index do |url, index|
656
- fetch_uri(url, headers) do |f|
654
+ (uri = as_a(uri)).each_with_index do |url, index|
655
+ URI.open(url, headers) do |f|
657
656
  data = f.read
658
657
  if algo && algo.hexdigest(data) != digest
659
658
  data = nil
@@ -690,7 +689,7 @@ module Squared
690
689
  file.write(data)
691
690
  file.close
692
691
  if create
693
- warn log_message(Logger::WARN, 'force remove', subject: name, hint: target)
692
+ warn log_message(Logger::WARN, 'force remove', subject: name, hint: target, pass: true)
694
693
  target.rmtree
695
694
  target.mkpath
696
695
  end
@@ -725,7 +724,7 @@ module Squared
725
724
  i += 1
726
725
  end
727
726
  FileUtils.mv(entry, dest)
728
- dest.children.each { |child| FileUtils.mv(child, target) }
727
+ dest.each_child { |child| FileUtils.mv(child, target) }
729
728
  dest.rmdir
730
729
  target = entry
731
730
  depth -= 1
@@ -783,6 +782,13 @@ module Squared
783
782
  end
784
783
 
785
784
  def variable_set(key, *args, **kwargs, &blk)
785
+ if block_given?
786
+ if blocks.include?(key)
787
+ series key, &blk
788
+ return self
789
+ end
790
+ args = block_args args, &blk
791
+ end
786
792
  if variables.include?(key) || blocks.include?(key)
787
793
  val = case args.size
788
794
  when 0
@@ -803,8 +809,6 @@ module Squared
803
809
  exclude_set val
804
810
  when :parent
805
811
  parent_set val
806
- when :archive
807
- archive_set val
808
812
  when :run
809
813
  run_set(*args, **kwargs)
810
814
  when :script
@@ -814,14 +818,7 @@ module Squared
814
818
  when :dependfile
815
819
  @dependfile = basepath(*args)
816
820
  else
817
- if block_given?
818
- if blocks.include?(key)
819
- series key, &blk
820
- return self
821
- end
822
- val = block_args val, &blk
823
- end
824
- instance_variable_set(:"@#{key}", val.first)
821
+ instance_variable_set(:"@#{key}", val)
825
822
  end
826
823
  else
827
824
  log&.warn "variable_set: @#{key} (private)"
@@ -966,32 +963,20 @@ module Squared
966
963
  puts_oe(*args, pipe: pipe)
967
964
  end
968
965
 
969
- def run(cmd = @session, var = nil, exception: @exception, sync: true, from: nil, banner: true, chdir: path,
970
- interactive: nil, **)
966
+ def run(cmd = @session, var = nil, exception: @exception, sync: true, from: nil, banner: true, chdir: path, **)
971
967
  unless cmd
972
- from = from&.to_s || 'unknown'
973
- return warn log_message(Logger::WARN, 'no command given', subject: project, hint: from, pass: true)
968
+ if warning?
969
+ from &&= from.to_s
970
+ warn log_message(Logger::WARN, from || 'unknown', subject: project, hint: 'no command given', pass: true)
971
+ end
972
+ return
974
973
  end
975
- i = interactive && !(@session && option('y'))
976
974
  cmd = cmd.target if cmd.is_a?(OptionPartition)
977
975
  cmd = session_done cmd
978
- if i
979
- title, y = case interactive
980
- when Array
981
- interactive
982
- when String
983
- [interactive, 'N']
984
- else
985
- ['Run', 'Y']
986
- end
987
- unless confirm("#{title}? [#{sub_style(cmd, styles: theme[:inline])}] #{y == 'Y' ? '[Y/n]' : '[y/N]'} ", y)
988
- raise_error('user cancelled', hint: from)
989
- end
990
- end
991
976
  log&.info cmd
992
977
  on :first, from
993
978
  begin
994
- if cmd.match?(/\A[^:]+:[^:]/) && workspace.task_defined?(cmd)
979
+ if cmd.start_with?(/[^:]+:[^:]/) && workspace.task_defined?(cmd)
995
980
  log&.warn "ENV discarded: #{var}" if var
996
981
  task_invoke(cmd, exception: exception, warning: warning?)
997
982
  else
@@ -1003,7 +988,7 @@ module Squared
1003
988
  when Enumerable
1004
989
  cmd = command(*pre.to_a, cmd)
1005
990
  else
1006
- cmd = command(pre, cmd)
991
+ cmd = command pre, cmd
1007
992
  end
1008
993
  end
1009
994
  args = var.is_a?(Hash) ? [var, cmd] : [cmd]
@@ -1048,7 +1033,7 @@ module Squared
1048
1033
  elsif obj.is_a?(Array) && obj.any? { |val| !val.is_a?(String) }
1049
1034
  build(*obj, **kwargs)
1050
1035
  elsif obj
1051
- run_s(*Array(obj), **kwargs)
1036
+ run_s(obj.is_a?(Enumerable) ? obj.to_a : obj, **kwargs)
1052
1037
  end
1053
1038
  end
1054
1039
  end
@@ -1095,7 +1080,7 @@ module Squared
1095
1080
 
1096
1081
  t = dedupe.call(proj.name)
1097
1082
  j = if out
1098
- if i == items.size - 1 || check.call(post = items[(i + 1)..-1]).empty?
1083
+ if i == items.size - 1 || check.call(post = items[i + 1..-1]).empty?
1099
1084
  true
1100
1085
  elsif !t.empty? && depth > 0
1101
1086
  post.reject { |pr| t.include?(pr) }.empty?
@@ -1107,9 +1092,9 @@ module Squared
1107
1092
  end
1108
1093
  if !out
1109
1094
  if !tasks && (script = workspace.script_get(:graph, group: proj.group, ref: proj.allref))
1110
- tasks = script[:graph]
1095
+ group = script[:graph]
1111
1096
  end
1112
- (tasks || (dev? ? ['build', 'copy'] : ['depend', 'build'])).each do |meth|
1097
+ (tasks || group || (dev? ? ['build', 'copy'] : ['depend', 'build'])).each do |meth|
1113
1098
  next if pass.include?(meth)
1114
1099
 
1115
1100
  if workspace.task_defined?(cmd = task_join(proj.name, meth))
@@ -1120,7 +1105,7 @@ module Squared
1120
1105
  end
1121
1106
  run(cmd, sync: false, banner: false)
1122
1107
  ENV.delete(key) if key
1123
- elsif proj.has?(meth, tasks ? nil : workspace.baseref)
1108
+ elsif proj.has?(meth, tasks || group ? nil : workspace.baseref)
1124
1109
  proj.__send__(meth.to_sym, sync: sync)
1125
1110
  end
1126
1111
  end
@@ -1157,6 +1142,7 @@ module Squared
1157
1142
  else
1158
1143
  items = workspace.find(group: val, ref: val.to_sym)
1159
1144
  end
1145
+
1160
1146
  items.each do |proj|
1161
1147
  next if pass.include?(proj.name)
1162
1148
 
@@ -1201,7 +1187,7 @@ module Squared
1201
1187
  end
1202
1188
  return ret == equals.to_s unless equals.nil?
1203
1189
 
1204
- ret.empty? || (ignore && Array(ignore).any? { |val| ret == val.to_s }) ? default : ret
1190
+ ret.empty? || (ignore && as_a(ignore).any? { |val| ret == val.to_s }) ? default : ret
1205
1191
  end
1206
1192
 
1207
1193
  def session(*cmd, prefix: cmd.first, main: true, path: true, options: true)
@@ -1249,18 +1235,15 @@ module Squared
1249
1235
  def option(*args, target: @session, prefix: target&.first, **kwargs)
1250
1236
  if prefix
1251
1237
  args.each do |val|
1252
- ret = env(env_key(stripext(prefix), val), **kwargs)
1253
- return ret if ret
1238
+ next unless (ret = env("#{stripext(prefix)}_#{val.gsub(/\W/, '_')}".upcase, **kwargs))
1239
+ return ret unless block_given?
1240
+
1241
+ return yield ret
1254
1242
  end
1255
1243
  end
1256
1244
  nil
1257
1245
  end
1258
1246
 
1259
- def option_sanitize(opts, list, target: @session, **kwargs)
1260
- op = OptionPartition.new(opts, list, target, project: self, **kwargs)
1261
- [op.extras, op.values]
1262
- end
1263
-
1264
1247
  def option_clear(opts, target: @session, **kwargs)
1265
1248
  return unless target
1266
1249
 
@@ -1286,7 +1269,7 @@ module Squared
1286
1269
  styles = [:bold] + styles
1287
1270
  end
1288
1271
  end
1289
- n = Project.max_width(lines)
1272
+ n = line_width lines
1290
1273
  ch = ' ' * pad
1291
1274
  index = -1
1292
1275
  lines.map! do |val|
@@ -1302,7 +1285,7 @@ module Squared
1302
1285
  end
1303
1286
 
1304
1287
  def print_footer(*lines, sub: nil, reverse: false, right: false, **kwargs)
1305
- n = Project.max_width(lines)
1288
+ n = line_width lines
1306
1289
  lines.map! do |val|
1307
1290
  s = right ? val.rjust(n) : val.ljust(n)
1308
1291
  sub&.each { |h| s = sub_style(s, **h) }
@@ -1313,46 +1296,33 @@ module Squared
1313
1296
  ret.join("\n")
1314
1297
  end
1315
1298
 
1316
- def print_status(*args, from: nil)
1317
- return if stdin?
1318
-
1319
- case from
1320
- when :outdated
1321
- out = print_footer("major #{args[0]} / minor #{args[1]} / patch #{args[2]}", right: true).split("\n")
1322
- out[1] = sub_style(out[1], pat: /^( +major )(\d+)(.+)$/, styles: theme[:major], index: 2)
1323
- out[1] = sub_style(out[1], pat: /^(.+)(minor )(\d+)(.+)$/, styles: theme[:active], index: 3)
1324
- puts out
1325
- end
1326
- end
1327
-
1328
1299
  def format_desc(action, flag, opts = nil, **kwargs)
1329
1300
  return unless TASK_METADATA
1330
1301
 
1331
- ret = [@desc, action]
1332
- ret << flag if flag
1333
- workspace.format_desc(ret, opts, **kwargs)
1302
+ workspace.format_desc([@desc, action, flag].compact, opts, **kwargs)
1334
1303
  end
1335
1304
 
1336
1305
  def format_banner(cmd, banner: true)
1337
1306
  return unless banner && banner?
1338
1307
 
1339
1308
  if (data = workspace.banner_get(*@ref, group: group))
1340
- return if data.empty?
1309
+ return if !data.command && data.order.empty?
1341
1310
 
1342
1311
  client = true
1343
1312
  else
1344
- data = { command: true, order: [:path], styles: theme[:banner], border: theme[:border] }
1313
+ data = Workspace::Support::BannerData.new(true, [:path], theme[:banner], theme[:border])
1345
1314
  end
1346
1315
  if verbose
1347
1316
  out = []
1348
- if data[:command]
1317
+ if data.command
1349
1318
  if cmd =~ /\A(?:"((?:[^"]|(?<=\\)")+)"|'((?:[^']|(?<=\\)')+)'|(\S+))( |\z)/
1350
1319
  path = $3 || $2 || $1
1351
- cmd = cmd.sub(path, stripext(path).upcase)
1320
+ name = stripext path
1321
+ cmd = cmd.sub(path, data.command == 0 ? name : name.upcase)
1352
1322
  end
1353
1323
  out << cmd
1354
1324
  end
1355
- data[:order].each do |val|
1325
+ data.order.each do |val|
1356
1326
  if val.is_a?(Array)
1357
1327
  s = ' '
1358
1328
  found = false
@@ -1362,7 +1332,7 @@ module Squared
1362
1332
  meth
1363
1333
  elsif respond_to?(meth)
1364
1334
  found = true
1365
- __send__(meth)
1335
+ __send__ meth
1366
1336
  end
1367
1337
  end
1368
1338
  val = val.compact.join(s)
@@ -1372,9 +1342,9 @@ module Squared
1372
1342
  end
1373
1343
  out << val.to_s
1374
1344
  end
1375
- print_banner(*out, styles: data[:styles], border: data[:border], client: client)
1345
+ print_banner(*out, styles: data.styles, border: data.border, client: client)
1376
1346
  elsif workspace.series.multiple?
1377
- "## #{__send__(data[:order].first || :path)} ##"
1347
+ "## #{__send__(data.order.first || :path)} ##"
1378
1348
  end
1379
1349
  end
1380
1350
 
@@ -1398,7 +1368,7 @@ module Squared
1398
1368
  out << ''
1399
1369
  end
1400
1370
  if from
1401
- out << (from = from.to_s)
1371
+ out << from
1402
1372
  pat = /\A(#{Regexp.escape(from)})(.*)\z/
1403
1373
  end
1404
1374
  else
@@ -1451,14 +1421,15 @@ module Squared
1451
1421
  end
1452
1422
 
1453
1423
  def append_any(val, target: @session, build: false, delim: false)
1424
+ return unless val
1425
+
1454
1426
  if delim && !target.include?('--')
1455
1427
  target << '--'
1456
1428
  else
1457
1429
  delim = false
1458
1430
  end
1431
+ val = shell_split(val) if val.is_a?(String)
1459
1432
  case val
1460
- when String
1461
- target << val
1462
1433
  when Hash
1463
1434
  append_hash(val, target: target, build: build)
1464
1435
  when Enumerable
@@ -1489,7 +1460,7 @@ module Squared
1489
1460
  return target << (if flag
1490
1461
  shell_option(opt, equals ? val : nil, quote: quote, escape: escape, force: force)
1491
1462
  else
1492
- shell_quote(val)
1463
+ shell_quote val
1493
1464
  end)
1494
1465
  end
1495
1466
  nil
@@ -1499,17 +1470,18 @@ module Squared
1499
1470
  **kwargs)
1500
1471
  return if list.empty?
1501
1472
 
1502
- ret = []
1503
- list.flatten.each do |flag|
1504
- next unless (val = option(flag, target: target, **kwargs))
1473
+ [].tap do |ret|
1474
+ list.flatten.each do |flag|
1475
+ next unless (val = option(flag, target: target, **kwargs))
1505
1476
 
1506
- if val == '0' && no
1507
- flag = "no-#{flag}"
1508
- val = nil
1477
+ if val == '0' && no
1478
+ flag = "no-#{flag}"
1479
+ val = nil
1480
+ end
1481
+ ret << shell_option(flag, equals ? val : nil, escape: escape, quote: quote, force: force)
1509
1482
  end
1510
- ret << shell_option(flag, equals ? val : nil, escape: escape, quote: quote, force: force)
1483
+ ret.each { |val| target << val } unless ret.empty?
1511
1484
  end
1512
- ret.each { |val| target << val } unless ret.empty?
1513
1485
  end
1514
1486
 
1515
1487
  def append_nocolor(target: @session)
@@ -1557,9 +1529,9 @@ module Squared
1557
1529
  end
1558
1530
 
1559
1531
  def collect_hash(data, pass: [])
1560
- ret = []
1561
- data.each { |key, val| ret.concat(val) unless pass.include?(key) }
1562
- ret
1532
+ [].tap do |ret|
1533
+ data.each { |key, val| ret.concat(val) unless pass.include?(key) }
1534
+ end
1563
1535
  end
1564
1536
 
1565
1537
  def parse_json(val, kind: Hash, hint: nil)
@@ -1567,20 +1539,11 @@ module Squared
1567
1539
  raise_error("invalid JSON #{kind.name}", val, hint: hint) if kind && !ret.is_a?(kind)
1568
1540
  rescue StandardError => e
1569
1541
  log&.warn e
1570
- warn log_message(Logger::WARN, e, subject: name) if warning?
1542
+ warn log_message(Logger::WARN, e, subject: name, pass: true) if warning?
1571
1543
  else
1572
1544
  ret
1573
1545
  end
1574
1546
 
1575
- def fetch_uri(*args, **kwargs, &blk)
1576
- require 'open-uri'
1577
- if RUBY_VERSION < '2.5'
1578
- open(*args, **kwargs, &blk)
1579
- else
1580
- URI.open(*args, **kwargs, &blk)
1581
- end
1582
- end
1583
-
1584
1547
  def param_guard(action, flag, args:, key: nil, pat: nil, values: nil)
1585
1548
  if args && key
1586
1549
  val = args.fetch(key, nil)
@@ -1595,7 +1558,7 @@ module Squared
1595
1558
  args
1596
1559
  end
1597
1560
 
1598
- def confirm_outdated(pkg, ver, rev, lock: false)
1561
+ def confirm_outdated(pkg, ver, rev, cur = nil, lock: false, col1: 0)
1599
1562
  a = sub_style(case rev
1600
1563
  when 1
1601
1564
  'MAJOR'
@@ -1603,11 +1566,11 @@ module Squared
1603
1566
  'MINOR'
1604
1567
  else
1605
1568
  'PATCH'
1606
- end, styles: theme[:header])
1607
- b = sub_style("#{pkg} #{ver}", styles: theme[:inline])
1569
+ end, styles: (rev == 1 && theme[:major]) || theme[:header])
1570
+ b = sub_style(pkg.ljust(col1), styles: theme[:inline])
1608
1571
  c, d = rev == 1 || lock ? ['y/N', 'N'] : ['Y/n', 'Y']
1609
- e = lock ? " #{sub_style('(locked)', styles: color(:red))}" : ''
1610
- confirm "Upgrade to #{a}? #{b + e} [#{c}] ", d
1572
+ e = lock ? sub_style((cur || 'locked').rjust(7), styles: color(:red)) : cur&.rjust(7)
1573
+ confirm "#{a}: #{b}#{e} #{sub_style(ver.rjust(col1 > 0 ? 10 : 0), styles: theme[:inline])} [#{c}] ", d
1611
1574
  end
1612
1575
 
1613
1576
  def choice_index(msg, list, values: nil, accept: nil, series: false, trim: nil, column: nil,
@@ -1624,28 +1587,25 @@ module Squared
1624
1587
  end
1625
1588
  ret = multiple ? ret.map! { |val| val.sub(trim, '') } : ret.sub(trim, '') if trim
1626
1589
  if column
1627
- a, b = Array(column)
1628
- ret = Array(ret).map! { |val| val[a, b || 1] }
1590
+ a, b = as_a column
1591
+ ret = as_a(ret).map! { |val| val[a, b || 1] }
1629
1592
  ret = ret.first unless multiple
1630
1593
  end
1631
1594
  if accept
1632
- hint = Array(ret).map { |val| sub_style(val, styles: theme[:inline]) }.join(', ')
1633
- accept = Array(accept).map { |val| Array(val) }
1595
+ a = as_a(ret).map { |val| sub_style(val, styles: theme[:inline]) }.join(', ')
1596
+ accept = as_a(accept).map { |val| as_a(val) }
1634
1597
  if accept.any? { |val| val[1] == true }
1635
1598
  ret = [ret]
1636
1599
  multiple = -1
1637
1600
  end
1638
1601
  loop do
1639
- item = accept.first
1640
- d, e = item[2] ? ['Y', '[Y/n]'] : ['N', '[y/N]']
1641
- c = confirm("#{item[0]}#{a ? " [#{a}]" : ''} #{e} ", d, timeout: 60)
1642
- if item[1] == true
1602
+ c = confirm("#{accept.first[0]}#{a ? " [#{a}]" : ''} [y/N] ", 'N', timeout: 60)
1603
+ if accept.shift[1] == true
1643
1604
  ret << c
1644
1605
  elsif !c
1645
1606
  break
1646
1607
  end
1647
- hint = nil
1648
- accept.shift
1608
+ a = nil
1649
1609
  break if accept.empty?
1650
1610
  end
1651
1611
  exit 1 unless accept.empty?
@@ -1676,7 +1636,7 @@ module Squared
1676
1636
  if (ret = instance_eval(&blk)).nil?
1677
1637
  val
1678
1638
  else
1679
- Array(ret)
1639
+ ret.is_a?(Array) ? ret : [ret]
1680
1640
  end
1681
1641
  end
1682
1642
 
@@ -1725,29 +1685,23 @@ module Squared
1725
1685
  end
1726
1686
 
1727
1687
  def semscan(val, fill: true)
1728
- ret = val.scan(SEM_VER).first
1729
- fill ? semver(ret) : ret
1688
+ val.scan(SEM_VER).first.yield_self { |data| fill ? semver(data) : data }
1730
1689
  end
1731
1690
 
1732
1691
  def indexitem(val)
1733
- [$1.to_i, $2 && $2[1..-1]] if val =~ /\A[=^#{indexchar}](\d+)(:.+)?\z/
1692
+ [$1.to_i, $2 && $2[1..-1]] if val =~ /\A\^(\d+)(:.+)?\z/
1734
1693
  end
1735
1694
 
1736
1695
  def indexerror(val, list = nil)
1737
1696
  raise_error("requested index #{val}", hint: list && "of #{list.size}")
1738
1697
  end
1739
1698
 
1740
- def indexchar
1741
- workspace.windows? ? '=' : '^'
1742
- end
1743
-
1744
1699
  def printsucc
1745
1700
  @@print_order += 1
1746
1701
  end
1747
1702
 
1748
1703
  def color(val)
1749
- ret = theme[val]
1750
- ret && !ret.empty? ? ret : [val]
1704
+ theme[val].yield_self { |styles| styles && !styles.empty? ? styles : [val] }
1751
1705
  end
1752
1706
 
1753
1707
  def colormap(val)
@@ -1789,40 +1743,22 @@ module Squared
1789
1743
  end
1790
1744
  end
1791
1745
 
1792
- def pwd_set(done = nil, pass: false, from: nil, dryrun: false)
1793
- pwd = Pathname.pwd
1794
- if block_given?
1795
- begin
1796
- pass = semscan(pass).join <= RUBY_VERSION if pass.is_a?(String)
1797
- if (path == pwd || pass == true) && !workspace.jruby_win?
1798
- ret = yield
1799
- else
1800
- Dir.chdir(path)
1801
- ret = yield
1802
- Dir.chdir(pwd)
1803
- end
1804
- rescue StandardError => e
1805
- log&.error e
1806
- unless dryrun
1807
- ret = on(:error, from, e)
1808
- raise if exception && ret != true
1809
- end
1810
- else
1811
- ret
1812
- end
1813
- elsif @pwd == pwd
1814
- @pwd = nil
1815
- pwd unless done
1816
- elsif @pwd
1817
- return unless path == pwd
1818
-
1819
- Dir.chdir(@pwd)
1820
- @pwd = nil
1821
- elsif !done && path != pwd
1822
- @pwd = pwd
1746
+ def pwd_set(pass: false, from: nil)
1747
+ pwd = Dir.pwd
1748
+ if path.to_s == pwd || pass == true || (pass.is_a?(String) && semscan(pass).join <= RUBY_VERSION)
1749
+ ret = yield
1750
+ else
1823
1751
  Dir.chdir(path)
1824
- @pwd
1752
+ ret = yield
1753
+ Dir.chdir(pwd)
1825
1754
  end
1755
+ rescue StandardError => e
1756
+ puts e
1757
+ log&.error e
1758
+ ret = on(:error, from, e)
1759
+ raise if exception && ret != true
1760
+ else
1761
+ ret
1826
1762
  end
1827
1763
 
1828
1764
  def run_set(cmd, val = nil, opts: nil, **)
@@ -1916,7 +1852,7 @@ module Squared
1916
1852
 
1917
1853
  def graph_set(val)
1918
1854
  @graph = if val
1919
- Array(val).map { |s| workspace.prefix ? workspace.task_name(s).to_sym : s.to_sym }.freeze
1855
+ as_a(val).map { |s| workspace.prefix ? workspace.task_name(s).to_sym : s.to_sym }.freeze
1920
1856
  end
1921
1857
  end
1922
1858
 
@@ -1969,7 +1905,7 @@ module Squared
1969
1905
  unless @pass.include?(key.to_s) || ws.task_defined?(name, action) || ws.task_exclude?(action, self)
1970
1906
  ws.task_desc(@desc, action)
1971
1907
  task action do
1972
- __send__(key)
1908
+ __send__ key
1973
1909
  end
1974
1910
  end
1975
1911
  next if (items = @children.select { |item| item.task_include?(key) }).empty?
@@ -1981,8 +1917,9 @@ module Squared
1981
1917
  end
1982
1918
 
1983
1919
  def projectpath?(val)
1984
- val = Pathname.new(val).cleanpath
1985
- val.absolute? ? val.to_s.start_with?(File.join(path, '')) : !val.to_s.start_with?(File.join('..', ''))
1920
+ Pathname.new(val).cleanpath.yield_self do |file|
1921
+ file.absolute? ? file.to_s.start_with?(File.join(path, '')) : !file.to_s.start_with?(File.join('..', ''))
1922
+ end
1986
1923
  end
1987
1924
 
1988
1925
  def checkdir?(val)
@@ -2034,8 +1971,7 @@ module Squared
2034
1971
  return false if workspace.series.chain?(val = task_join(name, action))
2035
1972
  return true if task_invoked?(val) && (!task_invoked?(ac) || !workspace.task_defined?(ac, 'sync'))
2036
1973
 
2037
- val = workspace.series.name_get(action)
2038
- val != action && invoked_sync?(val)
1974
+ workspace.series.name_get(action).yield_self { |name| name != action && invoked_sync?(name) }
2039
1975
  end
2040
1976
 
2041
1977
  def success?(ret)
@@ -2046,10 +1982,6 @@ module Squared
2046
1982
  ARG[:BANNER] && !env('BANNER', equals: '0')
2047
1983
  end
2048
1984
 
2049
- def pwd?
2050
- path == Pathname.pwd
2051
- end
2052
-
2053
1985
  def stdin?
2054
1986
  pipe == 0
2055
1987
  end
@@ -2082,7 +2014,7 @@ module Squared
2082
2014
  end
2083
2015
 
2084
2016
  def borderstyle
2085
- ((data = workspace.banner_get(*@ref, group: group)) && data[:border]) || theme[:border]
2017
+ workspace.banner_get(*@ref, group: group)&.border || theme[:border]
2086
2018
  end
2087
2019
 
2088
2020
  def headerstyle
@@ -2095,7 +2027,7 @@ module Squared
2095
2027
  end
2096
2028
 
2097
2029
  Application.implement(Base, base: true)
2098
- Application.attr_banner = Common::SymSet.new(%i[name project path ref group parent])
2030
+ Application.attr_banner = Set.new(%i[name project path ref group parent])
2099
2031
  end
2100
2032
  end
2101
2033
  end