squared 0.4.14 → 0.5.1

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.
@@ -103,6 +103,11 @@ module Squared
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]
@@ -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
@@ -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,7 +466,7 @@ 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 = Array(cmd).append(flags).concat(opts).compact.join(' ')
474
470
  when Enumerable
475
471
  cmd = Array(cmd).concat(opts.to_a)
476
472
  cmd.map! { |val| "#{val} #{flags}" } if flags
@@ -502,7 +498,7 @@ module Squared
502
498
  begin
503
499
  proj.__send__(meth, sync: sync)
504
500
  rescue StandardError => e
505
- ret = on(:error, :prereqs, e)
501
+ ret = on :error, :prereqs, e
506
502
  raise unless ret == true
507
503
  else
508
504
  next
@@ -559,7 +555,7 @@ module Squared
559
555
  @clean.each { |cmd, opts| build(cmd.to_s, opts, sync: sync) }
560
556
  rescue StandardError => e
561
557
  log&.error e
562
- ret = on(:error, from, e)
558
+ ret = on :error, from, e
563
559
  raise if exception && ret != true
564
560
  end
565
561
  else
@@ -609,7 +605,7 @@ module Squared
609
605
  end
610
606
  ret = graph_branch(self, data, tasks, out, sync: sync, pass: pass)
611
607
  rescue StandardError => e
612
- ret = on(:error, :graph, e)
608
+ ret = on :error, :graph, e
613
609
  raise unless ret == true
614
610
  else
615
611
  if out
@@ -620,6 +616,7 @@ module Squared
620
616
  end
621
617
 
622
618
  def unpack(target, uri:, sync: true, digest: nil, ext: nil, force: false, depth: 1, headers: {}, from: :unpack)
619
+ require 'open-uri'
623
620
  if !target.exist?
624
621
  target.mkpath
625
622
  elsif !target.directory?
@@ -653,7 +650,7 @@ module Squared
653
650
  end
654
651
  data = nil
655
652
  (uri = Array(uri)).each_with_index do |url, index|
656
- fetch_uri(url, headers) do |f|
653
+ URI.open(url, headers) do |f|
657
654
  data = f.read
658
655
  if algo && algo.hexdigest(data) != digest
659
656
  data = nil
@@ -725,7 +722,7 @@ module Squared
725
722
  i += 1
726
723
  end
727
724
  FileUtils.mv(entry, dest)
728
- dest.children.each { |child| FileUtils.mv(child, target) }
725
+ dest.each_child { |child| FileUtils.mv(child, target) }
729
726
  dest.rmdir
730
727
  target = entry
731
728
  depth -= 1
@@ -783,6 +780,13 @@ module Squared
783
780
  end
784
781
 
785
782
  def variable_set(key, *args, **kwargs, &blk)
783
+ if block_given?
784
+ if blocks.include?(key)
785
+ series key, &blk
786
+ return self
787
+ end
788
+ args = block_args args, &blk
789
+ end
786
790
  if variables.include?(key) || blocks.include?(key)
787
791
  val = case args.size
788
792
  when 0
@@ -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)"
@@ -984,14 +981,14 @@ module Squared
984
981
  else
985
982
  ['Run', 'Y']
986
983
  end
987
- unless confirm("#{title}? [#{sub_style(cmd, styles: theme[:inline])}] #{y == 'Y' ? '[Y/n]' : '[y/N]'} ", y)
984
+ unless confirm("#{title}? [#{sub_style(cmd, styles: theme[:inline])}]", y)
988
985
  raise_error('user cancelled', hint: from)
989
986
  end
990
987
  end
991
988
  log&.info cmd
992
989
  on :first, from
993
990
  begin
994
- if cmd.match?(/\A[^:]+:[^:]/) && workspace.task_defined?(cmd)
991
+ if cmd.start_with?(/[^:]+:[^:]/) && workspace.task_defined?(cmd)
995
992
  log&.warn "ENV discarded: #{var}" if var
996
993
  task_invoke(cmd, exception: exception, warning: warning?)
997
994
  else
@@ -1003,7 +1000,7 @@ module Squared
1003
1000
  when Enumerable
1004
1001
  cmd = command(*pre.to_a, cmd)
1005
1002
  else
1006
- cmd = command(pre, cmd)
1003
+ cmd = command pre, cmd
1007
1004
  end
1008
1005
  end
1009
1006
  args = var.is_a?(Hash) ? [var, cmd] : [cmd]
@@ -1011,7 +1008,7 @@ module Squared
1011
1008
  end
1012
1009
  rescue StandardError => e
1013
1010
  log&.error e
1014
- ret = on(:error, from, e)
1011
+ ret = on :error, from, e
1015
1012
  raise unless ret == true
1016
1013
 
1017
1014
  false
@@ -1026,7 +1023,7 @@ module Squared
1026
1023
  begin
1027
1024
  cmd.flatten.each { |val| run(val, env, sync: sync, banner: banner, **kwargs) }
1028
1025
  rescue StandardError => e
1029
- ret = on(:error, from, e)
1026
+ ret = on :error, from, e
1030
1027
  raise unless ret == true
1031
1028
  end
1032
1029
  on :last, from
@@ -1249,18 +1246,14 @@ module Squared
1249
1246
  def option(*args, target: @session, prefix: target&.first, **kwargs)
1250
1247
  if prefix
1251
1248
  args.each do |val|
1252
- ret = env(env_key(stripext(prefix), val), **kwargs)
1253
- return ret if ret
1249
+ next unless (ret = env(env_key(stripext(prefix), val), **kwargs))
1250
+
1251
+ return block_given? ? yield(ret) : ret
1254
1252
  end
1255
1253
  end
1256
1254
  nil
1257
1255
  end
1258
1256
 
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
1257
  def option_clear(opts, target: @session, **kwargs)
1265
1258
  return unless target
1266
1259
 
@@ -1286,7 +1279,7 @@ module Squared
1286
1279
  styles = [:bold] + styles
1287
1280
  end
1288
1281
  end
1289
- n = Project.max_width(lines)
1282
+ n = line_width lines
1290
1283
  ch = ' ' * pad
1291
1284
  index = -1
1292
1285
  lines.map! do |val|
@@ -1302,7 +1295,7 @@ module Squared
1302
1295
  end
1303
1296
 
1304
1297
  def print_footer(*lines, sub: nil, reverse: false, right: false, **kwargs)
1305
- n = Project.max_width(lines)
1298
+ n = line_width lines
1306
1299
  lines.map! do |val|
1307
1300
  s = right ? val.rjust(n) : val.ljust(n)
1308
1301
  sub&.each { |h| s = sub_style(s, **h) }
@@ -1328,31 +1321,30 @@ module Squared
1328
1321
  def format_desc(action, flag, opts = nil, **kwargs)
1329
1322
  return unless TASK_METADATA
1330
1323
 
1331
- ret = [@desc, action]
1332
- ret << flag if flag
1333
- workspace.format_desc(ret, opts, **kwargs)
1324
+ workspace.format_desc([@desc, action, flag].compact, opts, **kwargs)
1334
1325
  end
1335
1326
 
1336
1327
  def format_banner(cmd, banner: true)
1337
1328
  return unless banner && banner?
1338
1329
 
1339
1330
  if (data = workspace.banner_get(*@ref, group: group))
1340
- return if data.empty?
1331
+ return if !data.command && data.order.empty?
1341
1332
 
1342
1333
  client = true
1343
1334
  else
1344
- data = { command: true, order: [:path], styles: theme[:banner], border: theme[:border] }
1335
+ data = Struct::BannerData.new(true, [:path], theme[:banner], theme[:border])
1345
1336
  end
1346
1337
  if verbose
1347
1338
  out = []
1348
- if data[:command]
1339
+ if data.command
1349
1340
  if cmd =~ /\A(?:"((?:[^"]|(?<=\\)")+)"|'((?:[^']|(?<=\\)')+)'|(\S+))( |\z)/
1350
1341
  path = $3 || $2 || $1
1351
- cmd = cmd.sub(path, stripext(path).upcase)
1342
+ name = stripext path
1343
+ cmd = cmd.sub(path, data.command == 0 ? name : name.upcase)
1352
1344
  end
1353
1345
  out << cmd
1354
1346
  end
1355
- data[:order].each do |val|
1347
+ data.order.each do |val|
1356
1348
  if val.is_a?(Array)
1357
1349
  s = ' '
1358
1350
  found = false
@@ -1362,7 +1354,7 @@ module Squared
1362
1354
  meth
1363
1355
  elsif respond_to?(meth)
1364
1356
  found = true
1365
- __send__(meth)
1357
+ __send__ meth
1366
1358
  end
1367
1359
  end
1368
1360
  val = val.compact.join(s)
@@ -1372,9 +1364,9 @@ module Squared
1372
1364
  end
1373
1365
  out << val.to_s
1374
1366
  end
1375
- print_banner(*out, styles: data[:styles], border: data[:border], client: client)
1367
+ print_banner(*out, styles: data.styles, border: data.border, client: client)
1376
1368
  elsif workspace.series.multiple?
1377
- "## #{__send__(data[:order].first || :path)} ##"
1369
+ "## #{__send__(data.order.first || :path)} ##"
1378
1370
  end
1379
1371
  end
1380
1372
 
@@ -1386,7 +1378,7 @@ module Squared
1386
1378
  items.each_with_index do |val, i|
1387
1379
  next unless reg.empty? || reg.any? { |pat| val[0].match?(pat) }
1388
1380
 
1389
- out << "#{i.succ.to_s.rjust(pad)}. #{each ? each.call(val) : val[0]}"
1381
+ out << ('%*d. %s' % [pad, i.succ, each ? each.call(val) : val[0]])
1390
1382
  end
1391
1383
  end
1392
1384
  sub = [headerstyle]
@@ -1451,14 +1443,15 @@ module Squared
1451
1443
  end
1452
1444
 
1453
1445
  def append_any(val, target: @session, build: false, delim: false)
1446
+ return unless val
1447
+
1454
1448
  if delim && !target.include?('--')
1455
1449
  target << '--'
1456
1450
  else
1457
1451
  delim = false
1458
1452
  end
1453
+ val = shell_split(val) if val.is_a?(String)
1459
1454
  case val
1460
- when String
1461
- target << val
1462
1455
  when Hash
1463
1456
  append_hash(val, target: target, build: build)
1464
1457
  when Enumerable
@@ -1489,7 +1482,7 @@ module Squared
1489
1482
  return target << (if flag
1490
1483
  shell_option(opt, equals ? val : nil, quote: quote, escape: escape, force: force)
1491
1484
  else
1492
- shell_quote(val)
1485
+ shell_quote val
1493
1486
  end)
1494
1487
  end
1495
1488
  nil
@@ -1499,17 +1492,18 @@ module Squared
1499
1492
  **kwargs)
1500
1493
  return if list.empty?
1501
1494
 
1502
- ret = []
1503
- list.flatten.each do |flag|
1504
- next unless (val = option(flag, target: target, **kwargs))
1495
+ [].tap do |ret|
1496
+ list.flatten.each do |flag|
1497
+ next unless (val = option(flag, target: target, **kwargs))
1505
1498
 
1506
- if val == '0' && no
1507
- flag = "no-#{flag}"
1508
- val = nil
1499
+ if val == '0' && no
1500
+ flag = "no-#{flag}"
1501
+ val = nil
1502
+ end
1503
+ ret << shell_option(flag, equals ? val : nil, escape: escape, quote: quote, force: force)
1509
1504
  end
1510
- ret << shell_option(flag, equals ? val : nil, escape: escape, quote: quote, force: force)
1505
+ ret.each { |val| target << val } unless ret.empty?
1511
1506
  end
1512
- ret.each { |val| target << val } unless ret.empty?
1513
1507
  end
1514
1508
 
1515
1509
  def append_nocolor(target: @session)
@@ -1557,9 +1551,9 @@ module Squared
1557
1551
  end
1558
1552
 
1559
1553
  def collect_hash(data, pass: [])
1560
- ret = []
1561
- data.each { |key, val| ret.concat(val) unless pass.include?(key) }
1562
- ret
1554
+ [].tap do |ret|
1555
+ data.each { |key, val| ret.concat(val) unless pass.include?(key) }
1556
+ end
1563
1557
  end
1564
1558
 
1565
1559
  def parse_json(val, kind: Hash, hint: nil)
@@ -1572,15 +1566,6 @@ module Squared
1572
1566
  ret
1573
1567
  end
1574
1568
 
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
1569
  def param_guard(action, flag, args:, key: nil, pat: nil, values: nil)
1585
1570
  if args && key
1586
1571
  val = args.fetch(key, nil)
@@ -1595,7 +1580,7 @@ module Squared
1595
1580
  args
1596
1581
  end
1597
1582
 
1598
- def confirm_outdated(pkg, ver, rev, lock: false)
1583
+ def confirm_outdated(pkg, ver, rev, cur = nil, lock: false, col1: 0)
1599
1584
  a = sub_style(case rev
1600
1585
  when 1
1601
1586
  'MAJOR'
@@ -1603,11 +1588,11 @@ module Squared
1603
1588
  'MINOR'
1604
1589
  else
1605
1590
  'PATCH'
1606
- end, styles: theme[:header])
1607
- b = sub_style("#{pkg} #{ver}", styles: theme[:inline])
1608
- 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
1591
+ end, styles: (rev == 1 && theme[:major]) || theme[:header])
1592
+ b = sub_style(pkg.ljust(col1), styles: theme[:inline])
1593
+ c = lock ? sub_style((cur || 'locked').rjust(7), styles: color(:red)) : cur&.rjust(7)
1594
+ d = rev == 1 || lock ? 'N' : 'Y'
1595
+ confirm "#{a}: #{b}#{c} #{sub_style(ver.rjust(col1 > 0 ? 10 : 0), styles: theme[:inline])} ", d
1611
1596
  end
1612
1597
 
1613
1598
  def choice_index(msg, list, values: nil, accept: nil, series: false, trim: nil, column: nil,
@@ -1637,8 +1622,7 @@ module Squared
1637
1622
  end
1638
1623
  loop do
1639
1624
  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)
1625
+ c = confirm("#{item[0]}#{a ? " [#{hint}]" : ''}", item[2] ? 'Y' : 'N', timeout: 60)
1642
1626
  if item[1] == true
1643
1627
  ret << c
1644
1628
  elsif !c
@@ -1725,8 +1709,7 @@ module Squared
1725
1709
  end
1726
1710
 
1727
1711
  def semscan(val, fill: true)
1728
- ret = val.scan(SEM_VER).first
1729
- fill ? semver(ret) : ret
1712
+ val.scan(SEM_VER).first.yield_self { |data| fill ? semver(data) : data }
1730
1713
  end
1731
1714
 
1732
1715
  def indexitem(val)
@@ -1789,40 +1772,22 @@ module Squared
1789
1772
  end
1790
1773
  end
1791
1774
 
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
1775
+ def pwd_set(pass: false, from: nil)
1776
+ pass = semscan(pass).join <= RUBY_VERSION if pass.is_a?(String)
1777
+ pwd = Dir.pwd
1778
+ if (path.to_s == pwd || pass == true) && !workspace.jruby_win?
1779
+ ret = yield
1780
+ else
1823
1781
  Dir.chdir(path)
1824
- @pwd
1782
+ ret = yield
1783
+ Dir.chdir(pwd)
1825
1784
  end
1785
+ rescue StandardError => e
1786
+ log&.error e
1787
+ ret = on :error, from, e
1788
+ raise if exception && ret != true
1789
+ else
1790
+ ret
1826
1791
  end
1827
1792
 
1828
1793
  def run_set(cmd, val = nil, opts: nil, **)
@@ -1969,7 +1934,7 @@ module Squared
1969
1934
  unless @pass.include?(key.to_s) || ws.task_defined?(name, action) || ws.task_exclude?(action, self)
1970
1935
  ws.task_desc(@desc, action)
1971
1936
  task action do
1972
- __send__(key)
1937
+ __send__ key
1973
1938
  end
1974
1939
  end
1975
1940
  next if (items = @children.select { |item| item.task_include?(key) }).empty?
@@ -1981,8 +1946,9 @@ module Squared
1981
1946
  end
1982
1947
 
1983
1948
  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('..', ''))
1949
+ Pathname.new(val).cleanpath.yield_self do |file|
1950
+ file.absolute? ? file.to_s.start_with?(File.join(path, '')) : !file.to_s.start_with?(File.join('..', ''))
1951
+ end
1986
1952
  end
1987
1953
 
1988
1954
  def checkdir?(val)
@@ -2034,8 +2000,7 @@ module Squared
2034
2000
  return false if workspace.series.chain?(val = task_join(name, action))
2035
2001
  return true if task_invoked?(val) && (!task_invoked?(ac) || !workspace.task_defined?(ac, 'sync'))
2036
2002
 
2037
- val = workspace.series.name_get(action)
2038
- val != action && invoked_sync?(val)
2003
+ workspace.series.name_get(action).yield_self { |name| name != action && invoked_sync?(name) }
2039
2004
  end
2040
2005
 
2041
2006
  def success?(ret)
@@ -2082,7 +2047,7 @@ module Squared
2082
2047
  end
2083
2048
 
2084
2049
  def borderstyle
2085
- ((data = workspace.banner_get(*@ref, group: group)) && data[:border]) || theme[:border]
2050
+ workspace.banner_get(*@ref, group: group)&.border || theme[:border]
2086
2051
  end
2087
2052
 
2088
2053
  def headerstyle
@@ -2095,7 +2060,7 @@ module Squared
2095
2060
  end
2096
2061
 
2097
2062
  Application.implement(Base, base: true)
2098
- Application.attr_banner = Common::SymSet.new(%i[name project path ref group parent])
2063
+ Application.attr_banner = Set.new(%i[name project path ref group parent])
2099
2064
  end
2100
2065
  end
2101
2066
  end