squared 0.4.22 → 0.4.24

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4f67ab37dd0b66feaeb78631ac257ba860df78acba313f2e5fe2ffeb01136acf
4
- data.tar.gz: 8d0570c44cbdf41ba282b5c2fd9a0196b4c5678d595ca5774393b442b88eb854
3
+ metadata.gz: c07babae909a985bae708b8a2bec453b223d9889af828da70d990609e9966142
4
+ data.tar.gz: 5375a660bbcc0f49b5a3eaad5ab2740b103beeb3823a0d7b027b9005bf39faa9
5
5
  SHA512:
6
- metadata.gz: 01b00bf5afdd80a370ef363c0d546f76d8f2533474b25029fc37c9bb0bfb1b2104ea4aa78c38cb044cf8d2f194630496b6d1b48ad4d94e8be284b28dd5dfa03c
7
- data.tar.gz: 3968c3a15796f1c41939b95b4e50c8a8830f7f95fb6570a193c24c0043e259c82c6ac28571bd4cdbcddd2b77d6b47f38b55a963c3e567bad6e8e949a41ba8698
6
+ metadata.gz: 23cd1e57c7d0039fed851d6d426eec51022dba2c26bbce9faafddd20ded4aad3d00d6db023c3a99e2aa485aace597567df4f603130746daa5dc5e2d661c658dd
7
+ data.tar.gz: cb9556662d393d458413df3669f9859b4b3df9d9ca3e659b9098fac0d550349eaf8b414e6cb85b0828f522f3b78f1627c282350eb6b9b62218f76413ebcaabb8
data/CHANGELOG.md CHANGED
@@ -1,5 +1,32 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.4.24] - 2025-10-17
4
+
5
+ ### Added
6
+
7
+ - Repo task [init|all] can bypass dev? copy requirement with REPO_STAGE=4.
8
+
9
+ ### Changed
10
+
11
+ - Node command outdated does not check PNPM minimum version.
12
+
13
+ ### Fixed
14
+
15
+ - Project base rescue error handling used reversed parameters.
16
+ - Project absolute paths did not append wildcard with trailing slash.
17
+ - Powershell commands did not escape nested double quotes.
18
+ - OptionPartition did not strip flags without a value.
19
+ - Project base method add did not use parent context.
20
+ - Application property pipe did not parse numeric values.
21
+
22
+ ## [0.4.23] - 2025-10-11
23
+
24
+ ### Fixed
25
+
26
+ - Node task outdated did not compare wanted and latest by semver.
27
+ - Project base method append_hash did not have target when joined.
28
+ - Docker build for compose and bake was completely incapacitated.
29
+
3
30
  ## [0.4.22] - 2025-10-08
4
31
 
5
32
  ### Added
@@ -1010,6 +1037,8 @@
1010
1037
 
1011
1038
  - Changelog was created.
1012
1039
 
1040
+ [0.4.24]: https://github.com/anpham6/squared-ruby/releases/tag/v0.4.24
1041
+ [0.4.23]: https://github.com/anpham6/squared-ruby/releases/tag/v0.4.23
1013
1042
  [0.4.22]: https://github.com/anpham6/squared-ruby/releases/tag/v0.4.22
1014
1043
  [0.4.21]: https://github.com/anpham6/squared-ruby/releases/tag/v0.4.21
1015
1044
  [0.4.20]: https://github.com/anpham6/squared-ruby/releases/tag/v0.4.20
data/README.md CHANGED
@@ -723,7 +723,7 @@ REPO_SYNC # 0,1
723
723
  REPO_URL # manifest repository
724
724
  REPO_MANIFEST # e.g. latest,nightly,prod
725
725
  REPO_GROUPS # e.g. base,prod,docs
726
- REPO_STAGE # 0,1,2,3
726
+ REPO_STAGE # 0,1,2,3,4
727
727
  REPO_SUBMODULLES # 0,1
728
728
  REPO_TIMEOUT # confirm dialog (seconds)
729
729
  ```
@@ -178,8 +178,9 @@ module Squared
178
178
  args = args.map(&:to_s)
179
179
  if level.is_a?(::Numeric)
180
180
  if append && respond_to?(:log)
181
- ref = log rescue nil
182
- ref.add(level, message(subject, *args, hint: hint, space: ', ')) if ref.is_a?(Logger)
181
+ (log rescue nil).tap do |ref|
182
+ ref.add(level, message(subject, *args, hint: hint, space: ', ')) if ref.is_a?(Logger)
183
+ end
183
184
  end
184
185
  return false if !pass && level < ARG[:LEVEL]
185
186
  end
@@ -217,7 +218,8 @@ module Squared
217
218
  module_function
218
219
 
219
220
  def message(*args, hint: nil, empty: false, space: ARG[:SPACE])
220
- (empty ? args.reject { |val| val.nil? || val.empty? } : args).join(space) + (hint ? " (#{hint})" : '')
221
+ (empty ? args.reject { |val| val.nil? || (val.respond_to?(:empty?) && val.empty?) } : args)
222
+ .join(space) + (hint ? " (#{hint})" : '')
221
223
  end
222
224
 
223
225
  def emphasize(val, title: nil, footer: nil, right: false, cols: nil, sub: nil, pipe: nil,
@@ -16,15 +16,15 @@ module Squared
16
16
  elsif !r[3] || r[6]
17
17
  return val
18
18
  end
19
- if r[7].match?(/\A["']/)
20
- opt = "#{r[7]}#{r[7][0]}"
21
- elsif r[7].match?(/["']\z/)
22
- opt = "#{r[7][-1]}#{r[7]}"
23
- else
24
- return val unless r[7].match?(/\s/)
25
-
26
- opt = r[7]
27
- end
19
+ opt = if r[7].match?(/\A["']/)
20
+ "#{r[7]}#{r[7][0]}"
21
+ elsif r[7].match?(/["']\z/)
22
+ "#{r[7][-1]}#{r[7]}"
23
+ else
24
+ return val unless r[7].match?(/\s/)
25
+
26
+ r[7]
27
+ end
28
28
  r[1] + (data ? data[2] : r[2]) + r[4] + shell_quote(opt, double: double, force: force, override: override)
29
29
  elsif option && val =~ /\A([^=]+)=(.+)\z/m
30
30
  return val if $2.match?(/\A(["']).+\1\z/m)
@@ -65,15 +65,15 @@ module Squared
65
65
  escape = false
66
66
  override = true
67
67
  end
68
- if flag[0] == '-'
69
- b = flag[1] == '-' ? '=' : ' '
70
- elsif flag.size == 1
71
- a = '-'
72
- b = merge ? '' : ' '
73
- else
74
- a = '--'
75
- b = '='
76
- end
68
+ b = if flag[0] == '-'
69
+ flag[1] == '-' ? '=' : ' '
70
+ elsif flag.size == 1
71
+ a = '-'
72
+ merge ? '' : ' '
73
+ else
74
+ a = '--'
75
+ '='
76
+ end
77
77
  "#{a}#{flag}#{unless val.nil?
78
78
  "#{b}#{if escape
79
79
  shell_escape(val, quote: quote, double: double, override: override)
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Squared
4
- VERSION = '0.4.22'
4
+ VERSION = '0.4.24'
5
5
  end
@@ -140,7 +140,7 @@ module Squared
140
140
  return unless @pipe.is_a?(Pathname)
141
141
 
142
142
  msg = "Session started on #{Time.now} by #{@main}"
143
- bord = '#' * s.size
143
+ bord = '#' * msg.size
144
144
  puts bord, msg, bord
145
145
  end
146
146
 
@@ -2,7 +2,6 @@
2
2
 
3
3
  require 'json'
4
4
  require 'date'
5
- require 'time'
6
5
  require 'logger'
7
6
 
8
7
  module Squared
@@ -209,7 +208,7 @@ module Squared
209
208
  def initialize_env(dev: nil, prod: nil, **)
210
209
  @dev = env_match('BUILD', dev, suffix: 'DEV', strict: true)
211
210
  @prod = env_match('BUILD', prod, suffix: 'PROD', strict: true)
212
- unless @output[2] == false || !(val = env('BUILD', suffix: 'ENV'))
211
+ if (val = env('BUILD', suffix: 'ENV')) && @output[2] != false
213
212
  @output[2] = parse_json(val, hint: "BUILD_#{@envname}_ENV") || @output[2]
214
213
  end
215
214
  unless @output[0] == false || @output[0].is_a?(Array)
@@ -411,6 +410,7 @@ module Squared
411
410
  kwargs[:group] = group unless kwargs.key?(:group)
412
411
  kwargs[:ref] = ref unless kwargs.key?(:ref)
413
412
  parent = self
413
+ proj = nil
414
414
  name = case name
415
415
  when String, Symbol
416
416
  name.to_s
@@ -419,9 +419,10 @@ module Squared
419
419
  end
420
420
  workspace.add(path, name, **kwargs) do
421
421
  __send__ :parent_set, parent
422
- @children << self
422
+ proj = self
423
423
  instance_eval(&blk) if block_given?
424
424
  end
425
+ @children << proj
425
426
  self
426
427
  end
427
428
 
@@ -465,11 +466,11 @@ module Squared
465
466
  a, b, c, d, e = val
466
467
  case b
467
468
  when Hash
468
- b = append_hash(b, build: true).join(' ')
469
+ b = append_hash(b, target: [], build: true).join(' ')
469
470
  when Enumerable
470
471
  b = b.to_a.join(' ')
471
472
  end
472
- d = append_hash(d).join(' ') if d.is_a?(Hash)
473
+ d = append_hash(d, target: []).join(' ') if d.is_a?(Hash)
473
474
  if a
474
475
  cmd << [a, d, b].compact.join(' ')
475
476
  else
@@ -483,18 +484,18 @@ module Squared
483
484
  else
484
485
  cmd, opts, var, flags, extra = args
485
486
  end
486
- if cmd.is_a?(Proc) || cmd.is_a?(Method)
487
- run_b(cmd, sync: sync, from: from)
488
- return
489
- end
490
487
  if cmd
488
+ return run_b(cmd, sync: sync, from: from) if cmd.is_a?(Proc) || cmd.is_a?(Method)
489
+
491
490
  cmd = as_get(cmd, from)
492
491
  opts = compose(opts, script: false) if opts && respond_to?(:compose)
493
- flags = append_hash(flags).join(' ') if flags.is_a?(Hash)
492
+ flags = append_hash(flags, target: []).join(' ') if flags.is_a?(Hash)
494
493
  case opts
495
494
  when Hash
496
- opts = append_hash(opts, build: true)
497
- cmd = Array(cmd).push(flags).concat(opts).compact.join(' ')
495
+ cmd = Array(cmd).push(flags)
496
+ .concat(append_hash(opts, target: [], build: true))
497
+ .compact
498
+ .join(' ')
498
499
  when Enumerable
499
500
  cmd = Array(cmd).concat(opts.to_a)
500
501
  cmd.map! { |val| "#{val} #{flags}" } if flags
@@ -527,7 +528,7 @@ module Squared
527
528
  proj.__send__(meth, sync: sync)
528
529
  next
529
530
  rescue StandardError => e
530
- on_error(:prereqs, e, exception: true)
531
+ on_error(e, :prereqs, exception: true)
531
532
  end
532
533
  end
533
534
  print_error(name, 'method not found', subject: 'prereqs', hint: meth)
@@ -547,7 +548,7 @@ module Squared
547
548
  end
548
549
 
549
550
  def doc(*, sync: invoked_sync?('doc'), **)
550
- run_b(@doc, sync: sync, from: :doc, banner: from_base?('doc') ? verbosetype > 1 : verbose)
551
+ run_b(@doc, sync: sync, banner: verbosetype > (from_base?('doc') ? 1 : 0), from: :doc)
551
552
  end
552
553
 
553
554
  def lint(*, sync: invoked_sync?('lint'), **)
@@ -568,9 +569,9 @@ module Squared
568
569
  on :first, :clean unless pass
569
570
  case @clean
570
571
  when Struct
571
- if (any = instance_eval(&@clean.block) || @clean.run)
572
+ if (val = instance_eval(&@clean.block) || @clean.run)
572
573
  temp = @clean
573
- @clean = any
574
+ @clean = val
574
575
  clean(*args, sync: sync, pass: true, **kwargs)
575
576
  @clean = temp
576
577
  end
@@ -588,7 +589,7 @@ module Squared
588
589
  entry = basepath(val = val.to_s)
589
590
  if entry.directory? && val.match?(%r{[\\/]\z})
590
591
  log&.warn "rm -rf #{entry}"
591
- rm_rf(entry, verbose: verbose)
592
+ rm_rf(entry, verbose: verbosetype > 0)
592
593
  else
593
594
  log&.warn "rm #{entry}"
594
595
  (val.include?('*') ? Dir[entry] : [entry]).each do |file|
@@ -629,7 +630,7 @@ module Squared
629
630
  end
630
631
  ret = graph_branch(self, data, tasks, out, sync: sync, pass: pass)
631
632
  rescue StandardError => e
632
- on_error(:graph, e, exception: true)
633
+ on_error(e, :graph, exception: true)
633
634
  else
634
635
  if out
635
636
  [out, ret]
@@ -687,7 +688,7 @@ module Squared
687
688
  case f.content_type
688
689
  when 'application/zip'
689
690
  ext = 'zip'
690
- when 'application/x-gzip'
691
+ when %r{application/(?:x-)?gzip}
691
692
  ext = 'tgz'
692
693
  when 'application/x-xz'
693
694
  ext = 'txz'
@@ -749,9 +750,7 @@ module Squared
749
750
  break unless entry.directory?
750
751
 
751
752
  i = 0
752
- while (dest = target + "#{File.basename(file)}-#{i}").exist?
753
- i += 1
754
- end
753
+ i += 1 while (dest = target + "#{File.basename(file)}-#{i}").exist?
755
754
  FileUtils.mv(entry, dest)
756
755
  dest.children.each { |child| FileUtils.mv(child, target) }
757
756
  dest.rmdir
@@ -851,7 +850,7 @@ module Squared
851
850
  ret = shell(*args, chdir: chdir, exception: exception)
852
851
  end
853
852
  rescue StandardError => e
854
- on_error(from, e, exception: true)
853
+ on_error(e, from, exception: true)
855
854
  false
856
855
  else
857
856
  on :last, from
@@ -1267,11 +1266,11 @@ module Squared
1267
1266
  end
1268
1267
 
1269
1268
  def option(*args, target: @session, prefix: target&.first, **kwargs)
1270
- if prefix
1271
- args.each do |val|
1272
- ret = env(env_key(stripext(prefix), val), **kwargs)
1273
- return ret if ret
1274
- end
1269
+ return unless prefix
1270
+
1271
+ args.each do |val|
1272
+ ret = env(env_key(stripext(prefix), val), **kwargs)
1273
+ return ret if ret
1275
1274
  end
1276
1275
  nil
1277
1276
  end
@@ -1450,7 +1449,7 @@ module Squared
1450
1449
  opts.each { |val| target << shell_option(flag, val) }
1451
1450
  end
1452
1451
 
1453
- def append_hash(data, target: @session, build: false)
1452
+ def append_hash(data, target: @session || [], build: false)
1454
1453
  if build && (type = env('BUILD', suffix: 'TYPE') || ENV['BUILD_TYPE'])
1455
1454
  type = "__#{type}__"
1456
1455
  if (extra = data[type] || data[type.to_sym]).is_a?(Hash)
@@ -1553,7 +1552,7 @@ module Squared
1553
1552
  when String
1554
1553
  "#{base} #{data}"
1555
1554
  when Hash
1556
- "#{append_hash(base).join(' ')} #{data}"
1555
+ "#{append_hash(base, target: []).join(' ')} #{data}"
1557
1556
  when Enumerable
1558
1557
  "#{base.to_a.join(' ')} #{data}"
1559
1558
  else
@@ -1562,11 +1561,11 @@ module Squared
1562
1561
  when Hash
1563
1562
  case base
1564
1563
  when String
1565
- "#{base} #{append_hash(data).join(' ')}"
1564
+ "#{base} #{append_hash(data, target: []).join(' ')}"
1566
1565
  when Hash
1567
1566
  base.merge(data)
1568
1567
  when Enumerable
1569
- Set.new(base.to_a + append_hash(data)).to_a
1568
+ Set.new(base.to_a + append_hash(data, target: [])).to_a
1570
1569
  else
1571
1570
  data
1572
1571
  end
@@ -1575,7 +1574,7 @@ module Squared
1575
1574
  when String
1576
1575
  "#{base} #{data.to_a.join(' ')}"
1577
1576
  when Hash
1578
- "#{append_hash(base).join(' ')} #{data.to_a.join(' ')}"
1577
+ "#{append_hash(base, target: []).join(' ')} #{data.to_a.join(' ')}"
1579
1578
  when Enumerable
1580
1579
  Set.new(base.to_a + data.to_a).to_a
1581
1580
  else
@@ -1640,8 +1639,8 @@ module Squared
1640
1639
  confirm "Upgrade to #{a}? #{b + e} [#{c}] ", d
1641
1640
  end
1642
1641
 
1643
- def choice_index(msg, list, values: nil, accept: nil, series: false, trim: nil, column: nil,
1644
- multiple: false, force: true, **kwargs)
1642
+ def choice_index(msg, list, values: nil, accept: nil, series: false, trim: nil, column: nil, multiple: false,
1643
+ force: true, **kwargs)
1645
1644
  puts if !series && !printfirst?
1646
1645
  msg = "#{msg} (optional)" unless force
1647
1646
  unless (ret = choice(msg, list, multiple: multiple, force: force, **kwargs)) && !ret.empty?
@@ -1657,14 +1656,11 @@ module Squared
1657
1656
  if accept
1658
1657
  hint = Array(ret).map { |val| sub_style(val, styles: theme[:inline]) }.join(', ')
1659
1658
  accept = Array(accept).map { |val| Array(val) }
1660
- if accept.any? { |val| val[1] == true }
1661
- ret = [ret]
1662
- multiple = -1
1663
- end
1659
+ ret = Array(ret) if accept.any? { |val| val[1] == true }
1664
1660
  loop do
1665
1661
  item = accept.first
1666
1662
  d, e = item[2] ? ['Y', '[Y/n]'] : ['N', '[y/N]']
1667
- c = confirm("#{item[0]}#{a ? " [#{a}]" : ''} #{e} ", d, timeout: 60)
1663
+ c = confirm("#{item[0]}#{hint ? " [#{hint}]" : ''} #{e} ", d, timeout: 60)
1668
1664
  if item[1] == true
1669
1665
  ret << c
1670
1666
  elsif !c
@@ -1677,7 +1673,7 @@ module Squared
1677
1673
  exit 1 unless accept.empty?
1678
1674
  end
1679
1675
  if values
1680
- ret = [ret] unless accept && multiple == -1
1676
+ ret = Array(ret)
1681
1677
  values.each do |val|
1682
1678
  if val.is_a?(Array)
1683
1679
  val, force = val
@@ -1711,21 +1707,17 @@ module Squared
1711
1707
  end
1712
1708
 
1713
1709
  def command(*args)
1714
- if workspace.powershell?
1715
- "powershell.exe -Command \"& {#{args.join(' ; ')}}\""
1716
- else
1717
- args.join(' && ')
1718
- end
1710
+ return args.join(' && ') unless workspace.powershell?
1711
+
1712
+ "powershell.exe -Command #{shell_quote("& {#{args.join(' ; ')}}", option: false, double: true)}"
1719
1713
  end
1720
1714
 
1721
1715
  def relativepath(*list, all: false)
1722
1716
  return [] if list.empty?
1723
1717
 
1724
1718
  list.flatten.map! { |val| Pathname.new(val) }.select { |val| projectpath?(val) }.map! do |val|
1725
- val = val.absolute? ? val.relative_path_from(path).to_s : val.to_s
1726
- val = val[2..-1] if val.start_with?('./')
1727
- val = "#{val}*" if all && val.end_with?('/')
1728
- val
1719
+ ret = (val.absolute? ? val.relative_path_from(path) : val.cleanpath).to_s
1720
+ all && val.to_s.end_with?('/') ? "#{ret}/*" : ret
1729
1721
  end
1730
1722
  end
1731
1723
 
@@ -1810,8 +1802,7 @@ module Squared
1810
1802
  end
1811
1803
 
1812
1804
  def color(val)
1813
- ret = theme[val]
1814
- ret && !ret.empty? ? ret : [val]
1805
+ (ret = theme[val]) && !ret.empty? ? ret : [val]
1815
1806
  end
1816
1807
 
1817
1808
  def colormap(val)
@@ -2040,8 +2031,8 @@ module Squared
2040
2031
  end
2041
2032
 
2042
2033
  def projectpath?(val)
2043
- val = Pathname.new(val).cleanpath
2044
- val.absolute? ? val.to_s.start_with?(File.join(path, '')) : !val.to_s.start_with?(File.join('..', ''))
2034
+ ret = Pathname.new(val).cleanpath
2035
+ ret.absolute? ? ret.to_s.start_with?(File.join(path, '')) : !ret.to_s.start_with?(File.join('..', ''))
2045
2036
  end
2046
2037
 
2047
2038
  def checkdir?(val)
@@ -113,7 +113,7 @@ module Squared
113
113
  return unless dockerfile(file).exist?
114
114
 
115
115
  @context = context
116
- @tag = tag || tagname("#{@project}:#{@version || 'latest'}")
116
+ self.tag = tag || tagname("#{@project}:#{@version || 'latest'}")
117
117
  @mounts = mounts
118
118
  @secrets = secrets
119
119
  @registry = tagjoin registry, kwargs[:username]
@@ -206,7 +206,7 @@ module Squared
206
206
  end
207
207
  end
208
208
  else
209
- format_desc(action, flag, 'opts*,id/name', after: flag == :update ? '+' : '*')
209
+ format_desc action, flag, "opts*,id/name#{flag == :update ? '+' : '*'}"
210
210
  task flag do |_, args|
211
211
  container flag, args.to_a
212
212
  end
@@ -264,11 +264,11 @@ module Squared
264
264
  ret = docker_session
265
265
  if from == :run
266
266
  if bake?(n = filetype)
267
- ret << 'buildx' << 'bake'
267
+ ret << 'buildx bake'
268
268
  append_file n
269
269
  from = :bake
270
270
  elsif compose?(n)
271
- ret << 'compose' << 'build'
271
+ ret << 'compose build'
272
272
  append_file n
273
273
  from = :compose
274
274
  else
@@ -281,7 +281,7 @@ module Squared
281
281
  when String
282
282
  ret << opts
283
283
  when Hash
284
- ret.merge(append_hash(opts, build: true))
284
+ ret.merge(append_hash(opts, target: [], build: true))
285
285
  when Enumerable
286
286
  ret.merge(opts.to_a)
287
287
  end
@@ -522,7 +522,7 @@ module Squared
522
522
  list_image(flag, docker_output('image ls -a'), from: from) do |val|
523
523
  op << val
524
524
  if flag == :tag
525
- op << tagname("#{@project}:#{op.first}")
525
+ op << tagname("#{project}:#{op.first}")
526
526
  break
527
527
  end
528
528
  end
@@ -622,7 +622,7 @@ module Squared
622
622
  target << list.join(' && ') unless list.empty?
623
623
  end
624
624
 
625
- def append_file(type, target: @session)
625
+ def append_file(type, target: @session, index: 2)
626
626
  return if !@file || (ENV['COMPOSE_FILE'] && compose?(type))
627
627
 
628
628
  unless @file.is_a?(Array)
@@ -635,10 +635,10 @@ module Squared
635
635
  end
636
636
  files = Array(@file).map { |val| quote_option('file', basepath(val)) }
637
637
  if target.is_a?(Set)
638
- opts = target.to_a.insert(2, *files)
638
+ opts = target.to_a.insert(index, *files)
639
639
  target.clear.merge(opts)
640
640
  else
641
- target.insert(2, *files)
641
+ target.insert(index, *files)
642
642
  end
643
643
  end
644
644
 
@@ -653,7 +653,7 @@ module Squared
653
653
  ver = option('version', target: target, ignore: false)
654
654
  list = case val
655
655
  when String
656
- val.split(',')
656
+ split_escape val
657
657
  when Array
658
658
  val
659
659
  else
@@ -604,7 +604,7 @@ module Squared
604
604
  detach = args.detach
605
605
  commit = commithead args.commit
606
606
  end
607
- param_guard(action, flag, args: { create: create }, key: :create, pat: /\Ab\z/i) if create
607
+ param_guard(action, flag, args: { create: create }, key: :create, pat: /\A[Bb]\z/) if create
608
608
  else
609
609
  branch = choice_refs 'Choose a branch to switch'
610
610
  end
@@ -637,7 +637,7 @@ module Squared
637
637
  task flag, [:commit] do |_, args|
638
638
  commit = commithead args.commit
639
639
  unless commit
640
- commit, merge = choice_commit(values: ['Merge? [y|N]'])
640
+ commit, merge = choice_commit(values: ['Merge? [y/N]'])
641
641
  merge = merge&.upcase == 'Y'
642
642
  end
643
643
  checkout(flag, commit: commit, merge: merge)
@@ -721,7 +721,7 @@ module Squared
721
721
  task flag, [:name, :commit] do |_, args|
722
722
  branch = param_guard(action, flag, args: args, key: :name)
723
723
  commit = commithead args.commit
724
- commit, track = choice_commit(values: ['Track? [Y|n]'], force: false) if commit == ':'
724
+ commit, track = choice_commit(values: ['Track? [Y/n]'], force: false) if commit == ':'
725
725
  switch(flag, branch: branch, commit: commit, track: track)
726
726
  end
727
727
  when :detach
@@ -824,7 +824,7 @@ module Squared
824
824
  []
825
825
  else
826
826
  commit = choice_refs 'Choose "onto" branch'
827
- target, opts = choice_commit(multiple: 2, values: ['Options'], reflog: false)
827
+ target, opts = choice_commit(reflog: false, multiple: 2, values: ['Options'])
828
828
  branch, upstream = target
829
829
  OptionPartition.strip(opts)
830
830
  end
@@ -134,13 +134,13 @@ module Squared
134
134
  exact = true
135
135
  save = save[1..-1]
136
136
  end
137
- case save
138
- when 'prod', 'dev', 'optional', 'peer'
139
- packages = args.extras
140
- else
141
- save = 'prod'
142
- packages = args.to_a
143
- end
137
+ packages = case save
138
+ when 'prod', 'dev', 'optional', 'peer'
139
+ args.extras
140
+ else
141
+ save = 'prod'
142
+ args.to_a
143
+ end
144
144
  param_guard(action, 'name', args: packages)
145
145
  depend(:add, packages: packages, save: save, exact: exact)
146
146
  end
@@ -366,7 +366,7 @@ module Squared
366
366
  subdir << target.to_s
367
367
  end
368
368
  begin
369
- FileUtils.cp(basepath(s), dest, verbose: verbose.is_a?(Numeric) && verbose > 0)
369
+ FileUtils.cp(basepath(s), dest, verbose: verbosetype > 0)
370
370
  rescue StandardError => e
371
371
  print_error e
372
372
  errors += 1
@@ -410,7 +410,7 @@ module Squared
410
410
  target.each do |src, to|
411
411
  glob.each { |val| log.info "cp #{from + val} #{to}" }
412
412
  begin
413
- copy_dir(src, to, glob, create: create, link: link, force: force, pass: pass, verbose: verbose)
413
+ copy_dir(src, to, glob, create: create, link: link, force: force, pass: pass, verbose: verbosetype > 0)
414
414
  rescue StandardError => e
415
415
  on_error e, :copy
416
416
  end
@@ -482,7 +482,7 @@ module Squared
482
482
 
483
483
  def outdated(flag = nil, opts = [], sync: invoked_sync?('outdated', flag))
484
484
  dryrun = opts.include?('dry-run') || opts.include?('d')
485
- if pnpm? && read_packagemanager(version: '7.15', update: true)
485
+ if pnpm?
486
486
  cmd = session 'pnpm', 'outdated'
487
487
  dryrun ||= dryrun?('pnpm')
488
488
  else
@@ -527,7 +527,19 @@ module Squared
527
527
  next
528
528
  end
529
529
  current = val['current'] || file
530
- want = rev == :major && !latest[SEM_VER, 6] ? latest : val['wanted']
530
+ want = val['wanted']
531
+ unless latest[SEM_VER, 6]
532
+ case rev
533
+ when :major
534
+ want = latest
535
+ when :minor
536
+ want = latest if latest[SEM_VER, 1] == want[SEM_VER, 1]
537
+ when :patch
538
+ if (g = latest.match(SEM_VER)) && (h = want.match(SEM_VER)) && g[1] == h[1] && g[3] == h[3]
539
+ want = latest
540
+ end
541
+ end
542
+ end
531
543
  next unless (current != want || file != want) && (want.match?(SEM_VER) || !file.match?(SEM_VER))
532
544
 
533
545
  f = semscan file
@@ -845,7 +857,7 @@ module Squared
845
857
  when String
846
858
  target
847
859
  when Hash
848
- append_hash(target).join(' ')
860
+ append_hash(target, target: []).join(' ')
849
861
  when Enumerable
850
862
  target.to_a.join(' ')
851
863
  else
@@ -7,7 +7,7 @@ module Squared
7
7
  DEP_PYTHON = %w[poetry.lock setup.cfg pyproject.toml setup.py requirements.txt].freeze
8
8
  DIR_PYTHON = (DEP_PYTHON + %w[README.rst]).freeze
9
9
  OPT_PYTHON = {
10
- common: %w[b B d E h i I O OO P q s S u v x c=q m=b W=b X=q check-hash-based-pycs=b].freeze,
10
+ common: %w[b B d E h i I O P q s S u v x c=q m=b W=b X=q check-hash-based-pycs=b].freeze,
11
11
  build: %w[n|no-isolation s|sdist x|skip-dependency-check v|verbose w|wheel C|config-setting=q installer=b
12
12
  o|outdir=p].freeze,
13
13
  venv: %w[clear copies symlinks system-site-packages upgrade upgrade-deps without-scm-ignore-files without-pip
@@ -614,7 +614,7 @@ module Squared
614
614
  def python_session(*cmd, opts: nil)
615
615
  return session('python', *preopts(quiet: false), *cmd, path: venv.nil?) unless opts
616
616
 
617
- op = OptionPartition.new(opts, OPT_PYTHON[:common], project: self, single: /\Av+\z/)
617
+ op = OptionPartition.new(opts, OPT_PYTHON[:common], project: self, single: /\A(?:v+|OO)\z/)
618
618
  ret = session('python', *op.to_a, *cmd, path: venv.nil?)
619
619
  [ret, op.extras]
620
620
  end
@@ -874,7 +874,7 @@ module Squared
874
874
  op = OptionPartition.new(opts, OPT_PYTHON[:venv], cmd, project: self)
875
875
  op.append(dir, delim: true)
876
876
  .clear(pass: false)
877
- status = op.arg?(/\A-v+\z/, 'verbose')
877
+ status = op.arg?(/\A-v+\z/)
878
878
  run(op, env, exception: true, banner: banner)
879
879
  puts(dir.directory? ? "Success: #{dir}" : 'Failed') if banner && !status
880
880
  end
@@ -312,7 +312,7 @@ module Squared
312
312
  c = glob[i] || glob.first
313
313
  log.info "cp #{a + c} #{b}"
314
314
  begin
315
- copy_dir(a, b, c, pass: pass, verbose: verbose)
315
+ copy_dir(a, b, c, pass: pass, verbose: verbosetype > 0)
316
316
  rescue StandardError => e
317
317
  on_error e, :copy
318
318
  end
@@ -10,9 +10,10 @@ module Squared
10
10
  include Common::Shell
11
11
  extend Forwardable
12
12
 
13
+ OPT_NAME = /\A(?:(--)|-)((?(1)[A-Za-z\d]+|[A-Za-z\d]))\z/
13
14
  OPT_VALUE = /\A-{0,2}([^= ]+)(?: *= *| +)(.+)\z/
14
15
  OPT_SINGLE = /\A-([A-Za-z\d])(.+)\z/
15
- private_constant :OPT_VALUE, :OPT_SINGLE
16
+ private_constant :OPT_NAME, :OPT_VALUE, :OPT_SINGLE
16
17
 
17
18
  class << self
18
19
  include Common::Format
@@ -70,14 +71,14 @@ module Squared
70
71
  def strip(val)
71
72
  return [] unless val
72
73
 
73
- val = shell_split(val) if val.is_a?(String)
74
- val.map { |s| s.sub(OPT_SINGLE, '\1=\2').sub(OPT_VALUE, '\1=\2') }.reject(&:empty?)
74
+ val = shell_split val if val.is_a?(String)
75
+ val.map { |s| s.sub(OPT_SINGLE, '\1=\2').sub(OPT_VALUE, '\1=\2').sub(OPT_NAME, '\2') }.reject(&:empty?)
75
76
  end
76
77
 
77
78
  def select(list, bare: true, no: true, single: false, double: false)
78
79
  ret = bare ? list.grep_v(/=/) : list.grep(/=/).map! { |val| val.split('=', 2).first }
79
80
  ret.map! { |val| val.split('|', 2).last }
80
- ret = ret.grep_v(/^no-/) unless no
81
+ ret = ret.grep_v(/\Ano-/) unless no
81
82
  return ret if single == double
82
83
 
83
84
  ret.select { |val| single ? val.size == 1 : val.size > 1 }
@@ -132,19 +132,20 @@ module Squared
132
132
  task 'all' do |_, args|
133
133
  stage ||= 'all'
134
134
  ns['sync'].invoke(*args.to_a)
135
- next if env('REPO_STAGE', equals: '1')
135
+ next if (stage = env('REPO_STAGE')) == '1'
136
136
 
137
137
  @project.select do |_, proj|
138
138
  next unless proj.enabled?(proj.workspace.baseref)
139
139
 
140
140
  proj.depend(sync: true) if proj.depend?
141
- next if env('REPO_STAGE', equals: '2')
141
+ next if stage == '2'
142
142
 
143
143
  proj.build?
144
144
  end
145
145
  .each_value do |proj|
146
146
  proj.build(sync: true)
147
- next unless proj.dev? && proj.copy? && !env('REPO_STAGE', equals: '3')
147
+ next if stage == '3'
148
+ next unless proj.copy? && (proj.dev? || stage == '4')
148
149
 
149
150
  if (ws = proj.workspace).task_defined?(target = task_join(proj.name, 'copy'))
150
151
  task_invoke(target, **ws.invokeargs)
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: squared
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.22
4
+ version: 0.4.24
5
5
  platform: ruby
6
6
  authors:
7
7
  - An Pham
@@ -125,7 +125,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
125
125
  - !ruby/object:Gem::Version
126
126
  version: '0'
127
127
  requirements: []
128
- rubygems_version: 3.7.2
128
+ rubygems_version: 3.6.9
129
129
  specification_version: 4
130
130
  summary: Rake task generator for managing multi-language workspaces.
131
131
  test_files: []