squared 0.5.24 → 0.5.26

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: '028d4b5e86e6d05c09f73ecab333c5332dc87e6a4fc9491965eb5ed51f34499e'
4
- data.tar.gz: 464d5a95488fafbcc13f0569ccc31d80732e5181572627ca02bd58ec040819c3
3
+ metadata.gz: 4b8f593f81759da39eb42e2644e8947ed5d7ce8ff45410507c4432384ec63cc2
4
+ data.tar.gz: c914a1fec5afe22e057b48f7ec4e08107222fe68364a2dfa6124c94fa03946ef
5
5
  SHA512:
6
- metadata.gz: 25457fbc4821b604ccbe49e7ac6dbcdd677996ead1d39a089e8f745a7ee2d94215c065c54aa7abb9335c04cb72dc73832ca209cb8e8bda6dc9979f84dcda66c5
7
- data.tar.gz: 10e04c8c835b34ec1bb2f34e14a4f4ac25551b89ee7f1bd07cdd9d3503f87d3fff1980073ac6142a37c184d05e704a6b0d8608d50023f94511db197d2a659e83
6
+ metadata.gz: 4a8812a2ebae08ff07d54bab680e234d06ecc466877b493d6e2e037b0154e7350a9e77fdf2ab8a2227d2c8ddc9de1ca51f20a2ee2ef2c75e9db6314b0ab53c52
7
+ data.tar.gz: 0be6c80075ba5e49b92d09660fd8a6ac4c595d9eec7cf577c81ac55162042aac55f0b2b127d4a792dac819181e7f0ef69cf8501b95eb4848901e2d07d4aba4e6
data/CHANGELOG.md CHANGED
@@ -1,5 +1,45 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.5.26] - 2026-09-04
4
+
5
+ ### Fixed
6
+
7
+ - Node command nvm did not quote executable path.
8
+
9
+ ## [0.4.41] - 2026-09-04
10
+
11
+ ### Added
12
+
13
+ - Common base argument SUCCESS for command confirmation was created.
14
+
15
+ ### Changed
16
+
17
+ - Program options prefer using quotes instead of escape.
18
+ - Docker container run arguments with a leading dash are concatenated.
19
+
20
+ ### Fixed
21
+
22
+ - Common prompt method choice did not grep list items.
23
+ - OptionPartition static method strip did not parse flags with dashes.
24
+ - Project base method choice_index did not support multiple selections.
25
+
26
+ ## [0.5.25] - 2026-07-04
27
+
28
+ ### Fixed
29
+
30
+ - See `0.4.39`.
31
+
32
+ ## [0.4.39] - 2026-07-04
33
+
34
+ ### Changed
35
+
36
+ - Common global argument OUT with a file separator overrides PIPE.
37
+
38
+ ### Fixed
39
+
40
+ - Git output list results did not hide footer when banner was disabled.
41
+ - Project banners which were empty were being printed.
42
+
3
43
  ## [0.5.24] - 2026-06-14
4
44
 
5
45
  ### Fixed
@@ -1420,6 +1460,8 @@
1420
1460
 
1421
1461
  - Changelog was created.
1422
1462
 
1463
+ [0.5.26]: https://github.com/anpham6/squared-ruby/releases/tag/v0.5.26
1464
+ [0.5.25]: https://github.com/anpham6/squared-ruby/releases/tag/v0.5.25
1423
1465
  [0.5.24]: https://github.com/anpham6/squared-ruby/releases/tag/v0.5.24
1424
1466
  [0.5.23]: https://github.com/anpham6/squared-ruby/releases/tag/v0.5.23
1425
1467
  [0.5.22]: https://github.com/anpham6/squared-ruby/releases/tag/v0.5.22
@@ -1445,6 +1487,9 @@
1445
1487
  [0.5.2]: https://github.com/anpham6/squared-ruby/releases/tag/v0.5.2-ruby
1446
1488
  [0.5.1]: https://github.com/anpham6/squared-ruby/releases/tag/v0.5.1-ruby
1447
1489
  [0.5.0]: https://github.com/anpham6/squared-ruby/releases/tag/v0.5.0-ruby
1490
+ [0.4.41]: https://github.com/anpham6/squared-ruby/releases/tag/v0.4.41
1491
+ [0.4.40]: https://github.com/anpham6/squared-ruby/releases/tag/v0.4.40
1492
+ [0.4.39]: https://github.com/anpham6/squared-ruby/releases/tag/v0.4.39
1448
1493
  [0.4.38]: https://github.com/anpham6/squared-ruby/releases/tag/v0.4.38
1449
1494
  [0.4.37]: https://github.com/anpham6/squared-ruby/releases/tag/v0.4.37
1450
1495
  [0.4.36]: https://github.com/anpham6/squared-ruby/releases/tag/v0.4.36
@@ -14,6 +14,7 @@ module Squared
14
14
  CHOICE: 25,
15
15
  QUOTE: "'",
16
16
  SPACE: ' => ',
17
+ SUCCESS: 'Success',
17
18
  GRAPH: ['|', '-', '|', '\\', '-'].freeze,
18
19
  BORDER: ['|', '-', '-', '-', '-', '-', '|', '|', '-', '-'].freeze,
19
20
  VIEW: 'view',
@@ -90,6 +91,13 @@ module Squared
90
91
  VAR[key.is_a?(::String) ? key.to_sym : key] = val
91
92
  end
92
93
 
94
+ def __arg__(key, name = nil, &blk)
95
+ ret = ARG[key.to_sym]
96
+ return ret unless name && ret.is_a?(::Hash)
97
+
98
+ ret[name = name.downcase] || (block_given? ? ret.fetch(name.to_sym, &blk) : ret[name.to_sym])
99
+ end
100
+
93
101
  def __freeze__
94
102
  PATH.freeze
95
103
  ARG.freeze
@@ -60,7 +60,7 @@ module Squared
60
60
  end}] "
61
61
  end
62
62
  end
63
- valid = ->(s) { s.match?(/^\d+$/) && s.to_i.between?(min, max) }
63
+ valid = ->(s) { s.match?(/^-?\d+$/) && s.to_i.between?(min, max <= min ? Float::INFINITY : max) }
64
64
  Timeout.timeout(timeout) do
65
65
  while (ch = Readline.readline(msg))
66
66
  unless (ch = ch.strip).empty?
@@ -113,7 +113,7 @@ module Squared
113
113
  end
114
114
 
115
115
  def env_key(*val)
116
- val.join('_').gsub(/\W+/, '_').upcase
116
+ val.join('_').sub(/\A\d+\W*/, '__').gsub(/\W+/, '_').upcase
117
117
  end
118
118
 
119
119
  def env_value(key, default = '', suffix: nil, strict: false)
@@ -150,11 +150,19 @@ module Squared
150
150
  end
151
151
 
152
152
  def env_pipe(key, default = 1, suffix: nil, strict: false, root: nil)
153
+ out = 1
153
154
  case key
154
155
  when ::String
155
156
  case (ret = env_value(key, suffix: suffix, strict: strict))
156
157
  when '0', '1', '2'
157
158
  return ret.to_i
159
+ else
160
+ out = default if default.is_a?(::Numeric)
161
+ if ret.include?(File::SEPARATOR)
162
+ default = ret
163
+ elsif key.include?(File::SEPARATOR)
164
+ default = key
165
+ end
158
166
  end
159
167
  when ::Numeric
160
168
  return key if key.between?(0, 2)
@@ -165,7 +173,7 @@ module Squared
165
173
  (root ? Pathname.new(root) + default : Pathname.new(default)).realdirpath
166
174
  rescue StandardError => e
167
175
  warn e
168
- 1
176
+ out
169
177
  end
170
178
  end
171
179
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Squared
4
- VERSION = '0.5.24'
4
+ VERSION = '0.5.26'
5
5
  end
@@ -95,7 +95,13 @@ module Squared
95
95
  @kind = Support.hashlist
96
96
  @extensions = []
97
97
  @envname = env_key(@main).freeze
98
- @pipe = $DEBUG ? 2 : env_pipe(pipe, (ARG[:OUT] && env(ARG[:OUT])) || 1, root: @home)
98
+ @pipe = if $DEBUG
99
+ 2
100
+ elsif (out = ARG[:OUT]) && out.include?(File::SEPARATOR)
101
+ env_pipe(out, pipe, root: home)
102
+ else
103
+ env_pipe(pipe, (out && env(out)) || 1, root: home)
104
+ end
99
105
  @exception = env_bool exception
100
106
  @verbose = if $VERBOSE.nil?
101
107
  false
@@ -1303,7 +1303,7 @@ module Squared
1303
1303
  def env(key, default = nil, suffix: nil, equals: nil, ignore: nil, strict: false)
1304
1304
  a = "#{key}_#{@envname}"
1305
1305
  ret = if suffix
1306
- ENV.fetch("#{a}_#{suffix}", '')
1306
+ ENV["#{a}_#{suffix}"] || (ignore == false && ENV["#{key}_#{suffix}"]) || ''
1307
1307
  elsif strict
1308
1308
  ENV[a].to_s
1309
1309
  else
@@ -1367,7 +1367,7 @@ module Squared
1367
1367
  end
1368
1368
 
1369
1369
  def print_success(*)
1370
- puts 'Success'
1370
+ puts ARG[:SUCCESS]
1371
1371
  end
1372
1372
 
1373
1373
  def print_error(*args, loglevel: Logger::WARN, **kwargs)
@@ -1379,7 +1379,7 @@ module Squared
1379
1379
  def print_item(*val, series: true)
1380
1380
  puts unless printfirst?
1381
1381
  printsucc if series
1382
- puts val unless val.empty? || (val.size == 1 && val.first.nil?)
1382
+ puts val unless val.empty? || (val.size == 1 && (!val.first || val.first.empty?))
1383
1383
  end
1384
1384
 
1385
1385
  def print_banner(*lines, client: false, styles: theme[:banner], border: borderstyle, **)
@@ -1531,7 +1531,7 @@ module Squared
1531
1531
  end
1532
1532
 
1533
1533
  def append_hash(data, target: @session || [], build: false)
1534
- if build && (type = env('BUILD', suffix: 'TYPE') || ENV['BUILD_TYPE'])
1534
+ if build && (type = env('BUILD', suffix: 'TYPE', ignore: false))
1535
1535
  type = "__#{type}__"
1536
1536
  if (extra = data[type] || data[type.to_sym]).is_a?(Hash)
1537
1537
  data = data.merge(extra)
@@ -1740,7 +1740,10 @@ module Squared
1740
1740
  if accept
1741
1741
  hint = Array(ret).map { |val| sub_style(val, styles: theme[:inline]) }.join(', ')
1742
1742
  accept = Array(accept).map { |val| Array(val) }
1743
- ret = Array(ret) if accept.any? { |val| val[1] == true }
1743
+ if accept.any? { |val| val[1] == true }
1744
+ ret = [ret]
1745
+ multiple = -1
1746
+ end
1744
1747
  loop do
1745
1748
  item = accept.first
1746
1749
  c = confirm("#{item[0]}#{hint ? " [#{hint}]" : ''}", item[2] ? 'Y' : 'N', timeout: 60)
@@ -1756,7 +1759,7 @@ module Squared
1756
1759
  exit 1 unless accept.empty?
1757
1760
  end
1758
1761
  if values
1759
- ret = Array(ret)
1762
+ ret = [ret] unless accept && multiple == -1
1760
1763
  Array(values).each do |val|
1761
1764
  if val.is_a?(Array)
1762
1765
  val, force = val
@@ -1815,12 +1818,16 @@ module Squared
1815
1818
 
1816
1819
  def matchmap(list, prefix = nil)
1817
1820
  list.map do |val|
1818
- if val.is_a?(Regexp)
1819
- val
1820
- else
1821
- val = ".*#{val}" if prefix && !val.sub!(/\A(\^|\\A)/, '')
1822
- Regexp.new("#{prefix}#{val == '*' ? '.+' : val}")
1821
+ next val if val.is_a?(Regexp)
1822
+
1823
+ if prefix
1824
+ a = nil
1825
+ (val = val.dup).sub!(/\A(\^|\\A)/) do |s|
1826
+ a = s
1827
+ nil
1828
+ end
1823
1829
  end
1830
+ Regexp.new("#{a}#{prefix}#{val == '*' ? '.+' : val}")
1824
1831
  end
1825
1832
  end
1826
1833
 
@@ -21,13 +21,13 @@ module Squared
21
21
  }.freeze,
22
22
  compose: {
23
23
  common: %w[all-resources compatibility dry-run ansi=b env-file=p f|file=p parallel=n profile=b progress=b
24
- project-directory=p p|project-name=e].freeze,
24
+ project-directory=p p|project-name=b].freeze,
25
25
  build: %w[check no-cache print pull push with-dependencies q|quiet build-arg=qq builder=b m|memory=b
26
26
  provenance=q sbom=q ssh=qq].freeze,
27
- exec: %w[d|detach privileged e|env=qq index=i T|no-TTY=b? user=e w|workdir=q].freeze,
27
+ exec: %w[d|detach privileged e|env=qq index=i T|no-tty=!? user=b w|workdir=q].freeze,
28
28
  run: %w[build d|detach no-deps q|quiet quiet-build quiet-pull remove-orphans rm P|service-ports use-aliases
29
29
  cap-add=b cap-drop=b entrypoint=q e|env=qq env-from-file=p i|interactive=b? l|label=q name=b
30
- T|no-TTY=b? p|publish=q pull=b u|user=e v|volume=q w|workdir=q].freeze,
30
+ T|no-tty=!? p|publish=q pull=b u|user=b v|volume=qq w|workdir=q].freeze,
31
31
  up: %w[abort-on-container-exit abort-on-container-failure always-recreate-deps attach-dependencies build
32
32
  d|detach force-recreate menu no-build no-color no-deps no-log-prefix no-recreate no-start quiet-build
33
33
  quiet-pull remove-orphans V|renew-anon-volumes timestamps wait w|watch y|yes attach=b
@@ -36,9 +36,9 @@ module Squared
36
36
  }.freeze,
37
37
  container: {
38
38
  create: %w[init i|interactive no-healthcheck oom-kill-disable privileged P|publish-all q|quiet read-only
39
- rm t|tty use-api-socket add-host=q annotation=q a|attach=b blkio-weight=i blkio-weight-device=i
40
- cap-add=b cap-drop=b cgroup-parent=b cgroupns=b cidfile=p device=q device-cgroup-rule=q
41
- device-read-bps=q device-read-iops=q device-write-bps=q device-write-iops=q
39
+ rm t|tty=!? use-api-socket add-host=q annotation=q a|attach=b blkio-weight=i
40
+ blkio-weight-device=i cap-add=b cap-drop=b cgroup-parent=b cgroupns=b cidfile=p device=q
41
+ device-cgroup-rule=q device-read-bps=q device-read-iops=q device-write-bps=q device-write-iops=q
42
42
  disable-content-trust=b? dns=q dns-option=q dns-search=q domainname=b entrypoint=q e|env=qq
43
43
  env-file=p expose=q gpus=q group-add=b health-cmd=q health-interval=b health-retries=i
44
44
  health-start-interval=q health-start-period=q health-timeout=q hostname=q io-maxbandwidth=b
@@ -47,13 +47,14 @@ module Squared
47
47
  memory-swap=n memory-swappiness=n mount=qq name=b network=b network-alias=b oom-score-adj=b
48
48
  pid=b pids-limit=n platform=q p|publish=q pull=b restart=b runtime=b security-opt=q shm-size=b
49
49
  stop-signal=b stop-timeout=i storage-opt=q sysctl=q tmpfs=q ulimit=q u|user=b userns=b uts=b
50
- v|volume=q volume-driver=b volumes-from=b w|workdir=q].freeze,
50
+ v|volume=qq volume-driver=b volumes-from=b w|workdir=q].freeze,
51
51
  run: %w[d|detach detach-keys=q sig-proxy=b?].freeze,
52
52
  update: %w[blkio-weight=i cpu-period=i cpu-quota=i cpu-rt-period=i cpu-rt-runtime=i c|cpu-shares=i cpus=f
53
53
  cpuset-cpus=b cpuset-mems=b m|memory=b memory-reservation=b memory-swap=b pids-limit=n
54
54
  restart=q].freeze,
55
- exec: %w[d|detach i|interactive privileged t|tty detach-keys=q e|env=qq env-file=p user=e
55
+ exec: %w[d|detach i|interactive privileged t|tty=!? detach-keys=q e|env=qq env-file=p user=b
56
56
  w|workdir=q].freeze,
57
+ rm: %w[f|force l|link v|volumes].freeze,
57
58
  commit: %w[a|author=q c|change=q m|message=q pause=b?].freeze,
58
59
  inspect: %w[s|size f|format=q type=b].freeze,
59
60
  start: %w[a|attach i|interactive detach-keys=q].freeze,
@@ -207,7 +208,7 @@ module Squared
207
208
  end
208
209
  end
209
210
  else
210
- format_desc action, flag, "opts*,id/name#{flag == :update ? '+' : '*'}"
211
+ format_desc action, flag, "opts*,id/name#{flag == :update || flag == :inspect ? '+' : '*'}"
211
212
  task flag do |_, args|
212
213
  container flag, args.to_a
213
214
  end
@@ -416,7 +417,7 @@ module Squared
416
417
  end
417
418
  end
418
419
  append_command(flag, id || tagmain, op.extras)
419
- when :update
420
+ when :update, :inspect
420
421
  raise_error('missing container', hint: flag) if op.empty?
421
422
  op.append(escape: true, strip: /^:/)
422
423
  when :commit
@@ -633,8 +634,22 @@ module Squared
633
634
  when :exec
634
635
  raise_error('no command args', hint: flag) if list.empty?
635
636
  end
636
- target << val << list.shift
637
- target << list.join(' && ') unless list.empty?
637
+ target << val
638
+ case list.first
639
+ when '--'
640
+ target.merge(list.drop(1))
641
+ when /\A(--|&&)(\s|\z)/
642
+ target.merge(list)
643
+ else
644
+ target << list.shift
645
+ unless list.empty?
646
+ if list.first.start_with?('-')
647
+ target.merge(list)
648
+ else
649
+ target << list.join(' && ')
650
+ end
651
+ end
652
+ end
638
653
  end
639
654
 
640
655
  def append_file(type, target: @session, index: 2)
@@ -810,7 +825,7 @@ module Squared
810
825
  end
811
826
  cmd.merge(Array(out).map! { |val| parse.call(val) })
812
827
  cmd << args
813
- print_success if success?(run(cmd), ctx.start_with?(/network|tag|save/))
828
+ print_success if success?(run(cmd, { 'NO_COLOR' => 'true' }), ctx.start_with?(/network|tag|save/))
814
829
  end
815
830
  end
816
831
 
@@ -133,7 +133,6 @@ module Squared
133
133
  end
134
134
  File.write(@revfile, JSON.pretty_generate(@revdoc))
135
135
  rescue StandardError => e
136
- log&.debug e
137
136
  warn log_message(Logger::WARN, e, pass: true) if warning
138
137
  ensure
139
138
  @revlock = false
@@ -174,7 +173,7 @@ module Squared
174
173
  fetch: {
175
174
  base: %w[multiple porcelain progress P|prune-tags refetch stdin u|update-head-ok
176
175
  recurse-submodules-default=b].freeze,
177
- pull: %w[4 6 n t a|append atomic dry-run f|force k|keep negotiate-only prefetch p|prune q|quiet
176
+ pull: %w[n t 4|ipv4 6|ipv6 a|append atomic dry-run f|force k|keep negotiate-only prefetch p|prune q|quiet
178
177
  set-upstream unshallow update-shallow v|verbose deepen=i depth=i j|jobs=i negotiation-tip=q
179
178
  recurse-submodules=v refmap=q o|server-option=q shallow-exclude=b shallow-since=v
180
179
  upload-pack=q].freeze
@@ -210,7 +209,7 @@ module Squared
210
209
  ita-invisible-in-index minimal name-only name-status no-color-moved-ws no-prefix no-renames numstat
211
210
  patch-with-raw patch-with-stat patience pickaxe-all pickaxe-regex raw shortstat summary a|text
212
211
  abbrev=i? anchored=q break-rewrites=b? color=b color-moved=b color-moved-ws=b color-words=q?
213
- diff-algorithm=b diff-filter=e? X|dirstat=b? dirstat-by-file=b? dst-prefix=q find-copies=i?
212
+ diff-algorithm=b diff-filter=q? X|dirstat=b? dirstat-by-file=b? dst-prefix=q find-copies=i?
214
213
  find-object=b find-renames=b? ignore-matching-lines=q ignore-submodules=b? inter-hunk-context=i
215
214
  line-prefix=q output=p output-indicator-context=q output-indicator-new=q output-indicator-old=q
216
215
  relative=p rotate-to=p skip-to=p src-prefix=q stat=b? stat-count=i stat-width=i stat-name-width=i
@@ -266,7 +265,7 @@ module Squared
266
265
  checkout: %w[overwrite-ignore guess overlay progress recurse-submodules track].freeze,
267
266
  fetch: {
268
267
  base: %w[auto-gc auto-maintenance write-commit-graph write-fetch-head].freeze,
269
- pull: %w[all ipv4 ipv6 recurse-submodules show-forced-updates tags].freeze
268
+ pull: %w[all recurse-submodules show-forced-updates tags].freeze
270
269
  },
271
270
  log: {
272
271
  base: %w[decorate mailmap merges use-mailmap].freeze,
@@ -1139,7 +1138,7 @@ module Squared
1139
1138
  op.clear
1140
1139
  out, banner, from = source(io: true)
1141
1140
  print_item banner
1142
- list_result(write_lines(out), 'objects', from: from)
1141
+ list_result(write_lines(out), 'objects', banner: banner, from: from)
1143
1142
  return
1144
1143
  end
1145
1144
  else
@@ -1188,7 +1187,7 @@ module Squared
1188
1187
  end
1189
1188
  out, banner, from = source(io: true)
1190
1189
  ret = write_lines(out, banner: banner, sub: sub)
1191
- list_result(ret, 'files', from: from, action: 'modified')
1190
+ list_result(ret, 'files', action: 'modified', banner: banner, from: from)
1192
1191
  end
1193
1192
 
1194
1193
  def revbuild(flag = nil, opts = [], sync: nil, **kwargs)
@@ -1334,7 +1333,7 @@ module Squared
1334
1333
  out, banner, from = source(io: true)
1335
1334
  print_item banner
1336
1335
  ret = write_lines(out, grep: op.extras)
1337
- list_result(ret, 'tags', from: from, grep: op.extras)
1336
+ list_result(ret, 'tags', grep: op.extras, banner: banner, from: from)
1338
1337
  return
1339
1338
  end
1340
1339
  remote ||= option 'remote'
@@ -1577,7 +1576,7 @@ module Squared
1577
1576
  { pat: /^(\*\s+)(\S+)(.*)$/, styles: color(:green), index: 2 },
1578
1577
  { pat: %r{^(\s*)(remotes/\S+)(.*)$}, styles: color(:red), index: 2 }
1579
1578
  ])
1580
- list_result(ret, 'branches', from: from)
1579
+ list_result(ret, 'branches', banner: banner, from: from)
1581
1580
  return
1582
1581
  else
1583
1582
  if (head = git_spawn('rev-parse --abbrev-ref HEAD').chomp).empty?
@@ -1723,8 +1722,8 @@ module Squared
1723
1722
  op.add_quote(remote) if remote
1724
1723
  out, banner, from = source(io: true)
1725
1724
  print_item banner
1726
- ret = write_lines(out, grep: op.extras, prefix: "refs/#{flag}/")
1727
- list_result(ret, flag.to_s, from: from, grep: op.extras)
1725
+ ret = write_lines(out, grep: op.extras)
1726
+ list_result(ret, flag.to_s, grep: op.extras, banner: banner, from: from)
1728
1727
  end
1729
1728
 
1730
1729
  def ls_files(flag, opts = [])
@@ -1734,7 +1733,7 @@ module Squared
1734
1733
  out, banner, from = source(io: true)
1735
1734
  print_item banner
1736
1735
  ret = write_lines(out, grep: op.extras)
1737
- list_result(ret, 'files', from: from, grep: op.extras)
1736
+ list_result(ret, 'files', grep: op.extras, banner: banner, from: from)
1738
1737
  end
1739
1738
 
1740
1739
  def git(flag, opts = [])
@@ -1900,14 +1899,20 @@ module Squared
1900
1899
  ret += 1
1901
1900
  break if first
1902
1901
  end
1903
- print_item banner, out if banner && (ret > 0 || (!pass && !first))
1902
+ if banner && (ret > 0 || (!pass && !first))
1903
+ if banner.empty?
1904
+ print_item(*out)
1905
+ else
1906
+ print_item(banner, *out)
1907
+ end
1908
+ end
1904
1909
  ret
1905
1910
  end
1906
1911
 
1907
- def list_result(size, type, grep: [], action: 'found', from: nil)
1912
+ def list_result(size, type, action: 'found', grep: [], banner: nil, from: nil)
1908
1913
  if size == 0
1909
1914
  puts empty_status("No #{type} were #{action}", 'grep', grep.join(', '))
1910
- elsif stdout?
1915
+ elsif stdout? && (banner.nil? || (banner.is_a?(String) && !banner.empty?))
1911
1916
  styles = theme.fetch(:banner, []).reject { |s| s.to_s.end_with?('!') }
1912
1917
  styles << :bold if styles.size <= 1
1913
1918
  puts print_footer("#{size} #{size == 1 ? type.sub(/(?:(?<!l)e)?s\z/, '') : type}",
@@ -220,7 +220,7 @@ module Squared
220
220
  version = param_guard(action, 'version', args: args, key: :version)
221
221
  args = args.extras
222
222
  args << readline('Enter command', force: true) if args.empty?
223
- args.unshift(File.join(ENV['NVM_DIR'], 'nvm-exec'))
223
+ args.unshift(shell_quote(File.join(ENV['NVM_DIR'], 'nvm-exec')))
224
224
  run(args.join(' '), { 'NODE_VERSION' => version }, banner: false, from: :nvm)
225
225
  end
226
226
  when 'pack'
@@ -159,7 +159,7 @@ module Squared
159
159
  log.warn "run script #{n} of #{list.size} (out of range)"
160
160
  end
161
161
  else
162
- case index
162
+ case (index > 1 && poetry? ? 0 : index)
163
163
  when 0
164
164
  found |= 1
165
165
  run(session_output('poetry', 'run', val), from: :run)
@@ -558,7 +558,7 @@ module Squared
558
558
  case flag
559
559
  when :hatch, :twine
560
560
  if op.empty?
561
- op.push("#{dist.call}/*")
561
+ op.push(dist.call.join('*'))
562
562
  else
563
563
  op.map! { |val| basepath(val) }
564
564
  end
@@ -74,7 +74,25 @@ module Squared
74
74
  return [] unless val
75
75
 
76
76
  val = shell_split val if val.is_a?(String)
77
- val.map { |s| s.sub(OPT_SINGLE, '\1=\2').sub(OPT_VALUE, '\1=\2').sub(OPT_NAME, '\2') }.reject(&:empty?)
77
+ ret = []
78
+ pass = -1
79
+ (args = Array(val)).each_with_index do |s, i|
80
+ next if s.empty? || pass == i
81
+
82
+ if s == '--'
83
+ ret << s << args[i.succ..-1].join(' ')
84
+ break
85
+ end
86
+ next ret << s unless s.start_with?('-')
87
+
88
+ if !s.include?('=') && (j = args[i.succ]) && !j.start_with?('-')
89
+ ret << "#{s.sub(/^-{1,2}/, '')}=#{j}"
90
+ pass = i.succ
91
+ else
92
+ ret << s.sub(OPT_SINGLE, '\1=\2').sub(OPT_VALUE, '\1=\2').sub(OPT_NAME, '\2')
93
+ end
94
+ end
95
+ ret
78
96
  end
79
97
 
80
98
  def select(list, bare: true, no: true, single: false, double: false)
@@ -103,7 +121,11 @@ module Squared
103
121
  end
104
122
 
105
123
  def pattern?(val)
106
- val.match?(/(?:\A\^|\$\z)/) || val.match?(/(?:\.[*+]|\(\?:|\\[dsw]|\[.+\]|\{\d+,?\d*})/)
124
+ Regexp.new(val)
125
+ val.start_with?('\A', '^') || val.end_with?('\z', '$') ||
126
+ val.match?(/[.)][*+?]|\(\?[:=!><]|\\[dsw\d]|\[.+\]|\{\d+,?\d*\}/i)
127
+ rescue RegexpError
128
+ false
107
129
  end
108
130
 
109
131
  private
@@ -233,7 +255,7 @@ module Squared
233
255
  end
234
256
  numtype = [
235
257
  [i, /\A\d+\z/],
236
- [f, /\A\d*(?:\.\d+)?\z/],
258
+ [f, /\A(\d+(\.\d*)?|\d*\.\d+)\z/],
237
259
  [si, /\A-?\d+\z/]
238
260
  ].freeze
239
261
  numcheck = ->(k, v) { numtype.any? { |flag, pat| flag.include?(k) && pat.match?(v) } }
@@ -258,8 +280,8 @@ module Squared
258
280
  elsif q.include?(key)
259
281
  add quote_option(key, val, double: qq.include?(key), merge: merge)
260
282
  elsif p.include?(key)
261
- if val.match?(/\A(["']).+\1\z/)
262
- add shell_option(key, val, escape: false, merge: merge)
283
+ if val =~ /\A(["']).+\1\z/
284
+ add shell_option(key, val, double: $1 == '"', escape: false, merge: merge)
263
285
  elsif path
264
286
  add quote_option(key, path + val, merge: merge)
265
287
  else
@@ -235,8 +235,9 @@ module Squared
235
235
  already_invoked? parallel, val
236
236
  end
237
237
 
238
- def exclude?(key, empty = false)
239
- @exclude.include?(key) || (empty && (!@data.key?(key) || @data[key].empty?))
238
+ def exclude?(key, fallback = false, empty: nil)
239
+ fallback = empty unless empty.nil?
240
+ @exclude.include?(key) || (fallback && (!@data.key?(key) || @data[key].empty?))
240
241
  end
241
242
 
242
243
  private
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.5.24
4
+ version: 0.5.26
5
5
  platform: ruby
6
6
  authors:
7
7
  - An Pham
@@ -124,7 +124,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
124
124
  - !ruby/object:Gem::Version
125
125
  version: '0'
126
126
  requirements: []
127
- rubygems_version: 4.0.10
127
+ rubygems_version: 4.0.19
128
128
  specification_version: 4
129
129
  summary: Rake task generator for managing multi-language workspaces.
130
130
  test_files: []