squared 0.5.25 → 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: e0cd4ff3d9faafb78e2d7f13560866b4db396f766f06c4dd0def6e228fbb3b28
4
- data.tar.gz: 8e30a7002e81361a7554a232cee8483f1ecc99e4920431dc60242595ff4b8a15
3
+ metadata.gz: 4b8f593f81759da39eb42e2644e8947ed5d7ce8ff45410507c4432384ec63cc2
4
+ data.tar.gz: c914a1fec5afe22e057b48f7ec4e08107222fe68364a2dfa6124c94fa03946ef
5
5
  SHA512:
6
- metadata.gz: 3f7a5569c684260af71ced323cc90a4574b291e38c42cd6118811f2f1cbc7c6b6ce3880217260721de122bd742feedc986ff0f147cc248b5b16eb38c6df25f7a
7
- data.tar.gz: a42bf79be7e6d83776e97c67cef06cdb7a5183db8b788a69fc489e2156d7d366644433ea8ad677126e7ae191d33631b242f96ed0bdf179885e9e15b0462baa70
6
+ metadata.gz: 4a8812a2ebae08ff07d54bab680e234d06ecc466877b493d6e2e037b0154e7350a9e77fdf2ab8a2227d2c8ddc9de1ca51f20a2ee2ef2c75e9db6314b0ab53c52
7
+ data.tar.gz: 0be6c80075ba5e49b92d09660fd8a6ac4c595d9eec7cf577c81ac55162042aac55f0b2b127d4a792dac819181e7f0ef69cf8501b95eb4848901e2d07d4aba4e6
data/CHANGELOG.md CHANGED
@@ -1,5 +1,28 @@
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
+
3
26
  ## [0.5.25] - 2026-07-04
4
27
 
5
28
  ### Fixed
@@ -1437,6 +1460,7 @@
1437
1460
 
1438
1461
  - Changelog was created.
1439
1462
 
1463
+ [0.5.26]: https://github.com/anpham6/squared-ruby/releases/tag/v0.5.26
1440
1464
  [0.5.25]: https://github.com/anpham6/squared-ruby/releases/tag/v0.5.25
1441
1465
  [0.5.24]: https://github.com/anpham6/squared-ruby/releases/tag/v0.5.24
1442
1466
  [0.5.23]: https://github.com/anpham6/squared-ruby/releases/tag/v0.5.23
@@ -1463,6 +1487,8 @@
1463
1487
  [0.5.2]: https://github.com/anpham6/squared-ruby/releases/tag/v0.5.2-ruby
1464
1488
  [0.5.1]: https://github.com/anpham6/squared-ruby/releases/tag/v0.5.1-ruby
1465
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
1466
1492
  [0.4.39]: https://github.com/anpham6/squared-ruby/releases/tag/v0.4.39
1467
1493
  [0.4.38]: https://github.com/anpham6/squared-ruby/releases/tag/v0.4.38
1468
1494
  [0.4.37]: https://github.com/anpham6/squared-ruby/releases/tag/v0.4.37
@@ -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)
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Squared
4
- VERSION = '0.5.25'
4
+ VERSION = '0.5.26'
5
5
  end
@@ -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)
@@ -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
@@ -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,
@@ -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,
@@ -1723,7 +1722,7 @@ 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}/")
1725
+ ret = write_lines(out, grep: op.extras)
1727
1726
  list_result(ret, flag.to_s, grep: op.extras, banner: banner, from: from)
1728
1727
  end
1729
1728
 
@@ -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.25
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: []